fix(tasks): address task API review feedback

The public kill result used the awkward phrase already-terminal. Rename it to already-finished and keep the model-facing response aligned; not-alive would be inaccurate because a force-failed registry record can still correspond to orphaned producer work.

Task kinds were open strings even though producer namespaces are an extension point. Add the merge-extensible TaskKindMap and derived TaskKind, cover consumer declarations in task and bundle tests, and retain the runtime non-empty check for untyped callers.

With exactOptionalPropertyTypes, owner?: Agent | undefined allowed an explicit undefined value that no caller needs. Tighten the property to owner?: Agent so unowned work is expressed by omitting it.

Record the requested task-service/backend split as a follow-up, using a systemd-backed runtime as a concrete candidate without guessing its durability and ownership contract in this PR. Regenerate the type and Cordis catalogs so public docs match the declarations.
This commit is contained in:
Tianyi Cui
2026-07-15 21:45:30 +08:00
parent f4bd2405cc
commit b06ae91fa8
12 changed files with 84 additions and 36 deletions

View File

@@ -216,7 +216,7 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
'list(caller?: Agent): TaskSnapshot[]',
'get(id: TaskId, caller?: Agent): TaskSnapshot',
'read(id: TaskId, caller?: Agent): TaskRead',
'kill(id: TaskId, caller?: Agent, reason?: string): \'requested\' | \'already-terminal\'',
'kill(id: TaskId, caller?: Agent, reason?: string): \'requested\' | \'already-finished\'',
'async wait(id: TaskId, timeoutMs: number, caller?: Agent, signal?: AbortSignal): Promise<TaskSnapshot>',
'onTaskDone(listener: TaskDoneListener): () => void',
'attachSurface(name: string): () => void',
@@ -933,6 +933,14 @@ export const TYPE_API: readonly TypeApiEntry[] = [
name: 'TaskId',
declaration: 'export type TaskId = Branded<\'TaskId\'>;',
},
{
name: 'TaskKind',
declaration: 'export type TaskKind = TaskKindMap[keyof TaskKindMap];',
},
{
name: 'TaskKindMap',
declaration: 'export interface TaskKindMap {\n bash: \'bash\';\n subagent: \'subagent\';\n}',
},
{
name: 'TaskOutcome',
declaration: 'export interface TaskOutcome {\n status: \'completed\' | \'killed\' | \'failed\';\n detail?: string;\n output?: string;\n}',
@@ -943,11 +951,11 @@ export const TYPE_API: readonly TypeApiEntry[] = [
},
{
name: 'TaskSnapshot',
declaration: 'export interface TaskSnapshot {\n id: TaskId;\n kind: string;\n label: string;\n ownerSession?: SessionId;\n status: TaskStatus;\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n reported: boolean;\n}',
declaration: 'export interface TaskSnapshot {\n id: TaskId;\n kind: TaskKind;\n label: string;\n ownerSession?: SessionId;\n status: TaskStatus;\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n reported: boolean;\n}',
},
{
name: 'TaskStart',
declaration: 'export interface TaskStart {\n kind: string;\n label: string;\n owner?: Agent | undefined;\n run(): TaskHooks;\n}',
declaration: 'export interface TaskStart {\n kind: TaskKind;\n label: string;\n owner?: Agent;\n run(): TaskHooks;\n}',
},
{
name: 'TaskStatus',