This note documents the Tool_* workflow extension implemented in VLCode-Lite on top of the JS VL-Workflow-Engine vendor copy.
Canonical spec note:
3 is now VL Workflow Spec 3.18version: "3.16" during the transitionTool_*, tool_message, clientRunToken, and checkpoint rerun semantics are documented as part of the 3.17 extension profileSubflow_* is supported as an editor/runtime alias that lowers to WorkflowRun without introducing a separate execution primitiveSubflow_* node alias for child-workflow orchestrationTool_* node rendering and editing in public/workflow-editor.htmltool_start, tool_message, tool_done, tool_errorWorkflowRun, pause/resume, and executeFrom() rerunrunID and clientRunToken{
"id": "Tool_010_ReadSpec",
"tool": "ReadFile",
"input": {
"file_path": "=\"docs/spec.md\""
},
"out": {
"$specText": "=_result",
"$rawTool": "=_toolResult"
},
"next": "Stop_End"
}
Supported fields:
tool or toolName: explicit tool nameinput or in: tool argumentstimeout: forwarded into tool input when the input object does not already carry timeoutallowError or continueOnError: continue after tool failureout: normal workflow output mappingIf tool is omitted, VLCode derives it from the step id:
Tool_010_ReadFile → ReadFileTool_120_VLCompile → VLCompileDuring Tool_* output mapping, two temporary variables are available:
_result: normalized primary tool payload_toolResult: full raw tool envelopeNormalization rule:
{ result: ... }, _result is auto-unwrapped to that inner payload_toolResult when the workflow needs metadata like diff, undoId, or the original nested return shapeExample:
{
"id": "Tool_020_EditFile",
"tool": "EditFile",
"input": {
"file_path": "=\"Apps/Main.vx\"",
"old_string": "=\"old\"",
"new_string": "=\"new\""
},
"out": {
"$editSummary": "=_result",
"$editDiff": "=_toolResult.diff",
"$undoId": "=_toolResult.undoId"
}
}
VLCode tools may accept a second runtime argument:
execute: async (input, runtime = {}) => {
runtime.info?.('Reading spec', { file_path: input.file_path });
runtime.progress?.('Loaded first chunk', { bytes: 4096 });
return { result: '...' };
}
Available helpers:
runtime.emit(type, payload)runtime.text(message, meta)runtime.info(message, data)runtime.warn(message, data)runtime.error(message, data)runtime.progress(message, data)These are surfaced by the workflow runtime as tool_message events, so the outer window, detail log, SSE clients, and workflow-editor.html can display them while the tool is still running.
Default behavior:
tool_errorWith allowError: true:
{
"id": "Tool_030_Compile",
"tool": "VLCompile",
"allowError": true,
"input": {},
"out": {
"$compileOk": "=_result.ok",
"$compileError": "=_result.error"
},
"next": "Branch_040_HandleCompile"
}
In this mode:
tool_error still emits_result becomes { "ok": false, "error": "...", "tool": "VLCompile" }step_doneTool_* steps emit:
step_start
→ tool_start
→ tool_message(0..N)
→ tool_done | tool_error
→ var_changed(0..N)
→ step_done | step_error
tool_message payload shape:
{
"type": "tool_message",
"stepId": "Tool_010_ReadSpec",
"name": "ReadFile",
"level": "info",
"message": "Reading file",
"data": {
"file_path": "docs/spec.md"
},
"runID": "wf_1770000000000",
"clientRunToken": "client:1770000000000:1"
}
Server-side broadcasts now include runID and clientRunToken for all tool events, so parallel runs can be disambiguated in the editor and in the main UI.
The workflow editor now treats Tool as a first-class node type:
TLtool, input, timeout, allowErrortool_message, checkpoint, pause/resume, rerun, and other non-token eventsWorkflowRun now supports mode: "sync" for supervisor-style orchestration:
{
"id": "Tool_010_RunWorker",
"tool": "WorkflowRun",
"input": {
"mode": "sync",
"workflow_path": "=\"examples/workflows/vlclaw-worker-spec.json\"",
"params": {
"goal": "=goal",
"artifactPath": "=$specPath"
}
},
"out": {
"$workerRun": "=_result"
},
"next": "RETURN"
}
sync mode returns a structured object with:
statusrunIDfilesWrittenvariablescheckpointcompletedStepseventsThis is the recommended primitive for “workflow managing child workflows”, which is the most practical landing path for a VLClaw-style AI engineer manager.
Tool_* is a VLCode extension, not a pure core-spec nodeToolRegistryValidated locally on 2026-03-14:
node test-workflow-executor.jsnode test-workflow-run-tool-step.jsnode test-workflow-editor.jsnode test-workflow-parallel-codegen.js