@case-framework/survey-assistant 0.6.0 → 0.7.0
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 +9 -4
- package/dist/{authoring-references-CW38pYzK.mjs → authoring-references-BJQ_1nMX.mjs} +2 -2
- package/dist/authoring-references-BJQ_1nMX.mjs.map +1 -0
- package/dist/capabilities-1KNnNO1_.mjs +73 -0
- package/dist/capabilities-1KNnNO1_.mjs.map +1 -0
- package/dist/capabilities-default.d.mts +1 -1
- package/dist/capabilities-default.d.mts.map +1 -1
- package/dist/capabilities-default.mjs +22 -25
- package/dist/capabilities-default.mjs.map +1 -1
- package/dist/{constants-BMGTgfjv.d.mts → constants-Be91Gay9.d.mts} +3 -3
- package/dist/{constants-BMGTgfjv.d.mts.map → constants-Be91Gay9.d.mts.map} +1 -1
- package/dist/{controller-proxy-DMTqer6T.mjs → controller-proxy-BH05e-C2.mjs} +21 -8
- package/dist/controller-proxy-BH05e-C2.mjs.map +1 -0
- package/dist/{controller-proxy-mRvez2qw.d.mts → controller-proxy-Bd0ZHBPF.d.mts} +11 -11
- package/dist/controller-proxy-Bd0ZHBPF.d.mts.map +1 -0
- package/dist/{engine-CQwOAcwK.mjs → engine-Bo85Oyj0.mjs} +2985 -2347
- package/dist/engine-Bo85Oyj0.mjs.map +1 -0
- package/dist/engine.d.mts +2 -2
- package/dist/engine.mjs +3 -3
- package/dist/{index-D6nqkz0O.d.mts → index-Tnqv-yKW.d.mts} +56 -71
- package/dist/index-Tnqv-yKW.d.mts.map +1 -0
- package/dist/index-l_EK4yK7.d.mts +404 -0
- package/dist/index-l_EK4yK7.d.mts.map +1 -0
- package/dist/{index-DvTqML-0.d.mts → index-nhrgbgO5.d.mts} +19 -5
- package/dist/index-nhrgbgO5.d.mts.map +1 -0
- package/dist/{index-B0lxsAzx.d.mts → index-x0qprHgK.d.mts} +19 -7
- package/dist/index-x0qprHgK.d.mts.map +1 -0
- package/dist/{lifecycle-BmGAIUlv.d.mts → lifecycle-Bx0aq_4S.d.mts} +7 -1
- package/dist/{lifecycle-BmGAIUlv.d.mts.map → lifecycle-Bx0aq_4S.d.mts.map} +1 -1
- package/dist/{memory-thread-repository-CjFGVNZh.mjs → memory-thread-repository-KWHQWFEW.mjs} +43 -12
- package/dist/memory-thread-repository-KWHQWFEW.mjs.map +1 -0
- package/dist/{protocol-DJUP4gc0.mjs → protocol-BhzQbx81.mjs} +66 -16
- package/dist/protocol-BhzQbx81.mjs.map +1 -0
- package/dist/protocol.d.mts +3 -3
- package/dist/protocol.mjs +2 -2
- package/dist/react-B3ybjJ-X.mjs +1620 -0
- package/dist/react-B3ybjJ-X.mjs.map +1 -0
- package/dist/react-integration.d.mts +1 -1
- package/dist/react-integration.mjs +1 -1
- package/dist/react.d.mts +3 -3
- package/dist/react.mjs +3 -3
- package/dist/references/assistant-operations.md +45 -39
- package/dist/references/expressions.md +28 -0
- package/dist/references/item-types.md +1 -1
- package/dist/references/localization.md +5 -4
- package/dist/references/rich-text-content.md +60 -27
- package/dist/references/source-material-surveys.md +9 -2
- package/dist/references/survey-data-model.md +9 -1
- package/dist/{request-context-BjTHNcDd.mjs → request-context-CG4SWijt.mjs} +3 -3
- package/dist/{request-context-BjTHNcDd.mjs.map → request-context-CG4SWijt.mjs.map} +1 -1
- package/dist/server-agent.d.mts +19 -8
- package/dist/server-agent.d.mts.map +1 -1
- package/dist/server-agent.mjs +7 -11
- package/dist/server-agent.mjs.map +1 -1
- package/dist/server-runtime.d.mts +19 -13
- package/dist/server-runtime.d.mts.map +1 -1
- package/dist/server-runtime.mjs +7 -2
- package/dist/server-runtime.mjs.map +1 -1
- package/dist/server-tasks.d.mts +1 -1
- package/dist/server-tasks.mjs +2 -2
- package/dist/server-tools.d.mts +1 -1
- package/dist/server-tools.mjs +1 -1
- package/dist/server.d.mts +5 -5
- package/dist/server.mjs +3 -3
- package/dist/{tasks-DxzD25Zc.d.mts → tasks-CYqrcaRO.d.mts} +4 -4
- package/dist/{tasks-DxzD25Zc.d.mts.map → tasks-CYqrcaRO.d.mts.map} +1 -1
- package/dist/{thread-handlers-AbQbt4sX.d.mts → thread-handlers-DBAaU7BA.d.mts} +6 -4
- package/dist/thread-handlers-DBAaU7BA.d.mts.map +1 -0
- package/dist/{tools-CFh35R4d.mjs → tools-BvSovehT.mjs} +431 -495
- package/dist/tools-BvSovehT.mjs.map +1 -0
- package/dist/ui.css +1 -1
- package/dist/ui.d.mts +5 -4
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +619 -66
- package/dist/ui.mjs.map +1 -1
- package/docs/integration.md +40 -0
- package/package.json +21 -19
- package/dist/authoring-references-CW38pYzK.mjs.map +0 -1
- package/dist/controller-proxy-DMTqer6T.mjs.map +0 -1
- package/dist/controller-proxy-mRvez2qw.d.mts.map +0 -1
- package/dist/engine-CQwOAcwK.mjs.map +0 -1
- package/dist/form-authoring-kQDgC5oz.mjs +0 -155
- package/dist/form-authoring-kQDgC5oz.mjs.map +0 -1
- package/dist/index-B0lxsAzx.d.mts.map +0 -1
- package/dist/index-BS-Xjk1h.d.mts +0 -224
- package/dist/index-BS-Xjk1h.d.mts.map +0 -1
- package/dist/index-D6nqkz0O.d.mts.map +0 -1
- package/dist/index-DvTqML-0.d.mts.map +0 -1
- package/dist/memory-thread-repository-CjFGVNZh.mjs.map +0 -1
- package/dist/protocol-DJUP4gc0.mjs.map +0 -1
- package/dist/react-Dqlmasrs.mjs +0 -768
- package/dist/react-Dqlmasrs.mjs.map +0 -1
- package/dist/thread-handlers-AbQbt4sX.d.mts.map +0 -1
- package/dist/tools-CFh35R4d.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-B3ybjJ-X.mjs","names":["findLastUserMessageIndex","surveyAssistantPackageVersion"],"sources":["../src/react/session-state.ts","../src/react/turn-authorization.ts","../src/react/transport.ts","../src/react/thread-client.ts","../src/react/support-bundle-limits.ts","../src/react/diagnostic-store.ts","../package.json","../src/react/support-bundle.ts","../src/react/model-catalog.ts","../src/react/document-baseline.ts","../src/react/use-survey-assistant-session.ts"],"sourcesContent":["export type SurveyAssistantSessionState =\n | \"idle\"\n | \"submitting\"\n | \"streaming\"\n | \"completed\"\n | \"failed\"\n | \"aborted\"\n | \"applying\"\n | \"applied\";\n\nexport type SurveyAssistantSessionEvent =\n | { type: \"submit\" }\n | { type: \"stream-started\" }\n | { type: \"completed\" }\n | { type: \"apply-started\" }\n | { type: \"applied\" }\n | { type: \"failed\" }\n | { type: \"aborted\" }\n | { type: \"reset\"; hasTranscript: boolean };\n\nexport const isSurveyAssistantTurnActive = ({\n isStreaming,\n state,\n}: {\n isStreaming: boolean;\n state: SurveyAssistantSessionState;\n}): boolean =>\n state !== \"aborted\" &&\n (isStreaming || state === \"submitting\" || state === \"streaming\" || state === \"applying\");\n\nexport const reduceSurveyAssistantSessionState = (\n _state: SurveyAssistantSessionState,\n event: SurveyAssistantSessionEvent,\n): SurveyAssistantSessionState => {\n switch (event.type) {\n case \"submit\":\n return \"submitting\";\n case \"stream-started\":\n return \"streaming\";\n case \"completed\":\n return \"completed\";\n case \"apply-started\":\n return \"applying\";\n case \"applied\":\n return \"applied\";\n case \"failed\":\n return \"failed\";\n case \"aborted\":\n return \"aborted\";\n case \"reset\":\n return event.hasTranscript ? \"completed\" : \"idle\";\n }\n};\n","import {\n SURVEY_ASSISTANT_PROTOCOL_VERSION,\n SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n applyReceiptSchema,\n surveyAssistantTurnFinalSchema,\n surveyChangeSetSchema,\n type ApplyReceipt,\n type SurveyAssistantSnapshot,\n type SurveyAssistantTurnFinal,\n type SurveyApplyResult,\n type SurveyChangeSet,\n type SurveyDocumentVersion,\n} from \"../protocol\";\nimport type { UIMessage } from \"ai\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isCompletedToolPart = (\n part: UIMessage[\"parts\"][number],\n): part is UIMessage[\"parts\"][number] & { state: \"output-available\"; output: unknown } =>\n (part.type === \"dynamic-tool\" || part.type.startsWith(\"tool-\")) &&\n \"state\" in part &&\n part.state === \"output-available\" &&\n \"output\" in part;\n\nexport const unwrapSurveyAssistantToolOutput = (output: unknown) => {\n if (isRecord(output) && \"output\" in output && output.output !== undefined) {\n return output.output;\n }\n return output;\n};\n\nexport const parseSurveyChangeSet = (output: unknown): SurveyChangeSet | null => {\n const parsed = surveyChangeSetSchema.safeParse(unwrapSurveyAssistantToolOutput(output));\n return parsed.success ? parsed.data : null;\n};\n\nexport const collectSurveyChangeSets = (messages: UIMessage[]): SurveyChangeSet[] => {\n const changes: SurveyChangeSet[] = [];\n for (const message of messages) {\n for (const part of message.parts) {\n if (!isCompletedToolPart(part)) {\n continue;\n }\n const change = parseSurveyChangeSet(part.output);\n if (change) {\n changes.push(change);\n }\n }\n }\n return changes;\n};\n\nconst findLastUserMessageIndex = (messages: UIMessage[]) => {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.role === \"user\") return index;\n }\n return -1;\n};\n\nexport type SurveyTurnAuthorization =\n | { status: \"pending\" }\n | { status: \"invalid\"; reason: string; turnId?: string }\n | {\n status: \"failed\" | \"aborted\";\n turnFinal: SurveyAssistantTurnFinal;\n changeSets: [];\n }\n | {\n status: \"completed\";\n turnFinal: SurveyAssistantTurnFinal;\n changeSets: SurveyChangeSet[];\n };\n\nexport type SurveyTurnOutcome =\n | {\n status: \"failed\";\n terminationReason?: SurveyAssistantTurnFinal[\"terminationReason\"];\n }\n | {\n status: \"aborted\";\n terminationReason?: SurveyAssistantTurnFinal[\"terminationReason\"];\n }\n | {\n status: \"blocked\";\n blockedChangeSetCount: number;\n }\n | {\n status: \"apply-failed\";\n appliedChangeSetCount: number;\n failedChangeSetCount: number;\n };\n\nexport const resolveLatestSurveyTurnAuthorization = (\n messages: UIMessage[],\n): SurveyTurnAuthorization => {\n const lastUserIndex = findLastUserMessageIndex(messages);\n if (lastUserIndex < 0) {\n return { status: \"pending\" };\n }\n\n const turnMessages = messages.slice(lastUserIndex + 1);\n const finalParts = turnMessages\n .flatMap((message) => message.parts)\n .filter((part) => part.type === SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE);\n if (finalParts.length === 0) {\n return { status: \"pending\" };\n }\n if (finalParts.length !== 1) {\n return { status: \"invalid\", reason: \"The assistant returned multiple turn finals.\" };\n }\n\n const finalPart = finalParts[0];\n const finalParse = surveyAssistantTurnFinalSchema.safeParse(\n finalPart && \"data\" in finalPart ? finalPart.data : undefined,\n );\n if (!finalParse.success) {\n return { status: \"invalid\", reason: \"The assistant returned an invalid turn final.\" };\n }\n const turnFinal = finalParse.data;\n if (turnFinal.status !== \"completed\") {\n return { status: turnFinal.status, turnFinal, changeSets: [] };\n }\n\n const candidates = collectSurveyChangeSets(turnMessages).filter(\n (change) => change.turnId === turnFinal.turnId,\n );\n const candidatesById = new Map<string, SurveyChangeSet>();\n for (const candidate of candidates) {\n if (candidatesById.has(candidate.id)) {\n return {\n status: \"invalid\",\n turnId: turnFinal.turnId,\n reason: `The assistant returned duplicate change set \"${candidate.id}\".`,\n };\n }\n candidatesById.set(candidate.id, candidate);\n }\n\n for (const blockedChangeSetId of turnFinal.blockedChangeSetIds ?? []) {\n const candidate = candidatesById.get(blockedChangeSetId);\n if (!candidate || candidate.status !== \"rejected\" || candidate.validation.valid) {\n return {\n status: \"invalid\",\n turnId: turnFinal.turnId,\n reason: `The assistant did not provide blocked change set \"${blockedChangeSetId}\".`,\n };\n }\n }\n\n const changeSets: SurveyChangeSet[] = [];\n for (const changeSetId of turnFinal.executableChangeSetIds) {\n const candidate = candidatesById.get(changeSetId);\n if (!candidate || candidate.status !== \"validated\" || !candidate.validation.valid) {\n return {\n status: \"invalid\",\n turnId: turnFinal.turnId,\n reason: `The assistant did not provide authorized change set \"${changeSetId}\".`,\n };\n }\n changeSets.push(candidate);\n }\n\n return { status: \"completed\", turnFinal, changeSets };\n};\n\nexport const resolveSurveyTurnOutcome = ({\n applyResultsByChangeId,\n authorization,\n}: {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n authorization: SurveyTurnAuthorization;\n}): SurveyTurnOutcome | null => {\n if (authorization.status === \"failed\" || authorization.status === \"aborted\") {\n return {\n status: authorization.status,\n terminationReason: authorization.turnFinal.terminationReason,\n };\n }\n if (authorization.status !== \"completed\") {\n return null;\n }\n\n const blockedChangeSetCount = authorization.turnFinal.blockedChangeSetIds?.length ?? 0;\n if (blockedChangeSetCount > 0) {\n return { status: \"blocked\", blockedChangeSetCount };\n }\n\n if (authorization.changeSets.length === 0) {\n return null;\n }\n\n const results = authorization.changeSets.map((change) => applyResultsByChangeId[change.id]);\n if (results.some((result) => result === undefined)) {\n return null;\n }\n\n const failedChangeSetCount = results.filter((result) => result.status !== \"applied\").length;\n if (failedChangeSetCount === 0) {\n return null;\n }\n\n return {\n status: \"apply-failed\",\n appliedChangeSetCount: results.length - failedChangeSetCount,\n failedChangeSetCount,\n };\n};\n\nexport const getSurveyDocumentVersionFromSnapshot = (\n snapshot: SurveyAssistantSnapshot,\n): SurveyDocumentVersion => ({ ...snapshot.version });\n\nexport const createApplyReceipts = ({\n afterSnapshot,\n beforeSnapshot,\n changeSets,\n results,\n turnFinal,\n createdAt = new Date().toISOString(),\n}: {\n afterSnapshot: SurveyAssistantSnapshot | null;\n beforeSnapshot: SurveyAssistantSnapshot;\n changeSets: SurveyChangeSet[];\n results: SurveyApplyResult[];\n turnFinal: SurveyAssistantTurnFinal;\n createdAt?: string;\n}): ApplyReceipt[] => {\n const beforeVersion = getSurveyDocumentVersionFromSnapshot(beforeSnapshot);\n const afterVersion = afterSnapshot\n ? getSurveyDocumentVersionFromSnapshot(afterSnapshot)\n : undefined;\n const resultsByChangeId = new Map(results.map((result) => [result.changeId, result]));\n\n return changeSets.map((changeSet) => {\n const result = resultsByChangeId.get(changeSet.id);\n const status = result?.status ?? \"failed\";\n return applyReceiptSchema.parse({\n protocolVersion: SURVEY_ASSISTANT_PROTOCOL_VERSION,\n turnId: turnFinal.turnId,\n changeSetId: changeSet.id,\n beforeVersion,\n ...(status === \"applied\" && afterVersion ? { afterVersion } : {}),\n status,\n operationCount: changeSet.operations.length,\n ...(status === \"applied\" && afterVersion?.historyIndex !== undefined\n ? { commit: { index: afterVersion.historyIndex } }\n : {}),\n ...(result?.issues ? { issues: result.issues } : {}),\n createdAt,\n });\n });\n};\n","import { DefaultChatTransport, type UIMessage } from \"ai\";\nimport { readSurveyAssistantJson } from \"./client-error\";\n\nconst findLastUserMessage = (messages: UIMessage[]): UIMessage | undefined => {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.role === \"user\") return messages[index];\n }\n return undefined;\n};\n\nconst fetchSurveyAssistantChat: typeof fetch = async (input, init) => {\n const response = await globalThis.fetch(input, init);\n if (!response.ok) await readSurveyAssistantJson(response);\n return response;\n};\n\nexport const createSurveyAssistantTransport = ({\n api = \"/api/survey-assistant/chat\",\n resourceId,\n surveyId,\n threadId,\n}: {\n api?: string;\n resourceId: string;\n surveyId?: string;\n threadId: string;\n}) =>\n new DefaultChatTransport({\n api,\n body: { resourceId, ...(surveyId ? { surveyId } : {}), threadId },\n fetch: fetchSurveyAssistantChat,\n prepareSendMessagesRequest: ({\n api,\n body,\n credentials,\n headers,\n id,\n messageId,\n messages,\n trigger,\n }) => {\n const latestUserMessage = findLastUserMessage(messages);\n return {\n api,\n credentials,\n headers,\n body: {\n ...body,\n id,\n messages: latestUserMessage ? [latestUserMessage] : [],\n trigger,\n messageId,\n },\n };\n },\n });\n","import {\n surveyAssistantThreadListSchema,\n surveyAssistantThreadSchema,\n surveyAssistantThreadTranscriptSchema,\n type SurveyAssistantThread,\n type SurveyAssistantThreadList,\n type SurveyAssistantThreadTranscript,\n} from \"../protocol\";\nimport { readSurveyAssistantJson } from \"./client-error\";\n\nexport interface SurveyAssistantThreadClient {\n delete(threadId: string): Promise<void>;\n create(title?: string): Promise<SurveyAssistantThread>;\n list(): Promise<SurveyAssistantThread[]>;\n /** Paged history capability. Older custom clients may omit this method. */\n listPage?(options?: { cursor?: string }): Promise<SurveyAssistantThreadList>;\n read(\n threadId: string,\n cursor?: string,\n options?: { signal?: AbortSignal },\n ): Promise<SurveyAssistantThreadTranscript>;\n rename(threadId: string, title: string): Promise<SurveyAssistantThread>;\n setAutomaticTitle(threadId: string, title?: string): Promise<SurveyAssistantThread>;\n}\n\nexport const createSurveyAssistantThreadClient = (\n api = \"/api/survey-assistant/threads\",\n): SurveyAssistantThreadClient => ({\n async delete(threadId) {\n const response = await fetch(`${api}/${encodeURIComponent(threadId)}`, { method: \"DELETE\" });\n if (!response.ok) await readSurveyAssistantJson(response);\n },\n async create(title) {\n const body = await readSurveyAssistantJson(\n await fetch(api, {\n body: JSON.stringify(title ? { title } : {}),\n headers: { \"content-type\": \"application/json\" },\n method: \"POST\",\n }),\n );\n return surveyAssistantThreadSchema.parse(body.thread);\n },\n async list() {\n const body = await readSurveyAssistantJson(await fetch(api, { cache: \"no-store\" }));\n return surveyAssistantThreadListSchema.parse(body).threads;\n },\n async listPage(options) {\n const search = new URLSearchParams();\n if (options?.cursor) search.set(\"cursor\", options.cursor);\n const body = await readSurveyAssistantJson(\n await fetch(`${api}${search.size ? `?${search}` : \"\"}`, { cache: \"no-store\" }),\n );\n return surveyAssistantThreadListSchema.parse(body);\n },\n async read(threadId, cursor, options) {\n const search = cursor ? `?cursor=${encodeURIComponent(cursor)}` : \"\";\n const body = await readSurveyAssistantJson(\n await fetch(`${api}/${encodeURIComponent(threadId)}${search}`, {\n cache: \"no-store\",\n signal: options?.signal,\n }),\n );\n return surveyAssistantThreadTranscriptSchema.parse(body);\n },\n async rename(threadId, title) {\n const body = await readSurveyAssistantJson(\n await fetch(`${api}/${encodeURIComponent(threadId)}`, {\n body: JSON.stringify({ mode: \"manual\", title }),\n headers: { \"content-type\": \"application/json\" },\n method: \"PATCH\",\n }),\n );\n return surveyAssistantThreadSchema.parse(body.thread);\n },\n async setAutomaticTitle(threadId, title) {\n const body = await readSurveyAssistantJson(\n await fetch(`${api}/${encodeURIComponent(threadId)}`, {\n body: JSON.stringify({ mode: \"automatic\", ...(title ? { title } : {}) }),\n headers: { \"content-type\": \"application/json\" },\n method: \"PATCH\",\n }),\n );\n return surveyAssistantThreadSchema.parse(body.thread);\n },\n});\n","export interface SurveyAssistantSupportBundleLimits {\n attemptEvents: number;\n attemptStoreBytes: number;\n bundleBytes: number;\n emailWarningBytes: number;\n retainedAttempts: number;\n transcriptBytes: number;\n transcriptMessages: number;\n transcriptPages: number;\n zipEntryBytes: number;\n}\n\nconst MEBIBYTE = 1024 * 1024;\n\nexport const SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_LIMITS = {\n attemptEvents: 200,\n attemptStoreBytes: 48 * MEBIBYTE,\n bundleBytes: 64 * MEBIBYTE,\n emailWarningBytes: 15 * MEBIBYTE,\n retainedAttempts: 5,\n transcriptBytes: 24 * MEBIBYTE,\n transcriptMessages: 2_000,\n transcriptPages: 20,\n zipEntryBytes: 32 * MEBIBYTE,\n} as const satisfies SurveyAssistantSupportBundleLimits;\n\nexport const resolveSurveyAssistantSupportBundleLimits = (\n overrides?: Partial<SurveyAssistantSupportBundleLimits>,\n): SurveyAssistantSupportBundleLimits => {\n const limits = { ...SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_LIMITS, ...overrides };\n for (const [name, value] of Object.entries(limits)) {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error(\n `Survey assistant support-bundle limit \"${name}\" must be a positive integer.`,\n );\n }\n }\n if (limits.transcriptBytes > limits.zipEntryBytes) {\n throw new Error(\"The transcript limit cannot exceed the individual ZIP-entry limit.\");\n }\n if (limits.zipEntryBytes > limits.bundleBytes) {\n throw new Error(\"The individual ZIP-entry limit cannot exceed the complete bundle limit.\");\n }\n return limits;\n};\n","import { hashString } from \"../protocol/digest\";\nimport type {\n ApplyReceipt,\n SurveyAssistantApplyOutcome,\n SurveyAssistantAttachmentReference,\n SurveyAssistantErrorInfo,\n SurveyAssistantSnapshot,\n SurveyAssistantTurnFinal,\n} from \"../protocol\";\nimport type { FileUIPart } from \"ai\";\nimport {\n resolveSurveyAssistantSupportBundleLimits,\n type SurveyAssistantSupportBundleLimits,\n} from \"./support-bundle-limits\";\n\nexport type SurveyAssistantDiagnosticEventFields = Record<\n string,\n boolean | number | string | null | undefined\n>;\n\nexport interface SurveyAssistantDiagnosticEvent {\n at: string;\n event: string;\n fields?: SurveyAssistantDiagnosticEventFields;\n}\n\nexport interface SurveyAssistantDiagnosticAttachmentReference {\n bytes: number;\n filename: string;\n mediaType: string;\n sessionContentDigest: string;\n storeKey: string;\n}\n\nexport interface SurveyAssistantDiagnosticAttempt {\n applyOutcome?: SurveyAssistantApplyOutcome;\n applyReceipts?: ApplyReceipt[];\n attachments: SurveyAssistantDiagnosticAttachmentReference[];\n captureFailure?: string;\n error?: SurveyAssistantErrorInfo;\n events: SurveyAssistantDiagnosticEvent[];\n messages?: unknown[];\n modelId?: string;\n requestId: string;\n resourceId: string;\n submittedAt: string;\n submittedSurvey?: SurveyAssistantSnapshot | null;\n threadId: string;\n turnFinal?: SurveyAssistantTurnFinal;\n}\n\ninterface StoredAttachment extends SurveyAssistantDiagnosticAttachmentReference {\n dataUrl?: string;\n retainedBytes: number;\n}\n\ninterface StoredAttempt extends SurveyAssistantDiagnosticAttempt {\n retainedBytes: number;\n}\n\nexport interface SurveyAssistantDiagnosticStore {\n beginAttempt(input: {\n attachmentReferences?: SurveyAssistantAttachmentReference[];\n files: FileUIPart[];\n modelId?: string;\n requestId?: string;\n resourceId: string;\n submittedSurvey: SurveyAssistantSnapshot | null;\n threadId: string;\n }): string;\n deleteThread(threadId: string): void;\n getAttachment(storeKey: string): StoredAttachment | undefined;\n getExportAttempt(threadId: string): SurveyAssistantDiagnosticAttempt | undefined;\n recordApplyOutcome(threadId: string, outcome: SurveyAssistantApplyOutcome): void;\n recordApplyReceipts(threadId: string, receipts: ApplyReceipt[]): void;\n recordEvent(threadId: string, event: string, fields?: SurveyAssistantDiagnosticEventFields): void;\n recordFailure(threadId: string, messages: unknown[], error: SurveyAssistantErrorInfo): void;\n recordTurnFinal(threadId: string, turnFinal: SurveyAssistantTurnFinal): void;\n}\n\nexport const createSurveyAssistantDiagnosticId = (prefix = \"attempt\"): string => {\n const randomId = globalThis.crypto?.randomUUID?.();\n if (randomId) return `${prefix}-${randomId}`.slice(0, 64);\n const segment = () => Math.random().toString(36).slice(2).padEnd(12, \"0\");\n return `${prefix}-${segment()}${segment()}`.slice(0, 64);\n};\n\nconst cloneDiagnosticValue = <T>(value: T): T => {\n if (typeof structuredClone === \"function\") return structuredClone(value);\n return JSON.parse(JSON.stringify(value)) as T;\n};\n\nconst getDataUrlBytes = (value: string): number => {\n const comma = value.indexOf(\",\");\n if (comma < 0) return new TextEncoder().encode(value).byteLength;\n const payload = value.slice(comma + 1).replace(/\\s/g, \"\");\n if (!/;base64,/i.test(value.slice(0, comma + 1))) {\n try {\n return new TextEncoder().encode(decodeURIComponent(payload)).byteLength;\n } catch {\n return new TextEncoder().encode(payload).byteLength;\n }\n }\n const padding = payload.endsWith(\"==\") ? 2 : payload.endsWith(\"=\") ? 1 : 0;\n return Math.max(0, Math.floor((payload.length * 3) / 4) - padding);\n};\n\nconst stripMessageAttachmentBytes = (messages: unknown[]): unknown[] => {\n const cloned = cloneDiagnosticValue(messages);\n if (!Array.isArray(cloned)) return [];\n for (const message of cloned) {\n if (!message || typeof message !== \"object\" || !(\"parts\" in message)) continue;\n const parts = (message as { parts?: unknown }).parts;\n if (!Array.isArray(parts)) continue;\n for (const part of parts) {\n if (\n part &&\n typeof part === \"object\" &&\n \"type\" in part &&\n part.type === \"file\" &&\n \"url\" in part &&\n typeof part.url === \"string\" &&\n part.url.startsWith(\"data:\")\n ) {\n part.url = \"[attachment bytes retained separately when available]\";\n }\n }\n }\n return cloned;\n};\n\nconst getApproximateBytes = (value: unknown): number => {\n try {\n return new TextEncoder().encode(JSON.stringify(value)).byteLength;\n } catch {\n return 0;\n }\n};\n\nconst toAttachmentReference = (\n attachment: StoredAttachment,\n): SurveyAssistantDiagnosticAttachmentReference => ({\n bytes: attachment.bytes,\n filename: attachment.filename,\n mediaType: attachment.mediaType,\n sessionContentDigest: attachment.sessionContentDigest,\n storeKey: attachment.storeKey,\n});\n\nconst toPublicAttempt = ({ retainedBytes: _retainedBytes, ...attempt }: StoredAttempt) =>\n cloneDiagnosticValue(attempt);\n\nconst safeEventFields = (\n fields: SurveyAssistantDiagnosticEventFields | undefined,\n): SurveyAssistantDiagnosticEventFields | undefined => {\n if (!fields) return undefined;\n const allowed: SurveyAssistantDiagnosticEventFields = {};\n for (const [key, value] of Object.entries(fields)) {\n if (\n !/^(?:aborted|applied|changeSetId|code|count|durationMs|httpStatus|operationCount|retryable|status|turnId)$/.test(\n key,\n )\n )\n continue;\n if (\n value === null ||\n value === undefined ||\n typeof value === \"boolean\" ||\n typeof value === \"number\" ||\n typeof value === \"string\"\n ) {\n allowed[key] = typeof value === \"string\" ? value.slice(0, 240) : value;\n }\n }\n return Object.keys(allowed).length > 0 ? allowed : undefined;\n};\n\nexport const createSurveyAssistantDiagnosticStore = (\n overrides?: Partial<SurveyAssistantSupportBundleLimits>,\n): SurveyAssistantDiagnosticStore => {\n const limits = resolveSurveyAssistantSupportBundleLimits(overrides);\n const attempts: StoredAttempt[] = [];\n const attachments = new Map<string, StoredAttachment>();\n let attachmentSequence = 0;\n\n const latest = (threadId: string) =>\n [...attempts].reverse().find((attempt) => attempt.threadId === threadId);\n\n const exportAttempt = (threadId: string) => latest(threadId);\n\n const updateAttemptBytes = (attempt: StoredAttempt) => {\n const { retainedBytes: _retainedBytes, ...value } = attempt;\n attempt.retainedBytes = getApproximateBytes(value);\n };\n\n const retainedBytes = () =>\n attempts.reduce((total, attempt) => total + attempt.retainedBytes, 0) +\n [...attachments.values()].reduce((total, attachment) => total + attachment.retainedBytes, 0);\n\n const removeUnreferencedAttachments = () => {\n const retainedKeys = new Set(\n attempts.flatMap((attempt) => attempt.attachments.map((item) => item.storeKey)),\n );\n for (const key of attachments.keys()) if (!retainedKeys.has(key)) attachments.delete(key);\n };\n\n const enforceLimits = () => {\n if (attempts.length > limits.retainedAttempts) {\n const newest = attempts.at(-1)!;\n const newestFirst = [...attempts].reverse();\n const retained = new Set(\n [\n newest,\n ...newestFirst.filter(\n (attempt) =>\n attempt !== newest &&\n (attempt.error !== undefined || attempt.captureFailure !== undefined),\n ),\n ...newestFirst.filter(\n (attempt) =>\n attempt !== newest &&\n attempt.error === undefined &&\n attempt.captureFailure === undefined,\n ),\n ].slice(0, limits.retainedAttempts),\n );\n for (let index = attempts.length - 1; index >= 0; index -= 1) {\n if (!retained.has(attempts[index]!)) attempts.splice(index, 1);\n }\n }\n removeUnreferencedAttachments();\n if (retainedBytes() <= limits.attemptStoreBytes) return;\n\n const protectedAttempts = new Set(\n [...new Set(attempts.map((attempt) => attempt.threadId))]\n .map(exportAttempt)\n .filter((attempt): attempt is StoredAttempt => attempt !== undefined),\n );\n for (const attempt of attempts) {\n if (protectedAttempts.has(attempt)) continue;\n attempt.messages = undefined;\n attempt.submittedSurvey = undefined;\n updateAttemptBytes(attempt);\n if (retainedBytes() <= limits.attemptStoreBytes) return;\n }\n const protectedAttachmentKeys = new Set(\n [...protectedAttempts].flatMap((attempt) =>\n attempt.attachments.map((attachment) => attachment.storeKey),\n ),\n );\n for (const attachment of attachments.values()) {\n if (protectedAttachmentKeys.has(attachment.storeKey)) continue;\n attachment.dataUrl = undefined;\n attachment.retainedBytes = 0;\n if (retainedBytes() <= limits.attemptStoreBytes) return;\n }\n for (const attachment of attachments.values()) {\n attachment.dataUrl = undefined;\n attachment.retainedBytes = 0;\n if (retainedBytes() <= limits.attemptStoreBytes) return;\n }\n for (const protectedAttempt of protectedAttempts) {\n protectedAttempt.messages = undefined;\n protectedAttempt.submittedSurvey = undefined;\n protectedAttempt.captureFailure ??=\n \"Diagnostic content was evicted because the browser limit was reached.\";\n updateAttemptBytes(protectedAttempt);\n if (retainedBytes() <= limits.attemptStoreBytes) return;\n }\n };\n\n const retainAttachment = (file: FileUIPart): SurveyAssistantDiagnosticAttachmentReference => {\n const dataUrl =\n typeof file.url === \"string\" && file.url.startsWith(\"data:\") ? file.url : undefined;\n const mediaType = file.mediaType || \"application/octet-stream\";\n const filename = file.filename?.trim() || \"Attached document\";\n const bytes = dataUrl ? getDataUrlBytes(dataUrl) : 0;\n const sessionContentDigest = hashString(\n dataUrl ?? `${mediaType}\\u0000${filename}\\u0000${bytes}`,\n );\n if (dataUrl) {\n for (const candidate of attachments.values()) {\n if (\n candidate.sessionContentDigest === sessionContentDigest &&\n candidate.mediaType === mediaType &&\n candidate.bytes === bytes &&\n candidate.dataUrl === dataUrl\n ) {\n return toAttachmentReference(candidate);\n }\n }\n }\n attachmentSequence += 1;\n const stored: StoredAttachment = {\n bytes,\n filename,\n mediaType,\n sessionContentDigest,\n storeKey: `${sessionContentDigest}-${attachmentSequence}`,\n retainedBytes: dataUrl?.length ?? 0,\n ...(dataUrl ? { dataUrl } : {}),\n };\n attachments.set(stored.storeKey, stored);\n return toAttachmentReference(stored);\n };\n\n const retainAttachmentReference = (\n reference: SurveyAssistantAttachmentReference,\n ): SurveyAssistantDiagnosticAttachmentReference => {\n const filename = reference.filename.trim() || \"Attached document\";\n const mediaType = reference.mediaType || \"application/octet-stream\";\n const sessionContentDigest = hashString(\n `${reference.documentId ?? \"restored\"}\\u0000${mediaType}\\u0000${filename}\\u0000${reference.bytes}`,\n );\n attachmentSequence += 1;\n const stored: StoredAttachment = {\n bytes: reference.bytes,\n filename,\n mediaType,\n retainedBytes: 0,\n sessionContentDigest,\n storeKey: `${sessionContentDigest}-${attachmentSequence}`,\n };\n attachments.set(stored.storeKey, stored);\n return toAttachmentReference(stored);\n };\n\n const recordEvent = (\n threadId: string,\n event: string,\n fields?: SurveyAssistantDiagnosticEventFields,\n ) => {\n const attempt = latest(threadId);\n if (!attempt) return;\n attempt.events.push({\n at: new Date().toISOString(),\n event: event.slice(0, 80),\n ...(safeEventFields(fields) ? { fields: safeEventFields(fields) } : {}),\n });\n if (attempt.events.length > limits.attemptEvents) {\n attempt.events.splice(0, attempt.events.length - limits.attemptEvents);\n }\n updateAttemptBytes(attempt);\n };\n\n return {\n beginAttempt(input) {\n const requestId = input.requestId ?? createSurveyAssistantDiagnosticId();\n const attempt: StoredAttempt = {\n attachments: [\n ...input.files.map(retainAttachment),\n ...(input.attachmentReferences ?? []).map(retainAttachmentReference),\n ],\n events: [],\n ...(input.modelId ? { modelId: input.modelId } : {}),\n requestId,\n resourceId: input.resourceId,\n submittedAt: new Date().toISOString(),\n submittedSurvey: cloneDiagnosticValue(input.submittedSurvey),\n threadId: input.threadId,\n retainedBytes: 0,\n };\n updateAttemptBytes(attempt);\n attempts.push(attempt);\n recordEvent(input.threadId, \"submission\");\n enforceLimits();\n return requestId;\n },\n deleteThread(threadId) {\n for (let index = attempts.length - 1; index >= 0; index -= 1) {\n if (attempts[index]?.threadId === threadId) attempts.splice(index, 1);\n }\n removeUnreferencedAttachments();\n },\n getAttachment(storeKey) {\n return attachments.get(storeKey);\n },\n getExportAttempt(threadId) {\n const attempt = exportAttempt(threadId);\n return attempt ? toPublicAttempt(attempt) : undefined;\n },\n recordApplyOutcome(threadId, outcome) {\n const attempt = latest(threadId);\n if (!attempt) return;\n attempt.applyOutcome = cloneDiagnosticValue(outcome);\n recordEvent(threadId, \"apply-result\", { status: outcome.status });\n enforceLimits();\n },\n recordApplyReceipts(threadId, receipts) {\n const attempt = latest(threadId);\n if (!attempt) return;\n attempt.applyReceipts = cloneDiagnosticValue(receipts);\n recordEvent(threadId, \"apply-receipts\", {\n count: receipts.length,\n operationCount: receipts.reduce((sum, receipt) => sum + receipt.operationCount, 0),\n });\n enforceLimits();\n },\n recordEvent,\n recordFailure(threadId, messages, error) {\n const attempt = latest(threadId);\n if (!attempt) return;\n try {\n attempt.messages = stripMessageAttachmentBytes(messages);\n attempt.error = cloneDiagnosticValue(error);\n recordEvent(threadId, \"failure\", {\n code: error.code,\n httpStatus: error.upstreamStatus,\n retryable: error.retryable,\n });\n enforceLimits();\n } catch {\n attempt.messages = undefined;\n attempt.captureFailure = \"The failed assistant messages could not be captured.\";\n recordEvent(threadId, \"capture-failed\");\n }\n },\n recordTurnFinal(threadId, turnFinal) {\n const attempt = latest(threadId);\n if (!attempt) return;\n attempt.turnFinal = cloneDiagnosticValue(turnFinal);\n recordEvent(threadId, \"turn-final\", {\n durationMs: turnFinal.durationMs,\n status: turnFinal.status,\n turnId: turnFinal.turnId,\n });\n enforceLimits();\n },\n };\n};\n","","import {\n getSurveyAssistantEmbeddedBinaryMarker,\n isSurveyAssistantSensitiveMetadataKey,\n redactSurveyAssistantDiagnosticSecrets,\n type SurveyAssistantSnapshot,\n} from \"../protocol\";\nimport { Zip, ZipPassThrough } from \"fflate\";\nimport type { SurveyAssistantController } from \"./controller\";\nimport type {\n SurveyAssistantDiagnosticAttempt,\n SurveyAssistantDiagnosticStore,\n} from \"./diagnostic-store\";\nimport {\n resolveSurveyAssistantSupportBundleLimits,\n type SurveyAssistantSupportBundleLimits,\n} from \"./support-bundle-limits\";\nimport type { SurveyAssistantThreadClient } from \"./thread-client\";\nimport { version as surveyAssistantPackageVersion } from \"../../package.json\";\n\nexport type SurveyAssistantSupportBundleCategory = \"attachments\" | \"conversation\" | \"survey\";\n\nexport type SurveyAssistantSupportBundleSelection = Record<\n SurveyAssistantSupportBundleCategory,\n boolean\n>;\n\nexport const SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION = {\n attachments: true,\n conversation: true,\n survey: true,\n} as const satisfies SurveyAssistantSupportBundleSelection;\n\nexport interface SurveyAssistantSupportBundleConfig {\n /** Set to false to disable support-bundle preparation and generation. Defaults to true. */\n enabled?: boolean;\n hostBuildVersion?: string;\n limits?: Partial<SurveyAssistantSupportBundleLimits>;\n packageVersion?: string;\n subjectPrefix?: string;\n supportEmail?: string;\n}\n\nexport const isSurveyAssistantSupportBundleEnabled = (\n config?: SurveyAssistantSupportBundleConfig,\n): boolean => config?.enabled !== false;\n\nconst assertSurveyAssistantSupportBundleEnabled = (config?: SurveyAssistantSupportBundleConfig) => {\n if (!isSurveyAssistantSupportBundleEnabled(config)) {\n throw new Error(\"Support bundle export is disabled by host configuration.\");\n }\n};\n\ninterface PreparedEntry {\n bytes: Uint8Array;\n category: SurveyAssistantSupportBundleCategory;\n path: string;\n source: \"authorized-transcript\" | \"browser-session\";\n}\n\ninterface UnavailableComponent {\n bytes?: number;\n category: SurveyAssistantSupportBundleCategory;\n filename?: string;\n mediaType?: string;\n reason: \"capture-failed\" | \"no-attempt-retained\" | \"not-retained\" | \"too-large\" | \"unavailable\";\n path?: string;\n}\n\ninterface DeclinedUnavailableComponents {\n category: SurveyAssistantSupportBundleCategory;\n itemCount: number;\n totalBytes: number;\n}\n\nexport interface PreparedSurveyAssistantSupportBundle {\n attempt?: SurveyAssistantDiagnosticAttempt;\n categoryBytes: Record<SurveyAssistantSupportBundleCategory, number>;\n currentSurveyCapturedAt: string;\n entries: PreparedEntry[];\n limits: SurveyAssistantSupportBundleLimits;\n resourceId: string;\n threadId: string;\n unavailable: UnavailableComponent[];\n}\n\nexport interface GeneratedSurveyAssistantSupportBundle {\n blob: Blob;\n filename: string;\n generatedAt: string;\n includedCategories: SurveyAssistantSupportBundleCategory[];\n size: number;\n}\n\nconst encoder = new TextEncoder();\n\nconst encodeJson = (value: unknown): Uint8Array => encoder.encode(JSON.stringify(value));\n\nconst abortIfNeeded = (signal?: AbortSignal) => {\n if (signal?.aborted)\n throw new DOMException(\"Support bundle preparation was cancelled.\", \"AbortError\");\n};\n\ninterface SanitizationState {\n nodes: number;\n redactions: number;\n truncated: boolean;\n}\n\nconst sanitizeValue = (\n value: unknown,\n state: SanitizationState,\n parent?: Record<string, unknown>,\n key?: string,\n depth = 0,\n): unknown => {\n state.nodes += 1;\n if (state.nodes > 100_000) {\n state.redactions += 1;\n state.truncated = true;\n return { redacted: \"node-limit\" };\n }\n if (depth > 32) {\n state.redactions += 1;\n state.truncated = true;\n return { redacted: \"depth-limit\" };\n }\n\n const binaryMarker = getSurveyAssistantEmbeddedBinaryMarker(value, parent, key);\n if (binaryMarker) {\n state.redactions += 1;\n return binaryMarker;\n }\n if (key && isSurveyAssistantSensitiveMetadataKey(key)) {\n state.redactions += 1;\n return { redacted: \"sensitive-field\" };\n }\n if (typeof value === \"string\") {\n const redacted = redactSurveyAssistantDiagnosticSecrets(value);\n if (redacted !== value) state.redactions += 1;\n return redacted.length > 200_000 ? `${redacted.slice(0, 199_999)}…` : redacted;\n }\n if (value === null || typeof value === \"number\" || typeof value === \"boolean\") return value;\n if (value === undefined) return undefined;\n if (Array.isArray(value)) {\n if (value.length > 20_000) state.truncated = true;\n return value\n .slice(0, 20_000)\n .map((item) => sanitizeValue(item, state, undefined, undefined, depth + 1));\n }\n if (typeof value !== \"object\") return String(value);\n\n const record = value as Record<string, unknown>;\n const sanitized: Record<string, unknown> = {};\n const entries = Object.entries(record);\n if (entries.length > 20_000) state.truncated = true;\n for (const [childKey, childValue] of entries.slice(0, 20_000)) {\n sanitized[childKey] = sanitizeValue(childValue, state, record, childKey, depth + 1);\n }\n return sanitized;\n};\n\nexport const sanitizeSurveyAssistantSupportValue = (value: unknown) => {\n const state: SanitizationState = { nodes: 0, redactions: 0, truncated: false };\n const sanitized = sanitizeValue(value, state);\n return { redactions: state.redactions, truncated: state.truncated, value: sanitized };\n};\n\nconst createJsonEntry = (\n path: string,\n category: SurveyAssistantSupportBundleCategory,\n source: PreparedEntry[\"source\"],\n value: unknown,\n): PreparedEntry => {\n const state: SanitizationState = { nodes: 0, redactions: 0, truncated: false };\n const sanitized = sanitizeValue(value, state);\n return {\n bytes: encodeJson({\n redactions: state.redactions,\n truncated: state.truncated,\n value: sanitized,\n }),\n category,\n path,\n source,\n };\n};\n\nconst snapshotVersion = (snapshot: SurveyAssistantSnapshot | null | undefined) => snapshot?.version;\n\nconst extensionForMediaType = (mediaType: string): string => {\n switch (mediaType.toLocaleLowerCase()) {\n case \"application/pdf\":\n return \".pdf\";\n case \"image/jpeg\":\n return \".jpg\";\n case \"image/png\":\n return \".png\";\n default:\n return \".bin\";\n }\n};\n\nconst sanitizeFilename = (filename: string, mediaType: string): string => {\n const extension = extensionForMediaType(mediaType);\n const withoutExtension = filename.replace(/\\.[a-z0-9]{1,10}$/i, \"\");\n const stem = withoutExtension\n .normalize(\"NFKD\")\n .replace(/[^A-Za-z0-9._-]+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\")\n .slice(0, 100);\n return `${stem || \"attachment\"}${extension}`;\n};\n\nconst disambiguateFilenames = (files: Array<{ filename: string; mediaType: string }>): string[] => {\n const used = new Set<string>();\n return files.map((file) => {\n const sanitized = sanitizeFilename(file.filename, file.mediaType);\n const dot = sanitized.lastIndexOf(\".\");\n const stem = dot > 0 ? sanitized.slice(0, dot) : sanitized;\n const extension = dot > 0 ? sanitized.slice(dot) : \"\";\n let candidate = sanitized;\n let index = 2;\n while (used.has(candidate.toLocaleLowerCase())) {\n candidate = `${stem}-${index}${extension}`;\n index += 1;\n }\n used.add(candidate.toLocaleLowerCase());\n return candidate;\n });\n};\n\nconst dataUrlToBytes = (dataUrl: string): Uint8Array => {\n const comma = dataUrl.indexOf(\",\");\n if (comma < 0) return encoder.encode(dataUrl);\n const metadata = dataUrl.slice(0, comma);\n const payload = dataUrl.slice(comma + 1);\n if (!/;base64$/i.test(metadata)) return encoder.encode(decodeURIComponent(payload));\n const decoded = globalThis.atob(payload);\n const bytes = new Uint8Array(decoded.length);\n for (let index = 0; index < decoded.length; index += 1) bytes[index] = decoded.charCodeAt(index);\n return bytes;\n};\n\nconst pushPreparedEntry = (\n entries: PreparedEntry[],\n unavailable: UnavailableComponent[],\n entry: PreparedEntry,\n limits: SurveyAssistantSupportBundleLimits,\n) => {\n if (entry.bytes.byteLength > limits.zipEntryBytes) {\n unavailable.push({\n bytes: entry.bytes.byteLength,\n category: entry.category,\n path: entry.path,\n reason: \"too-large\",\n });\n return;\n }\n entries.push(entry);\n};\n\nexport const prepareSurveyAssistantSupportBundle = async ({\n config,\n controller,\n diagnosticStore,\n resourceId,\n signal,\n threadClient,\n threadId,\n}: {\n config?: SurveyAssistantSupportBundleConfig;\n controller?: SurveyAssistantController | null;\n diagnosticStore: SurveyAssistantDiagnosticStore;\n resourceId: string;\n signal?: AbortSignal;\n threadClient: SurveyAssistantThreadClient;\n threadId: string;\n}): Promise<PreparedSurveyAssistantSupportBundle> => {\n assertSurveyAssistantSupportBundleEnabled(config);\n const limits = resolveSurveyAssistantSupportBundleLimits(config?.limits);\n const entries: PreparedEntry[] = [];\n const unavailable: UnavailableComponent[] = [];\n const attempt = diagnosticStore.getExportAttempt(threadId);\n const currentSurveyCapturedAt = new Date().toISOString();\n let currentSurvey: SurveyAssistantSnapshot | null = null;\n try {\n currentSurvey = controller?.getSnapshot() ?? null;\n if (currentSurvey) {\n currentSurvey =\n typeof structuredClone === \"function\"\n ? structuredClone(currentSurvey)\n : (JSON.parse(JSON.stringify(currentSurvey)) as SurveyAssistantSnapshot);\n }\n } catch {\n unavailable.push({\n category: \"survey\",\n reason: \"capture-failed\",\n path: \"survey/current-survey.json\",\n });\n }\n\n abortIfNeeded(signal);\n if (!attempt) {\n unavailable.push(\n {\n category: \"conversation\",\n path: \"conversation/attempt-messages.json\",\n reason: \"no-attempt-retained\",\n },\n {\n category: \"conversation\",\n path: \"diagnostics/client-apply-outcome.json\",\n reason: \"no-attempt-retained\",\n },\n {\n category: \"conversation\",\n path: \"diagnostics/client-apply-receipts.json\",\n reason: \"no-attempt-retained\",\n },\n { category: \"attachments\", reason: \"no-attempt-retained\" },\n );\n }\n if (attempt?.messages) {\n pushPreparedEntry(\n entries,\n unavailable,\n createJsonEntry(\n \"conversation/attempt-messages.json\",\n \"conversation\",\n \"browser-session\",\n attempt.messages,\n ),\n limits,\n );\n } else if (attempt?.captureFailure) {\n unavailable.push({\n category: \"conversation\",\n reason: \"capture-failed\",\n path: \"conversation/attempt-messages.json\",\n });\n } else if (attempt) {\n unavailable.push({\n category: \"conversation\",\n reason: \"not-retained\",\n path: \"conversation/attempt-messages.json\",\n });\n }\n if (attempt?.applyOutcome) {\n pushPreparedEntry(\n entries,\n unavailable,\n createJsonEntry(\n \"diagnostics/client-apply-outcome.json\",\n \"conversation\",\n \"browser-session\",\n attempt.applyOutcome,\n ),\n limits,\n );\n }\n if (attempt?.applyReceipts) {\n pushPreparedEntry(\n entries,\n unavailable,\n createJsonEntry(\n \"diagnostics/client-apply-receipts.json\",\n \"conversation\",\n \"browser-session\",\n attempt.applyReceipts,\n ),\n limits,\n );\n }\n\n const transcriptMessages: unknown[] = [];\n let transcriptBytes = 0;\n let transcriptCursor: string | undefined;\n let transcriptRedactions = 0;\n let transcriptTruncated = false;\n try {\n for (let page = 0; page < limits.transcriptPages; page += 1) {\n abortIfNeeded(signal);\n const transcript = await threadClient.read(threadId, transcriptCursor, { signal });\n abortIfNeeded(signal);\n const pageState: SanitizationState = { nodes: 0, redactions: 0, truncated: false };\n const sanitizedPage = sanitizeValue(transcript.messages, pageState);\n transcriptRedactions += pageState.redactions;\n transcriptTruncated ||= pageState.truncated;\n const pageMessages = Array.isArray(sanitizedPage) ? sanitizedPage : [];\n const pageBytes = encodeJson(pageMessages).byteLength;\n if (\n transcriptMessages.length + pageMessages.length > limits.transcriptMessages ||\n transcriptBytes + pageBytes > limits.transcriptBytes\n ) {\n transcriptTruncated = true;\n break;\n }\n transcriptMessages.unshift(...pageMessages);\n transcriptBytes += pageBytes;\n transcriptCursor = transcript.nextCursor;\n if (!transcriptCursor) break;\n if (page === limits.transcriptPages - 1) transcriptTruncated = true;\n }\n pushPreparedEntry(\n entries,\n unavailable,\n {\n bytes: encodeJson({\n messages: transcriptMessages,\n redactions: transcriptRedactions,\n truncated: transcriptTruncated,\n }),\n category: \"conversation\",\n path: \"conversation/transcript.json\",\n source: \"authorized-transcript\",\n },\n limits,\n );\n } catch (error) {\n if (signal?.aborted) throw error;\n unavailable.push({\n category: \"conversation\",\n reason: \"unavailable\",\n path: \"conversation/transcript.json\",\n });\n }\n\n if (attempt?.submittedSurvey !== undefined) {\n pushPreparedEntry(\n entries,\n unavailable,\n createJsonEntry(\"survey/submitted-survey.json\", \"survey\", \"browser-session\", {\n snapshot: attempt.submittedSurvey,\n version: snapshotVersion(attempt.submittedSurvey),\n }),\n limits,\n );\n } else {\n unavailable.push({\n category: \"survey\",\n reason: attempt ? \"not-retained\" : \"no-attempt-retained\",\n path: \"survey/submitted-survey.json\",\n });\n }\n if (currentSurvey) {\n pushPreparedEntry(\n entries,\n unavailable,\n createJsonEntry(\"survey/current-survey.json\", \"survey\", \"browser-session\", {\n capturedAt: currentSurveyCapturedAt,\n snapshot: currentSurvey,\n version: snapshotVersion(currentSurvey),\n }),\n limits,\n );\n }\n\n if (attempt) {\n const availableAttachments = attempt.attachments\n .map((reference) => ({\n reference,\n stored: diagnosticStore.getAttachment(reference.storeKey),\n }))\n .filter((item) => Boolean(item.stored?.dataUrl));\n const filenames = disambiguateFilenames(availableAttachments.map(({ reference }) => reference));\n for (const [index, { reference, stored }] of availableAttachments.entries()) {\n abortIfNeeded(signal);\n const bytes = dataUrlToBytes(stored!.dataUrl!);\n pushPreparedEntry(\n entries,\n unavailable,\n {\n bytes,\n category: \"attachments\",\n path: `attachments/${filenames[index]}`,\n source: \"browser-session\",\n },\n limits,\n );\n }\n for (const reference of attempt.attachments) {\n if (!diagnosticStore.getAttachment(reference.storeKey)?.dataUrl) {\n unavailable.push({\n bytes: reference.bytes,\n category: \"attachments\",\n filename: reference.filename,\n mediaType: reference.mediaType,\n reason: \"not-retained\",\n });\n }\n }\n }\n\n const categoryBytes = {\n attachments: 0,\n conversation: 0,\n survey: 0,\n } satisfies Record<SurveyAssistantSupportBundleCategory, number>;\n for (const entry of entries) categoryBytes[entry.category] += entry.bytes.byteLength;\n\n return {\n attempt,\n categoryBytes,\n currentSurveyCapturedAt,\n entries,\n limits,\n resourceId,\n threadId,\n unavailable,\n };\n};\n\nconst validateZipPath = (path: string) => {\n if (!path || path.startsWith(\"/\") || path.includes(\"\\\\\") || path.split(\"/\").includes(\"..\")) {\n throw new Error(`Unsafe support-bundle ZIP path: ${path}`);\n }\n};\n\nconst toBlobPart = (bytes: Uint8Array): ArrayBuffer => {\n if (\n bytes.buffer instanceof ArrayBuffer &&\n bytes.byteOffset === 0 &&\n bytes.byteLength === bytes.buffer.byteLength\n ) {\n return bytes.buffer;\n }\n return bytes.slice().buffer as ArrayBuffer;\n};\n\nconst createZipBlob = (entries: Array<{ bytes: Uint8Array; path: string }>): Promise<Blob> => {\n const paths = new Set<string>();\n for (const entry of entries) {\n validateZipPath(entry.path);\n if (paths.has(entry.path)) throw new Error(`Duplicate support-bundle ZIP path: ${entry.path}`);\n paths.add(entry.path);\n }\n return new Promise((resolve, reject) => {\n const chunks: BlobPart[] = [];\n const zip = new Zip((error, data, final) => {\n if (error) {\n reject(error);\n return;\n }\n chunks.push(toBlobPart(data));\n if (final) resolve(new Blob(chunks, { type: \"application/zip\" }));\n });\n try {\n for (const entry of entries) {\n const file = new ZipPassThrough(entry.path);\n zip.add(file);\n file.push(entry.bytes, true);\n }\n zip.end();\n } catch (error) {\n zip.terminate();\n reject(error);\n }\n });\n};\n\nconst categoryDescriptors = (\n prepared: PreparedSurveyAssistantSupportBundle,\n selection: SurveyAssistantSupportBundleSelection,\n) =>\n (Object.keys(selection) as SurveyAssistantSupportBundleCategory[]).map((category) => {\n const entries = prepared.entries.filter((entry) => entry.category === category);\n return selection[category]\n ? {\n category,\n included: true,\n itemCount: entries.length,\n totalBytes: entries.reduce((total, entry) => total + entry.bytes.byteLength, 0),\n entries: entries.map((entry) => ({\n bytes: entry.bytes.byteLength,\n path: entry.path,\n source: entry.source,\n })),\n }\n : {\n category,\n included: false,\n itemCount: entries.length,\n totalBytes: entries.reduce((total, entry) => total + entry.bytes.byteLength, 0),\n };\n });\n\nconst createAttemptMetadata = (\n prepared: PreparedSurveyAssistantSupportBundle,\n selection: SurveyAssistantSupportBundleSelection,\n) => {\n const attempt = prepared.attempt;\n return {\n attemptAvailable: Boolean(attempt),\n ...(attempt\n ? {\n captureFailure: attempt.captureFailure,\n error: attempt.error,\n events: attempt.events,\n modelId: attempt.modelId,\n requestId: attempt.requestId,\n resourceId: attempt.resourceId,\n submittedAt: attempt.submittedAt,\n threadId: attempt.threadId,\n turnFinal: attempt.turnFinal,\n }\n : { threadId: prepared.threadId }),\n categories: categoryDescriptors(prepared, selection),\n };\n};\n\nconst encodeSanitizedJson = (value: unknown): Uint8Array =>\n encodeJson(sanitizeSurveyAssistantSupportValue(value).value);\n\nconst createRequiredEntries = (\n prepared: PreparedSurveyAssistantSupportBundle,\n selection: SurveyAssistantSupportBundleSelection,\n config: SurveyAssistantSupportBundleConfig | undefined,\n generatedAt: string,\n) => {\n const descriptors = categoryDescriptors(prepared, selection);\n const unavailable = (Object.keys(selection) as SurveyAssistantSupportBundleCategory[]).flatMap<\n UnavailableComponent | DeclinedUnavailableComponents\n >((category) => {\n const categoryUnavailable = prepared.unavailable.filter((item) => item.category === category);\n if (categoryUnavailable.length === 0) return [];\n if (selection[category]) return categoryUnavailable;\n return [\n {\n category,\n itemCount: categoryUnavailable.length,\n totalBytes: categoryUnavailable.reduce((total, item) => total + (item.bytes ?? 0), 0),\n },\n ];\n });\n const manifest = {\n schemaVersion: 1,\n generatedAt,\n packageVersion: config?.packageVersion ?? surveyAssistantPackageVersion,\n hostBuildVersion: config?.hostBuildVersion,\n resourceId: prepared.resourceId,\n threadId: prepared.threadId,\n requestId: prepared.attempt?.requestId,\n turnId: prepared.attempt?.turnFinal?.turnId,\n modelId: prepared.attempt?.modelId,\n categories: descriptors,\n unavailable,\n currentSurveyCapturedAt: prepared.currentSurveyCapturedAt,\n };\n const readme = [\n \"CASE Survey Assistant support bundle\",\n \"\",\n `Generated: ${generatedAt}`,\n \"This archive contains diagnostic data selected by the user, including visible model reasoning when conversation data is included.\",\n \"Nothing was uploaded or emailed automatically.\",\n \"See manifest.json for the authoritative inventory and availability information.\",\n \"Treat the archive as potentially sensitive.\",\n ].join(\"\\n\");\n return [\n { bytes: encodeSanitizedJson(manifest), path: \"manifest.json\" },\n { bytes: encoder.encode(readme), path: \"README.txt\" },\n {\n bytes: encodeSanitizedJson(createAttemptMetadata(prepared, selection)),\n path: \"diagnostics/client-attempt.json\",\n },\n ];\n};\n\nconst estimateArchiveBytes = (entries: Array<{ bytes: Uint8Array; path: string }>) =>\n entries.reduce(\n (total, entry) =>\n total + entry.bytes.byteLength + encoder.encode(entry.path).byteLength * 2 + 110,\n 22,\n );\n\nexport const estimateSurveyAssistantSupportBundleBytes = (\n prepared: PreparedSurveyAssistantSupportBundle,\n selection: SurveyAssistantSupportBundleSelection,\n config?: SurveyAssistantSupportBundleConfig,\n): number => {\n if (!isSurveyAssistantSupportBundleEnabled(config)) return 0;\n const entries = [\n ...createRequiredEntries(prepared, selection, config, new Date().toISOString()),\n ...prepared.entries\n .filter((entry) => selection[entry.category])\n .map(({ bytes, path }) => ({ bytes, path })),\n ];\n return estimateArchiveBytes(entries);\n};\n\nexport const generateSurveyAssistantSupportBundle = async (\n prepared: PreparedSurveyAssistantSupportBundle,\n selection: SurveyAssistantSupportBundleSelection,\n config?: SurveyAssistantSupportBundleConfig,\n): Promise<GeneratedSurveyAssistantSupportBundle> => {\n assertSurveyAssistantSupportBundleEnabled(config);\n const generatedAt = new Date().toISOString();\n const selectedEntries = prepared.entries.filter((entry) => selection[entry.category]);\n const allEntries = [\n ...createRequiredEntries(prepared, selection, config, generatedAt),\n ...selectedEntries.map(({ bytes, path }) => ({ bytes, path })),\n ];\n const estimatedBytes = estimateArchiveBytes(allEntries);\n if (estimatedBytes > prepared.limits.bundleBytes) {\n throw new Error(\"The selected support-bundle data exceeds the configured bundle limit.\");\n }\n const blob = await createZipBlob(allEntries);\n if (blob.size > prepared.limits.bundleBytes) {\n throw new Error(\"The selected support-bundle data exceeds the configured bundle limit.\");\n }\n const safeToken =\n (prepared.attempt?.requestId ?? prepared.attempt?.turnFinal?.turnId ?? \"unidentified\")\n .replace(/[^A-Za-z0-9_-]/g, \"-\")\n .slice(0, 64) || \"unidentified\";\n const timestamp = generatedAt.replace(/[-:]/g, \"\").replace(/\\.\\d{3}Z$/, \"Z\");\n return {\n blob,\n filename: `case-survey-assistant-support-${safeToken}-${timestamp}.zip`,\n generatedAt,\n includedCategories: (Object.keys(selection) as SurveyAssistantSupportBundleCategory[]).filter(\n (category) => selection[category],\n ),\n size: blob.size,\n };\n};\n\nexport const downloadSurveyAssistantSupportBundle = (\n bundle: GeneratedSurveyAssistantSupportBundle,\n) => {\n const url = URL.createObjectURL(bundle.blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = bundle.filename;\n anchor.style.display = \"none\";\n document.body.append(anchor);\n anchor.click();\n anchor.remove();\n window.setTimeout(() => URL.revokeObjectURL(url), 0);\n};\n\nexport const createSurveyAssistantSupportDetails = ({\n bundle,\n prepared,\n}: {\n bundle: GeneratedSurveyAssistantSupportBundle;\n prepared: PreparedSurveyAssistantSupportBundle;\n}): string =>\n [\n `File: ${bundle.filename}`,\n `Request: ${prepared.attempt?.requestId ?? \"unavailable\"}`,\n `Model: ${prepared.attempt?.modelId ?? \"unavailable\"}`,\n `Error category: ${prepared.attempt?.error?.code ?? \"unavailable\"}`,\n `Generated: ${bundle.generatedAt}`,\n ].join(\"\\n\");\n\nexport const createSurveyAssistantSupportMailto = ({\n bundle,\n config,\n prepared,\n}: {\n bundle: GeneratedSurveyAssistantSupportBundle;\n config: SurveyAssistantSupportBundleConfig;\n prepared: PreparedSurveyAssistantSupportBundle;\n}): string | undefined => {\n if (!isSurveyAssistantSupportBundleEnabled(config)) return undefined;\n if (!config.supportEmail?.trim()) return undefined;\n const subject =\n `${config.subjectPrefix?.trim() || \"CASE Survey Assistant support\"} ${prepared.attempt?.requestId ?? \"\"}`.trim();\n const body = [\n \"IMPORTANT: ATTACH THE DOWNLOADED ZIP FILE TO THIS EMAIL BEFORE SENDING.\",\n \"\",\n \"A Survey Assistant support bundle has been downloaded for this issue.\",\n \"\",\n createSurveyAssistantSupportDetails({ bundle, prepared }),\n ].join(\"\\n\");\n return `mailto:${encodeURIComponent(config.supportEmail.trim())}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;\n};\n","import { useCallback, useEffect, useState } from \"react\";\nimport {\n surveyAssistantModelCatalogSchema,\n type SurveyAssistantModelCatalog,\n type SurveyAssistantModelOption,\n} from \"../protocol\";\nimport { readSurveyAssistantJson } from \"./client-error\";\n\nconst DEFAULT_MODEL_STORAGE_KEY = \"survey-assistant-selected-model\";\n\nexport interface SurveyAssistantModelCatalogClient {\n get(): Promise<SurveyAssistantModelCatalog>;\n}\n\nexport const createSurveyAssistantModelCatalogClient = (\n api = \"/api/survey-assistant/models\",\n): SurveyAssistantModelCatalogClient => ({\n async get() {\n const body = await readSurveyAssistantJson(\n await fetch(api, { cache: \"no-store\" }),\n \"The assistant model catalog could not be loaded.\",\n );\n return surveyAssistantModelCatalogSchema.parse(body);\n },\n});\n\nexport interface UseSurveyAssistantModelCatalogOptions {\n api?: string;\n client?: SurveyAssistantModelCatalogClient;\n onModelChange?(modelId: string): void;\n storageKey?: string | false;\n}\n\nexport interface SurveyAssistantModelCatalogState {\n error: Error | null;\n loading: boolean;\n modelId?: string;\n models: SurveyAssistantModelOption[];\n reload(): void;\n selectModel(modelId: string): void;\n}\n\nexport const useSurveyAssistantModelCatalog = ({\n api,\n client: providedClient,\n onModelChange,\n storageKey = DEFAULT_MODEL_STORAGE_KEY,\n}: UseSurveyAssistantModelCatalogOptions = {}): SurveyAssistantModelCatalogState => {\n const [models, setModels] = useState<SurveyAssistantModelOption[]>([]);\n const [modelId, setModelId] = useState<string>();\n const [error, setError] = useState<Error | null>(null);\n const [loading, setLoading] = useState(true);\n const [reloadToken, setReloadToken] = useState(0);\n\n useEffect(() => {\n let cancelled = false;\n const client = providedClient ?? createSurveyAssistantModelCatalogClient(api);\n setLoading(true);\n setError(null);\n void client\n .get()\n .then((catalog) => {\n if (cancelled) return;\n const rememberedId =\n storageKey && typeof window !== \"undefined\"\n ? (window.localStorage.getItem(storageKey) ?? undefined)\n : undefined;\n const selectedId =\n rememberedId && catalog.models.some((model) => model.id === rememberedId)\n ? rememberedId\n : catalog.defaultModelId;\n setModels(catalog.models);\n setModelId(selectedId);\n onModelChange?.(selectedId);\n })\n .catch((reason: unknown) => {\n if (!cancelled) setError(reason instanceof Error ? reason : new Error(String(reason)));\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [api, onModelChange, providedClient, reloadToken, storageKey]);\n\n const selectModel = useCallback(\n (nextModelId: string) => {\n if (!models.some((model) => model.id === nextModelId)) return;\n setModelId(nextModelId);\n if (storageKey && typeof window !== \"undefined\") {\n window.localStorage.setItem(storageKey, nextModelId);\n }\n onModelChange?.(nextModelId);\n },\n [models, onModelChange, storageKey],\n );\n\n const reload = useCallback(() => setReloadToken((current) => current + 1), []);\n\n return { error, loading, modelId, models, reload, selectModel };\n};\n","\"use client\";\n\nimport {\n surveyDocumentVersionSchema,\n type SurveyAssistantSnapshot,\n type SurveyDocumentVersion,\n} from \"../protocol\";\n\nconst STORAGE_PREFIX = \"case-survey-assistant:settled-document:\";\nconst memoryBaselines = new Map<string, SurveyDocumentVersion>();\n\nconst getStorageKey = (resourceId: string, threadId: string) =>\n `${STORAGE_PREFIX}${encodeURIComponent(resourceId)}:${encodeURIComponent(threadId)}`;\n\nconst getSessionStorage = (): Storage | undefined => {\n if (typeof document === \"undefined\") return undefined;\n\n try {\n return window.sessionStorage;\n } catch {\n return undefined;\n }\n};\n\nexport const readSettledDocumentVersion = ({\n resourceId,\n threadId,\n}: {\n resourceId: string;\n threadId: string;\n}): SurveyDocumentVersion | undefined => {\n const storageKey = getStorageKey(resourceId, threadId);\n const storedInMemory = memoryBaselines.get(storageKey);\n if (storedInMemory) return { ...storedInMemory };\n\n const serialized = getSessionStorage()?.getItem(storageKey);\n if (!serialized) return undefined;\n\n try {\n const parsed = surveyDocumentVersionSchema.safeParse(JSON.parse(serialized));\n if (!parsed.success) return undefined;\n memoryBaselines.set(storageKey, parsed.data);\n return { ...parsed.data };\n } catch {\n return undefined;\n }\n};\n\nexport const writeSettledDocumentVersion = ({\n resourceId,\n snapshot,\n threadId,\n}: {\n resourceId: string;\n snapshot: SurveyAssistantSnapshot;\n threadId: string;\n}): void => {\n const storageKey = getStorageKey(resourceId, threadId);\n const version = surveyDocumentVersionSchema.parse(snapshot.version);\n memoryBaselines.set(storageKey, version);\n\n try {\n getSessionStorage()?.setItem(storageKey, JSON.stringify(version));\n } catch {\n // In-memory continuity still works when browser storage is disabled or full.\n }\n};\n","\"use client\";\n\nimport { useChat } from \"@ai-sdk/react\";\nimport {\n SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE,\n SURVEY_ASSISTANT_PROTOCOL_VERSION,\n parseSurveyAssistantError,\n surveyAssistantApplyOutcomeSchema,\n type ApplyReceipt,\n type SurveyAssistantApplyOutcome,\n type SurveyAssistantAttachmentReference,\n type SurveyApplyResult,\n type SurveyAssistantApplyPolicy,\n type SurveyAssistantTurnFinal,\n type SurveyChangeSet,\n} from \"../protocol\";\nimport type { ChatStatus, FileUIPart, UIMessage } from \"ai\";\nimport {\n useCallback,\n useEffect,\n useEffectEvent,\n useMemo,\n useReducer,\n useRef,\n useState,\n} from \"react\";\nimport {\n collectSurveyChangeSets,\n createApplyReceipts,\n resolveLatestSurveyTurnAuthorization,\n resolveSurveyTurnOutcome,\n} from \"./turn-authorization\";\nimport { isSurveyAssistantTurnActive, reduceSurveyAssistantSessionState } from \"./session-state\";\nimport type { SurveyAssistantSessionState } from \"./session-state\";\nimport type { SurveyTurnOutcome } from \"./turn-authorization\";\nimport { createSurveyAssistantTransport } from \"./transport\";\nimport type { SurveyAssistantController } from \"./controller\";\nimport { readSettledDocumentVersion, writeSettledDocumentVersion } from \"./document-baseline\";\nimport {\n applySurveyAssistantLaunchUIContext,\n type SurveyAssistantLaunchUIContext,\n} from \"./thread-launcher\";\nimport {\n createSurveyAssistantDiagnosticId,\n type SurveyAssistantDiagnosticStore,\n} from \"./diagnostic-store\";\n\nconst createLocalId = (prefix: string) => {\n return createSurveyAssistantDiagnosticId(prefix);\n};\n\nconst compactOutcomeText = (value: string, maximum: number, fallback: string) => {\n const normalized = value.trim() || fallback;\n return normalized.length > maximum ? `${normalized.slice(0, maximum - 1)}…` : normalized;\n};\n\nconst createApplyOutcome = ({\n message,\n preparedChanges,\n results,\n status,\n turnId,\n}: {\n message: string;\n preparedChanges?: SurveyChangeSet[];\n results?: SurveyApplyResult[];\n status: SurveyAssistantApplyOutcome[\"status\"];\n turnId: string;\n}): SurveyAssistantApplyOutcome =>\n surveyAssistantApplyOutcomeSchema.parse({\n protocolVersion: SURVEY_ASSISTANT_PROTOCOL_VERSION,\n turnId,\n status,\n message: compactOutcomeText(message, 2_000, \"No lifecycle detail was reported.\"),\n ...(results && results.length > 0\n ? {\n results: results.slice(0, 100).map((result) => ({\n status: result.status,\n changeId: compactOutcomeText(result.changeId, 240, \"unknown-change\"),\n summary: compactOutcomeText(result.summary, 500, \"Survey change\"),\n message: compactOutcomeText(result.message, 2_000, \"No apply detail was reported.\"),\n appliedOperations: result.appliedOperations,\n })),\n }\n : {}),\n ...(preparedChanges && preparedChanges.length > 0\n ? {\n preparedChanges: preparedChanges.slice(-24).map((change) => ({\n changeId: compactOutcomeText(change.id, 240, \"unknown-change\"),\n status: change.status,\n summary: compactOutcomeText(change.summary, 500, \"Survey change\"),\n operationCount: change.operations.length,\n })),\n }\n : {}),\n createdAt: new Date().toISOString(),\n });\n\ntype AssistantTextPart = Extract<UIMessage[\"parts\"][number], { type: \"text\" }>;\n\nconst getAssistantTextParts = (message: UIMessage) =>\n message.parts.filter(\n (part): part is AssistantTextPart => part.type === \"text\" && part.text.trim().length > 0,\n );\n\nconst findLastAssistantTextMessageIndex = (\n messages: UIMessage[],\n endExclusive = messages.length,\n) => {\n for (let index = Math.min(messages.length, endExclusive) - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message?.role === \"assistant\" && getAssistantTextParts(message).length > 0) return index;\n }\n return -1;\n};\n\nconst findLastUserMessageIndex = (messages: UIMessage[]) => {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.role === \"user\") return index;\n }\n return -1;\n};\n\nconst pruneFailedMessagesForDisplay = (messages: UIMessage[]): UIMessage[] => {\n const lastUserIndex = findLastUserMessageIndex(messages);\n const lastCompletedAssistantIndex = findLastAssistantTextMessageIndex(messages);\n\n if (lastUserIndex > lastCompletedAssistantIndex) return messages.slice(0, lastUserIndex + 1);\n return lastCompletedAssistantIndex >= 0 ? messages.slice(0, lastCompletedAssistantIndex + 1) : [];\n};\n\nconst hasCompletedAssistantResponseAfterLastUser = (messages: UIMessage[]) => {\n const lastUserIndex = findLastUserMessageIndex(messages);\n return lastUserIndex >= 0 && findLastAssistantTextMessageIndex(messages) > lastUserIndex;\n};\n\nconst collectChangeSetsAfterLastUser = (messages: UIMessage[]) => {\n const lastUserIndex = findLastUserMessageIndex(messages);\n return lastUserIndex < 0 ? [] : collectSurveyChangeSets(messages.slice(lastUserIndex + 1));\n};\n\nconst getInitialSessionState = (messages: UIMessage[]): SurveyAssistantSessionState => {\n if (messages.length === 0) return \"idle\";\n const authorization = resolveLatestSurveyTurnAuthorization(messages);\n if (authorization.status === \"failed\") return \"failed\";\n if (authorization.status === \"aborted\") return \"aborted\";\n return \"completed\";\n};\n\nexport interface SurveyAssistantSessionOptions {\n api?: string;\n /** Explicit host decision: apply immediately, present for review, or deny mutations. */\n applyPolicy: SurveyAssistantApplyPolicy;\n controller?: SurveyAssistantController | null;\n /** Optional browser-session diagnostics sink used by the support-bundle UI. */\n diagnosticStore?: SurveyAssistantDiagnosticStore;\n initialMessages?: UIMessage[];\n modelId?: string;\n onApplyReceipts?: (receipts: ApplyReceipt[]) => void;\n /**\n * Production persistence/audit barrier. The turn remains active until this\n * resolves; rejection leaves the settled baseline unchanged.\n */\n onSettleApply?: (input: {\n changeSets: SurveyChangeSet[];\n receipts: ApplyReceipt[];\n turnFinal: SurveyAssistantTurnFinal;\n }) => void | Promise<void>;\n /**\n * Required for `review`. Resolve true to apply the authorized change sets,\n * or false to leave the editor unchanged.\n */\n onReviewChangeSets?: (\n changeSets: SurveyChangeSet[],\n turnFinal: SurveyAssistantTurnFinal,\n ) => boolean | Promise<boolean>;\n /** Reports when a turn owns the editor state, including submission, streaming, and apply. */\n onTurnActiveChange?: (active: boolean) => void;\n resourceId?: string;\n /** Host survey id sent as untrusted request context for server-side authorization. */\n surveyId?: string;\n threadId?: string;\n}\n\nexport const resolveSurveyAssistantReviewDecision = async ({\n changeSets,\n onReviewChangeSets,\n turnFinal,\n}: {\n changeSets: SurveyChangeSet[];\n onReviewChangeSets?: SurveyAssistantSessionOptions[\"onReviewChangeSets\"];\n turnFinal: SurveyAssistantTurnFinal;\n}) => {\n if (!onReviewChangeSets) {\n throw new Error(\"No survey assistant review adapter is available.\");\n }\n return onReviewChangeSets(changeSets, turnFinal);\n};\n\nexport interface SurveyAssistantSubmitMessage {\n text: string;\n files: FileUIPart[];\n /** Optional model used for this turn instead of the session's selected model. */\n modelId?: string;\n /** Turn-local UI context layered over the controller snapshot for this submission. */\n uiContext?: SurveyAssistantLaunchUIContext;\n}\n\nexport interface SurveyAssistantSession {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n authorizationError: string | null;\n dismissError(): void;\n error: Error | undefined;\n isStreaming: boolean;\n latestTurnOutcome: SurveyTurnOutcome | null;\n messages: UIMessage[];\n prependMessages(messages: UIMessage[]): void;\n state: SurveyAssistantSessionState;\n status: ChatStatus;\n stop(): void;\n submit(message: SurveyAssistantSubmitMessage): boolean;\n retry(): void;\n}\n\nexport const useSurveyAssistantSession = ({\n api,\n applyPolicy,\n controller,\n diagnosticStore,\n initialMessages = [],\n modelId,\n onApplyReceipts,\n onSettleApply,\n onReviewChangeSets,\n onTurnActiveChange,\n resourceId: controlledResourceId,\n surveyId,\n threadId: controlledThreadId,\n}: SurveyAssistantSessionOptions): SurveyAssistantSession => {\n const [localResourceId] = useState(() => createLocalId(\"survey-assistant-local-user\"));\n const [localThreadId] = useState(() => createLocalId(\"survey-assistant-local-thread\"));\n const resourceId = controlledResourceId ?? localResourceId;\n const threadId = controlledThreadId ?? localThreadId;\n const applyOutcomeScopeKey = `${resourceId}\\u0000${threadId}`;\n const [state, dispatch] = useReducer(\n reduceSurveyAssistantSessionState,\n initialMessages,\n getInitialSessionState,\n );\n const [applyResultsByChangeId, setApplyResultsByChangeId] = useState<\n Record<string, SurveyApplyResult>\n >({});\n const [authorizationError, setAuthorizationError] = useState<string | null>(null);\n const handledTurnIdsRef = useRef<Set<string>>(new Set());\n const localTurnAwaitingApplyRef = useRef(false);\n const localTurnStreamStartedRef = useRef(false);\n const captureSettledVersionRef = useRef(false);\n const lastSubmittedUIContextRef = useRef<SurveyAssistantLaunchUIContext | undefined>(undefined);\n const lastSubmittedModelIdRef = useRef<string | undefined>(undefined);\n const previousApplyOutcomesRef = useRef<Map<string, SurveyAssistantApplyOutcome>>(new Map());\n const capturedChatErrorRef = useRef<Error | undefined>(undefined);\n\n const transport = useMemo(\n () => createSurveyAssistantTransport({ api, resourceId, surveyId, threadId }),\n [api, resourceId, surveyId, threadId],\n );\n const {\n messages,\n setMessages,\n sendMessage,\n status,\n stop: stopChat,\n error,\n clearError,\n regenerate,\n } = useChat({ id: threadId, messages: initialMessages, transport });\n const isStreaming = status === \"submitted\" || status === \"streaming\";\n const messagesRef = useRef(messages);\n messagesRef.current = messages;\n const isTurnActive = isSurveyAssistantTurnActive({ isStreaming, state });\n const notifyTurnActiveChange = useEffectEvent((active: boolean) => {\n onTurnActiveChange?.(active);\n });\n const prependMessages = useCallback(\n (olderMessages: UIMessage[]) => {\n setMessages((current) => {\n const currentIds = new Set(current.map((message) => message.id));\n return [...olderMessages.filter((message) => !currentIds.has(message.id)), ...current];\n });\n },\n [setMessages],\n );\n const turnAuthorization = useMemo(\n () => resolveLatestSurveyTurnAuthorization(messages),\n [messages],\n );\n const latestTurnOutcome = useMemo(\n () => resolveSurveyTurnOutcome({ applyResultsByChangeId, authorization: turnAuthorization }),\n [applyResultsByChangeId, turnAuthorization],\n );\n const hasUsefulLatestAssistantResponse = useMemo(\n () =>\n hasCompletedAssistantResponseAfterLastUser(messages) ||\n collectChangeSetsAfterLastUser(messages).length > 0,\n [messages],\n );\n\n const reportAuthorizationError = useCallback(\n (message: string) => {\n try {\n diagnosticStore?.recordFailure(threadId, messagesRef.current, {\n code: \"request_failed\",\n detail: message,\n retryable: false,\n });\n } catch {\n // Diagnostic capture must never replace the actual assistant error.\n }\n queueMicrotask(() => {\n setAuthorizationError(message);\n dispatch({ type: \"failed\" });\n });\n },\n [diagnosticStore, threadId],\n );\n\n const rememberApplyOutcome = useCallback(\n (outcome: SurveyAssistantApplyOutcome) => {\n previousApplyOutcomesRef.current.set(applyOutcomeScopeKey, outcome);\n try {\n diagnosticStore?.recordApplyOutcome(threadId, outcome);\n } catch {\n // Diagnostics are best-effort and cannot affect editor lifecycle.\n }\n },\n [applyOutcomeScopeKey, diagnosticStore, threadId],\n );\n\n useEffect(() => {\n if (status === \"submitted\") dispatch({ type: \"submit\" });\n if (status === \"streaming\") dispatch({ type: \"stream-started\" });\n }, [status]);\n\n useEffect(() => {\n notifyTurnActiveChange(isTurnActive);\n\n return () => {\n if (isTurnActive) notifyTurnActiveChange(false);\n };\n }, [isTurnActive]);\n\n useEffect(() => {\n if (\n !captureSettledVersionRef.current ||\n isStreaming ||\n (state !== \"completed\" && state !== \"failed\" && state !== \"aborted\" && state !== \"applied\")\n ) {\n return;\n }\n\n captureSettledVersionRef.current = false;\n try {\n const snapshot = controller?.getSnapshot();\n if (snapshot) {\n writeSettledDocumentVersion({ resourceId, snapshot, threadId });\n }\n } catch {\n // A failed host snapshot must not crash failure settlement or advance the baseline.\n }\n }, [controller, isStreaming, resourceId, state, threadId]);\n\n useEffect(() => {\n if (isStreaming) {\n localTurnStreamStartedRef.current = true;\n return;\n }\n if (!localTurnAwaitingApplyRef.current) return;\n\n if (turnAuthorization.status === \"pending\") {\n if (!localTurnStreamStartedRef.current) return;\n const timeoutId = window.setTimeout(() => {\n if (capturedChatErrorRef.current) return;\n localTurnAwaitingApplyRef.current = false;\n localTurnStreamStartedRef.current = false;\n reportAuthorizationError(\"The assistant response ended without a valid turn final.\");\n }, 100);\n return () => window.clearTimeout(timeoutId);\n }\n\n localTurnAwaitingApplyRef.current = false;\n localTurnStreamStartedRef.current = false;\n if (turnAuthorization.status === \"invalid\") {\n reportAuthorizationError(turnAuthorization.reason);\n return;\n }\n\n const { turnFinal } = turnAuthorization;\n try {\n diagnosticStore?.recordTurnFinal(threadId, turnFinal);\n } catch {\n // Diagnostics are best-effort and cannot affect turn settlement.\n }\n if (handledTurnIdsRef.current.has(turnFinal.turnId)) return;\n handledTurnIdsRef.current.add(turnFinal.turnId);\n const preparedChanges = collectChangeSetsAfterLastUser(messages).filter(\n (change) => change.turnId === turnFinal.turnId,\n );\n\n if (turnAuthorization.status === \"failed\") {\n rememberApplyOutcome(\n createApplyOutcome({\n turnId: turnFinal.turnId,\n status: \"not-applied\",\n message:\n \"The previous assistant turn failed before editor authorization. Every request-scoped draft change from that turn was discarded and was not applied.\",\n preparedChanges,\n }),\n );\n dispatch({ type: \"failed\" });\n return;\n }\n if (turnAuthorization.status === \"aborted\") {\n rememberApplyOutcome(\n createApplyOutcome({\n turnId: turnFinal.turnId,\n status: \"not-applied\",\n message:\n \"The previous assistant turn was interrupted before editor authorization. Every request-scoped draft change from that turn was discarded and was not applied.\",\n preparedChanges,\n }),\n );\n dispatch({ type: \"aborted\" });\n return;\n }\n if (turnAuthorization.changeSets.length === 0) {\n if ((turnFinal.blockedChangeSetIds?.length ?? 0) > 0) {\n rememberApplyOutcome(\n createApplyOutcome({\n turnId: turnFinal.turnId,\n status: \"not-applied\",\n message:\n \"The previous assistant turn ended with unresolved rejected changes. No request-scoped draft change from that turn was authorized or applied.\",\n preparedChanges,\n }),\n );\n }\n dispatch({ type: \"completed\" });\n return;\n }\n if (applyPolicy === \"deny\") {\n rememberApplyOutcome(\n createApplyOutcome({\n turnId: turnFinal.turnId,\n status: \"not-applied\",\n message: \"The host apply policy did not authorize editor mutations for this turn.\",\n preparedChanges,\n }),\n );\n dispatch({ type: \"completed\" });\n return;\n }\n dispatch({ type: \"apply-started\" });\n void (async () => {\n if (applyPolicy === \"review\") {\n let approved: boolean;\n try {\n approved = await resolveSurveyAssistantReviewDecision({\n changeSets: turnAuthorization.changeSets,\n onReviewChangeSets,\n turnFinal,\n });\n } catch (error) {\n const message =\n error instanceof Error &&\n error.message === \"No survey assistant review adapter is available.\"\n ? error.message\n : \"The survey assistant review could not be completed.\";\n rememberApplyOutcome(\n createApplyOutcome({\n turnId: turnFinal.turnId,\n status: \"not-applied\",\n message,\n preparedChanges,\n }),\n );\n reportAuthorizationError(message);\n return;\n }\n if (!approved) {\n rememberApplyOutcome(\n createApplyOutcome({\n turnId: turnFinal.turnId,\n status: \"not-applied\",\n message: \"The proposed editor changes were not approved during review.\",\n preparedChanges,\n }),\n );\n dispatch({ type: \"completed\" });\n return;\n }\n }\n\n if (!controller?.applyAssistantChanges) {\n const message = \"No survey editor apply adapter is available.\";\n rememberApplyOutcome(\n createApplyOutcome({\n turnId: turnFinal.turnId,\n status: \"apply-failed\",\n message,\n preparedChanges,\n }),\n );\n reportAuthorizationError(message);\n return;\n }\n const results: SurveyApplyResult[] = [];\n let applyStarted = false;\n const hasCompleteApplyResults = () => {\n const ids = new Set(results.map((result) => result.changeId));\n return (\n results.length === turnAuthorization.changeSets.length &&\n ids.size === results.length &&\n turnAuthorization.changeSets.every((change) => ids.has(change.id))\n );\n };\n const allChangesApplied = () =>\n hasCompleteApplyResults() && results.every((result) => result.status === \"applied\");\n const retainApplyResults = () => {\n const entries = results.map((result) => [result.changeId, result]);\n queueMicrotask(() =>\n setApplyResultsByChangeId((current) => ({ ...current, ...Object.fromEntries(entries) })),\n );\n };\n\n try {\n const beforeSnapshot = controller.getSnapshot();\n if (!beforeSnapshot) throw new Error(\"Editor snapshot unavailable.\");\n applyStarted = true;\n results.push(...controller.applyAssistantChanges(turnAuthorization.changeSets).results);\n retainApplyResults();\n const receipts = createApplyReceipts({\n beforeSnapshot,\n afterSnapshot: controller.getSnapshot(),\n changeSets: turnAuthorization.changeSets,\n results,\n turnFinal,\n });\n try {\n diagnosticStore?.recordApplyReceipts(threadId, receipts);\n } catch {\n // Diagnostics are best-effort and cannot affect host receipt delivery.\n }\n onApplyReceipts?.(receipts);\n if (!hasCompleteApplyResults())\n throw new Error(\"The host returned mismatched apply results.\");\n if (!allChangesApplied()) {\n rememberApplyOutcome(\n createApplyOutcome({\n turnId: turnFinal.turnId,\n status: \"apply-failed\",\n message: \"One or more authorized survey changes could not be applied to the editor.\",\n preparedChanges,\n results,\n }),\n );\n dispatch({ type: \"completed\" });\n return;\n }\n await onSettleApply?.({\n changeSets: turnAuthorization.changeSets,\n receipts,\n turnFinal,\n });\n previousApplyOutcomesRef.current.delete(applyOutcomeScopeKey);\n dispatch({ type: \"applied\" });\n } catch {\n // Preserve returned batch results if receipt delivery or host settlement throws.\n retainApplyResults();\n const applied = allChangesApplied();\n const message = applied\n ? \"The assistant changes were applied locally but could not be settled by the host.\"\n : applyStarted\n ? \"The host could not complete the assistant apply lifecycle. Some changes may already have been applied.\"\n : \"The editor state was unavailable before applying the assistant changes. No changes were applied.\";\n rememberApplyOutcome(\n createApplyOutcome({\n turnId: turnFinal.turnId,\n status: applied ? \"settle-failed\" : \"apply-failed\",\n message,\n preparedChanges,\n results,\n }),\n );\n reportAuthorizationError(message);\n }\n })();\n }, [\n applyPolicy,\n applyOutcomeScopeKey,\n controller,\n diagnosticStore,\n isStreaming,\n onApplyReceipts,\n onReviewChangeSets,\n onSettleApply,\n reportAuthorizationError,\n rememberApplyOutcome,\n messages,\n threadId,\n turnAuthorization,\n ]);\n\n useEffect(() => {\n if (!error) {\n capturedChatErrorRef.current = undefined;\n return;\n }\n if (capturedChatErrorRef.current === error) return;\n capturedChatErrorRef.current = error;\n localTurnAwaitingApplyRef.current = false;\n localTurnStreamStartedRef.current = false;\n dispatch({ type: \"failed\" });\n try {\n diagnosticStore?.recordFailure(\n threadId,\n messagesRef.current,\n parseSurveyAssistantError(error),\n );\n } catch {\n // Diagnostic capture must never replace the actual assistant error.\n }\n if (!hasUsefulLatestAssistantResponse) setMessages(pruneFailedMessagesForDisplay);\n }, [diagnosticStore, error, hasUsefulLatestAssistantResponse, setMessages, threadId]);\n\n const submit = useCallback(\n ({\n files,\n modelId: submittedModelId,\n text: rawText,\n uiContext,\n }: SurveyAssistantSubmitMessage) => {\n const text = rawText.trim();\n if (!text && files.length === 0) return false;\n if (isStreaming || localTurnAwaitingApplyRef.current) return false;\n\n let snapshot;\n try {\n snapshot = applySurveyAssistantLaunchUIContext(\n controller?.getSnapshot() ?? null,\n uiContext,\n );\n } catch {\n reportAuthorizationError(\n \"The editor state was unavailable before sending the assistant request. No request was sent.\",\n );\n return false;\n }\n\n localTurnAwaitingApplyRef.current = true;\n localTurnStreamStartedRef.current = false;\n setAuthorizationError(null);\n if ((authorizationError || error) && !hasUsefulLatestAssistantResponse) {\n setMessages(pruneFailedMessagesForDisplay);\n }\n clearError();\n dispatch({ type: \"submit\" });\n captureSettledVersionRef.current = true;\n lastSubmittedUIContextRef.current = uiContext;\n lastSubmittedModelIdRef.current = submittedModelId ?? modelId;\n\n const requestId = createSurveyAssistantDiagnosticId();\n try {\n diagnosticStore?.beginAttempt({\n files,\n modelId: lastSubmittedModelIdRef.current,\n requestId,\n resourceId,\n submittedSurvey: snapshot,\n threadId,\n });\n } catch {\n // Diagnostic capture is optional; the assistant request must continue.\n }\n void sendMessage(files.length > 0 ? (text ? { text, files } : { files }) : { text }, {\n body: {\n requestId,\n snapshot,\n previousSettledVersion: readSettledDocumentVersion({ resourceId, threadId }),\n previousApplyOutcome: previousApplyOutcomesRef.current.get(applyOutcomeScopeKey),\n ...(lastSubmittedModelIdRef.current ? { modelId: lastSubmittedModelIdRef.current } : {}),\n },\n });\n return true;\n },\n [\n authorizationError,\n applyOutcomeScopeKey,\n clearError,\n controller,\n diagnosticStore,\n error,\n hasUsefulLatestAssistantResponse,\n isStreaming,\n modelId,\n resourceId,\n reportAuthorizationError,\n sendMessage,\n setMessages,\n threadId,\n ],\n );\n\n const stop = useCallback(() => {\n localTurnAwaitingApplyRef.current = false;\n localTurnStreamStartedRef.current = false;\n dispatch({ type: \"aborted\" });\n void stopChat();\n }, [stopChat]);\n\n const retry = useCallback(() => {\n let snapshot;\n try {\n snapshot = applySurveyAssistantLaunchUIContext(\n controller?.getSnapshot() ?? null,\n lastSubmittedUIContextRef.current,\n );\n } catch {\n reportAuthorizationError(\n \"The editor state was unavailable before retrying the assistant request. No request was sent.\",\n );\n return;\n }\n localTurnAwaitingApplyRef.current = true;\n localTurnStreamStartedRef.current = false;\n setAuthorizationError(null);\n clearError();\n dispatch({ type: \"submit\" });\n captureSettledVersionRef.current = true;\n const latestUserMessage = [...messagesRef.current]\n .reverse()\n .find((message) => message.role === \"user\");\n const files = (latestUserMessage?.parts ?? []).filter(\n (part): part is FileUIPart => part.type === \"file\",\n );\n const attachmentReferences = (latestUserMessage?.parts ?? []).flatMap((part) =>\n part.type === SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE &&\n typeof part.data === \"object\" &&\n part.data !== null\n ? [part.data as SurveyAssistantAttachmentReference]\n : [],\n );\n const requestId = createSurveyAssistantDiagnosticId();\n try {\n diagnosticStore?.beginAttempt({\n attachmentReferences,\n files,\n modelId: lastSubmittedModelIdRef.current ?? modelId,\n requestId,\n resourceId,\n submittedSurvey: snapshot,\n threadId,\n });\n diagnosticStore?.recordEvent(threadId, \"retry\");\n } catch {\n // Diagnostic capture is optional; retry must continue.\n }\n void regenerate({\n body: {\n requestId,\n snapshot,\n previousSettledVersion: readSettledDocumentVersion({ resourceId, threadId }),\n previousApplyOutcome: previousApplyOutcomesRef.current.get(applyOutcomeScopeKey),\n ...(lastSubmittedModelIdRef.current ? { modelId: lastSubmittedModelIdRef.current } : {}),\n },\n });\n }, [\n applyOutcomeScopeKey,\n clearError,\n controller,\n diagnosticStore,\n modelId,\n regenerate,\n resourceId,\n reportAuthorizationError,\n threadId,\n ]);\n\n const dismissError = useCallback(() => {\n localTurnAwaitingApplyRef.current = false;\n localTurnStreamStartedRef.current = false;\n if (!hasUsefulLatestAssistantResponse) setMessages(pruneFailedMessagesForDisplay);\n setAuthorizationError(null);\n clearError();\n dispatch({ type: \"reset\", hasTranscript: messages.length > 0 });\n try {\n diagnosticStore?.recordEvent(threadId, \"dismiss\");\n } catch {\n // Diagnostic capture is optional.\n }\n }, [\n clearError,\n diagnosticStore,\n hasUsefulLatestAssistantResponse,\n messages.length,\n setMessages,\n threadId,\n ]);\n\n return {\n applyResultsByChangeId,\n authorizationError,\n dismissError,\n error,\n isStreaming,\n latestTurnOutcome,\n messages,\n prependMessages,\n state,\n status,\n stop,\n submit,\n retry,\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as createSurveyAssistantThreadLauncher, a as
|
|
1
|
+
import { _ as createSurveyAssistantThreadLauncher, a as SurveyAssistantTaskClient, c as SurveyAssistantTaskExecutor, d as createSurveyAssistantTaskClient, f as createSurveyAssistantTaskExecutor, g as SurveyAssistantThreadLauncher, h as SurveyAssistantThreadLaunch, i as createSurveyAssistantControllerProxy, l as SurveyAssistantTaskExecutorCacheContext, m as SurveyAssistantLaunchUIContext, n as SurveyAssistantControllerBridge, o as SurveyAssistantTaskClientOptions, p as SurveyAssistantController, r as createSurveyAssistantControllerBridge, s as SurveyAssistantTaskExecutionOptions, t as CreateSurveyAssistantControllerProxyOptions, u as SurveyAssistantTaskExecutorRequestOptions } from "./controller-proxy-Bd0ZHBPF.mjs";
|
|
2
2
|
export { type CreateSurveyAssistantControllerProxyOptions, type SurveyAssistantController, type SurveyAssistantControllerBridge, type SurveyAssistantLaunchUIContext, type SurveyAssistantTaskClient, type SurveyAssistantTaskClientOptions, type SurveyAssistantTaskExecutionOptions, type SurveyAssistantTaskExecutor, type SurveyAssistantTaskExecutorCacheContext, type SurveyAssistantTaskExecutorRequestOptions, type SurveyAssistantThreadLaunch, type SurveyAssistantThreadLauncher, createSurveyAssistantControllerBridge, createSurveyAssistantControllerProxy, createSurveyAssistantTaskClient, createSurveyAssistantTaskExecutor, createSurveyAssistantThreadLauncher };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { i as createSurveyAssistantTaskExecutor, n as createSurveyAssistantControllerProxy, r as createSurveyAssistantTaskClient, s as createSurveyAssistantThreadLauncher, t as createSurveyAssistantControllerBridge } from "./controller-proxy-
|
|
2
|
+
import { i as createSurveyAssistantTaskExecutor, n as createSurveyAssistantControllerProxy, r as createSurveyAssistantTaskClient, s as createSurveyAssistantThreadLauncher, t as createSurveyAssistantControllerBridge } from "./controller-proxy-BH05e-C2.mjs";
|
|
3
3
|
export { createSurveyAssistantControllerBridge, createSurveyAssistantControllerProxy, createSurveyAssistantTaskClient, createSurveyAssistantTaskExecutor, createSurveyAssistantThreadLauncher };
|
package/dist/react.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as
|
|
2
|
-
import { _ as createSurveyAssistantThreadLauncher, a as
|
|
3
|
-
export { CreateSurveyAssistantControllerProxyOptions, SurveyAssistantClientError, SurveyAssistantController, SurveyAssistantControllerBridge, SurveyAssistantLaunchUIContext, SurveyAssistantModelCatalogClient, SurveyAssistantModelCatalogState, SurveyAssistantSession, SurveyAssistantSessionEvent, SurveyAssistantSessionOptions, SurveyAssistantSessionState, SurveyAssistantSubmitMessage, SurveyAssistantTaskClient, SurveyAssistantTaskClientOptions, SurveyAssistantTaskExecutionOptions, SurveyAssistantTaskExecutor, SurveyAssistantTaskExecutorCacheContext, SurveyAssistantTaskExecutorRequestOptions, SurveyAssistantThreadClient, SurveyAssistantThreadLaunch, SurveyAssistantThreadLauncher, SurveyTurnAuthorization, SurveyTurnOutcome, UseSurveyAssistantModelCatalogOptions, collectSurveyChangeSets, createApplyReceipts, createSurveyAssistantControllerBridge, createSurveyAssistantControllerProxy, createSurveyAssistantModelCatalogClient, createSurveyAssistantTaskClient, createSurveyAssistantTaskExecutor, createSurveyAssistantThreadClient, createSurveyAssistantThreadLauncher, createSurveyAssistantTransport, getSurveyDocumentVersionFromSnapshot, isSurveyAssistantTurnActive, parseSurveyChangeSet, reduceSurveyAssistantSessionState, resolveLatestSurveyTurnAuthorization, resolveSurveyTurnOutcome, unwrapSurveyAssistantToolOutput, useSurveyAssistantModelCatalog, useSurveyAssistantSession };
|
|
1
|
+
import { A as SurveyAssistantSupportBundleLimits, B as getSurveyDocumentVersionFromSnapshot, C as sanitizeSurveyAssistantSupportValue, D as createSurveyAssistantDiagnosticId, E as SurveyAssistantDiagnosticStore, F as createSurveyAssistantTransport, G as SurveyAssistantSessionEvent, H as resolveLatestSurveyTurnAuthorization, I as SurveyTurnAuthorization, J as reduceSurveyAssistantSessionState, K as SurveyAssistantSessionState, L as SurveyTurnOutcome, M as SurveyAssistantClientError, N as SurveyAssistantThreadClient, O as createSurveyAssistantDiagnosticStore, P as createSurveyAssistantThreadClient, R as collectSurveyChangeSets, S as prepareSurveyAssistantSupportBundle, T as SurveyAssistantDiagnosticEvent, U as resolveSurveyTurnOutcome, V as parseSurveyChangeSet, W as unwrapSurveyAssistantToolOutput, _ as createSurveyAssistantSupportMailto, a as SurveyAssistantModelCatalogClient, b as generateSurveyAssistantSupportBundle, c as createSurveyAssistantModelCatalogClient, d as PreparedSurveyAssistantSupportBundle, f as SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION, g as createSurveyAssistantSupportDetails, h as SurveyAssistantSupportBundleSelection, i as useSurveyAssistantSession, j as resolveSurveyAssistantSupportBundleLimits, k as SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_LIMITS, l as useSurveyAssistantModelCatalog, m as SurveyAssistantSupportBundleConfig, n as SurveyAssistantSessionOptions, o as SurveyAssistantModelCatalogState, p as SurveyAssistantSupportBundleCategory, q as isSurveyAssistantTurnActive, r as SurveyAssistantSubmitMessage, s as UseSurveyAssistantModelCatalogOptions, t as SurveyAssistantSession, u as GeneratedSurveyAssistantSupportBundle, v as downloadSurveyAssistantSupportBundle, w as SurveyAssistantDiagnosticAttempt, x as isSurveyAssistantSupportBundleEnabled, y as estimateSurveyAssistantSupportBundleBytes, z as createApplyReceipts } from "./index-l_EK4yK7.mjs";
|
|
2
|
+
import { _ as createSurveyAssistantThreadLauncher, a as SurveyAssistantTaskClient, c as SurveyAssistantTaskExecutor, d as createSurveyAssistantTaskClient, f as createSurveyAssistantTaskExecutor, g as SurveyAssistantThreadLauncher, h as SurveyAssistantThreadLaunch, i as createSurveyAssistantControllerProxy, l as SurveyAssistantTaskExecutorCacheContext, m as SurveyAssistantLaunchUIContext, n as SurveyAssistantControllerBridge, o as SurveyAssistantTaskClientOptions, p as SurveyAssistantController, r as createSurveyAssistantControllerBridge, s as SurveyAssistantTaskExecutionOptions, t as CreateSurveyAssistantControllerProxyOptions, u as SurveyAssistantTaskExecutorRequestOptions } from "./controller-proxy-Bd0ZHBPF.mjs";
|
|
3
|
+
export { CreateSurveyAssistantControllerProxyOptions, GeneratedSurveyAssistantSupportBundle, PreparedSurveyAssistantSupportBundle, SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_LIMITS, SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION, SurveyAssistantClientError, SurveyAssistantController, SurveyAssistantControllerBridge, SurveyAssistantDiagnosticAttempt, SurveyAssistantDiagnosticEvent, SurveyAssistantDiagnosticStore, SurveyAssistantLaunchUIContext, SurveyAssistantModelCatalogClient, SurveyAssistantModelCatalogState, SurveyAssistantSession, SurveyAssistantSessionEvent, SurveyAssistantSessionOptions, SurveyAssistantSessionState, SurveyAssistantSubmitMessage, SurveyAssistantSupportBundleCategory, SurveyAssistantSupportBundleConfig, SurveyAssistantSupportBundleLimits, SurveyAssistantSupportBundleSelection, SurveyAssistantTaskClient, SurveyAssistantTaskClientOptions, SurveyAssistantTaskExecutionOptions, SurveyAssistantTaskExecutor, SurveyAssistantTaskExecutorCacheContext, SurveyAssistantTaskExecutorRequestOptions, SurveyAssistantThreadClient, SurveyAssistantThreadLaunch, SurveyAssistantThreadLauncher, SurveyTurnAuthorization, SurveyTurnOutcome, UseSurveyAssistantModelCatalogOptions, collectSurveyChangeSets, createApplyReceipts, createSurveyAssistantControllerBridge, createSurveyAssistantControllerProxy, createSurveyAssistantDiagnosticId, createSurveyAssistantDiagnosticStore, createSurveyAssistantModelCatalogClient, createSurveyAssistantSupportDetails, createSurveyAssistantSupportMailto, createSurveyAssistantTaskClient, createSurveyAssistantTaskExecutor, createSurveyAssistantThreadClient, createSurveyAssistantThreadLauncher, createSurveyAssistantTransport, downloadSurveyAssistantSupportBundle, estimateSurveyAssistantSupportBundleBytes, generateSurveyAssistantSupportBundle, getSurveyDocumentVersionFromSnapshot, isSurveyAssistantSupportBundleEnabled, isSurveyAssistantTurnActive, parseSurveyChangeSet, prepareSurveyAssistantSupportBundle, reduceSurveyAssistantSessionState, resolveLatestSurveyTurnAuthorization, resolveSurveyAssistantSupportBundleLimits, resolveSurveyTurnOutcome, sanitizeSurveyAssistantSupportValue, unwrapSurveyAssistantToolOutput, useSurveyAssistantModelCatalog, useSurveyAssistantSession };
|
package/dist/react.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as
|
|
3
|
-
import { c as SurveyAssistantClientError, i as createSurveyAssistantTaskExecutor, n as createSurveyAssistantControllerProxy, r as createSurveyAssistantTaskClient, s as createSurveyAssistantThreadLauncher, t as createSurveyAssistantControllerBridge } from "./controller-proxy-
|
|
4
|
-
export { SurveyAssistantClientError, collectSurveyChangeSets, createApplyReceipts, createSurveyAssistantControllerBridge, createSurveyAssistantControllerProxy, createSurveyAssistantModelCatalogClient, createSurveyAssistantTaskClient, createSurveyAssistantTaskExecutor, createSurveyAssistantThreadClient, createSurveyAssistantThreadLauncher, createSurveyAssistantTransport, getSurveyDocumentVersionFromSnapshot, isSurveyAssistantTurnActive, parseSurveyChangeSet, reduceSurveyAssistantSessionState, resolveLatestSurveyTurnAuthorization, resolveSurveyTurnOutcome, unwrapSurveyAssistantToolOutput, useSurveyAssistantModelCatalog, useSurveyAssistantSession };
|
|
2
|
+
import { C as resolveLatestSurveyTurnAuthorization, D as reduceSurveyAssistantSessionState, E as isSurveyAssistantTurnActive, S as parseSurveyChangeSet, T as unwrapSurveyAssistantToolOutput, _ as createSurveyAssistantThreadClient, a as createSurveyAssistantSupportDetails, b as createApplyReceipts, c as estimateSurveyAssistantSupportBundleBytes, d as prepareSurveyAssistantSupportBundle, f as sanitizeSurveyAssistantSupportValue, g as resolveSurveyAssistantSupportBundleLimits, h as SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_LIMITS, i as SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION, l as generateSurveyAssistantSupportBundle, m as createSurveyAssistantDiagnosticStore, n as createSurveyAssistantModelCatalogClient, o as createSurveyAssistantSupportMailto, p as createSurveyAssistantDiagnosticId, r as useSurveyAssistantModelCatalog, s as downloadSurveyAssistantSupportBundle, t as useSurveyAssistantSession, u as isSurveyAssistantSupportBundleEnabled, v as createSurveyAssistantTransport, w as resolveSurveyTurnOutcome, x as getSurveyDocumentVersionFromSnapshot, y as collectSurveyChangeSets } from "./react-B3ybjJ-X.mjs";
|
|
3
|
+
import { c as SurveyAssistantClientError, i as createSurveyAssistantTaskExecutor, n as createSurveyAssistantControllerProxy, r as createSurveyAssistantTaskClient, s as createSurveyAssistantThreadLauncher, t as createSurveyAssistantControllerBridge } from "./controller-proxy-BH05e-C2.mjs";
|
|
4
|
+
export { SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_LIMITS, SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION, SurveyAssistantClientError, collectSurveyChangeSets, createApplyReceipts, createSurveyAssistantControllerBridge, createSurveyAssistantControllerProxy, createSurveyAssistantDiagnosticId, createSurveyAssistantDiagnosticStore, createSurveyAssistantModelCatalogClient, createSurveyAssistantSupportDetails, createSurveyAssistantSupportMailto, createSurveyAssistantTaskClient, createSurveyAssistantTaskExecutor, createSurveyAssistantThreadClient, createSurveyAssistantThreadLauncher, createSurveyAssistantTransport, downloadSurveyAssistantSupportBundle, estimateSurveyAssistantSupportBundleBytes, generateSurveyAssistantSupportBundle, getSurveyDocumentVersionFromSnapshot, isSurveyAssistantSupportBundleEnabled, isSurveyAssistantTurnActive, parseSurveyChangeSet, prepareSurveyAssistantSupportBundle, reduceSurveyAssistantSessionState, resolveLatestSurveyTurnAuthorization, resolveSurveyAssistantSupportBundleLimits, resolveSurveyTurnOutcome, sanitizeSurveyAssistantSupportValue, unwrapSurveyAssistantToolOutput, useSurveyAssistantModelCatalog, useSurveyAssistantSession };
|
|
@@ -16,7 +16,7 @@ the latest cumulative change set for browser apply.
|
|
|
16
16
|
6. Use `survey-json-patch` through `survey_change` only for assistant-editable fields not covered by
|
|
17
17
|
typed or expression operations.
|
|
18
18
|
7. Mutation calls submit deltas to one request-scoped draft. Each successful call automatically accumulates with earlier successful calls, and later calls may target ids or assets introduced by the draft.
|
|
19
|
-
8. A rejected delta leaves the validated draft unchanged and blocks turn authorization. Correct
|
|
19
|
+
8. A rejected delta leaves the validated draft unchanged and blocks turn authorization. Correct every rejected operation and surface; unrelated valid edits do not clear the block. `pendingRepairs` reports outstanding obligations after each mutation. When `requiresExplicitRetry` is true, supply the rejected change id in `retryOfChangeIds` with the complete corrected scope. Correct unavailable or invalid target identities. Only when `allowsAcknowledgment` is true, inspect the validator-confirmed no-op and acknowledge it with `survey_change` using `operations: []` and `retryOfChangeIds`; do not invent an unrelated edit. Acknowledgments may be batched and cannot discharge identifiable pending edits. Malformed operations, invalid targets, and failed creations require a linked non-empty corrected retry. An ordinary empty call is invalid and must also be reconciled by a linked non-empty retry. Successful completion authorizes only the latest cumulative draft for one editor apply; acknowledgment alone never creates an empty editor commit.
|
|
20
20
|
|
|
21
21
|
## `survey_change` Typed Operations
|
|
22
22
|
|
|
@@ -25,13 +25,19 @@ For the canonical fields of one operation, call `survey_authoring_reference` aga
|
|
|
25
25
|
from the same validator used by `survey_change`, so this reference does not duplicate a static
|
|
26
26
|
operation catalog.
|
|
27
27
|
|
|
28
|
+
Generated operation schemas describe the canonical post-normalization contract. The model-facing
|
|
29
|
+
`survey_change` input also accepts the compact `richTextBlocks` shorthand documented in
|
|
30
|
+
`rich-text-content` wherever a typed translation accepts structured `content`; it is normalized to
|
|
31
|
+
canonical `content` before these schemas run. Never combine shorthand with `plainText` or `content`
|
|
32
|
+
in the same translation.
|
|
33
|
+
|
|
28
34
|
`create-item`
|
|
29
35
|
|
|
30
36
|
- Creates a new item under `target.parentItemId`.
|
|
31
37
|
- Use root group id/key for top-level items.
|
|
32
38
|
- Put visible text in top-level `translations`, not inside `item`.
|
|
33
|
-
- Each translation
|
|
34
|
-
- When a new item must contain an image, prefer
|
|
39
|
+
- Each canonical translation contains exactly one of `plainText` or a complete structured `content` value. Model-authored `survey_change` input may use `richTextBlocks` instead as described above.
|
|
40
|
+
- When a new item must contain an image, prefer `richTextBlocks` and place the canonical image block inside that array. Use canonical `content` for the whole translation only when the compact interface is unsuitable.
|
|
35
41
|
- Use the actual content locale in `translations[].locale`. Missing locales are introduced when translations are applied.
|
|
36
42
|
- Put item configuration inside `item.config`, not beside `item`.
|
|
37
43
|
- Item key must be unique among siblings.
|
|
@@ -155,7 +161,7 @@ Minimal valid examples:
|
|
|
155
161
|
- Use this with a new locale code when adding translated content for a locale that is not yet present.
|
|
156
162
|
- Use for titles, subtitles, top/bottom content, card footer, info content, and simple field/option labels when the key is known.
|
|
157
163
|
- Use `plainText` for simple unformatted text.
|
|
158
|
-
-
|
|
164
|
+
- For a complete formatted replacement, prefer top-level `richTextBlocks`; it normalizes to canonical `content`. Use canonical `content` directly when needed. Do not use markdown syntax to request formatting.
|
|
159
165
|
|
|
160
166
|
`update-placed-image`
|
|
161
167
|
|
|
@@ -184,10 +190,24 @@ Minimal valid examples:
|
|
|
184
190
|
- Target a top-level form with `{ "itemId": "<form-id>" }` or a choice option's form with `{ "itemId": "<choice-id>", "optionId": "<option-id>" }`.
|
|
185
191
|
- Add visible labels, placeholders, option labels, and validation messages in the operation's `translations` array so structure and content remain atomic.
|
|
186
192
|
- Group and field identifiers are stable ids; reorder operations require the complete current id set.
|
|
193
|
+
- To update only an existing field group's responsive layout, use `upsert-form-field-group` with the existing group id and a `group` containing `id` and `layout`. Omitted fields and other existing group properties are preserved.
|
|
187
194
|
- Simple forms contain one group and one field. Compatible updates to that same field may remain
|
|
188
195
|
simple; structural changes automatically make the form custom. This applies to top-level and
|
|
189
196
|
embedded forms and is intentionally one-way.
|
|
190
197
|
|
|
198
|
+
Update an existing form field group's layout without replacing its fields:
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"kind": "upsert-form-field-group",
|
|
203
|
+
"target": { "itemId": "profile" },
|
|
204
|
+
"group": {
|
|
205
|
+
"id": "main",
|
|
206
|
+
"layout": { "base": 1, "xs": 1, "sm": 2, "md": 2, "xl": 3 }
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
191
211
|
`set-embedded-form`, `remove-embedded-form`
|
|
192
212
|
|
|
193
213
|
- Add or remove a choice option's inline form using item and option ids, without raw array-index patches.
|
|
@@ -231,53 +251,39 @@ Minimal valid examples:
|
|
|
231
251
|
validation messages are ordinary config/content, not expression mutations.
|
|
232
252
|
- Use it for field controller internals and any existing custom-registry item config that is not covered by a typed helper.
|
|
233
253
|
|
|
234
|
-
## Raw Patch
|
|
254
|
+
## Raw Patch Example
|
|
235
255
|
|
|
236
|
-
|
|
256
|
+
Use a raw patch only for an existing, inspected survey-root extension that has no typed operation,
|
|
257
|
+
`patch-item-config` helper, or `survey_expression` mutation. Obtain the exact path and current value
|
|
258
|
+
from `survey_inspect` first. A guarded replacement has this shape:
|
|
237
259
|
|
|
238
260
|
```json
|
|
239
261
|
{
|
|
240
262
|
"kind": "survey-json-patch",
|
|
241
263
|
"patches": [
|
|
264
|
+
{
|
|
265
|
+
"op": "test",
|
|
266
|
+
"path": "/<inspected-extension>/<leaf>",
|
|
267
|
+
"value": "<current-value>"
|
|
268
|
+
},
|
|
242
269
|
{
|
|
243
270
|
"op": "replace",
|
|
244
|
-
"path": "
|
|
245
|
-
"value":
|
|
271
|
+
"path": "/<inspected-extension>/<leaf>",
|
|
272
|
+
"value": "<requested-value>"
|
|
246
273
|
}
|
|
247
274
|
]
|
|
248
275
|
}
|
|
249
276
|
```
|
|
250
277
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
{
|
|
255
|
-
"kind": "add-survey-locale",
|
|
256
|
-
"locale": "nl"
|
|
257
|
-
}
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
Never use this whole-branch operation for an existing locale. Patch the required leaf key instead,
|
|
261
|
-
or use `update-item-translation`, so sibling translations are preserved.
|
|
262
|
-
|
|
263
|
-
Add a form field and matching label in one proposal:
|
|
264
|
-
|
|
265
|
-
- Patch the form item config fieldGroups array.
|
|
266
|
-
- Patch `/translations/<locale>/itemTranslations/<itemId>/fields.<fieldId>.label`. This is REQUIRED, not optional — a field with no label translation shows no visible label to respondents.
|
|
267
|
-
- Include any placeholder, unit, option labels, or validation messages that the new field needs.
|
|
268
|
-
|
|
269
|
-
Survey-level translation branches:
|
|
270
|
-
|
|
271
|
-
- `/translations/<locale>/surveyCardContent` stores survey-card copy such as title/description content.
|
|
272
|
-
- `/translations/<locale>/navigationContent` stores participant navigation labels.
|
|
273
|
-
- `/translations/<locale>/validationMessages` stores survey-level validation copy such as `invalidResponse`.
|
|
274
|
-
- Use `survey-json-patch` for these branches today.
|
|
275
|
-
|
|
276
|
-
Add an embedded input to an existing choice option:
|
|
278
|
+
The placeholders describe the shape only; never send them literally or invent an extension path.
|
|
279
|
+
Keep every related raw edit in the same `patches` array, and keep this `survey-json-patch` operation
|
|
280
|
+
as the proposal's only operation.
|
|
277
281
|
|
|
278
|
-
|
|
279
|
-
- Patch the target option object under `/surveyItems/<choiceIndex>/config/options/<optionIndex>/embeddedForm`.
|
|
280
|
-
- Patch `/translations/<locale>/itemTranslations/<choiceItemId>/embeddedForms.<optionId>.fields.<fieldId>.label` with a complete Content value such as `{ "type": "md", "content": "Please specify" }`. This is REQUIRED, not optional — a field with no label translation shows no visible label to respondents (only its raw control type, e.g. "Input"). Never add, replace, or remove the surrounding locale or itemTranslations container; it would discard sibling text.
|
|
281
|
-
- Do not patch `allowOther`; it is not part of the current choice config.
|
|
282
|
+
### Raw Patch Rules
|
|
282
283
|
|
|
283
|
-
|
|
284
|
+
- Paths are survey-root JSON Pointers from current raw inspection. Each `/` separates path segments; within a segment, encode `~` as `~0` and `/` as `~1`.
|
|
285
|
+
- Patches run sequentially, so each operation sees the result of the previous operations. Parent paths must already exist; create missing containers explicitly in dependency order when the inspected extension contract permits them.
|
|
286
|
+
- Use `add` to create or replace an object member, insert before an existing array index, or append to an array with `/-`. Use `replace`, `remove`, or `test` only when the target path already exists.
|
|
287
|
+
- `move` and `copy` require an existing `from` path and use `path` as an add destination. A move removes the source before resolving the destination, so later array indexes refer to the already-modified array.
|
|
288
|
+
- A `test` compares the complete JSON value and type. Preserve booleans, numbers, `null`, arrays, and objects as those JSON types rather than converting them to strings. Put a matching `test` immediately before an overwrite, removal, or move when current inspection provides the expected value.
|
|
289
|
+
- Never patch `/$schema`, translation roots or whole existing locale branches, expression-owned paths, or another protected location rejected by the validator. Use the specialized operation or tool named by validation instead.
|
|
@@ -5,6 +5,8 @@ Use `survey_expression` for expression work. It is the expression capability bun
|
|
|
5
5
|
- `action: "context"` returns available response refs and optional existing expression locations.
|
|
6
6
|
- `action: "prepare"` validates expression refs/return types and registers a candidate change set.
|
|
7
7
|
- Prefer this tool over hand-written raw JSON Patch for expression-bearing locations.
|
|
8
|
+
- Provider adapters normalize optional fields when strict tool calling requires nullable wire
|
|
9
|
+
properties. Supply only the fields used by the chosen action.
|
|
8
10
|
|
|
9
11
|
## JsonExpression
|
|
10
12
|
|
|
@@ -39,6 +41,22 @@ Methods:
|
|
|
39
41
|
- `get`: returns the current slot value.
|
|
40
42
|
- `isDefined`: returns boolean true when a response exists.
|
|
41
43
|
|
|
44
|
+
`isDefined` means only "the respondent answered this slot." It never means a particular answer
|
|
45
|
+
such as Yes, selected, eligible, consented, or has children. When the user's condition names or
|
|
46
|
+
implies a choice, inspect the source choice item's exact option ids and labels, then compare the
|
|
47
|
+
`get` response with that option's reference using `eq` (single choice) or `list_contains`
|
|
48
|
+
(multiple choice). Do not substitute `isDefined` merely because the exact option id is not yet
|
|
49
|
+
known.
|
|
50
|
+
|
|
51
|
+
Avoid accidental cycles in assistant-authored explicit item-level display-condition response
|
|
52
|
+
dependencies, including direct self-reference and A depending on B while B depends on A. Shared
|
|
53
|
+
survey integrity analysis reports these as advisory findings because responses can be populated
|
|
54
|
+
before visibility is evaluated, including through prefills. Prefer an acyclic controlling source
|
|
55
|
+
item unless the dependency is intentional. This analysis currently covers explicit item-level
|
|
56
|
+
response edges; it does not model inherited group visibility or component-level dependency graphs.
|
|
57
|
+
Component-level conditions may still use another response slot from the same item when that
|
|
58
|
+
interaction is valid.
|
|
59
|
+
|
|
42
60
|
Never invent response refs. Use the current context response-slots scope or item details.
|
|
43
61
|
This rule is item-type independent: preserve every item id, slot id, component/validation key,
|
|
44
62
|
prefill id, template key, and reference constant exactly as inspected. Never humanize an identifier
|
|
@@ -209,6 +227,10 @@ creates in this one operations array.
|
|
|
209
227
|
|
|
210
228
|
## survey_expression Mutations
|
|
211
229
|
|
|
230
|
+
The shapes below are the canonical mutations. Send the complete array once as `mutations`; the
|
|
231
|
+
server validates every entry against these canonical shapes before changing the request-scoped
|
|
232
|
+
draft.
|
|
233
|
+
|
|
212
234
|
Item visibility:
|
|
213
235
|
|
|
214
236
|
```json
|
|
@@ -310,3 +332,9 @@ Template value shape:
|
|
|
310
332
|
```
|
|
311
333
|
|
|
312
334
|
Date formatting template values use `type: "date2string"`, `returnType: "string"`, and `dateFormat`.
|
|
335
|
+
|
|
336
|
+
## Bounded context and atomic batches
|
|
337
|
+
|
|
338
|
+
`survey_expression` action `context` filters response slots and expression locations with `itemIds` (ids, keys, or fullKeys). Follow `nextCursor` with the same filter and `limit` until absent; restart after a draft mutation. The returned model text contains the actual page and distinguishes filtered totals from the survey-wide response-slot count. For a controlling question outside the filter, omit itemIds and cursor to retrieve the survey-wide catalog. Unresolved identifiers are reported explicitly, not as evidence that an item has no response.
|
|
339
|
+
|
|
340
|
+
A `prepare` mutation array is executed in order within one atomic delta. Later mutations see earlier additions, replacements, and removals, including new containers and shifted prefill indexes. If any mutation fails, none of the delta is staged. Retry all requested mutations from that rejected delta; `pendingRepairs` tracks every remaining operation and surface. For missing or invalid targets, use the indicated `retryOfChangeIds` with the complete corrected input. If an expression location is already empty, inspect and acknowledge that rejected request with a linked `survey_change` using `operations: []`; other identifiable pending edits remain required. Clearing a condition is not a repair of a requested condition change.
|
|
@@ -38,7 +38,7 @@ Page-break/structural item. It has no response slots. Visible title uses content
|
|
|
38
38
|
|
|
39
39
|
Non-interactive content item. Config is normally an empty object. Visible body text uses content key `content`.
|
|
40
40
|
For plain text, create or update `content` with typed translation operations.
|
|
41
|
-
For formatted text,
|
|
41
|
+
For formatted text, load `assistant-operations` with the operation and item type and use only content surfaces marked `format=rich` in its capability profile. Prefer the model-facing `richTextBlocks` shorthand there; it normalizes to canonical richText `content`. A typed field accepting structured `content` does not by itself guarantee formatted rendering. See rich-text-content.md.
|
|
42
42
|
|
|
43
43
|
## choiceItem
|
|
44
44
|
|
|
@@ -17,10 +17,11 @@ Use this reference when the user asks to translate, localize, add a language, or
|
|
|
17
17
|
## Scope A Complete Localization Correctly
|
|
18
18
|
|
|
19
19
|
1. Use `survey_inspect` with `action: "localization"`, the source locale, and the target locale. Page until `nextCursor` is absent; this covers existing respondent-visible item and survey translation surfaces without one item-details call per item.
|
|
20
|
-
2.
|
|
21
|
-
3.
|
|
22
|
-
4.
|
|
23
|
-
5.
|
|
20
|
+
2. Treat `sourceText` and `targetText` as previews. When `sourceTruncated` is true for plain text, retrieve `sourceTextPath` through `survey_inspect` action `raw-json`, then follow `nextTextOffset` using `textOffset` and that same path until all segments are read. Translate the complete source, never only the preview. Rich-text `sourceContent` already contains the full canonical value. `targetPresent` proves presence, not translation fidelity or completeness.
|
|
21
|
+
3. Inspect item configuration separately only when the localization surface result or an audit indicates that the source survey itself is missing a visible content key. This includes choice-option labels, form-field labels, select-option labels, embedded-form labels, and validation copy.
|
|
22
|
+
4. Preserve the source language while writing each target-language value under the target locale. Do not replace source content or translation containers.
|
|
23
|
+
5. Use `update-item-translation` for ordinary item content. Use typed choice operations only when also changing the choice structure. Use a focused raw patch only for a supported survey-level translation surface that has no typed operation.
|
|
24
|
+
6. Before proposing, check that every visible label implied by the inspected item configuration has a target-locale translation. A title alone is not a complete localization of a choice or form item.
|
|
24
25
|
|
|
25
26
|
## Bounded Execution
|
|
26
27
|
|