digital-tasks 2.1.3 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +18 -0
- package/README.md +560 -0
- package/dist/client.d.ts +202 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +85 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +9 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/markdown.d.ts.map +1 -1
- package/dist/markdown.js +48 -27
- package/dist/markdown.js.map +1 -1
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +48 -30
- package/dist/project.js.map +1 -1
- package/dist/queue.d.ts.map +1 -1
- package/dist/queue.js +70 -31
- package/dist/queue.js.map +1 -1
- package/dist/task.d.ts +1 -1
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +122 -60
- package/dist/task.js.map +1 -1
- package/dist/types.d.ts +135 -22
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -2
- package/dist/types.js.map +1 -1
- package/dist/worker.d.ts +264 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +656 -0
- package/dist/worker.js.map +1 -0
- package/package.json +29 -14
- package/src/client.ts +268 -0
- package/src/index.ts +12 -10
- package/src/markdown.ts +63 -48
- package/src/project.ts +57 -42
- package/src/queue.ts +76 -37
- package/src/task.ts +132 -75
- package/src/types.ts +177 -40
- package/src/worker.ts +959 -0
- package/test/project.test.ts +28 -84
- package/test/queue.test.ts +51 -24
- package/test/task.test.ts +80 -27
- package/test/worker.test.ts +1158 -0
- package/tsconfig.json +2 -13
- package/vitest.config.ts +48 -0
- package/wrangler.jsonc +44 -0
- package/LICENSE +0 -21
- package/dist/function-task.d.ts +0 -319
- package/dist/function-task.d.ts.map +0 -1
- package/dist/function-task.js +0 -286
- package/dist/function-task.js.map +0 -1
- package/src/index.js +0 -73
- package/src/markdown.js +0 -509
- package/src/project.js +0 -396
- package/src/queue.js +0 -346
- package/src/task.js +0 -320
- package/src/types.js +0 -14
package/src/task.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
WorkerRef,
|
|
12
12
|
TaskResult,
|
|
13
13
|
TaskDependency,
|
|
14
|
+
TaskProgress,
|
|
14
15
|
} from './types.js'
|
|
15
16
|
import { taskQueue } from './queue.js'
|
|
16
17
|
|
|
@@ -27,7 +28,7 @@ function generateTaskId(): string {
|
|
|
27
28
|
* @example
|
|
28
29
|
* ```ts
|
|
29
30
|
* const task = await createTask({
|
|
30
|
-
*
|
|
31
|
+
* tool: {
|
|
31
32
|
* type: 'generative',
|
|
32
33
|
* name: 'summarize',
|
|
33
34
|
* args: { text: 'The text to summarize' },
|
|
@@ -44,6 +45,14 @@ export async function createTask<TInput = unknown, TOutput = unknown>(
|
|
|
44
45
|
): Promise<Task<TInput, TOutput>> {
|
|
45
46
|
const now = new Date()
|
|
46
47
|
|
|
48
|
+
// Resolve the underlying Tool from either `tool` (preferred) or
|
|
49
|
+
// the legacy `function` alias. Exactly one path is required; throw
|
|
50
|
+
// a clear error if neither is set so callers see this at runtime.
|
|
51
|
+
const tool = options.tool ?? options.function
|
|
52
|
+
if (!tool) {
|
|
53
|
+
throw new Error("createTask requires a 'tool' (preferred) or legacy 'function' option")
|
|
54
|
+
}
|
|
55
|
+
|
|
47
56
|
// Convert string dependencies to TaskDependency array
|
|
48
57
|
let dependencies: TaskDependency[] | undefined
|
|
49
58
|
if (options.dependencies && options.dependencies.length > 0) {
|
|
@@ -54,10 +63,10 @@ export async function createTask<TInput = unknown, TOutput = unknown>(
|
|
|
54
63
|
}))
|
|
55
64
|
}
|
|
56
65
|
|
|
57
|
-
// Determine allowed workers from function type
|
|
66
|
+
// Determine allowed workers from the Tool's function type
|
|
58
67
|
let allowedWorkers = options.allowedWorkers
|
|
59
68
|
if (!allowedWorkers) {
|
|
60
|
-
const funcType =
|
|
69
|
+
const funcType = tool.type
|
|
61
70
|
if (funcType === 'human') {
|
|
62
71
|
allowedWorkers = ['human']
|
|
63
72
|
} else if (funcType === 'agentic') {
|
|
@@ -69,27 +78,70 @@ export async function createTask<TInput = unknown, TOutput = unknown>(
|
|
|
69
78
|
|
|
70
79
|
const task: Task<TInput, TOutput> = {
|
|
71
80
|
id: generateTaskId(),
|
|
72
|
-
|
|
81
|
+
$type: 'Task',
|
|
82
|
+
// Action supertype: every Task is an Action of some Verb. Default
|
|
83
|
+
// the verb to the underlying Tool's name when not supplied.
|
|
84
|
+
verb: tool.name,
|
|
85
|
+
// Tool is the canonical field (CONTEXT.md). The legacy `function`
|
|
86
|
+
// alias is populated alongside for the duration of the deprecation
|
|
87
|
+
// window so older readers continue to work.
|
|
88
|
+
tool,
|
|
89
|
+
function: tool,
|
|
73
90
|
status: options.scheduledFor ? 'pending' : 'queued',
|
|
74
91
|
priority: options.priority || 'normal',
|
|
75
|
-
input: options.input,
|
|
76
92
|
allowedWorkers,
|
|
77
|
-
dependencies,
|
|
78
|
-
scheduledFor: options.scheduledFor,
|
|
79
|
-
deadline: options.deadline,
|
|
80
|
-
timeout: options.timeout,
|
|
81
|
-
tags: options.tags,
|
|
82
|
-
parentId: options.parentId,
|
|
83
|
-
projectId: options.projectId,
|
|
84
|
-
metadata: options.metadata,
|
|
85
93
|
createdAt: now,
|
|
86
94
|
events: [],
|
|
87
95
|
}
|
|
96
|
+
if (options.input !== undefined) {
|
|
97
|
+
task.input = options.input
|
|
98
|
+
}
|
|
99
|
+
if (dependencies !== undefined) {
|
|
100
|
+
task.dependencies = dependencies
|
|
101
|
+
}
|
|
102
|
+
if (options.scheduledFor !== undefined) {
|
|
103
|
+
task.scheduledFor = options.scheduledFor
|
|
104
|
+
}
|
|
105
|
+
if (options.deadline !== undefined) {
|
|
106
|
+
task.deadline = options.deadline
|
|
107
|
+
}
|
|
108
|
+
if (options.timeout !== undefined) {
|
|
109
|
+
task.timeout = options.timeout
|
|
110
|
+
}
|
|
111
|
+
if (options.tags !== undefined) {
|
|
112
|
+
task.tags = options.tags
|
|
113
|
+
}
|
|
114
|
+
if (options.parentId !== undefined) {
|
|
115
|
+
task.parentId = options.parentId
|
|
116
|
+
}
|
|
117
|
+
if (options.projectId !== undefined) {
|
|
118
|
+
task.projectId = options.projectId
|
|
119
|
+
}
|
|
120
|
+
if (options.metadata !== undefined) {
|
|
121
|
+
task.metadata = options.metadata
|
|
122
|
+
}
|
|
123
|
+
// Issue-shaped fields (SVO co-design)
|
|
124
|
+
if (options.title !== undefined) {
|
|
125
|
+
task.title = options.title
|
|
126
|
+
}
|
|
127
|
+
if (options.body !== undefined) {
|
|
128
|
+
task.body = options.body
|
|
129
|
+
}
|
|
130
|
+
if (options.labels !== undefined) {
|
|
131
|
+
task.labels = options.labels
|
|
132
|
+
}
|
|
133
|
+
if (options.project !== undefined) {
|
|
134
|
+
task.project = options.project
|
|
135
|
+
}
|
|
136
|
+
if (options.assignees !== undefined) {
|
|
137
|
+
task.assignees = options.assignees
|
|
138
|
+
}
|
|
88
139
|
|
|
89
|
-
// Auto-assign if specified
|
|
90
|
-
|
|
140
|
+
// Auto-assign if specified (single primary worker takes precedence)
|
|
141
|
+
const primaryAssignee = options.assignTo ?? options.assignees?.[0]
|
|
142
|
+
if (primaryAssignee) {
|
|
91
143
|
task.assignment = {
|
|
92
|
-
worker:
|
|
144
|
+
worker: primaryAssignee,
|
|
93
145
|
assignedAt: now,
|
|
94
146
|
}
|
|
95
147
|
task.status = 'assigned'
|
|
@@ -97,9 +149,7 @@ export async function createTask<TInput = unknown, TOutput = unknown>(
|
|
|
97
149
|
|
|
98
150
|
// Check if blocked by dependencies
|
|
99
151
|
if (dependencies && dependencies.length > 0) {
|
|
100
|
-
const hasPendingDeps = dependencies.some(
|
|
101
|
-
(d) => d.type === 'blocked_by' && !d.satisfied
|
|
102
|
-
)
|
|
152
|
+
const hasPendingDeps = dependencies.some((d) => d.type === 'blocked_by' && !d.satisfied)
|
|
103
153
|
if (hasPendingDeps) {
|
|
104
154
|
task.status = 'blocked'
|
|
105
155
|
}
|
|
@@ -121,10 +171,7 @@ export async function getTask(id: string): Promise<AnyTask | undefined> {
|
|
|
121
171
|
/**
|
|
122
172
|
* Start working on a task
|
|
123
173
|
*/
|
|
124
|
-
export async function startTask(
|
|
125
|
-
taskId: string,
|
|
126
|
-
worker: WorkerRef
|
|
127
|
-
): Promise<AnyTask | undefined> {
|
|
174
|
+
export async function startTask(taskId: string, worker: WorkerRef): Promise<AnyTask | undefined> {
|
|
128
175
|
const task = await taskQueue.get(taskId)
|
|
129
176
|
if (!task) return undefined
|
|
130
177
|
|
|
@@ -153,12 +200,15 @@ export async function updateProgress(
|
|
|
153
200
|
percent: number,
|
|
154
201
|
step?: string
|
|
155
202
|
): Promise<AnyTask | undefined> {
|
|
203
|
+
const progressUpdate: Partial<TaskProgress> = {
|
|
204
|
+
percent,
|
|
205
|
+
updatedAt: new Date(),
|
|
206
|
+
}
|
|
207
|
+
if (step !== undefined) {
|
|
208
|
+
progressUpdate.step = step
|
|
209
|
+
}
|
|
156
210
|
return taskQueue.update(taskId, {
|
|
157
|
-
progress:
|
|
158
|
-
percent,
|
|
159
|
-
step,
|
|
160
|
-
updatedAt: new Date(),
|
|
161
|
-
},
|
|
211
|
+
progress: progressUpdate,
|
|
162
212
|
event: {
|
|
163
213
|
type: 'progress',
|
|
164
214
|
message: step || `Progress: ${percent}%`,
|
|
@@ -188,28 +238,27 @@ export async function completeTask<TOutput>(
|
|
|
188
238
|
|
|
189
239
|
await taskQueue.complete(taskId, output)
|
|
190
240
|
|
|
241
|
+
const metadata: TaskResult<TOutput>['metadata'] = {
|
|
242
|
+
duration: task.startedAt ? Date.now() - task.startedAt.getTime() : 0,
|
|
243
|
+
startedAt: task.startedAt || new Date(),
|
|
244
|
+
completedAt: new Date(),
|
|
245
|
+
}
|
|
246
|
+
if (task.assignment?.worker !== undefined) {
|
|
247
|
+
metadata.worker = task.assignment.worker
|
|
248
|
+
}
|
|
249
|
+
|
|
191
250
|
return {
|
|
192
251
|
taskId,
|
|
193
252
|
success: true,
|
|
194
253
|
output,
|
|
195
|
-
metadata
|
|
196
|
-
duration: task.startedAt
|
|
197
|
-
? Date.now() - task.startedAt.getTime()
|
|
198
|
-
: 0,
|
|
199
|
-
startedAt: task.startedAt || new Date(),
|
|
200
|
-
completedAt: new Date(),
|
|
201
|
-
worker: task.assignment?.worker,
|
|
202
|
-
},
|
|
254
|
+
metadata,
|
|
203
255
|
}
|
|
204
256
|
}
|
|
205
257
|
|
|
206
258
|
/**
|
|
207
259
|
* Fail a task with error
|
|
208
260
|
*/
|
|
209
|
-
export async function failTask(
|
|
210
|
-
taskId: string,
|
|
211
|
-
error: string | Error
|
|
212
|
-
): Promise<TaskResult> {
|
|
261
|
+
export async function failTask(taskId: string, error: string | Error): Promise<TaskResult> {
|
|
213
262
|
const task = await taskQueue.get(taskId)
|
|
214
263
|
if (!task) {
|
|
215
264
|
return {
|
|
@@ -226,6 +275,15 @@ export async function failTask(
|
|
|
226
275
|
|
|
227
276
|
await taskQueue.fail(taskId, errorMessage)
|
|
228
277
|
|
|
278
|
+
const failMetadata: TaskResult['metadata'] = {
|
|
279
|
+
duration: task.startedAt ? Date.now() - task.startedAt.getTime() : 0,
|
|
280
|
+
startedAt: task.startedAt || new Date(),
|
|
281
|
+
completedAt: new Date(),
|
|
282
|
+
}
|
|
283
|
+
if (task.assignment?.worker !== undefined) {
|
|
284
|
+
failMetadata.worker = task.assignment.worker
|
|
285
|
+
}
|
|
286
|
+
|
|
229
287
|
return {
|
|
230
288
|
taskId,
|
|
231
289
|
success: false,
|
|
@@ -234,24 +292,14 @@ export async function failTask(
|
|
|
234
292
|
message: errorMessage,
|
|
235
293
|
details: error instanceof Error ? { stack: error.stack } : undefined,
|
|
236
294
|
},
|
|
237
|
-
metadata:
|
|
238
|
-
duration: task.startedAt
|
|
239
|
-
? Date.now() - task.startedAt.getTime()
|
|
240
|
-
: 0,
|
|
241
|
-
startedAt: task.startedAt || new Date(),
|
|
242
|
-
completedAt: new Date(),
|
|
243
|
-
worker: task.assignment?.worker,
|
|
244
|
-
},
|
|
295
|
+
metadata: failMetadata,
|
|
245
296
|
}
|
|
246
297
|
}
|
|
247
298
|
|
|
248
299
|
/**
|
|
249
300
|
* Cancel a task
|
|
250
301
|
*/
|
|
251
|
-
export async function cancelTask(
|
|
252
|
-
taskId: string,
|
|
253
|
-
reason?: string
|
|
254
|
-
): Promise<boolean> {
|
|
302
|
+
export async function cancelTask(taskId: string, reason?: string): Promise<boolean> {
|
|
255
303
|
const task = await taskQueue.get(taskId)
|
|
256
304
|
if (!task) return false
|
|
257
305
|
|
|
@@ -274,13 +322,14 @@ export async function addComment(
|
|
|
274
322
|
comment: string,
|
|
275
323
|
author?: WorkerRef
|
|
276
324
|
): Promise<AnyTask | undefined> {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
325
|
+
const event: Omit<import('./types.js').TaskEvent, 'id' | 'timestamp'> = {
|
|
326
|
+
type: 'comment',
|
|
327
|
+
message: comment,
|
|
328
|
+
}
|
|
329
|
+
if (author !== undefined) {
|
|
330
|
+
event.actor = author
|
|
331
|
+
}
|
|
332
|
+
return taskQueue.update(taskId, { event })
|
|
284
333
|
}
|
|
285
334
|
|
|
286
335
|
/**
|
|
@@ -329,22 +378,37 @@ export async function waitForTask(
|
|
|
329
378
|
}
|
|
330
379
|
|
|
331
380
|
if (task.status === 'completed') {
|
|
381
|
+
const completedMeta: TaskResult['metadata'] = {
|
|
382
|
+
duration:
|
|
383
|
+
task.completedAt && task.startedAt
|
|
384
|
+
? task.completedAt.getTime() - task.startedAt.getTime()
|
|
385
|
+
: 0,
|
|
386
|
+
startedAt: task.startedAt || task.createdAt,
|
|
387
|
+
completedAt: task.completedAt || new Date(),
|
|
388
|
+
}
|
|
389
|
+
if (task.assignment?.worker !== undefined) {
|
|
390
|
+
completedMeta.worker = task.assignment.worker
|
|
391
|
+
}
|
|
332
392
|
return {
|
|
333
393
|
taskId,
|
|
334
394
|
success: true,
|
|
335
395
|
output: task.output,
|
|
336
|
-
metadata:
|
|
337
|
-
duration: task.completedAt && task.startedAt
|
|
338
|
-
? task.completedAt.getTime() - task.startedAt.getTime()
|
|
339
|
-
: 0,
|
|
340
|
-
startedAt: task.startedAt || task.createdAt,
|
|
341
|
-
completedAt: task.completedAt || new Date(),
|
|
342
|
-
worker: task.assignment?.worker,
|
|
343
|
-
},
|
|
396
|
+
metadata: completedMeta,
|
|
344
397
|
}
|
|
345
398
|
}
|
|
346
399
|
|
|
347
400
|
if (task.status === 'failed') {
|
|
401
|
+
const failedMeta: TaskResult['metadata'] = {
|
|
402
|
+
duration:
|
|
403
|
+
task.completedAt && task.startedAt
|
|
404
|
+
? task.completedAt.getTime() - task.startedAt.getTime()
|
|
405
|
+
: 0,
|
|
406
|
+
startedAt: task.startedAt || task.createdAt,
|
|
407
|
+
completedAt: task.completedAt || new Date(),
|
|
408
|
+
}
|
|
409
|
+
if (task.assignment?.worker !== undefined) {
|
|
410
|
+
failedMeta.worker = task.assignment.worker
|
|
411
|
+
}
|
|
348
412
|
return {
|
|
349
413
|
taskId,
|
|
350
414
|
success: false,
|
|
@@ -352,14 +416,7 @@ export async function waitForTask(
|
|
|
352
416
|
code: 'TASK_FAILED',
|
|
353
417
|
message: task.error || 'Task failed',
|
|
354
418
|
},
|
|
355
|
-
metadata:
|
|
356
|
-
duration: task.completedAt && task.startedAt
|
|
357
|
-
? task.completedAt.getTime() - task.startedAt.getTime()
|
|
358
|
-
: 0,
|
|
359
|
-
startedAt: task.startedAt || task.createdAt,
|
|
360
|
-
completedAt: task.completedAt || new Date(),
|
|
361
|
-
worker: task.assignment?.worker,
|
|
362
|
-
},
|
|
419
|
+
metadata: failedMeta,
|
|
363
420
|
}
|
|
364
421
|
}
|
|
365
422
|
|
package/src/types.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Types for digital-tasks
|
|
3
3
|
*
|
|
4
|
-
* Task =
|
|
4
|
+
* Task = Action + issue-shaped metadata (title, body, comments, labels,
|
|
5
|
+
* dependencies, assignees, project). A Task is a specialization of an
|
|
6
|
+
* `Action` (`digital-objects.Action`) with project-management overlay,
|
|
7
|
+
* per the SVO co-design (`docs/plans/2026-05-05-svo-co-design.md`).
|
|
5
8
|
*
|
|
6
|
-
* Every task
|
|
9
|
+
* Every task wraps a callable Verb — historically the `function` field
|
|
10
|
+
* (an `ai-functions.FunctionDefinition`). Per CONTEXT.md the canonical
|
|
11
|
+
* name for callable Verbs is **Tool**; `function` is being renamed to
|
|
12
|
+
* `tool` over time. See the `function` / `tool` fields below.
|
|
13
|
+
*
|
|
14
|
+
* The function (now Tool) can be:
|
|
7
15
|
* - Code: generates executable code
|
|
8
16
|
* - Generative: AI generates content (no tools)
|
|
9
17
|
* - Agentic: AI with tools in a loop
|
|
@@ -19,6 +27,7 @@ import type {
|
|
|
19
27
|
AgenticFunctionDefinition,
|
|
20
28
|
HumanFunctionDefinition,
|
|
21
29
|
} from 'ai-functions'
|
|
30
|
+
import type { Action } from 'digital-objects'
|
|
22
31
|
|
|
23
32
|
// Re-export function types for convenience
|
|
24
33
|
export type {
|
|
@@ -29,6 +38,9 @@ export type {
|
|
|
29
38
|
HumanFunctionDefinition,
|
|
30
39
|
}
|
|
31
40
|
|
|
41
|
+
// Re-export Action so consumers can see the supertype
|
|
42
|
+
export type { Action }
|
|
43
|
+
|
|
32
44
|
// ============================================================================
|
|
33
45
|
// Task Status and Priority
|
|
34
46
|
// ============================================================================
|
|
@@ -37,15 +49,15 @@ export type {
|
|
|
37
49
|
* Task lifecycle status
|
|
38
50
|
*/
|
|
39
51
|
export type TaskStatus =
|
|
40
|
-
| 'pending'
|
|
41
|
-
| 'queued'
|
|
42
|
-
| 'assigned'
|
|
43
|
-
| 'in_progress'
|
|
44
|
-
| 'blocked'
|
|
45
|
-
| 'review'
|
|
46
|
-
| 'completed'
|
|
47
|
-
| 'failed'
|
|
48
|
-
| 'cancelled'
|
|
52
|
+
| 'pending' // Created but not started
|
|
53
|
+
| 'queued' // In queue waiting for worker
|
|
54
|
+
| 'assigned' // Assigned to a worker
|
|
55
|
+
| 'in_progress' // Being worked on
|
|
56
|
+
| 'blocked' // Waiting on dependency
|
|
57
|
+
| 'review' // Awaiting review
|
|
58
|
+
| 'completed' // Successfully finished
|
|
59
|
+
| 'failed' // Failed with error
|
|
60
|
+
| 'cancelled' // Cancelled
|
|
49
61
|
|
|
50
62
|
/**
|
|
51
63
|
* Task priority levels
|
|
@@ -89,11 +101,11 @@ export interface TaskAssignment {
|
|
|
89
101
|
* Dependency type
|
|
90
102
|
*/
|
|
91
103
|
export type DependencyType =
|
|
92
|
-
| 'blocks'
|
|
93
|
-
| 'blocked_by'
|
|
94
|
-
| 'related_to'
|
|
95
|
-
| 'parent'
|
|
96
|
-
| 'child'
|
|
104
|
+
| 'blocks' // This task blocks another
|
|
105
|
+
| 'blocked_by' // This task is blocked by another
|
|
106
|
+
| 'related_to' // Related but not blocking
|
|
107
|
+
| 'parent' // Parent task
|
|
108
|
+
| 'child' // Child subtask
|
|
97
109
|
|
|
98
110
|
/**
|
|
99
111
|
* Task dependency
|
|
@@ -125,7 +137,17 @@ export interface TaskProgress {
|
|
|
125
137
|
*/
|
|
126
138
|
export interface TaskEvent {
|
|
127
139
|
id: string
|
|
128
|
-
type:
|
|
140
|
+
type:
|
|
141
|
+
| 'created'
|
|
142
|
+
| 'assigned'
|
|
143
|
+
| 'started'
|
|
144
|
+
| 'progress'
|
|
145
|
+
| 'blocked'
|
|
146
|
+
| 'unblocked'
|
|
147
|
+
| 'completed'
|
|
148
|
+
| 'failed'
|
|
149
|
+
| 'cancelled'
|
|
150
|
+
| 'comment'
|
|
129
151
|
timestamp: Date
|
|
130
152
|
actor?: WorkerRef
|
|
131
153
|
data?: unknown
|
|
@@ -133,23 +155,101 @@ export interface TaskEvent {
|
|
|
133
155
|
}
|
|
134
156
|
|
|
135
157
|
// ============================================================================
|
|
136
|
-
//
|
|
158
|
+
// Comments (issue-shaped child Actions)
|
|
137
159
|
// ============================================================================
|
|
138
160
|
|
|
139
161
|
/**
|
|
140
|
-
*
|
|
162
|
+
* Comment - a thin wrapper around a comment posted on a Task.
|
|
141
163
|
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
164
|
+
* Per the SVO co-design, comments are child Actions of verb 'commented'
|
|
165
|
+
* whose `cause` role points back at the parent Task's Action id. This
|
|
166
|
+
* shape is the surfaced view of such an Action for issue-shaped UIs.
|
|
144
167
|
*/
|
|
145
|
-
export interface
|
|
146
|
-
/**
|
|
168
|
+
export interface Comment {
|
|
169
|
+
/** Comment id (matches the underlying Action id when persisted) */
|
|
147
170
|
id: string
|
|
171
|
+
/** Markdown body of the comment */
|
|
172
|
+
body: string
|
|
173
|
+
/** Who posted the comment */
|
|
174
|
+
author?: WorkerRef
|
|
175
|
+
/** When the comment was posted */
|
|
176
|
+
createdAt: Date
|
|
177
|
+
}
|
|
148
178
|
|
|
149
|
-
|
|
150
|
-
|
|
179
|
+
// ============================================================================
|
|
180
|
+
// Core Task Interface
|
|
181
|
+
// ============================================================================
|
|
151
182
|
|
|
152
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Task = Action + issue-shaped metadata
|
|
185
|
+
*
|
|
186
|
+
* A Task is a specialization of `digital-objects.Action` carrying
|
|
187
|
+
* project-management overlay (title, body, comments, labels,
|
|
188
|
+
* dependencies, assignees, milestone/project). The Action supertype
|
|
189
|
+
* provides id/verb/subject/object/roles/data/createdAt/completedAt.
|
|
190
|
+
*
|
|
191
|
+
* Status: Action's status taxonomy is lifecycle-only
|
|
192
|
+
* (pending/active/completed/failed/cancelled). Task's status taxonomy
|
|
193
|
+
* is project-management shaped (queued/assigned/in_progress/blocked/
|
|
194
|
+
* review/...). We omit Action's `status` and replace it with the
|
|
195
|
+
* Task-specific `TaskStatus`. Both supersets share `pending`,
|
|
196
|
+
* `completed`, `failed`, `cancelled`.
|
|
197
|
+
*
|
|
198
|
+
* Verb: every Task is an Action of some Verb. For tasks created via
|
|
199
|
+
* the legacy `createTask({ function })` path, `verb` defaults to the
|
|
200
|
+
* function's name (e.g. `'summarize'`).
|
|
201
|
+
*
|
|
202
|
+
* Backward compatibility: all previously-valid Task shapes remain
|
|
203
|
+
* assignable. Newly added fields (title/body/labels/project/assignees/
|
|
204
|
+
* comments/$type/verb) are optional or have defaults populated by
|
|
205
|
+
* `createTask`.
|
|
206
|
+
*/
|
|
207
|
+
export type Task<TInput = unknown, TOutput = unknown> = Omit<Action<TInput>, 'status'> & {
|
|
208
|
+
/** MDXLD type discriminator */
|
|
209
|
+
$type?: 'Task'
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* The Tool (callable Verb) this task executes. This is the canonical
|
|
213
|
+
* field per CONTEXT.md. `createTask` always populates `tool`; the
|
|
214
|
+
* legacy `function` alias is also populated during the deprecation
|
|
215
|
+
* window so existing readers keep working.
|
|
216
|
+
*
|
|
217
|
+
* Optional on the type so that older literals constructed with only
|
|
218
|
+
* `function` still typecheck; in practice every Task has exactly one
|
|
219
|
+
* underlying callable Verb available via `task.tool ?? task.function`.
|
|
220
|
+
*/
|
|
221
|
+
tool?: FunctionDefinition<TInput, TOutput>
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Legacy alias for `tool`.
|
|
225
|
+
*
|
|
226
|
+
* @deprecated Use `tool` instead. The canonical name for callable
|
|
227
|
+
* Verbs is **Tool** (see CONTEXT.md). `createTask` continues to
|
|
228
|
+
* populate this alongside `tool` for the duration of the deprecation
|
|
229
|
+
* window. Slated for removal in the next major version.
|
|
230
|
+
*/
|
|
231
|
+
function?: FunctionDefinition<TInput, TOutput>
|
|
232
|
+
|
|
233
|
+
/** Issue title (short, single-line) */
|
|
234
|
+
title?: string
|
|
235
|
+
|
|
236
|
+
/** Rich markdown body / description */
|
|
237
|
+
body?: string
|
|
238
|
+
|
|
239
|
+
/** GitHub-issue-shaped labels */
|
|
240
|
+
labels?: string[]
|
|
241
|
+
|
|
242
|
+
/** Milestone or project reference (string ref; cf. `projectId` for
|
|
243
|
+
* the durable internal id when a `Project` exists in this package). */
|
|
244
|
+
project?: string
|
|
245
|
+
|
|
246
|
+
/** Comments posted on this task (child Actions of verb 'commented') */
|
|
247
|
+
comments?: Comment[]
|
|
248
|
+
|
|
249
|
+
/** Workers assigned to this task */
|
|
250
|
+
assignees?: WorkerRef[]
|
|
251
|
+
|
|
252
|
+
/** Current task status (specialization — see jsdoc above) */
|
|
153
253
|
status: TaskStatus
|
|
154
254
|
|
|
155
255
|
/** Priority level */
|
|
@@ -166,10 +266,10 @@ export interface Task<TInput = unknown, TOutput = unknown> {
|
|
|
166
266
|
error?: string
|
|
167
267
|
|
|
168
268
|
// Assignment
|
|
169
|
-
/**
|
|
269
|
+
/** Worker types permitted to claim this task */
|
|
170
270
|
allowedWorkers?: WorkerType[]
|
|
171
271
|
|
|
172
|
-
/** Current assignment */
|
|
272
|
+
/** Current assignment (single primary worker) */
|
|
173
273
|
assignment?: TaskAssignment
|
|
174
274
|
|
|
175
275
|
// Dependencies
|
|
@@ -181,9 +281,6 @@ export interface Task<TInput = unknown, TOutput = unknown> {
|
|
|
181
281
|
progress?: TaskProgress
|
|
182
282
|
|
|
183
283
|
// Timing
|
|
184
|
-
/** When created */
|
|
185
|
-
createdAt: Date
|
|
186
|
-
|
|
187
284
|
/** Scheduled start time */
|
|
188
285
|
scheduledFor?: Date
|
|
189
286
|
|
|
@@ -193,9 +290,6 @@ export interface Task<TInput = unknown, TOutput = unknown> {
|
|
|
193
290
|
/** When started */
|
|
194
291
|
startedAt?: Date
|
|
195
292
|
|
|
196
|
-
/** When completed */
|
|
197
|
-
completedAt?: Date
|
|
198
|
-
|
|
199
293
|
/** Timeout in ms */
|
|
200
294
|
timeout?: number
|
|
201
295
|
|
|
@@ -203,7 +297,8 @@ export interface Task<TInput = unknown, TOutput = unknown> {
|
|
|
203
297
|
/** Parent task ID */
|
|
204
298
|
parentId?: string
|
|
205
299
|
|
|
206
|
-
/** Project ID
|
|
300
|
+
/** Project ID (internal `Project.id` when this Task belongs to a
|
|
301
|
+
* Project in this package; distinct from `project` ref string) */
|
|
207
302
|
projectId?: string
|
|
208
303
|
|
|
209
304
|
// Metadata
|
|
@@ -217,6 +312,18 @@ export interface Task<TInput = unknown, TOutput = unknown> {
|
|
|
217
312
|
events?: TaskEvent[]
|
|
218
313
|
}
|
|
219
314
|
|
|
315
|
+
/**
|
|
316
|
+
* Task dependency tuple — minimal shape from the SVO design doc.
|
|
317
|
+
*
|
|
318
|
+
* `TaskDependency` (above) is the richer in-package shape with a
|
|
319
|
+
* full DependencyType set; `TaskDep` is the issue-shaped pair from
|
|
320
|
+
* the design doc, retained as a convenience export.
|
|
321
|
+
*/
|
|
322
|
+
export interface TaskDep {
|
|
323
|
+
taskId: string
|
|
324
|
+
type: 'blocked_by' | 'related'
|
|
325
|
+
}
|
|
326
|
+
|
|
220
327
|
/**
|
|
221
328
|
* Any task (for collections)
|
|
222
329
|
*/
|
|
@@ -231,7 +338,10 @@ export type AnyTask = Task<any, any>
|
|
|
231
338
|
* Create task from a Code function
|
|
232
339
|
*/
|
|
233
340
|
export interface CodeTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
234
|
-
function
|
|
341
|
+
/** Tool (callable Verb) to run. Preferred over `function`. */
|
|
342
|
+
tool?: CodeFunctionDefinition<TInput, TOutput>
|
|
343
|
+
/** @deprecated Use `tool` instead. */
|
|
344
|
+
function?: CodeFunctionDefinition<TInput, TOutput>
|
|
235
345
|
input?: TInput
|
|
236
346
|
priority?: TaskPriority
|
|
237
347
|
assignTo?: WorkerRef
|
|
@@ -246,7 +356,10 @@ export interface CodeTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
|
246
356
|
* Create task from a Generative function
|
|
247
357
|
*/
|
|
248
358
|
export interface GenerativeTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
249
|
-
function
|
|
359
|
+
/** Tool (callable Verb) to run. Preferred over `function`. */
|
|
360
|
+
tool?: GenerativeFunctionDefinition<TInput, TOutput>
|
|
361
|
+
/** @deprecated Use `tool` instead. */
|
|
362
|
+
function?: GenerativeFunctionDefinition<TInput, TOutput>
|
|
250
363
|
input?: TInput
|
|
251
364
|
priority?: TaskPriority
|
|
252
365
|
assignTo?: WorkerRef
|
|
@@ -261,7 +374,10 @@ export interface GenerativeTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
|
261
374
|
* Create task from an Agentic function
|
|
262
375
|
*/
|
|
263
376
|
export interface AgenticTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
264
|
-
function
|
|
377
|
+
/** Tool (callable Verb) to run. Preferred over `function`. */
|
|
378
|
+
tool?: AgenticFunctionDefinition<TInput, TOutput>
|
|
379
|
+
/** @deprecated Use `tool` instead. */
|
|
380
|
+
function?: AgenticFunctionDefinition<TInput, TOutput>
|
|
265
381
|
input?: TInput
|
|
266
382
|
priority?: TaskPriority
|
|
267
383
|
assignTo?: WorkerRef
|
|
@@ -276,7 +392,10 @@ export interface AgenticTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
|
276
392
|
* Create task from a Human function
|
|
277
393
|
*/
|
|
278
394
|
export interface HumanTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
279
|
-
function
|
|
395
|
+
/** Tool (callable Verb) to run. Preferred over `function`. */
|
|
396
|
+
tool?: HumanFunctionDefinition<TInput, TOutput>
|
|
397
|
+
/** @deprecated Use `tool` instead. */
|
|
398
|
+
function?: HumanFunctionDefinition<TInput, TOutput>
|
|
280
399
|
input?: TInput
|
|
281
400
|
priority?: TaskPriority
|
|
282
401
|
assignTo?: WorkerRef
|
|
@@ -289,13 +408,22 @@ export interface HumanTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
|
289
408
|
|
|
290
409
|
/**
|
|
291
410
|
* Generic task creation options
|
|
411
|
+
*
|
|
412
|
+
* Either `tool` (preferred) or the deprecated `function` alias must be
|
|
413
|
+
* provided. `createTask` normalizes to `tool` and also populates the
|
|
414
|
+
* legacy `function` alias on the resulting Task for backward compat.
|
|
292
415
|
*/
|
|
293
416
|
export interface CreateTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
294
|
-
function
|
|
417
|
+
/** Tool (callable Verb) to run. Preferred over `function`. */
|
|
418
|
+
tool?: FunctionDefinition<TInput, TOutput>
|
|
419
|
+
/** @deprecated Use `tool` instead. */
|
|
420
|
+
function?: FunctionDefinition<TInput, TOutput>
|
|
295
421
|
input?: TInput
|
|
296
422
|
priority?: TaskPriority
|
|
297
423
|
allowedWorkers?: WorkerType[]
|
|
298
424
|
assignTo?: WorkerRef
|
|
425
|
+
/** Multiple assignees (issue-shaped); first becomes the primary `assignment` */
|
|
426
|
+
assignees?: WorkerRef[]
|
|
299
427
|
dependencies?: string[]
|
|
300
428
|
scheduledFor?: Date
|
|
301
429
|
deadline?: Date
|
|
@@ -304,6 +432,15 @@ export interface CreateTaskOptions<TInput = unknown, TOutput = unknown> {
|
|
|
304
432
|
parentId?: string
|
|
305
433
|
projectId?: string
|
|
306
434
|
metadata?: Record<string, unknown>
|
|
435
|
+
// Issue-shaped fields (SVO co-design)
|
|
436
|
+
/** Issue title (short, single-line) */
|
|
437
|
+
title?: string
|
|
438
|
+
/** Rich markdown body / description */
|
|
439
|
+
body?: string
|
|
440
|
+
/** GitHub-issue-shaped labels */
|
|
441
|
+
labels?: string[]
|
|
442
|
+
/** Milestone or project ref string */
|
|
443
|
+
project?: string
|
|
307
444
|
}
|
|
308
445
|
|
|
309
446
|
/**
|