omnix-chat 2.5.9 → 3.0.2
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/CHANGELOG.md +9 -0
- package/README.md +1 -1
- package/dist/omnix-chat.es.js +775 -737
- package/dist/omnix-chat.es.js.map +1 -1
- package/dist/omnix-chat.umd.cjs +15 -15
- package/dist/omnix-chat.umd.js +15 -15
- package/dist/omnix-chat.umd.js.map +1 -1
- package/dist/react-types-4kCc9MAv.cjs.js.map +1 -1
- package/dist/react-types-D6g7_-_a.js.map +1 -1
- package/dist/react.cjs +173 -122
- package/dist/react.cjs.js +173 -122
- package/dist/react.cjs.js.map +1 -1
- package/dist/react.es.js +518 -441
- package/dist/react.es.js.map +1 -1
- package/dist/react.legacy-types-B3OBHme4.cjs.js.map +1 -1
- package/dist/react.legacy-types-C11EZiOU.js.map +1 -1
- package/dist/react.legacy.cjs +93 -39
- package/dist/react.legacy.cjs.js +93 -39
- package/dist/react.legacy.cjs.js.map +1 -1
- package/dist/react.legacy.es.js +142 -62
- package/dist/react.legacy.es.js.map +1 -1
- package/dist/src/core/client/instance.d.ts +8 -1
- package/dist/src/core/client/instance.d.ts.map +1 -1
- package/dist/src/core/lib/errors.d.ts +1 -1
- package/dist/src/core/lib/errors.d.ts.map +1 -1
- package/dist/src/core/page/page-action-feedback-wish-response.d.ts +3 -1
- package/dist/src/core/page/page-action-feedback-wish-response.d.ts.map +1 -1
- package/dist/src/core/services/page-action.service.d.ts +6 -1
- package/dist/src/core/services/page-action.service.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/react/usePageAction.d.ts +16 -2
- package/dist/src/react/usePageAction.d.ts.map +1 -1
- package/dist/src/react/usePageActions.d.ts +15 -1
- package/dist/src/react/usePageActions.d.ts.map +1 -1
- package/dist/src/types.d.ts +23 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/sdk-version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.legacy-types-C11EZiOU.js","names":[],"sources":["../src/core/chat/message-blocks.ts","../src/core/draft-review/write-draft.ts","../src/core/draft-review/param-path.ts","../src/core/draft-review/edit-policy.ts","../src/core/draft-review/draft-review-bundle.ts","../src/core/page/skill-client.ts","../src/core/page/route-context.ts","../src/core/page/brain-clarify.ts","../src/core/approval/entity-reference.ts","../src/core/approval/approval-response.ts","../src/core/feedback/feedback-utils.ts","../src/core/page/page-action-workflow-progress.ts","../src/core/page/page-action-launch.ts","../src/core/page/page-action-process-view.ts","../src/types.ts"],"sourcesContent":["export type CoreMessageBlock = Record<string, unknown> & { type: string; id?: string };\n\nexport interface CoreMessageBlockPatch {\n replaceId: string;\n block: CoreMessageBlock;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function parseStoredBlocks(content: string | null | undefined): CoreMessageBlock[] | undefined {\n if (!content) return undefined;\n const trimmed = content.trim();\n if (!trimmed || trimmed[0] !== '{') return undefined;\n try {\n const parsed = JSON.parse(trimmed) as { blocks?: unknown };\n if (!Array.isArray(parsed.blocks)) return undefined;\n return parsed.blocks.filter(\n (item): item is CoreMessageBlock => isRecord(item) && typeof item.type === 'string',\n );\n } catch {\n return undefined;\n }\n}\n\nexport function blocksToText(blocks: CoreMessageBlock[] | undefined): string {\n if (!blocks?.length) return '';\n return blocks\n .map((block) => (block.type === 'text' && typeof block.content === 'string' ? block.content : ''))\n .join('');\n}\n\n/** Serialize blocks for `writeGate.editedPreviewSerialized` (same shape as stored assistant messages). */\nexport function serializeMessageBlocksForStorage(blocks: CoreMessageBlock[]): string {\n return JSON.stringify({ blocks });\n}\n\n/** Build `editedPreviewSerialized` after the user edits plain text in the gate editor. */\nexport function buildEditedPreviewFromText(\n editedText: string,\n sourceBlocks?: CoreMessageBlock[],\n): string {\n if (sourceBlocks?.length) {\n let replacedText = false;\n const next = sourceBlocks.map((block) => {\n if (block.type === 'text') {\n replacedText = true;\n return { ...block, content: editedText };\n }\n return block;\n });\n if (!replacedText) {\n next.unshift({ type: 'text', format: 'markdown', content: editedText });\n }\n return serializeMessageBlocksForStorage(next);\n }\n return serializeMessageBlocksForStorage([\n { type: 'text', format: 'markdown', content: editedText },\n ]);\n}\n\nfunction appendDeltaText(previous: CoreMessageBlock[], incoming: CoreMessageBlock[]): CoreMessageBlock[] {\n let textPiece = '';\n for (const block of incoming) {\n if (block.type === 'text' && typeof block.content === 'string') {\n textPiece += block.content;\n }\n }\n if (!textPiece) return previous;\n const next = [...previous];\n const last = next[next.length - 1];\n if (last?.type === 'text' && typeof last.content === 'string') {\n next[next.length - 1] = { ...last, content: `${last.content}${textPiece}` };\n return next;\n }\n next.push({ type: 'text', format: 'markdown', content: textPiece });\n return next;\n}\n\nconst STRUCTURED_BLOCK_TYPES = new Set([\n 'table',\n 'chart',\n 'metric',\n 'list',\n 'image',\n 'alert',\n]);\n\nfunction stripBlocksJsonTextBlocks(blocks: CoreMessageBlock[]): CoreMessageBlock[] {\n return blocks.filter((block) => {\n if (block.type !== 'text' || typeof block.content !== 'string') {\n return true;\n }\n const trimmed = block.content.trimStart();\n if (!trimmed.startsWith('{')) {\n return true;\n }\n return !parseStoredBlocks(block.content);\n });\n}\n\nfunction looksLikeMarkdownTable(text: string): boolean {\n const lines = text.trim().split('\\n').filter((line) => line.trim().length > 0);\n if (lines.length < 2) return false;\n return lines.slice(0, 3).some((line) => line.includes('|'));\n}\n\nfunction replaceOrAppendStructuredBlock(\n next: CoreMessageBlock[],\n block: CoreMessageBlock,\n): CoreMessageBlock[] {\n const id = typeof block.id === 'string' ? block.id.trim() : '';\n if (id) {\n const hit = next.findIndex((item) => item.id === id);\n if (hit >= 0) {\n const copy = [...next];\n copy[hit] = { ...block, id };\n return copy;\n }\n return [...next, { ...block, id }];\n }\n\n if (STRUCTURED_BLOCK_TYPES.has(block.type)) {\n const hit = next.findIndex((item) => item.type === block.type);\n if (hit >= 0) {\n const copy = [...next];\n copy[hit] = block;\n return copy;\n }\n }\n\n return [...next, block];\n}\n\nexport function applyStreamFull(previous: CoreMessageBlock[], incoming: CoreMessageBlock[]): CoreMessageBlock[] {\n let next = [...previous];\n const incomingHasStructured = incoming.some(\n (block) => block.type !== 'text' && block.type !== 'loading',\n );\n if (incomingHasStructured) {\n next = stripBlocksJsonTextBlocks(next);\n }\n const hasStructuredBlock = next.some((item) => STRUCTURED_BLOCK_TYPES.has(item.type));\n let sawText = false;\n\n for (const block of incoming) {\n if (block.type === 'text') {\n sawText = true;\n const text = typeof block.content === 'string' ? block.content : '';\n if (!text) continue;\n const hasDeltaText = next.some((item) => item.type === 'text' && typeof item.content === 'string');\n if (hasDeltaText) continue;\n // After patch/table blocks, ignore duplicate markdown table fallback from backend.\n if (hasStructuredBlock && looksLikeMarkdownTable(text)) continue;\n next.push({ ...block, content: text });\n continue;\n }\n next = replaceOrAppendStructuredBlock(next, block);\n }\n\n if (!sawText && incoming.length === 0) return previous;\n return next;\n}\n\nexport function applyStreamDelta(previous: CoreMessageBlock[], incoming: CoreMessageBlock[]): CoreMessageBlock[] {\n return appendDeltaText(previous, incoming);\n}\n\nfunction unescapeJsonStringFragment(fragment: string): string {\n let out = '';\n for (let i = 0; i < fragment.length; i += 1) {\n const ch = fragment[i];\n if (ch !== '\\\\') {\n out += ch;\n continue;\n }\n const next = fragment[i + 1];\n if (next === undefined) {\n out += ch;\n break;\n }\n switch (next) {\n case 'n':\n out += '\\n';\n break;\n case 't':\n out += '\\t';\n break;\n case 'r':\n out += '\\r';\n break;\n case '\"':\n out += '\"';\n break;\n case '\\\\':\n out += '\\\\';\n break;\n default:\n out += next;\n break;\n }\n i += 1;\n }\n return out;\n}\n\nfunction looksLikeBlocksJsonStreaming(text: string): boolean {\n const trimmed = text.trimStart();\n if (!trimmed.startsWith('{')) return false;\n return /\"blocks\"/.test(trimmed);\n}\n\nconst STREAMING_TEXT_CONTENT_MARKER =\n /\"type\"\\s*:\\s*\"text\"\\s*,\\s*\"content\"\\s*:\\s*\"/;\n\n/**\n * Extract markdown from an in-progress `{\"blocks\":[{\"type\":\"text\",\"content\":\"...\"}]}` payload.\n * Returns `undefined` when the string is not a blocks JSON envelope.\n * Returns `null` when the envelope prefix is still streaming (hide raw JSON).\n */\nexport function extractPartialBlocksJsonTextContent(raw: string): string | null | undefined {\n if (!looksLikeBlocksJsonStreaming(raw)) return undefined;\n\n const parsed = parseStoredBlocks(raw);\n if (parsed) return blocksToText(parsed);\n\n const match = STREAMING_TEXT_CONTENT_MARKER.exec(raw);\n if (!match) return null;\n\n const start = match.index + match[0].length;\n let i = start;\n let escaped = '';\n while (i < raw.length) {\n const ch = raw[i];\n if (ch === '\\\\') {\n if (i + 1 >= raw.length) {\n escaped += ch;\n break;\n }\n escaped += raw.slice(i, i + 2);\n i += 2;\n continue;\n }\n if (ch === '\"') break;\n escaped += ch;\n i += 1;\n }\n return unescapeJsonStringFragment(escaped);\n}\n\n/**\n * When the model streams a full `{\"blocks\":[...]}` JSON string inside a single\n * text block, unwrap it into structured blocks for rendering.\n */\nexport function unwrapBlocksJsonEnvelope(blocks: CoreMessageBlock[]): CoreMessageBlock[] {\n if (blocks.length !== 1) return blocks;\n const only = blocks[0];\n if (only?.type !== 'text' || typeof only.content !== 'string') return blocks;\n const parsed = parseStoredBlocks(only.content);\n if (parsed && parsed.length > 0) return parsed;\n\n const partial = extractPartialBlocksJsonTextContent(only.content);\n if (partial !== undefined) {\n const format = typeof only.format === 'string' ? only.format : 'markdown';\n return [{ type: 'text', format, content: partial ?? '' }];\n }\n\n return blocks;\n}\n\nexport function applyPatches(\n previous: CoreMessageBlock[],\n patches: CoreMessageBlockPatch[],\n): CoreMessageBlock[] {\n if (!patches.length) return previous;\n const next = [...previous];\n for (const patch of patches) {\n const id = patch.replaceId.trim();\n if (!id) continue;\n const hit = next.findIndex((block) => block.id === id);\n if (hit >= 0) next[hit] = { ...patch.block, id };\n else next.push({ ...patch.block, id });\n }\n return next;\n}\n","import type { CoreMessageBlock } from '../chat/message-blocks';\n\nexport type WriteDraftLastEvent = 'composed' | 'suspended' | 'user_edit' | 'retry';\n\n/** C-end write draft — execution truth is `arguments`; presentation is view-only. */\nexport interface WriteDraftPublic {\n version: number;\n tool: {\n name: string;\n toolId?: number;\n riskLevel: string;\n };\n arguments: Record<string, unknown>;\n presentation: {\n summaryText?: string | null;\n previewBlocks: CoreMessageBlock[];\n };\n provenance: {\n draftRetryCount: number;\n draftRetryMax: number;\n canRetry: boolean;\n composedAt: string;\n lastEvent: WriteDraftLastEvent;\n };\n}\n\nexport interface WriteDraftEditPayload {\n editedPendingWriteArguments?: Record<string, unknown>;\n editedPreviewSerialized?: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction readNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n return undefined;\n}\n\nfunction parsePreviewBlocks(value: unknown): CoreMessageBlock[] {\n if (!Array.isArray(value)) return [];\n return value.filter(\n (item): item is CoreMessageBlock =>\n isRecord(item) && typeof item.type === 'string',\n );\n}\n\n/** Parse SSE / inbox `writeDraft` payload. */\nexport function parseWriteDraftPublic(value: unknown): WriteDraftPublic | null {\n if (!isRecord(value)) return null;\n const version = readNumber(value.version);\n const toolRaw = value.tool;\n if (version == null || !isRecord(toolRaw)) return null;\n const toolName = readString(toolRaw.name);\n if (!toolName) return null;\n const toolId = readNumber(toolRaw.toolId);\n const riskLevel = readString(toolRaw.riskLevel) ?? 'L2';\n const args = isRecord(value.arguments) ? value.arguments : null;\n if (!args) return null;\n const presentationRaw = value.presentation;\n const presentation = isRecord(presentationRaw)\n ? {\n summaryText:\n typeof presentationRaw.summaryText === 'string' ? presentationRaw.summaryText : null,\n previewBlocks: parsePreviewBlocks(presentationRaw.previewBlocks),\n }\n : { summaryText: null, previewBlocks: [] as CoreMessageBlock[] };\n const provenanceRaw = value.provenance;\n const draftRetryCount = isRecord(provenanceRaw)\n ? (readNumber(provenanceRaw.draftRetryCount) ?? 0)\n : 0;\n const draftRetryMax = isRecord(provenanceRaw)\n ? (readNumber(provenanceRaw.draftRetryMax) ?? 3)\n : 3;\n const canRetry = isRecord(provenanceRaw)\n ? provenanceRaw.canRetry === false\n ? false\n : provenanceRaw.canRetry === true\n ? true\n : draftRetryCount < draftRetryMax\n : true;\n const composedAt = isRecord(provenanceRaw)\n ? (readString(provenanceRaw.composedAt) ?? new Date(0).toISOString())\n : new Date(0).toISOString();\n const lastEventRaw = isRecord(provenanceRaw) ? readString(provenanceRaw.lastEvent) : undefined;\n const lastEvent: WriteDraftLastEvent =\n lastEventRaw === 'composed' ||\n lastEventRaw === 'suspended' ||\n lastEventRaw === 'user_edit' ||\n lastEventRaw === 'retry'\n ? lastEventRaw\n : 'suspended';\n\n return {\n version,\n tool: {\n name: toolName,\n ...(toolId != null ? { toolId } : {}),\n riskLevel,\n },\n arguments: args,\n presentation,\n provenance: {\n draftRetryCount,\n draftRetryMax,\n canRetry,\n composedAt,\n lastEvent,\n },\n };\n}\n\nexport function cloneWriteDraftArguments(\n draft: WriteDraftPublic,\n): Record<string, unknown> {\n return structuredClone(draft.arguments);\n}\n\n/** Bind editor to `writeDraft.arguments` (form-driven). */\nexport function argumentsToEditorText(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 1 && typeof args.content === 'string') {\n return args.content;\n }\n if (keys.length > 0 && keys.every((key) => key === 'content' || args[key] === undefined)) {\n if (typeof args.content === 'string') return args.content;\n }\n try {\n return JSON.stringify(args, null, 2);\n } catch {\n return '';\n }\n}\n\nexport function editorTextToArguments(\n original: Record<string, unknown>,\n text: string,\n): Record<string, unknown> {\n const trimmed = text.trim();\n if (trimmed.startsWith('{')) {\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (isRecord(parsed) && !Array.isArray(parsed)) {\n return parsed;\n }\n } catch {\n /* fall through to scalar mapping */\n }\n }\n if (typeof original.content === 'string' || 'content' in original) {\n return { ...original, content: text };\n }\n return { content: text };\n}\n\nexport function buildConfirmWithEdits(\n draft: WriteDraftPublic,\n editedArgs: Record<string, unknown>,\n): WriteDraftEditPayload {\n return buildConfirmWithEditsFromArguments(draft.arguments, editedArgs);\n}\n\nexport function buildConfirmWithEditsFromArguments(\n original: Record<string, unknown>,\n edited: Record<string, unknown>,\n): WriteDraftEditPayload {\n const patch: Record<string, unknown> = {};\n const keys = new Set([...Object.keys(original), ...Object.keys(edited)]);\n for (const key of keys) {\n if (JSON.stringify(original[key]) !== JSON.stringify(edited[key])) {\n patch[key] = edited[key];\n }\n }\n return {\n editedPendingWriteArguments: Object.keys(patch).length > 0 ? patch : edited,\n };\n}\n","import type { EditPolicyPublic } from './edit-policy';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readSegments(path: string): string[] {\n return path.replace(/\\[\\]/g, '').split('.').filter(Boolean);\n}\n\nexport function readRootParamPath(args: Record<string, unknown>, path: string): unknown {\n let cursor: unknown = args;\n for (const segment of readSegments(path)) {\n if (!isRecord(cursor)) return undefined;\n cursor = cursor[segment];\n }\n return cursor;\n}\n\nexport function parseArrayItemSubmitPath(\n path: string,\n): { arrayPath: string; leafPath: string } | null {\n const match = /^(.+)\\[\\]\\.(.+)$/.exec(path.trim());\n if (!match) return null;\n return { arrayPath: match[1], leafPath: match[2] };\n}\n\n/** Read tool argument values using compact paths (`items[].body`). */\nexport function readValueAtParamPath(\n args: Record<string, unknown>,\n path: string,\n): unknown {\n const trimmed = path.trim();\n if (!trimmed) return undefined;\n\n const arrayParts = parseArrayItemSubmitPath(trimmed);\n if (arrayParts) {\n const arrayValue = readRootParamPath(args, arrayParts.arrayPath);\n if (!Array.isArray(arrayValue)) return undefined;\n for (const item of arrayValue) {\n if (isRecord(item) && arrayParts.leafPath in item) {\n return item[arrayParts.leafPath];\n }\n }\n return undefined;\n }\n\n return readRootParamPath(args, trimmed);\n}\n\nexport interface SubmitPathPreviewItem {\n index: number;\n label: string;\n text: string;\n meta: Array<{ label: string; value: string }>;\n}\n\nfunction formatScalar(value: unknown): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n if (typeof value === 'number') return String(value);\n return '';\n}\n\nfunction resolveFieldLabel(policy: EditPolicyPublic, path: string): string {\n return policy.fields.find((field) => field.path === path)?.label?.trim() || path;\n}\n\nfunction resolveArrayItemMeta(\n policy: EditPolicyPublic,\n arrayPath: string,\n item: Record<string, unknown>,\n submitLeaf: string,\n): Array<{ label: string; value: string }> {\n const prefix = `${arrayPath}[].`;\n return policy.fields\n .filter((field) => {\n if (!field.path.startsWith(prefix)) return false;\n const leaf = field.path.slice(prefix.length);\n if (!leaf || leaf.includes('.') || leaf === submitLeaf) return false;\n if (field.path === policy.submitPath) return false;\n return field.role === 'identifier' || field.widget === 'readonly';\n })\n .map((field) => {\n const leaf = field.path.slice(prefix.length);\n const raw = leaf in item ? item[leaf] : field.value;\n return { label: field.label, value: formatScalar(raw) };\n })\n .filter((row) => row.value.trim().length > 0);\n}\n\nfunction resolveScalarContextMeta(\n policy: EditPolicyPublic,\n args: Record<string, unknown>,\n): Array<{ label: string; value: string }> {\n const submitPath = policy.submitPath?.trim();\n return policy.fields\n .filter((field) => {\n if (field.path === submitPath) return false;\n if (field.path.includes('[]')) return false;\n return field.role === 'identifier' || field.widget === 'readonly';\n })\n .map((field) => ({\n label: field.label,\n value: formatScalar(readValueAtParamPath(args, field.path) ?? field.value),\n }))\n .filter((row) => row.value.trim().length > 0);\n}\n\n/** Expand `editPolicy.submitPath` into user-facing preview rows (supports `arr[].leaf`). */\nexport function resolveSubmitPathPreviewItems(\n args: Record<string, unknown>,\n policy: EditPolicyPublic,\n): SubmitPathPreviewItem[] {\n const submitPath = policy.submitPath?.trim();\n if (!submitPath) return [];\n\n const baseLabel = resolveFieldLabel(policy, submitPath);\n const arrayParts = parseArrayItemSubmitPath(submitPath);\n\n if (!arrayParts) {\n const value = readValueAtParamPath(args, submitPath);\n const text = typeof value === 'string' ? value : formatScalar(value);\n if (!text.trim()) return [];\n return [\n {\n index: 0,\n label: baseLabel,\n text,\n meta: resolveScalarContextMeta(policy, args),\n },\n ];\n }\n\n const arrayValue = readRootParamPath(args, arrayParts.arrayPath);\n if (!Array.isArray(arrayValue) || arrayValue.length === 0) return [];\n\n const items = arrayValue\n .map((entry, index) => {\n if (!isRecord(entry)) return null;\n const raw = entry[arrayParts.leafPath];\n const text = typeof raw === 'string' ? raw : formatScalar(raw);\n if (!text.trim()) return null;\n const label =\n arrayValue.length > 1 ? `${baseLabel} (${index + 1}/${arrayValue.length})` : baseLabel;\n return {\n index,\n label,\n text,\n meta: resolveArrayItemMeta(policy, arrayParts.arrayPath, entry, arrayParts.leafPath),\n };\n })\n .filter((item): item is SubmitPathPreviewItem => item != null);\n\n if (items.length > 0) return items;\n\n return [\n {\n index: 0,\n label: baseLabel,\n text: '',\n meta: resolveScalarContextMeta(policy, args),\n },\n ];\n}\n\nexport function readSubmitPathText(\n args: Record<string, unknown>,\n submitPath: string | null | undefined,\n policy?: EditPolicyPublic | null,\n): string {\n if (policy?.submitPath) {\n const items = resolveSubmitPathPreviewItems(args, policy);\n if (items.length === 1) return items[0].text;\n if (items.length > 1) {\n return items.map((item) => item.text).join('\\n\\n');\n }\n }\n if (!submitPath?.trim()) return '';\n const value = readValueAtParamPath(args, submitPath);\n if (typeof value === 'string') return value;\n return '';\n}\n\n/** Server machine preview — JSON dump in markdown, not user-facing copy. */\nexport function isMachineJsonPreview(text: string): boolean {\n const trimmed = text.trim();\n if (!trimmed) return false;\n if (/```json[\\s\\S]*```/i.test(trimmed)) return true;\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n JSON.parse(trimmed);\n return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n","import {\n blocksToText,\n buildEditedPreviewFromText,\n type CoreMessageBlock,\n} from '../chat/message-blocks';\nimport type { WriteDraftEditPayload, WriteDraftPublic } from './write-draft';\nimport { buildConfirmWithEditsFromArguments } from './write-draft';\nimport {\n isMachineJsonPreview,\n resolveSubmitPathPreviewItems,\n} from './param-path';\n\nexport type EditPolicyMode = 'preview_only' | 'allowlisted_fields' | 'full';\n\nexport type EditPolicyFieldRole =\n | 'content'\n | 'identifier'\n | 'scenario'\n | 'enum'\n | 'system';\n\nexport type EditPolicyFieldWidget =\n | 'text'\n | 'textarea'\n | 'select'\n | 'readonly'\n | 'hidden';\n\nexport interface EditPolicyEnumOption {\n label: string;\n value: string;\n}\n\nexport interface EditPolicyField {\n path: string;\n label: string;\n role: EditPolicyFieldRole;\n widget: EditPolicyFieldWidget;\n editable: boolean;\n required: boolean;\n value: unknown;\n enumOptions?: EditPolicyEnumOption[];\n reason?: string | null;\n}\n\nexport interface EditPolicyPublic {\n editMode: EditPolicyMode;\n submitPath?: string | null;\n allowArgumentsPatch: boolean;\n fields: EditPolicyField[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction readRole(value: unknown): EditPolicyFieldRole {\n const raw = readString(value);\n if (\n raw === 'content' ||\n raw === 'identifier' ||\n raw === 'scenario' ||\n raw === 'enum' ||\n raw === 'system'\n ) {\n return raw;\n }\n return 'system';\n}\n\nfunction readWidget(value: unknown): EditPolicyFieldWidget {\n const raw = readString(value);\n if (\n raw === 'text' ||\n raw === 'textarea' ||\n raw === 'select' ||\n raw === 'readonly' ||\n raw === 'hidden'\n ) {\n return raw;\n }\n return 'readonly';\n}\n\nfunction readMode(value: unknown): EditPolicyMode {\n const raw = readString(value);\n if (raw === 'allowlisted_fields' || raw === 'full') return raw;\n return 'preview_only';\n}\n\nfunction parseEnumOptions(value: unknown): EditPolicyEnumOption[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const options = value\n .map((item) => {\n if (!isRecord(item)) return null;\n const label = readString(item.label);\n const optionValue = readString(item.value);\n if (!label || optionValue == null) return null;\n return { label, value: optionValue };\n })\n .filter((item): item is EditPolicyEnumOption => item != null);\n return options.length > 0 ? options : undefined;\n}\n\nfunction parseField(row: unknown): EditPolicyField | null {\n if (!isRecord(row)) return null;\n const path = readString(row.path);\n const label = readString(row.label) ?? path;\n if (!path || !label) return null;\n return {\n path,\n label,\n role: readRole(row.role),\n widget: readWidget(row.widget),\n editable: row.editable === true,\n required: row.required === true,\n value: row.value,\n enumOptions: parseEnumOptions(row.enumOptions),\n reason: typeof row.reason === 'string' ? row.reason : null,\n };\n}\n\n/** Parse server `editPolicy` (SSE / run-state / approval). */\nexport function parseEditPolicyPublic(value: unknown): EditPolicyPublic | null {\n if (!isRecord(value)) return null;\n const fieldsRaw = Array.isArray(value.fields) ? value.fields : [];\n const fields = fieldsRaw\n .map((row) => parseField(row))\n .filter((field): field is EditPolicyField => field != null);\n return {\n editMode: readMode(value.editMode),\n submitPath: readString(value.submitPath) ?? null,\n allowArgumentsPatch: value.allowArgumentsPatch === true,\n fields,\n };\n}\n\nfunction inferWidgetForValue(value: unknown): EditPolicyFieldWidget {\n if (typeof value === 'string' && value.length > 80) return 'textarea';\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return 'text';\n }\n return 'readonly';\n}\n\nfunction inferSubmitPathFromArguments(args: Record<string, unknown>): string | null {\n for (const [key, value] of Object.entries(args)) {\n if (typeof value === 'string' && value.trim()) return key;\n if (Array.isArray(value) && value.length > 0 && isRecord(value[0])) {\n for (const [leaf, leafValue] of Object.entries(value[0])) {\n if (typeof leafValue === 'string' && leafValue.trim()) {\n return `${key}[].${leaf}`;\n }\n }\n }\n }\n const firstKey = Object.keys(args)[0];\n return firstKey ?? null;\n}\n\n/** Fallback when the server omits `editPolicy` (legacy payloads). */\nexport function deriveEditPolicyFromDraft(draft: WriteDraftPublic): EditPolicyPublic {\n const submitPath = inferSubmitPathFromArguments(draft.arguments);\n const previewBlocks = draft.presentation.previewBlocks;\n if (previewBlocks.length > 0) {\n return {\n editMode: 'preview_only',\n submitPath,\n allowArgumentsPatch: false,\n fields: Object.entries(draft.arguments).map(([path, value]) => ({\n path,\n label: path,\n role: path === submitPath ? 'content' : 'system',\n widget: 'readonly',\n editable: false,\n required: false,\n value,\n })),\n };\n }\n\n return {\n editMode: 'allowlisted_fields',\n submitPath: null,\n allowArgumentsPatch: true,\n fields: Object.entries(draft.arguments).map(([path, value]) => ({\n path,\n label: path,\n role: path === submitPath ? 'content' : 'system',\n widget: inferWidgetForValue(value),\n editable: inferWidgetForValue(value) !== 'readonly',\n required: false,\n value,\n })),\n };\n}\n\nexport function resolveEditPolicy(\n writeDraft: WriteDraftPublic | null | undefined,\n editPolicy: EditPolicyPublic | null | undefined,\n): EditPolicyPublic | null {\n if (editPolicy) return editPolicy;\n if (writeDraft) return deriveEditPolicyFromDraft(writeDraft);\n return null;\n}\n\nexport function visibleEditPolicyFields(policy: EditPolicyPublic): EditPolicyField[] {\n if (policy.editMode === 'preview_only') {\n return [];\n }\n return policy.fields.filter((field) => field.widget !== 'hidden');\n}\n\nexport function editableEditPolicyFields(policy: EditPolicyPublic): EditPolicyField[] {\n return policy.fields.filter((field) => field.editable && field.widget !== 'hidden');\n}\n\nexport function resolveSubmitPathFieldLabel(policy: EditPolicyPublic): string | null {\n if (!policy.submitPath) return null;\n const field = policy.fields.find((row) => row.path === policy.submitPath);\n return field?.label?.trim() || null;\n}\n\nexport function canEditDraftReview(\n writeDraft: WriteDraftPublic | null | undefined,\n editPolicy: EditPolicyPublic | null | undefined,\n): boolean {\n const policy = resolveEditPolicy(writeDraft, editPolicy);\n if (!policy || !writeDraft) return false;\n if (policy.editMode === 'preview_only') {\n const items = resolveSubmitPathPreviewItems(writeDraft.arguments, policy);\n if (items.length === 1 && items[0].text.trim()) return true;\n if (items.length > 1) return false;\n const fromBlocks = blocksToText(writeDraft.presentation.previewBlocks as CoreMessageBlock[]);\n if (fromBlocks && !isMachineJsonPreview(fromBlocks)) {\n return true;\n }\n return editableEditPolicyFields(policy).length > 0;\n }\n return editableEditPolicyFields(policy).length > 0;\n}\n\nexport function initialPreviewEditorText(\n writeDraft: WriteDraftPublic,\n policy: EditPolicyPublic | null,\n): string {\n if (policy?.submitPath) {\n const items = resolveSubmitPathPreviewItems(writeDraft.arguments, policy);\n if (items.length === 1) return items[0].text;\n if (items.length > 1) {\n return items.map((item) => item.text).join('\\n\\n');\n }\n }\n\n const blocks = writeDraft.presentation.previewBlocks as CoreMessageBlock[];\n const fromBlocks = blocksToText(blocks);\n if (fromBlocks && !isMachineJsonPreview(fromBlocks)) {\n return fromBlocks;\n }\n\n const stringField = policy?.fields.find(\n (field) =>\n field.path === policy.submitPath &&\n typeof field.value === 'string' &&\n field.value.trim(),\n );\n if (stringField && typeof stringField.value === 'string') {\n return stringField.value;\n }\n\n return '';\n}\n\nexport function draftReviewHasEdits(\n writeDraft: WriteDraftPublic,\n policy: EditPolicyPublic | null,\n editedPreviewText: string,\n editedArgs: Record<string, unknown>,\n): boolean {\n const resolved = resolveEditPolicy(writeDraft, policy)!;\n const baselinePreview = initialPreviewEditorText(writeDraft, resolved);\n const previewChanged = editedPreviewText.trim() !== baselinePreview.trim();\n const argsChanged =\n JSON.stringify(editedArgs) !== JSON.stringify(writeDraft.arguments);\n\n if (resolved.editMode === 'preview_only') {\n return previewChanged && editedPreviewText.trim().length > 0;\n }\n if (resolved.editMode === 'full') {\n return argsChanged;\n }\n return previewChanged || argsChanged;\n}\n\n/** Build `writeGate` / `decision` payload from policy-aware editor state. */\nexport function buildDraftReviewDecisionPayload(\n writeDraft: WriteDraftPublic,\n editPolicy: EditPolicyPublic | null | undefined,\n input: {\n editedPreviewText: string;\n editedArgs: Record<string, unknown>;\n },\n): WriteDraftEditPayload {\n const policy = resolveEditPolicy(writeDraft, editPolicy)!;\n const previewBlocks = writeDraft.presentation.previewBlocks as CoreMessageBlock[];\n const baselinePreview = initialPreviewEditorText(writeDraft, policy);\n const previewChanged = input.editedPreviewText.trim() !== baselinePreview.trim();\n\n if (policy.editMode === 'preview_only') {\n const previewBlocks = writeDraft.presentation.previewBlocks as CoreMessageBlock[];\n const serialized = buildEditedPreviewFromText(input.editedPreviewText, previewBlocks);\n if (isMachineJsonPreview(blocksToText(previewBlocks))) {\n return {\n editedPreviewSerialized: buildEditedPreviewFromText(input.editedPreviewText),\n };\n }\n return { editedPreviewSerialized: serialized };\n }\n\n const patchPayload = buildConfirmWithEditsFromArguments(\n writeDraft.arguments,\n input.editedArgs,\n );\n const payload: WriteDraftEditPayload = {};\n\n if (policy.editMode === 'full' || policy.allowArgumentsPatch) {\n const editablePaths = new Set(\n editableEditPolicyFields(policy).map((field) => field.path),\n );\n const filteredPatch: Record<string, unknown> = {};\n const patch = patchPayload.editedPendingWriteArguments ?? {};\n for (const [key, value] of Object.entries(patch)) {\n if (editablePaths.has(key)) {\n filteredPatch[key] = value;\n }\n }\n if (Object.keys(filteredPatch).length > 0) {\n payload.editedPendingWriteArguments = filteredPatch;\n } else if (policy.editMode === 'full') {\n payload.editedPendingWriteArguments = patch;\n }\n }\n\n if (policy.editMode === 'allowlisted_fields' && previewChanged) {\n payload.editedPreviewSerialized = buildEditedPreviewFromText(\n input.editedPreviewText,\n previewBlocks,\n );\n }\n\n return payload;\n}\n\nexport type DraftReviewGateErrorCode =\n | 'EDITED_LOCKED_FIELD'\n | 'EDITED_FIELD_NOT_ALLOWED'\n | 'EDITED_WRITE_ARGS_INVALID'\n | 'MULTI_WRITE_EDIT_NOT_SUPPORTED';\n\nexport function isDraftReviewGateErrorCode(\n code: string | undefined,\n): code is DraftReviewGateErrorCode {\n return (\n code === 'EDITED_LOCKED_FIELD' ||\n code === 'EDITED_FIELD_NOT_ALLOWED' ||\n code === 'EDITED_WRITE_ARGS_INVALID' ||\n code === 'MULTI_WRITE_EDIT_NOT_SUPPORTED'\n );\n}\n","import {\n initialPreviewEditorText,\n parseEditPolicyPublic,\n resolveEditPolicy,\n type EditPolicyPublic,\n} from './edit-policy';\nimport {\n cloneWriteDraftArguments,\n parseWriteDraftPublic,\n type WriteDraftPublic,\n} from './write-draft';\n\nexport interface DraftReviewBundle {\n writeDraft: WriteDraftPublic;\n editPolicy: EditPolicyPublic | null;\n}\n\nexport interface DraftReviewEditorState {\n editedPreviewText: string;\n editedArgs: Record<string, unknown>;\n}\n\nfunction parseWriteDraftList(value: unknown): WriteDraftPublic[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((row) => parseWriteDraftPublic(row))\n .filter((draft): draft is WriteDraftPublic => draft != null);\n}\n\nfunction parseEditPolicyList(value: unknown): EditPolicyPublic[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((row) => parseEditPolicyPublic(row))\n .filter((policy): policy is EditPolicyPublic => policy != null);\n}\n\n/** Pair `writeDraft(s)` with `editPolicy(ies)` from server payloads (legacy + multi-write). */\nexport function parseDraftReviewBundles(input: {\n writeDraft?: WriteDraftPublic | null;\n writeDrafts?: unknown;\n editPolicy?: EditPolicyPublic | null;\n editPolicies?: unknown;\n}): DraftReviewBundle[] {\n const fromArray = parseWriteDraftList(input.writeDrafts);\n if (fromArray.length > 0) {\n const policies = parseEditPolicyList(input.editPolicies);\n const fallbackPolicy = input.editPolicy ?? null;\n return fromArray.map((writeDraft, index) => ({\n writeDraft,\n editPolicy: policies[index] ?? fallbackPolicy,\n }));\n }\n\n const single =\n input.writeDraft ?? parseWriteDraftPublic(input.writeDraft);\n if (!single) return [];\n\n return [{ writeDraft: single, editPolicy: input.editPolicy ?? null }];\n}\n\nexport function buildDraftReviewEditorStates(\n bundles: DraftReviewBundle[],\n): DraftReviewEditorState[] {\n return bundles.map((bundle) => {\n const policy = resolveEditPolicy(bundle.writeDraft, bundle.editPolicy);\n return {\n editedPreviewText: initialPreviewEditorText(bundle.writeDraft, policy),\n editedArgs: cloneWriteDraftArguments(bundle.writeDraft),\n };\n });\n}\n\nexport function draftReviewBundleLabel(bundle: DraftReviewBundle, index: number): string {\n const name = bundle.writeDraft.tool.name?.trim();\n if (name) return name;\n return `Draft ${index + 1}`;\n}\n","import type { AgentChatPageContext, ChatSkillSummary, QueryClientSkillByAgent } from '../../types';\n\n/**\n * Build `GET /agent/:agentId/skills/client` query.\n * When `pageContext.page` is set, passes `?page=` so the list matches runtime skill selection.\n */\nexport function buildClientSkillListQuery(\n skillListQuery: QueryClientSkillByAgent | undefined,\n pageContext: AgentChatPageContext | null | undefined,\n): QueryClientSkillByAgent | undefined {\n const query: QueryClientSkillByAgent = { ...skillListQuery };\n const scope = pageContext?.page?.trim();\n if (scope) {\n query.page = scope;\n }\n return Object.keys(query).length > 0 ? query : undefined;\n}\n\n/**\n * Default skill when the server returns exactly one `pageMatched` item (page-scoped list).\n * Returns `undefined` when there is no unique page-bound skill — caller should not preselect.\n */\nexport function resolveDefaultSkillId(skills: ChatSkillSummary[]): string | undefined {\n const pageBound = skills.filter((skill) => skill.pageMatched === true);\n if (pageBound.length === 1) {\n return pageBound[0]!.id;\n }\n return undefined;\n}\n\n/** Whether the skill list was fetched with a page filter (`pageMatched` present). */\nexport function skillListHasPageFilter(skills: ChatSkillSummary[]): boolean {\n return skills.some((skill) => skill.pageMatched !== undefined);\n}\n","import type { AgentChatRouteContext } from '../../types';\n\nexport function readWindowRouteContext(): AgentChatRouteContext {\n if (typeof window === 'undefined') return {};\n const routePath = window.location.pathname || undefined;\n const routeParams: Record<string, string> = {};\n const search = new URLSearchParams(window.location.search);\n search.forEach((value, key) => {\n routeParams[key] = value;\n });\n return {\n routePath,\n routeParams: Object.keys(routeParams).length > 0 ? routeParams : undefined,\n };\n}\n\nexport function mergeRouteContext(\n base: AgentChatRouteContext,\n override?: AgentChatRouteContext | null,\n): AgentChatRouteContext {\n if (!override) return base;\n const routeParams = {\n ...(base.routeParams ?? {}),\n ...(override.routeParams ?? {}),\n };\n return {\n routePath: override.routePath ?? base.routePath,\n routeParams: Object.keys(routeParams).length > 0 ? routeParams : undefined,\n };\n}\n\nexport function isRouteContextEmpty(ctx: AgentChatRouteContext | null | undefined): boolean {\n if (!ctx) return true;\n return !(ctx.routePath || (ctx.routeParams && Object.keys(ctx.routeParams).length > 0));\n}\n","import type { BrainClarifyCandidate, BrainClarifyPayload, EntityCommit } from '../../types';\n\nexport const BRAIN_ASK_USER_ERROR_CODE = 'BRAIN_ASK_USER';\nexport const BRAIN_CLARIFY_NODE_OUTPUT_KEY = 'brain:clarify';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction parseCandidate(value: unknown): BrainClarifyCandidate | null {\n if (!isRecord(value)) return null;\n const id = readString(value.id);\n const entityType = readString(value.entityType);\n if (!id || !entityType) return null;\n const candidate: BrainClarifyCandidate = { id, entityType };\n const text = readString(value.text);\n if (text) candidate.text = text;\n if (isRecord(value.fields)) candidate.fields = value.fields;\n const source = readString(value.source);\n if (source) candidate.source = source;\n const path = readString(value.path);\n if (path) candidate.path = path;\n return candidate;\n}\n\n/** Parse `brainClarify` from SSE / GET detail / run steps. */\nexport function parseBrainClarifyPayload(value: unknown): BrainClarifyPayload | null {\n if (!isRecord(value)) return null;\n if (value.kind !== 'entity_resolve') return null;\n const question = readString(value.question);\n const entityType = readString(value.entityType);\n if (!question || !entityType) return null;\n if (!Array.isArray(value.candidates)) return null;\n\n const candidates = value.candidates\n .map((row) => parseCandidate(row))\n .filter((row): row is BrainClarifyCandidate => row != null);\n if (candidates.length === 0) return null;\n\n const commitHintEntity =\n isRecord(value.commitHint) && readString(value.commitHint.entityType)\n ? readString(value.commitHint.entityType)!\n : entityType;\n\n return {\n kind: 'entity_resolve',\n question,\n reason: readString(value.reason) ?? '',\n entityType,\n candidates,\n commitHint: { entityType: commitHintEntity },\n proposalType: readString(value.proposalType) ?? '',\n };\n}\n\nexport function isBrainAskUserErrorCode(errorCode: string | null | undefined): boolean {\n return errorCode?.trim() === BRAIN_ASK_USER_ERROR_CODE;\n}\n\nexport function buildEntityCommit(\n clarify: BrainClarifyPayload,\n selectedId: string,\n): EntityCommit {\n return {\n entityType: clarify.commitHint.entityType || clarify.entityType,\n selectedId: selectedId.trim(),\n };\n}\n\nexport function formatBrainClarifyCandidateLabel(candidate: BrainClarifyCandidate): string {\n const text = candidate.text?.trim();\n if (text) return text;\n if (candidate.fields && Object.keys(candidate.fields).length > 0) {\n try {\n return JSON.stringify(candidate.fields).slice(0, 80);\n } catch {\n /* ignore */\n }\n }\n return candidate.id;\n}\n\n/**\n * Extract `brainClarify` from AgentRun steps (Chat) or PageAction timeline-like steps.\n * Mirrors server `extractBrainClarifyFromRunSteps`.\n */\nexport function extractBrainClarifyFromRunSteps(input: {\n steps?: unknown;\n nodeOutputs?: Record<string, unknown> | null;\n errorCode?: string | null;\n}): BrainClarifyPayload | null {\n if (\n input.errorCode &&\n !isBrainAskUserErrorCode(input.errorCode) &&\n input.errorCode.trim().length > 0\n ) {\n return null;\n }\n\n if (Array.isArray(input.steps)) {\n for (let i = input.steps.length - 1; i >= 0; i -= 1) {\n const step = input.steps[i];\n if (!isRecord(step)) continue;\n const name = typeof step.name === 'string' ? step.name : '';\n if (\n name === 'runtime:brain_clarify' ||\n name === 'brain_clarify' ||\n name.endsWith(':brain_clarify')\n ) {\n const fromDetail = parseBrainClarifyPayload(step.detail);\n if (fromDetail) return fromDetail;\n const fromOutput = parseBrainClarifyPayload(step.output);\n if (fromOutput) return fromOutput;\n }\n const detail = isRecord(step.detail)\n ? step.detail\n : isRecord(step.output)\n ? step.output\n : null;\n if (name.includes('brain_blocked') && detail) {\n const nested = parseBrainClarifyPayload(detail.brainClarify);\n if (nested) return nested;\n }\n }\n }\n\n const outputs = input.nodeOutputs;\n if (outputs) {\n const fromKey = parseBrainClarifyPayload(outputs[BRAIN_CLARIFY_NODE_OUTPUT_KEY]);\n if (fromKey) return fromKey;\n }\n\n return null;\n}\n","import type {\n ApprovalEntityReference,\n ApprovalEntityReferenceDisplayField,\n ApprovalEntityReferenceInlineRecord,\n ApprovalEntityReferenceSource,\n} from '../../types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction readNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n return null;\n}\n\nfunction stringifyDisplayValue(value: unknown): string | null {\n if (value == null) return null;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return null;\n}\n\nfunction parseDisplayField(value: unknown): ApprovalEntityReferenceDisplayField | null {\n if (!isRecord(value)) return null;\n const key = readString(value.key);\n const label = readString(value.label);\n const fieldValue = stringifyDisplayValue(value.value);\n if (!key || !label || fieldValue == null) return null;\n return { key, label, value: fieldValue };\n}\n\nfunction parseDisplayFields(value: unknown): ApprovalEntityReferenceDisplayField[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((row) => parseDisplayField(row))\n .filter((row): row is ApprovalEntityReferenceDisplayField => row != null);\n}\n\nfunction parseStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const urls: string[] = [];\n for (const entry of value) {\n const url = readString(entry);\n if (url) urls.push(url);\n }\n return urls;\n}\n\nfunction legacySourceTitle(\n value: Record<string, unknown>,\n ref: string,\n action: string,\n): string {\n const toolName = readString(value.toolName);\n if (action === 'fetch_data') return toolName ?? ref;\n if (action === 'load_page_context') return 'load_page_context';\n if (action === 'summarize_images') return 'summarize_images';\n return toolName ?? (action || ref);\n}\n\nfunction parseInlineRecord(value: unknown): ApprovalEntityReferenceInlineRecord | null {\n if (!isRecord(value)) return null;\n const kind = readString(value.kind);\n if (!kind) return null;\n\n const title = readString(value.title) ?? kind;\n const hasProjectionFields = Array.isArray(value.fields);\n const legacyRecord = isRecord(value.record) ? value.record : null;\n\n if (!hasProjectionFields && legacyRecord) {\n return {\n kind,\n title,\n fields: [],\n imageUrls: [],\n legacyRecord,\n };\n }\n\n return {\n kind,\n title,\n fields: parseDisplayFields(value.fields),\n imageUrls: parseStringArray(value.imageUrls),\n };\n}\n\nfunction parseSource(value: unknown): ApprovalEntityReferenceSource | null {\n if (!isRecord(value)) return null;\n const ref = readString(value.ref);\n const action = readString(value.action);\n if (!ref || !action) return null;\n\n const fields = parseDisplayFields(value.fields);\n const imageUrls = parseStringArray(value.imageUrls);\n\n return {\n ref,\n action,\n title: readString(value.title) ?? legacySourceTitle(value, ref, action),\n toolName: readString(value.toolName),\n toolId: readNumber(value.toolId),\n data: value.data,\n fields,\n imageUrls: imageUrls.length > 0 ? imageUrls : undefined,\n };\n}\n\n/** True when snapshot still uses `inlineRecords[].record` (pre-projection). */\nexport function isLegacyEntityReference(\n reference: ApprovalEntityReference | null | undefined,\n): boolean {\n if (!reference) return false;\n if (reference.legacy) return true;\n return reference.inlineRecords.some((row) => row.legacyRecord != null);\n}\n\n/** Parse inbox/detail `entityReference` payload. */\nexport function parseApprovalEntityReference(\n value: unknown,\n): ApprovalEntityReference | null {\n if (!isRecord(value)) return null;\n const inlineRecords = Array.isArray(value.inlineRecords)\n ? value.inlineRecords\n .map((row) => parseInlineRecord(row))\n .filter((row): row is ApprovalEntityReferenceInlineRecord => row != null)\n : [];\n const sources = Array.isArray(value.sources)\n ? value.sources\n .map((row) => parseSource(row))\n .filter((row): row is ApprovalEntityReferenceSource => row != null)\n .sort((left, right) => left.ref.localeCompare(right.ref))\n : [];\n const legacy = inlineRecords.some((row) => row.legacyRecord != null);\n return {\n page: readString(value.page),\n routePath: readString(value.routePath),\n entityType: readString(value.entityType),\n entityId: readString(value.entityId),\n anchorLabel: readString(value.anchorLabel),\n inlineRecords,\n sources,\n legacy: legacy || undefined,\n };\n}\n\nexport function hasEntityReferenceContent(\n reference: ApprovalEntityReference | null | undefined,\n): boolean {\n if (!reference) return false;\n return (\n Boolean(\n reference.anchorLabel ||\n reference.entityType ||\n reference.entityId ||\n reference.page,\n ) ||\n reference.inlineRecords.length > 0 ||\n reference.sources.length > 0\n );\n}\n\n/** Header anchor line — prefers server `anchorLabel`. */\nexport function formatEntityReferenceAnchor(\n reference: ApprovalEntityReference,\n): string | null {\n if (reference.anchorLabel) {\n return reference.page\n ? `${reference.anchorLabel} · ${reference.page}`\n : reference.anchorLabel;\n }\n\n const parts: string[] = [];\n if (reference.entityType && reference.entityId) {\n parts.push(`${reference.entityType} #${reference.entityId}`);\n } else if (reference.entityType) {\n parts.push(reference.entityType);\n } else if (reference.entityId) {\n parts.push(`#${reference.entityId}`);\n }\n if (reference.page) {\n parts.push(reference.page);\n }\n return parts.length > 0 ? parts.join(' · ') : null;\n}\n\nexport function formatEntityReferenceListHint(\n reference: ApprovalEntityReference | null | undefined,\n): string | null {\n if (!reference) return null;\n return formatEntityReferenceAnchor(reference);\n}\n\nconst ENTITY_KIND_TITLE_KEYS = {\n review: 'approval.entityKindReview',\n order: 'approval.entityKindOrder',\n comment: 'approval.entityKindComment',\n} as const;\n\ntype EntityKindTitleKey = (typeof ENTITY_KIND_TITLE_KEYS)[keyof typeof ENTITY_KIND_TITLE_KEYS];\n\n/** i18n key for a known inline `kind`, or null to use `title`. */\nexport function entityKindTitleKey(kind: string): EntityKindTitleKey | null {\n return ENTITY_KIND_TITLE_KEYS[kind.trim().toLowerCase() as keyof typeof ENTITY_KIND_TITLE_KEYS] ?? null;\n}\n\nexport function readInlineRecordContent(record: Record<string, unknown>): string | null {\n const content = record.content;\n if (typeof content === 'string' && content.trim()) return content.trim();\n if (typeof content === 'number' || typeof content === 'boolean') {\n return String(content);\n }\n return null;\n}\n\nexport function listInlineRecordExtraFields(\n record: Record<string, unknown>,\n): Array<{ key: string; value: string }> {\n const rows: Array<{ key: string; value: string }> = [];\n for (const [key, value] of Object.entries(record)) {\n if (key === 'content' || key === 'images') continue;\n if (value == null) continue;\n if (typeof value === 'string' && !value.trim()) continue;\n if (Array.isArray(value)) continue;\n const text =\n typeof value === 'string'\n ? value.trim()\n : typeof value === 'number' || typeof value === 'boolean'\n ? String(value)\n : JSON.stringify(value, null, 2);\n rows.push({ key, value: text });\n }\n return rows;\n}\n\nexport function listLegacyInlineImageUrls(record: Record<string, unknown>): string[] {\n const images = record.images;\n if (!Array.isArray(images)) return [];\n const urls: string[] = [];\n for (const image of images) {\n if (typeof image === 'string') {\n const url = readString(image);\n if (url) urls.push(url);\n continue;\n }\n if (isRecord(image)) {\n const url = readString(image.url);\n if (url) urls.push(url);\n }\n }\n return urls;\n}\n\nexport function formatEntityDataPreview(value: unknown): string {\n if (value == null) return '—';\n if (typeof value === 'string') return value.trim() || '—';\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nexport function hasProjectedSourceBody(source: ApprovalEntityReferenceSource): boolean {\n return source.fields.length > 0 || Boolean(source.imageUrls?.length);\n}\n","import type {\n ApprovalConfirmResult,\n ApprovalDetail,\n ApprovalDraftReviewBudget,\n ApprovalInboxItem,\n ApprovalInboxList,\n ApprovalInitiator,\n ApprovalPendingWritePreview,\n ApprovalDecideResult,\n ApprovalRejectResult,\n ApprovalSource,\n ApprovalStatus,\n} from '../../types';\nimport { parseWriteDraftPublic } from '../draft-review/write-draft';\nimport { parseEditPolicyPublic } from '../draft-review/edit-policy';\nimport { parseDraftReviewBundles } from '../draft-review/draft-review-bundle';\nimport { parseApprovalEntityReference } from './entity-reference';\nimport type { CoreMessageBlock } from '../chat/message-blocks';\nimport { parseStoredBlocks } from '../chat/message-blocks';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction readNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n}\n\nfunction readApprovalSource(value: unknown): ApprovalSource | undefined {\n const raw = readString(value);\n if (raw === 'chat' || raw === 'page_action' || raw === 'webhook') return raw;\n return undefined;\n}\n\nfunction readApprovalStatus(value: unknown): ApprovalStatus | undefined {\n const raw = readString(value);\n if (\n raw === 'pending' ||\n raw === 'approved' ||\n raw === 'rejected' ||\n raw === 'cancelled' ||\n raw === 'expired'\n ) {\n return raw;\n }\n return undefined;\n}\n\nfunction parseInitiator(value: unknown): ApprovalInitiator | null {\n if (!isRecord(value)) return null;\n const id = readNumber(value.id);\n if (id == null) return null;\n return {\n id,\n username: readString(value.username) ?? null,\n employeeId: readString(value.employeeId) ?? null,\n };\n}\n\nfunction parseDraftReview(value: unknown): ApprovalDraftReviewBudget | null {\n if (!isRecord(value)) return null;\n const retryCount = readNumber(value.retryCount) ?? 0;\n const retryMax = value.retryMax === null ? null : (readNumber(value.retryMax) ?? null);\n return {\n retryCount,\n retryMax,\n canRetry:\n value.canRetry === false\n ? false\n : value.canRetry === true\n ? true\n : retryMax == null\n ? true\n : retryCount < retryMax,\n };\n}\n\nfunction parsePreviewBlocks(value: unknown): CoreMessageBlock[] | undefined {\n if (value == null) return undefined;\n if (typeof value === 'string') return parseStoredBlocks(value);\n if (isRecord(value) && Array.isArray(value.blocks)) {\n return value.blocks.filter(\n (item): item is CoreMessageBlock =>\n isRecord(item) && typeof item.type === 'string',\n );\n }\n if (Array.isArray(value)) {\n return value.filter(\n (item): item is CoreMessageBlock =>\n isRecord(item) && typeof item.type === 'string',\n );\n }\n return undefined;\n}\n\n/** Parse inbox `previewBlocks` into renderable blocks. */\nexport function parseApprovalPreviewBlocks(value: unknown): CoreMessageBlock[] | undefined {\n return parsePreviewBlocks(value);\n}\n\nfunction parsePendingWrite(value: unknown): ApprovalPendingWritePreview | null {\n if (!isRecord(value)) return null;\n const tool = readString(value.tool);\n if (!tool) return null;\n const riskLevel = readString(value.riskLevel) ?? 'L2';\n return { tool, riskLevel };\n}\n\nfunction parseInboxItem(row: unknown): ApprovalInboxItem | null {\n if (!isRecord(row)) return null;\n const id = readNumber(row.id);\n const source = readApprovalSource(row.source);\n const status = readApprovalStatus(row.status);\n const title = readString(row.title);\n const createdAt = readString(row.createdAt);\n if (id == null || !source || !status || !title || !createdAt) {\n return null;\n }\n const bundles = parseDraftReviewBundles({\n writeDraft: parseWriteDraftPublic(row.writeDraft),\n writeDrafts: row.writeDrafts,\n editPolicy: parseEditPolicyPublic(row.editPolicy),\n editPolicies: row.editPolicies,\n });\n const primary = bundles[0];\n return {\n id,\n source,\n status,\n title,\n summary: readString(row.summary) ?? null,\n workflowId: readNumber(row.workflowId) ?? 0,\n workflowVersion: readNumber(row.workflowVersion) ?? 0,\n workflowKey: readString(row.workflowKey) ?? null,\n workflowName: readString(row.workflowName) ?? null,\n nodeId: readString(row.nodeId) ?? '',\n sessionId: readString(row.sessionId) ?? null,\n pageActionRunId: readNumber(row.pageActionRunId) ?? null,\n initiator: parseInitiator(row.initiator),\n createdAt,\n decidedAt: readString(row.decidedAt) ?? null,\n previewBlocks: row.previewBlocks ?? null,\n pendingWrite: parsePendingWrite(row.pendingWrite),\n writeDraft: primary?.writeDraft ?? null,\n editPolicy: primary?.editPolicy ?? null,\n writeDrafts: bundles.length > 1 ? bundles.map((bundle) => bundle.writeDraft) : null,\n editPolicies: bundles.length > 1 ? bundles.map((bundle) => bundle.editPolicy) : null,\n draftReview: parseDraftReview(row.draftReview),\n entityReference: parseApprovalEntityReference(row.entityReference),\n };\n}\n\n/** Parse `GET /approval/inbox` body. */\nexport function parseApprovalInboxList(\n body: unknown,\n limit = 50,\n): ApprovalInboxList {\n const record = isRecord(body) ? body : null;\n const itemsRaw = Array.isArray(record?.items) ? record.items : [];\n const items = itemsRaw\n .map((row) => parseInboxItem(row))\n .filter((row): row is ApprovalInboxItem => row != null)\n .filter((row) => row.source !== 'chat');\n return { items, hasMore: items.length >= limit };\n}\n\n/** Parse `GET /approval/:id` body. */\nexport function parseApprovalDetail(body: unknown): ApprovalDetail | null {\n const item = parseInboxItem(body);\n if (!item) return null;\n return { ...item, decidedAt: item.decidedAt ?? null };\n}\n\n/** Parse `POST /approval/:id/confirm` or `decide` body. */\nexport function parseApprovalConfirmResult(body: unknown): ApprovalConfirmResult {\n const record = isRecord(body) ? body : null;\n return {\n resumed: record?.resumed === true,\n suspended: record?.suspended === true ? true : undefined,\n };\n}\n\n/** Parse `POST /approval/:id/decide` body. */\nexport function parseApprovalDecideResult(body: unknown): ApprovalDecideResult {\n return parseApprovalConfirmResult(body);\n}\n\n/** Parse `POST /approval/:id/reject` body. */\nexport function parseApprovalRejectResult(body: unknown): ApprovalRejectResult {\n const record = isRecord(body) ? body : null;\n return { ok: record?.ok === true };\n}\n","/** Database-assigned message ids used by feedback APIs. */\nexport function isPersistedMessageId(id: string): boolean {\n return /^\\d+$/.test(id);\n}\n\nexport function parsePersistedMessageId(id: string): number | null {\n if (!isPersistedMessageId(id)) return null;\n const value = Number(id);\n return Number.isFinite(value) ? value : null;\n}\n\n/** Mirrors backend down-feedback validation. */\nexport function canSubmitDownFeedback(input: {\n reasonTagKeys: string[];\n comment: string;\n}): boolean {\n const tags = input.reasonTagKeys;\n const text = input.comment.trim();\n if (tags.length === 0 && !text) return false;\n if (tags.includes('other') && !text) return false;\n return true;\n}\n","/**\n * PageAction `page_workflow` SSE → button progressLabel + optional narrative timeline.\n * Progress frames only update UI copy; they do not execute HostTool or append prose.\n */\n\nexport type PageWorkflowStageKind = 'planning' | 'gather' | 'produce' | 'other';\n\nexport type PageWorkflowProgressCode =\n | 'planning'\n | 'host_llm_waiting'\n | 'fetch_planning'\n | 'fetch_tools'\n | (string & {});\n\nexport type PageWorkflowPhase =\n | 'start'\n | 'progress'\n | 'complete'\n | 'failed'\n | 'awaiting_approval';\n\n/** Structured storyline item kinds from `page_workflow.narrativeItems`. */\nexport type NarrativeKind = 'stage' | 'thought' | 'evidence' | 'ask' | 'outcome';\n\nexport interface NarrativeField {\n key: string;\n label: string;\n value: string;\n}\n\nexport interface NarrativeItem {\n kind: NarrativeKind;\n /** Language-agnostic key for i18n / branching; `text` is the fallback. */\n code?: string;\n /** Short user-visible copy (server-truncated). */\n text?: string;\n turn?: number;\n /** Brain action: FETCH / PRODUCE / ASK / BOOTSTRAP … */\n actionType?: string;\n title?: string;\n /** Evidence / pagination meta; shape aligns with approval DisplayField. */\n fields?: NarrativeField[];\n /** Observation / tool ref for detail expand (not a business primary key). */\n ref?: string;\n /** `ask`: missing pieces (entity types, honesty gaps, …). */\n missing?: string[];\n}\n\nexport interface PageWorkflowEvent {\n phase: PageWorkflowPhase;\n actionRunId: number;\n actionKey: string;\n generation: number;\n clientActionId?: string | null;\n nodeId: string;\n action?: string | null;\n stageKind?: PageWorkflowStageKind | null;\n stageIndex?: number | null;\n stageTotal?: number | null;\n progress?: PageWorkflowProgressCode | null;\n /** Optional loading string (legacy / Chat); button copy still prefers `stageKind`. */\n narrative?: string | null;\n /** Optional structured storyline batch for this frame. */\n narrativeItems?: NarrativeItem[] | null;\n errorCode?: string | null;\n errorMessage?: string | null;\n}\n\nconst NARRATIVE_KIND_SET = new Set<NarrativeKind>([\n 'stage',\n 'thought',\n 'evidence',\n 'ask',\n 'outcome',\n]);\n\nconst NARRATIVE_TIMELINE_CAP = 80;\n\nconst ACTION_TO_STAGE: Record<string, PageWorkflowStageKind> = {\n fetch_data: 'gather',\n detect_clues: 'gather',\n summarize_images: 'gather',\n generate_and_push: 'produce',\n summarize: 'produce',\n compose_mutation: 'produce',\n present_mutation: 'produce',\n write_data: 'produce',\n await_user_confirm: 'other',\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction readNumber(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n\nfunction normalizeStageKind(raw: unknown): PageWorkflowStageKind | null {\n const value = readString(raw);\n if (\n value === 'planning' ||\n value === 'gather' ||\n value === 'produce' ||\n value === 'other'\n ) {\n return value;\n }\n return null;\n}\n\nfunction stageKindFromAction(action: string | null | undefined): PageWorkflowStageKind | null {\n const key = String(action ?? '').trim();\n if (!key) return null;\n return ACTION_TO_STAGE[key] ?? null;\n}\n\nfunction normalizeNarrativeKind(raw: unknown): NarrativeKind | null {\n const value = readString(raw);\n if (value && NARRATIVE_KIND_SET.has(value as NarrativeKind)) {\n return value as NarrativeKind;\n }\n return null;\n}\n\nfunction parseNarrativeField(raw: unknown): NarrativeField | null {\n if (!isRecord(raw)) return null;\n const key = readString(raw.key);\n const label = readString(raw.label);\n const value = readString(raw.value);\n if (!key || !label || value == null) return null;\n return { key, label, value: value ?? '' };\n}\n\nfunction parseNarrativeItem(raw: unknown): NarrativeItem | null {\n if (!isRecord(raw)) return null;\n const kind = normalizeNarrativeKind(raw.kind);\n if (!kind) return null;\n const fieldsRaw = Array.isArray(raw.fields) ? raw.fields : null;\n const fields =\n fieldsRaw == null\n ? undefined\n : fieldsRaw\n .map(parseNarrativeField)\n .filter((field): field is NarrativeField => field != null)\n .slice(0, 12);\n const missingRaw = Array.isArray(raw.missing) ? raw.missing : null;\n const missing =\n missingRaw == null\n ? undefined\n : missingRaw\n .map((entry) => readString(entry))\n .filter((entry): entry is string => Boolean(entry))\n .slice(0, 12);\n const turn = readNumber(raw.turn);\n return {\n kind,\n code: readString(raw.code),\n text: readString(raw.text),\n turn: turn ?? undefined,\n actionType: readString(raw.actionType),\n title: readString(raw.title),\n fields: fields && fields.length > 0 ? fields : undefined,\n ref: readString(raw.ref),\n missing: missing && missing.length > 0 ? missing : undefined,\n };\n}\n\nexport function parseNarrativeItems(raw: unknown): NarrativeItem[] {\n if (!Array.isArray(raw)) return [];\n return raw\n .map(parseNarrativeItem)\n .filter((item): item is NarrativeItem => item != null)\n .slice(0, 8);\n}\n\nfunction narrativeDedupeKey(item: NarrativeItem): string {\n return [\n item.kind,\n item.code ?? '',\n item.ref ?? '',\n item.turn == null ? '' : String(item.turn),\n item.text ?? '',\n item.title ?? '',\n ].join('\\u0001');\n}\n\n/**\n * Append a workflow frame's `narrativeItems` onto the row timeline.\n * Returns the previous array reference when nothing was added.\n */\nexport function appendPageActionNarrativeItems(\n existing: NarrativeItem[] | null | undefined,\n batch: NarrativeItem[] | null | undefined,\n): NarrativeItem[] {\n const prev = existing ?? [];\n const nextBatch = batch ?? [];\n if (nextBatch.length === 0) return prev;\n\n const seen = new Set(prev.map(narrativeDedupeKey));\n const merged = [...prev];\n for (const item of nextBatch) {\n const key = narrativeDedupeKey(item);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(item);\n }\n if (merged.length === prev.length) return prev;\n if (merged.length > NARRATIVE_TIMELINE_CAP) {\n return merged.slice(-NARRATIVE_TIMELINE_CAP);\n }\n return merged;\n}\n\n/** True when the timeline has more than stage ticks — show「查看过程」. */\nexport function shouldOfferNarrativeProcess(\n items: NarrativeItem[] | null | undefined,\n): boolean {\n const list = items ?? [];\n return list.some((item) => item.kind !== 'stage');\n}\n\nexport function countInterestingNarrativeItems(\n items: NarrativeItem[] | null | undefined,\n): number {\n const list = items ?? [];\n return list.filter((item) => item.kind !== 'stage').length;\n}\n\nconst PROTOCOL_FIELD_LABEL_ZH: Record<string, string> = {\n itemCount: '相关条数',\n observationCount: '观测数',\n identity: '标识',\n page: '页码',\n rowCount: '行数',\n fetchedCount: '已获取',\n achieved: '已达成',\n};\n\nconst PROTOCOL_FIELD_LABEL_EN: Record<string, string> = {\n itemCount: 'Items',\n observationCount: 'Observations',\n identity: 'ID',\n page: 'Page',\n rowCount: 'Rows',\n fetchedCount: 'Fetched',\n achieved: 'Achieved',\n};\n\nfunction isZhLocale(locale: string | undefined): boolean {\n const value = String(locale ?? '').toLowerCase();\n return !value || value.startsWith('zh');\n}\n\n/** Humanize protocol / English-fallback field labels for evidence cards. */\nexport function localizeNarrativeFieldLabel(\n field: NarrativeField,\n locale?: string,\n): string {\n const key = field.key.trim();\n const label = field.label.trim();\n const mapped = isZhLocale(locale)\n ? PROTOCOL_FIELD_LABEL_ZH[key]\n : PROTOCOL_FIELD_LABEL_EN[key];\n if (mapped) return mapped;\n // Server sometimes mirrors key as label (identity / itemCount).\n if (label === key && PROTOCOL_FIELD_LABEL_ZH[key]) {\n return isZhLocale(locale)\n ? PROTOCOL_FIELD_LABEL_ZH[key]!\n : PROTOCOL_FIELD_LABEL_EN[key]!;\n }\n return label || key;\n}\n\nexport function isEvidenceSummaryItem(item: NarrativeItem): boolean {\n const code = String(item.code ?? '');\n return (\n item.kind === 'evidence' &&\n (code.endsWith('_summary') ||\n code.endsWith('_empty') ||\n code === 'fetch_summary' ||\n code === 'fetch_empty')\n );\n}\n\nexport function isEvidenceEntityPreviewItem(item: NarrativeItem): boolean {\n const code = String(item.code ?? '');\n return (\n item.kind === 'evidence' &&\n (code.endsWith('_entity_preview') || code === 'fetch_entity_preview')\n );\n}\n\nexport function pickNarrativeHeadline(\n items: NarrativeItem[] | null | undefined,\n): string | null {\n const list = items ?? [];\n const prefer = (kinds: NarrativeKind[]): string | null => {\n for (let i = list.length - 1; i >= 0; i -= 1) {\n const item = list[i]!;\n if (!kinds.includes(item.kind)) continue;\n const text = item.text?.trim() || item.title?.trim();\n if (text) return text;\n }\n return null;\n };\n return (\n prefer(['ask']) ||\n prefer(['outcome']) ||\n prefer(['evidence']) ||\n prefer(['thought']) ||\n null\n );\n}\n\nexport type NarrativeDisplayBlock =\n | { type: 'ask'; item: NarrativeItem }\n | { type: 'thought'; item: NarrativeItem }\n | {\n type: 'evidence-group';\n summary: NarrativeItem | null;\n entities: NarrativeItem[];\n }\n | { type: 'evidence'; item: NarrativeItem }\n | { type: 'outcome'; item: NarrativeItem }\n | { type: 'stage-group'; items: NarrativeItem[] };\n\n/**\n * Build a display list: asks first, outcomes last, stages collapsed,\n * evidence summary + entity previews grouped.\n */\nexport function buildNarrativeDisplayBlocks(\n items: NarrativeItem[] | null | undefined,\n): NarrativeDisplayBlock[] {\n const list = items ?? [];\n const asks = list.filter((item) => item.kind === 'ask');\n const outcomes = list.filter((item) => item.kind === 'outcome');\n const middle = list.filter((item) => item.kind !== 'ask' && item.kind !== 'outcome');\n\n const blocks: NarrativeDisplayBlock[] = asks.map((item) => ({ type: 'ask', item }));\n\n let stageBuf: NarrativeItem[] = [];\n let evidenceSummary: NarrativeItem | null = null;\n let evidenceEntities: NarrativeItem[] = [];\n\n const flushStages = () => {\n if (stageBuf.length === 0) return;\n blocks.push({ type: 'stage-group', items: stageBuf });\n stageBuf = [];\n };\n\n const flushEvidence = () => {\n if (!evidenceSummary && evidenceEntities.length === 0) return;\n if (evidenceSummary || evidenceEntities.length > 0) {\n blocks.push({\n type: 'evidence-group',\n summary: evidenceSummary,\n entities: evidenceEntities,\n });\n }\n evidenceSummary = null;\n evidenceEntities = [];\n };\n\n for (const item of middle) {\n if (item.kind === 'stage') {\n flushEvidence();\n stageBuf.push(item);\n continue;\n }\n flushStages();\n if (item.kind === 'thought') {\n flushEvidence();\n blocks.push({ type: 'thought', item });\n continue;\n }\n if (item.kind === 'evidence') {\n if (isEvidenceSummaryItem(item)) {\n flushEvidence();\n evidenceSummary = item;\n continue;\n }\n if (isEvidenceEntityPreviewItem(item)) {\n evidenceEntities.push(item);\n continue;\n }\n flushEvidence();\n blocks.push({ type: 'evidence', item });\n }\n }\n flushStages();\n flushEvidence();\n\n for (const item of outcomes) {\n blocks.push({ type: 'outcome', item });\n }\n return blocks;\n}\n\nexport function parsePageWorkflowEvent(body: unknown): PageWorkflowEvent | null {\n if (!isRecord(body)) return null;\n const phase = readString(body.phase);\n if (\n phase !== 'start' &&\n phase !== 'progress' &&\n phase !== 'complete' &&\n phase !== 'failed' &&\n phase !== 'awaiting_approval'\n ) {\n return null;\n }\n const actionRunId = readNumber(body.actionRunId);\n const generation = readNumber(body.generation);\n const actionKey = readString(body.actionKey);\n const nodeId = readString(body.nodeId) ?? '';\n if (actionRunId == null || generation == null || !actionKey) {\n return null;\n }\n\n const action = readString(body.action) ?? (body.action === null ? null : undefined);\n const progress = readString(body.progress) ?? null;\n const stageKind =\n normalizeStageKind(body.stageKind) ??\n stageKindFromAction(action ?? null) ??\n stageKindFromProgress(progress);\n const narrative =\n readString(body.narrative) ?? (body.narrative === null ? null : undefined);\n const narrativeItemsRaw = body.narrativeItems;\n const narrativeItems =\n narrativeItemsRaw == null ? null : parseNarrativeItems(narrativeItemsRaw);\n\n return {\n phase,\n actionRunId,\n actionKey,\n generation,\n clientActionId: readString(body.clientActionId) ?? null,\n nodeId,\n action: action === undefined ? undefined : action,\n stageKind,\n stageIndex: readNumber(body.stageIndex),\n stageTotal: readNumber(body.stageTotal),\n progress,\n narrative: narrative === undefined ? undefined : narrative,\n narrativeItems,\n errorCode: readString(body.errorCode),\n errorMessage: readString(body.errorMessage),\n };\n}\n\nfunction stageKindFromProgress(\n progress: string | null | undefined,\n): PageWorkflowStageKind | null {\n const value = String(progress ?? '').trim();\n if (value === 'planning' || value === 'fetch_planning') {\n return 'planning';\n }\n if (value === 'host_llm_waiting' || value === 'fetch_tools') {\n return 'produce';\n }\n // Backend sometimes emits a loose \"fetching\" while gather nodes run.\n if (value === 'fetching' || value === 'fetch_data') {\n return 'gather';\n }\n return null;\n}\n\n/**\n * Button copy uses 1-based `current/total`. Tolerate 0-based `stageIndex`\n * (`0 .. total-1`) from some Brain builds so we never show `0/N`.\n */\nexport function displayPageWorkflowStageIndex(\n stageIndex: number | null | undefined,\n stageTotal: number | null | undefined,\n): number | null {\n if (\n stageIndex == null ||\n stageTotal == null ||\n !Number.isFinite(stageIndex) ||\n !Number.isFinite(stageTotal) ||\n stageTotal <= 1\n ) {\n return null;\n }\n const index = Math.trunc(stageIndex);\n const total = Math.trunc(stageTotal);\n if (total <= 1) return null;\n\n // 0-based: 0 .. total-1 → display 1 .. total\n if (index >= 0 && index < total) {\n // Prefer 1-based when index is already in 1..total (historical contract).\n // Only the `0` frame is unambiguously 0-based; for 1..total-1 keep as-is.\n if (index === 0) return 1;\n return index;\n }\n // 1-based last step: index === total\n if (index === total) return total;\n return null;\n}\n\n/** Default label before the first `page_workflow` frame. */\nexport function defaultPageActionProgressLabel(locale?: string): string {\n return isZhLocale(locale) ? '处理中…' : 'Working…';\n}\n\n/** Soft button label while `reuse-hint` is in flight. */\nexport function pageActionReuseCheckingLabel(locale?: string): string {\n return isZhLocale(locale) ? '查可用结果…' : 'Checking prior results…';\n}\n\n/** Soft tip after reusing an existing successful run (no new invoke). */\nexport function pageActionReusedMessage(locale?: string): string {\n return isZhLocale(locale) ? '已套用已有结果' : 'Applied existing result';\n}\n\n/** Button label while applying a selected historical run (replay). */\nexport function pageActionReusingLabel(locale?: string): string {\n return isZhLocale(locale) ? '套用结果…' : 'Applying result…';\n}\n\n/** Soft button label while Brain clarify popover is open. */\nexport function pageActionAwaitingClarifyLabel(locale?: string): string {\n return isZhLocale(locale) ? '请选择目标…' : 'Pick a target…';\n}\n\n/** Optimistic task-center subtitle while a run is in flight. */\nexport function pageActionTaskRunningSubtitle(locale?: string): string {\n return isZhLocale(locale) ? '正在执行…' : 'Running…';\n}\n\n/** Optimistic task-center subtitle while waiting for inbox approval. */\nexport function pageActionTaskAwaitingApprovalSubtitle(locale?: string): string {\n return isZhLocale(locale) ? '等待审批…' : 'Awaiting approval…';\n}\n\n/** Soft tip when invoke hits an already-running PageAction (local or HTTP 409). */\nexport function pageActionAlreadyRunningTip(locale?: string): string {\n return isZhLocale(locale) ? '当前任务已在执行中' : 'This task is already running';\n}\n\n/** Soft tip when invoke hits a run already waiting for inbox approval. */\nexport function pageActionAlreadyAwaitingApprovalTip(locale?: string): string {\n return isZhLocale(locale)\n ? '该操作正在等待审批,请在审批收件箱处理'\n : 'This action is awaiting approval — open the approval inbox to continue';\n}\n\n/**\n * Map a workflow event to button copy.\n * Returns `null` when the frame should not change the label\n * (`complete` keeps previous; `failed` leaves error to `page_action`).\n */\nexport function resolvePageWorkflowProgressLabel(\n event: PageWorkflowEvent,\n locale?: string,\n): string | null {\n if (event.phase === 'complete') {\n return null;\n }\n if (event.phase === 'failed') {\n return null;\n }\n\n const zh = isZhLocale(locale);\n // Prefer explicit stageKind; fall back via progress code (e.g. planning / host_llm_waiting).\n const kind =\n event.stageKind ??\n stageKindFromProgress(event.progress) ??\n 'other';\n\n if (event.phase === 'awaiting_approval') {\n return zh ? '等待审批…' : 'Waiting for approval…';\n }\n\n if (kind === 'planning') {\n return zh ? '正在规划步骤…' : 'Planning steps…';\n }\n\n if (kind === 'gather') {\n const displayIndex = displayPageWorkflowStageIndex(\n event.stageIndex,\n event.stageTotal,\n );\n if (displayIndex != null && event.stageTotal != null) {\n return zh\n ? `正在收集信息(${displayIndex}/${Math.trunc(event.stageTotal)})…`\n : `Gathering info (${displayIndex}/${Math.trunc(event.stageTotal)})…`;\n }\n return zh ? '正在收集信息…' : 'Gathering info…';\n }\n\n if (kind === 'produce') {\n return zh ? '正在生成结果…' : 'Generating results…';\n }\n\n return zh ? '处理中…' : 'Working…';\n}\n","import type { PageActionSourceRect } from '../../types';\n\nexport const PAGE_ACTION_LAUNCH_FLY_DURATION_MS = 1_100;\nexport const PAGE_ACTION_LAUNCH_LAND_DURATION_MS = 560;\nexport const PAGE_ACTION_LAUNCH_TOAST_DELAY_MS = Math.round(\n PAGE_ACTION_LAUNCH_FLY_DURATION_MS * 0.72,\n);\n\nconst PAGE_ACTION_LAUNCH_FLY_EASING = 'cubic-bezier(0.25, 0.55, 0.35, 1)';\n\nexport function pageActionLaunchCssVarsBlock(): string {\n return `:root {\n --ac-page-action-launch-fly-ms: ${PAGE_ACTION_LAUNCH_FLY_DURATION_MS}ms;\n --ac-page-action-launch-land-ms: ${PAGE_ACTION_LAUNCH_LAND_DURATION_MS}ms;\n}`;\n}\n\nexport function readLaunchSourceRect(\n anchor: HTMLElement | null | undefined,\n): PageActionSourceRect | null {\n if (!anchor || typeof anchor.getBoundingClientRect !== 'function') return null;\n const rect = anchor.getBoundingClientRect();\n if (rect.width <= 0 && rect.height <= 0) return null;\n return {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n}\n\nexport function rectCenter(rect: PageActionSourceRect): { x: number; y: number } {\n return {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n };\n}\n\nconst TASK_CENTER_FLY_TARGET_SELECTORS = [\n '.ai-assistant-bubble',\n '.ai-assistant-automation-task-btn',\n '.ai-assistant-bubble-satellite--task-center',\n] as const;\n\nconst LAUNCH_LAND_PULSE_SELECTORS = [\n '.ai-assistant-bubble',\n '.ai-assistant-automation-task-btn',\n '.ai-assistant-bubble-satellite--task-center',\n] as const;\n\nfunction queryLaunchRoots(hostElement?: HTMLElement | null): Array<Document | ShadowRoot> {\n const roots: Array<Document | ShadowRoot> = [];\n const seen = new Set<Document | ShadowRoot>();\n const addRoot = (root: Document | ShadowRoot | null | undefined) => {\n if (!root || seen.has(root)) return;\n seen.add(root);\n roots.push(root);\n };\n if (typeof document !== 'undefined') addRoot(document);\n if (hostElement) {\n const root = hostElement.getRootNode();\n if (root instanceof ShadowRoot || root instanceof Document) addRoot(root);\n }\n return roots;\n}\n\nfunction queryFirstVisibleElement(\n selectors: readonly string[],\n hostElement?: HTMLElement | null,\n): HTMLElement | null {\n for (const root of queryLaunchRoots(hostElement)) {\n for (const selector of selectors) {\n const el = root.querySelector(selector);\n if (!(el instanceof HTMLElement)) continue;\n const rect = el.getBoundingClientRect();\n if (rect.width > 0 || rect.height > 0) return el;\n }\n }\n return null;\n}\n\n/** Main launcher chat button (visible when the panel is closed). */\nexport function findLauncherBubble(hostElement?: HTMLElement | null): HTMLElement | null {\n return queryFirstVisibleElement(['.ai-assistant-bubble'], hostElement);\n}\n\n/** Resolve fly-to target — prefer the main chat bubble when visible. */\nexport function findTaskCenterTargetRect(\n hostElement?: HTMLElement | null,\n): PageActionSourceRect | null {\n if (typeof document === 'undefined') return null;\n\n const el = queryFirstVisibleElement(TASK_CENTER_FLY_TARGET_SELECTORS, hostElement);\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n if (rect.width <= 0 && rect.height <= 0) return null;\n return {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n}\n\nexport function prefersReducedMotion(): boolean {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return false;\n }\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/** Inline visuals so the orb stays visible when mounted on `document.body`. */\nexport function applyPageActionLaunchOrbStyles(orb: HTMLElement): void {\n Object.assign(orb.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n zIndex: '2147483647',\n width: '14px',\n height: '14px',\n margin: '0',\n borderRadius: '999px',\n pointerEvents: 'none',\n background: 'radial-gradient(circle at 35% 35%, #69b1ff 0%, #1677ff 55%, #0047ce 100%)',\n boxShadow:\n '0 0 0 2px rgba(255, 255, 255, 0.95), 0 4px 14px rgba(22, 119, 255, 0.45)',\n willChange: 'transform, opacity',\n });\n}\n\nfunction pulseElement(el: HTMLElement): void {\n el.classList.add('is-launch-landed');\n window.setTimeout(\n () => el.classList.remove('is-launch-landed'),\n PAGE_ACTION_LAUNCH_LAND_DURATION_MS + 80,\n );\n}\n\nfunction pulseLaunchTargets(hostElement?: HTMLElement | null): void {\n if (typeof document === 'undefined') return;\n\n const pulsed = new Set<HTMLElement>();\n for (const root of queryLaunchRoots(hostElement)) {\n for (const selector of LAUNCH_LAND_PULSE_SELECTORS) {\n const el = root.querySelector(selector);\n if (!(el instanceof HTMLElement) || pulsed.has(el)) continue;\n const rect = el.getBoundingClientRect();\n if (rect.width <= 0 && rect.height <= 0) continue;\n pulsed.add(el);\n pulseElement(el);\n }\n }\n}\n\n/** Spin ring on the launcher bubble — same visual as background chat reply. */\nfunction startLauncherReceivingAnimation(hostElement?: HTMLElement | null): void {\n const bubble = findLauncherBubble(hostElement);\n if (!bubble) return;\n bubble.classList.add('is-launch-receiving');\n window.setTimeout(\n () => bubble.classList.remove('is-launch-receiving'),\n PAGE_ACTION_LAUNCH_FLY_DURATION_MS + PAGE_ACTION_LAUNCH_LAND_DURATION_MS,\n );\n}\n\nfunction rippleLaunchAnchor(anchor: HTMLElement | null | undefined): void {\n if (!(anchor instanceof HTMLElement)) return;\n anchor.classList.add('ac-page-action-trigger', 'is-launched');\n window.setTimeout(() => anchor.classList.remove('is-launched'), PAGE_ACTION_LAUNCH_FLY_DURATION_MS);\n}\n\nfunction flyLaunchOrb(\n from: PageActionSourceRect,\n to: PageActionSourceRect,\n onComplete: () => void,\n): void {\n if (typeof document === 'undefined') return;\n\n const start = rectCenter(from);\n const end = rectCenter(to);\n const arcLift = Math.min(72, Math.max(36, Math.abs(end.x - start.x) * 0.22));\n const mid = {\n x: (start.x + end.x) / 2,\n y: Math.min(start.y, end.y) - arcLift,\n };\n\n const orb = document.createElement('div');\n orb.className = 'page-action-launch-orb';\n orb.setAttribute('aria-hidden', 'true');\n applyPageActionLaunchOrbStyles(orb);\n document.body.appendChild(orb);\n\n const keyframes: Keyframe[] = [\n {\n transform: `translate(${start.x}px, ${start.y}px) translate(-50%, -50%) scale(0.25)`,\n opacity: 0,\n },\n {\n transform: `translate(${start.x}px, ${start.y}px) translate(-50%, -50%) scale(1)`,\n opacity: 1,\n offset: 0.14,\n },\n {\n transform: `translate(${mid.x}px, ${mid.y}px) translate(-50%, -50%) scale(0.92)`,\n opacity: 1,\n offset: 0.52,\n },\n {\n transform: `translate(${end.x}px, ${end.y}px) translate(-50%, -50%) scale(0.45)`,\n opacity: 0,\n },\n ];\n\n const animation = orb.animate(keyframes, {\n duration: PAGE_ACTION_LAUNCH_FLY_DURATION_MS,\n easing: PAGE_ACTION_LAUNCH_FLY_EASING,\n fill: 'forwards',\n });\n\n animation.onfinish = () => {\n orb.remove();\n onComplete();\n };\n animation.oncancel = () => {\n orb.remove();\n };\n}\n\n/** Play fly-to-task-center animation without invoking PageAction. */\nexport function playPageActionLaunchAnimation(\n anchor: HTMLElement | null | undefined,\n hostElement?: HTMLElement | null,\n): boolean {\n if (prefersReducedMotion()) return false;\n const sourceRect = readLaunchSourceRect(anchor);\n if (!sourceRect) return false;\n return playPageActionLaunchFromRect(sourceRect, hostElement, anchor);\n}\n\nexport function playPageActionLaunchFromRect(\n sourceRect: PageActionSourceRect,\n hostElement?: HTMLElement | null,\n rippleAnchor?: HTMLElement | null,\n): boolean {\n if (prefersReducedMotion()) return false;\n const target = findTaskCenterTargetRect(hostElement);\n if (!target) return false;\n\n rippleLaunchAnchor(rippleAnchor);\n startLauncherReceivingAnimation(hostElement);\n flyLaunchOrb(sourceRect, target, () => pulseLaunchTargets(hostElement));\n return true;\n}\n","/**\n * Host-facing PageAction execution-process view model (scheme B).\n * Built from {@link PageActionRowState}; safe for custom rendering.\n */\n\nimport type { PageActionPhase, PageActionRowState } from '../../types';\nimport {\n countInterestingNarrativeItems,\n pickNarrativeHeadline,\n shouldOfferNarrativeProcess,\n type NarrativeItem,\n} from './page-action-workflow-progress';\n\n/** Live / waiting phases where a process affordance is usually useful. */\nexport function isPageActionProcessLivePhase(phase: PageActionPhase): boolean {\n return (\n phase === 'submitting' ||\n phase === 'launched' ||\n phase === 'streaming' ||\n phase === 'awaiting_approval' ||\n phase === 'awaiting_clarify'\n );\n}\n\n/**\n * Normalized execution-process snapshot for custom UI.\n * Prefer {@link progressLabel} on the trigger; use {@link narrativeItems} for detail.\n */\nexport interface PageActionProcessView {\n phase: PageActionPhase;\n loading: boolean;\n awaitingApproval: boolean;\n awaitingClarify: boolean;\n /** Button loading copy — do not replace with narrative headline. */\n progressLabel: string | null;\n narrativeItems: NarrativeItem[];\n /** True when storyline has non-stage items worth showing. */\n hasProcess: boolean;\n interestingCount: number;\n /** Submitting / streaming / awaiting user. */\n isLive: boolean;\n /** Short headline from latest ask / outcome / evidence (optional). */\n headline: string | null;\n /**\n * Suggested: show a process affordance (built-in or custom).\n * `hasProcess && isLive` by default.\n */\n showProcessAffordance: boolean;\n}\n\nexport function toPageActionProcessView(\n row: Pick<\n PageActionRowState,\n | 'phase'\n | 'loading'\n | 'awaitingApproval'\n | 'awaitingClarify'\n | 'progressLabel'\n | 'narrativeItems'\n >,\n): PageActionProcessView {\n const narrativeItems = row.narrativeItems ?? [];\n const hasProcess = shouldOfferNarrativeProcess(narrativeItems);\n const isLive = isPageActionProcessLivePhase(row.phase);\n return {\n phase: row.phase,\n loading: row.loading,\n awaitingApproval: row.awaitingApproval,\n awaitingClarify: row.awaitingClarify,\n progressLabel: row.progressLabel,\n narrativeItems,\n hasProcess,\n interestingCount: countInterestingNarrativeItems(narrativeItems),\n isLive,\n headline: pickNarrativeHeadline(narrativeItems),\n showProcessAffordance: hasProcess && isLive,\n };\n}\n","import type { PendingGateJob } from './core/auth/login-gate';\nimport type { AgentChatError } from './core/lib/errors';\nimport type { WriteDraftPublic } from './core/draft-review/write-draft';\nimport type { EditPolicyPublic } from './core/draft-review/edit-policy';\nimport type { NarrativeItem } from './core/page/page-action-workflow-progress';\nimport type { MouseEvent, ReactNode, TouchEvent } from 'react';\n\nexport type { WriteDraftPublic, WriteDraftEditPayload } from './core/draft-review/write-draft';\n\nexport interface UserContext {\n /** Stable user identifier in the host application. */\n id: string;\n email?: string;\n name?: string;\n /**\n * Optional HMAC of the user identity. The backend may require this to\n * prevent identity spoofing from the browser. The exact algorithm is\n * decided by the backend (commonly `HMAC-SHA256(secret, userId + timestamp)`).\n */\n signature?: string;\n /** Unix timestamp in seconds, paired with `signature`. */\n signatureTimestamp?: number;\n}\n\nexport type Theme = 'light' | 'dark' | 'auto';\n\nexport type WidgetPosition =\n | 'bottom-right'\n | 'bottom-left'\n | 'top-right'\n | 'top-left';\n\n/** How the chat panel opens over the host page. */\nexport type PanelMode = 'sidebar' | 'floating' | 'fullscreen';\n\n/**\n * Floating launcher presentation.\n * - `compact` (default): idle edge-peek; expands on hover or when there is attention.\n * - `fab`: always full-size bubble (legacy).\n * - `hidden`: no built-in launcher (host opens via API / own chrome).\n */\nexport type LauncherMode = 'compact' | 'fab' | 'hidden';\n\n/** Default floating launcher mode. */\nexport const DEFAULT_LAUNCHER_MODE: LauncherMode = 'compact';\n\n/**\n * Current route location — always sent with user messages (auto-read from\n * `window.location` unless overridden via {@link AgentChatInstance.setRouteContext}).\n */\nexport interface AgentChatRouteContext {\n routePath?: string;\n /** Query string and/or dynamic path params supplied by the host router. */\n routeParams?: Record<string, string>;\n}\n\n/**\n * Extended business page context set by the host via `pageContext` /\n * {@link AgentChatInstance.setPageContext}. Sent as a lightweight page anchor\n * for Auto-Agent and page tools (route info is sent separately).\n */\nexport interface AgentChatPageContext {\n /** Human-readable page id, e.g. `campaign-edit`. */\n page?: string;\n /** @deprecated Prefer {@link AgentChatRouteContext.routePath}; route is always sent via route context. */\n routePath?: string;\n /** @deprecated Prefer {@link AgentChatRouteContext.routeParams}. */\n routeParams?: Record<string, string>;\n flowId?: number;\n programName?: string;\n /** Primary entity on the page, e.g. `{ type: 'campaign', id: '123' }`. */\n entity?: {\n type?: string;\n id?: string;\n [key: string]: unknown;\n };\n /** Extra small key-value payload (avoid large blobs). */\n metadata?: Record<string, unknown>;\n}\n\n/** `POST /page-action/brain-invoke` request body. */\n/** Candidate row inside {@link BrainClarifyPayload}. */\nexport interface BrainClarifyCandidate {\n id: string;\n entityType: string;\n text?: string;\n fields?: Record<string, unknown>;\n source?: string;\n path?: string;\n}\n\n/**\n * Brain ASK_USER entity disambiguation payload (PageAction SSE / Chat run steps).\n * Continuations use {@link EntityCommit} — no dedicated `awaiting_clarify` run status.\n */\nexport interface BrainClarifyPayload {\n kind: 'entity_resolve';\n question: string;\n reason: string;\n entityType: string;\n candidates: BrainClarifyCandidate[];\n commitHint: { entityType: string };\n proposalType: string;\n}\n\n/** Structured entity pick for PageAction `invoke` / Chat `message` continuation. */\nexport interface EntityCommit {\n entityType: string;\n selectedId: string;\n}\n\nexport interface InvokePageActionRequest {\n actionKey: string;\n pageContext?: AgentChatPageContext;\n instruction?: string;\n context?: Record<string, unknown>;\n idempotencyKey?: string;\n clientActionId?: string;\n /**\n * Brain clarify continuation — same `pageContext` / `actionKey` as the prior run,\n * with the user-selected candidate id.\n */\n entityCommit?: EntityCommit;\n}\n\n/** `POST /page-action/brain-invoke` accepted payload (JSON, not SSE). */\nexport interface InvokePageActionAccepted {\n runId: number;\n generation: number;\n clientActionId: string | null;\n pageActionKey: string | null;\n streamUrl: string;\n status: AutomationTaskStatus;\n}\n\n/** `POST /page-action/brain-invoke` conflict — active run for same `pageActionKey`. */\nexport interface PageActionAlreadyActive {\n code: 'PAGE_ACTION_ALREADY_ACTIVE';\n message: string;\n pageActionKey: string;\n existingRunId: number;\n existingStatus: 'running' | 'awaiting_approval';\n approvalRequestId: number | null;\n streamUrl: string;\n}\n\nexport type PageActionInvokeResult =\n | ({ kind: 'accepted' } & InvokePageActionAccepted)\n | ({ kind: 'already_active' } & PageActionAlreadyActive);\n\nexport type PageActionLifecyclePhase =\n | 'started'\n | 'stream'\n | 'completed'\n | 'failed'\n | 'awaiting_approval';\n\nexport interface PageActionSseLifecycle {\n phase: PageActionLifecyclePhase;\n actionRunId: number;\n actionKey: string;\n generation: number;\n clientActionId?: string | null;\n streamId?: string | null;\n text?: string;\n dslOutcome?: string | null;\n errorCode?: string | null;\n errorMessage?: string | null;\n /** Present when `phase=failed` + `errorCode=BRAIN_ASK_USER`. */\n brainClarify?: BrainClarifyPayload | null;\n}\n\n/** {@link AgentChatInstance.invokePageAction} input. */\nexport interface PageBotInvokeInput extends InvokePageActionRequest {\n onChunk?: (chunk: string) => void;\n signal?: AbortSignal;\n /**\n * When `false`, returns after `POST /page-action/brain-invoke` and consumes SSE in the\n * background (for non-blocking trigger UIs). Default `true`.\n */\n awaitStream?: boolean;\n /** Optional DOM anchor for launch fly-to animation (`pageActionSubmitted.sourceRect`). */\n launchAnchor?: HTMLElement | null;\n /**\n * Host list-row key for per-row UI state (`usePageActions`).\n * Defaults to `String(pageContext.entity.id)` when omitted.\n */\n rowKey?: string;\n /**\n * When `true` (default) and the chat UI is mounted, check `reuse-hint` before invoke.\n * If reusable runs exist, show the SDK popover anchored to {@link launchAnchor};\n * only invoke after the user confirms「重新执行」.\n * Set `false` to skip the hint and invoke immediately.\n */\n preferReuse?: boolean;\n}\n\n/** One successful run returned by `POST /page-action/reuse-hint`. */\nexport interface PageActionReusableItem {\n ref: { kind: 'page_action_run'; id: number };\n triggerSource: AutomationTriggerSource;\n taskStatus: AutomationTaskStatus;\n succeeded?: boolean;\n /** Executor user id (cross-user reuse). */\n runUserId?: number;\n title: string;\n subtitle: string | null;\n pageActionKey: string | null;\n createdAt: string;\n finishedAt: string | null;\n outputs: {\n preview: string | null;\n fillText?: string | null;\n hasFillText: boolean;\n };\n}\n\n/** `POST /page-action/reuse-hint` response. */\nexport interface PageActionReuseHint {\n pageActionKey: string;\n actionKey: string;\n reusable: {\n total: number;\n items: PageActionReusableItem[];\n };\n}\n\n/** Decision from the built-in reuse popover (or a custom handler). */\nexport type PageActionReuseDecision =\n | { type: 'reuse'; runId: number }\n | { type: 'rerun' }\n | { type: 'cancel' };\n\n/**\n * Fields needed to re-invoke after the user applies a reused result and then\n * chooses「继续执行」from the docked bar.\n */\nexport interface PageActionReuseInvokeSnapshot {\n pageContext?: AgentChatPageContext;\n instruction?: string;\n context?: Record<string, unknown>;\n clientActionId?: string;\n idempotencyKey?: string;\n rowKey?: string;\n awaitStream?: boolean;\n}\n\n/** Payload for the SDK reuse prompt UI. */\nexport interface PageActionReusePromptRequest {\n actionKey: string;\n pageActionKey: string;\n items: PageActionReusableItem[];\n /** Button rect for anchoring the popover. */\n sourceRect: PageActionSourceRect | null;\n /** Live anchor element when still in the DOM (reposition on scroll). */\n launchAnchor?: HTMLElement | null;\n /** Snapshot for「继续执行」after a reused result was already applied. */\n invokeSnapshot?: PageActionReuseInvokeSnapshot;\n}\n\nexport type PageActionReusePromptHandler = (\n request: PageActionReusePromptRequest,\n) => Promise<PageActionReuseDecision>;\n\nexport type PageActionPhase =\n | 'idle'\n | 'submitting'\n | 'launched'\n | 'streaming'\n | 'awaiting_approval'\n /** Local UI: Brain ASK_USER — show clarify popover; not a server run status. */\n | 'awaiting_clarify'\n /** Local UI: reuse-hint popover open — not a server run; must not stick `loading`. */\n | 'awaiting_reuse'\n | 'completed'\n | 'failed';\n\n/**\n * Fields needed to re-invoke after the user picks a Brain clarify candidate.\n */\nexport interface PageActionBrainClarifyInvokeSnapshot {\n pageContext?: AgentChatPageContext;\n instruction?: string;\n context?: Record<string, unknown>;\n clientActionId?: string;\n idempotencyKey?: string;\n rowKey?: string;\n awaitStream?: boolean;\n}\n\n/** Payload for the built-in Brain clarify popover. */\nexport interface PageActionBrainClarifyPromptRequest {\n actionKey: string;\n runId: number;\n brainClarify: BrainClarifyPayload;\n sourceRect: PageActionSourceRect | null;\n launchAnchor?: HTMLElement | null;\n invokeSnapshot?: PageActionBrainClarifyInvokeSnapshot;\n}\n\n/**\n * Per-row PageAction UI state for list pages.\n * Keyed by host `rowKey` (typically `String(entity.id)`).\n */\nexport interface PageActionRowState {\n rowKey: string;\n actionKey: string;\n runId: number | null;\n pageActionKey: string | null;\n phase: PageActionPhase;\n awaitingApproval: boolean;\n /** True while {@link phase} is `awaiting_clarify`. */\n awaitingClarify: boolean;\n loading: boolean;\n disabled: boolean;\n error: string | null;\n /**\n * Soft tip (duplicate click / already running). Not a failure —\n * keep showing progress; do not treat as {@link error}.\n */\n message: string | null;\n /**\n * SSE `page_workflow` loading copy for the trigger button (`stageKind` path).\n * Hosts should render this as loading copy; clear on completed/failed.\n */\n progressLabel: string | null;\n /**\n * Accumulated `page_workflow.narrativeItems` storyline for this run.\n * Hosts may build custom process UI from this (see `toPageActionProcessView`).\n * Does not replace {@link progressLabel}.\n */\n narrativeItems: NarrativeItem[];\n approvalRequestId: number | null;\n /** Present when {@link phase} is `awaiting_clarify`. */\n brainClarify: BrainClarifyPayload | null;\n updatedAt: number;\n}\n\n/** Fired when a list-row PageAction slot changes. */\nexport interface PageActionRowChangedPayload {\n rowKey: string;\n state: PageActionRowState;\n}\n\n/** SSE re-attached after refresh or resume (not the initial invoke stream). */\nexport interface PageActionStreamResumedPayload {\n runId: number;\n actionKey: string;\n rowKey: string;\n}\n\nexport interface PageActionRunLifecyclePayload {\n runId: number;\n actionKey: string;\n rowKey?: string | null;\n errorMessage?: string | null;\n /** Set on failed runs — `BRAIN_ASK_USER` should not toast as a system failure. */\n errorCode?: string | null;\n brainClarify?: BrainClarifyPayload | null;\n}\n\n/** Intent from「应用到页面」waiting for the target page to become ready. */\nexport type PendingPageActionApply = {\n runId: number;\n actionKey: string;\n pageContext: AgentChatPageContext | null;\n createdAt: string;\n};\n\nexport type PageActionApplyPhase =\n | 'idle'\n | 'waiting_ready'\n | 'replaying'\n | 'done'\n | 'error';\n\nexport interface PageActionSlotApplyPhasePayload {\n slotKey: string;\n phase: PageActionApplyPhase;\n}\n\n/** Screen rect for PageAction launch animation (viewport coordinates). */\nexport type PageActionSourceRect = Pick<DOMRect, 'left' | 'top' | 'width' | 'height'>;\n\n/** `pageActionSubmitted` event payload. */\nexport type PageActionSubmittedPayload = InvokePageActionAccepted & {\n sourceRect?: PageActionSourceRect | null;\n /** Live trigger element when still in the DOM (reposition narrative chip). */\n launchAnchor?: HTMLElement | null;\n /** Host row slot for list pages. */\n rowKey?: string | null;\n actionKey?: string;\n};\n\n/** Outcome surfaced after inbox approve / decide resumes a PageAction run. */\nexport type ApprovalExecutionOutcome =\n | 'completed'\n | 'failed'\n | 'running'\n | 'awaiting_approval'\n | 'cancelled';\n\n/** `approvalExecutionCompleted` event payload. */\nexport interface ApprovalExecutionCompletedPayload {\n approvalId: number;\n runId: number | null;\n outcome: ApprovalExecutionOutcome;\n /**\n * Best display title for toasts — prefers the inbox approval title the user\n * just confirmed (list/detail), then the automation task title.\n */\n title?: string | null;\n /** Raw inbox item title when available (list-row identity). */\n approvalTitle?: string | null;\n /** Inbox summary for richer toast body. */\n approvalSummary?: string | null;\n preview?: string | null;\n taskStatus?: AutomationTaskStatus;\n}\n\nexport interface PageBotStreamResult {\n actionRunId: number;\n text: string;\n dslOutcome: string | null;\n /** Invoke paused at workflow approval gate — confirm via inbox API. */\n awaitingApproval?: boolean;\n /**\n * Brain ASK_USER — show clarify UI; not a thrown failure.\n * Continuations use a fresh `invoke` with {@link EntityCommit}.\n */\n awaitingClarify?: boolean;\n /** Set when {@link awaitingApproval} is true. */\n status?: 'awaiting_approval';\n actionKey?: string;\n clientActionId?: string;\n approvalRequestId?: number | null;\n brainClarify?: BrainClarifyPayload | null;\n /**\n * Soft tip (e.g. duplicate invoke / 409 already active).\n * Not a thrown error — UI may toast or show beside the button.\n */\n message?: string | null;\n /** True when invoke hit an already-active run (local guard or HTTP 409). */\n alreadyActive?: boolean;\n /** True when the user reused an existing successful run (no new invoke). */\n reused?: boolean;\n /** True when the reuse popover was dismissed without reuse or rerun. */\n cancelled?: boolean;\n}\n\nexport type ApprovalSource = 'chat' | 'page_action' | 'webhook';\n\nexport type ApprovalStatus = 'pending' | 'approved' | 'rejected' | 'cancelled' | 'expired';\n\n/** `GET /approval/inbox?status=` filter values. */\nexport type ApprovalInboxStatusFilter =\n | 'pending'\n | 'approved'\n | 'rejected'\n | 'cancelled'\n | 'expired'\n | 'decided'\n | 'all';\n\nexport interface ApprovalInitiator {\n id: number;\n username: string | null;\n employeeId: string | null;\n}\n\nexport interface ApprovalPendingWritePreview {\n tool: string;\n riskLevel: string;\n}\n\nexport type ApprovalEntityReferenceDisplayField = {\n key: string;\n label: string;\n value: string;\n};\n\n/** Workflow read / page inline snapshot for approval comparison. */\nexport interface ApprovalEntityReferenceInlineRecord {\n kind: string;\n title: string;\n fields: ApprovalEntityReferenceDisplayField[];\n imageUrls: string[];\n /** Pre-projection snapshot (`inlineRecords[].record`); render via legacy path only. */\n legacyRecord?: Record<string, unknown>;\n}\n\nexport interface ApprovalEntityReferenceSource {\n ref: string;\n action: string;\n title: string;\n toolName: string | null;\n toolId: number | null;\n data: unknown;\n fields: ApprovalEntityReferenceDisplayField[];\n imageUrls?: string[];\n}\n\nexport interface ApprovalEntityReference {\n page: string | null;\n routePath: string | null;\n entityType: string | null;\n entityId: string | null;\n anchorLabel: string | null;\n inlineRecords: ApprovalEntityReferenceInlineRecord[];\n sources: ApprovalEntityReferenceSource[];\n /** True when parsed from a pre-projection approval snapshot. */\n legacy?: boolean;\n}\n\n/** Draft retry budget from inbox `draftReview` (page_action approvals). */\nexport interface ApprovalDraftReviewBudget {\n retryCount: number;\n retryMax: number | null;\n canRetry: boolean;\n}\n\nexport interface ApprovalInboxItem {\n id: number;\n source: ApprovalSource;\n status: ApprovalStatus;\n title: string;\n summary: string | null;\n workflowId: number;\n workflowVersion: number;\n workflowKey: string | null;\n workflowName: string | null;\n nodeId: string;\n sessionId: string | null;\n pageActionRunId: number | null;\n initiator: ApprovalInitiator | null;\n createdAt: string;\n decidedAt?: string | null;\n previewBlocks: unknown;\n pendingWrite: ApprovalPendingWritePreview | null;\n /** Execution truth + presentation from server (`GET /approval/inbox`). */\n writeDraft?: WriteDraftPublic | null;\n /** Server-derived field edit rules — drives draft review UI. */\n editPolicy?: EditPolicyPublic | null;\n writeDrafts?: WriteDraftPublic[] | null;\n editPolicies?: Array<EditPolicyPublic | null> | null;\n draftReview?: ApprovalDraftReviewBudget | null;\n /** Paired reference snapshot (`GET /approval/inbox` / `GET /approval/:id`). */\n entityReference?: ApprovalEntityReference | null;\n}\n\nexport interface ApprovalInboxList {\n items: ApprovalInboxItem[];\n hasMore: boolean;\n}\n\nexport interface ApprovalDetail extends ApprovalInboxItem {\n decidedAt: string | null;\n}\n\nexport interface ApprovalConfirmResult {\n resumed: boolean;\n suspended?: boolean;\n}\n\n/** Alias of {@link WriteGate} for `POST /approval/:id/decide` body `decision`. */\nexport type DraftReviewDecision = WriteGate;\n\nexport interface ApprovalDecideResult {\n resumed: boolean;\n suspended?: boolean;\n}\n\nexport interface ApprovalRejectResult {\n ok: boolean;\n}\n\n/** Cached page_action / webhook approvals for the inbox UI (not chat write gates). */\nexport interface ApprovalInboxState {\n items: ApprovalInboxItem[];\n loading: boolean;\n loadingMore: boolean;\n hasMore: boolean;\n statusFilter: ApprovalInboxStatusFilter;\n /** Approximate pending count for badge (from last `status=pending` fetch). */\n pendingCount: number;\n}\n\nexport type AutomationTriggerSource = 'page_action' | 'webhook';\n\nexport type AutomationTaskRefKind = 'page_action_run' | 'webhook_approval';\n\nexport type AutomationTaskRef =\n | { kind: 'page_action_run'; id: number }\n | { kind: 'webhook_approval'; id: number };\n\nexport type AutomationTaskStatus =\n | 'running'\n | 'awaiting_approval'\n | 'completed'\n | 'failed'\n | 'cancelled';\n\n/** `GET /automation/tasks?status=` filter values. */\nexport type AutomationTaskStatusFilter =\n | AutomationTaskStatus\n | 'active'\n | 'all';\n\nexport type AutomationTriggerSourceFilter = AutomationTriggerSource | 'all';\n\nexport interface AutomationTaskListItem {\n ref: AutomationTaskRef;\n triggerSource: AutomationTriggerSource;\n taskStatus: AutomationTaskStatus;\n title: string;\n subtitle: string | null;\n workflowKey: string | null;\n workflowName: string | null;\n pageActionKey: string | null;\n createdAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n approval: { id: number; status: string } | null;\n outputs: {\n preview: string | null;\n hasFillText: boolean;\n };\n}\n\nexport type AutomationTaskTimelineEntry = {\n step: number;\n type: string;\n name: string;\n at: string;\n status?: 'ok' | 'failed' | 'skipped';\n};\n\nexport type AutomationTaskDetail = AutomationTaskListItem & {\n actionKey: string;\n instruction: string | null;\n errorCode: string | null;\n errorMessage: string | null;\n streamUrl: string;\n timeline: AutomationTaskTimelineEntry[];\n workflowRun: unknown | null;\n /** Present when `errorCode=BRAIN_ASK_USER`. */\n brainClarify: BrainClarifyPayload | null;\n /**\n * Invoke 时快照的页锚点(`page` / `entity` / 可选 `routePath`+`routeParams`)。\n * 任务中心「应用到页面」导航与 replay 门禁用;历史 run 可能为 null。\n */\n pageContext: AgentChatPageContext | null;\n /** 后端实时计算的重放能力(非缓存)。 */\n replay: {\n canReplay: boolean;\n hasHostAction: boolean;\n dslOutcome: string | null;\n };\n};\n\nexport interface AutomationTaskList {\n items: AutomationTaskListItem[];\n total: number;\n hasMore: boolean;\n}\n\n/** Cached PageAction automation tasks for the task center UI. */\nexport interface AutomationTaskCenterState {\n items: AutomationTaskListItem[];\n loading: boolean;\n loadingMore: boolean;\n hasMore: boolean;\n /** Server-reported total for the active tab filter (`0` when unknown). */\n total: number;\n statusFilter: AutomationTaskStatusFilter;\n /** Recently submitted run ids (optimistic highlight). */\n recentRunIds: number[];\n /** Active run count for launcher badge (derived from in-memory run registry). */\n activeCount: number;\n /** Detail row when a task card is opened. */\n selectedDetail: AutomationTaskDetail | null;\n detailLoading: boolean;\n}\n\n/** @deprecated Legacy SSE field — no longer read by the SDK. */\nexport type AgentChatHostActionType = 'refresh' | 'invalidate' | 'navigate';\n\n/** Known `reason` values on SSE `host_action` (server may send custom strings). */\nexport const HOST_ACTION_REASON = {\n PLAN_HOST_TOOL_STREAM: 'plan_host_tool_stream',\n PLAN_HOST_TOOL: 'plan_host_tool',\n AGENT_MUTATION_SUCCESS: 'agent_mutation_success',\n HOST_TOOL_DISPATCH: 'host_tool_dispatch',\n PAGE_ACTION_HOST_FILL: 'page_action_host_fill',\n} as const;\n\nexport type HostActionReason =\n (typeof HOST_ACTION_REASON)[keyof typeof HOST_ACTION_REASON] | string;\n\nexport interface AgentChatHostToolCall {\n name: string;\n args: Record<string, unknown>;\n}\n\n/**\n * SSE `host_action` payload — instructs the browser to run `hostTools`.\n * Aligned with agent-server `HostActionSsePayload` (no `status` field).\n */\nexport interface AgentChatHostAction {\n /** Envelope discriminator — always `host_action` after normalization. */\n action: 'host_action';\n /** Business page scope — matches `pageContext.page`; required for dispatch. */\n scope: string;\n entity?: AgentChatPageContext['entity'];\n metadata?: Record<string, unknown>;\n /** Registry tools to run in order (server sends only when non-empty). */\n hostTools: AgentChatHostToolCall[];\n /** Plan host_tool step id when pushed mid-run — not the reason step id. */\n planStepId?: string;\n /** e.g. `plan_host_tool` | `agent_mutation_success` */\n reason?: string;\n runId?: number;\n turnId?: number;\n messageId?: string;\n sessionId?: string;\n /** DSL v1 streaming phase — present on intermediate frames. */\n streamPhase?: 'streaming' | 'complete';\n /** Accumulated args preview during DSL streaming (`invokeOnAppend: false`). */\n streamPreview?: {\n callId: string;\n name: string;\n args: Record<string, unknown>;\n };\n}\n\n/** Alias aligned with agent-server host-action SDK docs. */\nexport type HostActionPayload = AgentChatHostAction;\n\nexport type HostToolHandler = (\n args: Record<string, unknown>,\n) => void | Promise<void>;\n\n/** Host tool metadata synced to the server (handler is local-only). */\nexport type HostToolMetadata = {\n name: string;\n description: string;\n argsSchema: Record<string, unknown>;\n generic?: boolean;\n /** Server-side args resolution, e.g. `{ entityId: '$entity.id' }`. */\n argsTemplate?: Record<string, unknown>;\n definitionKey?: string;\n /**\n * When `true`, registry handler runs on each `arg.append` / `arg.set` during DSL\n * streaming. When `false` (default) and `onPreview` is omitted, the SDK\n * still streams into the handler on each append; `stream.full` skips\n * duplicate execution for that call.\n */\n invokeOnAppend?: boolean;\n /**\n * Optional streaming-only callback. When set, takes precedence over the handler\n * during `arg.append`; handler still runs at `stream.full` unless already marked.\n */\n onPreview?: HostToolHandler;\n};\n\n/** Local host tool definition (handler stays in the browser). */\nexport interface HostToolDefinition extends HostToolMetadata {\n handler: HostToolHandler;\n}\n\n/**\n * App-root tool declaration — metadata sync + optional local handler.\n * App-wide scope is implied by {@link useAppAgent}; do not pass `generic`.\n */\nexport type AppHostToolDefinition = Omit<HostToolMetadata, 'generic'> & {\n handler?: HostToolHandler;\n};\n\nexport interface RegisterHostToolsOptions {\n /** `pageContext.page` — required for page-scoped tools. */\n scope?: string;\n pageLabel?: string;\n routePattern?: string;\n tools: Array<HostToolDefinition | AppHostToolDefinition>;\n /** Sync metadata to `POST /host-tool/client/register`. Default `true`. */\n syncToServer?: boolean;\n /**\n * App-wide registration (`useAppAgent`). Uses scope `*` and syncs `generic: true`\n * to the server without requiring `generic` on each tool.\n */\n appLevel?: boolean;\n}\n\n/** Options for {@link AgentChatInstance.prepareSession}. */\nexport interface PrepareSessionOptions {\n signal?: AbortSignal;\n /** Re-run even when the page/session fingerprint is unchanged. */\n force?: boolean;\n}\n\n/** Response from `POST /chat/{sessionId}/prepare` (host-tool L1 warm). */\nexport interface PrepareSessionResult {\n sessionId: string;\n prepared: boolean;\n agentReady: boolean;\n toolsCount: number;\n skillsCount: number;\n hostToolsCount: number;\n pageScope: string | null;\n sessionContextWarmed: boolean;\n warmedAt?: string;\n fromCache: boolean;\n revision?: Record<string, string>;\n}\n\nexport interface AgentChatHostActionPayload {\n action: AgentChatHostAction;\n phase?: 'streaming' | 'complete';\n}\n\n/** Origin of a host-tool DSL stream observed by the host page. */\nexport type PageAgentSource = 'chat' | 'page_action';\n\nexport interface PageAgentStreamEntity {\n type?: string;\n id?: string | number;\n}\n\n/** `onStart` — `session.begin` or `tool.begin`. */\nexport interface PageAgentStartContext {\n streamId: string;\n scope: string;\n source: PageAgentSource;\n toolName?: string;\n callId?: string;\n entity?: PageAgentStreamEntity;\n reason?: string;\n runId?: number;\n turnId?: number;\n}\n\n/** `onStream` — `arg.append` / `arg.set` with SDK-accumulated args. */\nexport interface PageAgentStreamContext {\n streamId: string;\n scope: string;\n source: PageAgentSource;\n callId: string;\n toolName: string;\n args: Record<string, unknown>;\n entity?: PageAgentStreamEntity;\n reason?: string;\n}\n\n/** `onComplete` — `stream.full` or batch `hostTools`. */\nexport interface PageAgentCompleteContext {\n streamId?: string;\n scope: string;\n source: PageAgentSource;\n hostTools: AgentChatHostToolCall[];\n action?: AgentChatHostAction;\n entity?: PageAgentStreamEntity;\n reason?: string;\n}\n\n/** `onError` — stream / tool / page_action failure. */\nexport interface PageAgentErrorContext {\n scope?: string;\n source: PageAgentSource;\n phase: 'stream' | 'tool' | 'page_action' | 'approval';\n code?: string;\n message: string;\n streamId?: string;\n callId?: string;\n}\n\nexport type PageAgentLifecyclePayload =\n | { type: 'start'; context: PageAgentStartContext }\n | { type: 'stream'; context: PageAgentStreamContext }\n | { type: 'complete'; context: PageAgentCompleteContext }\n | { type: 'error'; context: PageAgentErrorContext };\n\n/** Emitted when `invokePageAction` pauses at `awaiting_approval`. */\nexport interface PageAgentAwaitingApprovalPayload {\n scope: string;\n actionRunId: number;\n actionKey?: string;\n clientActionId?: string;\n approvalRequestId?: number | null;\n}\n\n/** Built-in notification when PageAction needs inbox approval. */\nexport interface PageActionAwaitingApprovalNoticePayload {\n actionRunId: number;\n actionKey?: string;\n approvalRequestId?: number | null;\n}\n\n/** Soft conflict tip (duplicate invoke / HTTP 409) — do not treat as PageAction failure. */\nexport interface PageActionSoftNoticePayload {\n kind: 'already_running' | 'already_awaiting_approval';\n message: string;\n runId?: number | null;\n actionKey?: string;\n approvalRequestId?: number | null;\n}\n\n/** Optional target when opening the approval inbox drawer. */\nexport interface OpenApprovalInboxPayload {\n approvalId?: number;\n}\n\n/** Optional target when opening the automation task center drawer. */\nexport interface OpenAutomationTaskCenterPayload {\n /** When set, open the drawer and hydrate that run’s detail view. */\n runId?: number;\n}\n\n/** Optional target when opening「我的反馈」drawer. */\nexport interface OpenPageActionFeedbackPayload {\n /** Prefer tab: `rating` = 场景评价, `wish` = 需求收集. */\n tab?: 'rating' | 'wish';\n /** Pre-select actionKey on the rating tab. */\n actionKey?: string;\n}\n\n/** Current user’s rating as returned on `GET /page-action/catalog` items. */\nexport interface PageActionCatalogMyFeedback {\n rating: number;\n comment: string | null;\n updatedAt: string;\n}\n\n/** One enabled PageAction from `GET /page-action/catalog`. */\nexport interface PageActionFeedbackCatalogItem {\n pageActionId: number;\n actionKey: string;\n name: string;\n description: string | null;\n pageScope: string | null;\n sortOrder: number;\n myFeedback: PageActionCatalogMyFeedback | null;\n}\n\nexport interface PageActionFeedbackCatalogQuery {\n /** Current `pageContext.page`. Omit for the global feedback center. */\n pageScope?: string | null;\n}\n\n/** One user’s rating on a PageAction config (`PUT/GET /page-action/feedback/:actionKey`). */\nexport interface PageActionFeedbackView {\n id: number;\n pageActionId: number;\n actionKey: string;\n pageActionName: string;\n appClientId: number;\n userId: number;\n rating: number;\n comment: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface UpsertPageActionFeedbackInput {\n rating: number;\n comment?: string;\n}\n\n/** Aggregate ratings for one actionKey. */\nexport interface PageActionFeedbackSummary {\n pageActionId: number;\n actionKey: string;\n pageActionName: string;\n count: number;\n avgRating: number | null;\n ratingDistribution: Record<'1' | '2' | '3' | '4' | '5', number>;\n}\n\nexport type PageActionWishStatus =\n | 'submitted'\n | 'reviewing'\n | 'planned'\n | 'in_progress'\n | 'done'\n | 'rejected'\n | 'cancelled';\n\nexport interface PageActionWishView {\n id: number;\n appClientId: number;\n userId: number;\n title: string;\n description: string;\n pageScope: string | null;\n relatedActionKey: string | null;\n status: PageActionWishStatus;\n developerNote: string | null;\n statusUpdatedAt: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreatePageActionWishInput {\n title: string;\n description: string;\n pageScope?: string;\n relatedActionKey?: string;\n}\n\nexport interface PageActionWishQuery {\n page?: number;\n pageSize?: number;\n status?: PageActionWishStatus;\n keyword?: string;\n pageScope?: string;\n relatedActionKey?: string;\n}\n\nexport interface PageActionWishList {\n items: PageActionWishView[];\n total: number;\n page: number;\n pageSize: number;\n hasMore: boolean;\n}\n\n/** Default panel layout when embedded. */\nexport const DEFAULT_PANEL_MODE: PanelMode = 'sidebar';\n\n/** Branding shown in the panel header and assistant avatar. */\nexport interface AgentChatProjectConfig {\n /** Project / product name shown at the top-left of the chat panel. */\n name?: string;\n /** Logo URL for the assistant avatar (and default launcher icon). */\n logo?: string;\n}\n\n/** Props passed to a custom floating launcher (`launcher` render function). */\nexport interface AgentChatLauncherProps {\n position: { x: number; y: number };\n loading: boolean;\n /** Pending page-action / webhook approvals (`GET /approval/inbox`). */\n pendingApprovalCount: number;\n open: () => void;\n /** Open panel + approval inbox drawer (launcher badge). */\n openApprovalInbox?: () => void;\n /** Active PageAction runs (`GET /automation/tasks?status=active`). */\n activeAutomationCount?: number;\n /** Open panel + automation task center drawer. */\n openAutomationTaskCenter?: () => void;\n /** Open「我的反馈」drawer (场景评价 + 需求收集). */\n openPageActionFeedback?: () => void;\n /**\n * Effective launcher mode for this render (`hidden` never reaches the slot).\n * Custom launchers may ignore this and own their chrome.\n */\n launcherMode?: Exclude<LauncherMode, 'hidden'>;\n /**\n * True when the default bubble should stay expanded (streaming, pending\n * approval, or active automation). Useful for custom compact launchers.\n */\n attention?: boolean;\n /**\n * Right-click menu actions for the default bubble.\n * `hide` dismisses until attention; `restore` clears the dismiss preference.\n */\n onLauncherVisibilityAction?: (action: 'hide' | 'restore') => void;\n /** True when the user has dismissed the launcher (menu → hide). */\n userDismissed?: boolean;\n onMouseDown: (event: MouseEvent<HTMLElement>) => void;\n onTouchStart: (event: TouchEvent<HTMLElement>) => void;\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n}\n\nexport interface AgentChatOptions {\n /**\n * Required. Opaque DSN string identifying this client on the auth service.\n * Treated as an unparsed credential — the SDK forwards it as the\n * `x-app-dsn` request header on every backend call.\n */\n dsn: string;\n /**\n * Backend base URL. Used for **all** SDK API calls, i.e. every request is\n * sent to `{baseUrl} + path`.\n * Defaults to `http://localhost:3030`; override in production.\n */\n baseUrl?: string;\n /**\n * Optional account token for `POST /app-client/auth` (`x-account-token` +\n * `x-app-dsn`). The response `accessToken` is used as `Authorization: Bearer`\n * on subsequent `/chat`, `/agent`, etc.\n */\n accountToken?: string;\n /**\n * @deprecated Alias of `accountToken` for backward compatibility.\n * Sent as `x-account-token` on `POST /app-client/auth`.\n */\n userAccessToken?: string;\n /** Optional end-user context. Forwarded to the backend at handshake time. */\n user?: UserContext;\n /** BCP-47 locale, defaults to `navigator.language`. */\n locale?: string;\n /** Visual theme. `auto` follows `prefers-color-scheme`. */\n theme?: Theme;\n /** Optional antd theme token overrides forwarded to ConfigProvider.theme.token. */\n themeToken?: Record<string, unknown>;\n /** Where the floating launcher button anchors to the viewport. */\n position?: WidgetPosition;\n /**\n * Floating launcher density. Default {@link DEFAULT_LAUNCHER_MODE} (`compact`):\n * idle peeks smaller toward the nearest edge; expands on hover or when there\n * is pending approval / streaming / active automation. Use `fab` for the\n * legacy always-on ball, or `hidden` to rely on host chrome / `open()`.\n */\n launcherMode?: LauncherMode;\n /**\n * Panel layout when open. `sidebar` (default) keeps the host page visible;\n * `floating` is a corner card; `fullscreen` covers the viewport.\n */\n panelMode?: PanelMode;\n /**\n * Allow end users to switch panel layout (sidebar / floating / fullscreen) from\n * the panel header. Preference is stored in `localStorage`. Default `true`.\n */\n panelModeSwitchable?: boolean;\n /**\n * Extended page context (entity, metadata, …) from the host app. Updated via\n * prop or {@link AgentChatInstance.setPageContext}. Sent as a lightweight page\n * anchor with chat messages so Auto-Agent and host-tool prepare can match the\n * current page; route info is always sent via {@link AgentChatState.routeContext}.\n */\n pageContext?: AgentChatPageContext;\n /** Default for the page-context visibility toggle in the chat panel. Default `false`. */\n attachPageContext?: boolean;\n /** Open the widget panel automatically after init (React UI must be mounted). */\n autoOpen?: boolean;\n /** Print verbose logs to the console. */\n debug?: boolean;\n /**\n * Host Tool DSL v1 stream reducer. Default `true`. Set `false` to only handle\n * v0 batch and `stream.mode=full` frames (emergency rollback).\n */\n hostToolStream?: boolean;\n /**\n * Built-in PageAction execution-process UI (detail affordance + timeline popover).\n * Default `true`. Set `false` when the host renders process from hook data\n * (`progressLabel` / `narrativeItems` / `toPageActionProcessView`).\n */\n pageActionProcessUi?: boolean;\n /**\n * 任务中心「应用到页面」时的宿主导航回调。\n * SDK 解析 `detail.pageContext` 优先级后传入;宿主负责真正 `navigate` / 路由表映射。\n */\n onNavigateForPageAction?: (\n input: import('./core/page/page-context-navigate').NavigateForPageActionInput,\n ) => void | Promise<void>;\n /** Extra request headers added to every backend call. */\n headers?: Record<string, string>;\n /** Convenience alias for `instance.on('ready', handler)`. */\n onReady?: () => void;\n /** Static agent list; used when `GET /agent/client/available` is unavailable. */\n agents?: ChatAgentSummary[];\n /** Static skill list; used when skills client API is unavailable. */\n skills?: ChatSkillSummary[];\n /** Optional query for `GET /agent/client/available`. */\n agentListQuery?: QueryClientAvailableAgents;\n /**\n * Optional extra query for `GET /agent/:agentId/skills/client`.\n * When `pageContext.page` is set, the SDK also sends `?page=` automatically.\n */\n skillListQuery?: QueryClientSkillByAgent;\n /** Initial agent selection (`id` from agents list). */\n defaultAgentId?: string;\n /** Initial skill selection (`id` from skills list). */\n defaultSkillId?: string;\n /** Project branding: panel title and assistant logo. */\n project?: AgentChatProjectConfig;\n /**\n * Replace the default floating bubble. Pass a render function for full control\n * (position, drag, open), or a React node mounted in a fixed-position slot\n * (use `useAgentChat().open()` inside your element).\n */\n launcher?: ReactNode | ((props: AgentChatLauncherProps) => ReactNode);\n}\n\nexport interface AgentMessageContentText {\n type: 'text';\n text: string;\n}\n\nexport type AgentMessageContent = AgentMessageContentText;\nexport type AgentMessageBlocks = Array<Record<string, unknown> & { type: string; id?: string }>;\n\nexport type AgentMessageRole = 'user' | 'agent' | 'system';\n\nexport type AgentMessageStatus = 'pending' | 'sent' | 'failed';\n\n/** Live assistant turn fed by SSE (`think` / `result` / `complete` / `error`). */\nexport interface AgentStreamState {\n phase: 'thinking' | 'result' | 'complete' | 'error';\n /** Accumulated thinking text from SSE `think` events (single block, appended in order). */\n thinkText: string;\n resultText: string;\n resultBlocks?: AgentMessageBlocks;\n runId?: number;\n seenSeq?: number[];\n errorMessage?: string;\n}\n\nexport type MessageFeedbackRating = 'up' | 'down';\n\nexport interface MessageFeedbackDownReasonTag {\n key: string;\n label: string;\n}\n\nexport interface MessageFeedbackView {\n messageId: number;\n rating: MessageFeedbackRating;\n reasonTags: string[];\n comment: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type UpsertMessageFeedbackBody =\n | { rating: 'up' }\n | {\n rating: 'down';\n reasonTags?: string[];\n comment?: string;\n };\n\nexport type MessageFeedbackBatchData = {\n items: MessageFeedbackView[];\n};\n\n/** User-selected page-context item attached to a single outgoing message. */\nexport interface ContextMentionAttachment {\n id: string;\n label: string;\n /** Metadata key used when merging into `pageContext.metadata` for this send. */\n kind: string;\n payload: Record<string, unknown>;\n}\n\nexport type ContextMentionGroup = 'page' | 'route' | 'metadata' | 'host';\n\n/** Host-registered @ mention catalog entry (see {@link AgentChatInstance.registerContextMentions}). */\nexport interface ContextMentionRegistration {\n id: string;\n label: string;\n /** Metadata merge key; defaults to registry id without `host:` prefix. */\n kind?: string;\n group?: ContextMentionGroup;\n description?: string;\n /** Static payload preview; merged with {@link resolve} result at send time. */\n payload?: Record<string, unknown>;\n /** Lazy payload resolver — return a string or record; SDK maps to inline `content`. */\n resolve?: () => string | Record<string, unknown> | Promise<string | Record<string, unknown>>;\n}\n\n/** Minimal host input — use {@link defineContextMention} or {@link useContextMentions}. */\nexport interface ContextMentionDefinition {\n /** Optional stable key; otherwise derived from {@link label}. */\n key?: string;\n label: string;\n group?: ContextMentionGroup;\n description?: string;\n value?: string | Record<string, unknown>;\n resolve?: () => string | Record<string, unknown> | Promise<string | Record<string, unknown>>;\n}\n\n/** Read-only registration snapshot exposed on {@link AgentChatState}. */\nexport interface RegisteredContextMention {\n id: string;\n label: string;\n kind: string;\n group?: ContextMentionGroup;\n description?: string;\n payload?: Record<string, unknown>;\n lazy?: boolean;\n}\n\nexport interface RegisterContextMentionsOptions {\n /** Replace the entire registry instead of merging by `id`. */\n replace?: boolean;\n}\n\nexport interface AgentMessage {\n id: string;\n role: AgentMessageRole;\n content: AgentMessageContent;\n /** Unix timestamp in milliseconds when the message was created. */\n createdAt: number;\n /** Local UI delivery state. Server-originated messages are always `sent`. */\n status?: AgentMessageStatus;\n /** Page-context @ mentions selected for this user message. */\n contextMentions?: ContextMentionAttachment[];\n /** Persisted thinking text from SSE `think` events (shown alongside result). */\n thinkText?: string;\n /** Populated while assistant reply streams over SSE. */\n stream?: AgentStreamState;\n /** Structured blocks for assistant content (table/chart/loading etc). */\n blocks?: AgentMessageBlocks;\n /** Current user's like/dislike on this assistant message. */\n feedback?: MessageFeedbackView | null;\n}\n\nexport interface SessionInfo {\n sessionId: string;\n conversationId: string;\n}\n\n/** Summary row for the session sidebar (`GET /chat`). */\nexport interface ChatSessionSummary {\n sessionId: string;\n title?: string;\n updatedAt?: number;\n preview?: string;\n}\n\n/** Agent option for the composer toolbar (`GET /agent/client/available`). */\nexport interface ChatAgentSummary {\n id: string;\n name: string;\n description?: string | null;\n}\n\nexport type AutoAgentSource = 'requested' | 'session' | 'auto' | 'default' | 'fallback';\n\nexport interface AutoAgentBinding {\n id: string;\n source?: AutoAgentSource;\n reason?: string | null;\n}\n\nexport type ToolLevel = 'L1' | 'L2' | 'L3';\n\n/** Skill option for the composer toolbar (`GET /agent/:agentId/skills/client`). */\nexport interface ChatSkillSummary {\n id: string;\n name: string;\n description?: string | null;\n agentId?: string;\n capabilityKey?: string | null;\n riskLevel?: ToolLevel;\n requiresWriteConfirmation?: boolean;\n toolIds?: number[];\n hostToolIds?: number[];\n /** Present only when `GET .../skills/client` was called with `?page=`. */\n pageMatched?: boolean;\n}\n\n/** Why the available-agent list is empty (client-side heuristic). */\nexport type AgentsEmptyReason = 'permission' | 'not_configured' | null;\n\n/** `GET /agent/client/available` query */\nexport interface QueryClientAvailableAgents {\n id?: number;\n definitionKey?: string;\n integrationId?: number;\n toolCategoryId?: number;\n toolCategoryIdIsNull?: boolean;\n name?: string;\n description?: string;\n path?: string;\n keyword?: string;\n riskLevel?: ToolLevel;\n method?: string;\n isActive?: boolean;\n}\n\n/** `GET /agent/:agentId/skills/client` query */\nexport interface QueryClientSkillByAgent {\n /** Page scope (kebab-case), same as `pageContext.page` / `HostPage.scope`. */\n page?: string;\n name?: string;\n capabilityKey?: string;\n keyword?: string;\n}\n\nexport interface AgentChatSessionsPayload {\n sessions: ChatSessionSummary[];\n}\n\nexport interface AgentChatErrorPayload {\n code: string;\n message: string;\n cause?: unknown;\n}\n\n/** Draft review decision submitted via `POST /chat/:sessionId/messages` `writeGate`. */\nexport type DraftReviewAction = 'confirm' | 'confirm_with_edits' | 'retry' | 'cancel';\n\nexport interface WriteGate {\n action: DraftReviewAction;\n /** Edited MessageBlocks JSON (`{ blocks: [...] }`). */\n editedPreviewSerialized?: string;\n /** Shallow merge into pending write tool arguments. */\n editedPendingWriteArguments?: Record<string, unknown>;\n /** Required when `action` is `retry`. */\n retryInstruction?: string;\n}\n\n/** Pending write-operation confirmation from SSE `confirmation_required`. */\nexport interface WriteConfirmationState {\n awaiting: boolean;\n submitting: boolean;\n runId: number;\n turnId?: number;\n message: string;\n /** Assistant bubble that triggered the confirmation. */\n messageId?: string;\n /** Session run generation — filters superseded SSE / gate UI. */\n generation?: number;\n draftRetryCount?: number;\n draftRetryMax?: number;\n canRetry?: boolean;\n /** Write draft from SSE — bind edits to `arguments`, not preview blocks. */\n writeDraft?: WriteDraftPublic | null;\n /** Additional pending write drafts when multiple tools await confirmation. */\n writeDrafts?: WriteDraftPublic[] | null;\n /** Server-derived edit rules for the write gate UI. */\n editPolicy?: EditPolicyPublic | null;\n /** Paired with `writeDrafts` by index. */\n editPolicies?: Array<EditPolicyPublic | null> | null;\n /** Gate-level validation error (gate stays open). */\n gateError?: string;\n gateErrorCode?: string;\n}\n\n/** Skill × user-intent alignment status from `route_plan` step output. */\nexport type SkillIntentAlignmentStatus =\n | 'none'\n | 'aligned'\n | 'intent_first'\n | 'clarified';\n\nexport type SkillIntentMismatchCode =\n | 'read_intent_vs_http_skill'\n | 'read_intent_vs_host_only_skill'\n | 'write_intent_vs_http_only_skill'\n | 'write_intent_vs_no_host_skill'\n | 'direct_answer_vs_any_skill'\n | 'orchestrated_http_vs_host_only_skill';\n\nexport type TurnSkillSelect = 'llm' | 'explicit' | 'page_host';\n\nexport type TurnScopedToolsSource = 'intent' | 'explicit_skill';\n\nexport type PageContextPlanKind = 'none' | 'inline_answer' | 'entity_read_detail';\n\nexport interface SkillIntentAlignmentSnapshot {\n status: SkillIntentAlignmentStatus;\n code?: SkillIntentMismatchCode;\n requestedSkillId?: number;\n droppedExplicitSkill?: boolean;\n}\n\n/** Parsed `route_plan` turn contract view (skill-intent-alignment + scoped tools). */\nexport interface SkillTurnContractView {\n skillAlignment: SkillIntentAlignmentSnapshot;\n skillSelect: TurnSkillSelect;\n scopedToolsSource: TurnScopedToolsSource;\n pageContextPlan: PageContextPlanKind;\n hostMutationIntent: boolean;\n requestedSkillId: number | null;\n}\n\n/** Shown when the server actually executed the pre-selected skill this turn. */\nexport interface SkillTurnActiveState {\n requestedSkillId?: number;\n requestedSkillName?: string;\n}\n\n/** Non-blocking hint when the server ignored the selected skill (`intent_first`). */\nexport interface SkillIntentBannerState {\n code?: SkillIntentMismatchCode;\n requestedSkillId?: number;\n requestedSkillName?: string;\n}\n\n/** Clarification card when write intent conflicts with the selected skill. */\nexport interface SkillIntentClarifyState {\n code: SkillIntentMismatchCode;\n requestedSkillId?: number;\n requestedSkillName?: string;\n /** User message from the conflicting turn — for resend without skill. */\n userMessage: string;\n /** Assistant bubble to attach the clarify card. */\n messageId?: string;\n runId?: number;\n}\n\n/** Brain entity disambiguation footer under an assistant bubble. */\nexport interface BrainClarifyUiState {\n messageId: string;\n runId: number;\n brainClarify: BrainClarifyPayload;\n}\n\nexport interface AgentChatMessagePayload {\n message: AgentMessage;\n source: AgentMessageRole;\n}\n\n/** Emitted when an assistant SSE turn completes while the panel is closed. */\nexport interface AgentChatBackgroundReplyPayload {\n sessionId: string;\n sessionTitle: string | null;\n}\n\nexport interface AgentChatEventMap extends Record<string, unknown> {\n ready: void;\n error: AgentChatErrorPayload;\n open: void;\n close: void;\n destroyed: void;\n session: SessionInfo;\n sessions: AgentChatSessionsPayload;\n message: AgentChatMessagePayload;\n hostAction: AgentChatHostActionPayload;\n /** Host-tool DSL lifecycle (`onStart` / `onStream` / `onComplete` / `onError`). */\n pageAgentLifecycle: PageAgentLifecyclePayload;\n /** Page Bot workflow paused for inbox approval. */\n pageAgentAwaitingApproval: PageAgentAwaitingApprovalPayload;\n /** Show built-in approval notice (panel mounted). */\n pageActionAwaitingApproval: PageActionAwaitingApprovalNoticePayload;\n /** Soft tip for already-active invoke (local row or HTTP 409) — never a host failure. */\n pageActionSoftNotice: PageActionSoftNoticePayload;\n backgroundReplyReady: AgentChatBackgroundReplyPayload;\n /** Emitted when inbox should refresh (PageAction awaiting approval / inbox confirm-reject). */\n approvalInboxChanged: void;\n /** Inbox approve/decide finished — surface PageAction execution status to the user. */\n approvalExecutionCompleted: ApprovalExecutionCompletedPayload;\n /** Open the panel and approval inbox drawer (launcher badge). */\n openApprovalInbox: OpenApprovalInboxPayload | undefined;\n /** Emitted when task center should refresh (PageAction invoke / run status change). */\n automationTaskCenterChanged: void;\n /** Open the panel and automation task center drawer (optional run deep-link). */\n openAutomationTaskCenter: OpenAutomationTaskCenterPayload | undefined;\n /** Open「我的反馈」drawer (rating + wish tabs). */\n openPageActionFeedback: OpenPageActionFeedbackPayload | undefined;\n /** PageAction invoke accepted — host may show a toast / launch animation. */\n pageActionSubmitted: PageActionSubmittedPayload;\n /** Per-row PageAction slot updated (list pages). */\n pageActionRowChanged: PageActionRowChangedPayload;\n /** Running PageAction SSE re-attached (refresh reconnect). */\n pageActionStreamResumed: PageActionStreamResumedPayload;\n /** Live run finished successfully. */\n pageActionRunCompleted: PageActionRunLifecyclePayload;\n /** Live run failed. */\n pageActionRunFailed: PageActionRunLifecyclePayload;\n /** Brain ASK_USER — show entity clarify popover (not a failure toast). */\n pageActionBrainClarify: PageActionBrainClarifyPromptRequest;\n /** Replay「应用到页面」started. */\n pageActionApplyStarted: PageActionRunLifecyclePayload;\n /** Replay「应用到页面」finished. */\n pageActionApplyCompleted: PageActionRunLifecyclePayload;\n /** Slot apply phase from {@link PageActionCoordinator}. */\n pageActionSlotApplyPhaseChanged: PageActionSlotApplyPhasePayload;\n /** 「应用到页面」pending intent changed (set / clear / consume). */\n pendingPageActionApplyChanged: PendingPageActionApply | null;\n}\n\nexport type AgentChatLifecycle =\n | 'uninitialized'\n | 'initialized'\n | 'destroyed';\n\nexport interface AgentChatState {\n lifecycle: AgentChatLifecycle;\n /** Current app DSN from init(); null before init completes. */\n dsn: string | null;\n isOpen: boolean;\n /** True after `POST /app-client/auth` succeeds during `init()`. Gates the launcher. */\n isClientAuthenticated: boolean;\n isLoggedIn: boolean;\n /** Sessions/agents catalog loaded at least once for the current login. */\n catalogHydrated: boolean;\n /** Normalized session ids with an open SSE connection. */\n streamingSessionIds: string[];\n /** Session ids that still have a pending assistant bubble in cache or active view. */\n pendingReplySessionIds: string[];\n session: SessionInfo | null;\n /** All chat sessions for the sidebar. */\n sessions: ChatSessionSummary[];\n /** Whether more sessions can be loaded (`GET /chat?page=&size=`). */\n sessionsHasMore: boolean;\n /** True while loading the next sessions page. */\n sessionsLoadingMore: boolean;\n /** Currently selected session; drives `messages`. */\n activeSessionId: string | null;\n messages: AgentMessage[];\n /** Whether older messages can be loaded for the active session. */\n sessionMessagesHasMore: boolean;\n /** True while loading older messages for the active session. */\n sessionMessagesLoadingMore: boolean;\n /** Available agents for the composer toolbar. */\n agents: ChatAgentSummary[];\n /** Skills for the currently selected agent. */\n skills: ChatSkillSummary[];\n selectedAgentId: string | null;\n /** Last server-side agent binding result. `source=\"auto\"` means Auto-Agent selected it. */\n autoAgent: AutoAgentBinding | null;\n selectedSkillId: string | null;\n agentsLoading: boolean;\n skillsLoading: boolean;\n /** Set when `client/available` is empty; uses `client/list` to distinguish permission vs config. */\n agentsEmptyReason: AgentsEmptyReason;\n lastError: AgentChatErrorPayload | null;\n /** Set when SSE requests user confirmation before executing write tools. */\n writeConfirmation: WriteConfirmationState | null;\n /** Pending automation approvals (`GET /approval/inbox`) — page_action / webhook only. */\n approvalInbox: ApprovalInboxState;\n /** PageAction automation history (`GET /automation/tasks`). */\n automationTaskCenter: AutomationTaskCenterState;\n /** Soft banner after `intent_first` alignment (selected skill not used). */\n skillIntentBanner: SkillIntentBannerState | null;\n /** Clarify card after `clarified` alignment (write intent vs skill). */\n skillIntentClarify: SkillIntentClarifyState | null;\n /** Brain entity disambiguation under the latest assistant bubble. */\n brainClarify: BrainClarifyUiState | null;\n /** Last `route_plan` turn contract (developer / diagnostics). */\n skillTurnContract: SkillTurnContractView | null;\n /** Shown when the server actually used the pre-selected skill this turn. */\n skillTurnActive: SkillTurnActiveState | null;\n /** When true, skill dropdown should open (e.g. from clarify card). */\n skillPickerOpen: boolean;\n /** Route path + params — always sent with user messages. */\n routeContext: AgentChatRouteContext | null;\n /** Extended host page context from `setPageContext` (manual). */\n pageContext: AgentChatPageContext | null;\n /** Host-registered @ mention catalog entries (without `resolve`). */\n registeredContextMentions: RegisteredContextMention[];\n /** UI preference for explicitly showing/attaching page context in the panel. */\n attachPageContext: boolean;\n /** Active session run coordinator snapshot (`GET .../run-state`); UI hints only. */\n activeSessionRun: SessionRunSnapshot | null;\n /** init / login 门禁当前挂起中的 API 调用 */\n pendingGateJobs: PendingGateJob[];\n}\n\nexport type { PendingGateJob, PendingGateJobKind } from './core/auth/login-gate';\n\n/** Subset of `GET /chat/:sessionId/run-state` exposed on {@link AgentChatState}. */\nexport interface SessionRunSnapshot {\n generation: number;\n activeRunId: number | null;\n pendingJobCount: number;\n redisBacked: boolean;\n}\n\nexport interface AgentChatLoginCredentials {\n email: string;\n password: string;\n}\n\n/**\n * Public surface of an omnix-chat instance. UI is rendered via React\n * (`<AgentChat />` from `omnix-chat/react`); this client is headless.\n */\nexport interface AgentChatInstance {\n init(options: AgentChatOptions): Promise<AgentChatInstance>;\n login(credentials: AgentChatLoginCredentials): Promise<void>;\n logout(): void;\n isLoggedIn(): boolean;\n /** init / login 门禁挂起任务快照 */\n getPendingGateJobs(): PendingGateJob[];\n destroy(): void;\n open(): void;\n close(): void;\n toggle(): void;\n isOpen(): boolean;\n /** Open the chat panel and the approval inbox drawer. */\n openApprovalInbox(opts?: OpenApprovalInboxPayload): void;\n /** Open the chat panel and the automation task center drawer. */\n openAutomationTaskCenter(opts?: OpenAutomationTaskCenterPayload): void;\n /** Open「我的反馈」drawer (场景评价 + 需求收集). */\n openPageActionFeedback(opts?: OpenPageActionFeedbackPayload): void;\n /**\n * `GET /page-action/catalog` — enabled PageActions for this App.\n * Global feedback center should omit `pageScope`.\n */\n fetchPageActionFeedbackCatalog(\n query?: PageActionFeedbackCatalogQuery,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackCatalogItem[]>;\n /** Last fetched catalog (empty until {@link fetchPageActionFeedbackCatalog}). */\n listPageActionFeedbackCatalog(): PageActionFeedbackCatalogItem[];\n /**\n * @deprecated Rating list comes from {@link fetchPageActionFeedbackCatalog}.\n * Kept as a no-op name overlay for optimistic task-center titles.\n */\n registerPageActionFeedbackCatalog(\n items: Array<{ actionKey: string; name?: string | null }>,\n ): void;\n getPageActionFeedback(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackView | null>;\n upsertPageActionFeedback(\n actionKey: string,\n body: UpsertPageActionFeedbackInput,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackView>;\n removePageActionFeedback(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<void>;\n getPageActionFeedbackSummary(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackSummary>;\n createPageActionWish(\n body: CreatePageActionWishInput,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView>;\n listPageActionWishes(\n query?: PageActionWishQuery,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishList>;\n getPageActionWish(\n id: number,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView>;\n cancelPageActionWish(\n id: number,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView>;\n identify(user: UserContext): void;\n /** Merge `pageContext` / `attachPageContext` from props without full re-init. */\n applyRuntimeOptions(\n options: Pick<AgentChatOptions, 'attachPageContext' | 'pageContext'>,\n ): void;\n /** Update extended host page context (entity, metadata, …) without re-init. */\n setPageContext(pageContext: AgentChatPageContext | null): void;\n /** Override auto-detected route path / params (e.g. from React Router). */\n setRouteContext(routeContext: AgentChatRouteContext | null): void;\n /** Register host-defined @ mention catalog entries for the composer. */\n registerContextMentions(\n items: Array<ContextMentionRegistration | ContextMentionDefinition>,\n options?: RegisterContextMentionsOptions,\n ): void;\n /** Remove host @ mention entries by id. */\n unregisterContextMentions(ids: string[]): void;\n /** Clear all host @ mention registrations. */\n clearContextMentions(): void;\n /** Re-read `window.location` and merge with any route override. */\n syncRouteContextFromWindow(): void;\n /** Toggle whether extended page context is sent with messages. */\n setAttachPageContext(attach: boolean): void;\n /** Current extended page context from `setPageContext` / props. */\n getPageContext(): AgentChatPageContext | null;\n /** App client id from init auth — used for host-tool server sync dedupe. */\n getAppClientId(): number | null;\n /** True when Bearer token + app client are ready for `POST /host-tool/client/register`. */\n isHostToolServerSyncReady(): boolean;\n /** Register a local host-tool handler (`*` scope for app-wide generic tools). */\n registerHostTool(scope: string, name: string, handler: HostToolHandler): void;\n unregisterHostTool(scope: string, name: string): void;\n undeclareHostTool(scope: string, name: string): void;\n /** Execute a registered host tool; returns false when not found. */\n runHostTool(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n ): Promise<boolean>;\n /** Local register + optional `POST /host-tool/client/register` sync. */\n registerHostToolsWithSync(options: RegisterHostToolsOptions): Promise<void>;\n /** Fetch server host-tool catalog for validation. */\n getHostToolCatalog(query?: { scope?: string; agentId?: number }): Promise<unknown>;\n selectSession(sessionId: string): Promise<void>;\n /** Delete a session via `DELETE /chat/{sessionId}`. */\n deleteSession(sessionId: string): Promise<void>;\n /**\n * Warm session runtime + host-tool cache via `POST /chat/{sessionId}/prepare`.\n * Sends current {@link AgentChatPageContext} (including `page`) when the host\n * has set page context — required for `hostToolsCount > 0` on the server.\n */\n prepareSession(\n sessionId: string,\n options?: AbortSignal | PrepareSessionOptions,\n ): Promise<PrepareSessionResult | null>;\n /** Fetch session list from `GET /chat` and refresh the sidebar. */\n refreshSessions(signal?: AbortSignal): Promise<void>;\n /** Load the next page of sessions when the sidebar is scrolled to the bottom. */\n loadMoreSessions(signal?: AbortSignal): Promise<void>;\n /** Load older messages when the message list is scrolled to the top. */\n loadMoreSessionMessages(signal?: AbortSignal): Promise<void>;\n /** Switch the active agent (reloads skills for that agent). */\n selectAgent(agentId: string): Promise<void>;\n /** Switch the active skill. */\n selectSkill(skillId: string): void;\n /** Dismiss the intent-first soft banner. */\n dismissSkillIntentBanner(): void;\n /** Clear skill selection from the intent-first banner. */\n clearSkillFromIntentBanner(): void;\n /** Dismiss the skill mismatch clarify card (keep selected skill). */\n dismissSkillIntentClarify(): void;\n /** Clear skill and resend the clarify turn user message. */\n followSkillIntentClarify(): Promise<void>;\n /** Dismiss the Brain entity clarify footer. */\n dismissBrainClarify(): void;\n /** Commit a Brain clarify candidate and continue the chat turn. */\n commitBrainClarify(selectedId: string): Promise<void>;\n /** Open the skill picker (clarify flow). */\n openSkillPicker(): void;\n /** Close the skill picker overlay. */\n closeSkillPicker(): void;\n sendMessage(\n text: string,\n opts?: {\n id?: string;\n contextMentions?: ContextMentionAttachment[];\n entityCommit?: EntityCommit;\n },\n ): Promise<AgentMessage>;\n /** Confirm a pending chat write gate (session SSE bubble — not the approval inbox). */\n confirmWrite(): Promise<void>;\n /** Submit edited draft preview / write arguments (`writeGate.action: confirm_with_edits`). */\n confirmWriteWithEdits(input: {\n editedPreviewSerialized?: string;\n editedPendingWriteArguments?: Record<string, unknown>;\n }): Promise<void>;\n /** Regenerate draft with user instruction (`writeGate.action: retry`). */\n retryWrite(retryInstruction: string): Promise<void>;\n /** Cancel a pending chat write gate (session SSE bubble — not the approval inbox). */\n cancelWrite(): Promise<void>;\n /** Refresh page_action / webhook pending approvals (`GET /approval/inbox`). */\n refreshApprovalInbox(opts?: {\n signal?: AbortSignal;\n status?: ApprovalInboxStatusFilter;\n limit?: number;\n offset?: number;\n append?: boolean;\n }): Promise<ApprovalInboxList>;\n setApprovalInboxStatusFilter(status: ApprovalInboxStatusFilter): void;\n refreshApprovalPendingCount(signal?: AbortSignal): Promise<void>;\n /** `GET /approval/:id` */\n getApproval(id: number, signal?: AbortSignal): Promise<ApprovalDetail | null>;\n /** Refresh a single inbox row from `GET /approval/:id` (after retry `suspended: true`). */\n hydrateApprovalInboxItem(id: number, signal?: AbortSignal): Promise<ApprovalDetail | null>;\n /** `POST /approval/:id/confirm` */\n confirmApproval(id: number, signal?: AbortSignal): Promise<ApprovalConfirmResult>;\n /** `POST /approval/:id/decide` — page_action draft review (confirm / edit / retry / cancel). */\n decideApproval(\n id: number,\n decision: DraftReviewDecision,\n opts?: { reason?: string; signal?: AbortSignal },\n ): Promise<ApprovalDecideResult>;\n /** `POST /approval/:id/reject` */\n rejectApproval(id: number, reason?: string, signal?: AbortSignal): Promise<ApprovalRejectResult>;\n /** Refresh automation tasks (`GET /automation/tasks`). */\n refreshAutomationTasks(opts?: {\n signal?: AbortSignal;\n status?: AutomationTaskStatusFilter;\n actionKey?: string;\n limit?: number;\n offset?: number;\n append?: boolean;\n }): Promise<AutomationTaskList>;\n setAutomationTaskStatusFilter(status: AutomationTaskStatusFilter): void;\n /**\n * Activate a task-center tab: restore cached list, or fetch page 1 when never loaded.\n * Pass `{ refresh: true }` to force-refresh page 1 (manual refresh button).\n */\n ensureAutomationTaskTabLoaded(\n status?: AutomationTaskStatusFilter,\n opts?: { refresh?: boolean; signal?: AbortSignal },\n ): Promise<void>;\n /** Append the next page for the current task-center tab (no-op while loading or no more). */\n loadAutomationTaskNextPage(opts?: { signal?: AbortSignal }): Promise<void>;\n /** Active PageAction runs — derived from in-memory run registry (no polling). */\n refreshAutomationActiveCount(signal?: AbortSignal): Promise<void>;\n /** Reconcile active tasks after tab becomes visible (event-driven, not interval). */\n reconcileAutomationTasksIfNeeded(): void;\n /** `GET /automation/tasks/page_action_run/:id` */\n getAutomationTaskDetail(\n runId: number,\n signal?: AbortSignal,\n ): Promise<AutomationTaskDetail | null>;\n /** Hydrate selected detail row in task center state. */\n hydrateAutomationTaskDetail(runId: number, signal?: AbortSignal): Promise<AutomationTaskDetail | null>;\n /** Clear task center detail view (back to list). */\n clearAutomationTaskDetail(): void;\n /**\n * 任务中心「应用到页面」:只导航 + 写入 pendingApply,不直接 replay。\n * 目标页 `usePageAction({ ready })` 就绪后自动 `replayPageAction`。\n * @see AgentChatOptions.onNavigateForPageAction\n */\n applyPageActionToPage(\n runId: number,\n opts?: { signal?: AbortSignal },\n ): Promise<import('./core/page/page-context-navigate').ApplyPageActionToPageResult>;\n /**\n * 重放已完成 PageAction 的 stream 产出。\n * 通常由 `usePageAction` 在 pending + ready 时调用;也可手动调用。\n */\n replayPageAction(runId: number, opts?: { signal?: AbortSignal }): Promise<void>;\n /** Current「应用到页面」pending intent (memory + sessionStorage). */\n getPendingPageActionApply(): PendingPageActionApply | null;\n /** Clear pending apply intent. */\n clearPendingPageActionApply(): void;\n /**\n * Attach (or no-op if already attached) to a running PageAction SSE stream.\n * Used after refresh to resume host_action / prose delivery.\n */\n attachPageActionStream(\n runId: number,\n opts?: { signal?: AbortSignal; rowKey?: string },\n ): Promise<boolean>;\n /**\n * After reconcile: attach streams for active `running` tasks matching `actionKey`.\n * @returns number of streams attached this call\n */\n resumeActivePageActionStreams(opts?: {\n actionKey?: string;\n signal?: AbortSignal;\n }): Promise<number>;\n /** Register a run id after invoke (list highlight / badge bump). */\n registerAutomationRun(\n runId: number,\n meta?: {\n actionKey?: string;\n accepted?: InvokePageActionAccepted;\n pageActionKey?: string | null;\n rowKey?: string | null;\n },\n ): void;\n /** Whether the server `pageActionKey` still has an active run in the local registry. */\n isPageActionKeyActive(pageActionKey: string | null | undefined): boolean;\n /**\n * Active `pageActionKey` for an `actionKey`, if any (from registry / task list sync).\n * List pages with multiple rows may have several — prefer {@link getPageActionRowState}.\n */\n getActivePageActionKeyForActionKey(actionKey: string): string | null;\n /** Read per-row PageAction UI state (list pages). */\n getPageActionRowState(rowKey: string): PageActionRowState | null;\n /** All known row slots for an `actionKey`. */\n getPageActionRowsForActionKey(actionKey: string): PageActionRowState[];\n /** Whether a list row currently has an active / pending PageAction. */\n isPageActionRowActive(rowKey: string): boolean;\n /** Clear error text on a row slot. */\n clearPageActionRowError(rowKey: string): void;\n /** Hydrate one row slot from `GET /automation/tasks/page_action_run/:runId`. */\n hydratePageActionByRunId(\n runId: number,\n opts?: { rowKey?: string; actionKey?: string; signal?: AbortSignal },\n ): Promise<PageActionRowState | null>;\n /**\n * Pull active tasks and refresh row slots for an `actionKey`\n * (`GET /automation/tasks?status=active&actionKey=`).\n */\n reconcileActivePageActions(opts?: {\n actionKey?: string;\n signal?: AbortSignal;\n }): Promise<PageActionRowState[]>;\n /**\n * Register a PageAction UI slot for restore (refresh / login / apply).\n * Returns unbind. Prefer hooks — hosts rarely call directly.\n */\n bindPageActionSlot(binding: {\n actionKey: string;\n rowKey: string;\n pageContext?: AgentChatPageContext | null;\n ready?: boolean;\n autoResume?: boolean;\n autoApplyPending?: boolean;\n }): () => void;\n /** Update a bound slot (e.g. `ready` flipped). */\n patchPageActionSlot(\n slotKey: string,\n patch: {\n pageContext?: AgentChatPageContext | null;\n ready?: boolean;\n autoResume?: boolean;\n autoApplyPending?: boolean;\n },\n ): void;\n /** @internal Demo / integration — slots registered via bindPageActionSlot */\n listBoundPageActionSlots(): Array<{\n actionKey: string;\n rowKey: string;\n pageContext?: AgentChatPageContext | null;\n ready: boolean;\n autoResume: boolean;\n autoApplyPending: boolean;\n }>;\n prefetch(): Promise<void>;\n /** Clear active session; next message starts a new chat. */\n startNewChat(): Promise<void>;\n /** Abort the current assistant SSE reply via `POST .../cancel-run`. */\n cancelGeneration(): Promise<void>;\n /**\n * Invoke a Page Bot action (no chat `sessionId`).\n * `POST /page-action/brain-invoke` returns JSON; SSE is on `GET .../runs/:id/stream`.\n * When the chat UI is mounted, may first show a reuse popover for prior successful runs.\n */\n invokePageAction(input: PageBotInvokeInput): Promise<PageBotStreamResult>;\n /** `POST /page-action/reuse-hint` — soft check for reusable successful runs. */\n reusePageActionHint(\n input: Pick<\n PageBotInvokeInput,\n 'actionKey' | 'pageContext' | 'instruction' | 'context' | 'signal'\n > & { refresh?: boolean },\n ): Promise<PageActionReuseHint>;\n /**\n * Register the built-in reuse popover (ChatRoot). Without a handler, invoke skips reuse.\n */\n setPageActionReusePromptHandler(\n handler: PageActionReusePromptHandler | null,\n ): () => void;\n /** Close Brain clarify UI and unlock the row (user dismissed without picking). */\n dismissPageActionBrainClarify(input?: {\n rowKey?: string | null;\n runId?: number | null;\n }): void;\n /**\n * Unlock the trigger after docked reuse「撤销」/ before「继续执行」.\n * Aborts in-flight historical replay so late SSE cannot soft-lock the button.\n */\n dismissPageActionReuse(input?: {\n rowKey?: string | null;\n runId?: number | null;\n }): void;\n /** Cached down-reason tags for the feedback modal (fetched on first use). */\n getDownReasonTags(): Promise<MessageFeedbackDownReasonTag[]>;\n /** Like or dislike an assistant message (`PUT .../feedback`). */\n submitMessageFeedback(\n messageId: string,\n body: UpsertMessageFeedbackBody,\n ): Promise<void>;\n /** Cancel like/dislike on a message (`DELETE .../feedback`). */\n removeMessageFeedback(messageId: string): Promise<void>;\n getState(): AgentChatState;\n on<K extends keyof AgentChatEventMap>(\n event: K,\n handler: (payload: AgentChatEventMap[K]) => void,\n ): () => void;\n off<K extends keyof AgentChatEventMap>(\n event: K,\n handler: (payload: AgentChatEventMap[K]) => void,\n ): void;\n}\n\nexport type { AgentChatError };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.legacy-types-C11EZiOU.js","names":[],"sources":["../src/core/chat/message-blocks.ts","../src/core/draft-review/write-draft.ts","../src/core/draft-review/param-path.ts","../src/core/draft-review/edit-policy.ts","../src/core/draft-review/draft-review-bundle.ts","../src/core/page/skill-client.ts","../src/core/page/route-context.ts","../src/core/page/brain-clarify.ts","../src/core/approval/entity-reference.ts","../src/core/approval/approval-response.ts","../src/core/feedback/feedback-utils.ts","../src/core/page/page-action-workflow-progress.ts","../src/core/page/page-action-launch.ts","../src/core/page/page-action-process-view.ts","../src/types.ts"],"sourcesContent":["export type CoreMessageBlock = Record<string, unknown> & { type: string; id?: string };\n\nexport interface CoreMessageBlockPatch {\n replaceId: string;\n block: CoreMessageBlock;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function parseStoredBlocks(content: string | null | undefined): CoreMessageBlock[] | undefined {\n if (!content) return undefined;\n const trimmed = content.trim();\n if (!trimmed || trimmed[0] !== '{') return undefined;\n try {\n const parsed = JSON.parse(trimmed) as { blocks?: unknown };\n if (!Array.isArray(parsed.blocks)) return undefined;\n return parsed.blocks.filter(\n (item): item is CoreMessageBlock => isRecord(item) && typeof item.type === 'string',\n );\n } catch {\n return undefined;\n }\n}\n\nexport function blocksToText(blocks: CoreMessageBlock[] | undefined): string {\n if (!blocks?.length) return '';\n return blocks\n .map((block) => (block.type === 'text' && typeof block.content === 'string' ? block.content : ''))\n .join('');\n}\n\n/** Serialize blocks for `writeGate.editedPreviewSerialized` (same shape as stored assistant messages). */\nexport function serializeMessageBlocksForStorage(blocks: CoreMessageBlock[]): string {\n return JSON.stringify({ blocks });\n}\n\n/** Build `editedPreviewSerialized` after the user edits plain text in the gate editor. */\nexport function buildEditedPreviewFromText(\n editedText: string,\n sourceBlocks?: CoreMessageBlock[],\n): string {\n if (sourceBlocks?.length) {\n let replacedText = false;\n const next = sourceBlocks.map((block) => {\n if (block.type === 'text') {\n replacedText = true;\n return { ...block, content: editedText };\n }\n return block;\n });\n if (!replacedText) {\n next.unshift({ type: 'text', format: 'markdown', content: editedText });\n }\n return serializeMessageBlocksForStorage(next);\n }\n return serializeMessageBlocksForStorage([\n { type: 'text', format: 'markdown', content: editedText },\n ]);\n}\n\nfunction appendDeltaText(previous: CoreMessageBlock[], incoming: CoreMessageBlock[]): CoreMessageBlock[] {\n let textPiece = '';\n for (const block of incoming) {\n if (block.type === 'text' && typeof block.content === 'string') {\n textPiece += block.content;\n }\n }\n if (!textPiece) return previous;\n const next = [...previous];\n const last = next[next.length - 1];\n if (last?.type === 'text' && typeof last.content === 'string') {\n next[next.length - 1] = { ...last, content: `${last.content}${textPiece}` };\n return next;\n }\n next.push({ type: 'text', format: 'markdown', content: textPiece });\n return next;\n}\n\nconst STRUCTURED_BLOCK_TYPES = new Set([\n 'table',\n 'chart',\n 'metric',\n 'list',\n 'image',\n 'alert',\n]);\n\nfunction stripBlocksJsonTextBlocks(blocks: CoreMessageBlock[]): CoreMessageBlock[] {\n return blocks.filter((block) => {\n if (block.type !== 'text' || typeof block.content !== 'string') {\n return true;\n }\n const trimmed = block.content.trimStart();\n if (!trimmed.startsWith('{')) {\n return true;\n }\n return !parseStoredBlocks(block.content);\n });\n}\n\nfunction looksLikeMarkdownTable(text: string): boolean {\n const lines = text.trim().split('\\n').filter((line) => line.trim().length > 0);\n if (lines.length < 2) return false;\n return lines.slice(0, 3).some((line) => line.includes('|'));\n}\n\nfunction replaceOrAppendStructuredBlock(\n next: CoreMessageBlock[],\n block: CoreMessageBlock,\n): CoreMessageBlock[] {\n const id = typeof block.id === 'string' ? block.id.trim() : '';\n if (id) {\n const hit = next.findIndex((item) => item.id === id);\n if (hit >= 0) {\n const copy = [...next];\n copy[hit] = { ...block, id };\n return copy;\n }\n return [...next, { ...block, id }];\n }\n\n if (STRUCTURED_BLOCK_TYPES.has(block.type)) {\n const hit = next.findIndex((item) => item.type === block.type);\n if (hit >= 0) {\n const copy = [...next];\n copy[hit] = block;\n return copy;\n }\n }\n\n return [...next, block];\n}\n\nexport function applyStreamFull(previous: CoreMessageBlock[], incoming: CoreMessageBlock[]): CoreMessageBlock[] {\n let next = [...previous];\n const incomingHasStructured = incoming.some(\n (block) => block.type !== 'text' && block.type !== 'loading',\n );\n if (incomingHasStructured) {\n next = stripBlocksJsonTextBlocks(next);\n }\n const hasStructuredBlock = next.some((item) => STRUCTURED_BLOCK_TYPES.has(item.type));\n let sawText = false;\n\n for (const block of incoming) {\n if (block.type === 'text') {\n sawText = true;\n const text = typeof block.content === 'string' ? block.content : '';\n if (!text) continue;\n const hasDeltaText = next.some((item) => item.type === 'text' && typeof item.content === 'string');\n if (hasDeltaText) continue;\n // After patch/table blocks, ignore duplicate markdown table fallback from backend.\n if (hasStructuredBlock && looksLikeMarkdownTable(text)) continue;\n next.push({ ...block, content: text });\n continue;\n }\n next = replaceOrAppendStructuredBlock(next, block);\n }\n\n if (!sawText && incoming.length === 0) return previous;\n return next;\n}\n\nexport function applyStreamDelta(previous: CoreMessageBlock[], incoming: CoreMessageBlock[]): CoreMessageBlock[] {\n return appendDeltaText(previous, incoming);\n}\n\nfunction unescapeJsonStringFragment(fragment: string): string {\n let out = '';\n for (let i = 0; i < fragment.length; i += 1) {\n const ch = fragment[i];\n if (ch !== '\\\\') {\n out += ch;\n continue;\n }\n const next = fragment[i + 1];\n if (next === undefined) {\n out += ch;\n break;\n }\n switch (next) {\n case 'n':\n out += '\\n';\n break;\n case 't':\n out += '\\t';\n break;\n case 'r':\n out += '\\r';\n break;\n case '\"':\n out += '\"';\n break;\n case '\\\\':\n out += '\\\\';\n break;\n default:\n out += next;\n break;\n }\n i += 1;\n }\n return out;\n}\n\nfunction looksLikeBlocksJsonStreaming(text: string): boolean {\n const trimmed = text.trimStart();\n if (!trimmed.startsWith('{')) return false;\n return /\"blocks\"/.test(trimmed);\n}\n\nconst STREAMING_TEXT_CONTENT_MARKER =\n /\"type\"\\s*:\\s*\"text\"\\s*,\\s*\"content\"\\s*:\\s*\"/;\n\n/**\n * Extract markdown from an in-progress `{\"blocks\":[{\"type\":\"text\",\"content\":\"...\"}]}` payload.\n * Returns `undefined` when the string is not a blocks JSON envelope.\n * Returns `null` when the envelope prefix is still streaming (hide raw JSON).\n */\nexport function extractPartialBlocksJsonTextContent(raw: string): string | null | undefined {\n if (!looksLikeBlocksJsonStreaming(raw)) return undefined;\n\n const parsed = parseStoredBlocks(raw);\n if (parsed) return blocksToText(parsed);\n\n const match = STREAMING_TEXT_CONTENT_MARKER.exec(raw);\n if (!match) return null;\n\n const start = match.index + match[0].length;\n let i = start;\n let escaped = '';\n while (i < raw.length) {\n const ch = raw[i];\n if (ch === '\\\\') {\n if (i + 1 >= raw.length) {\n escaped += ch;\n break;\n }\n escaped += raw.slice(i, i + 2);\n i += 2;\n continue;\n }\n if (ch === '\"') break;\n escaped += ch;\n i += 1;\n }\n return unescapeJsonStringFragment(escaped);\n}\n\n/**\n * When the model streams a full `{\"blocks\":[...]}` JSON string inside a single\n * text block, unwrap it into structured blocks for rendering.\n */\nexport function unwrapBlocksJsonEnvelope(blocks: CoreMessageBlock[]): CoreMessageBlock[] {\n if (blocks.length !== 1) return blocks;\n const only = blocks[0];\n if (only?.type !== 'text' || typeof only.content !== 'string') return blocks;\n const parsed = parseStoredBlocks(only.content);\n if (parsed && parsed.length > 0) return parsed;\n\n const partial = extractPartialBlocksJsonTextContent(only.content);\n if (partial !== undefined) {\n const format = typeof only.format === 'string' ? only.format : 'markdown';\n return [{ type: 'text', format, content: partial ?? '' }];\n }\n\n return blocks;\n}\n\nexport function applyPatches(\n previous: CoreMessageBlock[],\n patches: CoreMessageBlockPatch[],\n): CoreMessageBlock[] {\n if (!patches.length) return previous;\n const next = [...previous];\n for (const patch of patches) {\n const id = patch.replaceId.trim();\n if (!id) continue;\n const hit = next.findIndex((block) => block.id === id);\n if (hit >= 0) next[hit] = { ...patch.block, id };\n else next.push({ ...patch.block, id });\n }\n return next;\n}\n","import type { CoreMessageBlock } from '../chat/message-blocks';\n\nexport type WriteDraftLastEvent = 'composed' | 'suspended' | 'user_edit' | 'retry';\n\n/** C-end write draft — execution truth is `arguments`; presentation is view-only. */\nexport interface WriteDraftPublic {\n version: number;\n tool: {\n name: string;\n toolId?: number;\n riskLevel: string;\n };\n arguments: Record<string, unknown>;\n presentation: {\n summaryText?: string | null;\n previewBlocks: CoreMessageBlock[];\n };\n provenance: {\n draftRetryCount: number;\n draftRetryMax: number;\n canRetry: boolean;\n composedAt: string;\n lastEvent: WriteDraftLastEvent;\n };\n}\n\nexport interface WriteDraftEditPayload {\n editedPendingWriteArguments?: Record<string, unknown>;\n editedPreviewSerialized?: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction readNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n return undefined;\n}\n\nfunction parsePreviewBlocks(value: unknown): CoreMessageBlock[] {\n if (!Array.isArray(value)) return [];\n return value.filter(\n (item): item is CoreMessageBlock =>\n isRecord(item) && typeof item.type === 'string',\n );\n}\n\n/** Parse SSE / inbox `writeDraft` payload. */\nexport function parseWriteDraftPublic(value: unknown): WriteDraftPublic | null {\n if (!isRecord(value)) return null;\n const version = readNumber(value.version);\n const toolRaw = value.tool;\n if (version == null || !isRecord(toolRaw)) return null;\n const toolName = readString(toolRaw.name);\n if (!toolName) return null;\n const toolId = readNumber(toolRaw.toolId);\n const riskLevel = readString(toolRaw.riskLevel) ?? 'L2';\n const args = isRecord(value.arguments) ? value.arguments : null;\n if (!args) return null;\n const presentationRaw = value.presentation;\n const presentation = isRecord(presentationRaw)\n ? {\n summaryText:\n typeof presentationRaw.summaryText === 'string' ? presentationRaw.summaryText : null,\n previewBlocks: parsePreviewBlocks(presentationRaw.previewBlocks),\n }\n : { summaryText: null, previewBlocks: [] as CoreMessageBlock[] };\n const provenanceRaw = value.provenance;\n const draftRetryCount = isRecord(provenanceRaw)\n ? (readNumber(provenanceRaw.draftRetryCount) ?? 0)\n : 0;\n const draftRetryMax = isRecord(provenanceRaw)\n ? (readNumber(provenanceRaw.draftRetryMax) ?? 3)\n : 3;\n const canRetry = isRecord(provenanceRaw)\n ? provenanceRaw.canRetry === false\n ? false\n : provenanceRaw.canRetry === true\n ? true\n : draftRetryCount < draftRetryMax\n : true;\n const composedAt = isRecord(provenanceRaw)\n ? (readString(provenanceRaw.composedAt) ?? new Date(0).toISOString())\n : new Date(0).toISOString();\n const lastEventRaw = isRecord(provenanceRaw) ? readString(provenanceRaw.lastEvent) : undefined;\n const lastEvent: WriteDraftLastEvent =\n lastEventRaw === 'composed' ||\n lastEventRaw === 'suspended' ||\n lastEventRaw === 'user_edit' ||\n lastEventRaw === 'retry'\n ? lastEventRaw\n : 'suspended';\n\n return {\n version,\n tool: {\n name: toolName,\n ...(toolId != null ? { toolId } : {}),\n riskLevel,\n },\n arguments: args,\n presentation,\n provenance: {\n draftRetryCount,\n draftRetryMax,\n canRetry,\n composedAt,\n lastEvent,\n },\n };\n}\n\nexport function cloneWriteDraftArguments(\n draft: WriteDraftPublic,\n): Record<string, unknown> {\n return structuredClone(draft.arguments);\n}\n\n/** Bind editor to `writeDraft.arguments` (form-driven). */\nexport function argumentsToEditorText(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 1 && typeof args.content === 'string') {\n return args.content;\n }\n if (keys.length > 0 && keys.every((key) => key === 'content' || args[key] === undefined)) {\n if (typeof args.content === 'string') return args.content;\n }\n try {\n return JSON.stringify(args, null, 2);\n } catch {\n return '';\n }\n}\n\nexport function editorTextToArguments(\n original: Record<string, unknown>,\n text: string,\n): Record<string, unknown> {\n const trimmed = text.trim();\n if (trimmed.startsWith('{')) {\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (isRecord(parsed) && !Array.isArray(parsed)) {\n return parsed;\n }\n } catch {\n /* fall through to scalar mapping */\n }\n }\n if (typeof original.content === 'string' || 'content' in original) {\n return { ...original, content: text };\n }\n return { content: text };\n}\n\nexport function buildConfirmWithEdits(\n draft: WriteDraftPublic,\n editedArgs: Record<string, unknown>,\n): WriteDraftEditPayload {\n return buildConfirmWithEditsFromArguments(draft.arguments, editedArgs);\n}\n\nexport function buildConfirmWithEditsFromArguments(\n original: Record<string, unknown>,\n edited: Record<string, unknown>,\n): WriteDraftEditPayload {\n const patch: Record<string, unknown> = {};\n const keys = new Set([...Object.keys(original), ...Object.keys(edited)]);\n for (const key of keys) {\n if (JSON.stringify(original[key]) !== JSON.stringify(edited[key])) {\n patch[key] = edited[key];\n }\n }\n return {\n editedPendingWriteArguments: Object.keys(patch).length > 0 ? patch : edited,\n };\n}\n","import type { EditPolicyPublic } from './edit-policy';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readSegments(path: string): string[] {\n return path.replace(/\\[\\]/g, '').split('.').filter(Boolean);\n}\n\nexport function readRootParamPath(args: Record<string, unknown>, path: string): unknown {\n let cursor: unknown = args;\n for (const segment of readSegments(path)) {\n if (!isRecord(cursor)) return undefined;\n cursor = cursor[segment];\n }\n return cursor;\n}\n\nexport function parseArrayItemSubmitPath(\n path: string,\n): { arrayPath: string; leafPath: string } | null {\n const match = /^(.+)\\[\\]\\.(.+)$/.exec(path.trim());\n if (!match) return null;\n return { arrayPath: match[1], leafPath: match[2] };\n}\n\n/** Read tool argument values using compact paths (`items[].body`). */\nexport function readValueAtParamPath(\n args: Record<string, unknown>,\n path: string,\n): unknown {\n const trimmed = path.trim();\n if (!trimmed) return undefined;\n\n const arrayParts = parseArrayItemSubmitPath(trimmed);\n if (arrayParts) {\n const arrayValue = readRootParamPath(args, arrayParts.arrayPath);\n if (!Array.isArray(arrayValue)) return undefined;\n for (const item of arrayValue) {\n if (isRecord(item) && arrayParts.leafPath in item) {\n return item[arrayParts.leafPath];\n }\n }\n return undefined;\n }\n\n return readRootParamPath(args, trimmed);\n}\n\nexport interface SubmitPathPreviewItem {\n index: number;\n label: string;\n text: string;\n meta: Array<{ label: string; value: string }>;\n}\n\nfunction formatScalar(value: unknown): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n if (typeof value === 'number') return String(value);\n return '';\n}\n\nfunction resolveFieldLabel(policy: EditPolicyPublic, path: string): string {\n return policy.fields.find((field) => field.path === path)?.label?.trim() || path;\n}\n\nfunction resolveArrayItemMeta(\n policy: EditPolicyPublic,\n arrayPath: string,\n item: Record<string, unknown>,\n submitLeaf: string,\n): Array<{ label: string; value: string }> {\n const prefix = `${arrayPath}[].`;\n return policy.fields\n .filter((field) => {\n if (!field.path.startsWith(prefix)) return false;\n const leaf = field.path.slice(prefix.length);\n if (!leaf || leaf.includes('.') || leaf === submitLeaf) return false;\n if (field.path === policy.submitPath) return false;\n return field.role === 'identifier' || field.widget === 'readonly';\n })\n .map((field) => {\n const leaf = field.path.slice(prefix.length);\n const raw = leaf in item ? item[leaf] : field.value;\n return { label: field.label, value: formatScalar(raw) };\n })\n .filter((row) => row.value.trim().length > 0);\n}\n\nfunction resolveScalarContextMeta(\n policy: EditPolicyPublic,\n args: Record<string, unknown>,\n): Array<{ label: string; value: string }> {\n const submitPath = policy.submitPath?.trim();\n return policy.fields\n .filter((field) => {\n if (field.path === submitPath) return false;\n if (field.path.includes('[]')) return false;\n return field.role === 'identifier' || field.widget === 'readonly';\n })\n .map((field) => ({\n label: field.label,\n value: formatScalar(readValueAtParamPath(args, field.path) ?? field.value),\n }))\n .filter((row) => row.value.trim().length > 0);\n}\n\n/** Expand `editPolicy.submitPath` into user-facing preview rows (supports `arr[].leaf`). */\nexport function resolveSubmitPathPreviewItems(\n args: Record<string, unknown>,\n policy: EditPolicyPublic,\n): SubmitPathPreviewItem[] {\n const submitPath = policy.submitPath?.trim();\n if (!submitPath) return [];\n\n const baseLabel = resolveFieldLabel(policy, submitPath);\n const arrayParts = parseArrayItemSubmitPath(submitPath);\n\n if (!arrayParts) {\n const value = readValueAtParamPath(args, submitPath);\n const text = typeof value === 'string' ? value : formatScalar(value);\n if (!text.trim()) return [];\n return [\n {\n index: 0,\n label: baseLabel,\n text,\n meta: resolveScalarContextMeta(policy, args),\n },\n ];\n }\n\n const arrayValue = readRootParamPath(args, arrayParts.arrayPath);\n if (!Array.isArray(arrayValue) || arrayValue.length === 0) return [];\n\n const items = arrayValue\n .map((entry, index) => {\n if (!isRecord(entry)) return null;\n const raw = entry[arrayParts.leafPath];\n const text = typeof raw === 'string' ? raw : formatScalar(raw);\n if (!text.trim()) return null;\n const label =\n arrayValue.length > 1 ? `${baseLabel} (${index + 1}/${arrayValue.length})` : baseLabel;\n return {\n index,\n label,\n text,\n meta: resolveArrayItemMeta(policy, arrayParts.arrayPath, entry, arrayParts.leafPath),\n };\n })\n .filter((item): item is SubmitPathPreviewItem => item != null);\n\n if (items.length > 0) return items;\n\n return [\n {\n index: 0,\n label: baseLabel,\n text: '',\n meta: resolveScalarContextMeta(policy, args),\n },\n ];\n}\n\nexport function readSubmitPathText(\n args: Record<string, unknown>,\n submitPath: string | null | undefined,\n policy?: EditPolicyPublic | null,\n): string {\n if (policy?.submitPath) {\n const items = resolveSubmitPathPreviewItems(args, policy);\n if (items.length === 1) return items[0].text;\n if (items.length > 1) {\n return items.map((item) => item.text).join('\\n\\n');\n }\n }\n if (!submitPath?.trim()) return '';\n const value = readValueAtParamPath(args, submitPath);\n if (typeof value === 'string') return value;\n return '';\n}\n\n/** Server machine preview — JSON dump in markdown, not user-facing copy. */\nexport function isMachineJsonPreview(text: string): boolean {\n const trimmed = text.trim();\n if (!trimmed) return false;\n if (/```json[\\s\\S]*```/i.test(trimmed)) return true;\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n JSON.parse(trimmed);\n return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n","import {\n blocksToText,\n buildEditedPreviewFromText,\n type CoreMessageBlock,\n} from '../chat/message-blocks';\nimport type { WriteDraftEditPayload, WriteDraftPublic } from './write-draft';\nimport { buildConfirmWithEditsFromArguments } from './write-draft';\nimport {\n isMachineJsonPreview,\n resolveSubmitPathPreviewItems,\n} from './param-path';\n\nexport type EditPolicyMode = 'preview_only' | 'allowlisted_fields' | 'full';\n\nexport type EditPolicyFieldRole =\n | 'content'\n | 'identifier'\n | 'scenario'\n | 'enum'\n | 'system';\n\nexport type EditPolicyFieldWidget =\n | 'text'\n | 'textarea'\n | 'select'\n | 'readonly'\n | 'hidden';\n\nexport interface EditPolicyEnumOption {\n label: string;\n value: string;\n}\n\nexport interface EditPolicyField {\n path: string;\n label: string;\n role: EditPolicyFieldRole;\n widget: EditPolicyFieldWidget;\n editable: boolean;\n required: boolean;\n value: unknown;\n enumOptions?: EditPolicyEnumOption[];\n reason?: string | null;\n}\n\nexport interface EditPolicyPublic {\n editMode: EditPolicyMode;\n submitPath?: string | null;\n allowArgumentsPatch: boolean;\n fields: EditPolicyField[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction readRole(value: unknown): EditPolicyFieldRole {\n const raw = readString(value);\n if (\n raw === 'content' ||\n raw === 'identifier' ||\n raw === 'scenario' ||\n raw === 'enum' ||\n raw === 'system'\n ) {\n return raw;\n }\n return 'system';\n}\n\nfunction readWidget(value: unknown): EditPolicyFieldWidget {\n const raw = readString(value);\n if (\n raw === 'text' ||\n raw === 'textarea' ||\n raw === 'select' ||\n raw === 'readonly' ||\n raw === 'hidden'\n ) {\n return raw;\n }\n return 'readonly';\n}\n\nfunction readMode(value: unknown): EditPolicyMode {\n const raw = readString(value);\n if (raw === 'allowlisted_fields' || raw === 'full') return raw;\n return 'preview_only';\n}\n\nfunction parseEnumOptions(value: unknown): EditPolicyEnumOption[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const options = value\n .map((item) => {\n if (!isRecord(item)) return null;\n const label = readString(item.label);\n const optionValue = readString(item.value);\n if (!label || optionValue == null) return null;\n return { label, value: optionValue };\n })\n .filter((item): item is EditPolicyEnumOption => item != null);\n return options.length > 0 ? options : undefined;\n}\n\nfunction parseField(row: unknown): EditPolicyField | null {\n if (!isRecord(row)) return null;\n const path = readString(row.path);\n const label = readString(row.label) ?? path;\n if (!path || !label) return null;\n return {\n path,\n label,\n role: readRole(row.role),\n widget: readWidget(row.widget),\n editable: row.editable === true,\n required: row.required === true,\n value: row.value,\n enumOptions: parseEnumOptions(row.enumOptions),\n reason: typeof row.reason === 'string' ? row.reason : null,\n };\n}\n\n/** Parse server `editPolicy` (SSE / run-state / approval). */\nexport function parseEditPolicyPublic(value: unknown): EditPolicyPublic | null {\n if (!isRecord(value)) return null;\n const fieldsRaw = Array.isArray(value.fields) ? value.fields : [];\n const fields = fieldsRaw\n .map((row) => parseField(row))\n .filter((field): field is EditPolicyField => field != null);\n return {\n editMode: readMode(value.editMode),\n submitPath: readString(value.submitPath) ?? null,\n allowArgumentsPatch: value.allowArgumentsPatch === true,\n fields,\n };\n}\n\nfunction inferWidgetForValue(value: unknown): EditPolicyFieldWidget {\n if (typeof value === 'string' && value.length > 80) return 'textarea';\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return 'text';\n }\n return 'readonly';\n}\n\nfunction inferSubmitPathFromArguments(args: Record<string, unknown>): string | null {\n for (const [key, value] of Object.entries(args)) {\n if (typeof value === 'string' && value.trim()) return key;\n if (Array.isArray(value) && value.length > 0 && isRecord(value[0])) {\n for (const [leaf, leafValue] of Object.entries(value[0])) {\n if (typeof leafValue === 'string' && leafValue.trim()) {\n return `${key}[].${leaf}`;\n }\n }\n }\n }\n const firstKey = Object.keys(args)[0];\n return firstKey ?? null;\n}\n\n/** Fallback when the server omits `editPolicy` (legacy payloads). */\nexport function deriveEditPolicyFromDraft(draft: WriteDraftPublic): EditPolicyPublic {\n const submitPath = inferSubmitPathFromArguments(draft.arguments);\n const previewBlocks = draft.presentation.previewBlocks;\n if (previewBlocks.length > 0) {\n return {\n editMode: 'preview_only',\n submitPath,\n allowArgumentsPatch: false,\n fields: Object.entries(draft.arguments).map(([path, value]) => ({\n path,\n label: path,\n role: path === submitPath ? 'content' : 'system',\n widget: 'readonly',\n editable: false,\n required: false,\n value,\n })),\n };\n }\n\n return {\n editMode: 'allowlisted_fields',\n submitPath: null,\n allowArgumentsPatch: true,\n fields: Object.entries(draft.arguments).map(([path, value]) => ({\n path,\n label: path,\n role: path === submitPath ? 'content' : 'system',\n widget: inferWidgetForValue(value),\n editable: inferWidgetForValue(value) !== 'readonly',\n required: false,\n value,\n })),\n };\n}\n\nexport function resolveEditPolicy(\n writeDraft: WriteDraftPublic | null | undefined,\n editPolicy: EditPolicyPublic | null | undefined,\n): EditPolicyPublic | null {\n if (editPolicy) return editPolicy;\n if (writeDraft) return deriveEditPolicyFromDraft(writeDraft);\n return null;\n}\n\nexport function visibleEditPolicyFields(policy: EditPolicyPublic): EditPolicyField[] {\n if (policy.editMode === 'preview_only') {\n return [];\n }\n return policy.fields.filter((field) => field.widget !== 'hidden');\n}\n\nexport function editableEditPolicyFields(policy: EditPolicyPublic): EditPolicyField[] {\n return policy.fields.filter((field) => field.editable && field.widget !== 'hidden');\n}\n\nexport function resolveSubmitPathFieldLabel(policy: EditPolicyPublic): string | null {\n if (!policy.submitPath) return null;\n const field = policy.fields.find((row) => row.path === policy.submitPath);\n return field?.label?.trim() || null;\n}\n\nexport function canEditDraftReview(\n writeDraft: WriteDraftPublic | null | undefined,\n editPolicy: EditPolicyPublic | null | undefined,\n): boolean {\n const policy = resolveEditPolicy(writeDraft, editPolicy);\n if (!policy || !writeDraft) return false;\n if (policy.editMode === 'preview_only') {\n const items = resolveSubmitPathPreviewItems(writeDraft.arguments, policy);\n if (items.length === 1 && items[0].text.trim()) return true;\n if (items.length > 1) return false;\n const fromBlocks = blocksToText(writeDraft.presentation.previewBlocks as CoreMessageBlock[]);\n if (fromBlocks && !isMachineJsonPreview(fromBlocks)) {\n return true;\n }\n return editableEditPolicyFields(policy).length > 0;\n }\n return editableEditPolicyFields(policy).length > 0;\n}\n\nexport function initialPreviewEditorText(\n writeDraft: WriteDraftPublic,\n policy: EditPolicyPublic | null,\n): string {\n if (policy?.submitPath) {\n const items = resolveSubmitPathPreviewItems(writeDraft.arguments, policy);\n if (items.length === 1) return items[0].text;\n if (items.length > 1) {\n return items.map((item) => item.text).join('\\n\\n');\n }\n }\n\n const blocks = writeDraft.presentation.previewBlocks as CoreMessageBlock[];\n const fromBlocks = blocksToText(blocks);\n if (fromBlocks && !isMachineJsonPreview(fromBlocks)) {\n return fromBlocks;\n }\n\n const stringField = policy?.fields.find(\n (field) =>\n field.path === policy.submitPath &&\n typeof field.value === 'string' &&\n field.value.trim(),\n );\n if (stringField && typeof stringField.value === 'string') {\n return stringField.value;\n }\n\n return '';\n}\n\nexport function draftReviewHasEdits(\n writeDraft: WriteDraftPublic,\n policy: EditPolicyPublic | null,\n editedPreviewText: string,\n editedArgs: Record<string, unknown>,\n): boolean {\n const resolved = resolveEditPolicy(writeDraft, policy)!;\n const baselinePreview = initialPreviewEditorText(writeDraft, resolved);\n const previewChanged = editedPreviewText.trim() !== baselinePreview.trim();\n const argsChanged =\n JSON.stringify(editedArgs) !== JSON.stringify(writeDraft.arguments);\n\n if (resolved.editMode === 'preview_only') {\n return previewChanged && editedPreviewText.trim().length > 0;\n }\n if (resolved.editMode === 'full') {\n return argsChanged;\n }\n return previewChanged || argsChanged;\n}\n\n/** Build `writeGate` / `decision` payload from policy-aware editor state. */\nexport function buildDraftReviewDecisionPayload(\n writeDraft: WriteDraftPublic,\n editPolicy: EditPolicyPublic | null | undefined,\n input: {\n editedPreviewText: string;\n editedArgs: Record<string, unknown>;\n },\n): WriteDraftEditPayload {\n const policy = resolveEditPolicy(writeDraft, editPolicy)!;\n const previewBlocks = writeDraft.presentation.previewBlocks as CoreMessageBlock[];\n const baselinePreview = initialPreviewEditorText(writeDraft, policy);\n const previewChanged = input.editedPreviewText.trim() !== baselinePreview.trim();\n\n if (policy.editMode === 'preview_only') {\n const previewBlocks = writeDraft.presentation.previewBlocks as CoreMessageBlock[];\n const serialized = buildEditedPreviewFromText(input.editedPreviewText, previewBlocks);\n if (isMachineJsonPreview(blocksToText(previewBlocks))) {\n return {\n editedPreviewSerialized: buildEditedPreviewFromText(input.editedPreviewText),\n };\n }\n return { editedPreviewSerialized: serialized };\n }\n\n const patchPayload = buildConfirmWithEditsFromArguments(\n writeDraft.arguments,\n input.editedArgs,\n );\n const payload: WriteDraftEditPayload = {};\n\n if (policy.editMode === 'full' || policy.allowArgumentsPatch) {\n const editablePaths = new Set(\n editableEditPolicyFields(policy).map((field) => field.path),\n );\n const filteredPatch: Record<string, unknown> = {};\n const patch = patchPayload.editedPendingWriteArguments ?? {};\n for (const [key, value] of Object.entries(patch)) {\n if (editablePaths.has(key)) {\n filteredPatch[key] = value;\n }\n }\n if (Object.keys(filteredPatch).length > 0) {\n payload.editedPendingWriteArguments = filteredPatch;\n } else if (policy.editMode === 'full') {\n payload.editedPendingWriteArguments = patch;\n }\n }\n\n if (policy.editMode === 'allowlisted_fields' && previewChanged) {\n payload.editedPreviewSerialized = buildEditedPreviewFromText(\n input.editedPreviewText,\n previewBlocks,\n );\n }\n\n return payload;\n}\n\nexport type DraftReviewGateErrorCode =\n | 'EDITED_LOCKED_FIELD'\n | 'EDITED_FIELD_NOT_ALLOWED'\n | 'EDITED_WRITE_ARGS_INVALID'\n | 'MULTI_WRITE_EDIT_NOT_SUPPORTED';\n\nexport function isDraftReviewGateErrorCode(\n code: string | undefined,\n): code is DraftReviewGateErrorCode {\n return (\n code === 'EDITED_LOCKED_FIELD' ||\n code === 'EDITED_FIELD_NOT_ALLOWED' ||\n code === 'EDITED_WRITE_ARGS_INVALID' ||\n code === 'MULTI_WRITE_EDIT_NOT_SUPPORTED'\n );\n}\n","import {\n initialPreviewEditorText,\n parseEditPolicyPublic,\n resolveEditPolicy,\n type EditPolicyPublic,\n} from './edit-policy';\nimport {\n cloneWriteDraftArguments,\n parseWriteDraftPublic,\n type WriteDraftPublic,\n} from './write-draft';\n\nexport interface DraftReviewBundle {\n writeDraft: WriteDraftPublic;\n editPolicy: EditPolicyPublic | null;\n}\n\nexport interface DraftReviewEditorState {\n editedPreviewText: string;\n editedArgs: Record<string, unknown>;\n}\n\nfunction parseWriteDraftList(value: unknown): WriteDraftPublic[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((row) => parseWriteDraftPublic(row))\n .filter((draft): draft is WriteDraftPublic => draft != null);\n}\n\nfunction parseEditPolicyList(value: unknown): EditPolicyPublic[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((row) => parseEditPolicyPublic(row))\n .filter((policy): policy is EditPolicyPublic => policy != null);\n}\n\n/** Pair `writeDraft(s)` with `editPolicy(ies)` from server payloads (legacy + multi-write). */\nexport function parseDraftReviewBundles(input: {\n writeDraft?: WriteDraftPublic | null;\n writeDrafts?: unknown;\n editPolicy?: EditPolicyPublic | null;\n editPolicies?: unknown;\n}): DraftReviewBundle[] {\n const fromArray = parseWriteDraftList(input.writeDrafts);\n if (fromArray.length > 0) {\n const policies = parseEditPolicyList(input.editPolicies);\n const fallbackPolicy = input.editPolicy ?? null;\n return fromArray.map((writeDraft, index) => ({\n writeDraft,\n editPolicy: policies[index] ?? fallbackPolicy,\n }));\n }\n\n const single =\n input.writeDraft ?? parseWriteDraftPublic(input.writeDraft);\n if (!single) return [];\n\n return [{ writeDraft: single, editPolicy: input.editPolicy ?? null }];\n}\n\nexport function buildDraftReviewEditorStates(\n bundles: DraftReviewBundle[],\n): DraftReviewEditorState[] {\n return bundles.map((bundle) => {\n const policy = resolveEditPolicy(bundle.writeDraft, bundle.editPolicy);\n return {\n editedPreviewText: initialPreviewEditorText(bundle.writeDraft, policy),\n editedArgs: cloneWriteDraftArguments(bundle.writeDraft),\n };\n });\n}\n\nexport function draftReviewBundleLabel(bundle: DraftReviewBundle, index: number): string {\n const name = bundle.writeDraft.tool.name?.trim();\n if (name) return name;\n return `Draft ${index + 1}`;\n}\n","import type { AgentChatPageContext, ChatSkillSummary, QueryClientSkillByAgent } from '../../types';\n\n/**\n * Build `GET /agent/:agentId/skills/client` query.\n * When `pageContext.page` is set, passes `?page=` so the list matches runtime skill selection.\n */\nexport function buildClientSkillListQuery(\n skillListQuery: QueryClientSkillByAgent | undefined,\n pageContext: AgentChatPageContext | null | undefined,\n): QueryClientSkillByAgent | undefined {\n const query: QueryClientSkillByAgent = { ...skillListQuery };\n const scope = pageContext?.page?.trim();\n if (scope) {\n query.page = scope;\n }\n return Object.keys(query).length > 0 ? query : undefined;\n}\n\n/**\n * Default skill when the server returns exactly one `pageMatched` item (page-scoped list).\n * Returns `undefined` when there is no unique page-bound skill — caller should not preselect.\n */\nexport function resolveDefaultSkillId(skills: ChatSkillSummary[]): string | undefined {\n const pageBound = skills.filter((skill) => skill.pageMatched === true);\n if (pageBound.length === 1) {\n return pageBound[0]!.id;\n }\n return undefined;\n}\n\n/** Whether the skill list was fetched with a page filter (`pageMatched` present). */\nexport function skillListHasPageFilter(skills: ChatSkillSummary[]): boolean {\n return skills.some((skill) => skill.pageMatched !== undefined);\n}\n","import type { AgentChatRouteContext } from '../../types';\n\nexport function readWindowRouteContext(): AgentChatRouteContext {\n if (typeof window === 'undefined') return {};\n const routePath = window.location.pathname || undefined;\n const routeParams: Record<string, string> = {};\n const search = new URLSearchParams(window.location.search);\n search.forEach((value, key) => {\n routeParams[key] = value;\n });\n return {\n routePath,\n routeParams: Object.keys(routeParams).length > 0 ? routeParams : undefined,\n };\n}\n\nexport function mergeRouteContext(\n base: AgentChatRouteContext,\n override?: AgentChatRouteContext | null,\n): AgentChatRouteContext {\n if (!override) return base;\n const routeParams = {\n ...(base.routeParams ?? {}),\n ...(override.routeParams ?? {}),\n };\n return {\n routePath: override.routePath ?? base.routePath,\n routeParams: Object.keys(routeParams).length > 0 ? routeParams : undefined,\n };\n}\n\nexport function isRouteContextEmpty(ctx: AgentChatRouteContext | null | undefined): boolean {\n if (!ctx) return true;\n return !(ctx.routePath || (ctx.routeParams && Object.keys(ctx.routeParams).length > 0));\n}\n","import type { BrainClarifyCandidate, BrainClarifyPayload, EntityCommit } from '../../types';\n\nexport const BRAIN_ASK_USER_ERROR_CODE = 'BRAIN_ASK_USER';\nexport const BRAIN_CLARIFY_NODE_OUTPUT_KEY = 'brain:clarify';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction parseCandidate(value: unknown): BrainClarifyCandidate | null {\n if (!isRecord(value)) return null;\n const id = readString(value.id);\n const entityType = readString(value.entityType);\n if (!id || !entityType) return null;\n const candidate: BrainClarifyCandidate = { id, entityType };\n const text = readString(value.text);\n if (text) candidate.text = text;\n if (isRecord(value.fields)) candidate.fields = value.fields;\n const source = readString(value.source);\n if (source) candidate.source = source;\n const path = readString(value.path);\n if (path) candidate.path = path;\n return candidate;\n}\n\n/** Parse `brainClarify` from SSE / GET detail / run steps. */\nexport function parseBrainClarifyPayload(value: unknown): BrainClarifyPayload | null {\n if (!isRecord(value)) return null;\n if (value.kind !== 'entity_resolve') return null;\n const question = readString(value.question);\n const entityType = readString(value.entityType);\n if (!question || !entityType) return null;\n if (!Array.isArray(value.candidates)) return null;\n\n const candidates = value.candidates\n .map((row) => parseCandidate(row))\n .filter((row): row is BrainClarifyCandidate => row != null);\n if (candidates.length === 0) return null;\n\n const commitHintEntity =\n isRecord(value.commitHint) && readString(value.commitHint.entityType)\n ? readString(value.commitHint.entityType)!\n : entityType;\n\n return {\n kind: 'entity_resolve',\n question,\n reason: readString(value.reason) ?? '',\n entityType,\n candidates,\n commitHint: { entityType: commitHintEntity },\n proposalType: readString(value.proposalType) ?? '',\n };\n}\n\nexport function isBrainAskUserErrorCode(errorCode: string | null | undefined): boolean {\n return errorCode?.trim() === BRAIN_ASK_USER_ERROR_CODE;\n}\n\nexport function buildEntityCommit(\n clarify: BrainClarifyPayload,\n selectedId: string,\n): EntityCommit {\n return {\n entityType: clarify.commitHint.entityType || clarify.entityType,\n selectedId: selectedId.trim(),\n };\n}\n\nexport function formatBrainClarifyCandidateLabel(candidate: BrainClarifyCandidate): string {\n const text = candidate.text?.trim();\n if (text) return text;\n if (candidate.fields && Object.keys(candidate.fields).length > 0) {\n try {\n return JSON.stringify(candidate.fields).slice(0, 80);\n } catch {\n /* ignore */\n }\n }\n return candidate.id;\n}\n\n/**\n * Extract `brainClarify` from AgentRun steps (Chat) or PageAction timeline-like steps.\n * Mirrors server `extractBrainClarifyFromRunSteps`.\n */\nexport function extractBrainClarifyFromRunSteps(input: {\n steps?: unknown;\n nodeOutputs?: Record<string, unknown> | null;\n errorCode?: string | null;\n}): BrainClarifyPayload | null {\n if (\n input.errorCode &&\n !isBrainAskUserErrorCode(input.errorCode) &&\n input.errorCode.trim().length > 0\n ) {\n return null;\n }\n\n if (Array.isArray(input.steps)) {\n for (let i = input.steps.length - 1; i >= 0; i -= 1) {\n const step = input.steps[i];\n if (!isRecord(step)) continue;\n const name = typeof step.name === 'string' ? step.name : '';\n if (\n name === 'runtime:brain_clarify' ||\n name === 'brain_clarify' ||\n name.endsWith(':brain_clarify')\n ) {\n const fromDetail = parseBrainClarifyPayload(step.detail);\n if (fromDetail) return fromDetail;\n const fromOutput = parseBrainClarifyPayload(step.output);\n if (fromOutput) return fromOutput;\n }\n const detail = isRecord(step.detail)\n ? step.detail\n : isRecord(step.output)\n ? step.output\n : null;\n if (name.includes('brain_blocked') && detail) {\n const nested = parseBrainClarifyPayload(detail.brainClarify);\n if (nested) return nested;\n }\n }\n }\n\n const outputs = input.nodeOutputs;\n if (outputs) {\n const fromKey = parseBrainClarifyPayload(outputs[BRAIN_CLARIFY_NODE_OUTPUT_KEY]);\n if (fromKey) return fromKey;\n }\n\n return null;\n}\n","import type {\n ApprovalEntityReference,\n ApprovalEntityReferenceDisplayField,\n ApprovalEntityReferenceInlineRecord,\n ApprovalEntityReferenceSource,\n} from '../../types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction readNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n return null;\n}\n\nfunction stringifyDisplayValue(value: unknown): string | null {\n if (value == null) return null;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return null;\n}\n\nfunction parseDisplayField(value: unknown): ApprovalEntityReferenceDisplayField | null {\n if (!isRecord(value)) return null;\n const key = readString(value.key);\n const label = readString(value.label);\n const fieldValue = stringifyDisplayValue(value.value);\n if (!key || !label || fieldValue == null) return null;\n return { key, label, value: fieldValue };\n}\n\nfunction parseDisplayFields(value: unknown): ApprovalEntityReferenceDisplayField[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((row) => parseDisplayField(row))\n .filter((row): row is ApprovalEntityReferenceDisplayField => row != null);\n}\n\nfunction parseStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const urls: string[] = [];\n for (const entry of value) {\n const url = readString(entry);\n if (url) urls.push(url);\n }\n return urls;\n}\n\nfunction legacySourceTitle(\n value: Record<string, unknown>,\n ref: string,\n action: string,\n): string {\n const toolName = readString(value.toolName);\n if (action === 'fetch_data') return toolName ?? ref;\n if (action === 'load_page_context') return 'load_page_context';\n if (action === 'summarize_images') return 'summarize_images';\n return toolName ?? (action || ref);\n}\n\nfunction parseInlineRecord(value: unknown): ApprovalEntityReferenceInlineRecord | null {\n if (!isRecord(value)) return null;\n const kind = readString(value.kind);\n if (!kind) return null;\n\n const title = readString(value.title) ?? kind;\n const hasProjectionFields = Array.isArray(value.fields);\n const legacyRecord = isRecord(value.record) ? value.record : null;\n\n if (!hasProjectionFields && legacyRecord) {\n return {\n kind,\n title,\n fields: [],\n imageUrls: [],\n legacyRecord,\n };\n }\n\n return {\n kind,\n title,\n fields: parseDisplayFields(value.fields),\n imageUrls: parseStringArray(value.imageUrls),\n };\n}\n\nfunction parseSource(value: unknown): ApprovalEntityReferenceSource | null {\n if (!isRecord(value)) return null;\n const ref = readString(value.ref);\n const action = readString(value.action);\n if (!ref || !action) return null;\n\n const fields = parseDisplayFields(value.fields);\n const imageUrls = parseStringArray(value.imageUrls);\n\n return {\n ref,\n action,\n title: readString(value.title) ?? legacySourceTitle(value, ref, action),\n toolName: readString(value.toolName),\n toolId: readNumber(value.toolId),\n data: value.data,\n fields,\n imageUrls: imageUrls.length > 0 ? imageUrls : undefined,\n };\n}\n\n/** True when snapshot still uses `inlineRecords[].record` (pre-projection). */\nexport function isLegacyEntityReference(\n reference: ApprovalEntityReference | null | undefined,\n): boolean {\n if (!reference) return false;\n if (reference.legacy) return true;\n return reference.inlineRecords.some((row) => row.legacyRecord != null);\n}\n\n/** Parse inbox/detail `entityReference` payload. */\nexport function parseApprovalEntityReference(\n value: unknown,\n): ApprovalEntityReference | null {\n if (!isRecord(value)) return null;\n const inlineRecords = Array.isArray(value.inlineRecords)\n ? value.inlineRecords\n .map((row) => parseInlineRecord(row))\n .filter((row): row is ApprovalEntityReferenceInlineRecord => row != null)\n : [];\n const sources = Array.isArray(value.sources)\n ? value.sources\n .map((row) => parseSource(row))\n .filter((row): row is ApprovalEntityReferenceSource => row != null)\n .sort((left, right) => left.ref.localeCompare(right.ref))\n : [];\n const legacy = inlineRecords.some((row) => row.legacyRecord != null);\n return {\n page: readString(value.page),\n routePath: readString(value.routePath),\n entityType: readString(value.entityType),\n entityId: readString(value.entityId),\n anchorLabel: readString(value.anchorLabel),\n inlineRecords,\n sources,\n legacy: legacy || undefined,\n };\n}\n\nexport function hasEntityReferenceContent(\n reference: ApprovalEntityReference | null | undefined,\n): boolean {\n if (!reference) return false;\n return (\n Boolean(\n reference.anchorLabel ||\n reference.entityType ||\n reference.entityId ||\n reference.page,\n ) ||\n reference.inlineRecords.length > 0 ||\n reference.sources.length > 0\n );\n}\n\n/** Header anchor line — prefers server `anchorLabel`. */\nexport function formatEntityReferenceAnchor(\n reference: ApprovalEntityReference,\n): string | null {\n if (reference.anchorLabel) {\n return reference.page\n ? `${reference.anchorLabel} · ${reference.page}`\n : reference.anchorLabel;\n }\n\n const parts: string[] = [];\n if (reference.entityType && reference.entityId) {\n parts.push(`${reference.entityType} #${reference.entityId}`);\n } else if (reference.entityType) {\n parts.push(reference.entityType);\n } else if (reference.entityId) {\n parts.push(`#${reference.entityId}`);\n }\n if (reference.page) {\n parts.push(reference.page);\n }\n return parts.length > 0 ? parts.join(' · ') : null;\n}\n\nexport function formatEntityReferenceListHint(\n reference: ApprovalEntityReference | null | undefined,\n): string | null {\n if (!reference) return null;\n return formatEntityReferenceAnchor(reference);\n}\n\nconst ENTITY_KIND_TITLE_KEYS = {\n review: 'approval.entityKindReview',\n order: 'approval.entityKindOrder',\n comment: 'approval.entityKindComment',\n} as const;\n\ntype EntityKindTitleKey = (typeof ENTITY_KIND_TITLE_KEYS)[keyof typeof ENTITY_KIND_TITLE_KEYS];\n\n/** i18n key for a known inline `kind`, or null to use `title`. */\nexport function entityKindTitleKey(kind: string): EntityKindTitleKey | null {\n return ENTITY_KIND_TITLE_KEYS[kind.trim().toLowerCase() as keyof typeof ENTITY_KIND_TITLE_KEYS] ?? null;\n}\n\nexport function readInlineRecordContent(record: Record<string, unknown>): string | null {\n const content = record.content;\n if (typeof content === 'string' && content.trim()) return content.trim();\n if (typeof content === 'number' || typeof content === 'boolean') {\n return String(content);\n }\n return null;\n}\n\nexport function listInlineRecordExtraFields(\n record: Record<string, unknown>,\n): Array<{ key: string; value: string }> {\n const rows: Array<{ key: string; value: string }> = [];\n for (const [key, value] of Object.entries(record)) {\n if (key === 'content' || key === 'images') continue;\n if (value == null) continue;\n if (typeof value === 'string' && !value.trim()) continue;\n if (Array.isArray(value)) continue;\n const text =\n typeof value === 'string'\n ? value.trim()\n : typeof value === 'number' || typeof value === 'boolean'\n ? String(value)\n : JSON.stringify(value, null, 2);\n rows.push({ key, value: text });\n }\n return rows;\n}\n\nexport function listLegacyInlineImageUrls(record: Record<string, unknown>): string[] {\n const images = record.images;\n if (!Array.isArray(images)) return [];\n const urls: string[] = [];\n for (const image of images) {\n if (typeof image === 'string') {\n const url = readString(image);\n if (url) urls.push(url);\n continue;\n }\n if (isRecord(image)) {\n const url = readString(image.url);\n if (url) urls.push(url);\n }\n }\n return urls;\n}\n\nexport function formatEntityDataPreview(value: unknown): string {\n if (value == null) return '—';\n if (typeof value === 'string') return value.trim() || '—';\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nexport function hasProjectedSourceBody(source: ApprovalEntityReferenceSource): boolean {\n return source.fields.length > 0 || Boolean(source.imageUrls?.length);\n}\n","import type {\n ApprovalConfirmResult,\n ApprovalDetail,\n ApprovalDraftReviewBudget,\n ApprovalInboxItem,\n ApprovalInboxList,\n ApprovalInitiator,\n ApprovalPendingWritePreview,\n ApprovalDecideResult,\n ApprovalRejectResult,\n ApprovalSource,\n ApprovalStatus,\n} from '../../types';\nimport { parseWriteDraftPublic } from '../draft-review/write-draft';\nimport { parseEditPolicyPublic } from '../draft-review/edit-policy';\nimport { parseDraftReviewBundles } from '../draft-review/draft-review-bundle';\nimport { parseApprovalEntityReference } from './entity-reference';\nimport type { CoreMessageBlock } from '../chat/message-blocks';\nimport { parseStoredBlocks } from '../chat/message-blocks';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction readNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n}\n\nfunction readApprovalSource(value: unknown): ApprovalSource | undefined {\n const raw = readString(value);\n if (raw === 'chat' || raw === 'page_action' || raw === 'webhook') return raw;\n return undefined;\n}\n\nfunction readApprovalStatus(value: unknown): ApprovalStatus | undefined {\n const raw = readString(value);\n if (\n raw === 'pending' ||\n raw === 'approved' ||\n raw === 'rejected' ||\n raw === 'cancelled' ||\n raw === 'expired'\n ) {\n return raw;\n }\n return undefined;\n}\n\nfunction parseInitiator(value: unknown): ApprovalInitiator | null {\n if (!isRecord(value)) return null;\n const id = readNumber(value.id);\n if (id == null) return null;\n return {\n id,\n username: readString(value.username) ?? null,\n employeeId: readString(value.employeeId) ?? null,\n };\n}\n\nfunction parseDraftReview(value: unknown): ApprovalDraftReviewBudget | null {\n if (!isRecord(value)) return null;\n const retryCount = readNumber(value.retryCount) ?? 0;\n const retryMax = value.retryMax === null ? null : (readNumber(value.retryMax) ?? null);\n return {\n retryCount,\n retryMax,\n canRetry:\n value.canRetry === false\n ? false\n : value.canRetry === true\n ? true\n : retryMax == null\n ? true\n : retryCount < retryMax,\n };\n}\n\nfunction parsePreviewBlocks(value: unknown): CoreMessageBlock[] | undefined {\n if (value == null) return undefined;\n if (typeof value === 'string') return parseStoredBlocks(value);\n if (isRecord(value) && Array.isArray(value.blocks)) {\n return value.blocks.filter(\n (item): item is CoreMessageBlock =>\n isRecord(item) && typeof item.type === 'string',\n );\n }\n if (Array.isArray(value)) {\n return value.filter(\n (item): item is CoreMessageBlock =>\n isRecord(item) && typeof item.type === 'string',\n );\n }\n return undefined;\n}\n\n/** Parse inbox `previewBlocks` into renderable blocks. */\nexport function parseApprovalPreviewBlocks(value: unknown): CoreMessageBlock[] | undefined {\n return parsePreviewBlocks(value);\n}\n\nfunction parsePendingWrite(value: unknown): ApprovalPendingWritePreview | null {\n if (!isRecord(value)) return null;\n const tool = readString(value.tool);\n if (!tool) return null;\n const riskLevel = readString(value.riskLevel) ?? 'L2';\n return { tool, riskLevel };\n}\n\nfunction parseInboxItem(row: unknown): ApprovalInboxItem | null {\n if (!isRecord(row)) return null;\n const id = readNumber(row.id);\n const source = readApprovalSource(row.source);\n const status = readApprovalStatus(row.status);\n const title = readString(row.title);\n const createdAt = readString(row.createdAt);\n if (id == null || !source || !status || !title || !createdAt) {\n return null;\n }\n const bundles = parseDraftReviewBundles({\n writeDraft: parseWriteDraftPublic(row.writeDraft),\n writeDrafts: row.writeDrafts,\n editPolicy: parseEditPolicyPublic(row.editPolicy),\n editPolicies: row.editPolicies,\n });\n const primary = bundles[0];\n return {\n id,\n source,\n status,\n title,\n summary: readString(row.summary) ?? null,\n workflowId: readNumber(row.workflowId) ?? 0,\n workflowVersion: readNumber(row.workflowVersion) ?? 0,\n workflowKey: readString(row.workflowKey) ?? null,\n workflowName: readString(row.workflowName) ?? null,\n nodeId: readString(row.nodeId) ?? '',\n sessionId: readString(row.sessionId) ?? null,\n pageActionRunId: readNumber(row.pageActionRunId) ?? null,\n initiator: parseInitiator(row.initiator),\n createdAt,\n decidedAt: readString(row.decidedAt) ?? null,\n previewBlocks: row.previewBlocks ?? null,\n pendingWrite: parsePendingWrite(row.pendingWrite),\n writeDraft: primary?.writeDraft ?? null,\n editPolicy: primary?.editPolicy ?? null,\n writeDrafts: bundles.length > 1 ? bundles.map((bundle) => bundle.writeDraft) : null,\n editPolicies: bundles.length > 1 ? bundles.map((bundle) => bundle.editPolicy) : null,\n draftReview: parseDraftReview(row.draftReview),\n entityReference: parseApprovalEntityReference(row.entityReference),\n };\n}\n\n/** Parse `GET /approval/inbox` body. */\nexport function parseApprovalInboxList(\n body: unknown,\n limit = 50,\n): ApprovalInboxList {\n const record = isRecord(body) ? body : null;\n const itemsRaw = Array.isArray(record?.items) ? record.items : [];\n const items = itemsRaw\n .map((row) => parseInboxItem(row))\n .filter((row): row is ApprovalInboxItem => row != null)\n .filter((row) => row.source !== 'chat');\n return { items, hasMore: items.length >= limit };\n}\n\n/** Parse `GET /approval/:id` body. */\nexport function parseApprovalDetail(body: unknown): ApprovalDetail | null {\n const item = parseInboxItem(body);\n if (!item) return null;\n return { ...item, decidedAt: item.decidedAt ?? null };\n}\n\n/** Parse `POST /approval/:id/confirm` or `decide` body. */\nexport function parseApprovalConfirmResult(body: unknown): ApprovalConfirmResult {\n const record = isRecord(body) ? body : null;\n return {\n resumed: record?.resumed === true,\n suspended: record?.suspended === true ? true : undefined,\n };\n}\n\n/** Parse `POST /approval/:id/decide` body. */\nexport function parseApprovalDecideResult(body: unknown): ApprovalDecideResult {\n return parseApprovalConfirmResult(body);\n}\n\n/** Parse `POST /approval/:id/reject` body. */\nexport function parseApprovalRejectResult(body: unknown): ApprovalRejectResult {\n const record = isRecord(body) ? body : null;\n return { ok: record?.ok === true };\n}\n","/** Database-assigned message ids used by feedback APIs. */\nexport function isPersistedMessageId(id: string): boolean {\n return /^\\d+$/.test(id);\n}\n\nexport function parsePersistedMessageId(id: string): number | null {\n if (!isPersistedMessageId(id)) return null;\n const value = Number(id);\n return Number.isFinite(value) ? value : null;\n}\n\n/** Mirrors backend down-feedback validation. */\nexport function canSubmitDownFeedback(input: {\n reasonTagKeys: string[];\n comment: string;\n}): boolean {\n const tags = input.reasonTagKeys;\n const text = input.comment.trim();\n if (tags.length === 0 && !text) return false;\n if (tags.includes('other') && !text) return false;\n return true;\n}\n","/**\n * PageAction `page_workflow` SSE → button progressLabel + optional narrative timeline.\n * Progress frames only update UI copy; they do not execute HostTool or append prose.\n */\n\nexport type PageWorkflowStageKind = 'planning' | 'gather' | 'produce' | 'other';\n\nexport type PageWorkflowProgressCode =\n | 'planning'\n | 'host_llm_waiting'\n | 'fetch_planning'\n | 'fetch_tools'\n | (string & {});\n\nexport type PageWorkflowPhase =\n | 'start'\n | 'progress'\n | 'complete'\n | 'failed'\n | 'awaiting_approval';\n\n/** Structured storyline item kinds from `page_workflow.narrativeItems`. */\nexport type NarrativeKind = 'stage' | 'thought' | 'evidence' | 'ask' | 'outcome';\n\nexport interface NarrativeField {\n key: string;\n label: string;\n value: string;\n}\n\nexport interface NarrativeItem {\n kind: NarrativeKind;\n /** Language-agnostic key for i18n / branching; `text` is the fallback. */\n code?: string;\n /** Short user-visible copy (server-truncated). */\n text?: string;\n turn?: number;\n /** Brain action: FETCH / PRODUCE / ASK / BOOTSTRAP … */\n actionType?: string;\n title?: string;\n /** Evidence / pagination meta; shape aligns with approval DisplayField. */\n fields?: NarrativeField[];\n /** Observation / tool ref for detail expand (not a business primary key). */\n ref?: string;\n /** `ask`: missing pieces (entity types, honesty gaps, …). */\n missing?: string[];\n}\n\nexport interface PageWorkflowEvent {\n phase: PageWorkflowPhase;\n actionRunId: number;\n actionKey: string;\n generation: number;\n clientActionId?: string | null;\n nodeId: string;\n action?: string | null;\n stageKind?: PageWorkflowStageKind | null;\n stageIndex?: number | null;\n stageTotal?: number | null;\n progress?: PageWorkflowProgressCode | null;\n /** Optional loading string (legacy / Chat); button copy still prefers `stageKind`. */\n narrative?: string | null;\n /** Optional structured storyline batch for this frame. */\n narrativeItems?: NarrativeItem[] | null;\n errorCode?: string | null;\n errorMessage?: string | null;\n}\n\nconst NARRATIVE_KIND_SET = new Set<NarrativeKind>([\n 'stage',\n 'thought',\n 'evidence',\n 'ask',\n 'outcome',\n]);\n\nconst NARRATIVE_TIMELINE_CAP = 80;\n\nconst ACTION_TO_STAGE: Record<string, PageWorkflowStageKind> = {\n fetch_data: 'gather',\n detect_clues: 'gather',\n summarize_images: 'gather',\n generate_and_push: 'produce',\n summarize: 'produce',\n compose_mutation: 'produce',\n present_mutation: 'produce',\n write_data: 'produce',\n await_user_confirm: 'other',\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction readNumber(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n\nfunction normalizeStageKind(raw: unknown): PageWorkflowStageKind | null {\n const value = readString(raw);\n if (\n value === 'planning' ||\n value === 'gather' ||\n value === 'produce' ||\n value === 'other'\n ) {\n return value;\n }\n return null;\n}\n\nfunction stageKindFromAction(action: string | null | undefined): PageWorkflowStageKind | null {\n const key = String(action ?? '').trim();\n if (!key) return null;\n return ACTION_TO_STAGE[key] ?? null;\n}\n\nfunction normalizeNarrativeKind(raw: unknown): NarrativeKind | null {\n const value = readString(raw);\n if (value && NARRATIVE_KIND_SET.has(value as NarrativeKind)) {\n return value as NarrativeKind;\n }\n return null;\n}\n\nfunction parseNarrativeField(raw: unknown): NarrativeField | null {\n if (!isRecord(raw)) return null;\n const key = readString(raw.key);\n const label = readString(raw.label);\n const value = readString(raw.value);\n if (!key || !label || value == null) return null;\n return { key, label, value: value ?? '' };\n}\n\nfunction parseNarrativeItem(raw: unknown): NarrativeItem | null {\n if (!isRecord(raw)) return null;\n const kind = normalizeNarrativeKind(raw.kind);\n if (!kind) return null;\n const fieldsRaw = Array.isArray(raw.fields) ? raw.fields : null;\n const fields =\n fieldsRaw == null\n ? undefined\n : fieldsRaw\n .map(parseNarrativeField)\n .filter((field): field is NarrativeField => field != null)\n .slice(0, 12);\n const missingRaw = Array.isArray(raw.missing) ? raw.missing : null;\n const missing =\n missingRaw == null\n ? undefined\n : missingRaw\n .map((entry) => readString(entry))\n .filter((entry): entry is string => Boolean(entry))\n .slice(0, 12);\n const turn = readNumber(raw.turn);\n return {\n kind,\n code: readString(raw.code),\n text: readString(raw.text),\n turn: turn ?? undefined,\n actionType: readString(raw.actionType),\n title: readString(raw.title),\n fields: fields && fields.length > 0 ? fields : undefined,\n ref: readString(raw.ref),\n missing: missing && missing.length > 0 ? missing : undefined,\n };\n}\n\nexport function parseNarrativeItems(raw: unknown): NarrativeItem[] {\n if (!Array.isArray(raw)) return [];\n return raw\n .map(parseNarrativeItem)\n .filter((item): item is NarrativeItem => item != null)\n .slice(0, 8);\n}\n\nfunction narrativeDedupeKey(item: NarrativeItem): string {\n return [\n item.kind,\n item.code ?? '',\n item.ref ?? '',\n item.turn == null ? '' : String(item.turn),\n item.text ?? '',\n item.title ?? '',\n ].join('\\u0001');\n}\n\n/**\n * Append a workflow frame's `narrativeItems` onto the row timeline.\n * Returns the previous array reference when nothing was added.\n */\nexport function appendPageActionNarrativeItems(\n existing: NarrativeItem[] | null | undefined,\n batch: NarrativeItem[] | null | undefined,\n): NarrativeItem[] {\n const prev = existing ?? [];\n const nextBatch = batch ?? [];\n if (nextBatch.length === 0) return prev;\n\n const seen = new Set(prev.map(narrativeDedupeKey));\n const merged = [...prev];\n for (const item of nextBatch) {\n const key = narrativeDedupeKey(item);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(item);\n }\n if (merged.length === prev.length) return prev;\n if (merged.length > NARRATIVE_TIMELINE_CAP) {\n return merged.slice(-NARRATIVE_TIMELINE_CAP);\n }\n return merged;\n}\n\n/** True when the timeline has more than stage ticks — show「查看过程」. */\nexport function shouldOfferNarrativeProcess(\n items: NarrativeItem[] | null | undefined,\n): boolean {\n const list = items ?? [];\n return list.some((item) => item.kind !== 'stage');\n}\n\nexport function countInterestingNarrativeItems(\n items: NarrativeItem[] | null | undefined,\n): number {\n const list = items ?? [];\n return list.filter((item) => item.kind !== 'stage').length;\n}\n\nconst PROTOCOL_FIELD_LABEL_ZH: Record<string, string> = {\n itemCount: '相关条数',\n observationCount: '观测数',\n identity: '标识',\n page: '页码',\n rowCount: '行数',\n fetchedCount: '已获取',\n achieved: '已达成',\n};\n\nconst PROTOCOL_FIELD_LABEL_EN: Record<string, string> = {\n itemCount: 'Items',\n observationCount: 'Observations',\n identity: 'ID',\n page: 'Page',\n rowCount: 'Rows',\n fetchedCount: 'Fetched',\n achieved: 'Achieved',\n};\n\nfunction isZhLocale(locale: string | undefined): boolean {\n const value = String(locale ?? '').toLowerCase();\n return !value || value.startsWith('zh');\n}\n\n/** Humanize protocol / English-fallback field labels for evidence cards. */\nexport function localizeNarrativeFieldLabel(\n field: NarrativeField,\n locale?: string,\n): string {\n const key = field.key.trim();\n const label = field.label.trim();\n const mapped = isZhLocale(locale)\n ? PROTOCOL_FIELD_LABEL_ZH[key]\n : PROTOCOL_FIELD_LABEL_EN[key];\n if (mapped) return mapped;\n // Server sometimes mirrors key as label (identity / itemCount).\n if (label === key && PROTOCOL_FIELD_LABEL_ZH[key]) {\n return isZhLocale(locale)\n ? PROTOCOL_FIELD_LABEL_ZH[key]!\n : PROTOCOL_FIELD_LABEL_EN[key]!;\n }\n return label || key;\n}\n\nexport function isEvidenceSummaryItem(item: NarrativeItem): boolean {\n const code = String(item.code ?? '');\n return (\n item.kind === 'evidence' &&\n (code.endsWith('_summary') ||\n code.endsWith('_empty') ||\n code === 'fetch_summary' ||\n code === 'fetch_empty')\n );\n}\n\nexport function isEvidenceEntityPreviewItem(item: NarrativeItem): boolean {\n const code = String(item.code ?? '');\n return (\n item.kind === 'evidence' &&\n (code.endsWith('_entity_preview') || code === 'fetch_entity_preview')\n );\n}\n\nexport function pickNarrativeHeadline(\n items: NarrativeItem[] | null | undefined,\n): string | null {\n const list = items ?? [];\n const prefer = (kinds: NarrativeKind[]): string | null => {\n for (let i = list.length - 1; i >= 0; i -= 1) {\n const item = list[i]!;\n if (!kinds.includes(item.kind)) continue;\n const text = item.text?.trim() || item.title?.trim();\n if (text) return text;\n }\n return null;\n };\n return (\n prefer(['ask']) ||\n prefer(['outcome']) ||\n prefer(['evidence']) ||\n prefer(['thought']) ||\n null\n );\n}\n\nexport type NarrativeDisplayBlock =\n | { type: 'ask'; item: NarrativeItem }\n | { type: 'thought'; item: NarrativeItem }\n | {\n type: 'evidence-group';\n summary: NarrativeItem | null;\n entities: NarrativeItem[];\n }\n | { type: 'evidence'; item: NarrativeItem }\n | { type: 'outcome'; item: NarrativeItem }\n | { type: 'stage-group'; items: NarrativeItem[] };\n\n/**\n * Build a display list: asks first, outcomes last, stages collapsed,\n * evidence summary + entity previews grouped.\n */\nexport function buildNarrativeDisplayBlocks(\n items: NarrativeItem[] | null | undefined,\n): NarrativeDisplayBlock[] {\n const list = items ?? [];\n const asks = list.filter((item) => item.kind === 'ask');\n const outcomes = list.filter((item) => item.kind === 'outcome');\n const middle = list.filter((item) => item.kind !== 'ask' && item.kind !== 'outcome');\n\n const blocks: NarrativeDisplayBlock[] = asks.map((item) => ({ type: 'ask', item }));\n\n let stageBuf: NarrativeItem[] = [];\n let evidenceSummary: NarrativeItem | null = null;\n let evidenceEntities: NarrativeItem[] = [];\n\n const flushStages = () => {\n if (stageBuf.length === 0) return;\n blocks.push({ type: 'stage-group', items: stageBuf });\n stageBuf = [];\n };\n\n const flushEvidence = () => {\n if (!evidenceSummary && evidenceEntities.length === 0) return;\n if (evidenceSummary || evidenceEntities.length > 0) {\n blocks.push({\n type: 'evidence-group',\n summary: evidenceSummary,\n entities: evidenceEntities,\n });\n }\n evidenceSummary = null;\n evidenceEntities = [];\n };\n\n for (const item of middle) {\n if (item.kind === 'stage') {\n flushEvidence();\n stageBuf.push(item);\n continue;\n }\n flushStages();\n if (item.kind === 'thought') {\n flushEvidence();\n blocks.push({ type: 'thought', item });\n continue;\n }\n if (item.kind === 'evidence') {\n if (isEvidenceSummaryItem(item)) {\n flushEvidence();\n evidenceSummary = item;\n continue;\n }\n if (isEvidenceEntityPreviewItem(item)) {\n evidenceEntities.push(item);\n continue;\n }\n flushEvidence();\n blocks.push({ type: 'evidence', item });\n }\n }\n flushStages();\n flushEvidence();\n\n for (const item of outcomes) {\n blocks.push({ type: 'outcome', item });\n }\n return blocks;\n}\n\nexport function parsePageWorkflowEvent(body: unknown): PageWorkflowEvent | null {\n if (!isRecord(body)) return null;\n const phase = readString(body.phase);\n if (\n phase !== 'start' &&\n phase !== 'progress' &&\n phase !== 'complete' &&\n phase !== 'failed' &&\n phase !== 'awaiting_approval'\n ) {\n return null;\n }\n const actionRunId = readNumber(body.actionRunId);\n const generation = readNumber(body.generation);\n const actionKey = readString(body.actionKey);\n const nodeId = readString(body.nodeId) ?? '';\n if (actionRunId == null || generation == null || !actionKey) {\n return null;\n }\n\n const action = readString(body.action) ?? (body.action === null ? null : undefined);\n const progress = readString(body.progress) ?? null;\n const stageKind =\n normalizeStageKind(body.stageKind) ??\n stageKindFromAction(action ?? null) ??\n stageKindFromProgress(progress);\n const narrative =\n readString(body.narrative) ?? (body.narrative === null ? null : undefined);\n const narrativeItemsRaw = body.narrativeItems;\n const narrativeItems =\n narrativeItemsRaw == null ? null : parseNarrativeItems(narrativeItemsRaw);\n\n return {\n phase,\n actionRunId,\n actionKey,\n generation,\n clientActionId: readString(body.clientActionId) ?? null,\n nodeId,\n action: action === undefined ? undefined : action,\n stageKind,\n stageIndex: readNumber(body.stageIndex),\n stageTotal: readNumber(body.stageTotal),\n progress,\n narrative: narrative === undefined ? undefined : narrative,\n narrativeItems,\n errorCode: readString(body.errorCode),\n errorMessage: readString(body.errorMessage),\n };\n}\n\nfunction stageKindFromProgress(\n progress: string | null | undefined,\n): PageWorkflowStageKind | null {\n const value = String(progress ?? '').trim();\n if (value === 'planning' || value === 'fetch_planning') {\n return 'planning';\n }\n if (value === 'host_llm_waiting' || value === 'fetch_tools') {\n return 'produce';\n }\n // Backend sometimes emits a loose \"fetching\" while gather nodes run.\n if (value === 'fetching' || value === 'fetch_data') {\n return 'gather';\n }\n return null;\n}\n\n/**\n * Button copy uses 1-based `current/total`. Tolerate 0-based `stageIndex`\n * (`0 .. total-1`) from some Brain builds so we never show `0/N`.\n */\nexport function displayPageWorkflowStageIndex(\n stageIndex: number | null | undefined,\n stageTotal: number | null | undefined,\n): number | null {\n if (\n stageIndex == null ||\n stageTotal == null ||\n !Number.isFinite(stageIndex) ||\n !Number.isFinite(stageTotal) ||\n stageTotal <= 1\n ) {\n return null;\n }\n const index = Math.trunc(stageIndex);\n const total = Math.trunc(stageTotal);\n if (total <= 1) return null;\n\n // 0-based: 0 .. total-1 → display 1 .. total\n if (index >= 0 && index < total) {\n // Prefer 1-based when index is already in 1..total (historical contract).\n // Only the `0` frame is unambiguously 0-based; for 1..total-1 keep as-is.\n if (index === 0) return 1;\n return index;\n }\n // 1-based last step: index === total\n if (index === total) return total;\n return null;\n}\n\n/** Default label before the first `page_workflow` frame. */\nexport function defaultPageActionProgressLabel(locale?: string): string {\n return isZhLocale(locale) ? '处理中…' : 'Working…';\n}\n\n/** Soft button label while `reuse-hint` is in flight. */\nexport function pageActionReuseCheckingLabel(locale?: string): string {\n return isZhLocale(locale) ? '查可用结果…' : 'Checking prior results…';\n}\n\n/** Soft tip after reusing an existing successful run (no new invoke). */\nexport function pageActionReusedMessage(locale?: string): string {\n return isZhLocale(locale) ? '已套用已有结果' : 'Applied existing result';\n}\n\n/** Button label while applying a selected historical run (replay). */\nexport function pageActionReusingLabel(locale?: string): string {\n return isZhLocale(locale) ? '套用结果…' : 'Applying result…';\n}\n\n/** Soft button label while Brain clarify popover is open. */\nexport function pageActionAwaitingClarifyLabel(locale?: string): string {\n return isZhLocale(locale) ? '请选择目标…' : 'Pick a target…';\n}\n\n/** Optimistic task-center subtitle while a run is in flight. */\nexport function pageActionTaskRunningSubtitle(locale?: string): string {\n return isZhLocale(locale) ? '正在执行…' : 'Running…';\n}\n\n/** Optimistic task-center subtitle while waiting for inbox approval. */\nexport function pageActionTaskAwaitingApprovalSubtitle(locale?: string): string {\n return isZhLocale(locale) ? '等待审批…' : 'Awaiting approval…';\n}\n\n/** Soft tip when invoke hits an already-running PageAction (local or HTTP 409). */\nexport function pageActionAlreadyRunningTip(locale?: string): string {\n return isZhLocale(locale) ? '当前任务已在执行中' : 'This task is already running';\n}\n\n/** Soft tip when invoke hits a run already waiting for inbox approval. */\nexport function pageActionAlreadyAwaitingApprovalTip(locale?: string): string {\n return isZhLocale(locale)\n ? '该操作正在等待审批,请在审批收件箱处理'\n : 'This action is awaiting approval — open the approval inbox to continue';\n}\n\n/**\n * Map a workflow event to button copy.\n * Returns `null` when the frame should not change the label\n * (`complete` keeps previous; `failed` leaves error to `page_action`).\n */\nexport function resolvePageWorkflowProgressLabel(\n event: PageWorkflowEvent,\n locale?: string,\n): string | null {\n if (event.phase === 'complete') {\n return null;\n }\n if (event.phase === 'failed') {\n return null;\n }\n\n const zh = isZhLocale(locale);\n // Prefer explicit stageKind; fall back via progress code (e.g. planning / host_llm_waiting).\n const kind =\n event.stageKind ??\n stageKindFromProgress(event.progress) ??\n 'other';\n\n if (event.phase === 'awaiting_approval') {\n return zh ? '等待审批…' : 'Waiting for approval…';\n }\n\n if (kind === 'planning') {\n return zh ? '正在规划步骤…' : 'Planning steps…';\n }\n\n if (kind === 'gather') {\n const displayIndex = displayPageWorkflowStageIndex(\n event.stageIndex,\n event.stageTotal,\n );\n if (displayIndex != null && event.stageTotal != null) {\n return zh\n ? `正在收集信息(${displayIndex}/${Math.trunc(event.stageTotal)})…`\n : `Gathering info (${displayIndex}/${Math.trunc(event.stageTotal)})…`;\n }\n return zh ? '正在收集信息…' : 'Gathering info…';\n }\n\n if (kind === 'produce') {\n return zh ? '正在生成结果…' : 'Generating results…';\n }\n\n return zh ? '处理中…' : 'Working…';\n}\n","import type { PageActionSourceRect } from '../../types';\n\nexport const PAGE_ACTION_LAUNCH_FLY_DURATION_MS = 1_100;\nexport const PAGE_ACTION_LAUNCH_LAND_DURATION_MS = 560;\nexport const PAGE_ACTION_LAUNCH_TOAST_DELAY_MS = Math.round(\n PAGE_ACTION_LAUNCH_FLY_DURATION_MS * 0.72,\n);\n\nconst PAGE_ACTION_LAUNCH_FLY_EASING = 'cubic-bezier(0.25, 0.55, 0.35, 1)';\n\nexport function pageActionLaunchCssVarsBlock(): string {\n return `:root {\n --ac-page-action-launch-fly-ms: ${PAGE_ACTION_LAUNCH_FLY_DURATION_MS}ms;\n --ac-page-action-launch-land-ms: ${PAGE_ACTION_LAUNCH_LAND_DURATION_MS}ms;\n}`;\n}\n\nexport function readLaunchSourceRect(\n anchor: HTMLElement | null | undefined,\n): PageActionSourceRect | null {\n if (!anchor || typeof anchor.getBoundingClientRect !== 'function') return null;\n const rect = anchor.getBoundingClientRect();\n if (rect.width <= 0 && rect.height <= 0) return null;\n return {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n}\n\nexport function rectCenter(rect: PageActionSourceRect): { x: number; y: number } {\n return {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n };\n}\n\nconst TASK_CENTER_FLY_TARGET_SELECTORS = [\n '.ai-assistant-bubble',\n '.ai-assistant-automation-task-btn',\n '.ai-assistant-bubble-satellite--task-center',\n] as const;\n\nconst LAUNCH_LAND_PULSE_SELECTORS = [\n '.ai-assistant-bubble',\n '.ai-assistant-automation-task-btn',\n '.ai-assistant-bubble-satellite--task-center',\n] as const;\n\nfunction queryLaunchRoots(hostElement?: HTMLElement | null): Array<Document | ShadowRoot> {\n const roots: Array<Document | ShadowRoot> = [];\n const seen = new Set<Document | ShadowRoot>();\n const addRoot = (root: Document | ShadowRoot | null | undefined) => {\n if (!root || seen.has(root)) return;\n seen.add(root);\n roots.push(root);\n };\n if (typeof document !== 'undefined') addRoot(document);\n if (hostElement) {\n const root = hostElement.getRootNode();\n if (root instanceof ShadowRoot || root instanceof Document) addRoot(root);\n }\n return roots;\n}\n\nfunction queryFirstVisibleElement(\n selectors: readonly string[],\n hostElement?: HTMLElement | null,\n): HTMLElement | null {\n for (const root of queryLaunchRoots(hostElement)) {\n for (const selector of selectors) {\n const el = root.querySelector(selector);\n if (!(el instanceof HTMLElement)) continue;\n const rect = el.getBoundingClientRect();\n if (rect.width > 0 || rect.height > 0) return el;\n }\n }\n return null;\n}\n\n/** Main launcher chat button (visible when the panel is closed). */\nexport function findLauncherBubble(hostElement?: HTMLElement | null): HTMLElement | null {\n return queryFirstVisibleElement(['.ai-assistant-bubble'], hostElement);\n}\n\n/** Resolve fly-to target — prefer the main chat bubble when visible. */\nexport function findTaskCenterTargetRect(\n hostElement?: HTMLElement | null,\n): PageActionSourceRect | null {\n if (typeof document === 'undefined') return null;\n\n const el = queryFirstVisibleElement(TASK_CENTER_FLY_TARGET_SELECTORS, hostElement);\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n if (rect.width <= 0 && rect.height <= 0) return null;\n return {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n}\n\nexport function prefersReducedMotion(): boolean {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return false;\n }\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/** Inline visuals so the orb stays visible when mounted on `document.body`. */\nexport function applyPageActionLaunchOrbStyles(orb: HTMLElement): void {\n Object.assign(orb.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n zIndex: '2147483647',\n width: '14px',\n height: '14px',\n margin: '0',\n borderRadius: '999px',\n pointerEvents: 'none',\n background: 'radial-gradient(circle at 35% 35%, #69b1ff 0%, #1677ff 55%, #0047ce 100%)',\n boxShadow:\n '0 0 0 2px rgba(255, 255, 255, 0.95), 0 4px 14px rgba(22, 119, 255, 0.45)',\n willChange: 'transform, opacity',\n });\n}\n\nfunction pulseElement(el: HTMLElement): void {\n el.classList.add('is-launch-landed');\n window.setTimeout(\n () => el.classList.remove('is-launch-landed'),\n PAGE_ACTION_LAUNCH_LAND_DURATION_MS + 80,\n );\n}\n\nfunction pulseLaunchTargets(hostElement?: HTMLElement | null): void {\n if (typeof document === 'undefined') return;\n\n const pulsed = new Set<HTMLElement>();\n for (const root of queryLaunchRoots(hostElement)) {\n for (const selector of LAUNCH_LAND_PULSE_SELECTORS) {\n const el = root.querySelector(selector);\n if (!(el instanceof HTMLElement) || pulsed.has(el)) continue;\n const rect = el.getBoundingClientRect();\n if (rect.width <= 0 && rect.height <= 0) continue;\n pulsed.add(el);\n pulseElement(el);\n }\n }\n}\n\n/** Spin ring on the launcher bubble — same visual as background chat reply. */\nfunction startLauncherReceivingAnimation(hostElement?: HTMLElement | null): void {\n const bubble = findLauncherBubble(hostElement);\n if (!bubble) return;\n bubble.classList.add('is-launch-receiving');\n window.setTimeout(\n () => bubble.classList.remove('is-launch-receiving'),\n PAGE_ACTION_LAUNCH_FLY_DURATION_MS + PAGE_ACTION_LAUNCH_LAND_DURATION_MS,\n );\n}\n\nfunction rippleLaunchAnchor(anchor: HTMLElement | null | undefined): void {\n if (!(anchor instanceof HTMLElement)) return;\n anchor.classList.add('ac-page-action-trigger', 'is-launched');\n window.setTimeout(() => anchor.classList.remove('is-launched'), PAGE_ACTION_LAUNCH_FLY_DURATION_MS);\n}\n\nfunction flyLaunchOrb(\n from: PageActionSourceRect,\n to: PageActionSourceRect,\n onComplete: () => void,\n): void {\n if (typeof document === 'undefined') return;\n\n const start = rectCenter(from);\n const end = rectCenter(to);\n const arcLift = Math.min(72, Math.max(36, Math.abs(end.x - start.x) * 0.22));\n const mid = {\n x: (start.x + end.x) / 2,\n y: Math.min(start.y, end.y) - arcLift,\n };\n\n const orb = document.createElement('div');\n orb.className = 'page-action-launch-orb';\n orb.setAttribute('aria-hidden', 'true');\n applyPageActionLaunchOrbStyles(orb);\n document.body.appendChild(orb);\n\n const keyframes: Keyframe[] = [\n {\n transform: `translate(${start.x}px, ${start.y}px) translate(-50%, -50%) scale(0.25)`,\n opacity: 0,\n },\n {\n transform: `translate(${start.x}px, ${start.y}px) translate(-50%, -50%) scale(1)`,\n opacity: 1,\n offset: 0.14,\n },\n {\n transform: `translate(${mid.x}px, ${mid.y}px) translate(-50%, -50%) scale(0.92)`,\n opacity: 1,\n offset: 0.52,\n },\n {\n transform: `translate(${end.x}px, ${end.y}px) translate(-50%, -50%) scale(0.45)`,\n opacity: 0,\n },\n ];\n\n const animation = orb.animate(keyframes, {\n duration: PAGE_ACTION_LAUNCH_FLY_DURATION_MS,\n easing: PAGE_ACTION_LAUNCH_FLY_EASING,\n fill: 'forwards',\n });\n\n animation.onfinish = () => {\n orb.remove();\n onComplete();\n };\n animation.oncancel = () => {\n orb.remove();\n };\n}\n\n/** Play fly-to-task-center animation without invoking PageAction. */\nexport function playPageActionLaunchAnimation(\n anchor: HTMLElement | null | undefined,\n hostElement?: HTMLElement | null,\n): boolean {\n if (prefersReducedMotion()) return false;\n const sourceRect = readLaunchSourceRect(anchor);\n if (!sourceRect) return false;\n return playPageActionLaunchFromRect(sourceRect, hostElement, anchor);\n}\n\nexport function playPageActionLaunchFromRect(\n sourceRect: PageActionSourceRect,\n hostElement?: HTMLElement | null,\n rippleAnchor?: HTMLElement | null,\n): boolean {\n if (prefersReducedMotion()) return false;\n const target = findTaskCenterTargetRect(hostElement);\n if (!target) return false;\n\n rippleLaunchAnchor(rippleAnchor);\n startLauncherReceivingAnimation(hostElement);\n flyLaunchOrb(sourceRect, target, () => pulseLaunchTargets(hostElement));\n return true;\n}\n","/**\n * Host-facing PageAction execution-process view model (scheme B).\n * Built from {@link PageActionRowState}; safe for custom rendering.\n */\n\nimport type { PageActionPhase, PageActionRowState } from '../../types';\nimport {\n countInterestingNarrativeItems,\n pickNarrativeHeadline,\n shouldOfferNarrativeProcess,\n type NarrativeItem,\n} from './page-action-workflow-progress';\n\n/** Live / waiting phases where a process affordance is usually useful. */\nexport function isPageActionProcessLivePhase(phase: PageActionPhase): boolean {\n return (\n phase === 'submitting' ||\n phase === 'launched' ||\n phase === 'streaming' ||\n phase === 'awaiting_approval' ||\n phase === 'awaiting_clarify'\n );\n}\n\n/**\n * Normalized execution-process snapshot for custom UI.\n * Prefer {@link progressLabel} on the trigger; use {@link narrativeItems} for detail.\n */\nexport interface PageActionProcessView {\n phase: PageActionPhase;\n loading: boolean;\n awaitingApproval: boolean;\n awaitingClarify: boolean;\n /** Button loading copy — do not replace with narrative headline. */\n progressLabel: string | null;\n narrativeItems: NarrativeItem[];\n /** True when storyline has non-stage items worth showing. */\n hasProcess: boolean;\n interestingCount: number;\n /** Submitting / streaming / awaiting user. */\n isLive: boolean;\n /** Short headline from latest ask / outcome / evidence (optional). */\n headline: string | null;\n /**\n * Suggested: show a process affordance (built-in or custom).\n * `hasProcess && isLive` by default.\n */\n showProcessAffordance: boolean;\n}\n\nexport function toPageActionProcessView(\n row: Pick<\n PageActionRowState,\n | 'phase'\n | 'loading'\n | 'awaitingApproval'\n | 'awaitingClarify'\n | 'progressLabel'\n | 'narrativeItems'\n >,\n): PageActionProcessView {\n const narrativeItems = row.narrativeItems ?? [];\n const hasProcess = shouldOfferNarrativeProcess(narrativeItems);\n const isLive = isPageActionProcessLivePhase(row.phase);\n return {\n phase: row.phase,\n loading: row.loading,\n awaitingApproval: row.awaitingApproval,\n awaitingClarify: row.awaitingClarify,\n progressLabel: row.progressLabel,\n narrativeItems,\n hasProcess,\n interestingCount: countInterestingNarrativeItems(narrativeItems),\n isLive,\n headline: pickNarrativeHeadline(narrativeItems),\n showProcessAffordance: hasProcess && isLive,\n };\n}\n","import type { PendingGateJob } from './core/auth/login-gate';\nimport type { AgentChatError } from './core/lib/errors';\nimport type { WriteDraftPublic } from './core/draft-review/write-draft';\nimport type { EditPolicyPublic } from './core/draft-review/edit-policy';\nimport type { NarrativeItem } from './core/page/page-action-workflow-progress';\nimport type { MouseEvent, ReactNode, TouchEvent } from 'react';\n\nexport type { WriteDraftPublic, WriteDraftEditPayload } from './core/draft-review/write-draft';\n\nexport interface UserContext {\n /** Stable user identifier in the host application. */\n id: string;\n email?: string;\n name?: string;\n /**\n * Optional HMAC of the user identity. The backend may require this to\n * prevent identity spoofing from the browser. The exact algorithm is\n * decided by the backend (commonly `HMAC-SHA256(secret, userId + timestamp)`).\n */\n signature?: string;\n /** Unix timestamp in seconds, paired with `signature`. */\n signatureTimestamp?: number;\n}\n\nexport type Theme = 'light' | 'dark' | 'auto';\n\nexport type WidgetPosition =\n | 'bottom-right'\n | 'bottom-left'\n | 'top-right'\n | 'top-left';\n\n/** How the chat panel opens over the host page. */\nexport type PanelMode = 'sidebar' | 'floating' | 'fullscreen';\n\n/**\n * Floating launcher presentation.\n * - `compact` (default): idle edge-peek; expands on hover or when there is attention.\n * - `fab`: always full-size bubble (legacy).\n * - `hidden`: no built-in launcher (host opens via API / own chrome).\n */\nexport type LauncherMode = 'compact' | 'fab' | 'hidden';\n\n/** Default floating launcher mode. */\nexport const DEFAULT_LAUNCHER_MODE: LauncherMode = 'compact';\n\n/**\n * Current route location — always sent with user messages (auto-read from\n * `window.location` unless overridden via {@link AgentChatInstance.setRouteContext}).\n */\nexport interface AgentChatRouteContext {\n routePath?: string;\n /** Query string and/or dynamic path params supplied by the host router. */\n routeParams?: Record<string, string>;\n}\n\n/**\n * Extended business page context set by the host via `pageContext` /\n * {@link AgentChatInstance.setPageContext}. Sent as a lightweight page anchor\n * for Auto-Agent and page tools (route info is sent separately).\n */\nexport interface AgentChatPageContext {\n /** Human-readable page id, e.g. `campaign-edit`. */\n page?: string;\n /** @deprecated Prefer {@link AgentChatRouteContext.routePath}; route is always sent via route context. */\n routePath?: string;\n /** @deprecated Prefer {@link AgentChatRouteContext.routeParams}. */\n routeParams?: Record<string, string>;\n flowId?: number;\n programName?: string;\n /** Primary entity on the page, e.g. `{ type: 'campaign', id: '123' }`. */\n entity?: {\n type?: string;\n id?: string;\n [key: string]: unknown;\n };\n /** Extra small key-value payload (avoid large blobs). */\n metadata?: Record<string, unknown>;\n}\n\n/** `POST /page-action/brain-invoke` request body. */\n/** Candidate row inside {@link BrainClarifyPayload}. */\nexport interface BrainClarifyCandidate {\n id: string;\n entityType: string;\n text?: string;\n fields?: Record<string, unknown>;\n source?: string;\n path?: string;\n}\n\n/**\n * Brain ASK_USER entity disambiguation payload (PageAction SSE / Chat run steps).\n * Continuations use {@link EntityCommit} — no dedicated `awaiting_clarify` run status.\n */\nexport interface BrainClarifyPayload {\n kind: 'entity_resolve';\n question: string;\n reason: string;\n entityType: string;\n candidates: BrainClarifyCandidate[];\n commitHint: { entityType: string };\n proposalType: string;\n}\n\n/** Structured entity pick for PageAction `invoke` / Chat `message` continuation. */\nexport interface EntityCommit {\n entityType: string;\n selectedId: string;\n}\n\nexport interface InvokePageActionRequest {\n actionKey: string;\n pageContext?: AgentChatPageContext;\n instruction?: string;\n context?: Record<string, unknown>;\n idempotencyKey?: string;\n clientActionId?: string;\n /**\n * Brain clarify continuation — same `pageContext` / `actionKey` as the prior run,\n * with the user-selected candidate id.\n */\n entityCommit?: EntityCommit;\n}\n\n/** `POST /page-action/brain-invoke` accepted payload (JSON, not SSE). */\nexport interface InvokePageActionAccepted {\n runId: number;\n generation: number;\n clientActionId: string | null;\n pageActionKey: string | null;\n streamUrl: string;\n status: AutomationTaskStatus;\n}\n\n/** `POST /page-action/brain-invoke` conflict — active run for same `pageActionKey`. */\nexport interface PageActionAlreadyActive {\n code: 'PAGE_ACTION_ALREADY_ACTIVE';\n message: string;\n pageActionKey: string;\n existingRunId: number;\n existingStatus: 'running' | 'awaiting_approval';\n approvalRequestId: number | null;\n streamUrl: string;\n}\n\nexport type PageActionInvokeResult =\n | ({ kind: 'accepted' } & InvokePageActionAccepted)\n | ({ kind: 'already_active' } & PageActionAlreadyActive);\n\nexport type PageActionLifecyclePhase =\n | 'started'\n | 'stream'\n | 'completed'\n | 'failed'\n | 'awaiting_approval';\n\nexport interface PageActionSseLifecycle {\n phase: PageActionLifecyclePhase;\n actionRunId: number;\n actionKey: string;\n generation: number;\n clientActionId?: string | null;\n streamId?: string | null;\n text?: string;\n dslOutcome?: string | null;\n errorCode?: string | null;\n errorMessage?: string | null;\n /** Present when `phase=failed` + `errorCode=BRAIN_ASK_USER`. */\n brainClarify?: BrainClarifyPayload | null;\n}\n\n/** {@link AgentChatInstance.invokePageAction} input. */\nexport interface PageBotInvokeInput extends InvokePageActionRequest {\n onChunk?: (chunk: string) => void;\n signal?: AbortSignal;\n /**\n * When `false`, returns after `POST /page-action/brain-invoke` and consumes SSE in the\n * background (for non-blocking trigger UIs). Default `true`.\n */\n awaitStream?: boolean;\n /** Optional DOM anchor for launch fly-to animation (`pageActionSubmitted.sourceRect`). */\n launchAnchor?: HTMLElement | null;\n /**\n * Host list-row key for per-row UI state (`usePageActions`).\n * Defaults to `String(pageContext.entity.id)` when omitted.\n */\n rowKey?: string;\n /**\n * When `true` (default) and the chat UI is mounted, check `reuse-hint` before invoke.\n * If reusable runs exist, show the SDK popover anchored to {@link launchAnchor};\n * only invoke after the user confirms「重新执行」.\n * Set `false` to skip the hint and invoke immediately.\n */\n preferReuse?: boolean;\n}\n\n/** One successful run returned by `POST /page-action/reuse-hint`. */\nexport interface PageActionReusableItem {\n ref: { kind: 'page_action_run'; id: number };\n triggerSource: AutomationTriggerSource;\n taskStatus: AutomationTaskStatus;\n succeeded?: boolean;\n /** Executor user id (cross-user reuse). */\n runUserId?: number;\n title: string;\n subtitle: string | null;\n pageActionKey: string | null;\n createdAt: string;\n finishedAt: string | null;\n outputs: {\n preview: string | null;\n fillText?: string | null;\n hasFillText: boolean;\n };\n}\n\n/** `POST /page-action/reuse-hint` response. */\nexport interface PageActionReuseHint {\n pageActionKey: string;\n actionKey: string;\n reusable: {\n total: number;\n items: PageActionReusableItem[];\n };\n}\n\n/** Decision from the built-in reuse popover (or a custom handler). */\nexport type PageActionReuseDecision =\n | { type: 'reuse'; runId: number }\n | { type: 'rerun' }\n | { type: 'cancel' };\n\n/**\n * Fields needed to re-invoke after the user applies a reused result and then\n * chooses「继续执行」from the docked bar.\n */\nexport interface PageActionReuseInvokeSnapshot {\n pageContext?: AgentChatPageContext;\n instruction?: string;\n context?: Record<string, unknown>;\n clientActionId?: string;\n idempotencyKey?: string;\n rowKey?: string;\n awaitStream?: boolean;\n}\n\n/** Payload for the SDK reuse prompt UI. */\nexport interface PageActionReusePromptRequest {\n actionKey: string;\n pageActionKey: string;\n items: PageActionReusableItem[];\n /** Button rect for anchoring the popover. */\n sourceRect: PageActionSourceRect | null;\n /** Live anchor element when still in the DOM (reposition on scroll). */\n launchAnchor?: HTMLElement | null;\n /** Snapshot for「继续执行」after a reused result was already applied. */\n invokeSnapshot?: PageActionReuseInvokeSnapshot;\n}\n\nexport type PageActionReusePromptHandler = (\n request: PageActionReusePromptRequest,\n) => Promise<PageActionReuseDecision>;\n\nexport type PageActionPhase =\n | 'idle'\n | 'submitting'\n | 'launched'\n | 'streaming'\n | 'awaiting_approval'\n /** Local UI: Brain ASK_USER — show clarify popover; not a server run status. */\n | 'awaiting_clarify'\n /** Local UI: reuse-hint popover open — not a server run; must not stick `loading`. */\n | 'awaiting_reuse'\n | 'completed'\n | 'failed';\n\n/**\n * Fields needed to re-invoke after the user picks a Brain clarify candidate.\n */\nexport interface PageActionBrainClarifyInvokeSnapshot {\n pageContext?: AgentChatPageContext;\n instruction?: string;\n context?: Record<string, unknown>;\n clientActionId?: string;\n idempotencyKey?: string;\n rowKey?: string;\n awaitStream?: boolean;\n}\n\n/** Payload for the built-in Brain clarify popover. */\nexport interface PageActionBrainClarifyPromptRequest {\n actionKey: string;\n runId: number;\n brainClarify: BrainClarifyPayload;\n sourceRect: PageActionSourceRect | null;\n launchAnchor?: HTMLElement | null;\n invokeSnapshot?: PageActionBrainClarifyInvokeSnapshot;\n}\n\n/**\n * Per-row PageAction UI state for list pages.\n * Keyed by host `rowKey` (typically `String(entity.id)`).\n */\nexport interface PageActionRowState {\n rowKey: string;\n actionKey: string;\n runId: number | null;\n pageActionKey: string | null;\n phase: PageActionPhase;\n awaitingApproval: boolean;\n /** True while {@link phase} is `awaiting_clarify`. */\n awaitingClarify: boolean;\n loading: boolean;\n disabled: boolean;\n error: string | null;\n /**\n * Soft tip (duplicate click / already running). Not a failure —\n * keep showing progress; do not treat as {@link error}.\n */\n message: string | null;\n /**\n * SSE `page_workflow` loading copy for the trigger button (`stageKind` path).\n * Hosts should render this as loading copy; clear on completed/failed.\n */\n progressLabel: string | null;\n /**\n * Accumulated `page_workflow.narrativeItems` storyline for this run.\n * Hosts may build custom process UI from this (see `toPageActionProcessView`).\n * Does not replace {@link progressLabel}.\n */\n narrativeItems: NarrativeItem[];\n approvalRequestId: number | null;\n /** Present when {@link phase} is `awaiting_clarify`. */\n brainClarify: BrainClarifyPayload | null;\n updatedAt: number;\n}\n\n/** Fired when a list-row PageAction slot changes. */\nexport interface PageActionRowChangedPayload {\n rowKey: string;\n state: PageActionRowState;\n}\n\n/** SSE re-attached after refresh or resume (not the initial invoke stream). */\nexport interface PageActionStreamResumedPayload {\n runId: number;\n actionKey: string;\n rowKey: string;\n}\n\nexport interface PageActionRunLifecyclePayload {\n runId: number;\n actionKey: string;\n rowKey?: string | null;\n errorMessage?: string | null;\n /** Set on failed runs — `BRAIN_ASK_USER` should not toast as a system failure. */\n errorCode?: string | null;\n brainClarify?: BrainClarifyPayload | null;\n}\n\n/** Intent from「应用到页面」waiting for the target page to become ready. */\nexport type PendingPageActionApply = {\n runId: number;\n actionKey: string;\n pageContext: AgentChatPageContext | null;\n createdAt: string;\n};\n\nexport type PageActionApplyPhase =\n | 'idle'\n | 'waiting_ready'\n | 'replaying'\n | 'done'\n | 'error';\n\nexport interface PageActionSlotApplyPhasePayload {\n slotKey: string;\n phase: PageActionApplyPhase;\n}\n\n/** Screen rect for PageAction launch animation (viewport coordinates). */\nexport type PageActionSourceRect = Pick<DOMRect, 'left' | 'top' | 'width' | 'height'>;\n\n/** `pageActionSubmitted` event payload. */\nexport type PageActionSubmittedPayload = InvokePageActionAccepted & {\n sourceRect?: PageActionSourceRect | null;\n /** Live trigger element when still in the DOM (reposition narrative chip). */\n launchAnchor?: HTMLElement | null;\n /** Host row slot for list pages. */\n rowKey?: string | null;\n actionKey?: string;\n};\n\n/** Outcome surfaced after inbox approve / decide resumes a PageAction run. */\nexport type ApprovalExecutionOutcome =\n | 'completed'\n | 'failed'\n | 'running'\n | 'awaiting_approval'\n | 'cancelled';\n\n/** `approvalExecutionCompleted` event payload. */\nexport interface ApprovalExecutionCompletedPayload {\n approvalId: number;\n runId: number | null;\n outcome: ApprovalExecutionOutcome;\n /**\n * Best display title for toasts — prefers the inbox approval title the user\n * just confirmed (list/detail), then the automation task title.\n */\n title?: string | null;\n /** Raw inbox item title when available (list-row identity). */\n approvalTitle?: string | null;\n /** Inbox summary for richer toast body. */\n approvalSummary?: string | null;\n preview?: string | null;\n taskStatus?: AutomationTaskStatus;\n}\n\nexport interface PageBotStreamResult {\n actionRunId: number;\n text: string;\n dslOutcome: string | null;\n /** Invoke paused at workflow approval gate — confirm via inbox API. */\n awaitingApproval?: boolean;\n /**\n * Brain ASK_USER — show clarify UI; not a thrown failure.\n * Continuations use a fresh `invoke` with {@link EntityCommit}.\n */\n awaitingClarify?: boolean;\n /** Set when {@link awaitingApproval} is true. */\n status?: 'awaiting_approval';\n actionKey?: string;\n clientActionId?: string;\n approvalRequestId?: number | null;\n brainClarify?: BrainClarifyPayload | null;\n /**\n * Soft tip (e.g. duplicate invoke / 409 already active).\n * Not a thrown error — UI may toast or show beside the button.\n */\n message?: string | null;\n /** True when invoke hit an already-active run (local guard or HTTP 409). */\n alreadyActive?: boolean;\n /** True when the user reused an existing successful run (no new invoke). */\n reused?: boolean;\n /** True when the reuse popover was dismissed without reuse or rerun. */\n cancelled?: boolean;\n}\n\nexport type ApprovalSource = 'chat' | 'page_action' | 'webhook';\n\nexport type ApprovalStatus = 'pending' | 'approved' | 'rejected' | 'cancelled' | 'expired';\n\n/** `GET /approval/inbox?status=` filter values. */\nexport type ApprovalInboxStatusFilter =\n | 'pending'\n | 'approved'\n | 'rejected'\n | 'cancelled'\n | 'expired'\n | 'decided'\n | 'all';\n\nexport interface ApprovalInitiator {\n id: number;\n username: string | null;\n employeeId: string | null;\n}\n\nexport interface ApprovalPendingWritePreview {\n tool: string;\n riskLevel: string;\n}\n\nexport type ApprovalEntityReferenceDisplayField = {\n key: string;\n label: string;\n value: string;\n};\n\n/** Workflow read / page inline snapshot for approval comparison. */\nexport interface ApprovalEntityReferenceInlineRecord {\n kind: string;\n title: string;\n fields: ApprovalEntityReferenceDisplayField[];\n imageUrls: string[];\n /** Pre-projection snapshot (`inlineRecords[].record`); render via legacy path only. */\n legacyRecord?: Record<string, unknown>;\n}\n\nexport interface ApprovalEntityReferenceSource {\n ref: string;\n action: string;\n title: string;\n toolName: string | null;\n toolId: number | null;\n data: unknown;\n fields: ApprovalEntityReferenceDisplayField[];\n imageUrls?: string[];\n}\n\nexport interface ApprovalEntityReference {\n page: string | null;\n routePath: string | null;\n entityType: string | null;\n entityId: string | null;\n anchorLabel: string | null;\n inlineRecords: ApprovalEntityReferenceInlineRecord[];\n sources: ApprovalEntityReferenceSource[];\n /** True when parsed from a pre-projection approval snapshot. */\n legacy?: boolean;\n}\n\n/** Draft retry budget from inbox `draftReview` (page_action approvals). */\nexport interface ApprovalDraftReviewBudget {\n retryCount: number;\n retryMax: number | null;\n canRetry: boolean;\n}\n\nexport interface ApprovalInboxItem {\n id: number;\n source: ApprovalSource;\n status: ApprovalStatus;\n title: string;\n summary: string | null;\n workflowId: number;\n workflowVersion: number;\n workflowKey: string | null;\n workflowName: string | null;\n nodeId: string;\n sessionId: string | null;\n pageActionRunId: number | null;\n initiator: ApprovalInitiator | null;\n createdAt: string;\n decidedAt?: string | null;\n previewBlocks: unknown;\n pendingWrite: ApprovalPendingWritePreview | null;\n /** Execution truth + presentation from server (`GET /approval/inbox`). */\n writeDraft?: WriteDraftPublic | null;\n /** Server-derived field edit rules — drives draft review UI. */\n editPolicy?: EditPolicyPublic | null;\n writeDrafts?: WriteDraftPublic[] | null;\n editPolicies?: Array<EditPolicyPublic | null> | null;\n draftReview?: ApprovalDraftReviewBudget | null;\n /** Paired reference snapshot (`GET /approval/inbox` / `GET /approval/:id`). */\n entityReference?: ApprovalEntityReference | null;\n}\n\nexport interface ApprovalInboxList {\n items: ApprovalInboxItem[];\n hasMore: boolean;\n}\n\nexport interface ApprovalDetail extends ApprovalInboxItem {\n decidedAt: string | null;\n}\n\nexport interface ApprovalConfirmResult {\n resumed: boolean;\n suspended?: boolean;\n}\n\n/** Alias of {@link WriteGate} for `POST /approval/:id/decide` body `decision`. */\nexport type DraftReviewDecision = WriteGate;\n\nexport interface ApprovalDecideResult {\n resumed: boolean;\n suspended?: boolean;\n}\n\nexport interface ApprovalRejectResult {\n ok: boolean;\n}\n\n/** Cached page_action / webhook approvals for the inbox UI (not chat write gates). */\nexport interface ApprovalInboxState {\n items: ApprovalInboxItem[];\n loading: boolean;\n loadingMore: boolean;\n hasMore: boolean;\n statusFilter: ApprovalInboxStatusFilter;\n /** Approximate pending count for badge (from last `status=pending` fetch). */\n pendingCount: number;\n}\n\nexport type AutomationTriggerSource = 'page_action' | 'webhook';\n\nexport type AutomationTaskRefKind = 'page_action_run' | 'webhook_approval';\n\nexport type AutomationTaskRef =\n | { kind: 'page_action_run'; id: number }\n | { kind: 'webhook_approval'; id: number };\n\nexport type AutomationTaskStatus =\n | 'running'\n | 'awaiting_approval'\n | 'completed'\n | 'failed'\n | 'cancelled';\n\n/** `GET /automation/tasks?status=` filter values. */\nexport type AutomationTaskStatusFilter =\n | AutomationTaskStatus\n | 'active'\n | 'all';\n\nexport type AutomationTriggerSourceFilter = AutomationTriggerSource | 'all';\n\nexport interface AutomationTaskListItem {\n ref: AutomationTaskRef;\n triggerSource: AutomationTriggerSource;\n taskStatus: AutomationTaskStatus;\n title: string;\n subtitle: string | null;\n workflowKey: string | null;\n workflowName: string | null;\n pageActionKey: string | null;\n createdAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n approval: { id: number; status: string } | null;\n outputs: {\n preview: string | null;\n hasFillText: boolean;\n };\n}\n\nexport type AutomationTaskTimelineEntry = {\n step: number;\n type: string;\n name: string;\n at: string;\n status?: 'ok' | 'failed' | 'skipped';\n};\n\nexport type AutomationTaskDetail = AutomationTaskListItem & {\n actionKey: string;\n instruction: string | null;\n errorCode: string | null;\n errorMessage: string | null;\n streamUrl: string;\n timeline: AutomationTaskTimelineEntry[];\n workflowRun: unknown | null;\n /** Present when `errorCode=BRAIN_ASK_USER`. */\n brainClarify: BrainClarifyPayload | null;\n /**\n * Invoke 时快照的页锚点(`page` / `entity` / 可选 `routePath`+`routeParams`)。\n * 任务中心「应用到页面」导航与 replay 门禁用;历史 run 可能为 null。\n */\n pageContext: AgentChatPageContext | null;\n /** 后端实时计算的重放能力(非缓存)。 */\n replay: {\n canReplay: boolean;\n hasHostAction: boolean;\n dslOutcome: string | null;\n };\n};\n\nexport interface AutomationTaskList {\n items: AutomationTaskListItem[];\n total: number;\n hasMore: boolean;\n}\n\n/** Cached PageAction automation tasks for the task center UI. */\nexport interface AutomationTaskCenterState {\n items: AutomationTaskListItem[];\n loading: boolean;\n loadingMore: boolean;\n hasMore: boolean;\n /** Server-reported total for the active tab filter (`0` when unknown). */\n total: number;\n statusFilter: AutomationTaskStatusFilter;\n /** Recently submitted run ids (optimistic highlight). */\n recentRunIds: number[];\n /** Active run count for launcher badge (derived from in-memory run registry). */\n activeCount: number;\n /** Detail row when a task card is opened. */\n selectedDetail: AutomationTaskDetail | null;\n detailLoading: boolean;\n}\n\n/** @deprecated Legacy SSE field — no longer read by the SDK. */\nexport type AgentChatHostActionType = 'refresh' | 'invalidate' | 'navigate';\n\n/** Known `reason` values on SSE `host_action` (server may send custom strings). */\nexport const HOST_ACTION_REASON = {\n PLAN_HOST_TOOL_STREAM: 'plan_host_tool_stream',\n PLAN_HOST_TOOL: 'plan_host_tool',\n AGENT_MUTATION_SUCCESS: 'agent_mutation_success',\n HOST_TOOL_DISPATCH: 'host_tool_dispatch',\n PAGE_ACTION_HOST_FILL: 'page_action_host_fill',\n} as const;\n\nexport type HostActionReason =\n (typeof HOST_ACTION_REASON)[keyof typeof HOST_ACTION_REASON] | string;\n\nexport interface AgentChatHostToolCall {\n name: string;\n args: Record<string, unknown>;\n}\n\n/**\n * SSE `host_action` payload — instructs the browser to run `hostTools`.\n * Aligned with agent-server `HostActionSsePayload` (no `status` field).\n */\nexport interface AgentChatHostAction {\n /** Envelope discriminator — always `host_action` after normalization. */\n action: 'host_action';\n /** Business page scope — matches `pageContext.page`; required for dispatch. */\n scope: string;\n entity?: AgentChatPageContext['entity'];\n metadata?: Record<string, unknown>;\n /** Registry tools to run in order (server sends only when non-empty). */\n hostTools: AgentChatHostToolCall[];\n /** Plan host_tool step id when pushed mid-run — not the reason step id. */\n planStepId?: string;\n /** e.g. `plan_host_tool` | `agent_mutation_success` */\n reason?: string;\n runId?: number;\n turnId?: number;\n messageId?: string;\n sessionId?: string;\n /** DSL v1 streaming phase — present on intermediate frames. */\n streamPhase?: 'streaming' | 'complete';\n /** Accumulated args preview during DSL streaming (`invokeOnAppend: false`). */\n streamPreview?: {\n callId: string;\n name: string;\n args: Record<string, unknown>;\n };\n}\n\n/** Alias aligned with agent-server host-action SDK docs. */\nexport type HostActionPayload = AgentChatHostAction;\n\nexport type HostToolHandler = (\n args: Record<string, unknown>,\n) => void | Promise<void>;\n\n/** Host tool metadata synced to the server (handler is local-only). */\nexport type HostToolMetadata = {\n name: string;\n description: string;\n argsSchema: Record<string, unknown>;\n generic?: boolean;\n /** Server-side args resolution, e.g. `{ entityId: '$entity.id' }`. */\n argsTemplate?: Record<string, unknown>;\n definitionKey?: string;\n /**\n * When `true`, registry handler runs on each `arg.append` / `arg.set` during DSL\n * streaming. When `false` (default) and `onPreview` is omitted, the SDK\n * still streams into the handler on each append; `stream.full` skips\n * duplicate execution for that call.\n */\n invokeOnAppend?: boolean;\n /**\n * Optional streaming-only callback. When set, takes precedence over the handler\n * during `arg.append`; handler still runs at `stream.full` unless already marked.\n */\n onPreview?: HostToolHandler;\n};\n\n/** Local host tool definition (handler stays in the browser). */\nexport interface HostToolDefinition extends HostToolMetadata {\n handler: HostToolHandler;\n}\n\n/**\n * App-root tool declaration — metadata sync + optional local handler.\n * App-wide scope is implied by {@link useAppAgent}; do not pass `generic`.\n */\nexport type AppHostToolDefinition = Omit<HostToolMetadata, 'generic'> & {\n handler?: HostToolHandler;\n};\n\nexport interface RegisterHostToolsOptions {\n /** `pageContext.page` — required for page-scoped tools. */\n scope?: string;\n pageLabel?: string;\n routePattern?: string;\n tools: Array<HostToolDefinition | AppHostToolDefinition>;\n /** Sync metadata to `POST /host-tool/client/register`. Default `true`. */\n syncToServer?: boolean;\n /**\n * App-wide registration (`useAppAgent`). Uses scope `*` and syncs `generic: true`\n * to the server without requiring `generic` on each tool.\n */\n appLevel?: boolean;\n}\n\n/** Options for {@link AgentChatInstance.prepareSession}. */\nexport interface PrepareSessionOptions {\n signal?: AbortSignal;\n /** Re-run even when the page/session fingerprint is unchanged. */\n force?: boolean;\n}\n\n/** Response from `POST /chat/{sessionId}/prepare` (host-tool L1 warm). */\nexport interface PrepareSessionResult {\n sessionId: string;\n prepared: boolean;\n agentReady: boolean;\n toolsCount: number;\n skillsCount: number;\n hostToolsCount: number;\n pageScope: string | null;\n sessionContextWarmed: boolean;\n warmedAt?: string;\n fromCache: boolean;\n revision?: Record<string, string>;\n}\n\nexport interface AgentChatHostActionPayload {\n action: AgentChatHostAction;\n phase?: 'streaming' | 'complete';\n}\n\n/** Origin of a host-tool DSL stream observed by the host page. */\nexport type PageAgentSource = 'chat' | 'page_action';\n\nexport interface PageAgentStreamEntity {\n type?: string;\n id?: string | number;\n}\n\n/** `onStart` — `session.begin` or `tool.begin`. */\nexport interface PageAgentStartContext {\n streamId: string;\n scope: string;\n source: PageAgentSource;\n toolName?: string;\n callId?: string;\n entity?: PageAgentStreamEntity;\n reason?: string;\n runId?: number;\n turnId?: number;\n}\n\n/** `onStream` — `arg.append` / `arg.set` with SDK-accumulated args. */\nexport interface PageAgentStreamContext {\n streamId: string;\n scope: string;\n source: PageAgentSource;\n callId: string;\n toolName: string;\n args: Record<string, unknown>;\n entity?: PageAgentStreamEntity;\n reason?: string;\n}\n\n/** `onComplete` — `stream.full` or batch `hostTools`. */\nexport interface PageAgentCompleteContext {\n streamId?: string;\n scope: string;\n source: PageAgentSource;\n hostTools: AgentChatHostToolCall[];\n action?: AgentChatHostAction;\n entity?: PageAgentStreamEntity;\n reason?: string;\n}\n\n/** `onError` — stream / tool / page_action failure. */\nexport interface PageAgentErrorContext {\n scope?: string;\n source: PageAgentSource;\n phase: 'stream' | 'tool' | 'page_action' | 'approval';\n code?: string;\n message: string;\n streamId?: string;\n callId?: string;\n}\n\nexport type PageAgentLifecyclePayload =\n | { type: 'start'; context: PageAgentStartContext }\n | { type: 'stream'; context: PageAgentStreamContext }\n | { type: 'complete'; context: PageAgentCompleteContext }\n | { type: 'error'; context: PageAgentErrorContext };\n\n/** Emitted when `invokePageAction` pauses at `awaiting_approval`. */\nexport interface PageAgentAwaitingApprovalPayload {\n scope: string;\n actionRunId: number;\n actionKey?: string;\n clientActionId?: string;\n approvalRequestId?: number | null;\n}\n\n/** Built-in notification when PageAction needs inbox approval. */\nexport interface PageActionAwaitingApprovalNoticePayload {\n actionRunId: number;\n actionKey?: string;\n approvalRequestId?: number | null;\n}\n\n/** Soft conflict tip (duplicate invoke / HTTP 409) — do not treat as PageAction failure. */\nexport interface PageActionSoftNoticePayload {\n kind: 'already_running' | 'already_awaiting_approval';\n message: string;\n runId?: number | null;\n actionKey?: string;\n approvalRequestId?: number | null;\n}\n\n/** Optional target when opening the approval inbox drawer. */\nexport interface OpenApprovalInboxPayload {\n approvalId?: number;\n}\n\n/** Optional target when opening the automation task center drawer. */\nexport interface OpenAutomationTaskCenterPayload {\n /** When set, open the drawer and hydrate that run’s detail view. */\n runId?: number;\n}\n\n/** Optional target when opening「我的反馈」drawer. */\nexport interface OpenPageActionFeedbackPayload {\n /** Prefer tab: `rating` = 场景评价, `wish` = 需求收集. */\n tab?: 'rating' | 'wish';\n /** Pre-select actionKey on the rating tab. */\n actionKey?: string;\n}\n\n/** Current user’s rating as returned on `GET /page-action/catalog` items. */\nexport interface PageActionCatalogMyFeedback {\n rating: number;\n comment: string | null;\n updatedAt: string;\n}\n\n/** One enabled PageAction from `GET /page-action/catalog`. */\nexport interface PageActionFeedbackCatalogItem {\n pageActionId: number;\n actionKey: string;\n name: string;\n description: string | null;\n pageScope: string | null;\n sortOrder: number;\n /**\n * `true` when the PageAction has a non-empty rollout allowlist.\n * Items returned by catalog already passed the check; debug-only.\n */\n rolloutRestricted: boolean;\n myFeedback: PageActionCatalogMyFeedback | null;\n}\n\nexport interface PageActionFeedbackCatalogQuery {\n /** Current `pageContext.page`. Omit for the global feedback center. */\n pageScope?: string | null;\n}\n\n/** Reason codes from `POST /page-action/rollout-check`. */\nexport type PageActionRolloutReason =\n | 'open'\n | 'allowlist_hit'\n | 'denied'\n | 'not_found'\n | 'inactive'\n | string;\n\n/** One actionKey result from `POST /page-action/rollout-check`. */\nexport interface PageActionRolloutCheckItem {\n actionKey: string;\n allowed: boolean;\n reason: PageActionRolloutReason;\n}\n\nexport interface PageActionRolloutCheckInput {\n actionKeys: string[];\n}\n\n/** One user’s rating on a PageAction config (`PUT/GET /page-action/feedback/:actionKey`). */\nexport interface PageActionFeedbackView {\n id: number;\n pageActionId: number;\n actionKey: string;\n pageActionName: string;\n appClientId: number;\n userId: number;\n rating: number;\n comment: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface UpsertPageActionFeedbackInput {\n rating: number;\n comment?: string;\n}\n\n/** Aggregate ratings for one actionKey. */\nexport interface PageActionFeedbackSummary {\n pageActionId: number;\n actionKey: string;\n pageActionName: string;\n count: number;\n avgRating: number | null;\n ratingDistribution: Record<'1' | '2' | '3' | '4' | '5', number>;\n}\n\nexport type PageActionWishStatus =\n | 'submitted'\n | 'reviewing'\n | 'planned'\n | 'in_progress'\n | 'done'\n | 'rejected'\n | 'cancelled';\n\nexport interface PageActionWishView {\n id: number;\n appClientId: number;\n userId: number;\n title: string;\n description: string;\n pageScope: string | null;\n relatedActionKey: string | null;\n status: PageActionWishStatus;\n developerNote: string | null;\n statusUpdatedAt: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreatePageActionWishInput {\n title: string;\n description: string;\n pageScope?: string;\n relatedActionKey?: string;\n}\n\nexport interface PageActionWishQuery {\n page?: number;\n pageSize?: number;\n status?: PageActionWishStatus;\n keyword?: string;\n pageScope?: string;\n relatedActionKey?: string;\n}\n\nexport interface PageActionWishList {\n items: PageActionWishView[];\n total: number;\n page: number;\n pageSize: number;\n hasMore: boolean;\n}\n\n/** Default panel layout when embedded. */\nexport const DEFAULT_PANEL_MODE: PanelMode = 'sidebar';\n\n/** Branding shown in the panel header and assistant avatar. */\nexport interface AgentChatProjectConfig {\n /** Project / product name shown at the top-left of the chat panel. */\n name?: string;\n /** Logo URL for the assistant avatar (and default launcher icon). */\n logo?: string;\n}\n\n/** Props passed to a custom floating launcher (`launcher` render function). */\nexport interface AgentChatLauncherProps {\n position: { x: number; y: number };\n loading: boolean;\n /** Pending page-action / webhook approvals (`GET /approval/inbox`). */\n pendingApprovalCount: number;\n open: () => void;\n /** Open panel + approval inbox drawer (launcher badge). */\n openApprovalInbox?: () => void;\n /** Active PageAction runs (`GET /automation/tasks?status=active`). */\n activeAutomationCount?: number;\n /** Open panel + automation task center drawer. */\n openAutomationTaskCenter?: () => void;\n /** Open「我的反馈」drawer (场景评价 + 需求收集). */\n openPageActionFeedback?: () => void;\n /**\n * Effective launcher mode for this render (`hidden` never reaches the slot).\n * Custom launchers may ignore this and own their chrome.\n */\n launcherMode?: Exclude<LauncherMode, 'hidden'>;\n /**\n * True when the default bubble should stay expanded (streaming, pending\n * approval, or active automation). Useful for custom compact launchers.\n */\n attention?: boolean;\n /**\n * Right-click menu actions for the default bubble.\n * `hide` dismisses until attention; `restore` clears the dismiss preference.\n */\n onLauncherVisibilityAction?: (action: 'hide' | 'restore') => void;\n /** True when the user has dismissed the launcher (menu → hide). */\n userDismissed?: boolean;\n onMouseDown: (event: MouseEvent<HTMLElement>) => void;\n onTouchStart: (event: TouchEvent<HTMLElement>) => void;\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n}\n\nexport interface AgentChatOptions {\n /**\n * Required. Opaque DSN string identifying this client on the auth service.\n * Treated as an unparsed credential — the SDK forwards it as the\n * `x-app-dsn` request header on every backend call.\n */\n dsn: string;\n /**\n * Backend base URL. Used for **all** SDK API calls, i.e. every request is\n * sent to `{baseUrl} + path`.\n * Defaults to `http://localhost:3030`; override in production.\n */\n baseUrl?: string;\n /**\n * Optional account token for `POST /app-client/auth` (`x-account-token` +\n * `x-app-dsn`). The response `accessToken` is used as `Authorization: Bearer`\n * on subsequent `/chat`, `/agent`, etc.\n */\n accountToken?: string;\n /**\n * @deprecated Alias of `accountToken` for backward compatibility.\n * Sent as `x-account-token` on `POST /app-client/auth`.\n */\n userAccessToken?: string;\n /** Optional end-user context. Forwarded to the backend at handshake time. */\n user?: UserContext;\n /** BCP-47 locale, defaults to `navigator.language`. */\n locale?: string;\n /** Visual theme. `auto` follows `prefers-color-scheme`. */\n theme?: Theme;\n /** Optional antd theme token overrides forwarded to ConfigProvider.theme.token. */\n themeToken?: Record<string, unknown>;\n /** Where the floating launcher button anchors to the viewport. */\n position?: WidgetPosition;\n /**\n * Floating launcher density. Default {@link DEFAULT_LAUNCHER_MODE} (`compact`):\n * idle peeks smaller toward the nearest edge; expands on hover or when there\n * is pending approval / streaming / active automation. Use `fab` for the\n * legacy always-on ball, or `hidden` to rely on host chrome / `open()`.\n */\n launcherMode?: LauncherMode;\n /**\n * Panel layout when open. `sidebar` (default) keeps the host page visible;\n * `floating` is a corner card; `fullscreen` covers the viewport.\n */\n panelMode?: PanelMode;\n /**\n * Allow end users to switch panel layout (sidebar / floating / fullscreen) from\n * the panel header. Preference is stored in `localStorage`. Default `true`.\n */\n panelModeSwitchable?: boolean;\n /**\n * Extended page context (entity, metadata, …) from the host app. Updated via\n * prop or {@link AgentChatInstance.setPageContext}. Sent as a lightweight page\n * anchor with chat messages so Auto-Agent and host-tool prepare can match the\n * current page; route info is always sent via {@link AgentChatState.routeContext}.\n */\n pageContext?: AgentChatPageContext;\n /** Default for the page-context visibility toggle in the chat panel. Default `false`. */\n attachPageContext?: boolean;\n /** Open the widget panel automatically after init (React UI must be mounted). */\n autoOpen?: boolean;\n /** Print verbose logs to the console. */\n debug?: boolean;\n /**\n * Host Tool DSL v1 stream reducer. Default `true`. Set `false` to only handle\n * v0 batch and `stream.mode=full` frames (emergency rollback).\n */\n hostToolStream?: boolean;\n /**\n * Built-in PageAction execution-process UI (detail affordance + timeline popover).\n * Default `true`. Set `false` when the host renders process from hook data\n * (`progressLabel` / `narrativeItems` / `toPageActionProcessView`).\n */\n pageActionProcessUi?: boolean;\n /**\n * 任务中心「应用到页面」时的宿主导航回调。\n * SDK 解析 `detail.pageContext` 优先级后传入;宿主负责真正 `navigate` / 路由表映射。\n */\n onNavigateForPageAction?: (\n input: import('./core/page/page-context-navigate').NavigateForPageActionInput,\n ) => void | Promise<void>;\n /** Extra request headers added to every backend call. */\n headers?: Record<string, string>;\n /** Convenience alias for `instance.on('ready', handler)`. */\n onReady?: () => void;\n /** Static agent list; used when `GET /agent/client/available` is unavailable. */\n agents?: ChatAgentSummary[];\n /** Static skill list; used when skills client API is unavailable. */\n skills?: ChatSkillSummary[];\n /** Optional query for `GET /agent/client/available`. */\n agentListQuery?: QueryClientAvailableAgents;\n /**\n * Optional extra query for `GET /agent/:agentId/skills/client`.\n * When `pageContext.page` is set, the SDK also sends `?page=` automatically.\n */\n skillListQuery?: QueryClientSkillByAgent;\n /** Initial agent selection (`id` from agents list). */\n defaultAgentId?: string;\n /** Initial skill selection (`id` from skills list). */\n defaultSkillId?: string;\n /** Project branding: panel title and assistant logo. */\n project?: AgentChatProjectConfig;\n /**\n * Replace the default floating bubble. Pass a render function for full control\n * (position, drag, open), or a React node mounted in a fixed-position slot\n * (use `useAgentChat().open()` inside your element).\n */\n launcher?: ReactNode | ((props: AgentChatLauncherProps) => ReactNode);\n}\n\nexport interface AgentMessageContentText {\n type: 'text';\n text: string;\n}\n\nexport type AgentMessageContent = AgentMessageContentText;\nexport type AgentMessageBlocks = Array<Record<string, unknown> & { type: string; id?: string }>;\n\nexport type AgentMessageRole = 'user' | 'agent' | 'system';\n\nexport type AgentMessageStatus = 'pending' | 'sent' | 'failed';\n\n/** Live assistant turn fed by SSE (`think` / `result` / `complete` / `error`). */\nexport interface AgentStreamState {\n phase: 'thinking' | 'result' | 'complete' | 'error';\n /** Accumulated thinking text from SSE `think` events (single block, appended in order). */\n thinkText: string;\n resultText: string;\n resultBlocks?: AgentMessageBlocks;\n runId?: number;\n seenSeq?: number[];\n errorMessage?: string;\n}\n\nexport type MessageFeedbackRating = 'up' | 'down';\n\nexport interface MessageFeedbackDownReasonTag {\n key: string;\n label: string;\n}\n\nexport interface MessageFeedbackView {\n messageId: number;\n rating: MessageFeedbackRating;\n reasonTags: string[];\n comment: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type UpsertMessageFeedbackBody =\n | { rating: 'up' }\n | {\n rating: 'down';\n reasonTags?: string[];\n comment?: string;\n };\n\nexport type MessageFeedbackBatchData = {\n items: MessageFeedbackView[];\n};\n\n/** User-selected page-context item attached to a single outgoing message. */\nexport interface ContextMentionAttachment {\n id: string;\n label: string;\n /** Metadata key used when merging into `pageContext.metadata` for this send. */\n kind: string;\n payload: Record<string, unknown>;\n}\n\nexport type ContextMentionGroup = 'page' | 'route' | 'metadata' | 'host';\n\n/** Host-registered @ mention catalog entry (see {@link AgentChatInstance.registerContextMentions}). */\nexport interface ContextMentionRegistration {\n id: string;\n label: string;\n /** Metadata merge key; defaults to registry id without `host:` prefix. */\n kind?: string;\n group?: ContextMentionGroup;\n description?: string;\n /** Static payload preview; merged with {@link resolve} result at send time. */\n payload?: Record<string, unknown>;\n /** Lazy payload resolver — return a string or record; SDK maps to inline `content`. */\n resolve?: () => string | Record<string, unknown> | Promise<string | Record<string, unknown>>;\n}\n\n/** Minimal host input — use {@link defineContextMention} or {@link useContextMentions}. */\nexport interface ContextMentionDefinition {\n /** Optional stable key; otherwise derived from {@link label}. */\n key?: string;\n label: string;\n group?: ContextMentionGroup;\n description?: string;\n value?: string | Record<string, unknown>;\n resolve?: () => string | Record<string, unknown> | Promise<string | Record<string, unknown>>;\n}\n\n/** Read-only registration snapshot exposed on {@link AgentChatState}. */\nexport interface RegisteredContextMention {\n id: string;\n label: string;\n kind: string;\n group?: ContextMentionGroup;\n description?: string;\n payload?: Record<string, unknown>;\n lazy?: boolean;\n}\n\nexport interface RegisterContextMentionsOptions {\n /** Replace the entire registry instead of merging by `id`. */\n replace?: boolean;\n}\n\nexport interface AgentMessage {\n id: string;\n role: AgentMessageRole;\n content: AgentMessageContent;\n /** Unix timestamp in milliseconds when the message was created. */\n createdAt: number;\n /** Local UI delivery state. Server-originated messages are always `sent`. */\n status?: AgentMessageStatus;\n /** Page-context @ mentions selected for this user message. */\n contextMentions?: ContextMentionAttachment[];\n /** Persisted thinking text from SSE `think` events (shown alongside result). */\n thinkText?: string;\n /** Populated while assistant reply streams over SSE. */\n stream?: AgentStreamState;\n /** Structured blocks for assistant content (table/chart/loading etc). */\n blocks?: AgentMessageBlocks;\n /** Current user's like/dislike on this assistant message. */\n feedback?: MessageFeedbackView | null;\n}\n\nexport interface SessionInfo {\n sessionId: string;\n conversationId: string;\n}\n\n/** Summary row for the session sidebar (`GET /chat`). */\nexport interface ChatSessionSummary {\n sessionId: string;\n title?: string;\n updatedAt?: number;\n preview?: string;\n}\n\n/** Agent option for the composer toolbar (`GET /agent/client/available`). */\nexport interface ChatAgentSummary {\n id: string;\n name: string;\n description?: string | null;\n}\n\nexport type AutoAgentSource = 'requested' | 'session' | 'auto' | 'default' | 'fallback';\n\nexport interface AutoAgentBinding {\n id: string;\n source?: AutoAgentSource;\n reason?: string | null;\n}\n\nexport type ToolLevel = 'L1' | 'L2' | 'L3';\n\n/** Skill option for the composer toolbar (`GET /agent/:agentId/skills/client`). */\nexport interface ChatSkillSummary {\n id: string;\n name: string;\n description?: string | null;\n agentId?: string;\n capabilityKey?: string | null;\n riskLevel?: ToolLevel;\n requiresWriteConfirmation?: boolean;\n toolIds?: number[];\n hostToolIds?: number[];\n /** Present only when `GET .../skills/client` was called with `?page=`. */\n pageMatched?: boolean;\n}\n\n/** Why the available-agent list is empty (client-side heuristic). */\nexport type AgentsEmptyReason = 'permission' | 'not_configured' | null;\n\n/** `GET /agent/client/available` query */\nexport interface QueryClientAvailableAgents {\n id?: number;\n definitionKey?: string;\n integrationId?: number;\n toolCategoryId?: number;\n toolCategoryIdIsNull?: boolean;\n name?: string;\n description?: string;\n path?: string;\n keyword?: string;\n riskLevel?: ToolLevel;\n method?: string;\n isActive?: boolean;\n}\n\n/** `GET /agent/:agentId/skills/client` query */\nexport interface QueryClientSkillByAgent {\n /** Page scope (kebab-case), same as `pageContext.page` / `HostPage.scope`. */\n page?: string;\n name?: string;\n capabilityKey?: string;\n keyword?: string;\n}\n\nexport interface AgentChatSessionsPayload {\n sessions: ChatSessionSummary[];\n}\n\nexport interface AgentChatErrorPayload {\n code: string;\n message: string;\n cause?: unknown;\n}\n\n/** Draft review decision submitted via `POST /chat/:sessionId/messages` `writeGate`. */\nexport type DraftReviewAction = 'confirm' | 'confirm_with_edits' | 'retry' | 'cancel';\n\nexport interface WriteGate {\n action: DraftReviewAction;\n /** Edited MessageBlocks JSON (`{ blocks: [...] }`). */\n editedPreviewSerialized?: string;\n /** Shallow merge into pending write tool arguments. */\n editedPendingWriteArguments?: Record<string, unknown>;\n /** Required when `action` is `retry`. */\n retryInstruction?: string;\n}\n\n/** Pending write-operation confirmation from SSE `confirmation_required`. */\nexport interface WriteConfirmationState {\n awaiting: boolean;\n submitting: boolean;\n runId: number;\n turnId?: number;\n message: string;\n /** Assistant bubble that triggered the confirmation. */\n messageId?: string;\n /** Session run generation — filters superseded SSE / gate UI. */\n generation?: number;\n draftRetryCount?: number;\n draftRetryMax?: number;\n canRetry?: boolean;\n /** Write draft from SSE — bind edits to `arguments`, not preview blocks. */\n writeDraft?: WriteDraftPublic | null;\n /** Additional pending write drafts when multiple tools await confirmation. */\n writeDrafts?: WriteDraftPublic[] | null;\n /** Server-derived edit rules for the write gate UI. */\n editPolicy?: EditPolicyPublic | null;\n /** Paired with `writeDrafts` by index. */\n editPolicies?: Array<EditPolicyPublic | null> | null;\n /** Gate-level validation error (gate stays open). */\n gateError?: string;\n gateErrorCode?: string;\n}\n\n/** Skill × user-intent alignment status from `route_plan` step output. */\nexport type SkillIntentAlignmentStatus =\n | 'none'\n | 'aligned'\n | 'intent_first'\n | 'clarified';\n\nexport type SkillIntentMismatchCode =\n | 'read_intent_vs_http_skill'\n | 'read_intent_vs_host_only_skill'\n | 'write_intent_vs_http_only_skill'\n | 'write_intent_vs_no_host_skill'\n | 'direct_answer_vs_any_skill'\n | 'orchestrated_http_vs_host_only_skill';\n\nexport type TurnSkillSelect = 'llm' | 'explicit' | 'page_host';\n\nexport type TurnScopedToolsSource = 'intent' | 'explicit_skill';\n\nexport type PageContextPlanKind = 'none' | 'inline_answer' | 'entity_read_detail';\n\nexport interface SkillIntentAlignmentSnapshot {\n status: SkillIntentAlignmentStatus;\n code?: SkillIntentMismatchCode;\n requestedSkillId?: number;\n droppedExplicitSkill?: boolean;\n}\n\n/** Parsed `route_plan` turn contract view (skill-intent-alignment + scoped tools). */\nexport interface SkillTurnContractView {\n skillAlignment: SkillIntentAlignmentSnapshot;\n skillSelect: TurnSkillSelect;\n scopedToolsSource: TurnScopedToolsSource;\n pageContextPlan: PageContextPlanKind;\n hostMutationIntent: boolean;\n requestedSkillId: number | null;\n}\n\n/** Shown when the server actually executed the pre-selected skill this turn. */\nexport interface SkillTurnActiveState {\n requestedSkillId?: number;\n requestedSkillName?: string;\n}\n\n/** Non-blocking hint when the server ignored the selected skill (`intent_first`). */\nexport interface SkillIntentBannerState {\n code?: SkillIntentMismatchCode;\n requestedSkillId?: number;\n requestedSkillName?: string;\n}\n\n/** Clarification card when write intent conflicts with the selected skill. */\nexport interface SkillIntentClarifyState {\n code: SkillIntentMismatchCode;\n requestedSkillId?: number;\n requestedSkillName?: string;\n /** User message from the conflicting turn — for resend without skill. */\n userMessage: string;\n /** Assistant bubble to attach the clarify card. */\n messageId?: string;\n runId?: number;\n}\n\n/** Brain entity disambiguation footer under an assistant bubble. */\nexport interface BrainClarifyUiState {\n messageId: string;\n runId: number;\n brainClarify: BrainClarifyPayload;\n}\n\nexport interface AgentChatMessagePayload {\n message: AgentMessage;\n source: AgentMessageRole;\n}\n\n/** Emitted when an assistant SSE turn completes while the panel is closed. */\nexport interface AgentChatBackgroundReplyPayload {\n sessionId: string;\n sessionTitle: string | null;\n}\n\nexport interface AgentChatEventMap extends Record<string, unknown> {\n ready: void;\n error: AgentChatErrorPayload;\n open: void;\n close: void;\n destroyed: void;\n session: SessionInfo;\n sessions: AgentChatSessionsPayload;\n message: AgentChatMessagePayload;\n hostAction: AgentChatHostActionPayload;\n /** Host-tool DSL lifecycle (`onStart` / `onStream` / `onComplete` / `onError`). */\n pageAgentLifecycle: PageAgentLifecyclePayload;\n /** Page Bot workflow paused for inbox approval. */\n pageAgentAwaitingApproval: PageAgentAwaitingApprovalPayload;\n /** Show built-in approval notice (panel mounted). */\n pageActionAwaitingApproval: PageActionAwaitingApprovalNoticePayload;\n /** Soft tip for already-active invoke (local row or HTTP 409) — never a host failure. */\n pageActionSoftNotice: PageActionSoftNoticePayload;\n backgroundReplyReady: AgentChatBackgroundReplyPayload;\n /** Emitted when inbox should refresh (PageAction awaiting approval / inbox confirm-reject). */\n approvalInboxChanged: void;\n /** Inbox approve/decide finished — surface PageAction execution status to the user. */\n approvalExecutionCompleted: ApprovalExecutionCompletedPayload;\n /** Open the panel and approval inbox drawer (launcher badge). */\n openApprovalInbox: OpenApprovalInboxPayload | undefined;\n /** Emitted when task center should refresh (PageAction invoke / run status change). */\n automationTaskCenterChanged: void;\n /** Open the panel and automation task center drawer (optional run deep-link). */\n openAutomationTaskCenter: OpenAutomationTaskCenterPayload | undefined;\n /** Open「我的反馈」drawer (rating + wish tabs). */\n openPageActionFeedback: OpenPageActionFeedbackPayload | undefined;\n /** PageAction invoke accepted — host may show a toast / launch animation. */\n pageActionSubmitted: PageActionSubmittedPayload;\n /** Per-row PageAction slot updated (list pages). */\n pageActionRowChanged: PageActionRowChangedPayload;\n /** Running PageAction SSE re-attached (refresh reconnect). */\n pageActionStreamResumed: PageActionStreamResumedPayload;\n /** Live run finished successfully. */\n pageActionRunCompleted: PageActionRunLifecyclePayload;\n /** Live run failed. */\n pageActionRunFailed: PageActionRunLifecyclePayload;\n /** Brain ASK_USER — show entity clarify popover (not a failure toast). */\n pageActionBrainClarify: PageActionBrainClarifyPromptRequest;\n /** Replay「应用到页面」started. */\n pageActionApplyStarted: PageActionRunLifecyclePayload;\n /** Replay「应用到页面」finished. */\n pageActionApplyCompleted: PageActionRunLifecyclePayload;\n /** Slot apply phase from {@link PageActionCoordinator}. */\n pageActionSlotApplyPhaseChanged: PageActionSlotApplyPhasePayload;\n /** 「应用到页面」pending intent changed (set / clear / consume). */\n pendingPageActionApplyChanged: PendingPageActionApply | null;\n}\n\nexport type AgentChatLifecycle =\n | 'uninitialized'\n | 'initialized'\n | 'destroyed';\n\nexport interface AgentChatState {\n lifecycle: AgentChatLifecycle;\n /** Current app DSN from init(); null before init completes. */\n dsn: string | null;\n isOpen: boolean;\n /** True after `POST /app-client/auth` succeeds during `init()`. Gates the launcher. */\n isClientAuthenticated: boolean;\n isLoggedIn: boolean;\n /** Sessions/agents catalog loaded at least once for the current login. */\n catalogHydrated: boolean;\n /** Normalized session ids with an open SSE connection. */\n streamingSessionIds: string[];\n /** Session ids that still have a pending assistant bubble in cache or active view. */\n pendingReplySessionIds: string[];\n session: SessionInfo | null;\n /** All chat sessions for the sidebar. */\n sessions: ChatSessionSummary[];\n /** Whether more sessions can be loaded (`GET /chat?page=&size=`). */\n sessionsHasMore: boolean;\n /** True while loading the next sessions page. */\n sessionsLoadingMore: boolean;\n /** Currently selected session; drives `messages`. */\n activeSessionId: string | null;\n messages: AgentMessage[];\n /** Whether older messages can be loaded for the active session. */\n sessionMessagesHasMore: boolean;\n /** True while loading older messages for the active session. */\n sessionMessagesLoadingMore: boolean;\n /** Available agents for the composer toolbar. */\n agents: ChatAgentSummary[];\n /** Skills for the currently selected agent. */\n skills: ChatSkillSummary[];\n selectedAgentId: string | null;\n /** Last server-side agent binding result. `source=\"auto\"` means Auto-Agent selected it. */\n autoAgent: AutoAgentBinding | null;\n selectedSkillId: string | null;\n agentsLoading: boolean;\n skillsLoading: boolean;\n /** Set when `client/available` is empty; uses `client/list` to distinguish permission vs config. */\n agentsEmptyReason: AgentsEmptyReason;\n lastError: AgentChatErrorPayload | null;\n /** Set when SSE requests user confirmation before executing write tools. */\n writeConfirmation: WriteConfirmationState | null;\n /** Pending automation approvals (`GET /approval/inbox`) — page_action / webhook only. */\n approvalInbox: ApprovalInboxState;\n /** PageAction automation history (`GET /automation/tasks`). */\n automationTaskCenter: AutomationTaskCenterState;\n /** Soft banner after `intent_first` alignment (selected skill not used). */\n skillIntentBanner: SkillIntentBannerState | null;\n /** Clarify card after `clarified` alignment (write intent vs skill). */\n skillIntentClarify: SkillIntentClarifyState | null;\n /** Brain entity disambiguation under the latest assistant bubble. */\n brainClarify: BrainClarifyUiState | null;\n /** Last `route_plan` turn contract (developer / diagnostics). */\n skillTurnContract: SkillTurnContractView | null;\n /** Shown when the server actually used the pre-selected skill this turn. */\n skillTurnActive: SkillTurnActiveState | null;\n /** When true, skill dropdown should open (e.g. from clarify card). */\n skillPickerOpen: boolean;\n /** Route path + params — always sent with user messages. */\n routeContext: AgentChatRouteContext | null;\n /** Extended host page context from `setPageContext` (manual). */\n pageContext: AgentChatPageContext | null;\n /** Host-registered @ mention catalog entries (without `resolve`). */\n registeredContextMentions: RegisteredContextMention[];\n /** UI preference for explicitly showing/attaching page context in the panel. */\n attachPageContext: boolean;\n /** Active session run coordinator snapshot (`GET .../run-state`); UI hints only. */\n activeSessionRun: SessionRunSnapshot | null;\n /** init / login 门禁当前挂起中的 API 调用 */\n pendingGateJobs: PendingGateJob[];\n}\n\nexport type { PendingGateJob, PendingGateJobKind } from './core/auth/login-gate';\n\n/** Subset of `GET /chat/:sessionId/run-state` exposed on {@link AgentChatState}. */\nexport interface SessionRunSnapshot {\n generation: number;\n activeRunId: number | null;\n pendingJobCount: number;\n redisBacked: boolean;\n}\n\nexport interface AgentChatLoginCredentials {\n email: string;\n password: string;\n}\n\n/**\n * Public surface of an omnix-chat instance. UI is rendered via React\n * (`<AgentChat />` from `omnix-chat/react`); this client is headless.\n */\nexport interface AgentChatInstance {\n init(options: AgentChatOptions): Promise<AgentChatInstance>;\n login(credentials: AgentChatLoginCredentials): Promise<void>;\n logout(): void;\n isLoggedIn(): boolean;\n /** init / login 门禁挂起任务快照 */\n getPendingGateJobs(): PendingGateJob[];\n destroy(): void;\n open(): void;\n close(): void;\n toggle(): void;\n isOpen(): boolean;\n /** Open the chat panel and the approval inbox drawer. */\n openApprovalInbox(opts?: OpenApprovalInboxPayload): void;\n /** Open the chat panel and the automation task center drawer. */\n openAutomationTaskCenter(opts?: OpenAutomationTaskCenterPayload): void;\n /** Open「我的反馈」drawer (场景评价 + 需求收集). */\n openPageActionFeedback(opts?: OpenPageActionFeedbackPayload): void;\n /**\n * `GET /page-action/catalog` — enabled PageActions for this App.\n * Global feedback center should omit `pageScope`.\n */\n fetchPageActionFeedbackCatalog(\n query?: PageActionFeedbackCatalogQuery,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackCatalogItem[]>;\n /** Last fetched catalog (empty until {@link fetchPageActionFeedbackCatalog}). */\n listPageActionFeedbackCatalog(): PageActionFeedbackCatalogItem[];\n /**\n * `POST /page-action/rollout-check` — for hardcoded actionKey buttons (not catalog).\n * Hide the trigger when `allowed === false`.\n */\n checkPageActionRollout(\n actionKeys: string[],\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionRolloutCheckItem[]>;\n /**\n * @deprecated Rating list comes from {@link fetchPageActionFeedbackCatalog}.\n * Kept as a no-op name overlay for optimistic task-center titles.\n */\n registerPageActionFeedbackCatalog(\n items: Array<{ actionKey: string; name?: string | null }>,\n ): void;\n getPageActionFeedback(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackView | null>;\n upsertPageActionFeedback(\n actionKey: string,\n body: UpsertPageActionFeedbackInput,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackView>;\n removePageActionFeedback(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<void>;\n getPageActionFeedbackSummary(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackSummary>;\n createPageActionWish(\n body: CreatePageActionWishInput,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView>;\n listPageActionWishes(\n query?: PageActionWishQuery,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishList>;\n getPageActionWish(\n id: number,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView>;\n cancelPageActionWish(\n id: number,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView>;\n identify(user: UserContext): void;\n /** Merge `pageContext` / `attachPageContext` from props without full re-init. */\n applyRuntimeOptions(\n options: Pick<AgentChatOptions, 'attachPageContext' | 'pageContext'>,\n ): void;\n /** Update extended host page context (entity, metadata, …) without re-init. */\n setPageContext(pageContext: AgentChatPageContext | null): void;\n /** Override auto-detected route path / params (e.g. from React Router). */\n setRouteContext(routeContext: AgentChatRouteContext | null): void;\n /** Register host-defined @ mention catalog entries for the composer. */\n registerContextMentions(\n items: Array<ContextMentionRegistration | ContextMentionDefinition>,\n options?: RegisterContextMentionsOptions,\n ): void;\n /** Remove host @ mention entries by id. */\n unregisterContextMentions(ids: string[]): void;\n /** Clear all host @ mention registrations. */\n clearContextMentions(): void;\n /** Re-read `window.location` and merge with any route override. */\n syncRouteContextFromWindow(): void;\n /** Toggle whether extended page context is sent with messages. */\n setAttachPageContext(attach: boolean): void;\n /** Current extended page context from `setPageContext` / props. */\n getPageContext(): AgentChatPageContext | null;\n /** App client id from init auth — used for host-tool server sync dedupe. */\n getAppClientId(): number | null;\n /** True when Bearer token + app client are ready for `POST /host-tool/client/register`. */\n isHostToolServerSyncReady(): boolean;\n /** Register a local host-tool handler (`*` scope for app-wide generic tools). */\n registerHostTool(scope: string, name: string, handler: HostToolHandler): void;\n unregisterHostTool(scope: string, name: string): void;\n undeclareHostTool(scope: string, name: string): void;\n /** Execute a registered host tool; returns false when not found. */\n runHostTool(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n ): Promise<boolean>;\n /** Local register + optional `POST /host-tool/client/register` sync. */\n registerHostToolsWithSync(options: RegisterHostToolsOptions): Promise<void>;\n /** Fetch server host-tool catalog for validation. */\n getHostToolCatalog(query?: { scope?: string; agentId?: number }): Promise<unknown>;\n selectSession(sessionId: string): Promise<void>;\n /** Delete a session via `DELETE /chat/{sessionId}`. */\n deleteSession(sessionId: string): Promise<void>;\n /**\n * Warm session runtime + host-tool cache via `POST /chat/{sessionId}/prepare`.\n * Sends current {@link AgentChatPageContext} (including `page`) when the host\n * has set page context — required for `hostToolsCount > 0` on the server.\n */\n prepareSession(\n sessionId: string,\n options?: AbortSignal | PrepareSessionOptions,\n ): Promise<PrepareSessionResult | null>;\n /** Fetch session list from `GET /chat` and refresh the sidebar. */\n refreshSessions(signal?: AbortSignal): Promise<void>;\n /** Load the next page of sessions when the sidebar is scrolled to the bottom. */\n loadMoreSessions(signal?: AbortSignal): Promise<void>;\n /** Load older messages when the message list is scrolled to the top. */\n loadMoreSessionMessages(signal?: AbortSignal): Promise<void>;\n /** Switch the active agent (reloads skills for that agent). */\n selectAgent(agentId: string): Promise<void>;\n /** Switch the active skill. */\n selectSkill(skillId: string): void;\n /** Dismiss the intent-first soft banner. */\n dismissSkillIntentBanner(): void;\n /** Clear skill selection from the intent-first banner. */\n clearSkillFromIntentBanner(): void;\n /** Dismiss the skill mismatch clarify card (keep selected skill). */\n dismissSkillIntentClarify(): void;\n /** Clear skill and resend the clarify turn user message. */\n followSkillIntentClarify(): Promise<void>;\n /** Dismiss the Brain entity clarify footer. */\n dismissBrainClarify(): void;\n /** Commit a Brain clarify candidate and continue the chat turn. */\n commitBrainClarify(selectedId: string): Promise<void>;\n /** Open the skill picker (clarify flow). */\n openSkillPicker(): void;\n /** Close the skill picker overlay. */\n closeSkillPicker(): void;\n sendMessage(\n text: string,\n opts?: {\n id?: string;\n contextMentions?: ContextMentionAttachment[];\n entityCommit?: EntityCommit;\n },\n ): Promise<AgentMessage>;\n /** Confirm a pending chat write gate (session SSE bubble — not the approval inbox). */\n confirmWrite(): Promise<void>;\n /** Submit edited draft preview / write arguments (`writeGate.action: confirm_with_edits`). */\n confirmWriteWithEdits(input: {\n editedPreviewSerialized?: string;\n editedPendingWriteArguments?: Record<string, unknown>;\n }): Promise<void>;\n /** Regenerate draft with user instruction (`writeGate.action: retry`). */\n retryWrite(retryInstruction: string): Promise<void>;\n /** Cancel a pending chat write gate (session SSE bubble — not the approval inbox). */\n cancelWrite(): Promise<void>;\n /** Refresh page_action / webhook pending approvals (`GET /approval/inbox`). */\n refreshApprovalInbox(opts?: {\n signal?: AbortSignal;\n status?: ApprovalInboxStatusFilter;\n limit?: number;\n offset?: number;\n append?: boolean;\n }): Promise<ApprovalInboxList>;\n setApprovalInboxStatusFilter(status: ApprovalInboxStatusFilter): void;\n refreshApprovalPendingCount(signal?: AbortSignal): Promise<void>;\n /** `GET /approval/:id` */\n getApproval(id: number, signal?: AbortSignal): Promise<ApprovalDetail | null>;\n /** Refresh a single inbox row from `GET /approval/:id` (after retry `suspended: true`). */\n hydrateApprovalInboxItem(id: number, signal?: AbortSignal): Promise<ApprovalDetail | null>;\n /** `POST /approval/:id/confirm` */\n confirmApproval(id: number, signal?: AbortSignal): Promise<ApprovalConfirmResult>;\n /** `POST /approval/:id/decide` — page_action draft review (confirm / edit / retry / cancel). */\n decideApproval(\n id: number,\n decision: DraftReviewDecision,\n opts?: { reason?: string; signal?: AbortSignal },\n ): Promise<ApprovalDecideResult>;\n /** `POST /approval/:id/reject` */\n rejectApproval(id: number, reason?: string, signal?: AbortSignal): Promise<ApprovalRejectResult>;\n /** Refresh automation tasks (`GET /automation/tasks`). */\n refreshAutomationTasks(opts?: {\n signal?: AbortSignal;\n status?: AutomationTaskStatusFilter;\n actionKey?: string;\n limit?: number;\n offset?: number;\n append?: boolean;\n }): Promise<AutomationTaskList>;\n setAutomationTaskStatusFilter(status: AutomationTaskStatusFilter): void;\n /**\n * Activate a task-center tab: restore cached list, or fetch page 1 when never loaded.\n * Pass `{ refresh: true }` to force-refresh page 1 (manual refresh button).\n */\n ensureAutomationTaskTabLoaded(\n status?: AutomationTaskStatusFilter,\n opts?: { refresh?: boolean; signal?: AbortSignal },\n ): Promise<void>;\n /** Append the next page for the current task-center tab (no-op while loading or no more). */\n loadAutomationTaskNextPage(opts?: { signal?: AbortSignal }): Promise<void>;\n /** Active PageAction runs — derived from in-memory run registry (no polling). */\n refreshAutomationActiveCount(signal?: AbortSignal): Promise<void>;\n /** Reconcile active tasks after tab becomes visible (event-driven, not interval). */\n reconcileAutomationTasksIfNeeded(): void;\n /** `GET /automation/tasks/page_action_run/:id` */\n getAutomationTaskDetail(\n runId: number,\n signal?: AbortSignal,\n ): Promise<AutomationTaskDetail | null>;\n /** Hydrate selected detail row in task center state. */\n hydrateAutomationTaskDetail(runId: number, signal?: AbortSignal): Promise<AutomationTaskDetail | null>;\n /** Clear task center detail view (back to list). */\n clearAutomationTaskDetail(): void;\n /**\n * 任务中心「应用到页面」:只导航 + 写入 pendingApply,不直接 replay。\n * 目标页 `usePageAction({ ready })` 就绪后自动 `replayPageAction`。\n * @see AgentChatOptions.onNavigateForPageAction\n */\n applyPageActionToPage(\n runId: number,\n opts?: { signal?: AbortSignal },\n ): Promise<import('./core/page/page-context-navigate').ApplyPageActionToPageResult>;\n /**\n * 重放已完成 PageAction 的 stream 产出。\n * 通常由 `usePageAction` 在 pending + ready 时调用;也可手动调用。\n */\n replayPageAction(runId: number, opts?: { signal?: AbortSignal }): Promise<void>;\n /** Current「应用到页面」pending intent (memory + sessionStorage). */\n getPendingPageActionApply(): PendingPageActionApply | null;\n /** Clear pending apply intent. */\n clearPendingPageActionApply(): void;\n /**\n * Attach (or no-op if already attached) to a running PageAction SSE stream.\n * Used after refresh to resume host_action / prose delivery.\n */\n attachPageActionStream(\n runId: number,\n opts?: { signal?: AbortSignal; rowKey?: string },\n ): Promise<boolean>;\n /**\n * After reconcile: attach streams for active `running` tasks matching `actionKey`.\n * @returns number of streams attached this call\n */\n resumeActivePageActionStreams(opts?: {\n actionKey?: string;\n signal?: AbortSignal;\n }): Promise<number>;\n /** Register a run id after invoke (list highlight / badge bump). */\n registerAutomationRun(\n runId: number,\n meta?: {\n actionKey?: string;\n accepted?: InvokePageActionAccepted;\n pageActionKey?: string | null;\n rowKey?: string | null;\n },\n ): void;\n /** Whether the server `pageActionKey` still has an active run in the local registry. */\n isPageActionKeyActive(pageActionKey: string | null | undefined): boolean;\n /**\n * Active `pageActionKey` for an `actionKey`, if any (from registry / task list sync).\n * List pages with multiple rows may have several — prefer {@link getPageActionRowState}.\n */\n getActivePageActionKeyForActionKey(actionKey: string): string | null;\n /** Read per-row PageAction UI state (list pages). */\n getPageActionRowState(rowKey: string): PageActionRowState | null;\n /** All known row slots for an `actionKey`. */\n getPageActionRowsForActionKey(actionKey: string): PageActionRowState[];\n /** Whether a list row currently has an active / pending PageAction. */\n isPageActionRowActive(rowKey: string): boolean;\n /** Clear error text on a row slot. */\n clearPageActionRowError(rowKey: string): void;\n /** Hydrate one row slot from `GET /automation/tasks/page_action_run/:runId`. */\n hydratePageActionByRunId(\n runId: number,\n opts?: { rowKey?: string; actionKey?: string; signal?: AbortSignal },\n ): Promise<PageActionRowState | null>;\n /**\n * Pull active tasks and refresh row slots for an `actionKey`\n * (`GET /automation/tasks?status=active&actionKey=`).\n */\n reconcileActivePageActions(opts?: {\n actionKey?: string;\n signal?: AbortSignal;\n }): Promise<PageActionRowState[]>;\n /**\n * Register a PageAction UI slot for restore (refresh / login / apply).\n * Returns unbind. Prefer hooks — hosts rarely call directly.\n */\n bindPageActionSlot(binding: {\n actionKey: string;\n rowKey: string;\n pageContext?: AgentChatPageContext | null;\n ready?: boolean;\n autoResume?: boolean;\n autoApplyPending?: boolean;\n }): () => void;\n /** Update a bound slot (e.g. `ready` flipped). */\n patchPageActionSlot(\n slotKey: string,\n patch: {\n pageContext?: AgentChatPageContext | null;\n ready?: boolean;\n autoResume?: boolean;\n autoApplyPending?: boolean;\n },\n ): void;\n /** @internal Demo / integration — slots registered via bindPageActionSlot */\n listBoundPageActionSlots(): Array<{\n actionKey: string;\n rowKey: string;\n pageContext?: AgentChatPageContext | null;\n ready: boolean;\n autoResume: boolean;\n autoApplyPending: boolean;\n }>;\n prefetch(): Promise<void>;\n /** Clear active session; next message starts a new chat. */\n startNewChat(): Promise<void>;\n /** Abort the current assistant SSE reply via `POST .../cancel-run`. */\n cancelGeneration(): Promise<void>;\n /**\n * Invoke a Page Bot action (no chat `sessionId`).\n * `POST /page-action/brain-invoke` returns JSON; SSE is on `GET .../runs/:id/stream`.\n * When the chat UI is mounted, may first show a reuse popover for prior successful runs.\n */\n invokePageAction(input: PageBotInvokeInput): Promise<PageBotStreamResult>;\n /** `POST /page-action/reuse-hint` — soft check for reusable successful runs. */\n reusePageActionHint(\n input: Pick<\n PageBotInvokeInput,\n 'actionKey' | 'pageContext' | 'instruction' | 'context' | 'signal'\n > & { refresh?: boolean },\n ): Promise<PageActionReuseHint>;\n /**\n * Register the built-in reuse popover (ChatRoot). Without a handler, invoke skips reuse.\n */\n setPageActionReusePromptHandler(\n handler: PageActionReusePromptHandler | null,\n ): () => void;\n /** Close Brain clarify UI and unlock the row (user dismissed without picking). */\n dismissPageActionBrainClarify(input?: {\n rowKey?: string | null;\n runId?: number | null;\n }): void;\n /**\n * Unlock the trigger after docked reuse「撤销」/ before「继续执行」.\n * Aborts in-flight historical replay so late SSE cannot soft-lock the button.\n */\n dismissPageActionReuse(input?: {\n rowKey?: string | null;\n runId?: number | null;\n }): void;\n /** Cached down-reason tags for the feedback modal (fetched on first use). */\n getDownReasonTags(): Promise<MessageFeedbackDownReasonTag[]>;\n /** Like or dislike an assistant message (`PUT .../feedback`). */\n submitMessageFeedback(\n messageId: string,\n body: UpsertMessageFeedbackBody,\n ): Promise<void>;\n /** Cancel like/dislike on a message (`DELETE .../feedback`). */\n removeMessageFeedback(messageId: string): Promise<void>;\n getState(): AgentChatState;\n on<K extends keyof AgentChatEventMap>(\n event: K,\n handler: (payload: AgentChatEventMap[K]) => void,\n ): () => void;\n off<K extends keyof AgentChatEventMap>(\n event: K,\n handler: (payload: AgentChatEventMap[K]) => void,\n ): void;\n}\n\nexport type { AgentChatError };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,SAAS,WAAS,GAAkD;CAClE,OAAO,OAAO,KAAU,cAAY,KAAkB,CAAC,MAAM,QAAQ,CAAK;AAC5E;;AAEA,SAAgB,kBAAkB,GAAoE;CACpG,IAAI,CAAC,GAAS;CACd,IAAM,IAAU,EAAQ,KAAK;CACzB,OAAC,KAAW,EAAQ,OAAO,MAC/B,IAAI;EACF,IAAM,IAAS,KAAK,MAAM,CAAO;EAEjC,OADK,MAAM,QAAQ,EAAO,MAAM,IACzB,EAAO,OAAO,QAClB,MAAmC,WAAS,CAAI,KAAK,OAAO,EAAK,QAAS,QAC7E,IAHmC;CAIrC,SAAA,GAAQ;EACN;CACF;AACF;AAEA,SAAgB,aAAa,GAAgD;CAE3E,OADI,KAAA,QAAC,EAAQ,SACN,EACJ,KAAK,MAAW,EAAM,SAAS,UAAU,OAAO,EAAM,WAAY,WAAW,EAAM,UAAU,EAAG,CAAC,CACjG,KAAK,EAAE,IAHkB;AAI9B;AAGA,SAAgB,iCAAiC,GAAoC;CACnF,OAAO,KAAK,UAAU,EAAE,UAAO,CAAC;AAClC;AAGA,SAAgB,2BACd,GACA,GACQ;CACR,IAAA,KAAA,QAAI,EAAc,QAAQ;EACxB,IAAI,IAAe,IACb,IAAO,EAAa,KAAK,MACzB,EAAM,SAAS,UACjB,IAAe,IACR;GAAE,GAAG;GAAO,SAAS;EAAW,KAElC,CACR;EAID,OAHK,KACH,EAAK,QAAQ;GAAE,MAAM;GAAQ,QAAQ;GAAY,SAAS;EAAW,CAAC,GAEjE,iCAAiC,CAAI;CAC9C;CACA,OAAO,iCAAiC,CACtC;EAAE,MAAM;EAAQ,QAAQ;EAAY,SAAS;CAAW,CAC1D,CAAC;AACH;AAEA,SAAS,gBAAgB,GAA8B,GAAkD;CACvG,IAAI,IAAY;CAChB,KAAK,IAAM,KAAS,GAClB,AAAI,EAAM,SAAS,UAAU,OAAO,EAAM,WAAY,aACpD,KAAa,EAAM;CAGvB,IAAI,CAAC,GAAW,OAAO;CACvB,IAAM,IAAO,CAAC,GAAG,CAAQ,GACnB,IAAO,EAAK,EAAK,SAAS;CAMhC,QALA,KAAA,OAAA,KAAA,IAAI,EAAM,UAAS,UAAU,OAAO,EAAK,WAAY,YACnD,EAAK,EAAK,SAAS,KAAK;EAAE,GAAG;EAAM,SAAS,GAAG,EAAK,UAAU;CAAY,GACnE,MAET,EAAK,KAAK;EAAE,MAAM;EAAQ,QAAQ;EAAY,SAAS;CAAU,CAAC,GAC3D;AACT;AAEA,IAAM,oBAAyB,IAAI,IAAI;CACrC;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,0BAA0B,GAAgD;CACjF,OAAO,EAAO,QAAQ,MAChB,EAAM,SAAS,UAAU,OAAO,EAAM,WAAY,YAIlD,CADY,EAAM,QAAQ,UACzB,CAAA,CAAQ,WAAW,GAAG,KAGpB,CAAC,kBAAkB,EAAM,OAAO,CACxC;AACH;AAEA,SAAS,uBAAuB,GAAuB;CACrD,IAAM,IAAQ,EAAK,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,MAAS,EAAK,KAAK,CAAC,CAAC,SAAS,CAAC;CAE7E,OADI,EAAM,SAAS,IAAU,KACtB,EAAM,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,MAAS,EAAK,SAAS,GAAG,CAAC;AAC5D;AAEA,SAAS,+BACP,GACA,GACoB;CACpB,IAAM,IAAK,OAAO,EAAM,MAAO,WAAW,EAAM,GAAG,KAAK,IAAI;CAC5D,IAAI,GAAI;EACN,IAAM,IAAM,EAAK,WAAW,MAAS,EAAK,OAAO,CAAE;EACnD,IAAI,KAAO,GAAG;GACZ,IAAM,IAAO,CAAC,GAAG,CAAI;GAErB,OADA,EAAK,KAAO;IAAE,GAAG;IAAO;GAAG,GACpB;EACT;EACA,OAAO,CAAC,GAAG,GAAM;GAAE,GAAG;GAAO;EAAG,CAAC;CACnC;CAEA,IAAI,EAAuB,IAAI,EAAM,IAAI,GAAG;EAC1C,IAAM,IAAM,EAAK,WAAW,MAAS,EAAK,SAAS,EAAM,IAAI;EAC7D,IAAI,KAAO,GAAG;GACZ,IAAM,IAAO,CAAC,GAAG,CAAI;GAErB,OADA,EAAK,KAAO,GACL;EACT;CACF;CAEA,OAAO,CAAC,GAAG,GAAM,CAAK;AACxB;AAEA,SAAgB,gBAAgB,GAA8B,GAAkD;CAC9G,IAAI,IAAO,CAAC,GAAG,CAAQ;CAIvB,AAH8B,EAAS,MACpC,MAAU,EAAM,SAAS,UAAU,EAAM,SAAS,SAEjD,MACF,IAAO,0BAA0B,CAAI;CAEvC,IAAM,IAAqB,EAAK,MAAM,MAAS,EAAuB,IAAI,EAAK,IAAI,CAAC,GAChF,IAAU;CAEd,KAAK,IAAM,KAAS,GAAU;EAC5B,IAAI,EAAM,SAAS,QAAQ;GACzB,IAAU;GACV,IAAM,IAAO,OAAO,EAAM,WAAY,WAAW,EAAM,UAAU;GAKjE,IAJI,CAAC,KACgB,EAAK,MAAM,MAAS,EAAK,SAAS,UAAU,OAAO,EAAK,WAAY,QACrF,KAEA,KAAsB,uBAAuB,CAAI,GAAG;GACxD,EAAK,KAAK;IAAE,GAAG;IAAO,SAAS;GAAK,CAAC;GACrC;EACF;EACA,IAAO,+BAA+B,GAAM,CAAK;CACnD;CAGA,OADI,CAAC,KAAW,EAAS,WAAW,IAAU,IACvC;AACT;AAEA,SAAgB,iBAAiB,GAA8B,GAAkD;CAC/G,OAAO,gBAAgB,GAAU,CAAQ;AAC3C;AAEA,SAAS,2BAA2B,GAA0B;CAC5D,IAAI,IAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,EAAS,QAAQ,KAAK,GAAG;EAC3C,IAAM,IAAK,EAAS;EACpB,IAAI,MAAO,MAAM;GACf,KAAO;GACP;EACF;EACA,IAAM,IAAO,EAAS,IAAI;EAC1B,IAAI,MAAS,KAAA,GAAW;GACtB,KAAO;GACP;EACF;EACA,QAAQ,GAAR;GACE,KAAK;IACH,KAAO;IACP;GACF,KAAK;IACH,KAAO;IACP;GACF,KAAK;IACH,KAAO;IACP;GACF,KAAK;IACH,KAAO;IACP;GACF,KAAK;IACH,KAAO;IACP;GACF,SACE,KAAO;EAEX;EACA,KAAK;CACP;CACA,OAAO;AACT;AAEA,SAAS,6BAA6B,GAAuB;CAC3D,IAAM,IAAU,EAAK,UAAU;CAE/B,OADK,EAAQ,WAAW,GAAG,IACpB,WAAW,KAAK,CAAO,IADO;AAEvC;AAEA,IAAM,IACJ;AAOF,SAAgB,oCAAoC,GAAwC;CAC1F,IAAI,CAAC,6BAA6B,CAAG,GAAG;CAExC,IAAM,IAAS,kBAAkB,CAAG;CACpC,IAAI,GAAQ,OAAO,aAAa,CAAM;CAEtC,IAAM,IAAQ,EAA8B,KAAK,CAAG;CACpD,IAAI,CAAC,GAAO,OAAO;CAGnB,IAAI,IADU,EAAM,QAAQ,EAAM,EAAE,CAAC,QAEjC,IAAU;CACd,OAAO,IAAI,EAAI,SAAQ;EACrB,IAAM,IAAK,EAAI;EACf,IAAI,MAAO,MAAM;GACf,IAAI,IAAI,KAAK,EAAI,QAAQ;IACvB,KAAW;IACX;GACF;GAEA,AADA,KAAW,EAAI,MAAM,GAAG,IAAI,CAAC,GAC7B,KAAK;GACL;EACF;EACA,IAAI,MAAO,MAAK;EAEhB,AADA,KAAW,GACX,KAAK;CACP;CACA,OAAO,2BAA2B,CAAO;AAC3C;AAMA,SAAgB,yBAAyB,GAAgD;CACvF,IAAI,EAAO,WAAW,GAAG,OAAO;CAChC,IAAM,IAAO,EAAO;CACpB,KAAA,KAAA,OAAA,KAAA,IAAI,EAAM,UAAS,UAAU,OAAO,EAAK,WAAY,UAAU,OAAO;CACtE,IAAM,IAAS,kBAAkB,EAAK,OAAO;CAC7C,IAAI,KAAU,EAAO,SAAS,GAAG,OAAO;CAExC,IAAM,IAAU,oCAAoC,EAAK,OAAO;CAMhE,OALI,MAAY,KAAA,IAKT,IAHE,CAAC;EAAE,MAAM;EAAQ,QADT,OAAO,EAAK,UAAW,WAAW,EAAK,SAAS;EAC/B,SAAS,KAAA,OAAW,KAAX;CAAc,CAAC;AAI5D;AAEA,SAAgB,aACd,GACA,GACoB;CACpB,IAAI,CAAC,EAAQ,QAAQ,OAAO;CAC5B,IAAM,IAAO,CAAC,GAAG,CAAQ;CACzB,KAAK,IAAM,KAAS,GAAS;EAC3B,IAAM,IAAK,EAAM,UAAU,KAAK;EAChC,IAAI,CAAC,GAAI;EACT,IAAM,IAAM,EAAK,WAAW,MAAU,EAAM,OAAO,CAAE;EACrD,AAAI,KAAO,IAAG,EAAK,KAAO;GAAE,GAAG,EAAM;GAAO;EAAG,IAC1C,EAAK,KAAK;GAAE,GAAG,EAAM;GAAO;EAAG,CAAC;CACvC;CACA,OAAO;AACT;;;AC9PA,SAAS,WAAS,GAAkD;CAClE,OAAO,OAAO,KAAU,cAAY,KAAkB,CAAC,MAAM,QAAQ,CAAK;AAC5E;;AAEA,SAAS,aAAW,GAAoC;CACtD,OAAO,OAAO,KAAU,YAAY,EAAM,KAAK,CAAC,CAAC,SAAS,IAAI,EAAM,KAAK,IAAI,KAAA;AAC/E;;AAEA,SAAS,aAAW,GAAoC;CACtD,IAAI,OAAO,KAAU,YAAY,OAAO,SAAS,CAAK,GAAG,OAAO;AAElE;;AAEA,SAAS,qBAAmB,GAAoC;CAE9D,OADK,MAAM,QAAQ,CAAK,IACjB,EAAM,QACV,MACC,WAAS,CAAI,KAAK,OAAO,EAAK,QAAS,QAC3C,IAJkC,CAAC;AAKrC;;AAGA,SAAgB,sBAAsB,GAAyC;;CAC7E,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAC7B,IAAM,IAAU,aAAW,EAAM,OAAO,GAClC,IAAU,EAAM;CACtB,IAAI,KAAW,QAAQ,CAAC,WAAS,CAAO,GAAG,OAAO;CAClD,IAAM,IAAW,aAAW,EAAQ,IAAI;CACxC,IAAI,CAAC,GAAU,OAAO;CACtB,IAAM,IAAS,aAAW,EAAQ,MAAM,GAClC,KAAA,IAAY,aAAW,EAAQ,SAAS,MAAA,OAAK,OAAL,GACxC,IAAO,WAAS,EAAM,SAAS,IAAI,EAAM,YAAY;CAC3D,IAAI,CAAC,GAAM,OAAO;CAClB,IAAM,IAAkB,EAAM,cACxB,IAAe,WAAS,CAAe,IACzC;EACE,aACE,OAAO,EAAgB,eAAgB,WAAW,EAAgB,cAAc;EAClF,eAAe,qBAAmB,EAAgB,aAAa;CACjE,IACA;EAAE,aAAa;EAAM,eAAe,CAAC;CAAwB,GAC3D,IAAgB,EAAM,YACtB,IAAkB,WAAS,CAAa,KAAA,IACzC,aAAW,EAAc,eAAe,MAAA,OAAK,IAAL,IACzC,GACE,IAAgB,WAAS,CAAa,KAAA,IACvC,aAAW,EAAc,aAAa,MAAA,OAAK,IAAL,IACvC,GACE,IAAW,WAAS,CAAa,IACnC,EAAc,aAAa,KACzB,KACA,EAAc,aAAa,MAEzB,IAAkB,IACtB,IACE,IAAa,WAAS,CAAa,KAAA,IACpC,aAAW,EAAc,UAAU,MAAA,wBAAK,IAAI,KAAK,CAAC,EAAA,CAAE,YAAY,IAA7B,qBACpC,IAAI,KAAK,CAAC,EAAA,CAAE,YAAY,GACtB,IAAe,WAAS,CAAa,IAAI,aAAW,EAAc,SAAS,IAAI,KAAA,GAC/E,IACJ,MAAiB,cACjB,MAAiB,eACjB,MAAiB,eACjB,MAAiB,UACb,IACA;CAEN,OAAO;EACL;EACA,MAAM;GACJ,MAAM;GACN,GAAI,KAAU,OAAoB,CAAC,IAAd,EAAE,UAAO;GAC9B;EACF;EACA,WAAW;EACX;EACA,YAAY;GACV;GACA;GACA;GACA;GACA;EACF;CACF;AACF;AAEA,SAAgB,yBACd,GACyB;CACzB,OAAO,gBAAgB,EAAM,SAAS;AACxC;AA8CA,SAAgB,mCACd,GACA,GACuB;CACvB,IAAM,IAAiC,CAAC,GAClC,oBAAO,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,CAAQ,GAAG,GAAG,OAAO,KAAK,CAAM,CAAC,CAAC;CACvE,KAAK,IAAM,KAAO,GAChB,AAAI,KAAK,UAAU,EAAS,EAAI,MAAM,KAAK,UAAU,EAAO,EAAI,MAC9D,EAAM,KAAO,EAAO;CAGxB,OAAO,EACL,6BAA6B,OAAO,KAAK,CAAK,CAAC,CAAC,SAAS,IAAI,IAAQ,EACvE;AACF;;;ACnLA,SAAS,WAAS,GAAkD;CAClE,OAAO,OAAO,KAAU,cAAY,KAAkB,CAAC,MAAM,QAAQ,CAAK;AAC5E;;AAEA,SAAS,aAAa,GAAwB;CAC5C,OAAO,EAAK,QAAQ,SAAS,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO;AAC5D;AAEA,SAAgB,kBAAkB,GAA+B,GAAuB;CACtF,IAAI,IAAkB;CACtB,KAAK,IAAM,KAAW,aAAa,CAAI,GAAG;EACxC,IAAI,CAAC,WAAS,CAAM,GAAG;EACvB,IAAS,EAAO;CAClB;CACA,OAAO;AACT;AAEA,SAAgB,yBACd,GACgD;CAChD,IAAM,IAAQ,mBAAmB,KAAK,EAAK,KAAK,CAAC;CAEjD,OADK,IACE;EAAE,WAAW,EAAM;EAAI,UAAU,EAAM;CAAG,IAD9B;AAErB;AAGA,SAAgB,qBACd,GACA,GACS;CACT,IAAM,IAAU,EAAK,KAAK;CAC1B,IAAI,CAAC,GAAS;CAEd,IAAM,IAAa,yBAAyB,CAAO;CACnD,IAAI,GAAY;EACd,IAAM,IAAa,kBAAkB,GAAM,EAAW,SAAS;EAC/D,IAAI,CAAC,MAAM,QAAQ,CAAU,GAAG;EAChC,KAAK,IAAM,KAAQ,GACjB,IAAI,WAAS,CAAI,KAAK,EAAW,YAAY,GAC3C,OAAO,EAAK,EAAW;EAG3B;CACF;CAEA,OAAO,kBAAkB,GAAM,CAAO;AACxC;AASA,SAAS,aAAa,GAAwB;CAK5C,OAJI,KAAS,OAAa,KACtB,OAAO,KAAU,WAAiB,IAClC,OAAO,KAAU,YAAkB,IAAQ,SAAS,UACpD,OAAO,KAAU,WAAiB,OAAO,CAAK,IAC3C;AACT;AAEA,SAAS,kBAAkB,GAA0B,GAAsB;;CACzE,SAAA,IAAO,EAAO,OAAO,MAAM,MAAU,EAAM,SAAS,CAAI,MAAA,SAAA,IAAA,EAAG,UAAA,OAAA,KAAA,IAAA,EAAO,KAAK,MAAK;AAC9E;AAEA,SAAS,qBACP,GACA,GACA,GACA,GACyC;CACzC,IAAM,IAAS,GAAG,EAAU;CAC5B,OAAO,EAAO,OACX,QAAQ,MAAU;EACjB,IAAI,CAAC,EAAM,KAAK,WAAW,CAAM,GAAG,OAAO;EAC3C,IAAM,IAAO,EAAM,KAAK,MAAM,EAAO,MAAM;EAG3C,OAFI,CAAC,KAAQ,EAAK,SAAS,GAAG,KAAK,MAAS,KACxC,EAAM,SAAS,EAAO,aAAmB,KACtC,EAAM,SAAS,gBAAgB,EAAM,WAAW;CACzD,CAAC,CAAC,CACD,KAAK,MAAU;EACd,IAAM,IAAO,EAAM,KAAK,MAAM,EAAO,MAAM,GACrC,IAAM,KAAQ,IAAO,EAAK,KAAQ,EAAM;EAC9C,OAAO;GAAE,OAAO,EAAM;GAAO,OAAO,aAAa,CAAG;EAAE;CACxD,CAAC,CAAC,CACD,QAAQ,MAAQ,EAAI,MAAM,KAAK,CAAC,CAAC,SAAS,CAAC;AAChD;AAEA,SAAS,yBACP,GACA,GACyC;;CACzC,IAAM,KAAA,IAAa,EAAO,eAAA,OAAA,KAAA,IAAA,EAAY,KAAK;CAC3C,OAAO,EAAO,OACX,QAAQ,MACH,EAAM,SAAS,KACf,EAAM,KAAK,SAAS,IAAI,IAAU,KAC/B,EAAM,SAAS,gBAAgB,EAAM,WAAW,UACxD,CAAC,CACD,KAAK,MAAW;;;GACf,OAAO,EAAM;GACb,OAAO,cAAA,IAAa,qBAAqB,GAAM,EAAM,IAAI,MAAA,OAAK,EAAM,QAAX,CAAgB;EAC3E;CAAE,CAAA,CAAC,CACF,QAAQ,MAAQ,EAAI,MAAM,KAAK,CAAC,CAAC,SAAS,CAAC;AAChD;AAGA,SAAgB,8BACd,GACA,GACyB;;CACzB,IAAM,KAAA,IAAa,EAAO,eAAA,OAAA,KAAA,IAAA,EAAY,KAAK;CAC3C,IAAI,CAAC,GAAY,OAAO,CAAC;CAEzB,IAAM,IAAY,kBAAkB,GAAQ,CAAU,GAChD,IAAa,yBAAyB,CAAU;CAEtD,IAAI,CAAC,GAAY;EACf,IAAM,IAAQ,qBAAqB,GAAM,CAAU,GAC7C,IAAO,OAAO,KAAU,WAAW,IAAQ,aAAa,CAAK;EAEnE,OADK,EAAK,KAAK,IACR,CACL;GACE,OAAO;GACP,OAAO;GACP;GACA,MAAM,yBAAyB,GAAQ,CAAI;EAC7C,CACF,IARyB,CAAC;CAS5B;CAEA,IAAM,IAAa,kBAAkB,GAAM,EAAW,SAAS;CAC/D,IAAI,CAAC,MAAM,QAAQ,CAAU,KAAK,EAAW,WAAW,GAAG,OAAO,CAAC;CAEnE,IAAM,IAAQ,EACX,KAAK,GAAO,MAAU;EACrB,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;EAC7B,IAAM,IAAM,EAAM,EAAW,WACvB,IAAO,OAAO,KAAQ,WAAW,IAAM,aAAa,CAAG;EAI7D,OAHK,EAAK,KAAK,IAGR;GACL;GACA,OAHA,EAAW,SAAS,IAAI,GAAG,EAAU,IAAI,IAAQ,EAAE,GAAG,EAAW,OAAO,KAAK;GAI7E;GACA,MAAM,qBAAqB,GAAQ,EAAW,WAAW,GAAO,EAAW,QAAQ;EACrF,IARyB;CAS3B,CAAC,CAAC,CACD,QAAQ,MAAwC,KAAQ,IAAI;CAI/D,OAFI,EAAM,SAAS,IAAU,IAEtB,CACL;EACE,OAAO;EACP,OAAO;EACP,MAAM;EACN,MAAM,yBAAyB,GAAQ,CAAI;CAC7C,CACF;AACF;AAqBA,SAAgB,qBAAqB,GAAuB;CAC1D,IAAM,IAAU,EAAK,KAAK;CAC1B,IAAI,CAAC,GAAS,OAAO;CACrB,IAAI,qBAAqB,KAAK,CAAO,GAAG,OAAO;CAC/C,IAAI,EAAQ,WAAW,GAAG,KAAK,EAAQ,WAAW,GAAG,GACnD,IAAI;EAEF,OADA,KAAK,MAAM,CAAO,GACX;CACT,SAAA,GAAQ;EACN,OAAO;CACT;CAEF,OAAO;AACT;;;ACnJA,SAAS,WAAS,GAAkD;CAClE,OAAO,OAAO,KAAU,cAAY,KAAkB,CAAC,MAAM,QAAQ,CAAK;AAC5E;;AAEA,SAAS,aAAW,GAAoC;CACtD,OAAO,OAAO,KAAU,YAAY,EAAM,KAAK,CAAC,CAAC,SAAS,IAAI,EAAM,KAAK,IAAI,KAAA;AAC/E;;AAEA,SAAS,SAAS,GAAqC;CACrD,IAAM,IAAM,aAAW,CAAK;CAU5B,OARE,MAAQ,aACR,MAAQ,gBACR,MAAQ,cACR,MAAQ,UACR,MAAQ,WAED,IAEF;AACT;AAEA,SAAS,WAAW,GAAuC;CACzD,IAAM,IAAM,aAAW,CAAK;CAU5B,OARE,MAAQ,UACR,MAAQ,cACR,MAAQ,YACR,MAAQ,cACR,MAAQ,WAED,IAEF;AACT;AAEA,SAAS,SAAS,GAAgC;CAChD,IAAM,IAAM,aAAW,CAAK;CAE5B,OADI,MAAQ,wBAAwB,MAAQ,SAAe,IACpD;AACT;AAEA,SAAS,iBAAiB,GAAoD;CAC5E,IAAI,CAAC,MAAM,QAAQ,CAAK,GAAG;CAC3B,IAAM,IAAU,EACb,KAAK,MAAS;EACb,IAAI,CAAC,WAAS,CAAI,GAAG,OAAO;EAC5B,IAAM,IAAQ,aAAW,EAAK,KAAK,GAC7B,IAAc,aAAW,EAAK,KAAK;EAEzC,OADI,CAAC,KAAS,KAAe,OAAa,OACnC;GAAE;GAAO,OAAO;EAAY;CACrC,CAAC,CAAC,CACD,QAAQ,MAAuC,KAAQ,IAAI;CAC9D,OAAO,EAAQ,SAAS,IAAI,IAAU,KAAA;AACxC;AAEA,SAAS,WAAW,GAAsC;;CACxD,IAAI,CAAC,WAAS,CAAG,GAAG,OAAO;CAC3B,IAAM,IAAO,aAAW,EAAI,IAAI,GAC1B,KAAA,IAAQ,aAAW,EAAI,KAAK,MAAA,OAAK,IAAL;CAElC,OADI,CAAC,KAAQ,CAAC,IAAc,OACrB;EACL;EACA;EACA,MAAM,SAAS,EAAI,IAAI;EACvB,QAAQ,WAAW,EAAI,MAAM;EAC7B,UAAU,EAAI,aAAa;EAC3B,UAAU,EAAI,aAAa;EAC3B,OAAO,EAAI;EACX,aAAa,iBAAiB,EAAI,WAAW;EAC7C,QAAQ,OAAO,EAAI,UAAW,WAAW,EAAI,SAAS;CACxD;AACF;AAGA,SAAgB,sBAAsB,GAAyC;;CAC7E,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAE7B,IAAM,KADY,MAAM,QAAQ,EAAM,MAAM,IAAI,EAAM,SAAS,CAAC,EAAA,CAE7D,KAAK,MAAQ,WAAW,CAAG,CAAC,CAAC,CAC7B,QAAQ,MAAoC,KAAS,IAAI;CAC5D,OAAO;EACL,UAAU,SAAS,EAAM,QAAQ;EACjC,aAAA,IAAY,aAAW,EAAM,UAAU,MAAA,OAAK,OAAL;EACvC,qBAAqB,EAAM,wBAAwB;EACnD;CACF;AACF;AAEA,SAAS,oBAAoB,GAAuC;CAKlE,OAJI,OAAO,KAAU,YAAY,EAAM,SAAS,KAAW,aACvD,OAAO,KAAU,YAAY,OAAO,KAAU,YAAY,OAAO,KAAU,YACtE,SAEF;AACT;AAEA,SAAS,6BAA6B,GAA8C;CAClF,KAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,CAAI,GAAG;EAC/C,IAAI,OAAO,KAAU,YAAY,EAAM,KAAK,GAAG,OAAO;EACtD,IAAI,MAAM,QAAQ,CAAK,KAAK,EAAM,SAAS,KAAK,WAAS,EAAM,EAAE,GAC1D;QAAA,IAAM,CAAC,GAAM,MAAc,OAAO,QAAQ,EAAM,EAAE,GACrD,IAAI,OAAO,KAAc,YAAY,EAAU,KAAK,GAClD,OAAO,GAAG,EAAI,KAAK;EAAA;CAI3B;CACA,IAAM,IAAW,OAAO,KAAK,CAAI,CAAC,CAAC;CACnC,OAAO,KAAA,OAAY,OAAZ;AACT;AAGA,SAAgB,0BAA0B,GAA2C;CACnF,IAAM,IAAa,6BAA6B,EAAM,SAAS;CAmB/D,OAlBsB,EAAM,aAAa,cACvB,SAAS,IAClB;EACL,UAAU;EACV;EACA,qBAAqB;EACrB,QAAQ,OAAO,QAAQ,EAAM,SAAS,CAAC,CAAC,KAAK,CAAC,GAAM,QAAY;GAC9D;GACA,OAAO;GACP,MAAM,MAAS,IAAa,YAAY;GACxC,QAAQ;GACR,UAAU;GACV,UAAU;GACV;EACF,EAAE;CACJ,IAGK;EACL,UAAU;EACV,YAAY;EACZ,qBAAqB;EACrB,QAAQ,OAAO,QAAQ,EAAM,SAAS,CAAC,CAAC,KAAK,CAAC,GAAM,QAAY;GAC9D;GACA,OAAO;GACP,MAAM,MAAS,IAAa,YAAY;GACxC,QAAQ,oBAAoB,CAAK;GACjC,UAAU,oBAAoB,CAAK,MAAM;GACzC,UAAU;GACV;EACF,EAAE;CACJ;AACF;AAEA,SAAgB,kBACd,GACA,GACyB;CAGzB,OAFI,MACA,IAAmB,0BAA0B,CAAU,IACpD;AACT;AAEA,SAAgB,wBAAwB,GAA6C;CAInF,OAHI,EAAO,aAAa,iBACf,CAAC,IAEH,EAAO,OAAO,QAAQ,MAAU,EAAM,WAAW,QAAQ;AAClE;AAEA,SAAgB,yBAAyB,GAA6C;CACpF,OAAO,EAAO,OAAO,QAAQ,MAAU,EAAM,YAAY,EAAM,WAAW,QAAQ;AACpF;AAEA,SAAgB,4BAA4B,GAAyC;;CACnF,IAAI,CAAC,EAAO,YAAY,OAAO;CAC/B,IAAM,IAAQ,EAAO,OAAO,MAAM,MAAQ,EAAI,SAAS,EAAO,UAAU;CACxE,QAAA,KAAA,SAAA,IAAO,EAAO,UAAA,OAAA,KAAA,IAAA,EAAO,KAAK,MAAK;AACjC;AAEA,SAAgB,mBACd,GACA,GACS;CACT,IAAM,IAAS,kBAAkB,GAAY,CAAU;CACvD,IAAI,CAAC,KAAU,CAAC,GAAY,OAAO;CACnC,IAAI,EAAO,aAAa,gBAAgB;EACtC,IAAM,IAAQ,8BAA8B,EAAW,WAAW,CAAM;EACxE,IAAI,EAAM,WAAW,KAAK,EAAM,EAAE,CAAC,KAAK,KAAK,GAAG,OAAO;EACvD,IAAI,EAAM,SAAS,GAAG,OAAO;EAC7B,IAAM,IAAa,aAAa,EAAW,aAAa,aAAmC;EAI3F,OAHI,KAAc,CAAC,qBAAqB,CAAU,IACzC,KAEF,yBAAyB,CAAM,CAAC,CAAC,SAAS;CACnD;CACA,OAAO,yBAAyB,CAAM,CAAC,CAAC,SAAS;AACnD;AAEA,SAAgB,yBACd,GACA,GACQ;CACR,IAAA,KAAA,QAAI,EAAQ,YAAY;EACtB,IAAM,IAAQ,8BAA8B,EAAW,WAAW,CAAM;EACxE,IAAI,EAAM,WAAW,GAAG,OAAO,EAAM,EAAE,CAAC;EACxC,IAAI,EAAM,SAAS,GACjB,OAAO,EAAM,KAAK,MAAS,EAAK,IAAI,CAAC,CAAC,KAAK,MAAM;CAErD;CAEA,IAAM,IAAS,EAAW,aAAa,eACjC,IAAa,aAAa,CAAM;CACtC,IAAI,KAAc,CAAC,qBAAqB,CAAU,GAChD,OAAO;CAGT,IAAM,IAAA,KAAA,OAAA,KAAA,IAAc,EAAQ,OAAO,MAChC,MACC,EAAM,SAAS,EAAO,cACtB,OAAO,EAAM,SAAU,YACvB,EAAM,MAAM,KAAK,CACrB;CAKA,OAJI,KAAe,OAAO,EAAY,SAAU,WACvC,EAAY,QAGd;AACT;AAEA,SAAgB,oBACd,GACA,GACA,GACA,GACS;CACT,IAAM,IAAW,kBAAkB,GAAY,CAAM,GAC/C,IAAkB,yBAAyB,GAAY,CAAQ,GAC/D,IAAiB,EAAkB,KAAK,MAAM,EAAgB,KAAK,GACnE,IACJ,KAAK,UAAU,CAAU,MAAM,KAAK,UAAU,EAAW,SAAS;CAQpE,OANI,EAAS,aAAa,iBACjB,KAAkB,EAAkB,KAAK,CAAC,CAAC,SAAS,IAEzD,EAAS,aAAa,SACjB,IAEF,KAAkB;AAC3B;AAGA,SAAgB,gCACd,GACA,GACA,GAIuB;CACvB,IAAM,IAAS,kBAAkB,GAAY,CAAU,GACjD,IAAgB,EAAW,aAAa,eACxC,IAAkB,yBAAyB,GAAY,CAAM,GAC7D,IAAiB,EAAM,kBAAkB,KAAK,MAAM,EAAgB,KAAK;CAE/E,IAAI,EAAO,aAAa,gBAAgB;EACtC,IAAM,IAAgB,EAAW,aAAa,eACxC,IAAa,2BAA2B,EAAM,mBAAmB,CAAa;EAMpF,OALI,qBAAqB,aAAa,CAAa,CAAC,IAC3C,EACL,yBAAyB,2BAA2B,EAAM,iBAAiB,EAC7E,IAEK,EAAE,yBAAyB,EAAW;CAC/C;CAEA,IAAM,IAAe,mCACnB,EAAW,WACX,EAAM,UACR,GACM,IAAiC,CAAC;CAExC,IAAI,EAAO,aAAa,UAAU,EAAO,qBAAqB;;EAC5D,IAAM,IAAgB,IAAI,IACxB,yBAAyB,CAAM,CAAC,CAAC,KAAK,MAAU,EAAM,IAAI,CAC5D,GACM,IAAyC,CAAC,GAC1C,KAAA,IAAQ,EAAa,gCAAA,OAA+B,CAAC,IAAhC;EAC3B,KAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,CAAK,GAC7C,AAAI,EAAc,IAAI,CAAG,MACvB,EAAc,KAAO;EAGzB,AAAI,OAAO,KAAK,CAAa,CAAC,CAAC,SAAS,IACtC,EAAQ,8BAA8B,IAC7B,EAAO,aAAa,WAC7B,EAAQ,8BAA8B;CAE1C;CASA,OAPI,EAAO,aAAa,wBAAwB,MAC9C,EAAQ,0BAA0B,2BAChC,EAAM,mBACN,CACF,IAGK;AACT;AAQA,SAAgB,2BACd,GACkC;CAClC,OACE,MAAS,yBACT,MAAS,8BACT,MAAS,+BACT,MAAS;AAEb;;;AC9VA,SAAS,oBAAoB,GAAoC;CAE/D,OADK,MAAM,QAAQ,CAAK,IACjB,EACJ,KAAK,MAAQ,sBAAsB,CAAG,CAAC,CAAC,CACxC,QAAQ,MAAqC,KAAS,IAAI,IAH3B,CAAC;AAIrC;AAEA,SAAS,oBAAoB,GAAoC;CAE/D,OADK,MAAM,QAAQ,CAAK,IACjB,EACJ,KAAK,MAAQ,sBAAsB,CAAG,CAAC,CAAC,CACxC,QAAQ,MAAuC,KAAU,IAAI,IAH9B,CAAC;AAIrC;AAGA,SAAgB,wBAAwB,GAKhB;;CACtB,IAAM,IAAY,oBAAoB,EAAM,WAAW;CACvD,IAAI,EAAU,SAAS,GAAG;;EACxB,IAAM,IAAW,oBAAoB,EAAM,YAAY,GACjD,KAAA,IAAiB,EAAM,eAAA,OAAc,OAAd;EAC7B,OAAO,EAAU,KAAK,GAAY,MAAW;;;IAC3C;IACA,aAAA,IAAY,EAAS,OAAA,OAAU,IAAV;GACvB;EAAE,CAAA;CACJ;CAEA,IAAM,KAAA,IACJ,EAAM,eAAA,OAAc,sBAAsB,EAAM,UAAU,IAApD;CAGR,OAFK,IAEE,CAAC;EAAE,YAAY;EAAQ,aAAA,IAAY,EAAM,eAAA,OAAc,OAAd;CAAmB,CAAC,IAFhD,CAAC;AAGvB;AAEA,SAAgB,6BACd,GAC0B;CAC1B,OAAO,EAAQ,KAAK,MAAW;EAC7B,IAAM,IAAS,kBAAkB,EAAO,YAAY,EAAO,UAAU;EACrE,OAAO;GACL,mBAAmB,yBAAyB,EAAO,YAAY,CAAM;GACrE,YAAY,yBAAyB,EAAO,UAAU;EACxD;CACF,CAAC;AACH;AAEA,SAAgB,uBAAuB,GAA2B,GAAuB;;CAGvF,SAFM,IAAO,EAAO,WAAW,KAAK,SAAA,OAAA,KAAA,IAAA,EAAM,KAAK,MAExC,SAAS,IAAQ;AAC1B;;;ACtEA,SAAgB,0BACd,GACA,GACqC;;CACrC,IAAM,IAAiC,EAAE,GAAG,EAAe,GACrD,IAAA,KAAA,SAAA,IAAQ,EAAa,SAAA,OAAA,KAAA,IAAA,EAAM,KAAK;CAItC,OAHI,MACF,EAAM,OAAO,IAER,OAAO,KAAK,CAAK,CAAC,CAAC,SAAS,IAAI,IAAQ,KAAA;AACjD;AAMA,SAAgB,sBAAsB,GAAgD;CACpF,IAAM,IAAY,EAAO,QAAQ,MAAU,EAAM,gBAAgB,EAAI;CACrE,IAAI,EAAU,WAAW,GACvB,OAAO,EAAU,EAAE,CAAE;AAGzB;AAGA,SAAgB,uBAAuB,GAAqC;CAC1E,OAAO,EAAO,MAAM,MAAU,EAAM,gBAAgB,KAAA,CAAS;AAC/D;;;AC/BA,SAAgB,yBAAgD;CAC9D,IAAI,OAAO,SAAW,KAAa,OAAO,CAAC;CAC3C,IAAM,IAAY,OAAO,SAAS,YAAY,KAAA,GACxC,IAAsC,CAAC;CAK7C,OAHA,IADmB,gBAAgB,OAAO,SAAS,MACnD,CAAA,CAAO,SAAS,GAAO,MAAQ;EAC7B,EAAY,KAAO;CACrB,CAAC,GACM;EACL;EACA,aAAa,OAAO,KAAK,CAAW,CAAC,CAAC,SAAS,IAAI,IAAc,KAAA;CACnE;AACF;AAEA,SAAgB,kBACd,GACA,GACuB;;CACvB,IAAI,CAAC,GAAU,OAAO;CACtB,IAAM,IAAc;EAClB,IAAA,IAAI,EAAK,gBAAA,OAAe,CAAC,IAAhB;EACT,IAAA,IAAI,EAAS,gBAAA,OAAe,CAAC,IAAhB;CACf;CACA,OAAO;EACL,YAAA,IAAW,EAAS,cAAA,OAAa,EAAK,YAAlB;EACpB,aAAa,OAAO,KAAK,CAAW,CAAC,CAAC,SAAS,IAAI,IAAc,KAAA;CACnE;AACF;AAEA,SAAgB,oBAAoB,GAAwD;CAE1F,OADA,CAAK,KACE,EAAE,EAAI,aAAc,EAAI,eAAe,OAAO,KAAK,EAAI,WAAW,CAAC,CAAC,SAAS;AACtF;;;AChCA,IAAa,IAA4B,kBAC5B,IAAgC;AAE7C,SAAS,WAAS,GAAkD;CAClE,OAAyB,OAAO,KAAU,cAAnC,KAA+C,CAAC,MAAM,QAAQ,CAAK;AAC5E;;AAEA,SAAS,aAAW,GAAoC;CACtD,OAAO,OAAO,KAAU,YAAY,EAAM,KAAK,CAAC,CAAC,SAAS,IAAI,EAAM,KAAK,IAAI,KAAA;AAC/E;;AAEA,SAAS,eAAe,GAA8C;CACpE,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAC7B,IAAM,IAAK,aAAW,EAAM,EAAE,GACxB,IAAa,aAAW,EAAM,UAAU;CAC9C,IAAI,CAAC,KAAM,CAAC,GAAY,OAAO;CAC/B,IAAM,IAAmC;EAAE;EAAI;CAAW,GACpD,IAAO,aAAW,EAAM,IAAI;CAElC,AADI,MAAM,EAAU,OAAO,IACvB,WAAS,EAAM,MAAM,MAAG,EAAU,SAAS,EAAM;CACrD,IAAM,IAAS,aAAW,EAAM,MAAM;CACtC,AAAI,MAAQ,EAAU,SAAS;CAC/B,IAAM,IAAO,aAAW,EAAM,IAAI;CAElC,OADI,MAAM,EAAU,OAAO,IACpB;AACT;AAGA,SAAgB,yBAAyB,GAA4C;;CAEnF,IADI,CAAC,WAAS,CAAK,KACf,EAAM,SAAS,kBAAkB,OAAO;CAC5C,IAAM,IAAW,aAAW,EAAM,QAAQ,GACpC,IAAa,aAAW,EAAM,UAAU;CAE9C,IADI,CAAC,KAAY,CAAC,KACd,CAAC,MAAM,QAAQ,EAAM,UAAU,GAAG,OAAO;CAE7C,IAAM,IAAa,EAAM,WACtB,KAAK,MAAQ,eAAe,CAAG,CAAC,CAAC,CACjC,QAAQ,MAAsC,KAAO,IAAI;CAC5D,IAAI,EAAW,WAAW,GAAG,OAAO;CAEpC,IAAM,IACJ,WAAS,EAAM,UAAU,KAAK,aAAW,EAAM,WAAW,UAAU,IAChE,aAAW,EAAM,WAAW,UAAU,IACtC;CAEN,OAAO;EACL,MAAM;EACN;EACA,SAAA,IAAQ,aAAW,EAAM,MAAM,MAAA,OAAK,KAAL;EAC/B;EACA;EACA,YAAY,EAAE,YAAY,EAAiB;EAC3C,eAAA,IAAc,aAAW,EAAM,YAAY,MAAA,OAAK,KAAL;CAC7C;AACF;AAEA,SAAgB,wBAAwB,GAA+C;CACrF,QAAA,KAAA,OAAA,KAAA,IAAO,EAAW,KAAK,OAAM;AAC/B;AAEA,SAAgB,kBACd,GACA,GACc;CACd,OAAO;EACL,YAAY,EAAQ,WAAW,cAAc,EAAQ;EACrD,YAAY,EAAW,KAAK;CAC9B;AACF;AAEA,SAAgB,iCAAiC,GAA0C;;CACzF,IAAM,KAAA,IAAO,EAAU,SAAA,OAAA,KAAA,IAAA,EAAM,KAAK;CAClC,IAAI,GAAM,OAAO;CACjB,IAAI,EAAU,UAAU,OAAO,KAAK,EAAU,MAAM,CAAC,CAAC,SAAS,GAC7D,IAAI;EACF,OAAO,KAAK,UAAU,EAAU,MAAM,CAAC,CAAC,MAAM,GAAG,EAAE;CACrD,SAAA,GAAQ,CAER;CAEF,OAAO,EAAU;AACnB;AAMA,SAAgB,gCAAgC,GAIjB;CAC7B,IACE,EAAM,aACN,CAAC,wBAAwB,EAAM,SAAS,KACxC,EAAM,UAAU,KAAK,CAAC,CAAC,SAAS,GAEhC,OAAO;CAGT,IAAI,MAAM,QAAQ,EAAM,KAAK,GAC3B,KAAK,IAAI,IAAI,EAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAQ;EACnD,IAAM,IAAO,EAAM,MAAM;EACzB,IAAI,CAAC,WAAS,CAAI,GAAG;EACrB,IAAM,IAAO,OAAO,EAAK,QAAS,WAAW,EAAK,OAAO;EACzD,IACE,MAAS,2BACT,MAAS,mBACT,EAAK,SAAS,gBAAgB,GAC9B;GACA,IAAM,IAAa,yBAAyB,EAAK,MAAM;GACvD,IAAI,GAAY,OAAO;GACvB,IAAM,IAAa,yBAAyB,EAAK,MAAM;GACvD,IAAI,GAAY,OAAO;EACzB;EACA,IAAM,IAAS,WAAS,EAAK,MAAM,IAC/B,EAAK,SACL,WAAS,EAAK,MAAM,IAClB,EAAK,SACL;EACN,IAAI,EAAK,SAAS,eAAe,KAAK,GAAQ;GAC5C,IAAM,IAAS,yBAAyB,EAAO,YAAY;GAC3D,IAAI,GAAQ,OAAO;EACrB;CACF;CAGF,IAAM,IAAU,EAAM;CACtB,IAAI,GAAS;EACX,IAAM,IAAU,yBAAyB,EAAQ,EAA8B;EAC/E,IAAI,GAAS,OAAO;CACtB;CAEA,OAAO;AACT;;;AClIA,SAAS,WAAS,GAAkD;CAClE,OAAyB,OAAO,KAAU,cAAnC,KAA+C,CAAC,MAAM,QAAQ,CAAK;AAC5E;;AAEA,SAAS,aAAW,GAA+B;CACjD,IAAI,OAAO,KAAU,UAAU,OAAO;CACtC,IAAM,IAAU,EAAM,KAAK;CAC3B,OAAO,EAAQ,SAAS,IAAI,IAAU;AACxC;;AAEA,SAAS,aAAW,GAA+B;CACjD,IAAI,OAAO,KAAU,YAAY,OAAO,SAAS,CAAK,GAAG,OAAO;CAChE,IAAI,OAAO,KAAU,YAAY,EAAM,KAAK,CAAC,CAAC,SAAS,GAAG;EACxD,IAAM,IAAS,OAAO,CAAK;EAC3B,OAAO,OAAO,SAAS,CAAM,IAAI,IAAS;CAC5C;CACA,OAAO;AACT;;AAEA,SAAS,sBAAsB,GAA+B;CAI5D,OAHI,KAAS,OAAa,OACtB,OAAO,KAAU,WAAiB,IAClC,OAAO,KAAU,YAAY,OAAO,KAAU,YAAkB,OAAO,CAAK,IACzE;AACT;AAEA,SAAS,kBAAkB,GAA4D;CACrF,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAC7B,IAAM,IAAM,aAAW,EAAM,GAAG,GAC1B,IAAQ,aAAW,EAAM,KAAK,GAC9B,IAAa,sBAAsB,EAAM,KAAK;CAEpD,OADI,CAAC,KAAO,CAAC,KAAS,KAAc,OAAa,OAC1C;EAAE;EAAK;EAAO,OAAO;CAAW;AACzC;AAEA,SAAS,mBAAmB,GAAuD;CAEjF,OADK,MAAM,QAAQ,CAAK,IACjB,EACJ,KAAK,MAAQ,kBAAkB,CAAG,CAAC,CAAC,CACpC,QAAQ,MAAoD,KAAO,IAAI,IAHxC,CAAC;AAIrC;AAEA,SAAS,iBAAiB,GAA0B;CAClD,IAAI,CAAC,MAAM,QAAQ,CAAK,GAAG,OAAO,CAAC;CACnC,IAAM,IAAiB,CAAC;CACxB,KAAK,IAAM,KAAS,GAAO;EACzB,IAAM,IAAM,aAAW,CAAK;EAC5B,AAAI,KAAK,EAAK,KAAK,CAAG;CACxB;CACA,OAAO;AACT;AAEA,SAAS,kBACP,GACA,GACA,GACQ;CACR,IAAM,IAAW,aAAW,EAAM,QAAQ;CAI1C,OAHI,MAAW,eAAqB,KAAA,OAAY,IAAZ,IAChC,MAAW,sBAA4B,sBACvC,MAAW,qBAA2B,qBACnC,KAAA,OAAa,KAAU,IAAvB;AACT;AAEA,SAAS,kBAAkB,GAA4D;;CACrF,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAC7B,IAAM,IAAO,aAAW,EAAM,IAAI;CAClC,IAAI,CAAC,GAAM,OAAO;CAElB,IAAM,KAAA,IAAQ,aAAW,EAAM,KAAK,MAAA,OAAK,IAAL,GAC9B,IAAsB,MAAM,QAAQ,EAAM,MAAM,GAChD,IAAe,WAAS,EAAM,MAAM,IAAI,EAAM,SAAS;CAY7D,OAVI,CAAC,KAAuB,IACnB;EACL;EACA;EACA,QAAQ,CAAC;EACT,WAAW,CAAC;EACZ;CACF,IAGK;EACL;EACA;EACA,QAAQ,mBAAmB,EAAM,MAAM;EACvC,WAAW,iBAAiB,EAAM,SAAS;CAC7C;AACF;AAEA,SAAS,YAAY,GAAsD;;CACzE,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAC7B,IAAM,IAAM,aAAW,EAAM,GAAG,GAC1B,IAAS,aAAW,EAAM,MAAM;CACtC,IAAI,CAAC,KAAO,CAAC,GAAQ,OAAO;CAE5B,IAAM,IAAS,mBAAmB,EAAM,MAAM,GACxC,IAAY,iBAAiB,EAAM,SAAS;CAElD,OAAO;EACL;EACA;EACA,QAAA,IAAO,aAAW,EAAM,KAAK,MAAA,OAAK,kBAAkB,GAAO,GAAK,CAAM,IAAzC;EAC7B,UAAU,aAAW,EAAM,QAAQ;EACnC,QAAQ,aAAW,EAAM,MAAM;EAC/B,MAAM,EAAM;EACZ;EACA,WAAW,EAAU,SAAS,IAAI,IAAY,KAAA;CAChD;AACF;AAGA,SAAgB,wBACd,GACS;CAGT,OAFK,IACD,EAAU,SAAe,KACtB,EAAU,cAAc,MAAM,MAAQ,EAAI,gBAAgB,IAAI,IAF9C;AAGzB;AAGA,SAAgB,6BACd,GACgC;CAChC,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAC7B,IAAM,IAAgB,MAAM,QAAQ,EAAM,aAAa,IACnD,EAAM,cACH,KAAK,MAAQ,kBAAkB,CAAG,CAAC,CAAC,CACpC,QAAQ,MAAoD,KAAO,IAAI,IAC1E,CAAC,GACC,IAAU,MAAM,QAAQ,EAAM,OAAO,IACvC,EAAM,QACH,KAAK,MAAQ,YAAY,CAAG,CAAC,CAAC,CAC9B,QAAQ,MAA8C,KAAO,IAAI,CAAC,CAClE,MAAM,GAAM,MAAU,EAAK,IAAI,cAAc,EAAM,GAAG,CAAC,IAC1D,CAAC,GACC,IAAS,EAAc,MAAM,MAAQ,EAAI,gBAAgB,IAAI;CACnE,OAAO;EACL,MAAM,aAAW,EAAM,IAAI;EAC3B,WAAW,aAAW,EAAM,SAAS;EACrC,YAAY,aAAW,EAAM,UAAU;EACvC,UAAU,aAAW,EAAM,QAAQ;EACnC,aAAa,aAAW,EAAM,WAAW;EACzC;EACA;EACA,QAAQ,KAAU,KAAA;CACpB;AACF;AAEA,SAAgB,0BACd,GACS;CAET,OADK,IAEH,GACE,EAAU,eACR,EAAU,cACV,EAAU,YACV,EAAU,SAEd,EAAU,cAAc,SAAS,KACjC,EAAU,QAAQ,SAAS,IATN;AAWzB;AAGA,SAAgB,4BACd,GACe;CACf,IAAI,EAAU,aACZ,OAAO,EAAU,OACb,GAAG,EAAU,YAAY,KAAK,EAAU,SACxC,EAAU;CAGhB,IAAM,IAAkB,CAAC;CAWzB,OAVI,EAAU,cAAc,EAAU,WACpC,EAAM,KAAK,GAAG,EAAU,WAAW,IAAI,EAAU,UAAU,IAClD,EAAU,aACnB,EAAM,KAAK,EAAU,UAAU,IACtB,EAAU,YACnB,EAAM,KAAK,IAAI,EAAU,UAAU,GAEjC,EAAU,QACZ,EAAM,KAAK,EAAU,IAAI,GAEpB,EAAM,SAAS,IAAI,EAAM,KAAK,KAAK,IAAI;AAChD;AAEA,SAAgB,8BACd,GACe;CAEf,OADK,IACE,4BAA4B,CAAS,IADrB;AAEzB;AAEA,IAAM,IAAyB;CAC7B,QAAQ;CACR,OAAO;CACP,SAAS;AACX;AAKA,SAAgB,mBAAmB,GAAyC;;CAC1E,QAAA,IAAO,EAAuB,EAAK,KAAK,CAAC,CAAC,YAAY,OAAA,OAA6C,OAA7C;AACxD;AAEA,SAAgB,wBAAwB,GAAgD;CACtF,IAAM,IAAU,EAAO;CAKvB,OAJI,OAAO,KAAY,YAAY,EAAQ,KAAK,IAAU,EAAQ,KAAK,IACnE,OAAO,KAAY,YAAY,OAAO,KAAY,YAC7C,OAAO,CAAO,IAEhB;AACT;AAEA,SAAgB,4BACd,GACuC;CACvC,IAAM,IAA8C,CAAC;CACrD,KAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,CAAM,GAAG;EAIjD,IAHI,MAAQ,aAAa,MAAQ,YAC7B,KAAS,QACT,OAAO,KAAU,YAAY,CAAC,EAAM,KAAK,KACzC,MAAM,QAAQ,CAAK,GAAG;EAC1B,IAAM,IACJ,OAAO,KAAU,WACb,EAAM,KAAK,IACX,OAAO,KAAU,YAAY,OAAO,KAAU,YAC5C,OAAO,CAAK,IACZ,KAAK,UAAU,GAAO,MAAM,CAAC;EACrC,EAAK,KAAK;GAAE;GAAK,OAAO;EAAK,CAAC;CAChC;CACA,OAAO;AACT;AAEA,SAAgB,0BAA0B,GAA2C;CACnF,IAAM,IAAS,EAAO;CACtB,IAAI,CAAC,MAAM,QAAQ,CAAM,GAAG,OAAO,CAAC;CACpC,IAAM,IAAiB,CAAC;CACxB,KAAK,IAAM,KAAS,GAAQ;EAC1B,IAAI,OAAO,KAAU,UAAU;GAC7B,IAAM,IAAM,aAAW,CAAK;GAC5B,AAAI,KAAK,EAAK,KAAK,CAAG;GACtB;EACF;EACA,IAAI,WAAS,CAAK,GAAG;GACnB,IAAM,IAAM,aAAW,EAAM,GAAG;GAChC,AAAI,KAAK,EAAK,KAAK,CAAG;EACxB;CACF;CACA,OAAO;AACT;AAEA,SAAgB,wBAAwB,GAAwB;CAC9D,IAAI,KAAS,MAAM,OAAO;CAC1B,IAAI,OAAO,KAAU,UAAU,OAAO,EAAM,KAAK,KAAK;CACtD,IAAI,OAAO,KAAU,YAAY,OAAO,KAAU,WAAW,OAAO,OAAO,CAAK;CAChF,IAAI;EACF,OAAO,KAAK,UAAU,GAAO,MAAM,CAAC;CACtC,SAAA,GAAQ;EACN,OAAO,OAAO,CAAK;CACrB;AACF;AAEA,SAAgB,uBAAuB,GAAgD;;CACrF,OAAO,EAAO,OAAO,SAAS,KAAK,IAAA,IAAQ,EAAO,cAAA,QAAA,EAAW;AAC/D;;;ACjQA,SAAS,WAAS,GAAkD;CAClE,OAAyB,OAAO,KAAU,cAAnC,KAA+C,CAAC,MAAM,QAAQ,CAAK;AAC5E;;AAEA,SAAS,aAAW,GAAoC;CACtD,OAAO,OAAO,KAAU,YAAY,EAAM,KAAK,CAAC,CAAC,SAAS,IAAI,EAAM,KAAK,IAAI,KAAA;AAC/E;;AAEA,SAAS,aAAW,GAAoC;CACtD,IAAI,OAAO,KAAU,YAAY,OAAO,SAAS,CAAK,GAAG,OAAO;CAChE,IAAI,OAAO,KAAU,YAAY,EAAM,KAAK,CAAC,CAAC,SAAS,GAAG;EACxD,IAAM,IAAS,OAAO,CAAK;EAC3B,OAAO,OAAO,SAAS,CAAM,IAAI,IAAS,KAAA;CAC5C;AAEF;;AAEA,SAAS,mBAAmB,GAA4C;CACtE,IAAM,IAAM,aAAW,CAAK;CAC5B,IAAI,MAAQ,UAAU,MAAQ,iBAAiB,MAAQ,WAAW,OAAO;AAE3E;AAEA,SAAS,mBAAmB,GAA4C;CACtE,IAAM,IAAM,aAAW,CAAK;CAC5B,IACE,MAAQ,aACR,MAAQ,cACR,MAAQ,cACR,MAAQ,eACR,MAAQ,WAER,OAAO;AAGX;AAEA,SAAS,eAAe,GAA0C;;CAChE,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAC7B,IAAM,IAAK,aAAW,EAAM,EAAE;CAE9B,OADI,KAAM,OAAa,OAChB;EACL;EACA,WAAA,IAAU,aAAW,EAAM,QAAQ,MAAA,OAAK,OAAL;EACnC,aAAA,IAAY,aAAW,EAAM,UAAU,MAAA,OAAK,OAAL;CACzC;AACF;AAEA,SAAS,iBAAiB,GAAkD;;CAC1E,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAC7B,IAAM,KAAA,IAAa,aAAW,EAAM,UAAU,MAAA,OAAK,IAAL,GACxC,IAAW,EAAM,aAAa,SAAO,IAAQ,aAAW,EAAM,QAAQ,MAAA,OAAjC,OAAiC;CAC5E,OAAO;EACL;EACA;EACA,UACE,EAAM,aAAa,KACf,KACA,EAAM,aAAa,MAEjB,KAAY,QAEV,IAAa;CACzB;AACF;AAEA,SAAS,mBAAmB,GAAgD;CACtE,SAAS,MACb;MAAI,OAAO,KAAU,UAAU,OAAO,kBAAkB,CAAK;EAC7D,IAAI,WAAS,CAAK,KAAK,MAAM,QAAQ,EAAM,MAAM,GAC/C,OAAO,EAAM,OAAO,QACjB,MACC,WAAS,CAAI,KAAK,OAAO,EAAK,QAAS,QAC3C;EAEF,IAAI,MAAM,QAAQ,CAAK,GACrB,OAAO,EAAM,QACV,MACC,WAAS,CAAI,KAAK,OAAO,EAAK,QAAS,QAC3C;CAX2D;AAc/D;AAGA,SAAgB,2BAA2B,GAAgD;CACzF,OAAO,mBAAmB,CAAK;AACjC;AAEA,SAAS,kBAAkB,GAAoD;;CAC7E,IAAI,CAAC,WAAS,CAAK,GAAG,OAAO;CAC7B,IAAM,IAAO,aAAW,EAAM,IAAI;CAGlC,OAFK,IAEE;EAAE;EAAM,YAAA,IADG,aAAW,EAAM,SAAS,MAAA,OAAK,OAAL;CACnB,IAFP;AAGpB;AAEA,SAAS,eAAe,GAAwC;;CAC9D,IAAI,CAAC,WAAS,CAAG,GAAG,OAAO;CAC3B,IAAM,IAAK,aAAW,EAAI,EAAE,GACtB,IAAS,mBAAmB,EAAI,MAAM,GACtC,IAAS,mBAAmB,EAAI,MAAM,GACtC,IAAQ,aAAW,EAAI,KAAK,GAC5B,IAAY,aAAW,EAAI,SAAS;CAC1C,IAAI,KAAM,QAAQ,CAAC,KAAU,CAAC,KAAU,CAAC,KAAS,CAAC,GACjD,OAAO;CAET,IAAM,IAAU,wBAAwB;EACtC,YAAY,sBAAsB,EAAI,UAAU;EAChD,aAAa,EAAI;EACjB,YAAY,sBAAsB,EAAI,UAAU;EAChD,cAAc,EAAI;CACpB,CAAC,GACK,IAAU,EAAQ;CACxB,OAAO;EACL;EACA;EACA;EACA;EACA,UAAA,IAAS,aAAW,EAAI,OAAO,MAAA,OAAK,OAAL;EAC/B,aAAA,IAAY,aAAW,EAAI,UAAU,MAAA,OAAK,IAAL;EACrC,kBAAA,IAAiB,aAAW,EAAI,eAAe,MAAA,OAAK,IAAL;EAC/C,cAAA,IAAa,aAAW,EAAI,WAAW,MAAA,OAAK,OAAL;EACvC,eAAA,IAAc,aAAW,EAAI,YAAY,MAAA,OAAK,OAAL;EACzC,SAAA,IAAQ,aAAW,EAAI,MAAM,MAAA,OAAK,KAAL;EAC7B,YAAA,IAAW,aAAW,EAAI,SAAS,MAAA,OAAK,OAAL;EACnC,kBAAA,IAAiB,aAAW,EAAI,eAAe,MAAA,OAAK,OAAL;EAC/C,WAAW,eAAe,EAAI,SAAS;EACvC;EACA,YAAA,IAAW,aAAW,EAAI,SAAS,MAAA,OAAK,OAAL;EACnC,gBAAA,IAAe,EAAI,kBAAA,OAAiB,OAAjB;EACnB,cAAc,kBAAkB,EAAI,YAAY;EAChD,aAAA,IAAA,KAAA,OAAA,KAAA,IAAY,EAAS,eAAA,OAAc,OAAd;EACrB,aAAA,IAAA,KAAA,OAAA,KAAA,IAAY,EAAS,eAAA,OAAc,OAAd;EACrB,aAAa,EAAQ,SAAS,IAAI,EAAQ,KAAK,MAAW,EAAO,UAAU,IAAI;EAC/E,cAAc,EAAQ,SAAS,IAAI,EAAQ,KAAK,MAAW,EAAO,UAAU,IAAI;EAChF,aAAa,iBAAiB,EAAI,WAAW;EAC7C,iBAAiB,6BAA6B,EAAI,eAAe;CACnE;AACF;AAGA,SAAgB,uBACd,GACA,IAAQ,IACW;CACnB,IAAM,IAAS,WAAS,CAAI,IAAI,IAAO,MAEjC,KADW,MAAM,QAAA,KAAA,OAAA,KAAA,IAAQ,EAAQ,KAAK,IAAI,EAAO,QAAQ,CAAC,EAAA,CAE7D,KAAK,MAAQ,eAAe,CAAG,CAAC,CAAC,CACjC,QAAQ,MAAkC,KAAO,IAAI,CAAC,CACtD,QAAQ,MAAQ,EAAI,WAAW,MAAM;CACxC,OAAO;EAAE;EAAO,SAAS,EAAM,UAAU;CAAM;AACjD;AAGA,SAAgB,oBAAoB,GAAsC;;CACxE,IAAM,IAAO,eAAe,CAAI;CAEhC,OADK,IACE;EAAE,GAAG;EAAM,YAAA,IAAW,EAAK,cAAA,OAAa,OAAb;CAAkB,IADlC;AAEpB;AAGA,SAAgB,2BAA2B,GAAsC;CAC/E,IAAM,IAAS,WAAS,CAAI,IAAI,IAAO;CACvC,OAAO;EACL,UAAA,KAAA,OAAA,KAAA,IAAS,EAAQ,aAAY;EAC7B,YAAA,KAAA,OAAA,KAAA,IAAW,EAAQ,eAAc,MAAc,KAAA;CACjD;AACF;AAGA,SAAgB,0BAA0B,GAAqC;CAC7E,OAAO,2BAA2B,CAAI;AACxC;AAGA,SAAgB,0BAA0B,GAAqC;CAC7E,IAAM,IAAS,WAAS,CAAI,IAAI,IAAO;CACvC,OAAO,EAAE,KAAA,KAAA,OAAA,KAAA,IAAI,EAAQ,QAAO,GAAK;AACnC;;;ACvMA,SAAgB,qBAAqB,GAAqB;CACxD,OAAO,QAAQ,KAAK,CAAE;AACxB;AAEA,SAAgB,wBAAwB,GAA2B;CACjE,IAAI,CAAC,qBAAqB,CAAE,GAAG,OAAO;CACtC,IAAM,IAAQ,OAAO,CAAE;CACvB,OAAO,OAAO,SAAS,CAAK,IAAI,IAAQ;AAC1C;AAGA,SAAgB,sBAAsB,GAG1B;CACV,IAAM,IAAO,EAAM,eACb,IAAO,EAAM,QAAQ,KAAK;CAGhC,OADA,EADI,EAAK,WAAW,KAAK,CAAC,KACtB,EAAK,SAAS,OAAO,KAAK,CAAC;AAEjC;;;AC+CA,IAAM,oBAAqB,IAAI,IAAmB;CAChD;CACA;CACA;CACA;CACA;AACF,CAAC,GAEK,IAAyB,IAEzB,IAAyD;CAC7D,YAAY;CACZ,cAAc;CACd,kBAAkB;CAClB,mBAAmB;CACnB,WAAW;CACX,kBAAkB;CAClB,kBAAkB;CAClB,YAAY;CACZ,oBAAoB;AACtB;AAEA,SAAS,SAAS,GAAkD;CAClE,OAAyB,OAAO,KAAU,cAAnC,KAA+C,CAAC,MAAM,QAAQ,CAAK;AAC5E;AAEA,SAAS,WAAW,GAAoC;CACtD,OAAO,OAAO,KAAU,YAAY,EAAM,KAAK,CAAC,CAAC,SAAS,IAAI,EAAM,KAAK,IAAI,KAAA;AAC/E;AAEA,SAAS,WAAW,GAA+B;CACjD,OAAO,OAAO,KAAU,YAAY,OAAO,SAAS,CAAK,IAAI,IAAQ;AACvE;AAEA,SAAS,mBAAmB,GAA4C;CACtE,IAAM,IAAQ,WAAW,CAAG;CAS5B,OAPE,MAAU,cACV,MAAU,YACV,MAAU,aACV,MAAU,UAEH,IAEF;AACT;AAEA,SAAS,oBAAoB,GAAiE;;CAC5F,IAAM,IAAM,OAAO,KAAA,OAAU,KAAV,CAAY,CAAC,CAAC,KAAK;CAEtC,OADK,KACL,IAAO,EAAgB,OAAA,OAAQ,OAAR,IADN;AAEnB;AAEA,SAAS,uBAAuB,GAAoC;CAClE,IAAM,IAAQ,WAAW,CAAG;CAI5B,OAHI,KAAS,EAAmB,IAAI,CAAsB,IACjD,IAEF;AACT;AAEA,SAAS,oBAAoB,GAAqC;CAChE,IAAI,CAAC,SAAS,CAAG,GAAG,OAAO;CAC3B,IAAM,IAAM,WAAW,EAAI,GAAG,GACxB,IAAQ,WAAW,EAAI,KAAK,GAC5B,IAAQ,WAAW,EAAI,KAAK;CAElC,OADI,CAAC,KAAO,CAAC,KAAS,KAAS,OAAa,OACrC;EAAE;EAAK;EAAO,OAAO,KAAA,OAAS,KAAT;CAAY;AAC1C;AAEA,SAAS,mBAAmB,GAAoC;CAC9D,IAAI,CAAC,SAAS,CAAG,GAAG,OAAO;CAC3B,IAAM,IAAO,uBAAuB,EAAI,IAAI;CAC5C,IAAI,CAAC,GAAM,OAAO;CAClB,IAAM,IAAY,MAAM,QAAQ,EAAI,MAAM,IAAI,EAAI,SAAS,MACrD,IACJ,KAAa,OACT,KAAA,IACA,EACG,IAAI,mBAAmB,CAAC,CACxB,QAAQ,MAAmC,KAAS,IAAI,CAAC,CACzD,MAAM,GAAG,EAAE,GACd,IAAa,MAAM,QAAQ,EAAI,OAAO,IAAI,EAAI,UAAU,MACxD,IACJ,KAAc,OACV,KAAA,IACA,EACG,KAAK,MAAU,WAAW,CAAK,CAAC,CAAC,CACjC,QAAQ,MAA2B,EAAQ,CAAM,CAAC,CAClD,MAAM,GAAG,EAAE,GACd,IAAO,WAAW,EAAI,IAAI;CAChC,OAAO;EACL;EACA,MAAM,WAAW,EAAI,IAAI;EACzB,MAAM,WAAW,EAAI,IAAI;EACzB,MAAM,KAAA,OAAQ,KAAA,IAAR;EACN,YAAY,WAAW,EAAI,UAAU;EACrC,OAAO,WAAW,EAAI,KAAK;EAC3B,QAAQ,KAAU,EAAO,SAAS,IAAI,IAAS,KAAA;EAC/C,KAAK,WAAW,EAAI,GAAG;EACvB,SAAS,KAAW,EAAQ,SAAS,IAAI,IAAU,KAAA;CACrD;AACF;AAEA,SAAgB,oBAAoB,GAA+B;CAEjE,OADK,MAAM,QAAQ,CAAG,IACf,EACJ,IAAI,kBAAkB,CAAC,CACvB,QAAQ,MAAgC,KAAQ,IAAI,CAAC,CACrD,MAAM,GAAG,CAAC,IAJmB,CAAC;AAKnC;AAEA,SAAS,mBAAmB,GAA6B;;CACvD,OAAO;EACL,EAAK;GACL,IAAA,EAAK,SAAA,OAAQ,KAAR;GACL,IAAA,EAAK,QAAA,OAAO,KAAP;EACL,EAAK,QAAQ,OAAO,KAAK,OAAO,EAAK,IAAI;GACzC,IAAA,EAAK,SAAA,OAAQ,KAAR;GACL,IAAA,EAAK,UAAA,OAAS,KAAT;CACP,CAAC,CAAC,KAAK,GAAQ;AACjB;AAMA,SAAgB,+BACd,GACA,GACiB;CACjB,IAAM,IAAO,KAAA,OAAY,CAAC,IAAb,GACP,IAAY,KAAA,OAAS,CAAC,IAAV;CAClB,IAAI,EAAU,WAAW,GAAG,OAAO;CAEnC,IAAM,IAAO,IAAI,IAAI,EAAK,IAAI,kBAAkB,CAAC,GAC3C,IAAS,CAAC,GAAG,CAAI;CACvB,KAAK,IAAM,KAAQ,GAAW;EAC5B,IAAM,IAAM,mBAAmB,CAAI;EAC/B,EAAK,IAAI,CAAG,MAChB,EAAK,IAAI,CAAG,GACZ,EAAO,KAAK,CAAI;CAClB;CAKA,OAJI,EAAO,WAAW,EAAK,SAAe,IACtC,EAAO,SAAS,IACX,EAAO,MAAM,GAAuB,IAEtC;AACT;AAGA,SAAgB,4BACd,GACS;CAET,QADa,KAAA,OAAS,CAAC,IAAV,EAAU,CACX,MAAM,MAAS,EAAK,SAAS,OAAO;AAClD;AAEA,SAAgB,+BACd,GACQ;CAER,QADa,KAAA,OAAS,CAAC,IAAV,EAAU,CACX,QAAQ,MAAS,EAAK,SAAS,OAAO,CAAC,CAAC;AACtD;AAEA,IAAM,IAAkD;CACtD,WAAW;CACX,kBAAkB;CAClB,UAAU;CACV,MAAM;CACN,UAAU;CACV,cAAc;CACd,UAAU;AACZ,GAEM,IAAkD;CACtD,WAAW;CACX,kBAAkB;CAClB,UAAU;CACV,MAAM;CACN,UAAU;CACV,cAAc;CACd,UAAU;AACZ;AAEA,SAAS,WAAW,GAAqC;CACvD,IAAM,IAAQ,OAAO,KAAA,OAAU,KAAV,CAAY,CAAC,CAAC,YAAY;CAC/C,OAAO,CAAC,KAAS,EAAM,WAAW,IAAI;AACxC;AAGA,SAAgB,4BACd,GACA,GACQ;CACR,IAAM,IAAM,EAAM,IAAI,KAAK,GACrB,IAAQ,EAAM,MAAM,KAAK;CAW/B,QAVe,WAAW,CAAM,IAC5B,EAAwB,KACxB,EAAwB,QAGxB,MAAU,KAAO,EAAwB,KACpC,WAAW,CAAM,IACpB,EAAwB,KACxB,EAAwB,KAEvB,KAAS;AAClB;AAEA,SAAgB,sBAAsB,GAA8B;;CAClE,IAAM,IAAO,QAAA,IAAO,EAAK,SAAA,OAAQ,KAAR,CAAU;CACnC,OACE,EAAK,SAAS,eACb,EAAK,SAAS,UAAU,KACvB,EAAK,SAAS,QAAQ,KACtB,MAAS,mBACT,MAAS;AAEf;AAEA,SAAgB,4BAA4B,GAA8B;;CACxE,IAAM,IAAO,QAAA,IAAO,EAAK,SAAA,OAAQ,KAAR,CAAU;CACnC,OACE,EAAK,SAAS,eACb,EAAK,SAAS,iBAAiB,KAAK,MAAS;AAElD;AAEA,SAAgB,sBACd,GACe;CACf,IAAM,IAAO,KAAA,OAAS,CAAC,IAAV,GACP,UAAU,MAA0C;EACxD,KAAK,IAAI,IAAI,EAAK,SAAS,GAAG,KAAK,GAAG,KAAQ;;GAC5C,IAAM,IAAO,EAAK;GAClB,IAAI,CAAC,EAAM,SAAS,EAAK,IAAI,GAAG;GAChC,IAAM,MAAA,IAAO,EAAK,SAAA,OAAA,KAAA,IAAA,EAAM,KAAK,QAAA,IAAK,EAAK,UAAA,OAAA,KAAA,IAAA,EAAO,KAAK;GACnD,IAAI,GAAM,OAAO;EACnB;EACA,OAAO;CACT;CACA,OACE,OAAO,CAAC,KAAK,CAAC,KACd,OAAO,CAAC,SAAS,CAAC,KAClB,OAAO,CAAC,UAAU,CAAC,KACnB,OAAO,CAAC,SAAS,CAAC,KAClB;AAEJ;AAkBA,SAAgB,4BACd,GACyB;CACzB,IAAM,IAAO,KAAA,OAAS,CAAC,IAAV,GACP,IAAO,EAAK,QAAQ,MAAS,EAAK,SAAS,KAAK,GAChD,IAAW,EAAK,QAAQ,MAAS,EAAK,SAAS,SAAS,GACxD,IAAS,EAAK,QAAQ,MAAS,EAAK,SAAS,SAAS,EAAK,SAAS,SAAS,GAE7E,IAAkC,EAAK,KAAK,OAAU;EAAE,MAAM;EAAO;CAAK,EAAE,GAE9E,IAA4B,CAAC,GAC7B,IAAwC,MACxC,IAAoC,CAAC,GAEnC,oBAAoB;EACpB,EAAS,WAAW,MACxB,EAAO,KAAK;GAAE,MAAM;GAAe,OAAO;EAAS,CAAC,GACpD,IAAW,CAAC;CACd,GAEM,sBAAsB;EACtB,CAAC,KAAmB,EAAiB,WAAW,OAChD,KAAmB,EAAiB,SAAS,MAC/C,EAAO,KAAK;GACV,MAAM;GACN,SAAS;GACT,UAAU;EACZ,CAAC,GAEH,IAAkB,MAClB,IAAmB,CAAC;CACtB;CAEA,KAAK,IAAM,KAAQ,GAAQ;EACzB,IAAI,EAAK,SAAS,SAAS;GAEzB,AADA,cAAc,GACd,EAAS,KAAK,CAAI;GAClB;EACF;EAEA,IADA,YAAY,GACR,EAAK,SAAS,WAAW;GAE3B,AADA,cAAc,GACd,EAAO,KAAK;IAAE,MAAM;IAAW;GAAK,CAAC;GACrC;EACF;EACA,IAAI,EAAK,SAAS,YAAY;GAC5B,IAAI,sBAAsB,CAAI,GAAG;IAE/B,AADA,cAAc,GACd,IAAkB;IAClB;GACF;GACA,IAAI,4BAA4B,CAAI,GAAG;IACrC,EAAiB,KAAK,CAAI;IAC1B;GACF;GAEA,AADA,cAAc,GACd,EAAO,KAAK;IAAE,MAAM;IAAY;GAAK,CAAC;EACxC;CACF;CAEA,AADA,YAAY,GACZ,cAAc;CAEd,KAAK,IAAM,KAAQ,GACjB,EAAO,KAAK;EAAE,MAAM;EAAW;CAAK,CAAC;CAEvC,OAAO;AACT;AAEA,SAAgB,uBAAuB,GAAyC;;CAC9E,IAAI,CAAC,SAAS,CAAI,GAAG,OAAO;CAC5B,IAAM,IAAQ,WAAW,EAAK,KAAK;CACnC,IACE,MAAU,WACV,MAAU,cACV,MAAU,cACV,MAAU,YACV,MAAU,qBAEV,OAAO;CAET,IAAM,IAAc,WAAW,EAAK,WAAW,GACzC,IAAa,WAAW,EAAK,UAAU,GACvC,IAAY,WAAW,EAAK,SAAS,GACrC,KAAA,IAAS,WAAW,EAAK,MAAM,MAAA,OAAK,KAAL;CACrC,IAAI,KAAe,QAAQ,KAAc,QAAQ,CAAC,GAChD,OAAO;CAGT,IAAM,KAAA,IAAS,WAAW,EAAK,MAAM,MAAA,OAAM,EAAK,WAAW,OAAO,OAAO,KAAA,IAApC,GAC/B,KAAA,IAAW,WAAW,EAAK,QAAQ,MAAA,OAAK,OAAL,GACnC,KAAA,KAAA,IACJ,mBAAmB,EAAK,SAAS,MAAA,OACjC,oBAAoB,KAAA,OAAU,OAAV,CAAc,IADD,MACC,OAClC,sBAAsB,CAAQ,IADI,GAE9B,KAAA,IACJ,WAAW,EAAK,SAAS,MAAA,OAAM,EAAK,cAAc,OAAO,OAAO,KAAA,IAAvC,GACrB,IAAoB,EAAK,gBACzB,IACJ,KAAqB,OAAO,OAAO,oBAAoB,CAAiB;CAE1E,OAAO;EACL;EACA;EACA;EACA;EACA,iBAAA,IAAgB,WAAW,EAAK,cAAc,MAAA,OAAK,OAAL;EAC9C;EACA,QAAQ,MAAW,KAAA,IAAY,KAAA,IAAY;EAC3C;EACA,YAAY,WAAW,EAAK,UAAU;EACtC,YAAY,WAAW,EAAK,UAAU;EACtC;EACA,WAAW,MAAc,KAAA,IAAY,KAAA,IAAY;EACjD;EACA,WAAW,WAAW,EAAK,SAAS;EACpC,cAAc,WAAW,EAAK,YAAY;CAC5C;AACF;AAEA,SAAS,sBACP,GAC8B;CAC9B,IAAM,IAAQ,OAAO,KAAA,OAAY,KAAZ,CAAc,CAAC,CAAC,KAAK;CAW1C,OAVI,MAAU,cAAc,MAAU,mBAC7B,aAEL,MAAU,sBAAsB,MAAU,gBACrC,YAGL,MAAU,cAAc,MAAU,eAC7B,WAEF;AACT;AAMA,SAAgB,8BACd,GACA,GACe;CACf,IACE,KAAc,QACd,KAAc,QACd,CAAC,OAAO,SAAS,CAAU,KAC3B,CAAC,OAAO,SAAS,CAAU,KAC3B,KAAc,GAEd,OAAO;CAET,IAAM,IAAQ,KAAK,MAAM,CAAU,GAC7B,IAAQ,KAAK,MAAM,CAAU;CAYnC,OAXI,KAAS,IAAU,OAGnB,KAAS,KAAK,IAAQ,IAGpB,MAAU,IAAU,IACjB,IAGL,MAAU,IAAc,IACrB;AACT;AAGA,SAAgB,+BAA+B,GAAyB;CACtE,OAAO,WAAW,CAAM,IAAI,SAAS;AACvC;AAGA,SAAgB,6BAA6B,GAAyB;CACpE,OAAO,WAAW,CAAM,IAAI,WAAW;AACzC;AAGA,SAAgB,wBAAwB,GAAyB;CAC/D,OAAO,WAAW,CAAM,IAAI,YAAY;AAC1C;AAGA,SAAgB,uBAAuB,GAAyB;CAC9D,OAAO,WAAW,CAAM,IAAI,UAAU;AACxC;AAGA,SAAgB,+BAA+B,GAAyB;CACtE,OAAO,WAAW,CAAM,IAAI,WAAW;AACzC;AAGA,SAAgB,8BAA8B,GAAyB;CACrE,OAAO,WAAW,CAAM,IAAI,UAAU;AACxC;AAGA,SAAgB,uCAAuC,GAAyB;CAC9E,OAAO,WAAW,CAAM,IAAI,UAAU;AACxC;AAGA,SAAgB,4BAA4B,GAAyB;CACnE,OAAO,WAAW,CAAM,IAAI,cAAc;AAC5C;AAGA,SAAgB,qCAAqC,GAAyB;CAC5E,OAAO,WAAW,CAAM,IACpB,wBACA;AACN;AAOA,SAAgB,iCACd,GACA,GACe;;CAIf,IAHI,EAAM,UAAU,cAGhB,EAAM,UAAU,UAClB,OAAO;CAGT,IAAM,IAAK,WAAW,CAAM,GAEtB,KAAA,KAAA,IACJ,EAAM,cAAA,OACN,sBAAsB,EAAM,QAAQ,IAD9B,MAC8B,OACpC,UADoC;CAGtC,IAAI,EAAM,UAAU,qBAClB,OAAO,IAAK,UAAU;CAGxB,IAAI,MAAS,YACX,OAAO,IAAK,YAAY;CAG1B,IAAI,MAAS,UAAU;EACrB,IAAM,IAAe,8BACnB,EAAM,YACN,EAAM,UACR;EAMA,OALI,KAAgB,QAAQ,EAAM,cAAc,OACvC,IACH,UAAU,EAAa,GAAG,KAAK,MAAM,EAAM,UAAU,EAAE,MACvD,mBAAmB,EAAa,GAAG,KAAK,MAAM,EAAM,UAAU,EAAE,MAE/D,IAAK,YAAY;CAC1B;CAMA,OAJI,MAAS,YACJ,IAAK,YAAY,wBAGnB,IAAK,SAAS;AACvB;;;ACtlBA,IAAa,IAAqC;AAED,KAAK,MACpD,IAAqC,GACvC;AAEA,IAAM,IAAgC;AAEtC,SAAgB,+BAAuC;CACrD,OAAO;oCAC2B,EAAmC;;;AAGvE;AAEA,SAAgB,qBACd,GAC6B;CAC7B,IAAI,CAAC,KAAU,OAAO,EAAO,yBAA0B,YAAY,OAAO;CAC1E,IAAM,IAAO,EAAO,sBAAsB;CAE1C,OADI,EAAK,SAAS,KAAK,EAAK,UAAU,IAAU,OACzC;EACL,MAAM,EAAK;EACX,KAAK,EAAK;EACV,OAAO,EAAK;EACZ,QAAQ,EAAK;CACf;AACF;AAEA,SAAgB,WAAW,GAAsD;CAC/E,OAAO;EACL,GAAG,EAAK,OAAO,EAAK,QAAQ;EAC5B,GAAG,EAAK,MAAM,EAAK,SAAS;CAC9B;AACF;AAEA,IAAM,IAAmC;CACvC;CACA;CACA;AACF,GAEM,IAA8B;CAClC;CACA;CACA;AACF;AAEA,SAAS,iBAAiB,GAAgE;CACxF,IAAM,IAAsC,CAAC,GACvC,oBAAO,IAAI,IAA2B,GACtC,WAAW,MAAmD;EAC9D,CAAC,KAAQ,EAAK,IAAI,CAAI,MAC1B,EAAK,IAAI,CAAI,GACb,EAAM,KAAK,CAAI;CACjB;CAEA,IADI,OAAO,WAAa,OAAa,QAAQ,QAAQ,GACjD,GAAa;EACf,IAAM,IAAO,EAAY,YAAY;EACrC,CAAI,aAAgB,cAAc,aAAgB,aAAU,QAAQ,CAAI;CAC1E;CACA,OAAO;AACT;AAEA,SAAS,yBACP,GACA,GACoB;CACpB,KAAK,IAAM,KAAQ,iBAAiB,CAAW,GAC7C,KAAK,IAAM,KAAY,GAAW;EAChC,IAAM,IAAK,EAAK,cAAc,CAAQ;EACtC,IAAI,EAAE,aAAc,cAAc;EAClC,IAAM,IAAO,EAAG,sBAAsB;EACtC,IAAI,EAAK,QAAQ,KAAK,EAAK,SAAS,GAAG,OAAO;CAChD;CAEF,OAAO;AACT;AAGA,SAAgB,mBAAmB,GAAsD;CACvF,OAAO,yBAAyB,CAAC,sBAAsB,GAAG,CAAW;AACvE;AAGA,SAAgB,yBACd,GAC6B;CAC7B,IAAI,OAAO,WAAa,KAAa,OAAO;CAE5C,IAAM,IAAK,yBAAyB,GAAkC,CAAW;CACjF,IAAI,CAAC,GAAI,OAAO;CAChB,IAAM,IAAO,EAAG,sBAAsB;CAEtC,OADI,EAAK,SAAS,KAAK,EAAK,UAAU,IAAU,OACzC;EACL,MAAM,EAAK;EACX,KAAK,EAAK;EACV,OAAO,EAAK;EACZ,QAAQ,EAAK;CACf;AACF;AAEA,SAAgB,uBAAgC;CAI9C,OAHI,OAAO,SAAW,OAAe,OAAO,OAAO,cAAe,aACzD,KAEF,OAAO,WAAW,kCAAkC,CAAC,CAAC;AAC/D;AAGA,SAAgB,+BAA+B,GAAwB;CACrE,OAAO,OAAO,EAAI,OAAO;EACvB,UAAU;EACV,MAAM;EACN,KAAK;EACL,QAAQ;EACR,OAAO;EACP,QAAQ;EACR,QAAQ;EACR,cAAc;EACd,eAAe;EACf,YAAY;EACZ,WACE;EACF,YAAY;CACd,CAAC;AACH;AAEA,SAAS,aAAa,GAAuB;CAE3C,AADA,EAAG,UAAU,IAAI,kBAAkB,GACnC,OAAO,iBACC,EAAG,UAAU,OAAO,kBAAkB,GAC5C,GACF;AACF;AAEA,SAAS,mBAAmB,GAAwC;CAClE,IAAI,OAAO,WAAa,KAAa;CAErC,IAAM,oBAAS,IAAI,IAAiB;CACpC,KAAK,IAAM,KAAQ,iBAAiB,CAAW,GAC7C,KAAK,IAAM,KAAY,GAA6B;EAClD,IAAM,IAAK,EAAK,cAAc,CAAQ;EACtC,IAAI,EAAE,aAAc,gBAAgB,EAAO,IAAI,CAAE,GAAG;EACpD,IAAM,IAAO,EAAG,sBAAsB;EAClC,EAAK,SAAS,KAAK,EAAK,UAAU,MACtC,EAAO,IAAI,CAAE,GACb,aAAa,CAAE;CACjB;AAEJ;AAGA,SAAS,gCAAgC,GAAwC;CAC/E,IAAM,IAAS,mBAAmB,CAAW;CACxC,MACL,EAAO,UAAU,IAAI,qBAAqB,GAC1C,OAAO,iBACC,EAAO,UAAU,OAAO,qBAAqB,GACnD,IACF;AACF;AAEA,SAAS,mBAAmB,GAA8C;CAClE,aAAkB,gBACxB,EAAO,UAAU,IAAI,0BAA0B,aAAa,GAC5D,OAAO,iBAAiB,EAAO,UAAU,OAAO,aAAa,GAAG,CAAkC;AACpG;AAEA,SAAS,aACP,GACA,GACA,GACM;CACN,IAAI,OAAO,WAAa,KAAa;CAErC,IAAM,IAAQ,WAAW,CAAI,GACvB,IAAM,WAAW,CAAE,GACnB,IAAU,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,EAAI,IAAI,EAAM,CAAC,IAAI,GAAI,CAAC,GACrE,IAAM;EACV,IAAI,EAAM,IAAI,EAAI,KAAK;EACvB,GAAG,KAAK,IAAI,EAAM,GAAG,EAAI,CAAC,IAAI;CAChC,GAEM,IAAM,SAAS,cAAc,KAAK;CAIxC,AAHA,EAAI,YAAY,0BAChB,EAAI,aAAa,eAAe,MAAM,GACtC,+BAA+B,CAAG,GAClC,SAAS,KAAK,YAAY,CAAG;CAE7B,IAAM,IAAwB;EAC5B;GACE,WAAW,aAAa,EAAM,EAAE,MAAM,EAAM,EAAE;GAC9C,SAAS;EACX;EACA;GACE,WAAW,aAAa,EAAM,EAAE,MAAM,EAAM,EAAE;GAC9C,SAAS;GACT,QAAQ;EACV;EACA;GACE,WAAW,aAAa,EAAI,EAAE,MAAM,EAAI,EAAE;GAC1C,SAAS;GACT,QAAQ;EACV;EACA;GACE,WAAW,aAAa,EAAI,EAAE,MAAM,EAAI,EAAE;GAC1C,SAAS;EACX;CACF,GAEM,IAAY,EAAI,QAAQ,GAAW;EACvC,UAAU;EACV,QAAQ;EACR,MAAM;CACR,CAAC;CAMD,AAJA,EAAU,iBAAiB;EAEzB,AADA,EAAI,OAAO,GACX,EAAW;CACb,GACA,EAAU,iBAAiB;EACzB,EAAI,OAAO;CACb;AACF;AAaA,SAAgB,6BACd,GACA,GACA,GACS;CACT,IAAI,qBAAqB,GAAG,OAAO;CACnC,IAAM,IAAS,yBAAyB,CAAW;CAMnD,OALK,KAEL,mBAAmB,CAAY,GAC/B,gCAAgC,CAAW,GAC3C,aAAa,GAAY,SAAc,mBAAmB,CAAW,CAAC,GAC/D,MALa;AAMtB;;;AC9OA,SAAgB,6BAA6B,GAAiC;CAC5E,OACE,MAAU,gBACV,MAAU,cACV,MAAU,eACV,MAAU,uBACV,MAAU;AAEd;AA4BA,SAAgB,wBACd,GASuB;;CACvB,IAAM,KAAA,IAAiB,EAAI,mBAAA,OAAkB,CAAC,IAAnB,GACrB,IAAa,4BAA4B,CAAc,GACvD,IAAS,6BAA6B,EAAI,KAAK;CACrD,OAAO;EACL,OAAO,EAAI;EACX,SAAS,EAAI;EACb,kBAAkB,EAAI;EACtB,iBAAiB,EAAI;EACrB,eAAe,EAAI;EACnB;EACA;EACA,kBAAkB,+BAA+B,CAAc;EAC/D;EACA,UAAU,sBAAsB,CAAc;EAC9C,uBAAuB,KAAc;CACvC;AACF;;;ACjCA,IAAa,IAAsC,WAooBtC,IAAqB;CAChC,uBAAuB;CACvB,gBAAgB;CAChB,wBAAwB;CACxB,oBAAoB;CACpB,uBAAuB;AACzB,GAqWa,IAAgC"}
|