Implementing the Stop Button (ui_stop_wf)
The traffic-light red button in a widget window's title bar lets users stop a running app directly from the dashboard UI. This button is inactive (greyed out) by default — it only activates for process diagram classes that declare a ui_stop_wf workflow.
How It Works
When a user clicks the red button on a widget window, the dashboard looks up the ui_stop_wf field for the running diagram's pdClass in the app manifest. If a value is present, the dashboard calls that named workflow on the running PDI. The workflow is responsible for performing whatever cleanup the app requires before the stop.
Declaring ui_stop_wf in Your App Manifest
In your app's manifest.json, add ui_stop_wf to the pdClass definition:
{
"pdClasses": {
"my_agent": {
"name": "My Agent",
"desc": "Does something useful",
"ui_stop_wf": "stop_hook"
}
}
}
The value is the workflow name to invoke — it must exist in your PDI's workflow library and be callable as a named workflow trigger.
Writing the Stop Workflow
The stop workflow is invoked via triggerNamedWorkflow from the dashboard. It receives no special arguments — its job is simply to perform an orderly shutdown of whatever the PDI is doing.
Typical stop workflow responsibilities:
- Publish a final status message to any active swarms
- Cancel any pending timers or in-flight HTTP requests
- Write any state that should persist to memory or disk
- Call
stop_hookon child PDIs if the agent manages sub-diagrams
The workflow follows the standard 3-file convention (json.json, xml.xml, script.js). Most stop hooks are all-preflight — the Blockly wrapper is trivial.
Minimal example (script.js)
async function preflight(wfProxy) {
const alias = wfProxy.getGlobalValue('pd_alias');
// publish a shutdown notification to the agent's send swarm
const sendSwarm = wfProxy.getGlobalValue('agent_send_swarm');
if (sendSwarm) {
await wfProxy.publishToSwarm(sendSwarm, {
from: wfProxy.getGlobalValue('wf_agent_name') || alias,
id: alias,
args: [{ username: 'system', text: '[agent stopped]', timestamp: Date.now(), type: 'text/plain' }]
});
}
resp = { success: true };
return Promise.resolve({ success: true });
}
Notes
- If
ui_stop_wfis absent or empty in the manifest, the red button is rendered but is visually greyed and non-interactive — no error is shown. - The stop workflow does not automatically shut down the PDI process itself. If you want the PDI to exit after stop, call the appropriate teardown API from within the workflow.
- For
kilroy.ai.servicespipeline agents (ai_agent,wf_agent, etc.), the stop lifecycle is managed by the pipeline'sstop_hookworkflow — you do not need to declareui_stop_wfon individual agent pdClasses unless you want per-agent granular stop controls.