@xfey/tutti 0.1.126 → 0.1.128
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/README.md +2 -0
- package/dist/approvals/decision-command.d.ts +2 -2
- package/dist/chat-assistant/diagnostics.d.ts +11 -3
- package/dist/chat-assistant/diagnostics.js +5 -2
- package/dist/chat-assistant/failures.d.ts +27 -0
- package/dist/chat-assistant/failures.js +102 -0
- package/dist/chat-assistant/index.d.ts +14 -2
- package/dist/chat-assistant/index.js +241 -54
- package/dist/chat-assistant/language-context.d.ts +8 -0
- package/dist/chat-assistant/language-context.js +41 -0
- package/dist/chat-assistant/requests.d.ts +30 -0
- package/dist/chat-assistant/requests.js +58 -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/communication-language.d.ts +31 -0
- package/dist/collaboration-state/communication-language.js +36 -0
- package/dist/collaboration-state/task-compile-context.d.ts +1 -1
- package/dist/collaboration-state/task-compile-context.js +20 -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/index.d.ts +75 -0
- package/dist/communication-language/index.js +122 -0
- package/dist/communication-language/live-smoke-cli.d.ts +2 -0
- package/dist/communication-language/live-smoke-cli.js +368 -0
- package/dist/communication-language/prompt.d.ts +22 -0
- package/dist/communication-language/prompt.js +73 -0
- package/dist/control-plane/communication-language.d.ts +33 -0
- package/dist/control-plane/communication-language.js +72 -0
- package/dist/control-plane/context-sync.js +7 -0
- package/dist/control-plane/follow-up-output.js +25 -4
- package/dist/control-plane/follow-up-start.js +17 -0
- package/dist/control-plane/project-brief-refresh.js +10 -1
- package/dist/control-plane/project-context-bootstrap.d.ts +2 -0
- package/dist/control-plane/project-context-bootstrap.js +8 -0
- package/dist/control-plane/reference-summary-refresh.js +7 -0
- package/dist/control-plane/run-start.js +14 -6
- package/dist/control-plane/scratchpad-refresh-start.d.ts +1 -0
- package/dist/control-plane/scratchpad-refresh-start.js +13 -0
- package/dist/control-plane/scratchpad-refresh.d.ts +2 -0
- package/dist/control-plane/scratchpad-refresh.js +40 -26
- package/dist/control-plane/task-compile-continuation.js +16 -1
- package/dist/control-plane/task-compile-output.js +38 -14
- 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.d.ts +1 -0
- package/dist/control-plane/task-compile-start.js +62 -3
- package/dist/control-plane/types.d.ts +2 -0
- package/dist/control-plane/workflows/openai.js +48 -28
- package/dist/control-plane/workflows/types.d.ts +18 -13
- package/dist/prompt-templates/index.d.ts +1 -1
- package/dist/prompt-templates/index.js +2 -0
- package/dist/providers/failure-classification.d.ts +23 -0
- package/dist/providers/failure-classification.js +43 -0
- 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/run-pipeline/task-run-invocation.js +12 -9
- 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 +4 -1
- 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/0023_communication_language.sql +14 -0
- package/migrations/0024_chat_requests.sql +19 -0
- package/migrations/0025_task_compile_requests.sql +50 -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/prompts/README.md +1 -0
- package/prompts/chat-assistant.md +1 -1
- package/prompts/communication-language-result.md +27 -0
- package/prompts/communication-language.md +50 -0
- package/prompts/procedures/follow-up-check.md +1 -1
- package/prompts/procedures/scratchpad-refresh.md +2 -2
- package/prompts/procedures/task-compile.md +1 -1
- package/prompts/prompt-flow-map.md +2 -0
- package/web/assets/{homepage-motion-scene-DyEmWwvt.js → homepage-motion-scene-BcMt0AVW.js} +1 -1
- package/web/assets/index-2eX37Jx6.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
|
@@ -3,6 +3,8 @@ import { readFollowUpCheckInputFromStore } from "./follow-up-context.js";
|
|
|
3
3
|
import { applyFollowUpCheckOutput, closeTaskBoundFollowUpAsRetaskingRequired, } from "./follow-up-output.js";
|
|
4
4
|
import { startRunFromFollowUp as startRunFromFollowUpSuccessor } from "./follow-up-run.js";
|
|
5
5
|
import { logProcedureExecutionError } from "./procedure-logging.js";
|
|
6
|
+
import { workflowLanguageContext, sourceLanguageEvidence, messageLanguageEvidence, logLanguageContext, } from "./communication-language.js";
|
|
7
|
+
import { readScratchpadReceiptSourceRefs } from "../collaboration-state/index.js";
|
|
6
8
|
export function startControlPlaneTaskBoundFollowUpCheck(options) {
|
|
7
9
|
const runnerResolution = options.resolveWorkflowRunner();
|
|
8
10
|
if (runnerResolution.kind !== "ready" || runnerResolution.runner.runFollowUpCheck === undefined) {
|
|
@@ -79,6 +81,20 @@ export function startControlPlaneTaskBoundFollowUpCheck(options) {
|
|
|
79
81
|
});
|
|
80
82
|
}
|
|
81
83
|
const input = inputResult.input;
|
|
84
|
+
const submitted = new Set(input.submitted_message_refs);
|
|
85
|
+
input.communication_language = workflowLanguageContext(options.store.db, {
|
|
86
|
+
workflowRef: input.task_detail.task.created_from_workflow_ref,
|
|
87
|
+
taskId: input.task_id,
|
|
88
|
+
sources: sourceLanguageEvidence(options.store.db, readScratchpadReceiptSourceRefs(options.store.db, input.task_detail.task.created_from_workflow_ref)),
|
|
89
|
+
answers: input.round_messages
|
|
90
|
+
.filter((message) => submitted.has(message.id))
|
|
91
|
+
.map(messageLanguageEvidence),
|
|
92
|
+
});
|
|
93
|
+
logLanguageContext(options.logger, input.communication_language, {
|
|
94
|
+
workflow_ref: workflowRef,
|
|
95
|
+
activity_ref: context.activity_ref,
|
|
96
|
+
task_id: input.task_id,
|
|
97
|
+
});
|
|
82
98
|
output = await runnerResolution.runner.runFollowUpCheck?.(input, {
|
|
83
99
|
workflow_ref: workflowRef,
|
|
84
100
|
activity_ref: context.activity_ref,
|
|
@@ -90,6 +106,7 @@ export function startControlPlaneTaskBoundFollowUpCheck(options) {
|
|
|
90
106
|
result_anchor: { kind: "workflow", workflow_ref: workflowRef },
|
|
91
107
|
};
|
|
92
108
|
}
|
|
109
|
+
logLanguageContext(options.logger, input.communication_language, { workflow_ref: workflowRef, activity_ref: context.activity_ref, task_id: input.task_id }, output.communication_language);
|
|
93
110
|
return applyFollowUpCheckOutput({
|
|
94
111
|
store: options.store,
|
|
95
112
|
events: options.events,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readProjectBriefProjection, readProjectBriefSourceDocuments, upsertProjectBriefProjection, } from "../project-brief/index.js";
|
|
2
2
|
import { PROJECT_DOC_PATHS } from "../workspace-ops/index.js";
|
|
3
|
+
import { projectLanguageContext, logLanguageContext } from "./communication-language.js";
|
|
3
4
|
export function projectBriefShouldRefreshForUpdatedPaths(paths) {
|
|
4
5
|
return paths.some((path) => PROJECT_DOC_PATHS.includes(path));
|
|
5
6
|
}
|
|
@@ -57,7 +58,15 @@ export async function refreshProjectBriefProjection(input) {
|
|
|
57
58
|
}
|
|
58
59
|
let output;
|
|
59
60
|
try {
|
|
60
|
-
|
|
61
|
+
const language = projectLanguageContext(input.store.db, "summary");
|
|
62
|
+
logLanguageContext(input.logger, language, {
|
|
63
|
+
...(input.workflowRef === undefined ? {} : { workflow_ref: input.workflowRef }),
|
|
64
|
+
...(input.activityRef === undefined ? {} : { activity_ref: input.activityRef }),
|
|
65
|
+
});
|
|
66
|
+
output = await runner.runProjectBriefRefresh({
|
|
67
|
+
docs: sourceDocs,
|
|
68
|
+
communication_language: language,
|
|
69
|
+
}, input.workflowRef === undefined || input.activityRef === undefined
|
|
61
70
|
? undefined
|
|
62
71
|
: {
|
|
63
72
|
workflow_ref: input.workflowRef,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ActivityRef, WorkflowInvocationRef } from "@tutti/shared/ids";
|
|
2
2
|
import type { ScratchpadContentSnapshot } from "../collaboration-state/index.js";
|
|
3
|
+
import type { CommunicationLanguageContext } from "../communication-language/index.js";
|
|
3
4
|
import type { ProcedureProgressUpdate } from "../procedure-engine/index.js";
|
|
4
5
|
import type { WorkspaceEventBus } from "../server-shell/http/workspace-events.js";
|
|
5
6
|
import type { InitializeProjectDocsResult, ProjectDocsInitializationContext, ProjectDocsInitializationDocument } from "../workspace-ops/index.js";
|
|
@@ -14,6 +15,7 @@ export declare function buildProjectContextBootstrapWorkflowInput(options: {
|
|
|
14
15
|
}): ProjectContextBootstrapWorkflowInput | undefined;
|
|
15
16
|
export declare function projectContextBootstrapDocuments(output: ProjectContextBootstrapWorkflowOutput): ProjectDocsInitializationDocument[];
|
|
16
17
|
export declare function tryProjectContextBootstrapDocuments(input: {
|
|
18
|
+
communicationLanguage?: CommunicationLanguageContext;
|
|
17
19
|
runner: ProcedureWorkflowRunner;
|
|
18
20
|
projectContext: Phase5ControlPlaneOptions["projectContext"];
|
|
19
21
|
scratchpad: ScratchpadContentSnapshot;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { projectDocPath, readProjectDocsSummaries } from "../project-docs/context.js";
|
|
2
2
|
import { projectContextBootstrapInvalidates } from "./invalidations.js";
|
|
3
|
+
import { logLanguageContext } from "./communication-language.js";
|
|
3
4
|
export function buildProjectDocsInitializationContext(scratchpad) {
|
|
4
5
|
return {
|
|
5
6
|
source: "scratchpad_submit",
|
|
@@ -56,6 +57,13 @@ export async function tryProjectContextBootstrapDocuments(input) {
|
|
|
56
57
|
if (workflowInput === undefined) {
|
|
57
58
|
return undefined;
|
|
58
59
|
}
|
|
60
|
+
if (input.communicationLanguage !== undefined) {
|
|
61
|
+
workflowInput.communication_language = input.communicationLanguage;
|
|
62
|
+
logLanguageContext(input.logger, input.communicationLanguage, {
|
|
63
|
+
workflow_ref: input.workflowRef,
|
|
64
|
+
activity_ref: input.activityRef,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
59
67
|
try {
|
|
60
68
|
const output = await input.runner.runProjectContextBootstrap(workflowInput, {
|
|
61
69
|
workflow_ref: input.workflowRef,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createWorkflowInvocationRef } from "@tutti/shared/ids";
|
|
2
|
+
import { projectLanguageContext, logLanguageContext } from "./communication-language.js";
|
|
2
3
|
import { recordProjectTimelineEvent } from "../project-timeline/index.js";
|
|
3
4
|
import { withHostStoreTransaction } from "../store/index.js";
|
|
4
5
|
import { WorkspaceOpsError, readReferenceSummaryTargets, updateReferenceSummaries, } from "../workspace-ops/index.js";
|
|
@@ -89,6 +90,7 @@ async function runReferenceSummaryRefresh(options) {
|
|
|
89
90
|
let completedInBatch = 0;
|
|
90
91
|
const batchResults = await mapWithConcurrency(batch, REFERENCE_SUMMARY_CONCURRENCY, async (target) => {
|
|
91
92
|
const result = await summarizeReferenceTarget({
|
|
93
|
+
communicationLanguage: projectLanguageContext(options.store.db, "summary"),
|
|
92
94
|
target,
|
|
93
95
|
runner: options.runner,
|
|
94
96
|
workflowRef: options.workflowRef,
|
|
@@ -211,7 +213,12 @@ async function mapWithConcurrency(items, concurrency, worker) {
|
|
|
211
213
|
async function summarizeReferenceTarget(options) {
|
|
212
214
|
for (let attempt = 1; attempt <= REFERENCE_SUMMARY_MAX_ATTEMPTS; attempt += 1) {
|
|
213
215
|
try {
|
|
216
|
+
logLanguageContext(options.logger, options.communicationLanguage, {
|
|
217
|
+
workflow_ref: options.workflowRef,
|
|
218
|
+
activity_ref: options.activityRef,
|
|
219
|
+
});
|
|
214
220
|
const output = await options.runner.runReferenceFileSummary?.({
|
|
221
|
+
communication_language: options.communicationLanguage,
|
|
215
222
|
workflow_ref: options.workflowRef,
|
|
216
223
|
activity_ref: options.activityRef,
|
|
217
224
|
file: {
|
|
@@ -2,8 +2,9 @@ import { readScratchpadReceiptSourceRefs } from "../collaboration-state/index.js
|
|
|
2
2
|
import { materializeWorkflowRecentReferences } from "./recent-references.js";
|
|
3
3
|
import { readCompletedTaskCompileClarificationRounds } from "./task-compile-clarification-context.js";
|
|
4
4
|
import { materializePromptSourceMessages } from "./task-source-context.js";
|
|
5
|
-
import { recordRunPipelineFailure, recordRunPipelineResult
|
|
5
|
+
import { recordRunPipelineFailure, recordRunPipelineResult } from "./run-result-recording.js";
|
|
6
6
|
import { projectBriefShouldRefreshForUpdatedPaths, refreshProjectBriefProjection, } from "./project-brief-refresh.js";
|
|
7
|
+
import { workflowLanguageContext, sourceLanguageEvidence, logLanguageContext, } from "./communication-language.js";
|
|
7
8
|
function runLineageFields(lineage) {
|
|
8
9
|
return {
|
|
9
10
|
run_lineage_kind: lineage.kind,
|
|
@@ -83,8 +84,7 @@ export function startControlPlaneRunForTask(input) {
|
|
|
83
84
|
const pipelineStartedAt = input.now();
|
|
84
85
|
input.logger?.info(lifecycleFields, "Run pipeline started");
|
|
85
86
|
try {
|
|
86
|
-
const workflowRef = input.run.task
|
|
87
|
-
.created_from_workflow_ref;
|
|
87
|
+
const workflowRef = input.run.task.created_from_workflow_ref;
|
|
88
88
|
const sourceMessages = materializePromptSourceMessages(input.store.db, readScratchpadReceiptSourceRefs(input.store.db, workflowRef));
|
|
89
89
|
const clarificationRounds = readCompletedTaskCompileClarificationRounds({
|
|
90
90
|
store: input.store,
|
|
@@ -98,7 +98,17 @@ export function startControlPlaneRunForTask(input) {
|
|
|
98
98
|
workflowRef,
|
|
99
99
|
now: input.now,
|
|
100
100
|
});
|
|
101
|
+
const language = workflowLanguageContext(input.store.db, {
|
|
102
|
+
workflowRef,
|
|
103
|
+
taskId: input.run.task.id,
|
|
104
|
+
sources: sourceLanguageEvidence(input.store.db, readScratchpadReceiptSourceRefs(input.store.db, workflowRef)),
|
|
105
|
+
});
|
|
106
|
+
logLanguageContext(input.logger, language, {
|
|
107
|
+
activity_ref: context.activity_ref,
|
|
108
|
+
task_id: input.run.task.id,
|
|
109
|
+
});
|
|
101
110
|
const pipelineResult = await input.run.runner.runTask({
|
|
111
|
+
communication_language: language,
|
|
102
112
|
activity_ref: context.activity_ref,
|
|
103
113
|
task: input.run.task,
|
|
104
114
|
task_detail: input.run.task_detail,
|
|
@@ -114,9 +124,7 @@ export function startControlPlaneRunForTask(input) {
|
|
|
114
124
|
...(clarificationRounds.length === 0
|
|
115
125
|
? {}
|
|
116
126
|
: { clarification_rounds: clarificationRounds }),
|
|
117
|
-
...(recentReferences.length === 0
|
|
118
|
-
? {}
|
|
119
|
-
: { recent_references: recentReferences }),
|
|
127
|
+
...(recentReferences.length === 0 ? {} : { recent_references: recentReferences }),
|
|
120
128
|
on_stage: (progress) => context.reportProgress({
|
|
121
129
|
phase: progress.stage,
|
|
122
130
|
summary: runStageSummary(input.run, progress),
|
|
@@ -30,6 +30,7 @@ export declare function runControlPlaneScratchpadRefreshProcedure(options: {
|
|
|
30
30
|
events: WorkspaceEventBus;
|
|
31
31
|
sourceBatch: ScratchpadSourceBatch;
|
|
32
32
|
lane: ProcedureLane;
|
|
33
|
+
logger?: ControlPlaneLogger | undefined;
|
|
33
34
|
recordRecoveryIntent?: boolean;
|
|
34
35
|
recoveryIntentId?: ControlPlaneIntentId;
|
|
35
36
|
now: () => Date;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createWorkflowInvocationRef, } from "@tutti/shared/ids";
|
|
2
2
|
import { readActiveTaskCompileContext, readMainChatMessagesForScratchpadCycle, readScratchpadSourceState, readWorklistProjection, markScratchpadRefreshFailed, markScratchpadRefreshStarted, } from "../collaboration-state/index.js";
|
|
3
|
+
import { projectLanguageContext, messageLanguageEvidence, logLanguageContext, } from "./communication-language.js";
|
|
3
4
|
import { readProjectBriefProjection, readProjectBriefSourceDocuments, } from "../project-brief/index.js";
|
|
4
5
|
import { withHostStoreTransaction } from "../store/index.js";
|
|
5
6
|
import { logProcedureExecutionError } from "./procedure-logging.js";
|
|
@@ -37,6 +38,7 @@ function workflowInputSize(input) {
|
|
|
37
38
|
}
|
|
38
39
|
function fitScratchpadRefreshWorkflowInput(input) {
|
|
39
40
|
const base = {
|
|
41
|
+
communication_language: input.language,
|
|
40
42
|
...(input.projectBrief === undefined ? {} : { project_brief: input.projectBrief }),
|
|
41
43
|
...(input.activeTaskCompile === undefined
|
|
42
44
|
? {}
|
|
@@ -107,6 +109,7 @@ export function readControlPlaneScratchpadSourceBatch(store, options = {}) {
|
|
|
107
109
|
...(activeContext === null ? {} : { activeTaskCompile: activeContext.scratchpad_snapshot }),
|
|
108
110
|
worklist: readWorklistProjection(store.db),
|
|
109
111
|
sourceMessages,
|
|
112
|
+
language: projectLanguageContext(store.db, "scratchpad", sourceMessages.map(messageLanguageEvidence)),
|
|
110
113
|
});
|
|
111
114
|
return {
|
|
112
115
|
workflow_input: workflowInput,
|
|
@@ -146,6 +149,12 @@ export async function runControlPlaneScratchpadRefreshProcedure(options) {
|
|
|
146
149
|
now: options.now,
|
|
147
150
|
});
|
|
148
151
|
});
|
|
152
|
+
const language = options.sourceBatch.workflow_input.communication_language;
|
|
153
|
+
if (language !== undefined)
|
|
154
|
+
logLanguageContext(options.logger, language, {
|
|
155
|
+
workflow_ref: options.workflowRef,
|
|
156
|
+
activity_ref: options.activityRef,
|
|
157
|
+
});
|
|
149
158
|
let output;
|
|
150
159
|
try {
|
|
151
160
|
output = await options.runner.runScratchpadRefresh(options.sourceBatch.workflow_input, {
|
|
@@ -160,6 +169,8 @@ export async function runControlPlaneScratchpadRefreshProcedure(options) {
|
|
|
160
169
|
});
|
|
161
170
|
throw error;
|
|
162
171
|
}
|
|
172
|
+
if (language !== undefined)
|
|
173
|
+
logLanguageContext(options.logger, language, { workflow_ref: options.workflowRef, activity_ref: options.activityRef }, output.communication_language);
|
|
163
174
|
return applyScratchpadRefreshOutput({
|
|
164
175
|
store: options.store,
|
|
165
176
|
events: options.events,
|
|
@@ -169,6 +180,7 @@ export async function runControlPlaneScratchpadRefreshProcedure(options) {
|
|
|
169
180
|
cursorUpdate: options.sourceBatch.cursor_update,
|
|
170
181
|
sourceRefs: options.sourceBatch.source_refs,
|
|
171
182
|
now: options.now,
|
|
183
|
+
...(language === undefined ? {} : { languageContext: language }),
|
|
172
184
|
});
|
|
173
185
|
}
|
|
174
186
|
export function readActiveScratchpadRefreshActivityRef(options) {
|
|
@@ -247,6 +259,7 @@ export function startControlPlaneScratchpadRefresh(options) {
|
|
|
247
259
|
error,
|
|
248
260
|
}),
|
|
249
261
|
execute: async (context) => runControlPlaneScratchpadRefreshProcedure({
|
|
262
|
+
logger: options.logger,
|
|
250
263
|
runner: runnerResolution.runner,
|
|
251
264
|
workflowRef,
|
|
252
265
|
activityRef: context.activity_ref,
|
|
@@ -3,6 +3,7 @@ import type { ScratchpadSourceCursorUpdate } from "../collaboration-state/scratc
|
|
|
3
3
|
import type { ScratchpadSourceRefInput } from "../collaboration-state/types.js";
|
|
4
4
|
import type { WorkspaceEventBus } from "../server-shell/http/workspace-events.js";
|
|
5
5
|
import type { HostProjectStore } from "../store/index.js";
|
|
6
|
+
import type { CommunicationLanguageContext } from "../communication-language/index.js";
|
|
6
7
|
import type { ScratchpadRefreshWorkflowOutput } from "./workflows/index.js";
|
|
7
8
|
export declare function applyScratchpadRefreshOutput(input: {
|
|
8
9
|
store: HostProjectStore;
|
|
@@ -13,6 +14,7 @@ export declare function applyScratchpadRefreshOutput(input: {
|
|
|
13
14
|
cursorUpdate: ScratchpadSourceCursorUpdate;
|
|
14
15
|
sourceRefs: ScratchpadSourceRefInput[];
|
|
15
16
|
now: () => Date;
|
|
17
|
+
languageContext?: CommunicationLanguageContext;
|
|
16
18
|
}): {
|
|
17
19
|
kind: "needs_human";
|
|
18
20
|
summary: string;
|
|
@@ -1,44 +1,58 @@
|
|
|
1
|
-
import { createMainChatAgentMessage, markScratchpadRefreshSucceeded, upsertScratchpadProjection, } from "../collaboration-state/index.js";
|
|
1
|
+
import { createMainChatAgentMessage, markScratchpadRefreshSucceeded, upsertScratchpadProjection, readMessageProjectionById, } from "../collaboration-state/index.js";
|
|
2
|
+
import { withHostStoreTransaction } from "../store/index.js";
|
|
3
|
+
import { recordScratchpadLanguage } from "./communication-language.js";
|
|
2
4
|
import { mainChatInvalidates, scratchpadRefreshInvalidates } from "./invalidations.js";
|
|
3
5
|
export function applyScratchpadRefreshOutput(input) {
|
|
6
|
+
const persistLanguage = () => recordScratchpadLanguage(input.store.db, {
|
|
7
|
+
...(input.output.communication_language === undefined
|
|
8
|
+
? {}
|
|
9
|
+
: { language: input.output.communication_language }),
|
|
10
|
+
...(input.languageContext === undefined ? {} : { context: input.languageContext }),
|
|
11
|
+
sourceMessages: input.sourceRefs.flatMap((source) => {
|
|
12
|
+
const message = readMessageProjectionById(input.store.db, source.message_id);
|
|
13
|
+
return message === null ? [] : [message];
|
|
14
|
+
}),
|
|
15
|
+
activityRef: input.activityRef,
|
|
16
|
+
snapshot: input.output.decision === "ready",
|
|
17
|
+
now: input.now,
|
|
18
|
+
});
|
|
4
19
|
if (input.output.decision === "needs_human") {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
20
|
+
const request = input.output.request_payload.request;
|
|
21
|
+
const message = withHostStoreTransaction(input.store.db, () => {
|
|
22
|
+
persistLanguage();
|
|
23
|
+
markScratchpadRefreshSucceeded(input.store.db, { ...input.cursorUpdate, now: input.now });
|
|
24
|
+
return createMainChatAgentMessage(input.store.db, {
|
|
25
|
+
body: request,
|
|
26
|
+
refs: {
|
|
27
|
+
workflow_ref: input.workflowRef,
|
|
28
|
+
activity_ref: input.activityRef,
|
|
29
|
+
scratchpad_source: "exclude",
|
|
30
|
+
},
|
|
31
|
+
now: input.now,
|
|
32
|
+
});
|
|
13
33
|
});
|
|
14
34
|
input.events.publish({
|
|
15
35
|
event_type: "message.created",
|
|
16
36
|
payload: { message },
|
|
17
37
|
invalidates: mainChatInvalidates(),
|
|
18
38
|
});
|
|
19
|
-
markScratchpadRefreshSucceeded(input.store.db, {
|
|
20
|
-
...input.cursorUpdate,
|
|
21
|
-
now: input.now,
|
|
22
|
-
});
|
|
23
39
|
return {
|
|
24
40
|
kind: "needs_human",
|
|
25
41
|
summary: input.output.request_payload.summary,
|
|
26
42
|
result_anchor: { kind: "workflow", workflow_ref: input.workflowRef },
|
|
27
43
|
};
|
|
28
44
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
...input.cursorUpdate,
|
|
41
|
-
now: input.now,
|
|
45
|
+
const snapshot = input.output.scratchpad_snapshot;
|
|
46
|
+
const scratchpad = withHostStoreTransaction(input.store.db, () => {
|
|
47
|
+
persistLanguage();
|
|
48
|
+
const projection = upsertScratchpadProjection(input.store.db, {
|
|
49
|
+
...snapshot,
|
|
50
|
+
source_refs: input.sourceRefs,
|
|
51
|
+
updated_by_activity_ref: input.activityRef,
|
|
52
|
+
now: input.now,
|
|
53
|
+
});
|
|
54
|
+
markScratchpadRefreshSucceeded(input.store.db, { ...input.cursorUpdate, now: input.now });
|
|
55
|
+
return projection;
|
|
42
56
|
});
|
|
43
57
|
input.events.publish({
|
|
44
58
|
event_type: "scratchpad.updated",
|
|
@@ -1,11 +1,13 @@
|
|
|
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";
|
|
6
7
|
import { materializePromptSourceMessages } from "./task-source-context.js";
|
|
7
8
|
import { logProcedureExecutionError } from "./procedure-logging.js";
|
|
8
9
|
import { materializeRecentReferences, readRecentReferenceSources } from "./recent-references.js";
|
|
10
|
+
import { workflowLanguageContext, sourceLanguageEvidence, logLanguageContext, } from "./communication-language.js";
|
|
9
11
|
export function startControlPlaneTaskCompileContinuation(options) {
|
|
10
12
|
if (options.owner.kind !== "task_compile") {
|
|
11
13
|
return { kind: "obsolete", errorCode: "owner_kind_mismatch" };
|
|
@@ -26,6 +28,7 @@ export function startControlPlaneTaskCompileContinuation(options) {
|
|
|
26
28
|
summary: "Continuing task_compile from clarification input.",
|
|
27
29
|
now: options.now,
|
|
28
30
|
onTransition: (state) => {
|
|
31
|
+
linkTaskCompileActivity(options.store.db, workflowRef, state.activity.activity_ref);
|
|
29
32
|
options.publishProcedureTransition(state);
|
|
30
33
|
if (state.transition_kind === "terminal") {
|
|
31
34
|
options.onTerminal?.(state.activity.status === "failed"
|
|
@@ -59,10 +62,21 @@ export function startControlPlaneTaskCompileContinuation(options) {
|
|
|
59
62
|
sources: readRecentReferenceSources(options.store.db, taskCompileContext.sources),
|
|
60
63
|
now: options.now,
|
|
61
64
|
});
|
|
65
|
+
const sourceMessages = materializePromptSourceMessages(options.store.db, taskCompileContext.sources);
|
|
66
|
+
const language = workflowLanguageContext(options.store.db, {
|
|
67
|
+
workflowRef,
|
|
68
|
+
sources: sourceLanguageEvidence(options.store.db, taskCompileContext.sources),
|
|
69
|
+
answers: clarificationRounds.flatMap((entry) => entry.answer_messages),
|
|
70
|
+
});
|
|
71
|
+
logLanguageContext(options.logger, language, {
|
|
72
|
+
workflow_ref: workflowRef,
|
|
73
|
+
activity_ref: context.activity_ref,
|
|
74
|
+
});
|
|
62
75
|
const output = await runnerResolution.runner.runTaskCompile({
|
|
76
|
+
communication_language: language,
|
|
63
77
|
workflow_ref: workflowRef,
|
|
64
78
|
scratchpad: taskCompileContext.scratchpad_snapshot,
|
|
65
|
-
source_messages:
|
|
79
|
+
source_messages: sourceMessages,
|
|
66
80
|
worklist: readWorklistProjection(options.store.db),
|
|
67
81
|
...(recentReferences.length === 0 ? {} : { recent_references: recentReferences }),
|
|
68
82
|
clarification_rounds: clarificationRounds,
|
|
@@ -71,6 +85,7 @@ export function startControlPlaneTaskCompileContinuation(options) {
|
|
|
71
85
|
activity_ref: context.activity_ref,
|
|
72
86
|
reportProgress: context.reportProgress,
|
|
73
87
|
});
|
|
88
|
+
logLanguageContext(options.logger, language, { workflow_ref: workflowRef, activity_ref: context.activity_ref }, output.communication_language);
|
|
74
89
|
return applyTaskCompileProcedureOutput({
|
|
75
90
|
store: options.store,
|
|
76
91
|
events: options.events,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { applyTaskCompileProposal, completeTaskCompileContext, materializeClarificationSuccessor, openNextTaskCompileClarificationRound, openTaskCompileClarificationRound, readClarificationRoundProjection, readWorklistProjection, } from "../collaboration-state/index.js";
|
|
2
2
|
import { withHostStoreTransaction } from "../store/index.js";
|
|
3
|
-
import { clarificationInvalidates, taskCompileInvalidates
|
|
3
|
+
import { clarificationInvalidates, taskCompileInvalidates } from "./invalidations.js";
|
|
4
4
|
import { normalizeTaskCompileProposal } from "./task-proposal.js";
|
|
5
|
+
import { recordWorkflowLanguage } from "./communication-language.js";
|
|
5
6
|
const EMPTY_INITIAL_WORKLIST_CLARIFICATION = {
|
|
6
7
|
title: "Worklist scope needed",
|
|
7
8
|
summary: "No existing Worklist task covers this Scratchpad, and no new task was produced.",
|
|
@@ -11,20 +12,28 @@ function countWorklistTasks(worklist) {
|
|
|
11
12
|
return worklist.modules.reduce((count, module) => count + module.tasks.length, 0);
|
|
12
13
|
}
|
|
13
14
|
function openTaskCompileNeedsHuman(input) {
|
|
14
|
-
const opened = input.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
now: input.now,
|
|
20
|
-
})
|
|
21
|
-
: openNextTaskCompileClarificationRound(input.store.db, {
|
|
22
|
-
continue_from_round_id: input.continueFromRoundId,
|
|
23
|
-
workflow_ref: input.workflowRef,
|
|
24
|
-
activity_ref: input.activityRef,
|
|
25
|
-
request_payload: input.requestPayload,
|
|
15
|
+
const opened = withHostStoreTransaction(input.store.db, (tx) => {
|
|
16
|
+
recordWorkflowLanguage(tx, {
|
|
17
|
+
owner: { kind: "workflow", ref: input.workflowRef },
|
|
18
|
+
...(input.language === undefined ? {} : { language: input.language }),
|
|
19
|
+
activityRef: input.activityRef,
|
|
26
20
|
now: input.now,
|
|
27
21
|
});
|
|
22
|
+
return input.continueFromRoundId === undefined
|
|
23
|
+
? openTaskCompileClarificationRound(input.store.db, {
|
|
24
|
+
workflow_ref: input.workflowRef,
|
|
25
|
+
activity_ref: input.activityRef,
|
|
26
|
+
request_payload: input.requestPayload,
|
|
27
|
+
now: input.now,
|
|
28
|
+
})
|
|
29
|
+
: openNextTaskCompileClarificationRound(input.store.db, {
|
|
30
|
+
continue_from_round_id: input.continueFromRoundId,
|
|
31
|
+
workflow_ref: input.workflowRef,
|
|
32
|
+
activity_ref: input.activityRef,
|
|
33
|
+
request_payload: input.requestPayload,
|
|
34
|
+
now: input.now,
|
|
35
|
+
});
|
|
36
|
+
});
|
|
28
37
|
const roundId = opened.round.id;
|
|
29
38
|
if (input.continueFromRoundId !== undefined) {
|
|
30
39
|
input.events.publish({
|
|
@@ -66,9 +75,13 @@ function openTaskCompileNeedsHuman(input) {
|
|
|
66
75
|
}
|
|
67
76
|
export function applyTaskCompileProcedureOutput(input) {
|
|
68
77
|
if (input.output.decision === "needs_human") {
|
|
78
|
+
const requestPayload = input.output.clarification_request_payload;
|
|
69
79
|
return openTaskCompileNeedsHuman({
|
|
70
80
|
...input,
|
|
71
|
-
requestPayload
|
|
81
|
+
requestPayload,
|
|
82
|
+
...(input.output.communication_language === undefined
|
|
83
|
+
? {}
|
|
84
|
+
: { language: input.output.communication_language }),
|
|
72
85
|
});
|
|
73
86
|
}
|
|
74
87
|
const currentWorklist = readWorklistProjection(input.store.db);
|
|
@@ -79,12 +92,23 @@ export function applyTaskCompileProcedureOutput(input) {
|
|
|
79
92
|
return openTaskCompileNeedsHuman({
|
|
80
93
|
...input,
|
|
81
94
|
requestPayload: EMPTY_INITIAL_WORKLIST_CLARIFICATION,
|
|
95
|
+
...(input.output.communication_language === undefined
|
|
96
|
+
? {}
|
|
97
|
+
: { language: input.output.communication_language }),
|
|
82
98
|
});
|
|
83
99
|
}
|
|
84
100
|
const continuationRound = input.continueFromRoundId === undefined
|
|
85
101
|
? null
|
|
86
102
|
: readClarificationRoundProjection(input.store.db, input.continueFromRoundId);
|
|
87
103
|
const committed = withHostStoreTransaction(input.store.db, (tx) => {
|
|
104
|
+
recordWorkflowLanguage(tx, {
|
|
105
|
+
owner: { kind: "workflow", ref: input.workflowRef },
|
|
106
|
+
...(input.output.communication_language === undefined
|
|
107
|
+
? {}
|
|
108
|
+
: { language: input.output.communication_language }),
|
|
109
|
+
activityRef: input.activityRef,
|
|
110
|
+
now: input.now,
|
|
111
|
+
});
|
|
88
112
|
const applied = applyTaskCompileProposal(tx, {
|
|
89
113
|
workflow_ref: input.workflowRef,
|
|
90
114
|
proposal,
|
|
@@ -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
|
|
@@ -52,6 +52,7 @@ export declare function resumeControlPlaneTaskCompileChain(options: {
|
|
|
52
52
|
onChainTerminal: (result?: IntentRuntimeTerminal) => void;
|
|
53
53
|
}): IntentRuntimeStartResult;
|
|
54
54
|
export declare function runControlPlaneTaskCompileProcedure(options: {
|
|
55
|
+
logger?: ControlPlaneLogger | undefined;
|
|
55
56
|
runner: ProcedureWorkflowRunner;
|
|
56
57
|
workflowRef: WorkflowInvocationRef;
|
|
57
58
|
activityRef: ActivityRef;
|