@xfey/tutti 0.1.111 → 0.1.113
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/index.d.ts +1 -1
- package/dist/chat-assistant/index.js +19 -6
- package/dist/collaboration-ingestion/clarification.d.ts +25 -0
- package/dist/collaboration-ingestion/clarification.js +63 -0
- package/dist/collaboration-ingestion/external-source.d.ts +2 -0
- package/dist/collaboration-ingestion/external-source.js +35 -0
- package/dist/collaboration-ingestion/index.d.ts +2 -0
- package/dist/collaboration-ingestion/index.js +2 -0
- package/dist/collaboration-ingestion/platform-clarification.d.ts +10 -0
- package/dist/collaboration-ingestion/platform-clarification.js +42 -0
- package/dist/collaboration-state/clarification-messages.js +3 -2
- package/dist/collaboration-state/clarification-records.d.ts +1 -1
- package/dist/collaboration-state/clarification-records.js +7 -5
- package/dist/collaboration-state/clarification-rounds.js +5 -5
- package/dist/collaboration-state/clarification-snapshot.d.ts +228 -0
- package/dist/collaboration-state/clarification-snapshot.js +29 -0
- package/dist/collaboration-state/clarification-successors.js +6 -6
- package/dist/collaboration-state/index.d.ts +1 -0
- package/dist/collaboration-state/index.js +1 -0
- package/dist/collaboration-state/run-recording.js +1 -1
- package/dist/collaboration-state/task-compile-context.d.ts +1 -1
- package/dist/collaboration-state/types.d.ts +1 -0
- package/dist/control-plane/clarification-commands.d.ts +3 -2
- package/dist/control-plane/clarification-commands.js +13 -4
- package/dist/control-plane/follow-up-context.js +8 -14
- package/dist/control-plane/index.d.ts +3 -2
- package/dist/control-plane/task-compile-clarification-context.js +7 -2
- package/dist/control-plane/types.d.ts +1 -0
- package/dist/control-plane/workflows/openai.js +5 -4
- package/dist/platform-outbound/repository.js +83 -4
- package/dist/server-shell/cli/host-lifecycle.js +1 -0
- package/dist/server-shell/cli/host-server-runtime.d.ts +2 -1
- package/dist/server-shell/cli/host-server-runtime.js +4 -2
- package/dist/server-shell/cli/relay-registration.js +1 -0
- package/dist/server-shell/http/host-tunnel.d.ts +2 -1
- package/dist/server-shell/http/host-tunnel.js +4 -1
- package/dist/server-shell/http/integration-clarification-dispatch.d.ts +6 -0
- package/dist/server-shell/http/integration-clarification-dispatch.js +43 -0
- package/dist/server-shell/http/routes/project-api/clarification-routes.js +16 -42
- package/dist/server-shell/http/routes/project-api/openapi-collaboration-routes.d.ts +2 -0
- package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.d.ts +1 -0
- package/dist/server-shell/http/routes/project-api/openapi.d.ts +3 -0
- package/dist/server-shell/http/routes/project-api/schemas.d.ts +1 -0
- package/migrations/0022_clarification_projection_cursors.sql +7 -0
- package/node_modules/@tutti/relay-client/dist/host-control.d.ts +1 -0
- package/node_modules/@tutti/relay-client/dist/host-control.js +3 -0
- package/node_modules/@tutti/shared/dist/schemas/api/clarifications.d.ts +13 -1
- package/node_modules/@tutti/shared/dist/schemas/api/clarifications.js +9 -2
- package/node_modules/@tutti/shared/dist/schemas/internal/index.d.ts +2 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/index.js +2 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/platform-clarification-content.d.ts +15 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/platform-clarification-content.js +24 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/platform-clarification.d.ts +354 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/platform-clarification.js +94 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/platform-integration.d.ts +89 -3
- package/node_modules/@tutti/shared/dist/schemas/internal/platform-integration.js +15 -3
- package/node_modules/@tutti/shared/dist/utils/clarification-participants.d.ts +4 -0
- package/node_modules/@tutti/shared/dist/utils/clarification-participants.js +11 -0
- package/node_modules/@tutti/shared/dist/utils/index.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/utils/index.js +1 -0
- package/package.json +1 -1
- package/prompts/procedures/follow-up-check.md +4 -4
- package/web/assets/{homepage-motion-scene-TmkKf8wQ.js → homepage-motion-scene-BwdH6Iss.js} +1 -1
- package/web/assets/index-B29RuNsd.js +69 -0
- package/web/index.html +1 -1
- package/web/assets/index-B1oL1p9_.js +0 -69
|
@@ -22,6 +22,7 @@ export declare function executeApprovalDecisionCommand(input: {
|
|
|
22
22
|
approval?: {
|
|
23
23
|
state: "none";
|
|
24
24
|
} | {
|
|
25
|
+
state: "pending";
|
|
25
26
|
request: {
|
|
26
27
|
task_id?: string;
|
|
27
28
|
activity_ref?: string;
|
|
@@ -64,8 +65,8 @@ export declare function executeApprovalDecisionCommand(input: {
|
|
|
64
65
|
request_kind: "command_execution" | "file_change" | "permissions" | "legacy_exec_command" | "legacy_apply_patch";
|
|
65
66
|
requested_at: string;
|
|
66
67
|
};
|
|
67
|
-
state: "pending";
|
|
68
68
|
} | {
|
|
69
|
+
state: "resolved";
|
|
69
70
|
request: {
|
|
70
71
|
task_id?: string;
|
|
71
72
|
activity_ref?: string;
|
|
@@ -108,7 +109,6 @@ export declare function executeApprovalDecisionCommand(input: {
|
|
|
108
109
|
request_kind: "command_execution" | "file_change" | "permissions" | "legacy_exec_command" | "legacy_apply_patch";
|
|
109
110
|
requested_at: string;
|
|
110
111
|
};
|
|
111
|
-
state: "resolved";
|
|
112
112
|
resolution: {
|
|
113
113
|
decided_by?: {
|
|
114
114
|
display_name: string;
|
|
@@ -49,7 +49,7 @@ export type ReadOnlyChatAssistantOptions = {
|
|
|
49
49
|
model: ReadOnlyChatAssistantModel;
|
|
50
50
|
promptsRoot?: string;
|
|
51
51
|
onScratchpadSourceChanged?: (message: MessageProjection) => void;
|
|
52
|
-
|
|
52
|
+
onAgentMessageCreated?: (input: {
|
|
53
53
|
tx: SqliteDatabase;
|
|
54
54
|
triggerMessage: MessageProjection;
|
|
55
55
|
responseMessage: MessageProjection;
|
|
@@ -262,7 +262,7 @@ export class ReadOnlyChatAssistant {
|
|
|
262
262
|
...(refs === undefined ? {} : { refs }),
|
|
263
263
|
...(this.options.now === undefined ? {} : { now: this.options.now }),
|
|
264
264
|
});
|
|
265
|
-
const callback = this.options.
|
|
265
|
+
const callback = this.options.onAgentMessageCreated?.({
|
|
266
266
|
tx,
|
|
267
267
|
triggerMessage,
|
|
268
268
|
responseMessage,
|
|
@@ -286,12 +286,24 @@ export class ReadOnlyChatAssistant {
|
|
|
286
286
|
}
|
|
287
287
|
appendClarificationRoundAssistantMessage(input) {
|
|
288
288
|
const round = readClarificationRoundProjection(this.options.store.db, input.roundId);
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
289
|
+
let afterCommit;
|
|
290
|
+
const message = withHostStoreTransaction(this.options.store.db, (tx) => {
|
|
291
|
+
const responseMessage = createClarificationRoundAgentMessage(tx, {
|
|
292
|
+
round_id: input.roundId,
|
|
293
|
+
body: input.body,
|
|
294
|
+
...(input.refs === undefined ? {} : { refs: input.refs }),
|
|
295
|
+
...(this.options.now === undefined ? {} : { now: this.options.now }),
|
|
296
|
+
});
|
|
297
|
+
const callback = this.options.onAgentMessageCreated?.({
|
|
298
|
+
tx,
|
|
299
|
+
triggerMessage: input.triggerMessage,
|
|
300
|
+
responseMessage,
|
|
301
|
+
});
|
|
302
|
+
if (typeof callback === "function")
|
|
303
|
+
afterCommit = callback;
|
|
304
|
+
return responseMessage;
|
|
294
305
|
});
|
|
306
|
+
afterCommit?.();
|
|
295
307
|
const invalidates = [
|
|
296
308
|
{
|
|
297
309
|
kind: "clarification",
|
|
@@ -314,6 +326,7 @@ export class ReadOnlyChatAssistant {
|
|
|
314
326
|
appendAssistantMessageForTrigger(triggerMessage, body, refs) {
|
|
315
327
|
if (triggerMessage.scope.kind === "clarification_round") {
|
|
316
328
|
this.appendClarificationRoundAssistantMessage({
|
|
329
|
+
triggerMessage,
|
|
317
330
|
roundId: triggerMessage.scope.clarification_round_ref,
|
|
318
331
|
body,
|
|
319
332
|
...(refs === undefined ? {} : { refs }),
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ClarificationRoundRef, IdempotencyKey } from "@tutti/shared/ids";
|
|
2
|
+
import type { MessageProjection, SendClarificationRoundMessagePayload, SendClarificationRoundMessageResponse, SubmitClarificationRoundPayload, SubmitClarificationRoundResponse } from "@tutti/shared/schemas/api";
|
|
3
|
+
import type { Phase5ControlPlane } from "../control-plane/index.js";
|
|
4
|
+
import type { HostProjectStore, SqliteDatabase } from "../store/index.js";
|
|
5
|
+
import type { ChatAssistantEnqueuer, TrustedCollaborationAuthor } from "./types.js";
|
|
6
|
+
type RoundCommandOptions = {
|
|
7
|
+
store: HostProjectStore;
|
|
8
|
+
controlPlane: Pick<Phase5ControlPlane, "sendClarificationRoundMessage" | "submitClarificationRound">;
|
|
9
|
+
roundId: ClarificationRoundRef;
|
|
10
|
+
commandId: IdempotencyKey;
|
|
11
|
+
now?: () => Date;
|
|
12
|
+
};
|
|
13
|
+
/** Browser and trusted platform input share command identity, mutation and write-once effects. */
|
|
14
|
+
export declare function ingestClarificationMessage(options: RoundCommandOptions & {
|
|
15
|
+
payload: SendClarificationRoundMessagePayload;
|
|
16
|
+
author: TrustedCollaborationAuthor;
|
|
17
|
+
chatAssistant?: ChatAssistantEnqueuer;
|
|
18
|
+
idempotencyContext?: unknown;
|
|
19
|
+
afterCreate?: (tx: SqliteDatabase, message: MessageProjection) => void;
|
|
20
|
+
}): SendClarificationRoundMessageResponse;
|
|
21
|
+
export declare function submitClarificationAnswers(options: RoundCommandOptions & {
|
|
22
|
+
payload: SubmitClarificationRoundPayload;
|
|
23
|
+
}): SubmitClarificationRoundResponse;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=clarification.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { readClarificationRoundProjection, readMessageProjectionById, } from "../collaboration-state/index.js";
|
|
2
|
+
import { clarificationInvalidates } from "../control-plane/invalidations.js";
|
|
3
|
+
import { executeIdempotentCommand } from "../server-shell/command-idempotency/index.js";
|
|
4
|
+
/** Browser and trusted platform input share command identity, mutation and write-once effects. */
|
|
5
|
+
export function ingestClarificationMessage(options) {
|
|
6
|
+
const execution = executeIdempotentCommand({
|
|
7
|
+
db: options.store.db,
|
|
8
|
+
command_id: options.commandId,
|
|
9
|
+
command_name: "clarification.message.create",
|
|
10
|
+
target_ref: options.roundId,
|
|
11
|
+
payload: {
|
|
12
|
+
body: options.payload.body,
|
|
13
|
+
author_ref: options.author.account_ref,
|
|
14
|
+
...(options.author.kind === "development_operator"
|
|
15
|
+
? { author_kind: "development_operator" }
|
|
16
|
+
: {}),
|
|
17
|
+
...(options.idempotencyContext === undefined
|
|
18
|
+
? {}
|
|
19
|
+
: { ingestion_context: options.idempotencyContext }),
|
|
20
|
+
},
|
|
21
|
+
...(options.now === undefined ? {} : { now: options.now }),
|
|
22
|
+
execute: (tx) => {
|
|
23
|
+
const result = options.controlPlane.sendClarificationRoundMessage(options.roundId, options.payload, options.author);
|
|
24
|
+
if (result.result?.message !== undefined)
|
|
25
|
+
options.afterCreate?.(tx, result.result.message);
|
|
26
|
+
return result;
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
const replayedMessage = execution.disposition.kind === "created" && execution.disposition.message_id !== undefined
|
|
30
|
+
? readMessageProjectionById(options.store.db, execution.disposition.message_id)
|
|
31
|
+
: null;
|
|
32
|
+
const result = execution.result ?? (replayedMessage === null ? undefined : { message: replayedMessage });
|
|
33
|
+
if (!execution.replayed && result?.message !== undefined)
|
|
34
|
+
options.chatAssistant?.enqueue({ message: result.message });
|
|
35
|
+
return {
|
|
36
|
+
command_id: execution.command_id,
|
|
37
|
+
disposition: execution.disposition,
|
|
38
|
+
invalidates: clarificationInvalidates(options.roundId),
|
|
39
|
+
...(result === undefined ? {} : { result }),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function submitClarificationAnswers(options) {
|
|
43
|
+
const execution = executeIdempotentCommand({
|
|
44
|
+
db: options.store.db,
|
|
45
|
+
command_id: options.commandId,
|
|
46
|
+
command_name: "clarification.round.submit",
|
|
47
|
+
target_ref: options.roundId,
|
|
48
|
+
payload: options.payload,
|
|
49
|
+
...(options.now === undefined ? {} : { now: options.now }),
|
|
50
|
+
execute: () => options.controlPlane.submitClarificationRound(options.roundId, options.payload, options.commandId),
|
|
51
|
+
});
|
|
52
|
+
const round = execution.disposition.kind === "accepted" || execution.disposition.kind === "already_submitted"
|
|
53
|
+
? readClarificationRoundProjection(options.store.db, options.roundId)
|
|
54
|
+
: null;
|
|
55
|
+
const result = execution.result ?? (round === null ? undefined : { round });
|
|
56
|
+
return {
|
|
57
|
+
command_id: execution.command_id,
|
|
58
|
+
disposition: execution.disposition,
|
|
59
|
+
invalidates: clarificationInvalidates(options.roundId),
|
|
60
|
+
...(result === undefined ? {} : { result }),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=clarification.js.map
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { IntegrationDeliveryDisposition, TrustedConversationSourceIngestionCommand } from "@tutti/shared/schemas/internal";
|
|
2
2
|
import type { HostProjectStore } from "../store/index.js";
|
|
3
3
|
import type { WorkspaceEventBus } from "../server-shell/http/workspace-events.js";
|
|
4
|
+
import type { Phase5ControlPlane } from "../control-plane/index.js";
|
|
4
5
|
import type { ChatAssistantEnqueuer, ScratchpadSourceNotifier } from "./types.js";
|
|
5
6
|
export declare const TRUSTED_INTEGRATION_INGESTION_PATH = "/internal/integration/v1/conversation-sources";
|
|
6
7
|
export type IngestTrustedConversationSourceOptions = {
|
|
7
8
|
store: HostProjectStore;
|
|
8
9
|
events: WorkspaceEventBus;
|
|
9
10
|
command: TrustedConversationSourceIngestionCommand;
|
|
11
|
+
controlPlane?: Pick<Phase5ControlPlane, "sendClarificationRoundMessage" | "submitClarificationRound">;
|
|
10
12
|
scratchpadSource?: ScratchpadSourceNotifier;
|
|
11
13
|
chatAssistant?: ChatAssistantEnqueuer;
|
|
12
14
|
now?: () => Date;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { INTEGRATION_CONVERSATION_SOURCE_TUNNEL_PATH, isTrustedConversationSourceIngestionCommand, } from "@tutti/shared/schemas/internal";
|
|
3
3
|
import { ingestMainChatMessage } from "./main-chat.js";
|
|
4
|
+
import { ingestClarificationMessage } from "./clarification.js";
|
|
4
5
|
export const TRUSTED_INTEGRATION_INGESTION_PATH = INTEGRATION_CONVERSATION_SOURCE_TUNNEL_PATH;
|
|
5
6
|
function sha256Text(value) {
|
|
6
7
|
return `sha256:${createHash("sha256").update(value, "utf8").digest("hex")}`;
|
|
@@ -77,6 +78,40 @@ export function ingestTrustedConversationSource(options) {
|
|
|
77
78
|
if (source.content.text.length > 8_000) {
|
|
78
79
|
return { kind: "unsupported", reason_code: "message_too_long" };
|
|
79
80
|
}
|
|
81
|
+
if (options.command.clarification_round_ref !== undefined) {
|
|
82
|
+
if (options.controlPlane === undefined)
|
|
83
|
+
return {
|
|
84
|
+
kind: "host_incompatible",
|
|
85
|
+
retryable: true,
|
|
86
|
+
reason_code: "integration_clarification_unsupported",
|
|
87
|
+
};
|
|
88
|
+
// Feishu replies may automatically mention Tutti. Directed round input is an
|
|
89
|
+
// answer, not an implicit Q&A request; retain its text but omit the assistant.
|
|
90
|
+
// Browser round composers and ordinary main-chat mentions keep their own path.
|
|
91
|
+
const response = ingestClarificationMessage({
|
|
92
|
+
store: options.store,
|
|
93
|
+
controlPlane: options.controlPlane,
|
|
94
|
+
commandId: options.command.command_id,
|
|
95
|
+
roundId: options.command.clarification_round_ref,
|
|
96
|
+
payload: { body: source.content.text },
|
|
97
|
+
author: {
|
|
98
|
+
...(options.command.actor.kind === "bot" ? { kind: "development_operator" } : {}),
|
|
99
|
+
account_ref: options.command.actor.account_ref,
|
|
100
|
+
display_name: options.command.actor.display_name,
|
|
101
|
+
},
|
|
102
|
+
idempotencyContext: {
|
|
103
|
+
binding_ref: options.command.binding_ref,
|
|
104
|
+
external_message_ref: source.locator.message_ref,
|
|
105
|
+
},
|
|
106
|
+
afterCreate: (tx, message) => insertExternalSourceEvidence(tx, options.command, message),
|
|
107
|
+
...(options.now === undefined ? {} : { now: options.now }),
|
|
108
|
+
});
|
|
109
|
+
if (response.disposition.kind === "created" && response.result?.message !== undefined)
|
|
110
|
+
return { kind: "created", message_id: response.result.message.id };
|
|
111
|
+
if (response.disposition.kind === "interrupted")
|
|
112
|
+
return { kind: "host_unavailable", retryable: true, reason_code: "command_interrupted" };
|
|
113
|
+
return { kind: "invalid", reason_code: `clarification_${response.disposition.kind}` };
|
|
114
|
+
}
|
|
80
115
|
const response = ingestMainChatMessage({
|
|
81
116
|
store: options.store,
|
|
82
117
|
events: options.events,
|
|
@@ -5,4 +5,6 @@ export { ingestTrustedManagedReference, readManagedReferenceSourcePaths, type In
|
|
|
5
5
|
export { ingestReferenceFile, REFERENCE_FILE_INGESTION_COMMAND_NAME, REFERENCE_FILE_INGESTION_TARGET_REF, toReferenceFileProjection, type IngestReferenceFileOptions, } from "./reference-files.js";
|
|
6
6
|
export { ingestTrustedReferenceAttachment, TRUSTED_INTEGRATION_REFERENCE_ATTACHMENT_PATH, type IngestTrustedReferenceAttachmentOptions, type ResolvedReferenceAttachmentContent, } from "./reference-attachments.js";
|
|
7
7
|
export type { ChatAssistantEnqueuer, ReferenceSummaryStarter, ScratchpadSourceNotifier, TrustedCollaborationAuthor, } from "./types.js";
|
|
8
|
+
export { ingestClarificationMessage, submitClarificationAnswers } from "./clarification.js";
|
|
9
|
+
export { executeTrustedClarification } from "./platform-clarification.js";
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -4,4 +4,6 @@ export { ingestManagedReferenceSnapshot, publishManagedReferenceSnapshotChanged,
|
|
|
4
4
|
export { ingestTrustedManagedReference, readManagedReferenceSourcePaths, } from "./managed-reference-sources.js";
|
|
5
5
|
export { ingestReferenceFile, REFERENCE_FILE_INGESTION_COMMAND_NAME, REFERENCE_FILE_INGESTION_TARGET_REF, toReferenceFileProjection, } from "./reference-files.js";
|
|
6
6
|
export { ingestTrustedReferenceAttachment, TRUSTED_INTEGRATION_REFERENCE_ATTACHMENT_PATH, } from "./reference-attachments.js";
|
|
7
|
+
export { ingestClarificationMessage, submitClarificationAnswers } from "./clarification.js";
|
|
8
|
+
export { executeTrustedClarification } from "./platform-clarification.js";
|
|
7
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type TrustedClarificationCommand, type IntegrationClarificationResponse } from "@tutti/shared/schemas/internal";
|
|
2
|
+
import type { Phase5ControlPlane } from "../control-plane/index.js";
|
|
3
|
+
import type { HostProjectStore } from "../store/index.js";
|
|
4
|
+
export declare function executeTrustedClarification(options: {
|
|
5
|
+
store: HostProjectStore;
|
|
6
|
+
controlPlane: Phase5ControlPlane;
|
|
7
|
+
command: TrustedClarificationCommand;
|
|
8
|
+
now?: () => Date;
|
|
9
|
+
}): IntegrationClarificationResponse;
|
|
10
|
+
//# sourceMappingURL=platform-clarification.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { isTrustedClarificationCommand, } from "@tutti/shared/schemas/internal";
|
|
2
|
+
import { readActiveClarificationProjection, readClarificationRoundProjection, readClarificationThreadResponse, } from "../collaboration-state/index.js";
|
|
3
|
+
import { submitClarificationAnswers } from "./clarification.js";
|
|
4
|
+
export function executeTrustedClarification(options) {
|
|
5
|
+
const { command, store } = options;
|
|
6
|
+
if (!isTrustedClarificationCommand(command))
|
|
7
|
+
return {
|
|
8
|
+
protocol_version: 1,
|
|
9
|
+
disposition: { kind: "invalid", reason_code: "trusted_clarification_invalid" },
|
|
10
|
+
};
|
|
11
|
+
if (command.operation.kind === "submit")
|
|
12
|
+
return {
|
|
13
|
+
protocol_version: 1,
|
|
14
|
+
disposition: {
|
|
15
|
+
kind: "submitted",
|
|
16
|
+
response: submitClarificationAnswers({
|
|
17
|
+
store,
|
|
18
|
+
controlPlane: options.controlPlane,
|
|
19
|
+
commandId: command.command_id,
|
|
20
|
+
roundId: command.operation.round_id,
|
|
21
|
+
payload: { expected_answer_revision: command.operation.expected_answer_revision },
|
|
22
|
+
...(options.now === undefined ? {} : { now: options.now }),
|
|
23
|
+
}),
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
const round = command.operation.round_id === undefined
|
|
27
|
+
? null
|
|
28
|
+
: readClarificationRoundProjection(store.db, command.operation.round_id);
|
|
29
|
+
const thread = round === null
|
|
30
|
+
? null
|
|
31
|
+
: readClarificationThreadResponse(store.db, round.thread_id)
|
|
32
|
+
?.thread;
|
|
33
|
+
return {
|
|
34
|
+
protocol_version: 1,
|
|
35
|
+
disposition: {
|
|
36
|
+
kind: "queried",
|
|
37
|
+
active: readActiveClarificationProjection(store.db),
|
|
38
|
+
...(round === null || thread == null ? {} : { selected: { round, thread } }),
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=platform-clarification.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createMessageId
|
|
2
|
-
import { clampLimit, decodeCursor, messageCursor, nowIso, stringifyJson
|
|
1
|
+
import { createMessageId } from "@tutti/shared/ids";
|
|
2
|
+
import { clampLimit, decodeCursor, messageCursor, nowIso, stringifyJson } from "./serialization.js";
|
|
3
3
|
import { readClarificationRoundRow } from "./clarification-records.js";
|
|
4
4
|
import { mapMessageRow } from "./messages.js";
|
|
5
5
|
import { recordReadNotificationEvent } from "./read-state.js";
|
|
@@ -7,6 +7,7 @@ export function createClarificationRoundMessage(db, input) {
|
|
|
7
7
|
const createdAt = nowIso(input.now);
|
|
8
8
|
const id = createMessageId();
|
|
9
9
|
const refs = {
|
|
10
|
+
...(input.refs ?? {}),
|
|
10
11
|
clarification_round_ref: input.round_id,
|
|
11
12
|
};
|
|
12
13
|
db.prepare(`
|
|
@@ -4,7 +4,7 @@ import type { SqliteDatabase } from "../store/index.js";
|
|
|
4
4
|
import type { SealedClarificationRoundWithoutSuccessor } from "./types.js";
|
|
5
5
|
import type { ClarificationRoundRow, ClarificationThreadRow } from "./storage-types.js";
|
|
6
6
|
export declare function mapClarificationThreadRow(row: ClarificationThreadRow): ClarificationThreadProjection;
|
|
7
|
-
export declare function mapClarificationRoundRow(row: ClarificationRoundRow): ClarificationRoundProjection;
|
|
7
|
+
export declare function mapClarificationRoundRow(row: ClarificationRoundRow, db: SqliteDatabase): ClarificationRoundProjection;
|
|
8
8
|
export declare function readClarificationThreadRow(db: SqliteDatabase, threadId: ClarificationThreadRef): ClarificationThreadRow | null;
|
|
9
9
|
export declare function readClarificationRoundRow(db: SqliteDatabase, roundId: ClarificationRoundRef): ClarificationRoundRow | null;
|
|
10
10
|
export declare function readActiveClarificationProjection(db: SqliteDatabase): ActiveClarificationProjection;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseJson } from "./serialization.js";
|
|
2
|
+
import { readClarificationAnswerRevision } from "./clarification-snapshot.js";
|
|
2
3
|
export function mapClarificationThreadRow(row) {
|
|
3
4
|
const thread = {
|
|
4
5
|
id: row.id,
|
|
@@ -26,7 +27,7 @@ export function mapClarificationThreadRow(row) {
|
|
|
26
27
|
}
|
|
27
28
|
return thread;
|
|
28
29
|
}
|
|
29
|
-
export function mapClarificationRoundRow(row) {
|
|
30
|
+
export function mapClarificationRoundRow(row, db) {
|
|
30
31
|
const round = {
|
|
31
32
|
id: row.id,
|
|
32
33
|
thread_id: row.clarification_thread_id,
|
|
@@ -38,6 +39,7 @@ export function mapClarificationRoundRow(row) {
|
|
|
38
39
|
}),
|
|
39
40
|
card_message_id: row.card_message_id,
|
|
40
41
|
opening_message_id: row.opening_message_id,
|
|
42
|
+
answer_revision: readClarificationAnswerRevision(db, row.id),
|
|
41
43
|
successor_status: row.successor_status,
|
|
42
44
|
capabilities: {
|
|
43
45
|
send_message: row.status === "writable",
|
|
@@ -99,7 +101,7 @@ export function readActiveClarificationProjection(db) {
|
|
|
99
101
|
return {
|
|
100
102
|
state: "active",
|
|
101
103
|
thread: mapClarificationThreadRow(row),
|
|
102
|
-
round: mapClarificationRoundRow(round),
|
|
104
|
+
round: mapClarificationRoundRow(round, db),
|
|
103
105
|
};
|
|
104
106
|
}
|
|
105
107
|
export function readSealedClarificationRoundsWithoutSuccessor(db) {
|
|
@@ -120,7 +122,7 @@ export function readSealedClarificationRoundsWithoutSuccessor(db) {
|
|
|
120
122
|
return [
|
|
121
123
|
{
|
|
122
124
|
thread: mapClarificationThreadRow(thread),
|
|
123
|
-
round: mapClarificationRoundRow(roundRow),
|
|
125
|
+
round: mapClarificationRoundRow(roundRow, db),
|
|
124
126
|
},
|
|
125
127
|
];
|
|
126
128
|
});
|
|
@@ -142,7 +144,7 @@ export function deleteStaleClarificationSubmitReplayHints(db) {
|
|
|
142
144
|
}
|
|
143
145
|
export function readClarificationRoundProjection(db, roundId) {
|
|
144
146
|
const row = readClarificationRoundRow(db, roundId);
|
|
145
|
-
return row === null ? null : mapClarificationRoundRow(row);
|
|
147
|
+
return row === null ? null : mapClarificationRoundRow(row, db);
|
|
146
148
|
}
|
|
147
149
|
export function readClarificationRoundsForThread(db, threadId, options = {}) {
|
|
148
150
|
const rows = options.throughRoundIndex === undefined
|
|
@@ -163,7 +165,7 @@ export function readClarificationRoundsForThread(db, threadId, options = {}) {
|
|
|
163
165
|
ORDER BY round_index ASC
|
|
164
166
|
`)
|
|
165
167
|
.all(threadId, options.throughRoundIndex);
|
|
166
|
-
return rows.map((row) => mapClarificationRoundRow(row));
|
|
168
|
+
return rows.map((row) => mapClarificationRoundRow(row, db));
|
|
167
169
|
}
|
|
168
170
|
export function readTaskCompileClarificationRoundsByWorkflowRef(db, workflowRef) {
|
|
169
171
|
const threads = db
|
|
@@ -114,7 +114,7 @@ export function openTaskCompileClarificationRound(db, input) {
|
|
|
114
114
|
}
|
|
115
115
|
return {
|
|
116
116
|
thread: mapClarificationThreadRow(thread),
|
|
117
|
-
round: mapClarificationRoundRow(round),
|
|
117
|
+
round: mapClarificationRoundRow(round, db),
|
|
118
118
|
card_message: mapMessageRow(cardMessage, db),
|
|
119
119
|
opening_message: mapMessageRow(openingMessage),
|
|
120
120
|
};
|
|
@@ -219,8 +219,8 @@ export function openNextTaskCompileClarificationRound(db, input) {
|
|
|
219
219
|
}
|
|
220
220
|
return {
|
|
221
221
|
thread: mapClarificationThreadRow(thread),
|
|
222
|
-
previous_round: mapClarificationRoundRow(previousRound),
|
|
223
|
-
round: mapClarificationRoundRow(round),
|
|
222
|
+
previous_round: mapClarificationRoundRow(previousRound, db),
|
|
223
|
+
round: mapClarificationRoundRow(round, db),
|
|
224
224
|
card_message: mapMessageRow(cardMessage, db),
|
|
225
225
|
opening_message: mapMessageRow(openingMessage),
|
|
226
226
|
};
|
|
@@ -337,8 +337,8 @@ export function openNextTaskBoundClarificationRound(db, input) {
|
|
|
337
337
|
}
|
|
338
338
|
return {
|
|
339
339
|
thread: mapClarificationThreadRow(thread),
|
|
340
|
-
previous_round: mapClarificationRoundRow(previousRound),
|
|
341
|
-
round: mapClarificationRoundRow(round),
|
|
340
|
+
previous_round: mapClarificationRoundRow(previousRound, db),
|
|
341
|
+
round: mapClarificationRoundRow(round, db),
|
|
342
342
|
task,
|
|
343
343
|
card_message: mapMessageRow(cardMessage, db),
|
|
344
344
|
opening_message: mapMessageRow(openingMessage),
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import type { ClarificationRoundRef } from "@tutti/shared/ids";
|
|
2
|
+
import type { SqliteDatabase } from "../store/index.js";
|
|
3
|
+
/** Round messages are append-only; the eligible answer count is a stable CAS revision. */
|
|
4
|
+
export declare function readClarificationAnswerRevision(db: SqliteDatabase, roundId: ClarificationRoundRef): number;
|
|
5
|
+
/** Read the immutable submitted refs, not a first page or messages appended after sealing. */
|
|
6
|
+
export declare function readSubmittedClarificationMessages(db: SqliteDatabase, roundId: ClarificationRoundRef): {
|
|
7
|
+
clarification_card?: {
|
|
8
|
+
title?: string;
|
|
9
|
+
status: "writable" | "sealed";
|
|
10
|
+
round_id: string;
|
|
11
|
+
thread_id: string;
|
|
12
|
+
summary: string;
|
|
13
|
+
is_current_round: boolean;
|
|
14
|
+
};
|
|
15
|
+
refs?: {
|
|
16
|
+
task_id?: string;
|
|
17
|
+
activity_ref?: string;
|
|
18
|
+
artifact_feedback?: {
|
|
19
|
+
summary?: string;
|
|
20
|
+
kind: "artifact_feedback";
|
|
21
|
+
version: 1;
|
|
22
|
+
preview_generation: string;
|
|
23
|
+
annotations: {
|
|
24
|
+
document_url: string;
|
|
25
|
+
comment: string;
|
|
26
|
+
target: {
|
|
27
|
+
fallback_context?: {
|
|
28
|
+
snapshot: {
|
|
29
|
+
role?: string;
|
|
30
|
+
accessible_name?: string;
|
|
31
|
+
text_excerpt?: string;
|
|
32
|
+
state?: {
|
|
33
|
+
expanded?: boolean;
|
|
34
|
+
selected?: boolean;
|
|
35
|
+
checked?: boolean;
|
|
36
|
+
pressed?: boolean;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
};
|
|
39
|
+
tag_name: string;
|
|
40
|
+
element_kind: "content" | "control" | "container";
|
|
41
|
+
context: {
|
|
42
|
+
role?: string;
|
|
43
|
+
accessible_name?: string;
|
|
44
|
+
tag_name: string;
|
|
45
|
+
}[];
|
|
46
|
+
};
|
|
47
|
+
anchor: {
|
|
48
|
+
explicit_anchor?: string;
|
|
49
|
+
stable_attributes?: {
|
|
50
|
+
id?: string;
|
|
51
|
+
test_id?: string;
|
|
52
|
+
};
|
|
53
|
+
version: 1;
|
|
54
|
+
semantic_path: {
|
|
55
|
+
role?: string;
|
|
56
|
+
accessible_name?: string;
|
|
57
|
+
}[];
|
|
58
|
+
selector_path: {
|
|
59
|
+
root: "document" | "open_shadow_root";
|
|
60
|
+
selector: string;
|
|
61
|
+
}[];
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
snapshot: {
|
|
65
|
+
role?: string;
|
|
66
|
+
accessible_name?: string;
|
|
67
|
+
text_excerpt?: string;
|
|
68
|
+
state?: {
|
|
69
|
+
expanded?: boolean;
|
|
70
|
+
selected?: boolean;
|
|
71
|
+
checked?: boolean;
|
|
72
|
+
pressed?: boolean;
|
|
73
|
+
disabled?: boolean;
|
|
74
|
+
};
|
|
75
|
+
tag_name: string;
|
|
76
|
+
element_kind: "content" | "control" | "container";
|
|
77
|
+
context: {
|
|
78
|
+
role?: string;
|
|
79
|
+
accessible_name?: string;
|
|
80
|
+
tag_name: string;
|
|
81
|
+
}[];
|
|
82
|
+
};
|
|
83
|
+
anchor: {
|
|
84
|
+
explicit_anchor?: string;
|
|
85
|
+
stable_attributes?: {
|
|
86
|
+
id?: string;
|
|
87
|
+
test_id?: string;
|
|
88
|
+
};
|
|
89
|
+
version: 1;
|
|
90
|
+
semantic_path: {
|
|
91
|
+
role?: string;
|
|
92
|
+
accessible_name?: string;
|
|
93
|
+
}[];
|
|
94
|
+
selector_path: {
|
|
95
|
+
root: "document" | "open_shadow_root";
|
|
96
|
+
selector: string;
|
|
97
|
+
}[];
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
}[];
|
|
101
|
+
artifact_title: string;
|
|
102
|
+
inspector_version: 1;
|
|
103
|
+
};
|
|
104
|
+
reference_file?: {
|
|
105
|
+
media_type?: string;
|
|
106
|
+
blob_oid?: string;
|
|
107
|
+
path: string;
|
|
108
|
+
name: string;
|
|
109
|
+
source: "human_upload" | "tutti_output";
|
|
110
|
+
category: "file" | "image";
|
|
111
|
+
size_bytes: number;
|
|
112
|
+
text_read: {
|
|
113
|
+
blocked_reason?: "unknown" | "binary" | "too_large" | "unsupported_encoding" | "restricted_path" | "secret_like";
|
|
114
|
+
can_read: boolean;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
workflow_ref?: string;
|
|
118
|
+
clarification_round_ref?: string;
|
|
119
|
+
clarification_thread_ref?: string;
|
|
120
|
+
task_result?: {
|
|
121
|
+
error_code?: string;
|
|
122
|
+
activity_ref?: string;
|
|
123
|
+
generated_files?: {
|
|
124
|
+
media_type?: string;
|
|
125
|
+
group?: string;
|
|
126
|
+
path: string;
|
|
127
|
+
name: string;
|
|
128
|
+
size_bytes: number;
|
|
129
|
+
}[];
|
|
130
|
+
module_name?: string;
|
|
131
|
+
latest_run_result_id?: string;
|
|
132
|
+
retry_action?: "retryable" | "retried";
|
|
133
|
+
final_note?: string;
|
|
134
|
+
status: "completed" | "failed";
|
|
135
|
+
kind: "task_result";
|
|
136
|
+
task_id: string;
|
|
137
|
+
title: string;
|
|
138
|
+
summary: string;
|
|
139
|
+
task_title: string;
|
|
140
|
+
result_key: string;
|
|
141
|
+
};
|
|
142
|
+
worklist_compile?: {
|
|
143
|
+
kind: "worklist_compile";
|
|
144
|
+
title: string;
|
|
145
|
+
workflow_ref: string;
|
|
146
|
+
tasks: {
|
|
147
|
+
status: "failed" | "done" | "pending" | "todo" | "running";
|
|
148
|
+
task_id: string;
|
|
149
|
+
title: string;
|
|
150
|
+
summary: string;
|
|
151
|
+
module_id: string;
|
|
152
|
+
module_name: string;
|
|
153
|
+
}[];
|
|
154
|
+
task_count: number;
|
|
155
|
+
};
|
|
156
|
+
artifact_preview?: {
|
|
157
|
+
task_id?: string;
|
|
158
|
+
run_result_id?: string;
|
|
159
|
+
status: "available" | "updated";
|
|
160
|
+
kind: "artifact_preview";
|
|
161
|
+
title: string;
|
|
162
|
+
};
|
|
163
|
+
development_operator?: true;
|
|
164
|
+
external_reference_reads?: string[];
|
|
165
|
+
external_references?: {
|
|
166
|
+
name: string;
|
|
167
|
+
kind: "feishu_docx" | "feishu_drive_file" | "feishu_file" | "feishu_image";
|
|
168
|
+
created_at: string;
|
|
169
|
+
source_ref: string;
|
|
170
|
+
}[];
|
|
171
|
+
scratchpad_source?: "include" | "exclude";
|
|
172
|
+
worklist_feedback?: {
|
|
173
|
+
generated_files?: {
|
|
174
|
+
media_type?: string;
|
|
175
|
+
group?: string;
|
|
176
|
+
path: string;
|
|
177
|
+
name: string;
|
|
178
|
+
size_bytes: number;
|
|
179
|
+
}[];
|
|
180
|
+
final_note?: string;
|
|
181
|
+
primary_task_id?: string;
|
|
182
|
+
status: "completed" | "failed";
|
|
183
|
+
kind: "worklist_terminal";
|
|
184
|
+
items: {
|
|
185
|
+
module_name?: string;
|
|
186
|
+
latest_run_result_id?: string;
|
|
187
|
+
status: "failed" | "done";
|
|
188
|
+
task_id: string;
|
|
189
|
+
title: string;
|
|
190
|
+
summary: string;
|
|
191
|
+
}[];
|
|
192
|
+
title: string;
|
|
193
|
+
reason: "all_tasks_done" | "run_failed";
|
|
194
|
+
counters: {
|
|
195
|
+
completed: number;
|
|
196
|
+
failed: number;
|
|
197
|
+
remaining: number;
|
|
198
|
+
};
|
|
199
|
+
feedback_key: string;
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
scope: {
|
|
203
|
+
kind: "main_chat";
|
|
204
|
+
} | {
|
|
205
|
+
kind: "clarification_round";
|
|
206
|
+
clarification_round_ref: string;
|
|
207
|
+
};
|
|
208
|
+
id: string;
|
|
209
|
+
author: {
|
|
210
|
+
ref?: string;
|
|
211
|
+
display_name?: string;
|
|
212
|
+
avatar?: {
|
|
213
|
+
kind: "initials";
|
|
214
|
+
initials: string;
|
|
215
|
+
color: "neutral" | "green" | "blue" | "yellow";
|
|
216
|
+
} | {
|
|
217
|
+
kind: "image";
|
|
218
|
+
initials: string;
|
|
219
|
+
color: "neutral" | "green" | "blue" | "yellow";
|
|
220
|
+
image_url: string;
|
|
221
|
+
};
|
|
222
|
+
kind: "human" | "system" | "agent";
|
|
223
|
+
};
|
|
224
|
+
body: string;
|
|
225
|
+
created_at: string;
|
|
226
|
+
message_kind: "user_text" | "agent_text" | "system_notice" | "clarification_request" | "clarification_card";
|
|
227
|
+
}[];
|
|
228
|
+
//# sourceMappingURL=clarification-snapshot.d.ts.map
|