@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
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { createIdempotencyKey } from "@tutti/shared/ids";
|
|
1
|
+
import { createIdempotencyKey, } from "@tutti/shared/ids";
|
|
2
2
|
import { Value } from "@sinclair/typebox/value";
|
|
3
3
|
import { PlatformOutboundContentSchema, } from "@tutti/shared/schemas/internal";
|
|
4
|
+
import { readClarificationRoundProjection, readClarificationThreadResponse, } from "../collaboration-state/index.js";
|
|
4
5
|
const MAX_PLATFORM_OUTBOUND_TEXT_LENGTH = 4_000;
|
|
5
6
|
function boundedPlatformOutboundText(value) {
|
|
6
7
|
const characters = [...value.trim()];
|
|
@@ -134,10 +135,13 @@ export function materializePlatformStatusOutboundIntents(db, now = () => new Dat
|
|
|
134
135
|
subjectRef: roundRef,
|
|
135
136
|
targetKind: "project",
|
|
136
137
|
canonicalMessageId: candidate.id,
|
|
138
|
+
content: clarificationContent(db, roundRef),
|
|
137
139
|
now,
|
|
138
140
|
});
|
|
139
141
|
if (result?.created === true) {
|
|
140
142
|
created.push(result.intent);
|
|
143
|
+
const content = clarificationContent(db, roundRef);
|
|
144
|
+
db.prepare("INSERT OR IGNORE INTO platform_clarification_projection_cursors (round_id, binding_ref, version) VALUES (?, ?, ?)").run(roundRef, result.intent.binding_ref, content.version);
|
|
141
145
|
}
|
|
142
146
|
continue;
|
|
143
147
|
}
|
|
@@ -162,9 +166,61 @@ export function materializePlatformStatusOutboundIntents(db, now = () => new Dat
|
|
|
162
166
|
created.push(result.intent);
|
|
163
167
|
}
|
|
164
168
|
}
|
|
169
|
+
for (const cursor of db
|
|
170
|
+
.prepare("SELECT round_id, binding_ref, version FROM platform_clarification_projection_cursors WHERE closed = 0")
|
|
171
|
+
.all()) {
|
|
172
|
+
const content = clarificationContent(db, cursor.round_id);
|
|
173
|
+
if (content === null || readLatestFeishuDestination(db)?.binding_ref !== cursor.binding_ref) {
|
|
174
|
+
db.prepare("UPDATE platform_clarification_projection_cursors SET closed = 1 WHERE round_id = ?").run(cursor.round_id);
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (content.version <= cursor.version)
|
|
178
|
+
continue;
|
|
179
|
+
const result = createPlatformStatusOutboundIntent(db, {
|
|
180
|
+
eventKind: "needs_input",
|
|
181
|
+
eventKey: `clarification_round:${cursor.round_id}:state:${content.version}`,
|
|
182
|
+
subjectKind: "clarification_round",
|
|
183
|
+
subjectRef: cursor.round_id,
|
|
184
|
+
targetKind: "project",
|
|
185
|
+
content,
|
|
186
|
+
now,
|
|
187
|
+
});
|
|
188
|
+
if (result !== null) {
|
|
189
|
+
db.prepare("UPDATE platform_clarification_projection_cursors SET version = ?, closed = ? WHERE round_id = ?").run(content.version, content.state === "closed" ? 1 : 0, cursor.round_id);
|
|
190
|
+
if (result.created)
|
|
191
|
+
created.push(result.intent);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
165
194
|
return created;
|
|
166
195
|
})();
|
|
167
196
|
}
|
|
197
|
+
function clarificationContent(db, roundId) {
|
|
198
|
+
const round = readClarificationRoundProjection(db, roundId);
|
|
199
|
+
if (round === null)
|
|
200
|
+
return null;
|
|
201
|
+
const thread = readClarificationThreadResponse(db, round.thread_id)?.thread;
|
|
202
|
+
const state = thread?.status !== "active" || thread.current_round_id !== round.id
|
|
203
|
+
? "closed"
|
|
204
|
+
: round.successor_status === "materialized"
|
|
205
|
+
? "continued"
|
|
206
|
+
: round.status === "sealed"
|
|
207
|
+
? "submitted"
|
|
208
|
+
: "writable";
|
|
209
|
+
const answerRevision = round.answer_revision ?? 0;
|
|
210
|
+
return {
|
|
211
|
+
kind: "clarification",
|
|
212
|
+
round_id: round.id,
|
|
213
|
+
answer_revision: answerRevision,
|
|
214
|
+
version: answerRevision * 4 + { writable: 0, submitted: 1, continued: 2, closed: 3 }[state],
|
|
215
|
+
state,
|
|
216
|
+
...(state === "closed" && thread?.closed_reason !== undefined
|
|
217
|
+
? { closed_reason: thread.closed_reason }
|
|
218
|
+
: {}),
|
|
219
|
+
title: (round.request_payload.title ?? "Needs your input").slice(0, 512),
|
|
220
|
+
request: round.request_payload.request.slice(0, 4_000),
|
|
221
|
+
opened_at: round.created_at,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
168
224
|
export function createPlatformOutboundIntent(tx, input) {
|
|
169
225
|
const existing = tx
|
|
170
226
|
.prepare("SELECT * FROM platform_outbound_intents WHERE canonical_message_id = ?")
|
|
@@ -172,13 +228,27 @@ export function createPlatformOutboundIntent(tx, input) {
|
|
|
172
228
|
if (existing !== undefined) {
|
|
173
229
|
return { created: false, intent: existing };
|
|
174
230
|
}
|
|
231
|
+
// An H5 round answer can finish before the periodic status worker observes the
|
|
232
|
+
// opening card. Capture its destination first, in this same transaction.
|
|
233
|
+
if (tx
|
|
234
|
+
.prepare("SELECT 1 FROM messages WHERE id = ? AND scope_kind = 'clarification_round'")
|
|
235
|
+
.get(input.triggerMessageId) !== undefined)
|
|
236
|
+
materializePlatformStatusOutboundIntents(tx, input.now);
|
|
175
237
|
const destination = tx
|
|
176
238
|
.prepare(`
|
|
177
239
|
SELECT platform, installation_ref, binding_ref
|
|
178
240
|
FROM external_source_mappings
|
|
179
241
|
WHERE message_id = ? AND platform = 'feishu'
|
|
180
242
|
`)
|
|
181
|
-
.get(input.triggerMessageId)
|
|
243
|
+
.get(input.triggerMessageId) ??
|
|
244
|
+
tx
|
|
245
|
+
.prepare(`
|
|
246
|
+
SELECT i.platform, i.installation_ref, i.binding_ref FROM messages m
|
|
247
|
+
JOIN platform_clarification_projection_cursors c ON c.round_id = m.clarification_round_id
|
|
248
|
+
JOIN platform_outbound_intents i ON i.event_key = 'clarification_round:' || c.round_id || ':opened'
|
|
249
|
+
WHERE m.id = ? AND m.scope_kind = 'clarification_round'
|
|
250
|
+
`)
|
|
251
|
+
.get(input.triggerMessageId);
|
|
182
252
|
if (destination === undefined) {
|
|
183
253
|
return null;
|
|
184
254
|
}
|
|
@@ -216,7 +286,7 @@ export function claimDuePlatformOutboundIntent(db, now = () => new Date()) {
|
|
|
216
286
|
const row = db
|
|
217
287
|
.prepare(`
|
|
218
288
|
SELECT platform_outbound_intents.*,
|
|
219
|
-
COALESCE(platform_outbound_intents.content_text, messages.body) AS body
|
|
289
|
+
COALESCE(platform_outbound_intents.content_text, messages.body) AS body, messages.clarification_round_id
|
|
220
290
|
FROM platform_outbound_intents
|
|
221
291
|
LEFT JOIN messages ON messages.id = platform_outbound_intents.canonical_message_id
|
|
222
292
|
WHERE platform_outbound_intents.disposition IN ('pending', 'retry_wait')
|
|
@@ -243,7 +313,16 @@ export function claimDuePlatformOutboundIntent(db, now = () => new Date()) {
|
|
|
243
313
|
}
|
|
244
314
|
else if (row.body !== null) {
|
|
245
315
|
const body = boundedPlatformOutboundText(row.body);
|
|
246
|
-
content =
|
|
316
|
+
content =
|
|
317
|
+
body.length === 0
|
|
318
|
+
? null
|
|
319
|
+
: {
|
|
320
|
+
kind: "text",
|
|
321
|
+
text: body,
|
|
322
|
+
...(row.clarification_round_id == null
|
|
323
|
+
? {}
|
|
324
|
+
: { clarification_round_ref: row.clarification_round_id }),
|
|
325
|
+
};
|
|
247
326
|
}
|
|
248
327
|
if (content === null) {
|
|
249
328
|
return null;
|
|
@@ -311,6 +311,7 @@ export async function startLaunchProject(options) {
|
|
|
311
311
|
projectSurface: preparation.machine_local.binding.surface_profile.kind,
|
|
312
312
|
trustedMetadataStore: host.trusted_relay_metadata_store,
|
|
313
313
|
integrationDelivery: host.integration_delivery,
|
|
314
|
+
integrationClarification: host.integration_clarification,
|
|
314
315
|
integrationReferenceAttachment: host.integration_reference_attachment,
|
|
315
316
|
integrationManagedReference: host.integration_managed_reference,
|
|
316
317
|
integrationApprovalDecision: host.integration_approval_decision,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FastifyInstance } from "fastify";
|
|
2
2
|
import { type ExecutionStatusProjection } from "@tutti/shared/schemas/api";
|
|
3
|
-
import type { IntegrationApprovalDecisionDisposition, IntegrationDeliveryDisposition, IntegrationManagedReferenceDisposition, TrustedApprovalDecisionCommand, TrustedConversationSourceIngestionCommand, TrustedManagedReferenceIngestionCommand, TrustedReferenceAttachmentIngestionCommand } from "@tutti/shared/schemas/internal";
|
|
3
|
+
import type { IntegrationApprovalDecisionDisposition, IntegrationClarificationResponse, TrustedClarificationCommand, IntegrationDeliveryDisposition, IntegrationManagedReferenceDisposition, TrustedApprovalDecisionCommand, TrustedConversationSourceIngestionCommand, TrustedManagedReferenceIngestionCommand, TrustedReferenceAttachmentIngestionCommand } from "@tutti/shared/schemas/internal";
|
|
4
4
|
import { type HostProjectStore } from "../../store/index.js";
|
|
5
5
|
import type { createHostServer } from "../http/create-server.js";
|
|
6
6
|
import type { HostLocalLaunchStatus } from "../http/routes/local-control.js";
|
|
@@ -19,6 +19,7 @@ export type HostServerHandle = {
|
|
|
19
19
|
runtime_endpoint: MachineRuntimeEndpointRecord;
|
|
20
20
|
trusted_relay_metadata_store: TrustedRelaySessionMetadataStore;
|
|
21
21
|
integration_delivery: (command: TrustedConversationSourceIngestionCommand) => IntegrationDeliveryDisposition;
|
|
22
|
+
integration_clarification: (command: TrustedClarificationCommand) => IntegrationClarificationResponse;
|
|
22
23
|
integration_approval_decision: (command: TrustedApprovalDecisionCommand) => IntegrationApprovalDecisionDisposition;
|
|
23
24
|
integration_reference_attachment: (command: TrustedReferenceAttachmentIngestionCommand) => Promise<IntegrationDeliveryDisposition>;
|
|
24
25
|
integration_managed_reference: (command: TrustedManagedReferenceIngestionCommand) => Promise<IntegrationManagedReferenceDisposition>;
|
|
@@ -6,7 +6,7 @@ import { ApprovalRequestManager, executeApprovalDecisionCommand } from "../../ap
|
|
|
6
6
|
import { ArtifactPreviewManager } from "../../artifacts/index.js";
|
|
7
7
|
import { ReadOnlyChatAssistant } from "../../chat-assistant/index.js";
|
|
8
8
|
import { CheckProcessCoordinator } from "../../checks/index.js";
|
|
9
|
-
import { ingestTrustedConversationSource, ingestTrustedManagedReference, ingestTrustedReferenceAttachment, } from "../../collaboration-ingestion/index.js";
|
|
9
|
+
import { ingestTrustedConversationSource, executeTrustedClarification, ingestTrustedManagedReference, ingestTrustedReferenceAttachment, } from "../../collaboration-ingestion/index.js";
|
|
10
10
|
import { ensureInitialProjectWelcomeMessage } from "../../collaboration-state/index.js";
|
|
11
11
|
import { Phase5ControlPlane } from "../../control-plane/index.js";
|
|
12
12
|
import { resolveProjectOpenAiProcedureWorkflowRunner } from "../../control-plane/workflows/index.js";
|
|
@@ -447,7 +447,7 @@ export async function startForegroundHostServer(options) {
|
|
|
447
447
|
...(platformOutboundCoordinator === undefined
|
|
448
448
|
? {}
|
|
449
449
|
: {
|
|
450
|
-
|
|
450
|
+
onAgentMessageCreated: ({ tx, triggerMessage, responseMessage }) => platformOutboundCoordinator.captureAgentResponse(tx, {
|
|
451
451
|
triggerMessage,
|
|
452
452
|
responseMessage,
|
|
453
453
|
}),
|
|
@@ -714,6 +714,7 @@ export async function startForegroundHostServer(options) {
|
|
|
714
714
|
trusted_relay_metadata_store: trustedMetadataStore,
|
|
715
715
|
integration_delivery: (command) => ingestTrustedConversationSource({
|
|
716
716
|
store,
|
|
717
|
+
controlPlane,
|
|
717
718
|
events: workspaceEvents,
|
|
718
719
|
command,
|
|
719
720
|
scratchpadSource: {
|
|
@@ -722,6 +723,7 @@ export async function startForegroundHostServer(options) {
|
|
|
722
723
|
chatAssistant,
|
|
723
724
|
now,
|
|
724
725
|
}),
|
|
726
|
+
integration_clarification: (command) => executeTrustedClarification({ store, controlPlane, command, now }),
|
|
725
727
|
integration_reference_attachment: async (command) => await ingestTrustedReferenceAttachment({
|
|
726
728
|
store,
|
|
727
729
|
workspaceRoot: options.preparation.workspace_root,
|
|
@@ -37,6 +37,8 @@ export async function registerHostWithRelay(options) {
|
|
|
37
37
|
joinToken: { mode: options.joinTokenMode ?? "rotate" },
|
|
38
38
|
capabilities: {
|
|
39
39
|
integration_source_ingestion_v1: true,
|
|
40
|
+
integration_development_bot_v1: true,
|
|
41
|
+
integration_clarification_v1: true,
|
|
40
42
|
integration_external_references_v1: true,
|
|
41
43
|
integration_attachment_ingestion_v1: true,
|
|
42
44
|
integration_managed_reference_ingestion_v1: true,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { FastifyInstance } from "fastify";
|
|
2
2
|
import type { RelayHostTunnelRequestHandler, RelayHostTunnelStreamRequestHandler } from "@tutti/relay-client";
|
|
3
|
-
import type { IntegrationApprovalDecisionDisposition, IntegrationDeliveryDisposition, IntegrationManagedReferenceDisposition, TrustedApprovalDecisionCommand, TrustedConversationSourceIngestionCommand, TrustedManagedReferenceIngestionCommand, TrustedReferenceAttachmentIngestionCommand } from "@tutti/shared/schemas/internal";
|
|
3
|
+
import type { IntegrationApprovalDecisionDisposition, IntegrationClarificationResponse, TrustedClarificationCommand, IntegrationDeliveryDisposition, IntegrationManagedReferenceDisposition, TrustedApprovalDecisionCommand, TrustedConversationSourceIngestionCommand, TrustedManagedReferenceIngestionCommand, TrustedReferenceAttachmentIngestionCommand } from "@tutti/shared/schemas/internal";
|
|
4
4
|
import type { ProjectSurface } from "@tutti/shared/domain";
|
|
5
5
|
import { type TrustedRelaySessionMetadataStore } from "../session/relay-session-context.js";
|
|
6
6
|
export type HostProjectApiTunnelDispatchOptions = {
|
|
7
7
|
app: FastifyInstance;
|
|
8
8
|
projectSurface?: ProjectSurface;
|
|
9
9
|
trustedMetadataStore: TrustedRelaySessionMetadataStore;
|
|
10
|
+
integrationClarification?: (command: TrustedClarificationCommand) => IntegrationClarificationResponse;
|
|
10
11
|
integrationDelivery?: (command: TrustedConversationSourceIngestionCommand) => IntegrationDeliveryDisposition;
|
|
11
12
|
integrationApprovalDecision?: (command: TrustedApprovalDecisionCommand) => IntegrationApprovalDecisionDisposition;
|
|
12
13
|
integrationReferenceAttachment?: (command: TrustedReferenceAttachmentIngestionCommand) => Promise<IntegrationDeliveryDisposition>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { dispatchIntegrationClarification } from "./integration-clarification-dispatch.js";
|
|
2
|
+
import { INTEGRATION_APPROVAL_DECISION_TUNNEL_PATH, INTEGRATION_CLARIFICATION_TUNNEL_PATH, INTEGRATION_MANAGED_REFERENCE_TUNNEL_PATH, INTEGRATION_REFERENCE_ATTACHMENT_TUNNEL_PATH, isTrustedApprovalDecisionCommand, isTrustedConversationSourceIngestionCommand, isTrustedManagedReferenceIngestionCommand, isTrustedReferenceAttachmentIngestionCommand, } from "@tutti/shared/schemas/internal";
|
|
2
3
|
import { TRUSTED_INTEGRATION_INGESTION_PATH, TRUSTED_INTEGRATION_REFERENCE_ATTACHMENT_PATH, } from "../../collaboration-ingestion/index.js";
|
|
3
4
|
import { TRUSTED_RELAY_METADATA_REQUEST_HEADER, } from "../session/relay-session-context.js";
|
|
4
5
|
function browserMetadataMatchesSurface(projectSurface, request) {
|
|
@@ -78,6 +79,8 @@ function dispatchIntegrationDelivery(options, request) {
|
|
|
78
79
|
if (request.path === INTEGRATION_APPROVAL_DECISION_TUNNEL_PATH) {
|
|
79
80
|
return dispatchIntegrationApprovalDecision(options, request);
|
|
80
81
|
}
|
|
82
|
+
if (request.path === INTEGRATION_CLARIFICATION_TUNNEL_PATH)
|
|
83
|
+
return Promise.resolve(dispatchIntegrationClarification(options, request));
|
|
81
84
|
if (request.path === INTEGRATION_REFERENCE_ATTACHMENT_TUNNEL_PATH) {
|
|
82
85
|
return dispatchIntegrationReferenceAttachment(options, request);
|
|
83
86
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RelayHostTunnelRequest, RelayHostTunnelResponse } from "@tutti/relay-client";
|
|
2
|
+
import { type IntegrationClarificationResponse, type TrustedClarificationCommand } from "@tutti/shared/schemas/internal";
|
|
3
|
+
export declare function dispatchIntegrationClarification(options: {
|
|
4
|
+
integrationClarification?: (command: TrustedClarificationCommand) => IntegrationClarificationResponse;
|
|
5
|
+
}, request: RelayHostTunnelRequest): RelayHostTunnelResponse;
|
|
6
|
+
//# sourceMappingURL=integration-clarification-dispatch.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { INTEGRATION_CLARIFICATION_TUNNEL_PATH, isTrustedClarificationCommand, } from "@tutti/shared/schemas/internal";
|
|
2
|
+
export function dispatchIntegrationClarification(options, request) {
|
|
3
|
+
const finish = (body) => ({
|
|
4
|
+
request_id: request.request_id,
|
|
5
|
+
status_code: 200,
|
|
6
|
+
headers: { "content-type": "application/json; charset=utf-8" },
|
|
7
|
+
body_base64: Buffer.from(JSON.stringify(body), "utf8").toString("base64"),
|
|
8
|
+
});
|
|
9
|
+
const invalid = (reason_code) => finish({ protocol_version: 1, disposition: { kind: "invalid", reason_code } });
|
|
10
|
+
if (request.method !== "POST" ||
|
|
11
|
+
request.path !== INTEGRATION_CLARIFICATION_TUNNEL_PATH ||
|
|
12
|
+
!("integration_delivery" in request.metadata))
|
|
13
|
+
return invalid("internal_route_invalid");
|
|
14
|
+
let command;
|
|
15
|
+
try {
|
|
16
|
+
command = JSON.parse(Buffer.from(request.body_base64 ?? "", "base64").toString("utf8"));
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return invalid("trusted_command_invalid");
|
|
20
|
+
}
|
|
21
|
+
if (!isTrustedClarificationCommand(command))
|
|
22
|
+
return invalid("trusted_command_invalid");
|
|
23
|
+
const metadata = request.metadata.integration_delivery;
|
|
24
|
+
if (!("operation_ref" in metadata) ||
|
|
25
|
+
command.operation_ref !== metadata.operation_ref ||
|
|
26
|
+
command.binding_ref !== metadata.binding_ref ||
|
|
27
|
+
command.relay_project_ref !== metadata.relay_project_ref ||
|
|
28
|
+
command.actor.verified_at !== metadata.verified_at ||
|
|
29
|
+
command.conversation.installation.platform !== metadata.installation.platform ||
|
|
30
|
+
command.conversation.installation.installation_ref !== metadata.installation.installation_ref)
|
|
31
|
+
return invalid("trusted_metadata_mismatch");
|
|
32
|
+
if (options.integrationClarification === undefined)
|
|
33
|
+
return finish({
|
|
34
|
+
protocol_version: 1,
|
|
35
|
+
disposition: {
|
|
36
|
+
kind: "unavailable",
|
|
37
|
+
retryable: true,
|
|
38
|
+
reason_code: "integration_clarification_unsupported",
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
return finish(options.integrationClarification(command));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=integration-clarification-dispatch.js.map
|
|
@@ -99,9 +99,7 @@ export function registerAgentContextReferenceRoutes(app, options) {
|
|
|
99
99
|
request.log.warn({
|
|
100
100
|
...diagnosticFields,
|
|
101
101
|
stage: "local_reference_unavailable",
|
|
102
|
-
reason_code: error instanceof WorkspaceOpsError
|
|
103
|
-
? error.code
|
|
104
|
-
: "reference_read_unavailable",
|
|
102
|
+
reason_code: error instanceof WorkspaceOpsError ? error.code : "reference_read_unavailable",
|
|
105
103
|
elapsed_ms: Math.round(performance.now() - started),
|
|
106
104
|
}, "Local Reference read unavailable");
|
|
107
105
|
if (error instanceof WorkspaceOpsError) {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { ActiveClarificationProjectionSchema, GetClarificationRoundMessagesRequestSchema, GetClarificationRoundResponseSchema, GetClarificationThreadResponseSchema, MessageWindowSchema, SendClarificationRoundMessageBodySchema, SendClarificationRoundMessageResponseSchema, SubmitClarificationRoundBodySchema, SubmitClarificationRoundResponseSchema, } from "@tutti/shared/schemas/api";
|
|
2
2
|
import { readActiveClarificationProjection, readClarificationRoundMessagesWindow, readClarificationRoundProjection, readClarificationThreadResponse, } from "../../../../collaboration-state/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ingestClarificationMessage, submitClarificationAnswers, } from "../../../../collaboration-ingestion/index.js";
|
|
4
4
|
import { HOST_PROJECT_API_BASE_PATH } from "./constants.js";
|
|
5
5
|
import { HostProjectNotFoundError } from "./errors.js";
|
|
6
|
-
import { clarificationRoundInvalidates } from "./invalidations.js";
|
|
7
6
|
import { requireValidMessageWindowRequest, requireValidRoundMessagePayload, } from "./payload-validation.js";
|
|
8
7
|
import { ClarificationRoundParamsSchema, ClarificationThreadParamsSchema, } from "./schemas.js";
|
|
9
8
|
import { requireControlPlane, requireHostProjectSession, requireProjectStore, } from "./session-requirements.js";
|
|
@@ -85,35 +84,20 @@ export function registerClarificationRoutes(app, options) {
|
|
|
85
84
|
const store = requireProjectStore(options);
|
|
86
85
|
const controlPlane = requireControlPlane(options);
|
|
87
86
|
const payload = requireValidRoundMessagePayload(request.body.payload);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
payload
|
|
94
|
-
|
|
95
|
-
author_ref: session.account.account_ref,
|
|
96
|
-
},
|
|
97
|
-
...(options.now === undefined ? {} : { now: options.now }),
|
|
98
|
-
execute: () => controlPlane.sendClarificationRoundMessage(request.params.roundId, payload, {
|
|
87
|
+
return ingestClarificationMessage({
|
|
88
|
+
store,
|
|
89
|
+
controlPlane,
|
|
90
|
+
commandId: request.body.command_id,
|
|
91
|
+
roundId: request.params.roundId,
|
|
92
|
+
payload,
|
|
93
|
+
author: {
|
|
99
94
|
account_ref: session.account.account_ref,
|
|
100
95
|
display_name: session.account.display_name,
|
|
101
96
|
avatar: session.account.avatar,
|
|
102
|
-
}
|
|
97
|
+
},
|
|
98
|
+
...(options.now === undefined ? {} : { now: options.now }),
|
|
99
|
+
...(options.chatAssistant === undefined ? {} : { chatAssistant: options.chatAssistant }),
|
|
103
100
|
});
|
|
104
|
-
const response = {
|
|
105
|
-
command_id: execution.command_id,
|
|
106
|
-
disposition: execution.disposition,
|
|
107
|
-
invalidates: clarificationRoundInvalidates(request.params.roundId),
|
|
108
|
-
};
|
|
109
|
-
if (execution.result !== undefined) {
|
|
110
|
-
response.result = execution.result;
|
|
111
|
-
}
|
|
112
|
-
const message = execution.result?.message;
|
|
113
|
-
if (!execution.replayed && message !== undefined) {
|
|
114
|
-
options.chatAssistant?.enqueue({ message });
|
|
115
|
-
}
|
|
116
|
-
return response;
|
|
117
101
|
});
|
|
118
102
|
app.post(`${HOST_PROJECT_API_BASE_PATH}/clarifications/rounds/:roundId/submit`, {
|
|
119
103
|
schema: {
|
|
@@ -127,24 +111,14 @@ export function registerClarificationRoutes(app, options) {
|
|
|
127
111
|
requireHostProjectSession(request, options);
|
|
128
112
|
const store = requireProjectStore(options);
|
|
129
113
|
const controlPlane = requireControlPlane(options);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
114
|
+
return submitClarificationAnswers({
|
|
115
|
+
store,
|
|
116
|
+
controlPlane,
|
|
117
|
+
commandId: request.body.command_id,
|
|
118
|
+
roundId: request.params.roundId,
|
|
135
119
|
payload: request.body.payload,
|
|
136
120
|
...(options.now === undefined ? {} : { now: options.now }),
|
|
137
|
-
execute: () => controlPlane.submitClarificationRound(request.params.roundId, request.body.payload, request.body.command_id),
|
|
138
121
|
});
|
|
139
|
-
const response = {
|
|
140
|
-
command_id: execution.command_id,
|
|
141
|
-
disposition: execution.disposition,
|
|
142
|
-
invalidates: clarificationRoundInvalidates(request.params.roundId),
|
|
143
|
-
};
|
|
144
|
-
if (execution.result !== undefined) {
|
|
145
|
-
response.result = execution.result;
|
|
146
|
-
}
|
|
147
|
-
return response;
|
|
148
122
|
});
|
|
149
123
|
}
|
|
150
124
|
//# sourceMappingURL=clarification-routes.js.map
|
|
@@ -266,6 +266,7 @@ export declare const HOST_PROJECT_COLLABORATION_OPENAPI_ROUTES: ({
|
|
|
266
266
|
}>;
|
|
267
267
|
card_message_id: import("@sinclair/typebox").TString;
|
|
268
268
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
269
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
269
270
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
270
271
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
271
272
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -421,6 +422,7 @@ export declare const HOST_PROJECT_COLLABORATION_OPENAPI_ROUTES: ({
|
|
|
421
422
|
}>;
|
|
422
423
|
card_message_id: import("@sinclair/typebox").TString;
|
|
423
424
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
425
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
424
426
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
425
427
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
426
428
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -1117,6 +1117,7 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
1117
1117
|
}>;
|
|
1118
1118
|
card_message_id: import("@sinclair/typebox").TString;
|
|
1119
1119
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
1120
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
1120
1121
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
1121
1122
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
1122
1123
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -410,6 +410,7 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
410
410
|
}>;
|
|
411
411
|
card_message_id: import("@sinclair/typebox").TString;
|
|
412
412
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
413
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
413
414
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
414
415
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
415
416
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -565,6 +566,7 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
565
566
|
}>;
|
|
566
567
|
card_message_id: import("@sinclair/typebox").TString;
|
|
567
568
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
569
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
568
570
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
569
571
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
570
572
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -2400,6 +2402,7 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
2400
2402
|
}>;
|
|
2401
2403
|
card_message_id: import("@sinclair/typebox").TString;
|
|
2402
2404
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
2405
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
2403
2406
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
2404
2407
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
2405
2408
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -1081,6 +1081,7 @@ export declare const BootstrapResponseSchema: {
|
|
|
1081
1081
|
}>;
|
|
1082
1082
|
card_message_id: import("@sinclair/typebox").TString;
|
|
1083
1083
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
1084
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
1084
1085
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
1085
1086
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
1086
1087
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
CREATE TABLE platform_clarification_projection_cursors (
|
|
2
|
+
round_id TEXT PRIMARY KEY REFERENCES clarification_rounds(id),
|
|
3
|
+
binding_ref TEXT NOT NULL,
|
|
4
|
+
version INTEGER NOT NULL CHECK (version >= 0),
|
|
5
|
+
closed INTEGER NOT NULL DEFAULT 0 CHECK (closed IN (0, 1))
|
|
6
|
+
);
|
|
7
|
+
CREATE INDEX idx_platform_clarification_live ON platform_clarification_projection_cursors(closed);
|
|
@@ -44,6 +44,8 @@ export type RegisterRelayHostConnectionPayload = {
|
|
|
44
44
|
browser_secret_write: false;
|
|
45
45
|
repo_viewer: boolean;
|
|
46
46
|
integration_source_ingestion_v1?: boolean;
|
|
47
|
+
integration_development_bot_v1?: boolean;
|
|
48
|
+
integration_clarification_v1?: boolean;
|
|
47
49
|
integration_external_references_v1?: boolean;
|
|
48
50
|
integration_attachment_ingestion_v1?: boolean;
|
|
49
51
|
integration_managed_reference_ingestion_v1?: boolean;
|
|
@@ -57,11 +57,17 @@ function createRegisterPayload(options) {
|
|
|
57
57
|
browser_secret_write: false,
|
|
58
58
|
repo_viewer: capabilities.repo_viewer ?? false,
|
|
59
59
|
integration_source_ingestion_v1: capabilities.integration_source_ingestion_v1 ?? false,
|
|
60
|
+
...(capabilities.integration_development_bot_v1 === true
|
|
61
|
+
? { integration_development_bot_v1: true }
|
|
62
|
+
: {}),
|
|
60
63
|
integration_external_references_v1: capabilities.integration_external_references_v1 ?? false,
|
|
61
64
|
integration_attachment_ingestion_v1: capabilities.integration_attachment_ingestion_v1 ?? false,
|
|
62
65
|
integration_managed_reference_ingestion_v1: capabilities.integration_managed_reference_ingestion_v1 ?? false,
|
|
63
66
|
integration_outbound_v1: capabilities.integration_outbound_v1 ?? false,
|
|
64
67
|
integration_approval_decision_v1: capabilities.integration_approval_decision_v1 ?? false,
|
|
68
|
+
...(capabilities.integration_clarification_v1 === true
|
|
69
|
+
? { integration_clarification_v1: true }
|
|
70
|
+
: {}),
|
|
65
71
|
},
|
|
66
72
|
},
|
|
67
73
|
};
|
|
@@ -201,6 +201,7 @@ export declare const ClarificationRoundProjectionSchema: import("@sinclair/typeb
|
|
|
201
201
|
}>;
|
|
202
202
|
card_message_id: import("@sinclair/typebox").TString;
|
|
203
203
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
204
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
204
205
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
205
206
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
206
207
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -299,6 +300,7 @@ export declare const ActiveClarificationProjectionSchema: import("@sinclair/type
|
|
|
299
300
|
}>;
|
|
300
301
|
card_message_id: import("@sinclair/typebox").TString;
|
|
301
302
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
303
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
302
304
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
303
305
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
304
306
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -437,6 +439,7 @@ export declare const GetClarificationRoundResponseSchema: import("@sinclair/type
|
|
|
437
439
|
}>;
|
|
438
440
|
card_message_id: import("@sinclair/typebox").TString;
|
|
439
441
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
442
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
440
443
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
441
444
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
442
445
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -471,6 +474,7 @@ export declare const SendClarificationRoundMessagePayloadSchema: import("@sincla
|
|
|
471
474
|
}>;
|
|
472
475
|
export declare const SendClarificationRoundMessageDispositionSchema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
473
476
|
kind: import("@sinclair/typebox").TLiteral<"created">;
|
|
477
|
+
message_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
474
478
|
}>, import("@sinclair/typebox").TObject<{
|
|
475
479
|
kind: import("@sinclair/typebox").TLiteral<"stale_round">;
|
|
476
480
|
current_round_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -507,6 +511,7 @@ export declare const SendClarificationRoundMessageResultSchema: import("@sinclai
|
|
|
507
511
|
message_kind: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"user_text">, import("@sinclair/typebox").TLiteral<"agent_text">, import("@sinclair/typebox").TLiteral<"system_notice">, import("@sinclair/typebox").TLiteral<"clarification_request">, import("@sinclair/typebox").TLiteral<"clarification_card">]>;
|
|
508
512
|
body: import("@sinclair/typebox").TString;
|
|
509
513
|
refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
514
|
+
development_operator: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TLiteral<true>>;
|
|
510
515
|
external_reference_reads: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
511
516
|
external_references: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
512
517
|
source_ref: import("@sinclair/typebox").TString;
|
|
@@ -705,9 +710,16 @@ export declare const SendClarificationRoundMessageResultSchema: import("@sinclai
|
|
|
705
710
|
}>;
|
|
706
711
|
export declare const SendClarificationRoundMessageBodySchema: import("@sinclair/typebox").TSchema;
|
|
707
712
|
export declare const SendClarificationRoundMessageResponseSchema: import("@sinclair/typebox").TSchema;
|
|
708
|
-
export declare const SubmitClarificationRoundPayloadSchema: import("@sinclair/typebox").TObject<{
|
|
713
|
+
export declare const SubmitClarificationRoundPayloadSchema: import("@sinclair/typebox").TObject<{
|
|
714
|
+
expected_answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
715
|
+
}>;
|
|
709
716
|
export declare const SubmitClarificationRoundDispositionSchema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
710
717
|
kind: import("@sinclair/typebox").TLiteral<"accepted">;
|
|
718
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
719
|
+
kind: import("@sinclair/typebox").TLiteral<"no_answers">;
|
|
720
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
721
|
+
kind: import("@sinclair/typebox").TLiteral<"answers_changed">;
|
|
722
|
+
current_answer_revision: import("@sinclair/typebox").TInteger;
|
|
711
723
|
}>, import("@sinclair/typebox").TObject<{
|
|
712
724
|
kind: import("@sinclair/typebox").TLiteral<"already_submitted">;
|
|
713
725
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -789,6 +801,7 @@ export declare const SubmitClarificationRoundResultSchema: import("@sinclair/typ
|
|
|
789
801
|
}>;
|
|
790
802
|
card_message_id: import("@sinclair/typebox").TString;
|
|
791
803
|
opening_message_id: import("@sinclair/typebox").TString;
|
|
804
|
+
answer_revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
792
805
|
submitted_at: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
793
806
|
submitted_message_refs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
794
807
|
successor_status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"not_materialized">, import("@sinclair/typebox").TLiteral<"materialized">]>;
|
|
@@ -119,6 +119,8 @@ export const ClarificationRoundProjectionSchema = Type.Object({
|
|
|
119
119
|
request_payload: ClarificationRequestPayloadSchema,
|
|
120
120
|
card_message_id: MessageIdSchema,
|
|
121
121
|
opening_message_id: MessageIdSchema,
|
|
122
|
+
// Append-only eligible answers. Optional for compatibility with older Hosts.
|
|
123
|
+
answer_revision: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
122
124
|
submitted_at: Type.Optional(IsoDateTimeStringSchema),
|
|
123
125
|
submitted_message_refs: Type.Optional(Type.Array(MessageIdSchema)),
|
|
124
126
|
successor_status: Type.Union([Type.Literal("not_materialized"), Type.Literal("materialized")]),
|
|
@@ -168,7 +170,7 @@ export const SendClarificationRoundMessagePayloadSchema = Type.Object({
|
|
|
168
170
|
body: Type.String({ minLength: 1, maxLength: 8000 }),
|
|
169
171
|
}, { additionalProperties: false });
|
|
170
172
|
export const SendClarificationRoundMessageDispositionSchema = Type.Union([
|
|
171
|
-
Type.Object({ kind: Type.Literal("created") }, { additionalProperties: false }),
|
|
173
|
+
Type.Object({ kind: Type.Literal("created"), message_id: Type.Optional(MessageIdSchema) }, { additionalProperties: false }),
|
|
172
174
|
Type.Object({
|
|
173
175
|
kind: Type.Literal("stale_round"),
|
|
174
176
|
current_round_id: Type.Optional(ClarificationRoundRefSchema),
|
|
@@ -181,9 +183,14 @@ export const SendClarificationRoundMessageResultSchema = Type.Object({
|
|
|
181
183
|
}, { additionalProperties: false });
|
|
182
184
|
export const SendClarificationRoundMessageBodySchema = commandEnvelopeSchema(SendClarificationRoundMessagePayloadSchema);
|
|
183
185
|
export const SendClarificationRoundMessageResponseSchema = commandResponseWithResultSchema(SendClarificationRoundMessageDispositionSchema, SendClarificationRoundMessageResultSchema);
|
|
184
|
-
export const SubmitClarificationRoundPayloadSchema = Type.Object({}, { additionalProperties: false });
|
|
186
|
+
export const SubmitClarificationRoundPayloadSchema = Type.Object({ expected_answer_revision: Type.Optional(Type.Integer({ minimum: 0 })) }, { additionalProperties: false });
|
|
185
187
|
export const SubmitClarificationRoundDispositionSchema = Type.Union([
|
|
186
188
|
Type.Object({ kind: Type.Literal("accepted") }, { additionalProperties: false }),
|
|
189
|
+
Type.Object({ kind: Type.Literal("no_answers") }, { additionalProperties: false }),
|
|
190
|
+
Type.Object({
|
|
191
|
+
kind: Type.Literal("answers_changed"),
|
|
192
|
+
current_answer_revision: Type.Integer({ minimum: 0 }),
|
|
193
|
+
}, { additionalProperties: false }),
|
|
187
194
|
Type.Object({
|
|
188
195
|
kind: Type.Literal("already_submitted"),
|
|
189
196
|
successor_status: Type.Union([
|