O que taskflow faz?
Use TaskFlow quando um job precisar sobreviver a um prompt ou a uma execução desanexada, mas você ainda quiser uma sessão de proprietário, um contexto de retorno e um lugar para inspecionar ou retomar o trabalho.
Quando usar
- Trabalho em segundo plano multi-etapa com um proprietário
- Trabalho que depende de tarefas ACP desanexadas ou subagentes
- Jobs que podem precisar emitir uma atualização clara de volta ao proprietário
- Jobs que precisam de pequeno estado persistente entre etapas
- Trabalho de plugin ou ferramenta que deve sobreviver a reinicializações e conflitos de revisão de forma limpa
O que o TaskFlow gerencia
- identidade do fluxo
- sessão do proprietário e origem do solicitante
currentStep,stateJsonewaitJson- tarefas filhas vinculadas e seu id do fluxo pai
- estado de conclusão, falha, cancelamento, espera e bloqueio
- rastreamento de revisão para mutações seguras contra conflitos
Ele não gerencia ramificações ou lógica de negócios. Coloque isso no Lobster, acpx ou no código chamador.
Forma atual do runtime
Ponto de entrada canônico para plugin/runtime:
api.runtime.tasks.flowapi.runtime.taskFlowainda existe como alias, masapi.runtime.tasks.flowé a forma canônica
Vinculação:
api.runtime.tasks.flow.fromToolContext(ctx)quando você já tem um contexto de ferramenta confiável comsessionKeyapi.runtime.tasks.flow.bindSession({ sessionKey, requesterOrigin })quando sua camada de vinculo já resolveu a sessão e o contexto de entrega
Ciclo de vida do fluxo gerenciado:
createManaged(...)runTask(...)setWaiting(...)ao aguardar uma pessoa ou um sistema externoresume(...)quando o trabalho pode continuarfinish(...)oufail(...)requestCancel(...)oucancel(...)quando todo o job deve parar
Restrições de design
- Use fluxos gerenciados quando seu código for o responsável pela orquestração.
- Fluxos espelhados de uma tarefa são criados pelo runtime principal para trabalho ACP/subagente desanexado; esta skill é principalmente sobre fluxos gerenciados.
- Trate
stateJsoncomo o saco de estado persistido. Não há API separadasetFlowOutputouappendFlowOutput. - Todo método mutante após a criação é verificado por revisão. Avance com a revisão mais recente (
flow.revision) após cada mutação bem-sucedida. runTask(...)vincula a tarefa filha ao fluxo. Use-o em vez de criar manualmente tarefas desanexadas quando você quiser orquestração pai.
Exemplo de forma
const taskFlow = api.runtime.tasks.flow.fromToolContext(ctx);
const created = taskFlow.createManaged({
controllerId: "my-plugin/inbox-triage",
goal: "triagem de caixa de entrada",
currentStep: "classificar",
stateJson: {
businessThreads: [],
personalItems: [],
eodSummary: [],
},
});
const classify = taskFlow.runTask({
flowId: created.flowId,
runtime: "acp",
childSessionKey: "agent:main:subagent:classifier",
runId: "inbox-classify-1",
task: "Classificar mensagens da caixa de entrada",
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: "aguardar_resposta_comercial",
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: "finalizar",
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,
});
Mantenha condicionais acima do runtime
Use o runtime do fluxo para estado e vinculação de tarefas. Mantenha as decisões na camada de autoria:
business-> postar no Slack e aguardarpersonal-> notificar o proprietário agoralater-> anexar a um balde de resumo do final do dia
Padrão operacional
- Armazene apenas o estado mínimo necessário para retomar.
- Coloque razões de espera legíveis por humanos em
blockedSummaryou metadados de espera estruturados emwaitJson. - Use
getTaskSummary(flowId)quando o orquestrador precisar de uma visão compacta da saúde do trabalho filho. - Use
requestCancel(...)quando um chamador quiser que o fluxo pare de agendar imediatamente. - Use
cancel(...)quando você também quiser cancelar tarefas filhas vinculadas ativas.
Exemplos
- Veja
skills/taskflow/examples/inbox-triage.lobster - Veja
skills/taskflow/examples/pr-intake.lobster - Veja
skills/taskflow-inbox-triage/SKILL.mdpara um padrão concreto de roteamento