@xfey/tutti 0.1.110 → 0.1.112
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 +1 -1
- package/dist/approvals/decision-command.d.ts +2 -2
- package/dist/chat-assistant/index.d.ts +1 -1
- package/dist/chat-assistant/index.js +26 -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/main-chat.js +9 -2
- package/dist/collaboration-ingestion/platform-clarification.d.ts +10 -0
- package/dist/collaboration-ingestion/platform-clarification.js +42 -0
- package/dist/collaboration-ingestion/types.d.ts +1 -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/scratchpad-source-messages.js +9 -3
- package/dist/control-plane/task-compile-clarification-context.js +7 -2
- package/dist/control-plane/task-source-context-types.d.ts +1 -1
- package/dist/control-plane/task-source-context.js +4 -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 +2 -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/agent-context-reference-routes.js +1 -3
- 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 +2 -0
- package/node_modules/@tutti/relay-client/dist/host-control.js +6 -0
- package/node_modules/@tutti/shared/dist/schemas/api/clarifications.d.ts +14 -1
- package/node_modules/@tutti/shared/dist/schemas/api/clarifications.js +9 -2
- package/node_modules/@tutti/shared/dist/schemas/api/messages.d.ts +4 -0
- package/node_modules/@tutti/shared/dist/schemas/api/messages.js +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/viewer-reference.d.ts +1 -0
- 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 +132 -5
- package/node_modules/@tutti/shared/dist/schemas/internal/platform-integration.js +29 -5
- 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/chat-assistant.md +1 -0
- package/prompts/procedures/follow-up-check.md +4 -4
- package/prompts/procedures/scratchpad-refresh.md +22 -2
- package/prompts/procedures/task-compile.md +1 -0
- package/prompts/runs/task-execute.md +2 -0
- package/web/assets/{homepage-motion-scene-rxYjg-zc.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-BrKWdtKZ.js +0 -69
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
`apps/server` 是 Tutti 的项目 host service,也是机器级 Local Console 的进程入口。
|
|
6
6
|
|
|
7
|
-
`0.1.110`
|
|
7
|
+
`0.1.110` 已发布每次 Chat invocation 的外部资料核验规则、本地/外部 provenance、从实际读取证据派生的回答来源线索,以及隔离多轮模型 smoke;配套 F.3 增量支持群资料确认与普通云盘文件。Web/Relay/Integration 已先行同步,registry byte match 与本机 CLI/Console/原在线 Host 更新通过;实际发布与剩余真人验收状态见同一[按需资料计划](../../docs/roadmap/feishu-on-demand-reference-plan.md)。历史快照不删除,读取线索不继承新鲜度或权限。
|
|
8
8
|
|
|
9
9
|
已发布的 `0.1.109` 统一验证 Codex `skills/extraRoots/set` / `skills/list` 与实际 `SKILL.md` 文件身份;Chat 的安全阶段日志可通过 invocation ref 关联外部 Reference 读取。候选安装/升级、registry byte match、本机 CLI/Console/测试 Host 更新及更新后 Docx 真人读取闭环已通过;连续更新/同次 pin/附件/失权 live 矩阵仍独立跟踪。证据见[按需资料计划](../../docs/roadmap/feishu-on-demand-reference-plan.md),不以安装版本代替实际读取证据。
|
|
10
10
|
|
|
@@ -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;
|
|
@@ -49,6 +49,7 @@ function assistantFailureMessage() {
|
|
|
49
49
|
function messageToContext(message) {
|
|
50
50
|
const authorDisplayName = message.author.display_name?.trim();
|
|
51
51
|
return {
|
|
52
|
+
...(message.refs?.development_operator === true ? { source_role: "operator" } : {}),
|
|
52
53
|
...(authorDisplayName === undefined || authorDisplayName === ""
|
|
53
54
|
? {}
|
|
54
55
|
: { author_display_name: authorDisplayName }),
|
|
@@ -57,6 +58,8 @@ function messageToContext(message) {
|
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
60
|
function messageRole(message) {
|
|
61
|
+
if (message.author.kind === "system" && message.refs?.development_operator === true)
|
|
62
|
+
return "operator";
|
|
60
63
|
if (message.author.kind === "agent") {
|
|
61
64
|
return "tutti";
|
|
62
65
|
}
|
|
@@ -110,6 +113,10 @@ export class ReadOnlyChatAssistant {
|
|
|
110
113
|
this.maxQueuedMentions = options.maxQueuedMentions ?? 8;
|
|
111
114
|
}
|
|
112
115
|
enqueue(input) {
|
|
116
|
+
if (input.message.author.kind !== "human" &&
|
|
117
|
+
!(input.message.author.kind === "system" && input.message.refs?.development_operator === true)) {
|
|
118
|
+
return { triggered: false };
|
|
119
|
+
}
|
|
113
120
|
if (!containsTuttiMention(messageTextForTuttiMention(input.message))) {
|
|
114
121
|
return { triggered: false };
|
|
115
122
|
}
|
|
@@ -255,7 +262,7 @@ export class ReadOnlyChatAssistant {
|
|
|
255
262
|
...(refs === undefined ? {} : { refs }),
|
|
256
263
|
...(this.options.now === undefined ? {} : { now: this.options.now }),
|
|
257
264
|
});
|
|
258
|
-
const callback = this.options.
|
|
265
|
+
const callback = this.options.onAgentMessageCreated?.({
|
|
259
266
|
tx,
|
|
260
267
|
triggerMessage,
|
|
261
268
|
responseMessage,
|
|
@@ -279,12 +286,24 @@ export class ReadOnlyChatAssistant {
|
|
|
279
286
|
}
|
|
280
287
|
appendClarificationRoundAssistantMessage(input) {
|
|
281
288
|
const round = readClarificationRoundProjection(this.options.store.db, input.roundId);
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
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;
|
|
287
305
|
});
|
|
306
|
+
afterCommit?.();
|
|
288
307
|
const invalidates = [
|
|
289
308
|
{
|
|
290
309
|
kind: "clarification",
|
|
@@ -307,6 +326,7 @@ export class ReadOnlyChatAssistant {
|
|
|
307
326
|
appendAssistantMessageForTrigger(triggerMessage, body, refs) {
|
|
308
327
|
if (triggerMessage.scope.kind === "clarification_round") {
|
|
309
328
|
this.appendClarificationRoundAssistantMessage({
|
|
329
|
+
triggerMessage,
|
|
310
330
|
roundId: triggerMessage.scope.clarification_round_ref,
|
|
311
331
|
body,
|
|
312
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,12 +78,45 @@ 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
|
+
const response = ingestClarificationMessage({
|
|
89
|
+
store: options.store,
|
|
90
|
+
controlPlane: options.controlPlane,
|
|
91
|
+
commandId: options.command.command_id,
|
|
92
|
+
roundId: options.command.clarification_round_ref,
|
|
93
|
+
payload: { body: source.content.text },
|
|
94
|
+
author: {
|
|
95
|
+
...(options.command.actor.kind === "bot" ? { kind: "development_operator" } : {}),
|
|
96
|
+
account_ref: options.command.actor.account_ref,
|
|
97
|
+
display_name: options.command.actor.display_name,
|
|
98
|
+
},
|
|
99
|
+
idempotencyContext: {
|
|
100
|
+
binding_ref: options.command.binding_ref,
|
|
101
|
+
external_message_ref: source.locator.message_ref,
|
|
102
|
+
},
|
|
103
|
+
afterCreate: (tx, message) => insertExternalSourceEvidence(tx, options.command, message),
|
|
104
|
+
...(options.chatAssistant === undefined ? {} : { chatAssistant: options.chatAssistant }),
|
|
105
|
+
...(options.now === undefined ? {} : { now: options.now }),
|
|
106
|
+
});
|
|
107
|
+
if (response.disposition.kind === "created" && response.result?.message !== undefined)
|
|
108
|
+
return { kind: "created", message_id: response.result.message.id };
|
|
109
|
+
if (response.disposition.kind === "interrupted")
|
|
110
|
+
return { kind: "host_unavailable", retryable: true, reason_code: "command_interrupted" };
|
|
111
|
+
return { kind: "invalid", reason_code: `clarification_${response.disposition.kind}` };
|
|
112
|
+
}
|
|
80
113
|
const response = ingestMainChatMessage({
|
|
81
114
|
store: options.store,
|
|
82
115
|
events: options.events,
|
|
83
116
|
commandId: options.command.command_id,
|
|
84
117
|
payload: { body: source.content.text },
|
|
85
118
|
author: {
|
|
119
|
+
...(options.command.actor.kind === "bot" ? { kind: "development_operator" } : {}),
|
|
86
120
|
account_ref: options.command.actor.account_ref,
|
|
87
121
|
display_name: options.command.actor.display_name,
|
|
88
122
|
},
|
|
@@ -100,6 +134,7 @@ export function ingestTrustedConversationSource(options) {
|
|
|
100
134
|
external_message_ref: source.locator.message_ref,
|
|
101
135
|
binding_ref: options.command.binding_ref,
|
|
102
136
|
receipt_key: options.command.receipt.receipt_key,
|
|
137
|
+
...(options.command.actor.kind === "bot" ? { actor_kind: "bot" } : {}),
|
|
103
138
|
...(source.external_references === undefined
|
|
104
139
|
? {}
|
|
105
140
|
: { external_references: source.external_references }),
|
|
@@ -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
|
|
@@ -10,6 +10,9 @@ export function ingestMainChatMessage(options) {
|
|
|
10
10
|
payload: {
|
|
11
11
|
...options.payload,
|
|
12
12
|
author_ref: options.author.account_ref,
|
|
13
|
+
...(options.author.kind === "development_operator"
|
|
14
|
+
? { author_kind: "development_operator" }
|
|
15
|
+
: {}),
|
|
13
16
|
...(options.idempotencyContext === undefined
|
|
14
17
|
? {}
|
|
15
18
|
: { ingestion_context: options.idempotencyContext }),
|
|
@@ -23,12 +26,16 @@ export function ingestMainChatMessage(options) {
|
|
|
23
26
|
const message = createMainChatMessage(tx, {
|
|
24
27
|
body: materialized.body,
|
|
25
28
|
author: {
|
|
26
|
-
kind: "human",
|
|
29
|
+
kind: options.author.kind === "development_operator" ? "system" : "human",
|
|
27
30
|
ref: options.author.account_ref,
|
|
28
31
|
display_name: options.author.display_name,
|
|
29
32
|
...(options.author.avatar === undefined ? {} : { avatar: options.author.avatar }),
|
|
30
33
|
},
|
|
31
|
-
...(
|
|
34
|
+
...(options.author.kind === "development_operator"
|
|
35
|
+
? { refs: { ...materialized.refs, development_operator: true } }
|
|
36
|
+
: materialized.refs === undefined
|
|
37
|
+
? {}
|
|
38
|
+
: { refs: materialized.refs }),
|
|
32
39
|
...(options.now === undefined ? {} : { now: options.now }),
|
|
33
40
|
});
|
|
34
41
|
options.afterCreate?.(tx, message);
|
|
@@ -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,6 +1,7 @@
|
|
|
1
1
|
import type { AccountAvatarProjection } from "@tutti/shared/domain";
|
|
2
2
|
import type { MessageProjection } from "@tutti/shared/schemas/api";
|
|
3
3
|
export type TrustedCollaborationAuthor = {
|
|
4
|
+
kind?: "human" | "development_operator";
|
|
4
5
|
account_ref: string;
|
|
5
6
|
display_name: string;
|
|
6
7
|
avatar?: AccountAvatarProjection;
|
|
@@ -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),
|