@xfey/tutti 0.1.127 → 0.1.129
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/approvals/decision-command.d.ts +2 -2
- package/dist/chat-assistant/diagnostics.d.ts +17 -3
- package/dist/chat-assistant/diagnostics.js +5 -2
- package/dist/chat-assistant/failure-messages.d.ts +4 -0
- package/dist/chat-assistant/failure-messages.js +57 -0
- package/dist/chat-assistant/failures.d.ts +27 -0
- package/dist/chat-assistant/failures.js +46 -0
- package/dist/chat-assistant/index.d.ts +18 -4
- package/dist/chat-assistant/index.js +254 -51
- package/dist/chat-assistant/language-context.d.ts +2 -0
- package/dist/chat-assistant/language-context.js +17 -14
- package/dist/chat-assistant/requests.d.ts +34 -0
- package/dist/chat-assistant/requests.js +64 -0
- package/dist/collaboration-ingestion/clarification.js +3 -1
- package/dist/collaboration-ingestion/main-chat.js +1 -0
- package/dist/collaboration-ingestion/types.d.ts +2 -0
- package/dist/collaboration-state/clarification-snapshot.d.ts +5 -5
- package/dist/collaboration-state/context-sync-attempts.d.ts +9 -0
- package/dist/collaboration-state/context-sync-attempts.js +13 -0
- package/dist/collaboration-state/task-compile-context.d.ts +1 -1
- package/dist/collaboration-state/task-compile-context.js +11 -1
- package/dist/collaboration-state/task-compile-requests.d.ts +6 -0
- package/dist/collaboration-state/task-compile-requests.js +16 -0
- package/dist/communication-language/notice-locale.d.ts +4 -0
- package/dist/communication-language/notice-locale.js +14 -0
- package/dist/control-plane/context-sync-completion.d.ts +7 -0
- package/dist/control-plane/context-sync-completion.js +27 -0
- package/dist/control-plane/context-sync.d.ts +1 -0
- package/dist/control-plane/context-sync.js +23 -0
- package/dist/control-plane/index.d.ts +13 -4
- package/dist/control-plane/index.js +30 -23
- package/dist/control-plane/task-compile-continuation.js +2 -0
- package/dist/control-plane/task-compile-request-status.d.ts +6 -0
- package/dist/control-plane/task-compile-request-status.js +70 -0
- package/dist/control-plane/task-compile-start.js +40 -2
- package/dist/control-plane/types.d.ts +2 -0
- package/dist/providers/failure-classification.d.ts +23 -0
- package/dist/providers/failure-classification.js +43 -0
- package/dist/providers/invocation-progress.d.ts +6 -0
- package/dist/providers/invocation-progress.js +24 -0
- package/dist/providers/openai/app-server/read-only-procedure.js +1 -0
- package/dist/providers/openai/chat-assistant.js +2 -1
- package/dist/reference-access/read-evidence.d.ts +2 -0
- package/dist/reference-access/read-evidence.js +5 -0
- package/dist/reference-access/service.d.ts +2 -0
- package/dist/reference-access/service.js +2 -0
- package/dist/runtime-failures.js +15 -1
- package/dist/server-shell/cli/external-reference-runtime.js +6 -3
- package/dist/server-shell/cli/host-server-runtime.js +8 -2
- package/dist/server-shell/cli/relay-registration.js +1 -0
- package/dist/server-shell/http/routes/project-api/messages-routes.js +22 -1
- package/dist/server-shell/http/routes/project-api/openapi-collaboration-routes.d.ts +140 -5
- package/dist/server-shell/http/routes/project-api/openapi-collaboration-routes.js +29 -2
- package/dist/server-shell/http/routes/project-api/openapi-skills-routes.d.ts +2 -0
- package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.d.ts +6 -0
- package/dist/server-shell/http/routes/project-api/openapi.d.ts +148 -5
- package/dist/server-shell/http/routes/project-api/schemas.d.ts +6 -0
- package/dist/server-shell/http/routes/project-api/schemas.js +1 -0
- package/dist/server-shell/http/routes/project-api/types.d.ts +1 -0
- package/dist/server-shell/http/routes/project-api/workflow-routes.js +39 -3
- package/dist/server-shell/http/routes/project-api/workspace-projections.js +1 -0
- package/dist/server-shell/http/validation.js +8 -2
- package/dist/server-shell/local-console/managed-project-service.d.ts +1 -1
- package/dist/server-shell/managed-access/transport.d.ts +1 -1
- package/migrations/0024_chat_requests.sql +19 -0
- package/migrations/0025_task_compile_requests.sql +50 -0
- package/migrations/0026_context_sync_and_chat_locale.sql +12 -0
- package/migrations/README.md +3 -1
- package/node_modules/@tutti/relay-client/dist/host-control.d.ts +1 -0
- package/node_modules/@tutti/relay-client/dist/host-control.js +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/index.js +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/operation-status.d.ts +174 -0
- package/node_modules/@tutti/shared/dist/schemas/api/operation-status.js +75 -0
- package/node_modules/@tutti/shared/dist/schemas/api/primitives.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/primitives.js +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.js +2 -1
- package/package.json +1 -1
- package/web/assets/{homepage-motion-scene-DyEmWwvt.js → homepage-motion-scene-BHhw4CfM.js} +1 -1
- package/web/assets/index-5COc1Yku.js +70 -0
- package/web/assets/index-BJvKuUiT.css +1 -0
- package/web/index.html +2 -2
- package/web/assets/index-By3idT4U.js +0 -70
- package/web/assets/index-DSBjOZmJ.css +0 -1
|
@@ -13,8 +13,9 @@ export declare function readSubmittedClarificationMessages(db: SqliteDatabase, r
|
|
|
13
13
|
is_current_round: boolean;
|
|
14
14
|
};
|
|
15
15
|
refs?: {
|
|
16
|
-
task_id?: string;
|
|
17
16
|
activity_ref?: string;
|
|
17
|
+
workflow_ref?: string;
|
|
18
|
+
task_id?: string;
|
|
18
19
|
artifact_feedback?: {
|
|
19
20
|
summary?: string;
|
|
20
21
|
kind: "artifact_feedback";
|
|
@@ -106,15 +107,14 @@ export declare function readSubmittedClarificationMessages(db: SqliteDatabase, r
|
|
|
106
107
|
blob_oid?: string;
|
|
107
108
|
path: string;
|
|
108
109
|
name: string;
|
|
109
|
-
source: "human_upload" | "tutti_output";
|
|
110
110
|
category: "file" | "image";
|
|
111
|
+
source: "human_upload" | "tutti_output";
|
|
111
112
|
size_bytes: number;
|
|
112
113
|
text_read: {
|
|
113
114
|
blocked_reason?: "unknown" | "binary" | "too_large" | "unsupported_encoding" | "restricted_path" | "secret_like";
|
|
114
115
|
can_read: boolean;
|
|
115
116
|
};
|
|
116
117
|
};
|
|
117
|
-
workflow_ref?: string;
|
|
118
118
|
clarification_round_ref?: string;
|
|
119
119
|
clarification_thread_ref?: string;
|
|
120
120
|
task_result?: {
|
|
@@ -141,10 +141,10 @@ export declare function readSubmittedClarificationMessages(db: SqliteDatabase, r
|
|
|
141
141
|
};
|
|
142
142
|
worklist_compile?: {
|
|
143
143
|
kind: "worklist_compile";
|
|
144
|
-
title: string;
|
|
145
144
|
workflow_ref: string;
|
|
145
|
+
title: string;
|
|
146
146
|
tasks: {
|
|
147
|
-
status: "failed" | "pending" | "
|
|
147
|
+
status: "failed" | "pending" | "running" | "done" | "todo";
|
|
148
148
|
task_id: string;
|
|
149
149
|
title: string;
|
|
150
150
|
summary: string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SqliteDatabase } from "../store/index.js";
|
|
2
|
+
export declare function hasContextSyncCompletionAttempt(db: SqliteDatabase, batchKey: string): boolean;
|
|
3
|
+
/** Persist before invoking the provider; failure/unknown outcome is not a retry permit. */
|
|
4
|
+
export declare function recordContextSyncCompletionAttempt(db: SqliteDatabase, input: {
|
|
5
|
+
batchKey: string;
|
|
6
|
+
workflowRef: string;
|
|
7
|
+
startedAt: string;
|
|
8
|
+
}): boolean;
|
|
9
|
+
//# sourceMappingURL=context-sync-attempts.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function hasContextSyncCompletionAttempt(db, batchKey) {
|
|
2
|
+
return (db
|
|
3
|
+
.prepare("SELECT 1 AS present FROM context_sync_completion_attempts WHERE batch_key = ?")
|
|
4
|
+
.get(batchKey) !== undefined);
|
|
5
|
+
}
|
|
6
|
+
/** Persist before invoking the provider; failure/unknown outcome is not a retry permit. */
|
|
7
|
+
export function recordContextSyncCompletionAttempt(db, input) {
|
|
8
|
+
return (db
|
|
9
|
+
.prepare(`INSERT OR IGNORE INTO context_sync_completion_attempts(batch_key, workflow_ref, started_at)
|
|
10
|
+
VALUES (?, ?, ?)`)
|
|
11
|
+
.run(input.batchKey, input.workflowRef, input.startedAt).changes === 1);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=context-sync-attempts.js.map
|
|
@@ -24,7 +24,7 @@ export declare function completeTaskCompileContext(db: SqliteDatabase, input: Co
|
|
|
24
24
|
task_changes: string[];
|
|
25
25
|
receipts: {
|
|
26
26
|
compiled_tasks?: {
|
|
27
|
-
status: "failed" | "pending" | "
|
|
27
|
+
status: "failed" | "pending" | "running" | "done" | "todo";
|
|
28
28
|
task_id: string;
|
|
29
29
|
title: string;
|
|
30
30
|
summary: string;
|
|
@@ -3,6 +3,7 @@ import { readScratchpadProjection } from "./scratchpad.js";
|
|
|
3
3
|
import { readCommunicationLanguage, copyCommunicationLanguage } from "./communication-language.js";
|
|
4
4
|
import { readScratchpadSourceState } from "./scratchpad-source-state.js";
|
|
5
5
|
import { nowIso, stringifyJson } from "./serialization.js";
|
|
6
|
+
import { registerTaskCompileRequest, closeFailedTaskCompileRequest, } from "./task-compile-requests.js";
|
|
6
7
|
function cursorIsAfter(left, right) {
|
|
7
8
|
if (left === undefined) {
|
|
8
9
|
return false;
|
|
@@ -145,6 +146,7 @@ export function recordTaskCompileSubmission(db, input) {
|
|
|
145
146
|
if (readActiveTaskCompileContext(db) !== null) {
|
|
146
147
|
throw new Error("An active Task Compile Context already exists");
|
|
147
148
|
}
|
|
149
|
+
registerTaskCompileRequest(db, input.workflow_ref, input.accepted_activity_ref, nowIso(input.now));
|
|
148
150
|
db.prepare(`
|
|
149
151
|
INSERT INTO pending_task_compile_submissions (
|
|
150
152
|
id,
|
|
@@ -226,6 +228,7 @@ export function captureTaskCompileContext(db, input) {
|
|
|
226
228
|
: { created_at: lastSource.created_at, message_id: lastSource.message_id });
|
|
227
229
|
const after = submission?.source_window.after ?? sourceState.cycle_start_cursor;
|
|
228
230
|
const submittedAt = nowIso(input.now);
|
|
231
|
+
registerTaskCompileRequest(tx, input.workflow_ref, input.captured_by_activity_ref, submittedAt);
|
|
229
232
|
tx.prepare(`
|
|
230
233
|
INSERT INTO active_task_compile_context (
|
|
231
234
|
id,
|
|
@@ -337,9 +340,16 @@ export function rollbackTaskCompileContext(db, input) {
|
|
|
337
340
|
return withHostStoreTransaction(db, (tx) => {
|
|
338
341
|
const context = readActiveTaskCompileContext(tx, input.workflow_ref);
|
|
339
342
|
if (context === null) {
|
|
340
|
-
|
|
343
|
+
const pending = readPendingTaskCompileSubmission(tx, input.workflow_ref);
|
|
344
|
+
if (pending === null)
|
|
345
|
+
return false;
|
|
346
|
+
// Before capture the source cursor has not moved: release only this admission.
|
|
347
|
+
closeFailedTaskCompileRequest(tx, input.workflow_ref, nowIso(input.now));
|
|
348
|
+
tx.prepare("DELETE FROM pending_task_compile_submissions WHERE workflow_ref = ?").run(input.workflow_ref);
|
|
349
|
+
return true;
|
|
341
350
|
}
|
|
342
351
|
const rolledBackAt = nowIso(input.now);
|
|
352
|
+
closeFailedTaskCompileRequest(tx, input.workflow_ref, rolledBackAt);
|
|
343
353
|
const sourceState = readScratchpadSourceState(tx);
|
|
344
354
|
const after = context.source_window.after;
|
|
345
355
|
const through = context.source_window.through;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SqliteDatabase } from "../store/index.js";
|
|
2
|
+
/** Persistence only: callers own acceptance, stage selection and rollback. */
|
|
3
|
+
export declare function registerTaskCompileRequest(db: SqliteDatabase, workflowRef: string, activityRef: string, createdAt: string): void;
|
|
4
|
+
export declare function linkTaskCompileActivity(db: SqliteDatabase, workflowRef: string, activityRef: string): void;
|
|
5
|
+
export declare function closeFailedTaskCompileRequest(db: SqliteDatabase, workflowRef: string, now: string, code?: "task_compile_failed" | "scratchpad_empty_after_refresh"): void;
|
|
6
|
+
//# sourceMappingURL=task-compile-requests.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Persistence only: callers own acceptance, stage selection and rollback. */
|
|
2
|
+
export function registerTaskCompileRequest(db, workflowRef, activityRef, createdAt) {
|
|
3
|
+
db.prepare(`INSERT OR IGNORE INTO task_compile_requests
|
|
4
|
+
(workflow_ref, accepted_activity_ref, current_activity_ref, created_at)
|
|
5
|
+
VALUES (?, ?, ?, ?)`).run(workflowRef, activityRef, activityRef, createdAt);
|
|
6
|
+
}
|
|
7
|
+
export function linkTaskCompileActivity(db, workflowRef, activityRef) {
|
|
8
|
+
db.prepare(`UPDATE task_compile_requests SET current_activity_ref = ?
|
|
9
|
+
WHERE workflow_ref = ? AND closed_at IS NULL`).run(activityRef, workflowRef);
|
|
10
|
+
}
|
|
11
|
+
export function closeFailedTaskCompileRequest(db, workflowRef, now, code = "task_compile_failed") {
|
|
12
|
+
db.prepare(`UPDATE task_compile_requests SET failure_code = ?, closed_at = ?
|
|
13
|
+
WHERE workflow_ref = ? AND closed_at IS NULL
|
|
14
|
+
AND NOT EXISTS (SELECT 1 FROM scratchpad_receipts WHERE workflow_ref = ?)`).run(code, now, workflowRef, workflowRef);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=task-compile-requests.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function noticeLocale(locale) {
|
|
2
|
+
if (locale === undefined || locale === null)
|
|
3
|
+
return "en";
|
|
4
|
+
try {
|
|
5
|
+
const parsed = new Intl.Locale(locale);
|
|
6
|
+
if (parsed.language !== "zh")
|
|
7
|
+
return "en";
|
|
8
|
+
return parsed.maximize().script === "Hant" ? "zh-Hant" : "zh-Hans";
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return "en";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=notice-locale.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SqliteDatabase } from "../store/index.js";
|
|
2
|
+
import type { ContextSyncWorkflowTrigger } from "./workflows/index.js";
|
|
3
|
+
export declare function pendingContextSyncCompletion(db: SqliteDatabase): {
|
|
4
|
+
key: string;
|
|
5
|
+
trigger: ContextSyncWorkflowTrigger;
|
|
6
|
+
} | undefined;
|
|
7
|
+
//# sourceMappingURL=context-sync-completion.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { hasContextSyncCompletionAttempt } from "../collaboration-state/context-sync-attempts.js";
|
|
3
|
+
import { readWorklistProjection } from "../collaboration-state/index.js";
|
|
4
|
+
export function pendingContextSyncCompletion(db) {
|
|
5
|
+
const worklist = readWorklistProjection(db);
|
|
6
|
+
const tasks = worklist.modules
|
|
7
|
+
.flatMap((entry) => entry.tasks)
|
|
8
|
+
.sort((a, b) => (a.id < b.id ? -1 : 1));
|
|
9
|
+
if (tasks.length === 0 || tasks.some((task) => task.status !== "done"))
|
|
10
|
+
return undefined;
|
|
11
|
+
// A changed result on the same task is a new completion. Source messages,
|
|
12
|
+
// ordering, labels and context_sync's own Git commit are deliberately absent.
|
|
13
|
+
const key = createHash("sha256")
|
|
14
|
+
.update(JSON.stringify(tasks.map((task) => [task.id, task.latest_run_result_id])))
|
|
15
|
+
.digest("hex");
|
|
16
|
+
if (hasContextSyncCompletionAttempt(db, key))
|
|
17
|
+
return undefined;
|
|
18
|
+
return {
|
|
19
|
+
key,
|
|
20
|
+
trigger: {
|
|
21
|
+
kind: "worklist_all_tasks_completed",
|
|
22
|
+
completed_task_count: tasks.length,
|
|
23
|
+
module_count: worklist.modules.length,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=context-sync-completion.js.map
|
|
@@ -10,6 +10,7 @@ export declare function startContextSyncAnalysisProcedure(input: {
|
|
|
10
10
|
store: HostProjectStore;
|
|
11
11
|
events: WorkspaceEventBus;
|
|
12
12
|
trigger: ContextSyncWorkflowTrigger;
|
|
13
|
+
completionBatchKey?: string;
|
|
13
14
|
resolveWorkflowRunner: ProcedureWorkflowRunnerResolver;
|
|
14
15
|
readActiveActivity: () => {
|
|
15
16
|
activity_ref: ActivityRef;
|
|
@@ -3,6 +3,7 @@ import { projectLanguageContext, logLanguageContext } from "./communication-lang
|
|
|
3
3
|
import { recordProjectTimelineEvent } from "../project-timeline/index.js";
|
|
4
4
|
import { syncProjectDocs } from "../workspace-ops/index.js";
|
|
5
5
|
import { logProcedureExecutionError } from "./procedure-logging.js";
|
|
6
|
+
import { recordContextSyncCompletionAttempt } from "../collaboration-state/context-sync-attempts.js";
|
|
6
7
|
import { projectBriefShouldRefreshForUpdatedPaths, refreshProjectBriefProjection, } from "./project-brief-refresh.js";
|
|
7
8
|
function publishContextSyncTimelineChanged(input) {
|
|
8
9
|
input.events.publish({
|
|
@@ -63,6 +64,28 @@ export function startContextSyncAnalysisProcedure(input) {
|
|
|
63
64
|
error,
|
|
64
65
|
}),
|
|
65
66
|
execute: async (context) => {
|
|
67
|
+
if (input.completionBatchKey !== undefined) {
|
|
68
|
+
const recorded = recordContextSyncCompletionAttempt(input.store.db, {
|
|
69
|
+
batchKey: input.completionBatchKey,
|
|
70
|
+
workflowRef,
|
|
71
|
+
startedAt: input.now().toISOString(),
|
|
72
|
+
});
|
|
73
|
+
if (!recorded)
|
|
74
|
+
return {
|
|
75
|
+
kind: "completed",
|
|
76
|
+
summary: "These task results were already checked for document maintenance.",
|
|
77
|
+
};
|
|
78
|
+
try {
|
|
79
|
+
input.logger?.info({
|
|
80
|
+
workflow_ref: workflowRef,
|
|
81
|
+
activity_ref: context.activity_ref,
|
|
82
|
+
trigger: "worklist_all_tasks_completed",
|
|
83
|
+
}, "Automatic context sync attempt recorded");
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
/* Logging must not prevent the recorded maintenance attempt. */
|
|
87
|
+
}
|
|
88
|
+
}
|
|
66
89
|
const language = projectLanguageContext(input.store.db, "documents");
|
|
67
90
|
logLanguageContext(input.logger, language, {
|
|
68
91
|
workflow_ref: workflowRef,
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { type ActivityRef, type ClarificationRoundRef, type IdempotencyKey, type TaskId, type WorkflowInvocationRef } from "@tutti/shared/ids";
|
|
2
2
|
import type { TrustedCollaborationAuthor } from "../collaboration-ingestion/types.js";
|
|
3
|
+
import type { WorkflowKind } from "@tutti/shared/domain";
|
|
3
4
|
import type { ExecutionStatusProjection, MessageProjection, ContextSyncDisposition, ContextSyncResult, RefreshScratchpadDisposition, RefreshScratchpadResult, RunSchedulerNowDisposition, RunSchedulerNowPayload, RetryTaskDisposition, RetryTaskPayload, RefreshReferenceSummariesDisposition, RefreshReferenceSummariesPayload, RefreshReferenceSummariesResult, SendClarificationRoundMessageDisposition, SendClarificationRoundMessagePayload, SendClarificationRoundMessageResult, SubmitClarificationRoundDisposition, SubmitClarificationRoundPayload, SubmitClarificationRoundResult, SubmitWorklistDisposition, SubmitWorklistPayload, SubmitWorklistResult, ProcedureLane } from "@tutti/shared/schemas/api";
|
|
4
|
-
import type { ContextSyncWorkflowTrigger } from "./workflows/index.js";
|
|
5
5
|
import type { ControlPlaneCommandResult, Phase5ControlPlaneOptions, StartupRecoveryOptions, StartupRecoveryResult } from "./types.js";
|
|
6
6
|
import { type ProjectBriefRefreshReason, type RefreshProjectBriefProjectionResult } from "./project-brief-refresh.js";
|
|
7
|
+
type ActiveActivity = {
|
|
8
|
+
activity_ref: ActivityRef;
|
|
9
|
+
activity_kind: "run" | "procedure";
|
|
10
|
+
lane?: ProcedureLane;
|
|
11
|
+
workflow_kind?: WorkflowKind;
|
|
12
|
+
workflow_ref?: WorkflowInvocationRef;
|
|
13
|
+
};
|
|
7
14
|
export type { ControlPlaneCommandResult, ControlPlaneLogger, Phase5ControlPlaneOptions, RunCorrectionContext, RunContinuationContext, RunDispatchContext, RunDispatchTrigger, RunPipelineInput, RunPipelineResolution, RunPipelineResolver, RunPipelineResult, RunPipelineRunner, StartupRecoveryOptions, StartupRecoveryResult, TrustedHumanAuthor, } from "./types.js";
|
|
8
15
|
export declare class Phase5ControlPlane {
|
|
9
16
|
private readonly engine;
|
|
@@ -14,6 +21,7 @@ export declare class Phase5ControlPlane {
|
|
|
14
21
|
private readonly resolveRunPipeline;
|
|
15
22
|
private readonly readMainlineStatus;
|
|
16
23
|
private readonly readActiveApproval;
|
|
24
|
+
private readonly hasPendingChatRequests;
|
|
17
25
|
private readonly logger;
|
|
18
26
|
private readonly projectContext;
|
|
19
27
|
private readonly runLifecycle;
|
|
@@ -46,9 +54,10 @@ export declare class Phase5ControlPlane {
|
|
|
46
54
|
}): Promise<RefreshProjectBriefProjectionResult>;
|
|
47
55
|
beginShutdown(): void;
|
|
48
56
|
dispose(): Promise<void>;
|
|
49
|
-
waitForRepoInspectionIdle(): Promise<void>;
|
|
57
|
+
waitForRepoInspectionIdle(onBlocked?: (blocker: ActiveActivity) => void): Promise<void>;
|
|
50
58
|
startTaskCompile(payload: SubmitWorklistPayload): ControlPlaneCommandResult<SubmitWorklistDisposition, SubmitWorklistResult>;
|
|
51
|
-
startContextSyncAnalysis(
|
|
59
|
+
startContextSyncAnalysis(): ControlPlaneCommandResult<ContextSyncDisposition, ContextSyncResult>;
|
|
60
|
+
private startContextSync;
|
|
52
61
|
startReferenceSummaryRefresh(payload?: RefreshReferenceSummariesPayload): ControlPlaneCommandResult<RefreshReferenceSummariesDisposition, RefreshReferenceSummariesResult>;
|
|
53
62
|
private tryStartPendingReferenceSummaryRefresh;
|
|
54
63
|
sendClarificationRoundMessage(roundId: ClarificationRoundRef, payload: SendClarificationRoundMessagePayload, author: TrustedCollaborationAuthor): ControlPlaneCommandResult<SendClarificationRoundMessageDisposition, SendClarificationRoundMessageResult>;
|
|
@@ -71,7 +80,7 @@ export declare class Phase5ControlPlane {
|
|
|
71
80
|
private handleRunTerminalTransition;
|
|
72
81
|
private tryRunTaskArrivalScheduler;
|
|
73
82
|
private maybeScheduleAfterRunCompletion;
|
|
74
|
-
|
|
83
|
+
notifyChatRequestsChanged(): void;
|
|
75
84
|
private scheduleContextSyncAfterWorklistCompletion;
|
|
76
85
|
private attemptContextSyncAfterWorklistCompletion;
|
|
77
86
|
private cancelPendingWorklistCompletionContextSync;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { readActiveClarificationProjection, readActiveTaskCompileContext, markScratchpadRefreshSucceeded, readPendingTaskCompileSubmission, readTaskDetailProjection, readTaskProjectionByActivityRef, readScratchpadSourceState,
|
|
1
|
+
import { readActiveClarificationProjection, readActiveTaskCompileContext, markScratchpadRefreshSucceeded, readPendingTaskCompileSubmission, readTaskDetailProjection, readTaskProjectionByActivityRef, readScratchpadSourceState, } from "../collaboration-state/index.js";
|
|
2
2
|
import { ProcedureEngine } from "../procedure-engine/index.js";
|
|
3
3
|
import { RunEngine } from "../run-engine/index.js";
|
|
4
4
|
import { WorkspaceOpsError, isReferenceFilePath, readReferenceSummaryTargets, } from "../workspace-ops/index.js";
|
|
5
5
|
import { publishProcedureTransition as publishProcedureTransitionEvent, publishRunResultRecorded as publishRunResultRecordedEvent, publishRunTransition as publishRunTransitionEvent, publishTaskRunStarted as publishTaskRunStartedEvent, } from "./event-publishers.js";
|
|
6
6
|
import { startContextSyncAnalysisProcedure } from "./context-sync.js";
|
|
7
|
+
import { pendingContextSyncCompletion } from "./context-sync-completion.js";
|
|
7
8
|
import { refreshProjectBriefProjection, } from "./project-brief-refresh.js";
|
|
8
9
|
import { startReferenceSummaryRefreshProcedure } from "./reference-summary-refresh.js";
|
|
9
10
|
import { runControlPlaneStartupRecovery } from "./startup-recovery.js";
|
|
@@ -30,6 +31,7 @@ export class Phase5ControlPlane {
|
|
|
30
31
|
resolveRunPipeline;
|
|
31
32
|
readMainlineStatus;
|
|
32
33
|
readActiveApproval;
|
|
34
|
+
hasPendingChatRequests;
|
|
33
35
|
logger;
|
|
34
36
|
projectContext;
|
|
35
37
|
runLifecycle;
|
|
@@ -53,6 +55,7 @@ export class Phase5ControlPlane {
|
|
|
53
55
|
this.resolveRunPipeline = options.resolveRunPipeline;
|
|
54
56
|
this.readMainlineStatus = options.readMainlineStatus;
|
|
55
57
|
this.readActiveApproval = options.readActiveApproval;
|
|
58
|
+
this.hasPendingChatRequests = options.hasPendingChatRequests ?? (() => false);
|
|
56
59
|
this.logger = options.logger;
|
|
57
60
|
this.projectContext = options.projectContext;
|
|
58
61
|
this.runLifecycle = options.runLifecycle;
|
|
@@ -177,13 +180,17 @@ export class Phase5ControlPlane {
|
|
|
177
180
|
this.beginShutdown();
|
|
178
181
|
return this.waitForIdle();
|
|
179
182
|
}
|
|
180
|
-
async waitForRepoInspectionIdle() {
|
|
183
|
+
async waitForRepoInspectionIdle(onBlocked) {
|
|
181
184
|
for (;;) {
|
|
182
185
|
const waits = [];
|
|
183
|
-
|
|
186
|
+
const run = this.readActiveRun();
|
|
187
|
+
const procedure = this.readActiveForegroundProcedure();
|
|
188
|
+
if (run !== null) {
|
|
189
|
+
onBlocked?.(run);
|
|
184
190
|
waits.push(this.runEngine.waitForIdle());
|
|
185
191
|
}
|
|
186
|
-
if (
|
|
192
|
+
if (procedure !== null) {
|
|
193
|
+
onBlocked?.(procedure);
|
|
187
194
|
waits.push(this.engine.waitForLaneIdle("foreground"));
|
|
188
195
|
}
|
|
189
196
|
if (waits.length === 0) {
|
|
@@ -233,15 +240,17 @@ export class Phase5ControlPlane {
|
|
|
233
240
|
shouldContinue: () => !this.closing,
|
|
234
241
|
});
|
|
235
242
|
}
|
|
236
|
-
startContextSyncAnalysis(
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
243
|
+
startContextSyncAnalysis() {
|
|
244
|
+
this.cancelPendingWorklistCompletionContextSync();
|
|
245
|
+
return this.startContextSync({ kind: "manual" });
|
|
246
|
+
}
|
|
247
|
+
startContextSync(trigger, completionBatchKey) {
|
|
240
248
|
return startContextSyncAnalysisProcedure({
|
|
241
249
|
engine: this.engine,
|
|
242
250
|
store: this.store,
|
|
243
251
|
events: this.events,
|
|
244
252
|
trigger,
|
|
253
|
+
...(completionBatchKey === undefined ? {} : { completionBatchKey }),
|
|
245
254
|
resolveWorkflowRunner: this.resolveWorkflowRunner,
|
|
246
255
|
readActiveActivity: () => this.readSchedulerBlocker(),
|
|
247
256
|
projectContext: this.projectContext,
|
|
@@ -544,17 +553,13 @@ export class Phase5ControlPlane {
|
|
|
544
553
|
}
|
|
545
554
|
this.scheduleContextSyncAfterWorklistCompletion();
|
|
546
555
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
if (
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
kind: "worklist_all_tasks_completed",
|
|
555
|
-
completed_task_count: tasks.length,
|
|
556
|
-
module_count: worklist.modules.length,
|
|
557
|
-
};
|
|
556
|
+
notifyChatRequestsChanged() {
|
|
557
|
+
if (this.closing || !this.store.db.open)
|
|
558
|
+
return;
|
|
559
|
+
if (this.hasPendingChatRequests())
|
|
560
|
+
this.cancelPendingWorklistCompletionContextSync();
|
|
561
|
+
else
|
|
562
|
+
this.scheduleContextSyncAfterWorklistCompletion();
|
|
558
563
|
}
|
|
559
564
|
scheduleContextSyncAfterWorklistCompletion() {
|
|
560
565
|
if (this.closing ||
|
|
@@ -563,7 +568,8 @@ export class Phase5ControlPlane {
|
|
|
563
568
|
return;
|
|
564
569
|
}
|
|
565
570
|
const sourceState = readScratchpadSourceState(this.store.db);
|
|
566
|
-
if (this.
|
|
571
|
+
if (pendingContextSyncCompletion(this.store.db) === undefined ||
|
|
572
|
+
this.hasPendingChatRequests() ||
|
|
567
573
|
sourceState.dirty_since !== undefined ||
|
|
568
574
|
sourceState.in_flight !== undefined ||
|
|
569
575
|
this.readSchedulerBlocker() !== null) {
|
|
@@ -579,15 +585,16 @@ export class Phase5ControlPlane {
|
|
|
579
585
|
if (this.closing || !this.store.db.open) {
|
|
580
586
|
return;
|
|
581
587
|
}
|
|
582
|
-
const
|
|
588
|
+
const completion = pendingContextSyncCompletion(this.store.db);
|
|
583
589
|
const sourceState = readScratchpadSourceState(this.store.db);
|
|
584
|
-
if (
|
|
590
|
+
if (completion === undefined ||
|
|
591
|
+
this.hasPendingChatRequests() ||
|
|
585
592
|
sourceState.dirty_since !== undefined ||
|
|
586
593
|
sourceState.in_flight !== undefined ||
|
|
587
594
|
this.readSchedulerBlocker() !== null) {
|
|
588
595
|
return;
|
|
589
596
|
}
|
|
590
|
-
void this.
|
|
597
|
+
void this.startContextSync(completion.trigger, completion.key);
|
|
591
598
|
}
|
|
592
599
|
cancelPendingWorklistCompletionContextSync() {
|
|
593
600
|
if (this.pendingWorklistCompletionContextSyncTimer === null) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { materializeClarificationSuccessor, readActiveTaskCompileContext, readClarificationRoundProjection, readWorklistProjection, rollbackTaskCompileContext, } from "../collaboration-state/index.js";
|
|
2
2
|
import { withHostStoreTransaction } from "../store/index.js";
|
|
3
|
+
import { linkTaskCompileActivity } from "../collaboration-state/task-compile-requests.js";
|
|
3
4
|
import { clarificationInvalidates } from "./invalidations.js";
|
|
4
5
|
import { applyTaskCompileProcedureOutput } from "./task-compile-output.js";
|
|
5
6
|
import { readTaskCompileClarificationRounds } from "./task-compile-clarification-context.js";
|
|
@@ -27,6 +28,7 @@ export function startControlPlaneTaskCompileContinuation(options) {
|
|
|
27
28
|
summary: "Continuing task_compile from clarification input.",
|
|
28
29
|
now: options.now,
|
|
29
30
|
onTransition: (state) => {
|
|
31
|
+
linkTaskCompileActivity(options.store.db, workflowRef, state.activity.activity_ref);
|
|
30
32
|
options.publishProcedureTransition(state);
|
|
31
33
|
if (state.transition_kind === "terminal") {
|
|
32
34
|
options.onTerminal?.(state.activity.status === "failed"
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ExecutionStatusProjection, WorklistSubmissionStatus } from "@tutti/shared/schemas/api";
|
|
2
|
+
import type { SqliteDatabase } from "../store/index.js";
|
|
3
|
+
/** Pure projection of owned records. A missing receipt is never proof of failure. */
|
|
4
|
+
export declare function readTaskCompileRequestStatus(db: SqliteDatabase, execution: ExecutionStatusProjection, workflowRef?: string): WorklistSubmissionStatus | null;
|
|
5
|
+
export declare function readTaskCompileCommandRef(db: SqliteDatabase, commandId: string): string | undefined;
|
|
6
|
+
//# sourceMappingURL=task-compile-request-status.d.ts.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { readActiveClarificationProjection, readActiveTaskCompileContext, readPendingTaskCompileSubmission, } from "../collaboration-state/index.js";
|
|
2
|
+
/** Pure projection of owned records. A missing receipt is never proof of failure. */
|
|
3
|
+
export function readTaskCompileRequestStatus(db, execution, workflowRef) {
|
|
4
|
+
const row = workflowRef === undefined
|
|
5
|
+
? db
|
|
6
|
+
.prepare("SELECT * FROM task_compile_requests ORDER BY rowid DESC LIMIT 1")
|
|
7
|
+
.get()
|
|
8
|
+
: db
|
|
9
|
+
.prepare("SELECT * FROM task_compile_requests WHERE workflow_ref = ?")
|
|
10
|
+
.get(workflowRef);
|
|
11
|
+
if (row === undefined)
|
|
12
|
+
return null;
|
|
13
|
+
const common = {
|
|
14
|
+
operation: { kind: "worklist_submit", ref: row.workflow_ref },
|
|
15
|
+
created_at: row.created_at,
|
|
16
|
+
activity_ref: row.current_activity_ref,
|
|
17
|
+
};
|
|
18
|
+
if (db.prepare("SELECT 1 FROM scratchpad_receipts WHERE workflow_ref = ?").get(row.workflow_ref)) {
|
|
19
|
+
return { ...common, status: "succeeded", phase: "settled" };
|
|
20
|
+
}
|
|
21
|
+
if (row.failure_code !== null) {
|
|
22
|
+
return {
|
|
23
|
+
...common,
|
|
24
|
+
status: "failed",
|
|
25
|
+
phase: "settled",
|
|
26
|
+
failure: {
|
|
27
|
+
code: row.failure_code,
|
|
28
|
+
category: "internal",
|
|
29
|
+
recovery: "none",
|
|
30
|
+
diagnostic_id: row.workflow_ref,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const clarification = readActiveClarificationProjection(db);
|
|
35
|
+
if (clarification.state === "active" &&
|
|
36
|
+
clarification.thread.owner.kind === "task_compile" &&
|
|
37
|
+
clarification.thread.owner.workflow_ref === row.workflow_ref &&
|
|
38
|
+
clarification.round.status === "writable") {
|
|
39
|
+
return {
|
|
40
|
+
...common,
|
|
41
|
+
status: "waiting_input",
|
|
42
|
+
phase: "clarification",
|
|
43
|
+
round_id: clarification.round.id,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const activities = execution.active_activities ?? (execution.active_activity ? [execution.active_activity] : []);
|
|
47
|
+
const active = activities.find((entry) => entry.activity_ref === row.current_activity_ref || entry.workflow_ref === row.workflow_ref);
|
|
48
|
+
if (active !== undefined) {
|
|
49
|
+
const kind = active.workflow_kind;
|
|
50
|
+
const phase = kind === "scratchpad_refresh" ||
|
|
51
|
+
kind === "reference_summary_refresh" ||
|
|
52
|
+
kind === "project_context_bootstrap" ||
|
|
53
|
+
kind === "task_compile"
|
|
54
|
+
? kind
|
|
55
|
+
: "preparing";
|
|
56
|
+
return { ...common, activity_ref: active.activity_ref, status: "running", phase };
|
|
57
|
+
}
|
|
58
|
+
const ref = row.workflow_ref;
|
|
59
|
+
if (readPendingTaskCompileSubmission(db, ref) !== null ||
|
|
60
|
+
readActiveTaskCompileContext(db, ref) !== null) {
|
|
61
|
+
return { ...common, status: "running", phase: "preparing" };
|
|
62
|
+
}
|
|
63
|
+
return { ...common, status: "unknown", phase: "unconfirmed" };
|
|
64
|
+
}
|
|
65
|
+
export function readTaskCompileCommandRef(db, commandId) {
|
|
66
|
+
return db
|
|
67
|
+
.prepare("SELECT workflow_ref FROM task_compile_request_commands WHERE command_id = ?")
|
|
68
|
+
.get(commandId)?.workflow_ref;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=task-compile-request-status.js.map
|
|
@@ -12,10 +12,15 @@ import { enqueueControlPlaneIntent } from "./dispatch-intents.js";
|
|
|
12
12
|
import { materializePromptSourceMessages } from "./task-source-context.js";
|
|
13
13
|
import { materializeRecentReferences, readPendingRecentReferenceSummaryPaths, readRecentReferenceSources, } from "./recent-references.js";
|
|
14
14
|
import { startReferenceSummaryRefreshProcedure } from "./reference-summary-refresh.js";
|
|
15
|
+
import { linkTaskCompileActivity, closeFailedTaskCompileRequest, } from "../collaboration-state/task-compile-requests.js";
|
|
15
16
|
export function startControlPlaneTaskCompile(options) {
|
|
16
17
|
const activeContext = readActiveTaskCompileContext(options.store.db);
|
|
17
18
|
if (activeContext !== null) {
|
|
18
19
|
return {
|
|
20
|
+
result: {
|
|
21
|
+
submission_ref: activeContext.workflow_ref,
|
|
22
|
+
activity_ref: activeContext.captured_by_activity_ref,
|
|
23
|
+
},
|
|
19
24
|
disposition: {
|
|
20
25
|
kind: "already_running",
|
|
21
26
|
activity_ref: activeContext.captured_by_activity_ref,
|
|
@@ -25,6 +30,10 @@ export function startControlPlaneTaskCompile(options) {
|
|
|
25
30
|
const pendingSubmission = readPendingTaskCompileSubmission(options.store.db);
|
|
26
31
|
if (pendingSubmission !== null) {
|
|
27
32
|
return {
|
|
33
|
+
result: {
|
|
34
|
+
submission_ref: pendingSubmission.workflow_ref,
|
|
35
|
+
activity_ref: pendingSubmission.accepted_activity_ref,
|
|
36
|
+
},
|
|
28
37
|
disposition: {
|
|
29
38
|
kind: "already_running",
|
|
30
39
|
activity_ref: pendingSubmission.accepted_activity_ref,
|
|
@@ -72,7 +81,7 @@ export function startControlPlaneTaskCompile(options) {
|
|
|
72
81
|
},
|
|
73
82
|
};
|
|
74
83
|
}
|
|
75
|
-
|
|
84
|
+
const started = startScratchpadRefreshBeforeTaskCompileActivity({
|
|
76
85
|
...options,
|
|
77
86
|
runner: runnerResolution.runner,
|
|
78
87
|
sourceBatch,
|
|
@@ -86,6 +95,7 @@ export function startControlPlaneTaskCompile(options) {
|
|
|
86
95
|
now: options.now,
|
|
87
96
|
}),
|
|
88
97
|
});
|
|
98
|
+
return withSubmissionRef(started, taskCompileWorkflowRef);
|
|
89
99
|
}
|
|
90
100
|
if (!scratchpadHasSubmittableContent(scratchpad)) {
|
|
91
101
|
return { disposition: { kind: "scratchpad_empty" } };
|
|
@@ -108,7 +118,12 @@ export function startControlPlaneTaskCompile(options) {
|
|
|
108
118
|
now: options.now,
|
|
109
119
|
});
|
|
110
120
|
}
|
|
111
|
-
return started;
|
|
121
|
+
return withSubmissionRef(started, taskCompileWorkflowRef);
|
|
122
|
+
}
|
|
123
|
+
function withSubmissionRef(result, submissionRef) {
|
|
124
|
+
return result.disposition.kind === "accepted"
|
|
125
|
+
? { ...result, result: { ...result.result, submission_ref: submissionRef } }
|
|
126
|
+
: result;
|
|
112
127
|
}
|
|
113
128
|
function recordTaskCompileSubmissionIntent(options) {
|
|
114
129
|
return withHostStoreTransaction(options.store.db, (tx) => {
|
|
@@ -152,6 +167,7 @@ function startControlPlaneTaskCompileActivity(options) {
|
|
|
152
167
|
summary: "Compiling Scratchpad into Worklist tasks.",
|
|
153
168
|
now: options.now,
|
|
154
169
|
onTransition: (state) => {
|
|
170
|
+
linkTaskCompileActivity(options.store.db, options.taskCompileWorkflowRef, state.activity.activity_ref);
|
|
155
171
|
options.publishProcedureTransition(state);
|
|
156
172
|
if (state.transition_kind === "terminal") {
|
|
157
173
|
options.onChainTerminal?.(state.activity.status === "failed"
|
|
@@ -206,11 +222,16 @@ function startScratchpadRefreshBeforeTaskCompileActivity(options) {
|
|
|
206
222
|
summary: "Refreshing Scratchpad before submitting to Worklist.",
|
|
207
223
|
now: options.now,
|
|
208
224
|
onTransition: (state) => {
|
|
225
|
+
linkTaskCompileActivity(options.store.db, options.taskCompileWorkflowRef, state.activity.activity_ref);
|
|
209
226
|
options.publishProcedureTransition(state);
|
|
210
227
|
if (state.transition_kind !== "terminal") {
|
|
211
228
|
return;
|
|
212
229
|
}
|
|
213
230
|
if (state.activity.status !== "finished") {
|
|
231
|
+
rollbackTaskCompileContext(options.store.db, {
|
|
232
|
+
workflow_ref: options.taskCompileWorkflowRef,
|
|
233
|
+
now: options.now,
|
|
234
|
+
});
|
|
214
235
|
options.onChainTerminal?.({
|
|
215
236
|
state: "failed",
|
|
216
237
|
errorCode: "scratchpad_refresh_failed",
|
|
@@ -222,6 +243,10 @@ function startScratchpadRefreshBeforeTaskCompileActivity(options) {
|
|
|
222
243
|
}
|
|
223
244
|
const scratchpad = readScratchpadProjection(options.store.db);
|
|
224
245
|
if (!scratchpadHasSubmittableContent(scratchpad)) {
|
|
246
|
+
withHostStoreTransaction(options.store.db, (tx) => {
|
|
247
|
+
closeFailedTaskCompileRequest(tx, options.taskCompileWorkflowRef, options.now().toISOString(), "scratchpad_empty_after_refresh");
|
|
248
|
+
tx.prepare("DELETE FROM pending_task_compile_submissions WHERE workflow_ref = ?").run(options.taskCompileWorkflowRef);
|
|
249
|
+
});
|
|
225
250
|
options.onChainTerminal?.({
|
|
226
251
|
state: "failed",
|
|
227
252
|
errorCode: "scratchpad_empty_after_refresh",
|
|
@@ -230,6 +255,10 @@ function startScratchpadRefreshBeforeTaskCompileActivity(options) {
|
|
|
230
255
|
}
|
|
231
256
|
const next = startReferenceSummaryGateOrNextStage(options);
|
|
232
257
|
if (next.disposition.kind !== "accepted" && next.disposition.kind !== "already_running") {
|
|
258
|
+
rollbackTaskCompileContext(options.store.db, {
|
|
259
|
+
workflow_ref: options.taskCompileWorkflowRef,
|
|
260
|
+
now: options.now,
|
|
261
|
+
});
|
|
233
262
|
options.onChainTerminal?.({
|
|
234
263
|
state: "failed",
|
|
235
264
|
errorCode: "task_compile_stage_unavailable",
|
|
@@ -413,6 +442,10 @@ function startReferenceSummaryGateOrNextStage(options) {
|
|
|
413
442
|
});
|
|
414
443
|
registerReferenceSummaryGateWaiter(options, activeReferenceSummary.activity_ref);
|
|
415
444
|
return {
|
|
445
|
+
result: {
|
|
446
|
+
submission_ref: options.taskCompileWorkflowRef,
|
|
447
|
+
activity_ref: activeReferenceSummary.activity_ref,
|
|
448
|
+
},
|
|
416
449
|
disposition: {
|
|
417
450
|
kind: "already_running",
|
|
418
451
|
activity_ref: activeReferenceSummary.activity_ref,
|
|
@@ -514,6 +547,10 @@ function startProjectContextBootstrapActivity(options) {
|
|
|
514
547
|
return;
|
|
515
548
|
}
|
|
516
549
|
if (state.activity.status !== "finished") {
|
|
550
|
+
rollbackTaskCompileContext(options.store.db, {
|
|
551
|
+
workflow_ref: options.taskCompileWorkflowRef,
|
|
552
|
+
now: options.now,
|
|
553
|
+
});
|
|
517
554
|
options.onChainTerminal?.({ state: "failed", errorCode: "project_context_failed" });
|
|
518
555
|
return;
|
|
519
556
|
}
|
|
@@ -697,6 +734,7 @@ function readOrCaptureTaskCompileContext(input) {
|
|
|
697
734
|
captured_by_activity_ref: input.activityRef,
|
|
698
735
|
now: input.now,
|
|
699
736
|
});
|
|
737
|
+
linkTaskCompileActivity(tx, input.workflowRef, input.activityRef);
|
|
700
738
|
enqueueControlPlaneIntent(tx, {
|
|
701
739
|
kind: "task_compile_start",
|
|
702
740
|
ownerKind: "task_compile",
|