Loading...
Loading...
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
npx skill4agent add steipete/clawdis taskflowcurrentStepstateJsonwaitJsonapi.runtime.tasks.flowapi.runtime.taskFlowapi.runtime.tasks.flowapi.runtime.tasks.flow.fromToolContext(ctx)sessionKeyapi.runtime.tasks.flow.bindSession({ sessionKey, requesterOrigin })createManaged(...)runTask(...)setWaiting(...)resume(...)finish(...)fail(...)requestCancel(...)cancel(...)stateJsonsetFlowOutputappendFlowOutputflow.revisionrunTask(...)const taskFlow = api.runtime.tasks.flow.fromToolContext(ctx);
const created = taskFlow.createManaged({
controllerId: "my-plugin/inbox-triage",
goal: "triage inbox",
currentStep: "classify",
stateJson: {
businessThreads: [],
personalItems: [],
eodSummary: [],
},
});
const classify = taskFlow.runTask({
flowId: created.flowId,
runtime: "acp",
childSessionKey: "agent:main:subagent:classifier",
runId: "inbox-classify-1",
task: "Classify inbox messages",
status: "running",
startedAt: Date.now(),
lastEventAt: Date.now(),
});
if (!classify.created) {
throw new Error(classify.reason);
}
const waiting = taskFlow.setWaiting({
flowId: created.flowId,
expectedRevision: created.revision,
currentStep: "await_business_reply",
stateJson: {
businessThreads: ["slack:thread-1"],
personalItems: [],
eodSummary: [],
},
waitJson: {
kind: "reply",
channel: "slack",
threadKey: "slack:thread-1",
},
});
if (!waiting.applied) {
throw new Error(waiting.code);
}
const resumed = taskFlow.resume({
flowId: waiting.flow.flowId,
expectedRevision: waiting.flow.revision,
status: "running",
currentStep: "finalize",
stateJson: waiting.flow.stateJson,
});
if (!resumed.applied) {
throw new Error(resumed.code);
}
taskFlow.finish({
flowId: resumed.flow.flowId,
expectedRevision: resumed.flow.revision,
stateJson: resumed.flow.stateJson,
});businesspersonallaterblockedSummarywaitJsongetTaskSummary(flowId)requestCancel(...)cancel(...)skills/taskflow/examples/inbox-triage.lobsterskills/taskflow/examples/pr-intake.lobsterskills/taskflow-inbox-triage/SKILL.md