@xfey/tutti 0.1.60 → 0.1.61
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/dist/collaboration-state/clarification-records.d.ts +0 -9
- package/dist/collaboration-state/clarification-records.js +0 -57
- package/dist/collaboration-state/index.d.ts +6 -5
- package/dist/collaboration-state/index.js +5 -4
- package/dist/collaboration-state/messages.d.ts +4 -6
- package/dist/collaboration-state/messages.js +22 -29
- package/dist/collaboration-state/scratchpad-source-state.d.ts +4 -12
- package/dist/collaboration-state/scratchpad-source-state.js +24 -58
- package/dist/collaboration-state/scratchpad.d.ts +1 -2
- package/dist/collaboration-state/scratchpad.js +0 -59
- package/dist/collaboration-state/storage-types.d.ts +25 -5
- package/dist/collaboration-state/task-compile-context.d.ts +40 -0
- package/dist/collaboration-state/task-compile-context.js +273 -0
- package/dist/collaboration-state/types.d.ts +39 -9
- package/dist/control-plane/clarification-commands.d.ts +0 -1
- package/dist/control-plane/clarification-commands.js +0 -1
- package/dist/control-plane/index.js +16 -3
- package/dist/control-plane/project-context-bootstrap.d.ts +4 -4
- package/dist/control-plane/project-context-bootstrap.js +7 -12
- package/dist/control-plane/scratchpad-auto-refresh.js +12 -1
- package/dist/control-plane/scratchpad-refresh-start.js +77 -94
- package/dist/control-plane/scratchpad-refresh.js +3 -1
- package/dist/control-plane/scratchpad-source-messages.d.ts +15 -7
- package/dist/control-plane/scratchpad-source-messages.js +53 -69
- package/dist/control-plane/task-compile-clarification-context.d.ts +9 -0
- package/dist/control-plane/task-compile-clarification-context.js +70 -0
- package/dist/control-plane/task-compile-continuation.js +28 -56
- package/dist/control-plane/task-compile-output.js +50 -14
- package/dist/control-plane/task-compile-start.js +119 -55
- package/dist/control-plane/workflows/openai.d.ts +2 -1
- package/dist/control-plane/workflows/openai.js +13 -27
- package/dist/control-plane/workflows/types.d.ts +27 -17
- package/migrations/0014_scratchpad_task_compile_context.sql +147 -0
- package/migrations/README.md +2 -1
- package/package.json +1 -1
- package/prompts/procedures/README.md +3 -3
- package/prompts/procedures/scratchpad-refresh.md +17 -9
- package/prompts/procedures/task-compile.md +6 -3
- package/prompts/prompt-flow-map.md +21 -14
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { applyTaskCompileProposal, openNextTaskCompileClarificationRound, openTaskCompileClarificationRound,
|
|
1
|
+
import { applyTaskCompileProposal, completeTaskCompileContext, materializeClarificationSuccessor, openNextTaskCompileClarificationRound, openTaskCompileClarificationRound, readClarificationRoundProjection, readWorklistProjection, } from "../collaboration-state/index.js";
|
|
2
|
+
import { withHostStoreTransaction } from "../store/index.js";
|
|
2
3
|
import { clarificationInvalidates, taskCompileInvalidates, } from "./invalidations.js";
|
|
3
4
|
import { normalizeTaskCompileProposal } from "./task-proposal.js";
|
|
4
5
|
const EMPTY_INITIAL_WORKLIST_CLARIFICATION = {
|
|
@@ -72,25 +73,45 @@ export function applyTaskCompileProcedureOutput(input) {
|
|
|
72
73
|
}
|
|
73
74
|
const currentWorklist = readWorklistProjection(input.store.db);
|
|
74
75
|
const proposal = normalizeTaskCompileProposal(input.output.proposal);
|
|
75
|
-
if (
|
|
76
|
+
if (input.continueFromRoundId === undefined &&
|
|
77
|
+
proposal.tasks.length === 0 &&
|
|
78
|
+
countWorklistTasks(currentWorklist) === 0) {
|
|
76
79
|
return openTaskCompileNeedsHuman({
|
|
77
80
|
...input,
|
|
78
81
|
requestPayload: EMPTY_INITIAL_WORKLIST_CLARIFICATION,
|
|
79
82
|
});
|
|
80
83
|
}
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
const continuationRound = input.continueFromRoundId === undefined
|
|
85
|
+
? null
|
|
86
|
+
: readClarificationRoundProjection(input.store.db, input.continueFromRoundId);
|
|
87
|
+
const committed = withHostStoreTransaction(input.store.db, (tx) => {
|
|
88
|
+
const applied = applyTaskCompileProposal(tx, {
|
|
89
|
+
workflow_ref: input.workflowRef,
|
|
90
|
+
proposal,
|
|
91
|
+
now: input.now,
|
|
92
|
+
});
|
|
93
|
+
const scratchpad = completeTaskCompileContext(tx, {
|
|
94
|
+
workflow_ref: input.workflowRef,
|
|
95
|
+
activity_ref: input.activityRef,
|
|
96
|
+
now: input.now,
|
|
97
|
+
});
|
|
98
|
+
if (input.continueFromRoundId !== undefined) {
|
|
99
|
+
materializeClarificationSuccessor(tx, {
|
|
100
|
+
round_id: input.continueFromRoundId,
|
|
101
|
+
successor_ref: {
|
|
102
|
+
kind: "proposal_applied",
|
|
103
|
+
workflow_ref: input.workflowRef,
|
|
104
|
+
},
|
|
105
|
+
close_thread: true,
|
|
106
|
+
now: input.now,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return { applied, scratchpad };
|
|
85
110
|
});
|
|
111
|
+
const { applied } = committed;
|
|
86
112
|
if (applied.changed_task_ids.length > 0) {
|
|
87
113
|
input.onTasksAdded?.();
|
|
88
114
|
}
|
|
89
|
-
const submittedScratchpad = submitScratchpadProjection(input.store.db, {
|
|
90
|
-
workflow_ref: input.workflowRef,
|
|
91
|
-
activity_ref: input.activityRef,
|
|
92
|
-
now: input.now,
|
|
93
|
-
});
|
|
94
115
|
input.events.publish({
|
|
95
116
|
event_type: "worklist.changed",
|
|
96
117
|
payload: {
|
|
@@ -105,21 +126,36 @@ export function applyTaskCompileProcedureOutput(input) {
|
|
|
105
126
|
input.events.publish({
|
|
106
127
|
event_type: "scratchpad.updated",
|
|
107
128
|
payload: {
|
|
108
|
-
scratchpad:
|
|
129
|
+
scratchpad: committed.scratchpad,
|
|
109
130
|
activity_ref: input.activityRef,
|
|
110
131
|
},
|
|
111
132
|
invalidates: taskCompileInvalidates(),
|
|
112
133
|
});
|
|
134
|
+
if (input.continueFromRoundId !== undefined && continuationRound !== null) {
|
|
135
|
+
input.events.publish({
|
|
136
|
+
event_type: "clarification.changed",
|
|
137
|
+
payload: {
|
|
138
|
+
reason: "successor_materialized",
|
|
139
|
+
thread_id: continuationRound.thread_id,
|
|
140
|
+
round_id: input.continueFromRoundId,
|
|
141
|
+
successor_ref: {
|
|
142
|
+
kind: "proposal_applied",
|
|
143
|
+
workflow_ref: input.workflowRef,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
invalidates: clarificationInvalidates(input.continueFromRoundId, continuationRound.thread_id),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
113
149
|
if (input.continueFromRoundId !== undefined) {
|
|
114
150
|
return {
|
|
115
151
|
kind: "completed",
|
|
116
|
-
summary: "Worklist compiled.",
|
|
152
|
+
summary: proposal.tasks.length === 0 ? "No new task created." : "Worklist compiled.",
|
|
117
153
|
result_anchor: { kind: "workflow", workflow_ref: input.workflowRef },
|
|
118
154
|
};
|
|
119
155
|
}
|
|
120
156
|
return {
|
|
121
157
|
kind: "completed",
|
|
122
|
-
summary: "Worklist compiled.",
|
|
158
|
+
summary: proposal.tasks.length === 0 ? "No new task created." : "Worklist compiled.",
|
|
123
159
|
result_anchor: { kind: "workflow", workflow_ref: input.workflowRef },
|
|
124
160
|
};
|
|
125
161
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createWorkflowInvocationRef, } from "@tutti/shared/ids";
|
|
2
|
-
import { readScratchpadProjection, readWorklistProjection } from "../collaboration-state/index.js";
|
|
2
|
+
import { captureTaskCompileContext, readActiveTaskCompileContext, readScratchpadProjection, readWorklistProjection, rollbackTaskCompileContext, } from "../collaboration-state/index.js";
|
|
3
3
|
import { initializeProjectDocs, readProjectDocsInitializationStatus, } from "../workspace-ops/index.js";
|
|
4
4
|
import { logProcedureExecutionError } from "./procedure-logging.js";
|
|
5
5
|
import { projectBriefShouldRefreshForUpdatedPaths, refreshProjectBriefProjection, } from "./project-brief-refresh.js";
|
|
@@ -7,6 +7,15 @@ import { applyProjectDocsInitializationResult, buildProjectDocsInitializationCon
|
|
|
7
7
|
import { readActiveScratchpadRefreshActivityRef, readControlPlaneScratchpadSourceBatch, runControlPlaneScratchpadRefreshProcedure, } from "./scratchpad-refresh-start.js";
|
|
8
8
|
import { applyTaskCompileProcedureOutput } from "./task-compile-output.js";
|
|
9
9
|
export function startControlPlaneTaskCompile(options) {
|
|
10
|
+
const activeContext = readActiveTaskCompileContext(options.store.db);
|
|
11
|
+
if (activeContext !== null) {
|
|
12
|
+
return {
|
|
13
|
+
disposition: {
|
|
14
|
+
kind: "already_running",
|
|
15
|
+
activity_ref: activeContext.captured_by_activity_ref,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
10
19
|
const scratchpad = readScratchpadProjection(options.store.db);
|
|
11
20
|
if (options.payload.expected_scratchpad_updated_at !== undefined &&
|
|
12
21
|
options.payload.expected_scratchpad_updated_at !== scratchpad.updated_at) {
|
|
@@ -31,6 +40,7 @@ export function startControlPlaneTaskCompile(options) {
|
|
|
31
40
|
},
|
|
32
41
|
};
|
|
33
42
|
}
|
|
43
|
+
const taskCompileWorkflowRef = createWorkflowInvocationRef();
|
|
34
44
|
const sourceBatch = readControlPlaneScratchpadSourceBatch(options.store);
|
|
35
45
|
if (sourceBatch.source_message_count > 0) {
|
|
36
46
|
const activeScratchpadRefresh = readActiveScratchpadRefreshActivityRef({
|
|
@@ -49,6 +59,7 @@ export function startControlPlaneTaskCompile(options) {
|
|
|
49
59
|
...options,
|
|
50
60
|
runner: runnerResolution.runner,
|
|
51
61
|
sourceBatch,
|
|
62
|
+
taskCompileWorkflowRef,
|
|
52
63
|
});
|
|
53
64
|
}
|
|
54
65
|
if (!scratchpadHasSubmittableContent(scratchpad)) {
|
|
@@ -58,19 +69,23 @@ export function startControlPlaneTaskCompile(options) {
|
|
|
58
69
|
return startProjectContextBootstrapActivity({
|
|
59
70
|
...options,
|
|
60
71
|
runner: runnerResolution.runner,
|
|
72
|
+
taskCompileWorkflowRef,
|
|
61
73
|
});
|
|
62
74
|
}
|
|
63
75
|
return startControlPlaneTaskCompileActivity({
|
|
64
76
|
...options,
|
|
65
77
|
runner: runnerResolution.runner,
|
|
78
|
+
taskCompileWorkflowRef,
|
|
66
79
|
});
|
|
67
80
|
}
|
|
68
81
|
function startControlPlaneTaskCompileActivity(options) {
|
|
82
|
+
const activeContext = readActiveTaskCompileContext(options.store.db, options.taskCompileWorkflowRef);
|
|
69
83
|
const scratchpad = readScratchpadProjection(options.store.db);
|
|
70
|
-
if (
|
|
84
|
+
if (activeContext === null &&
|
|
85
|
+
!scratchpadHasSubmittableContent(scratchpad)) {
|
|
71
86
|
return { disposition: { kind: "scratchpad_empty" } };
|
|
72
87
|
}
|
|
73
|
-
const workflowRef =
|
|
88
|
+
const workflowRef = options.taskCompileWorkflowRef;
|
|
74
89
|
const start = options.engine.startProcedure({
|
|
75
90
|
workflow_ref: workflowRef,
|
|
76
91
|
workflow_kind: "task_compile",
|
|
@@ -201,8 +216,7 @@ function startProjectContextBootstrapActivity(options) {
|
|
|
201
216
|
if (shouldInitializeControlPlaneProjectContext(options)) {
|
|
202
217
|
return;
|
|
203
218
|
}
|
|
204
|
-
|
|
205
|
-
if (!scratchpadHasSubmittableContent(scratchpad)) {
|
|
219
|
+
if (readActiveTaskCompileContext(options.store.db, options.taskCompileWorkflowRef) === null) {
|
|
206
220
|
return;
|
|
207
221
|
}
|
|
208
222
|
void startControlPlaneTaskCompileActivity(options);
|
|
@@ -221,44 +235,59 @@ function startProjectContextBootstrapActivity(options) {
|
|
|
221
235
|
summary: "Project context is unavailable.",
|
|
222
236
|
};
|
|
223
237
|
}
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
projectContext: options.projectContext,
|
|
228
|
-
scratchpad: readScratchpadProjection(options.store.db),
|
|
229
|
-
projectName: options.projectContext.projectName,
|
|
230
|
-
workflowRef,
|
|
238
|
+
const taskCompileContext = readOrCaptureTaskCompileContext({
|
|
239
|
+
store: options.store,
|
|
240
|
+
workflowRef: options.taskCompileWorkflowRef,
|
|
231
241
|
activityRef: context.activity_ref,
|
|
232
|
-
logger: options.logger,
|
|
233
|
-
reportProgress: context.reportProgress,
|
|
234
|
-
now: options.now,
|
|
235
|
-
});
|
|
236
|
-
const initialized = initializeProjectDocs({
|
|
237
|
-
workspaceRoot: options.projectContext.workspaceRoot,
|
|
238
|
-
projectName: options.projectContext.projectName,
|
|
239
|
-
context: initializationContext,
|
|
240
|
-
...(modelDocuments === undefined ? {} : { documents: modelDocuments }),
|
|
241
242
|
now: options.now,
|
|
242
243
|
});
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
projectContext: options.projectContext,
|
|
247
|
-
reason: "project_context_bootstrap",
|
|
244
|
+
try {
|
|
245
|
+
const initializationContext = buildProjectDocsInitializationContext(taskCompileContext.scratchpad_snapshot);
|
|
246
|
+
const modelDocuments = await tryProjectContextBootstrapDocuments({
|
|
248
247
|
runner: options.runner,
|
|
248
|
+
projectContext: options.projectContext,
|
|
249
|
+
scratchpad: taskCompileContext.scratchpad_snapshot,
|
|
250
|
+
projectName: options.projectContext.projectName,
|
|
249
251
|
workflowRef,
|
|
250
252
|
activityRef: context.activity_ref,
|
|
251
253
|
logger: options.logger,
|
|
254
|
+
reportProgress: context.reportProgress,
|
|
255
|
+
now: options.now,
|
|
256
|
+
});
|
|
257
|
+
const initialized = initializeProjectDocs({
|
|
258
|
+
workspaceRoot: options.projectContext.workspaceRoot,
|
|
259
|
+
projectName: options.projectContext.projectName,
|
|
260
|
+
context: initializationContext,
|
|
261
|
+
...(modelDocuments === undefined ? {} : { documents: modelDocuments }),
|
|
262
|
+
now: options.now,
|
|
263
|
+
});
|
|
264
|
+
if (projectBriefShouldRefreshForUpdatedPaths(initialized.created_paths)) {
|
|
265
|
+
await refreshProjectBriefProjection({
|
|
266
|
+
store: options.store,
|
|
267
|
+
projectContext: options.projectContext,
|
|
268
|
+
reason: "project_context_bootstrap",
|
|
269
|
+
runner: options.runner,
|
|
270
|
+
workflowRef,
|
|
271
|
+
activityRef: context.activity_ref,
|
|
272
|
+
logger: options.logger,
|
|
273
|
+
now: options.now,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
return applyProjectDocsInitializationResult({
|
|
277
|
+
events: options.events,
|
|
278
|
+
logger: options.logger,
|
|
279
|
+
result: initialized,
|
|
280
|
+
workflowRef,
|
|
281
|
+
activityRef: context.activity_ref,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
rollbackTaskCompileContext(options.store.db, {
|
|
286
|
+
workflow_ref: options.taskCompileWorkflowRef,
|
|
252
287
|
now: options.now,
|
|
253
288
|
});
|
|
289
|
+
throw error;
|
|
254
290
|
}
|
|
255
|
-
return applyProjectDocsInitializationResult({
|
|
256
|
-
events: options.events,
|
|
257
|
-
logger: options.logger,
|
|
258
|
-
result: initialized,
|
|
259
|
-
workflowRef,
|
|
260
|
-
activityRef: context.activity_ref,
|
|
261
|
-
});
|
|
262
291
|
},
|
|
263
292
|
});
|
|
264
293
|
if (start.kind === "already_running") {
|
|
@@ -278,33 +307,59 @@ function startProjectContextBootstrapActivity(options) {
|
|
|
278
307
|
};
|
|
279
308
|
}
|
|
280
309
|
export async function runControlPlaneTaskCompileProcedure(options) {
|
|
281
|
-
const
|
|
282
|
-
if (!scratchpadHasSubmittableContent(scratchpad)) {
|
|
283
|
-
return {
|
|
284
|
-
kind: "failed",
|
|
285
|
-
summary: "Scratchpad is empty. Discuss more before running.",
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
const output = await options.runner.runTaskCompile({
|
|
289
|
-
workflow_ref: options.workflowRef,
|
|
290
|
-
scratchpad,
|
|
291
|
-
worklist: readWorklistProjection(options.store.db),
|
|
292
|
-
}, {
|
|
293
|
-
workflow_ref: options.workflowRef,
|
|
294
|
-
activity_ref: options.activityRef,
|
|
295
|
-
...(options.reportProgress === undefined
|
|
296
|
-
? {}
|
|
297
|
-
: { reportProgress: options.reportProgress }),
|
|
298
|
-
});
|
|
299
|
-
return applyTaskCompileProcedureOutput({
|
|
310
|
+
const context = readOrCaptureTaskCompileContext({
|
|
300
311
|
store: options.store,
|
|
301
|
-
events: options.events,
|
|
302
|
-
output,
|
|
303
312
|
workflowRef: options.workflowRef,
|
|
304
313
|
activityRef: options.activityRef,
|
|
305
314
|
now: options.now,
|
|
306
|
-
onTasksAdded: options.onTasksAdded,
|
|
307
315
|
});
|
|
316
|
+
if (!scratchpadSnapshotHasSubmittableContent(context.scratchpad_snapshot)) {
|
|
317
|
+
rollbackTaskCompileContext(options.store.db, {
|
|
318
|
+
workflow_ref: options.workflowRef,
|
|
319
|
+
now: options.now,
|
|
320
|
+
});
|
|
321
|
+
return {
|
|
322
|
+
kind: "failed",
|
|
323
|
+
summary: "Scratchpad is empty. Discuss more before running.",
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
try {
|
|
327
|
+
const output = await options.runner.runTaskCompile({
|
|
328
|
+
workflow_ref: options.workflowRef,
|
|
329
|
+
scratchpad: context.scratchpad_snapshot,
|
|
330
|
+
worklist: readWorklistProjection(options.store.db),
|
|
331
|
+
}, {
|
|
332
|
+
workflow_ref: options.workflowRef,
|
|
333
|
+
activity_ref: options.activityRef,
|
|
334
|
+
...(options.reportProgress === undefined
|
|
335
|
+
? {}
|
|
336
|
+
: { reportProgress: options.reportProgress }),
|
|
337
|
+
});
|
|
338
|
+
return applyTaskCompileProcedureOutput({
|
|
339
|
+
store: options.store,
|
|
340
|
+
events: options.events,
|
|
341
|
+
output,
|
|
342
|
+
workflowRef: options.workflowRef,
|
|
343
|
+
activityRef: options.activityRef,
|
|
344
|
+
now: options.now,
|
|
345
|
+
onTasksAdded: options.onTasksAdded,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
rollbackTaskCompileContext(options.store.db, {
|
|
350
|
+
workflow_ref: options.workflowRef,
|
|
351
|
+
now: options.now,
|
|
352
|
+
});
|
|
353
|
+
throw error;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function readOrCaptureTaskCompileContext(input) {
|
|
357
|
+
return (readActiveTaskCompileContext(input.store.db, input.workflowRef) ??
|
|
358
|
+
captureTaskCompileContext(input.store.db, {
|
|
359
|
+
workflow_ref: input.workflowRef,
|
|
360
|
+
captured_by_activity_ref: input.activityRef,
|
|
361
|
+
now: input.now,
|
|
362
|
+
}));
|
|
308
363
|
}
|
|
309
364
|
function scratchpadHasSubmittableContent(scratchpad) {
|
|
310
365
|
if (scratchpad.state !== "ready") {
|
|
@@ -318,4 +373,13 @@ function scratchpadHasSubmittableContent(scratchpad) {
|
|
|
318
373
|
...scratchpad.task_changes,
|
|
319
374
|
].some((item) => item.trim().length > 0);
|
|
320
375
|
}
|
|
376
|
+
function scratchpadSnapshotHasSubmittableContent(scratchpad) {
|
|
377
|
+
return [
|
|
378
|
+
scratchpad.topic,
|
|
379
|
+
scratchpad.background_summary,
|
|
380
|
+
...scratchpad.current_consensus,
|
|
381
|
+
...scratchpad.open_questions,
|
|
382
|
+
...scratchpad.task_changes,
|
|
383
|
+
].some((item) => item.trim().length > 0);
|
|
384
|
+
}
|
|
321
385
|
//# sourceMappingURL=task-compile-start.js.map
|
|
@@ -2,7 +2,7 @@ import type { ProjectId } from "@tutti/shared/ids";
|
|
|
2
2
|
import type { ProviderUsageRecorder } from "../../provider-usage/index.js";
|
|
3
3
|
import { type OpenAiStructuredOutputClient } from "../../providers/openai/sdk-procedure-runner.js";
|
|
4
4
|
import { type OpenAiProviderConfig } from "../../providers/openai/provider-config.js";
|
|
5
|
-
import type { ProcedureWorkflowRunner, ProcedureWorkflowRunnerResolution } from "./types.js";
|
|
5
|
+
import type { ProcedureWorkflowRunner, ProcedureWorkflowRunnerResolution, TaskCompilePromptInput, TaskCompileWorkflowInput } from "./types.js";
|
|
6
6
|
import type { CodexAppServerAgentContextRuntime } from "../../providers/openai/app-server/skills.js";
|
|
7
7
|
export type OpenAiProcedureWorkflowRunnerOptions = {
|
|
8
8
|
config: OpenAiProviderConfig;
|
|
@@ -30,6 +30,7 @@ export type ProjectOpenAiProcedureWorkflowRunnerOptions = {
|
|
|
30
30
|
agentContext?: CodexAppServerAgentContextRuntime;
|
|
31
31
|
recordUsage?: ProviderUsageRecorder;
|
|
32
32
|
};
|
|
33
|
+
export declare function buildTaskCompilePromptInput(input: TaskCompileWorkflowInput): TaskCompilePromptInput;
|
|
33
34
|
export declare function createOpenAiProcedureWorkflowRunner(options: OpenAiProcedureWorkflowRunnerOptions): ProcedureWorkflowRunner;
|
|
34
35
|
export declare function resolveProjectOpenAiProcedureWorkflowRunner(options: ProjectOpenAiProcedureWorkflowRunnerOptions): ProcedureWorkflowRunnerResolution;
|
|
35
36
|
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -137,7 +137,7 @@ function followUpCheckWorkflowOutput(output) {
|
|
|
137
137
|
summary: output.result.requires_retasking.summary,
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
|
-
function
|
|
140
|
+
export function buildTaskCompilePromptInput(input) {
|
|
141
141
|
const promptInput = {
|
|
142
142
|
scratchpad: {
|
|
143
143
|
topic: input.scratchpad.topic,
|
|
@@ -160,34 +160,20 @@ function taskCompilePromptInput(input) {
|
|
|
160
160
|
})),
|
|
161
161
|
},
|
|
162
162
|
};
|
|
163
|
-
if (input.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
.filter((message) => message.message_kind === "user_text" || message.message_kind === "agent_text")
|
|
175
|
-
.map(taskCompileClarificationMessage),
|
|
176
|
-
};
|
|
163
|
+
if (input.clarification_rounds !== undefined) {
|
|
164
|
+
promptInput.clarification_rounds = input.clarification_rounds.map((round) => ({
|
|
165
|
+
request: {
|
|
166
|
+
...(round.request_payload.title === undefined
|
|
167
|
+
? {}
|
|
168
|
+
: { title: round.request_payload.title }),
|
|
169
|
+
summary: round.request_payload.summary,
|
|
170
|
+
request: round.request_payload.request,
|
|
171
|
+
},
|
|
172
|
+
answer_messages: round.answer_messages,
|
|
173
|
+
}));
|
|
177
174
|
}
|
|
178
175
|
return promptInput;
|
|
179
176
|
}
|
|
180
|
-
function taskCompileClarificationMessage(message) {
|
|
181
|
-
const role = message.author.kind === "agent" ? "tutti" : "human";
|
|
182
|
-
const authorDisplayName = message.author.display_name?.trim();
|
|
183
|
-
return {
|
|
184
|
-
role,
|
|
185
|
-
...(role === "human" && authorDisplayName !== undefined && authorDisplayName !== ""
|
|
186
|
-
? { author_display_name: authorDisplayName }
|
|
187
|
-
: {}),
|
|
188
|
-
text: message.body.trim(),
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
177
|
function taskCompileWorkflowOutput(output) {
|
|
192
178
|
if ("clarification_request_payload" in output.result) {
|
|
193
179
|
return {
|
|
@@ -280,7 +266,7 @@ export function createOpenAiProcedureWorkflowRunner(options) {
|
|
|
280
266
|
templateKey: "procedures.task_compile",
|
|
281
267
|
...(options.promptsRoot === undefined ? {} : { promptsRoot: options.promptsRoot }),
|
|
282
268
|
variables: {
|
|
283
|
-
workflow_input_json:
|
|
269
|
+
workflow_input_json: buildTaskCompilePromptInput(input),
|
|
284
270
|
},
|
|
285
271
|
});
|
|
286
272
|
const result = await runCodexAppServerReadOnlyProcedure({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExecutionRuntimeSnapshot, MessageProjection, RunResultProjection,
|
|
1
|
+
import type { ExecutionRuntimeSnapshot, MessageProjection, RunResultProjection, TaskDetailProjection, WorklistProjection } from "@tutti/shared/schemas/api";
|
|
2
2
|
import type { ClarificationRequestPayload, TaskContractProjection } from "@tutti/shared/schemas/api";
|
|
3
3
|
import type { ProjectDocKey } from "@tutti/shared/schemas/api";
|
|
4
4
|
import type { ActivityRef, ClarificationRoundRef, ClarificationThreadRef, MessageId, TaskId, TaskModuleId, WorkflowInvocationRef } from "@tutti/shared/ids";
|
|
@@ -6,21 +6,31 @@ import type { RunLineage } from "@tutti/shared/domain";
|
|
|
6
6
|
import type { ProjectBriefSnapshot, ProjectBriefSourceDocument } from "../../project-brief/index.js";
|
|
7
7
|
export type ScratchpadRefreshWorkflowInput = {
|
|
8
8
|
project_brief?: ProjectBriefSnapshot;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
worklist: ScratchpadRefreshWorklistInput;
|
|
10
|
+
active_task_compile?: ScratchpadWorkflowSnapshot;
|
|
11
|
+
messages: ScratchpadRefreshSourceMessageInput[];
|
|
12
|
+
};
|
|
13
|
+
export type ScratchpadWorkflowSnapshot = {
|
|
14
|
+
topic: string;
|
|
15
|
+
background_summary: string;
|
|
16
|
+
current_consensus: string[];
|
|
17
|
+
open_questions: string[];
|
|
18
|
+
task_changes: string[];
|
|
19
|
+
};
|
|
20
|
+
export type ScratchpadRefreshWorklistInput = {
|
|
21
|
+
modules: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
tasks: Array<{
|
|
24
|
+
title: string;
|
|
25
|
+
summary?: string;
|
|
26
|
+
status: WorklistProjection["modules"][number]["tasks"][number]["status"];
|
|
27
|
+
}>;
|
|
28
|
+
}>;
|
|
18
29
|
};
|
|
19
30
|
export type ScratchpadRefreshSourceMessageInput = {
|
|
20
31
|
role: "human" | "tutti";
|
|
21
32
|
author_display_name?: string;
|
|
22
33
|
text: string;
|
|
23
|
-
ref?: string;
|
|
24
34
|
};
|
|
25
35
|
export type ScratchpadRefreshWorkflowContext = {
|
|
26
36
|
workflow_ref: WorkflowInvocationRef;
|
|
@@ -68,12 +78,12 @@ export type TaskCompileProposalTask = {
|
|
|
68
78
|
};
|
|
69
79
|
export type TaskCompileWorkflowInput = {
|
|
70
80
|
workflow_ref: WorkflowInvocationRef;
|
|
71
|
-
scratchpad:
|
|
81
|
+
scratchpad: ScratchpadWorkflowSnapshot;
|
|
72
82
|
worklist: WorklistProjection;
|
|
73
|
-
|
|
83
|
+
clarification_rounds?: Array<{
|
|
74
84
|
request_payload: ClarificationRequestPayload;
|
|
75
|
-
|
|
76
|
-
}
|
|
85
|
+
answer_messages: TaskCompilePromptClarificationMessage[];
|
|
86
|
+
}>;
|
|
77
87
|
};
|
|
78
88
|
export type TaskCompileWorkflowOutput = {
|
|
79
89
|
decision: "ready";
|
|
@@ -103,14 +113,14 @@ export type TaskCompilePromptInput = {
|
|
|
103
113
|
}>;
|
|
104
114
|
}>;
|
|
105
115
|
};
|
|
106
|
-
|
|
116
|
+
clarification_rounds?: Array<{
|
|
107
117
|
request: {
|
|
108
118
|
title?: string;
|
|
109
119
|
summary: string;
|
|
110
120
|
request: string;
|
|
111
121
|
};
|
|
112
122
|
answer_messages: TaskCompilePromptClarificationMessage[];
|
|
113
|
-
}
|
|
123
|
+
}>;
|
|
114
124
|
};
|
|
115
125
|
export type TaskCompilePromptClarificationMessage = {
|
|
116
126
|
role: "human" | "tutti";
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
DROP TABLE IF EXISTS scratchpad_receipt_sources;
|
|
2
|
+
DROP TABLE IF EXISTS scratchpad_source_refs;
|
|
3
|
+
DROP TABLE IF EXISTS scratchpad_source_state;
|
|
4
|
+
|
|
5
|
+
CREATE TABLE scratchpad_source_state (
|
|
6
|
+
id TEXT PRIMARY KEY CHECK (id = 'current'),
|
|
7
|
+
cycle_start_cursor_created_at TEXT,
|
|
8
|
+
cycle_start_cursor_message_id TEXT,
|
|
9
|
+
refreshed_through_cursor_created_at TEXT,
|
|
10
|
+
refreshed_through_cursor_message_id TEXT,
|
|
11
|
+
dirty_since TEXT,
|
|
12
|
+
in_flight_activity_ref TEXT,
|
|
13
|
+
in_flight_started_at TEXT,
|
|
14
|
+
last_completed_at TEXT,
|
|
15
|
+
last_failed_at TEXT,
|
|
16
|
+
backoff_until TEXT,
|
|
17
|
+
updated_at TEXT NOT NULL,
|
|
18
|
+
CHECK (
|
|
19
|
+
(cycle_start_cursor_created_at IS NULL AND cycle_start_cursor_message_id IS NULL)
|
|
20
|
+
OR (
|
|
21
|
+
cycle_start_cursor_created_at IS NOT NULL
|
|
22
|
+
AND cycle_start_cursor_message_id IS NOT NULL
|
|
23
|
+
)
|
|
24
|
+
),
|
|
25
|
+
CHECK (
|
|
26
|
+
(
|
|
27
|
+
refreshed_through_cursor_created_at IS NULL
|
|
28
|
+
AND refreshed_through_cursor_message_id IS NULL
|
|
29
|
+
)
|
|
30
|
+
OR (
|
|
31
|
+
refreshed_through_cursor_created_at IS NOT NULL
|
|
32
|
+
AND refreshed_through_cursor_message_id IS NOT NULL
|
|
33
|
+
)
|
|
34
|
+
),
|
|
35
|
+
CHECK (
|
|
36
|
+
(in_flight_activity_ref IS NULL AND in_flight_started_at IS NULL)
|
|
37
|
+
OR (in_flight_activity_ref IS NOT NULL AND in_flight_started_at IS NOT NULL)
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE TABLE scratchpad_source_refs (
|
|
42
|
+
scratchpad_id TEXT NOT NULL DEFAULT 'current' CHECK (scratchpad_id = 'current'),
|
|
43
|
+
message_id TEXT NOT NULL,
|
|
44
|
+
source_scope TEXT NOT NULL DEFAULT 'main_chat' CHECK (source_scope = 'main_chat'),
|
|
45
|
+
created_at TEXT NOT NULL,
|
|
46
|
+
PRIMARY KEY (scratchpad_id, message_id),
|
|
47
|
+
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE INDEX idx_scratchpad_source_refs_created_at
|
|
51
|
+
ON scratchpad_source_refs (scratchpad_id, created_at ASC, message_id ASC);
|
|
52
|
+
|
|
53
|
+
CREATE TABLE scratchpad_receipt_sources (
|
|
54
|
+
workflow_ref TEXT NOT NULL,
|
|
55
|
+
message_id TEXT NOT NULL,
|
|
56
|
+
source_scope TEXT NOT NULL DEFAULT 'main_chat' CHECK (source_scope = 'main_chat'),
|
|
57
|
+
created_at TEXT NOT NULL,
|
|
58
|
+
PRIMARY KEY (workflow_ref, message_id),
|
|
59
|
+
FOREIGN KEY (workflow_ref) REFERENCES scratchpad_receipts(workflow_ref) ON DELETE CASCADE,
|
|
60
|
+
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
CREATE INDEX idx_scratchpad_receipt_sources_created_at
|
|
64
|
+
ON scratchpad_receipt_sources (workflow_ref, created_at ASC, message_id ASC);
|
|
65
|
+
|
|
66
|
+
CREATE TABLE active_task_compile_context (
|
|
67
|
+
id TEXT PRIMARY KEY CHECK (id = 'current'),
|
|
68
|
+
workflow_ref TEXT NOT NULL UNIQUE,
|
|
69
|
+
captured_by_activity_ref TEXT NOT NULL,
|
|
70
|
+
submitted_at TEXT NOT NULL,
|
|
71
|
+
topic TEXT NOT NULL,
|
|
72
|
+
background_summary TEXT NOT NULL,
|
|
73
|
+
current_consensus_json TEXT NOT NULL CHECK (
|
|
74
|
+
json_valid(current_consensus_json) AND json_type(current_consensus_json) = 'array'
|
|
75
|
+
),
|
|
76
|
+
open_questions_json TEXT NOT NULL CHECK (
|
|
77
|
+
json_valid(open_questions_json) AND json_type(open_questions_json) = 'array'
|
|
78
|
+
),
|
|
79
|
+
task_changes_json TEXT NOT NULL CHECK (
|
|
80
|
+
json_valid(task_changes_json) AND json_type(task_changes_json) = 'array'
|
|
81
|
+
),
|
|
82
|
+
scratchpad_updated_at TEXT NOT NULL,
|
|
83
|
+
source_window_after_created_at TEXT,
|
|
84
|
+
source_window_after_message_id TEXT,
|
|
85
|
+
source_window_through_created_at TEXT,
|
|
86
|
+
source_window_through_message_id TEXT,
|
|
87
|
+
CHECK (
|
|
88
|
+
(source_window_after_created_at IS NULL AND source_window_after_message_id IS NULL)
|
|
89
|
+
OR (
|
|
90
|
+
source_window_after_created_at IS NOT NULL
|
|
91
|
+
AND source_window_after_message_id IS NOT NULL
|
|
92
|
+
)
|
|
93
|
+
),
|
|
94
|
+
CHECK (
|
|
95
|
+
(source_window_through_created_at IS NULL AND source_window_through_message_id IS NULL)
|
|
96
|
+
OR (
|
|
97
|
+
source_window_through_created_at IS NOT NULL
|
|
98
|
+
AND source_window_through_message_id IS NOT NULL
|
|
99
|
+
)
|
|
100
|
+
),
|
|
101
|
+
CHECK (
|
|
102
|
+
source_window_after_created_at IS NULL
|
|
103
|
+
OR source_window_through_created_at IS NULL
|
|
104
|
+
OR source_window_through_created_at > source_window_after_created_at
|
|
105
|
+
OR (
|
|
106
|
+
source_window_through_created_at = source_window_after_created_at
|
|
107
|
+
AND source_window_through_message_id >= source_window_after_message_id
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
CREATE TRIGGER active_task_compile_context_immutable
|
|
113
|
+
BEFORE UPDATE ON active_task_compile_context
|
|
114
|
+
BEGIN
|
|
115
|
+
SELECT RAISE(ABORT, 'active Task Compile Context is immutable');
|
|
116
|
+
END;
|
|
117
|
+
|
|
118
|
+
CREATE TABLE active_task_compile_context_sources (
|
|
119
|
+
workflow_ref TEXT NOT NULL,
|
|
120
|
+
message_id TEXT NOT NULL,
|
|
121
|
+
created_at TEXT NOT NULL,
|
|
122
|
+
PRIMARY KEY (workflow_ref, message_id),
|
|
123
|
+
FOREIGN KEY (workflow_ref) REFERENCES active_task_compile_context(workflow_ref)
|
|
124
|
+
ON DELETE CASCADE,
|
|
125
|
+
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
CREATE INDEX idx_active_task_compile_context_sources_order
|
|
129
|
+
ON active_task_compile_context_sources (workflow_ref, created_at ASC, message_id ASC);
|
|
130
|
+
|
|
131
|
+
CREATE TRIGGER active_task_compile_context_sources_main_chat_only
|
|
132
|
+
BEFORE INSERT ON active_task_compile_context_sources
|
|
133
|
+
WHEN NOT EXISTS (
|
|
134
|
+
SELECT 1
|
|
135
|
+
FROM messages
|
|
136
|
+
WHERE messages.id = NEW.message_id
|
|
137
|
+
AND messages.scope_kind = 'main_chat'
|
|
138
|
+
)
|
|
139
|
+
BEGIN
|
|
140
|
+
SELECT RAISE(ABORT, 'Task Compile Context source must be a main-chat message');
|
|
141
|
+
END;
|
|
142
|
+
|
|
143
|
+
CREATE TRIGGER active_task_compile_context_sources_immutable
|
|
144
|
+
BEFORE UPDATE ON active_task_compile_context_sources
|
|
145
|
+
BEGIN
|
|
146
|
+
SELECT RAISE(ABORT, 'Task Compile Context sources are immutable');
|
|
147
|
+
END;
|