feat(flow-coordinator): add slashCommand/slashArgs support for unified workflow

- Add buildNodeInstruction() to construct instructions from slashCommand field
- Support slashArgs with {{variable}} interpolation
- Append additional instruction as context when slashCommand is set
- Update unified-workflow-spec.md with slashCommand/slashArgs documentation

This enables frontend orchestrator JSON to be directly consumed by
flow-coordinator skill in Claude client.
This commit is contained in:
catlog22
2026-02-05 15:33:06 +08:00
parent e555355a71
commit 834951a08d
2 changed files with 43 additions and 7 deletions

View File

@@ -43,6 +43,8 @@ Execution Modes:
**Unified PromptTemplate Model**: All workflow steps are natural language instructions with:
- `instruction`: What to execute (natural language)
- `slashCommand`: Optional slash command name (e.g., "workflow:plan")
- `slashArgs`: Optional arguments for slash command (supports {{variable}})
- `outputName`: Name for output reference
- `contextRefs`: References to previous step outputs
- `tool`: Optional CLI tool (gemini/qwen/codex/claude)
@@ -137,18 +139,14 @@ async function executeDAG(workflow, order, state, statusPath) {
continue; // Will be executed when dependencies complete
}
// Resolve context references
const resolvedInstruction = resolveContextRefs(
data.instruction,
data.contextRefs || [],
state.outputs
);
// Build instruction from slashCommand or raw instruction
let instruction = buildNodeInstruction(data, state.outputs);
// Execute based on mode
state.nodeStates[nodeId] = { status: 'running' };
write(statusPath, JSON.stringify(state, null, 2));
const result = await executeNode(resolvedInstruction, data.tool, data.mode);
const result = await executeNode(instruction, data.tool, data.mode);
// Store output for downstream nodes
state.nodeStates[nodeId] = { status: 'completed', result };
@@ -162,6 +160,36 @@ async function executeDAG(workflow, order, state, statusPath) {
write(statusPath, JSON.stringify(state, null, 2));
}
/**
* Build node instruction from slashCommand or raw instruction
* Handles slashCommand/slashArgs fields from frontend orchestrator
*/
function buildNodeInstruction(data, outputs) {
const refs = data.contextRefs || [];
// If slashCommand is set, construct instruction from it
if (data.slashCommand) {
// Resolve variables in slashArgs
const args = data.slashArgs
? resolveContextRefs(data.slashArgs, refs, outputs)
: '';
// Build slash command instruction
let instruction = `/${data.slashCommand}${args ? ' ' + args : ''}`;
// Append additional instruction if provided
if (data.instruction) {
const additionalInstruction = resolveContextRefs(data.instruction, refs, outputs);
instruction = `${instruction}\n\n${additionalInstruction}`;
}
return instruction;
}
// Fallback: use raw instruction with context refs resolved
return resolveContextRefs(data.instruction || '', refs, outputs);
}
function resolveContextRefs(instruction, refs, outputs) {
let resolved = instruction;
for (const ref of refs) {

View File

@@ -48,6 +48,10 @@ interface PromptTemplateNodeData {
label: string; // Display label in editor
instruction: string; // Natural language instruction
// === Slash Command (optional, overrides instruction) ===
slashCommand?: string; // Slash command name (e.g., "workflow:plan")
slashArgs?: string; // Arguments for slash command (supports {{variable}})
// === Data Flow ===
outputName?: string; // Name for output reference
contextRefs?: string[]; // References to previous outputs
@@ -63,6 +67,10 @@ interface PromptTemplateNodeData {
}
```
**Instruction Resolution Priority**:
1. If `slashCommand` is set: `/{slashCommand} {slashArgs}` + optional `instruction` as context
2. Otherwise: `instruction` directly
### FlowEdge
```typescript