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
package/dist/react.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.cjs.js","names":["React"],"sources":["../src/core/lib/errors.ts","../src/core/lib/resolve.ts","../src/core/auth/auth-headers.ts","../src/core/auth/auth-response.ts","../src/core/chat/session-run.ts","../src/core/chat/chat-response.ts","../node_modules/.pnpm/zustand@5.0.15_@types+react@19.2.18_immer@11.1.18_react@19.2.8_use-sync-external-store@1.6.0_react@19.2.8_/node_modules/zustand/esm/vanilla.mjs","../node_modules/.pnpm/zustand@5.0.15_@types+react@19.2.18_immer@11.1.18_react@19.2.8_use-sync-external-store@1.6.0_react@19.2.8_/node_modules/zustand/esm/react.mjs","../node_modules/.pnpm/zustand@5.0.15_@types+react@19.2.18_immer@11.1.18_react@19.2.8_use-sync-external-store@1.6.0_react@19.2.8_/node_modules/zustand/esm/middleware.mjs","../src/core/auth/auth-bridge.ts","../src/core/auth/auth-store.ts","../src/core/auth/auth-session.ts","../src/core/auth/login-gate.ts","../src/core/extension/extension-contract.ts","../src/core/extension/auth-extension-resync.ts","../src/core/lib/events.ts","../src/core/host-tool/stream/host-tool-stream.types.ts","../src/core/host-tool/host-action.ts","../src/core/chat/chat-sse.ts","../src/core/host-tool/host-tool-registry.ts","../src/core/host-tool/host-action-registry.ts","../src/core/host-tool/host-tool-path-args.ts","../src/core/host-tool/stream/host-tool-stream-reducer.ts","../src/core/host-tool/stream/host-tool-stream-gate.ts","../src/core/host-tool/stream/host-tool-stream-round.ts","../src/core/host-tool/stream/host-tool-stream-reconcile.ts","../src/core/host-tool/stream/host-tool-stream.ts","../src/core/host-tool/register-host-tools.ts","../src/core/page/context-mention.ts","../src/core/page/context-mention-define.ts","../src/core/page/context-mention-registry.ts","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/HTTPError.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/NonError.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/ForceRetryError.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/core/constants.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/body.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/is.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/merge.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/normalize.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/TimeoutError.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/timeout.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/delay.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/options.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/type-guards.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/core/Ky.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/index.js","../src/core/http/errors.ts","../node_modules/.pnpm/eventsource-parser@3.1.1/node_modules/eventsource-parser/dist/index.js","../src/core/http/sse.ts","../src/core/http/client.ts","../src/core/services/auth.service.ts","../src/core/services/agent.service.ts","../src/core/services/chat.service.ts","../src/core/lib/api-envelope.ts","../src/core/services/feedback.service.ts","../src/core/services/host-tool.service.ts","../src/core/services/agent-run.service.ts","../src/core/page/page-context-snapshot.ts","../src/core/automation/automation-response.ts","../src/core/page/page-action-feedback-wish-response.ts","../src/core/services/page-action.service.ts","../src/core/services/automation.service.ts","../src/core/services/approval.service.ts","../src/core/services/app-tool.service.ts","../src/core/auth/auth.ts","../src/core/chat/skill-intent-alignment.ts","../src/core/page/page-action-client.ts","../src/core/page/page-action-reuse-cache.ts","../src/core/page/page-context-navigate.ts","../src/core/page/pending-page-action-apply.ts","../src/core/automation/automation-run-tracker.ts","../src/core/automation/automation-task-tab-store.ts","../src/core/page/page-action-rows.ts","../src/core/page/page-action-coordinator.ts","../src/utils/sdk-version.ts","../src/utils/id.ts","../src/core/client/instance.ts","../src/react/context.ts","../src/react/AgentChat.tsx","../src/react/AgentChatProvider.tsx","../src/react/useAgentChatClient.ts","../src/react/useAgentChat.ts","../src/react/useHostAction.ts","../src/react/page-agent-lifecycle.ts","../src/react/host-agent-registration.ts","../src/react/usePageAgent.ts","../src/core/page/page-action-row-sync.ts","../src/react/usePageActions.ts","../src/react/usePageAction.ts","../src/core/extension/omnix-extension-client.ts","../src/react/useOmnixExtension.ts","../src/react/useAppTool.ts","../src/react/useContextMentions.ts","../src/react/useAppAgent.ts"],"sourcesContent":["export type AgentChatErrorCode =\n | 'INVALID_DSN'\n | 'DSN_RESOLVE_FAILED'\n | 'INVALID_OPTIONS'\n | 'AUTH_REQUIRED'\n | 'LOGIN_FAILED'\n | 'ALREADY_INITIALIZED'\n | 'NOT_INITIALIZED'\n | 'SESSION_HANDSHAKE_FAILED'\n | 'MESSAGE_FAILED'\n | 'PAGE_ACTION_FAILED'\n | 'PAGE_ACTION_ALREADY_ACTIVE'\n | 'TRANSPORT_ABORTED'\n | 'TRANSPORT_FAILED'\n | 'PENDING_TIMEOUT'\n | 'CANCELLED'\n | 'DESTROYED';\n\nexport interface AgentChatErrorOptions {\n cause?: unknown;\n details?: Record<string, unknown>;\n}\n\n/**\n * Single error class used everywhere in the SDK. The `code` field is the\n * stable contract — it is what consumers should `switch` on. The `message`\n * is human readable and may evolve between versions.\n */\nexport class AgentChatError extends Error {\n readonly code: AgentChatErrorCode;\n readonly details?: Record<string, unknown>;\n\n constructor(code: AgentChatErrorCode, message: string, options: AgentChatErrorOptions = {}) {\n super(message);\n this.name = 'AgentChatError';\n this.code = code;\n if (options.cause !== undefined) {\n (this as { cause?: unknown }).cause = options.cause;\n }\n if (options.details !== undefined) {\n this.details = options.details;\n }\n if (typeof Object.setPrototypeOf === 'function') {\n Object.setPrototypeOf(this, AgentChatError.prototype);\n }\n }\n}\n","import { AgentChatError } from './errors';\n\nexport const DEFAULT_BASE_URL = 'http://localhost:3030';\n\n/** Header name through which the opaque DSN is forwarded as a credential. */\nexport const DSN_AUTH_HEADER = 'x-app-dsn';\n\nexport function normalizeDsn(dsn: unknown): string {\n if (typeof dsn !== 'string' || dsn.trim() === '') {\n throw new AgentChatError('INVALID_DSN', 'DSN must be a non-empty string', {\n details: { received: typeof dsn },\n });\n }\n return dsn.trim();\n}\n","import type { HttpClient } from '../http';\nimport { DSN_AUTH_HEADER } from '../lib/resolve';\n\n/** Sent on the first `/app-client/auth` call when an account token already exists. */\nexport const ACCOUNT_TOKEN_HEADER = 'x-account-token';\n\nexport const AUTHORIZATION_HEADER = 'Authorization';\n\n/** C-end client API DSN header (`AppClientDsnGuard`). */\nexport const CLIENT_DSN_HEADER = 'X-App-Dsn';\n\n/** Headers for `POST /app-client/auth` — `x-app-dsn` (+ optional `x-account-token`). */\nexport function buildAppClientAuthHeaders(\n dsn: string,\n accountToken?: string | null,\n): Record<string, string> {\n const headers: Record<string, string> = {\n [DSN_AUTH_HEADER]: dsn.trim(),\n };\n if (accountToken?.trim()) {\n headers[ACCOUNT_TOKEN_HEADER] = normalizeAccessToken(accountToken);\n }\n return headers;\n}\n\nexport function normalizeAccessToken(accessToken: string): string {\n return accessToken.trim().replace(/^Bearer\\s+/i, '');\n}\n\nexport function formatBearerToken(accessToken: string): string {\n return `Bearer ${normalizeAccessToken(accessToken)}`;\n}\n\n/**\n * Attach the access token returned by `/app-client/auth` for all subsequent API\n * calls (`/chat`, messages, etc.).\n */\nexport function applyAccessTokenHeader(http: HttpClient, accessToken: string): void {\n http.setDefaultHeader(AUTHORIZATION_HEADER, formatBearerToken(accessToken));\n}\n\nexport function clearAccessTokenHeader(http: HttpClient): void {\n http.setDefaultHeader(AUTHORIZATION_HEADER, undefined);\n}\n\n/** Headers for `/agent/*` client APIs (`X-App-Dsn` only; Bearer comes from defaults). */\nexport function buildAgentClientHeaders(dsn: string): Record<string, string> {\n return { [CLIENT_DSN_HEADER]: dsn.trim() };\n}\n","import type { AppClientAuthData } from './auth-types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object';\n}\n\n/**\n * Unwrap `{ data: T }` envelopes from the backend. Falls back to the root\n * object when no `data` key is present.\n */\nexport function unwrapApiData<T extends Record<string, unknown>>(body: unknown): T | null {\n if (!isRecord(body)) return null;\n if (isRecord(body.data)) return body.data as T;\n return body as T;\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction parseAppClient(value: unknown): AppClientAuthData['appClient'] {\n if (!isRecord(value)) return undefined;\n const id = value.id;\n const dsn = readString(value.dsn);\n const name = readString(value.name);\n if (typeof id !== 'number' || !dsn || !name) return undefined;\n return { id, dsn, name };\n}\n\nfunction parseUser(value: unknown): AppClientAuthData['user'] {\n if (!isRecord(value)) return undefined;\n const id = value.id;\n const email = readString(value.email);\n const username = readString(value.username);\n const userType = readString(value.userType);\n const userRole = readString(value.userRole);\n if (typeof id !== 'number' || !email || !username || !userType || !userRole) {\n return undefined;\n }\n return {\n id,\n employeeId: readString(value.employeeId),\n email,\n username,\n userType,\n userRole,\n mustChangePassword:\n typeof value.mustChangePassword === 'boolean' ? value.mustChangePassword : undefined,\n createdAt: readString(value.createdAt),\n };\n}\n\n/** Parse `/app-client/auth` or `/user/login` JSON into a normalized auth payload. */\nexport function parseAuthResponse(body: unknown): AppClientAuthData | null {\n const raw = unwrapApiData<Record<string, unknown>>(body);\n if (!raw) return null;\n\n const accessToken = readString(raw.accessToken);\n const ok = raw.ok === true || (raw.ok !== false && accessToken !== undefined);\n\n return {\n ok,\n accessToken,\n appClient: parseAppClient(raw.appClient),\n user: parseUser(raw.user),\n accountTokenBound:\n typeof raw.accountTokenBound === 'boolean' ? raw.accountTokenBound : undefined,\n };\n}\n","import { unwrapApiData } from '../auth/auth-response';\nimport { parseDraftReviewBundles } from '../draft-review/draft-review-bundle';\nimport { parseWriteDraftPublic } from '../draft-review/write-draft';\nimport { parseEditPolicyPublic } from '../draft-review/edit-policy';\nimport type { WriteDraftPublic } from '../draft-review/write-draft';\nimport type { EditPolicyPublic } from '../draft-review/edit-policy';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object';\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\n/** Discard agent-run SSE when the session has moved on (supersede / cancel-run). */\nexport function isStaleAgentRunEvent(\n sessionGeneration: number,\n generation?: number,\n): boolean {\n if (generation == null) return false;\n return generation < sessionGeneration;\n}\n\n/** Read `runGeneration` from `POST .../messages` or `POST /chat` bodies. */\nexport function parseRunGeneration(body: unknown): number | undefined {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return undefined;\n return readNumber(raw.runGeneration) ?? readNumber(raw.run_generation);\n}\n\nexport interface CancelRunResult {\n superseded: boolean;\n generation: number;\n cancelledRunId: number | null;\n}\n\n/** `GET /chat/:sessionId/run-state` — pending write gate (page refresh / multi-tab). */\nexport interface PendingWriteGateSnapshot {\n runId: number;\n turnId: number;\n draftRetryCount: number;\n draftRetryMax: number;\n canRetry: boolean;\n writeDraft: WriteDraftPublic | null;\n writeDrafts: WriteDraftPublic[] | null;\n editPolicy: EditPolicyPublic | null;\n editPolicies: Array<EditPolicyPublic | null> | null;\n}\n\n/** `GET /chat/:sessionId/run-state` snapshot. */\nexport interface SessionRunStateSnapshot {\n generation: number;\n activeRunId: number | null;\n activeTurnId: number | null;\n pendingJobCount: number;\n redisBacked: boolean;\n pendingWriteGate: PendingWriteGateSnapshot | null;\n}\n\nfunction parsePendingWriteGate(value: unknown): PendingWriteGateSnapshot | null {\n if (!isRecord(value)) return null;\n const runId = readNumber(value.runId);\n const turnId = readNumber(value.turnId);\n if (runId == null || turnId == null) return null;\n const draftRetryCount = readNumber(value.draftRetryCount) ?? 0;\n const draftRetryMax = readNumber(value.draftRetryMax) ?? 3;\n const canRetry =\n value.canRetry === false\n ? false\n : value.canRetry === true\n ? true\n : draftRetryCount < draftRetryMax;\n const bundles = parseDraftReviewBundles({\n writeDraft: parseWriteDraftPublic(value.writeDraft),\n writeDrafts: value.writeDrafts,\n editPolicy: parseEditPolicyPublic(value.editPolicy),\n editPolicies: value.editPolicies,\n });\n const primary = bundles[0] ?? null;\n return {\n runId,\n turnId,\n draftRetryCount,\n draftRetryMax,\n canRetry,\n writeDraft: primary?.writeDraft ?? null,\n writeDrafts: bundles.length > 1 ? bundles.map((bundle) => bundle.writeDraft) : null,\n editPolicy: primary?.editPolicy ?? null,\n editPolicies: bundles.length > 1 ? bundles.map((bundle) => bundle.editPolicy) : null,\n };\n}\n\n/** Parse `GET /chat/:sessionId/run-state` response. */\nexport function parseSessionRunState(body: unknown): SessionRunStateSnapshot | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n const generation = readNumber(raw.generation);\n if (generation == null) return null;\n const activeRunId = readNumber(raw.activeRunId) ?? readNumber(raw.active_run_id) ?? null;\n const activeTurnId = readNumber(raw.activeTurnId) ?? readNumber(raw.active_turn_id) ?? null;\n const pendingJobCount =\n readNumber(raw.pendingJobCount) ?? readNumber(raw.pending_job_count) ?? 0;\n return {\n generation,\n activeRunId,\n activeTurnId,\n pendingJobCount,\n redisBacked: raw.redisBacked === true || raw.redis_backed === true,\n pendingWriteGate:\n raw.pendingWriteGate === null\n ? null\n : parsePendingWriteGate(raw.pendingWriteGate),\n };\n}\n\n/** Parse `POST /chat/:sessionId/cancel-run` response. */\nexport function parseCancelRunResponse(body: unknown): CancelRunResult {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) {\n return { superseded: false, generation: 0, cancelledRunId: null };\n }\n const cancelledRunId = readNumber(raw.cancelledRunId) ?? readNumber(raw.cancelled_run_id) ?? null;\n return {\n superseded: raw.superseded === true,\n generation: readNumber(raw.generation) ?? 0,\n cancelledRunId,\n };\n}\n","import { unwrapApiData } from '../auth/auth-response';\nimport { parseRunGeneration } from './session-run';\nimport type {\n AutoAgentBinding,\n AutoAgentSource,\n ChatAgentSummary,\n ChatSessionSummary,\n ChatSkillSummary,\n} from '../../types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object';\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction parseSessionRow(row: unknown): ChatSessionSummary | null {\n if (!isRecord(row)) return null;\n\n const sessionId =\n readString(row.sessionId) ??\n readString(row.id) ??\n (typeof row.sessionId === 'number' ? String(row.sessionId) : undefined) ??\n (typeof row.id === 'number' ? String(row.id) : undefined);\n if (!sessionId) return null;\n\n const updatedAtRaw = row.updatedAt ?? row.updated_at ?? row.lastMessageAt;\n let updatedAt: number | undefined;\n if (typeof updatedAtRaw === 'number') {\n updatedAt = updatedAtRaw;\n } else if (updatedAtRaw !== undefined) {\n const parsed = new Date(updatedAtRaw as string | Date).getTime();\n updatedAt = Number.isFinite(parsed) ? parsed : undefined;\n }\n\n return {\n sessionId,\n title: readString(row.title) ?? readString(row.name),\n preview:\n readString(row.preview) ??\n readString(row.lastMessage) ??\n readString(row.summary),\n updatedAt,\n };\n}\n\nfunction rowsFromBody(body: unknown): unknown[] {\n if (Array.isArray(body)) return body;\n if (!isRecord(body)) return [];\n\n if (Array.isArray(body.data)) return body.data;\n\n if (isRecord(body.data)) {\n for (const key of ['sessions', 'agents', 'skills', 'list', 'items', 'records'] as const) {\n const candidate = body.data[key];\n if (Array.isArray(candidate)) return candidate;\n }\n }\n\n for (const key of ['sessions', 'agents', 'skills', 'list', 'items', 'records'] as const) {\n const candidate = body[key];\n if (Array.isArray(candidate)) return candidate;\n }\n\n return [];\n}\n\n/** Parse `GET /chat` response into sidebar session summaries. */\nexport function parseChatSessionList(body: unknown): ChatSessionSummary[] {\n return rowsFromBody(body)\n .map((row) => parseSessionRow(row))\n .filter((row): row is ChatSessionSummary => row !== null);\n}\n\nexport interface ChatSessionListPage {\n sessions: ChatSessionSummary[];\n page: number;\n size: number;\n total?: number;\n hasMore: boolean;\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 readBoolean(value: unknown): boolean | undefined {\n if (typeof value === 'boolean') return value;\n return undefined;\n}\n\nfunction metaRoot(body: unknown): Record<string, unknown> | null {\n if (!isRecord(body)) return null;\n if (isRecord(body.data)) return body.data;\n return body;\n}\n\n/** Parse paginated `GET /chat?page=&size=` response. */\nexport function parseChatSessionListPage(\n body: unknown,\n requestedPage: number,\n requestedSize: number,\n): ChatSessionListPage {\n const sessions = parseChatSessionList(body);\n const root = metaRoot(body);\n\n const page = readNumber(root?.page) ?? readNumber(root?.current) ?? requestedPage;\n const size =\n readNumber(root?.size) ?? readNumber(root?.pageSize) ?? requestedSize;\n const total = readNumber(root?.total) ?? readNumber(root?.totalCount);\n\n let hasMore =\n readBoolean(root?.hasMore) ??\n readBoolean(root?.hasNext) ??\n (total !== undefined ? page * size < total : sessions.length >= requestedSize);\n\n if (sessions.length < requestedSize) {\n hasMore = false;\n }\n\n return { sessions, page, size, total, hasMore };\n}\n\nexport interface ChatSessionDetail {\n sessionId: string;\n messages: unknown[];\n}\n\nexport interface ChatSessionDetailPage {\n sessionId: string;\n agentId?: string;\n messages: unknown[];\n page: number;\n size: number;\n total?: number;\n hasMore: boolean;\n}\n\ninterface DetailMessagesPageSlice {\n messages: unknown[];\n page?: number;\n size?: number;\n total?: number;\n totalPages?: number;\n hasMore?: boolean;\n}\n\nfunction messagesPageFromDetailRaw(raw: Record<string, unknown>): DetailMessagesPageSlice {\n const messagesField = raw.messages;\n\n if (Array.isArray(messagesField)) {\n return { messages: messagesField };\n }\n\n if (isRecord(messagesField)) {\n const messages = Array.isArray(messagesField.items)\n ? messagesField.items\n : Array.isArray(messagesField.list)\n ? messagesField.list\n : Array.isArray(messagesField.records)\n ? messagesField.records\n : [];\n\n const page = readNumber(messagesField.page) ?? readNumber(messagesField.current);\n const size =\n readNumber(messagesField.pageSize) ??\n readNumber(messagesField.size);\n const total =\n readNumber(messagesField.total) ?? readNumber(messagesField.totalCount);\n const totalPages = readNumber(messagesField.totalPages);\n\n let hasMore =\n readBoolean(messagesField.hasMore) ?? readBoolean(messagesField.hasNext);\n if (hasMore === undefined && page !== undefined && totalPages !== undefined) {\n hasMore = page < totalPages;\n }\n if (hasMore === undefined && page !== undefined && size !== undefined && total !== undefined) {\n hasMore = page * size < total;\n }\n\n return { messages, page, size, total, totalPages, hasMore };\n }\n\n for (const key of ['list', 'items', 'records'] as const) {\n const candidate = raw[key];\n if (Array.isArray(candidate)) return { messages: candidate };\n }\n\n return { messages: [] };\n}\n\nfunction resolveSessionIdFromRaw(raw: Record<string, unknown>): string | undefined {\n return (\n readString(raw.sessionId) ??\n readString(raw.id) ??\n (typeof raw.sessionId === 'number' ? String(raw.sessionId) : undefined)\n );\n}\n\nfunction readCatalogIdFromValue(value: unknown): string | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n return readString(value);\n}\n\nfunction readAutoAgentSource(value: unknown): AutoAgentSource | undefined {\n return value === 'requested' ||\n value === 'session' ||\n value === 'auto' ||\n value === 'default' ||\n value === 'fallback'\n ? value\n : undefined;\n}\n\nfunction parseAutoAgentBinding(raw: unknown): AutoAgentBinding | null {\n if (!isRecord(raw)) return null;\n const id = readCatalogIdFromValue(raw.id) ?? readCatalogIdFromValue(raw.agentId);\n if (!id) return null;\n return {\n id,\n source: readAutoAgentSource(raw.source),\n reason: readString(raw.reason) ?? null,\n };\n}\n\n/** Parse paginated `GET /chat/{sessionId}?page=&size=` response. */\nexport function parseChatSessionDetailPage(\n body: unknown,\n fallbackSessionId: string,\n requestedPage: number,\n requestedSize: number,\n): ChatSessionDetailPage | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n\n const sessionId = resolveSessionIdFromRaw(raw) ?? fallbackSessionId.trim();\n if (!sessionId) return null;\n const agentId = readCatalogIdFromValue(raw.agentId);\n\n const slice = messagesPageFromDetailRaw(raw);\n const messages = slice.messages;\n const root = metaRoot(body);\n\n const page =\n slice.page ??\n readNumber(root?.page) ??\n readNumber(root?.current) ??\n requestedPage;\n const size =\n slice.size ??\n readNumber(root?.size) ??\n readNumber(root?.pageSize) ??\n requestedSize;\n const total = slice.total ?? readNumber(root?.total) ?? readNumber(root?.totalCount);\n\n let hasMore =\n slice.hasMore ??\n readBoolean(root?.hasMore) ??\n readBoolean(root?.hasNext);\n\n if (hasMore === undefined && slice.totalPages !== undefined) {\n hasMore = page < slice.totalPages;\n }\n if (hasMore === undefined && total !== undefined) {\n hasMore = page * size < total;\n }\n if (hasMore === undefined) {\n hasMore = messages.length >= requestedSize;\n }\n\n if (messages.length < requestedSize) {\n hasMore = false;\n }\n\n return { sessionId, agentId, messages, page, size, total, hasMore };\n}\n\nexport interface CreateSessionResult {\n sessionId: string;\n agent?: AutoAgentBinding | null;\n}\n\n/** Parse `POST /chat` response (`{ data: { sessionId } }` or bare `{ sessionId }`). */\nexport function parseCreateSessionResponse(body: unknown): CreateSessionResult | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n\n const sessionId =\n readString(raw.sessionId) ??\n readString(raw.id) ??\n (typeof raw.sessionId === 'number' ? String(raw.sessionId) : undefined);\n if (!sessionId) return null;\n\n return { sessionId, agent: parseAutoAgentBinding(raw.agent) };\n}\n\nexport interface PostedMessagePayload {\n id: string | number;\n role: string;\n content: string | null;\n createdAt: string | number | Date;\n /** Session generation after this user turn was enqueued (SUPERSEDE or QUEUE). */\n runGeneration?: number;\n}\n\n/** Parse `POST /chat/{sessionId}/messages` response. */\nexport function parsePostedMessage(body: unknown): PostedMessagePayload | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n\n const idRaw = raw.id;\n if (\n idRaw === undefined ||\n idRaw === null ||\n (typeof idRaw !== 'string' && typeof idRaw !== 'number')\n ) {\n return null;\n }\n\n const role = readString(raw.role) ?? 'user';\n const content =\n typeof raw.content === 'string' ? raw.content : raw.content == null ? null : String(raw.content);\n\n const createdAt = (raw.createdAt ?? raw.created_at ?? Date.now()) as string | number | Date;\n\n const runGeneration = parseRunGeneration(raw);\n\n return { id: idRaw, role, content, createdAt, runGeneration };\n}\n\n/** Parse `GET /chat/{sessionId}` response. */\nexport function parseChatSessionDetail(body: unknown): ChatSessionDetail | null {\n const page = parseChatSessionDetailPage(body, '', 1, Number.MAX_SAFE_INTEGER);\n if (!page || !page.sessionId) return null;\n return { sessionId: page.sessionId, messages: page.messages };\n}\n\nfunction readCatalogId(\n row: Record<string, unknown>,\n ...keys: string[]\n): string | undefined {\n for (const key of keys) {\n const value = row[key];\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n const text = readString(value);\n if (text) return text;\n }\n return undefined;\n}\n\nfunction parseAgentRow(row: unknown): ChatAgentSummary | null {\n if (!isRecord(row)) return null;\n const id = readCatalogId(row, 'id', 'agentId');\n const name =\n readString(row.name) ?? readString(row.title) ?? readString(row.label);\n if (!id || !name) return null;\n return {\n id,\n name,\n description: readString(row.description) ?? readString(row.desc) ?? null,\n };\n}\n\nfunction parseSkillRow(row: unknown): ChatSkillSummary | null {\n if (!isRecord(row)) return null;\n const id = readCatalogId(row, 'id', 'skillId');\n const name =\n readString(row.name) ?? readString(row.title) ?? readString(row.label);\n if (!id || !name) return null;\n const agentId = readCatalogId(row, 'agentId', 'agent_id');\n const riskLevelRaw = readString(row.riskLevel);\n const riskLevel =\n riskLevelRaw === 'L1' || riskLevelRaw === 'L2' || riskLevelRaw === 'L3'\n ? riskLevelRaw\n : undefined;\n const toolIds = Array.isArray(row.toolIds)\n ? row.toolIds.filter((value): value is number => typeof value === 'number')\n : undefined;\n const hostToolIds = Array.isArray(row.hostToolIds)\n ? row.hostToolIds.filter((value): value is number => typeof value === 'number')\n : undefined;\n const pageMatched =\n typeof row.pageMatched === 'boolean' ? row.pageMatched : undefined;\n return {\n id,\n name,\n description: readString(row.description) ?? readString(row.desc) ?? null,\n agentId,\n capabilityKey: readString(row.capabilityKey) ?? null,\n riskLevel,\n requiresWriteConfirmation:\n typeof row.requiresWriteConfirmation === 'boolean'\n ? row.requiresWriteConfirmation\n : undefined,\n toolIds,\n hostToolIds,\n pageMatched,\n };\n}\n\n/** Parse `GET /agent/client/available` (or bare JSON array) response. */\nexport function parseAgentList(body: unknown): ChatAgentSummary[] {\n return rowsFromBody(body)\n .map((row) => parseAgentRow(row))\n .filter((row): row is ChatAgentSummary => row !== null);\n}\n\nfunction readStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === 'string' && item.trim().length > 0);\n}\n\nfunction parseDownReasonTagRow(row: unknown): { key: string; label: string } | null {\n if (!isRecord(row)) return null;\n const key = readString(row.key);\n const label = readString(row.label);\n if (!key || !label) return null;\n return { key, label };\n}\n\n/** Parse `GET /chat/feedback/down-reason-tags` `data`. */\nexport function parseDownReasonTags(data: unknown): { items: { key: string; label: string }[] } {\n if (!isRecord(data)) return { items: [] };\n const rows = Array.isArray(data.items) ? data.items : [];\n return {\n items: rows\n .map((row) => parseDownReasonTagRow(row))\n .filter((row): row is { key: string; label: string } => row !== null),\n };\n}\n\n/** Parse `MessageFeedbackView` from API `data`. */\nexport function parseMessageFeedbackView(data: unknown): {\n messageId: number;\n rating: 'up' | 'down';\n reasonTags: string[];\n comment: string | null;\n createdAt: string;\n updatedAt: string;\n} {\n if (!isRecord(data)) {\n throw new Error('Invalid message feedback payload');\n }\n const messageId = readNumber(data.messageId);\n const rating = data.rating === 'up' || data.rating === 'down' ? data.rating : null;\n const createdAt = readString(data.createdAt);\n const updatedAt = readString(data.updatedAt);\n if (messageId === undefined || !rating || !createdAt || !updatedAt) {\n throw new Error('Invalid message feedback payload');\n }\n return {\n messageId,\n rating,\n reasonTags: readStringArray(data.reasonTags),\n comment: typeof data.comment === 'string' ? data.comment : data.comment == null ? null : String(data.comment),\n createdAt,\n updatedAt,\n };\n}\n\n/** Parse `GET .../messages/feedbacks` `data`. */\nexport function parseMessageFeedbackBatch(data: unknown): {\n items: ReturnType<typeof parseMessageFeedbackView>[];\n} {\n if (!isRecord(data)) return { items: [] };\n const rows = Array.isArray(data.items) ? data.items : [];\n const items: ReturnType<typeof parseMessageFeedbackView>[] = [];\n for (const row of rows) {\n try {\n items.push(parseMessageFeedbackView(row));\n } catch {\n /* skip malformed row */\n }\n }\n return { items };\n}\n\n/** Parse `GET /agent/:agentId/skills/client` (or bare JSON array) response. */\nexport function parseSkillList(body: unknown, agentId?: string): ChatSkillSummary[] {\n const normalizedAgentId = agentId?.trim().toLowerCase();\n return rowsFromBody(body)\n .map((row) => parseSkillRow(row))\n .filter((row): row is ChatSkillSummary => row !== null)\n .filter((row) => {\n if (!normalizedAgentId) return true;\n if (!row.agentId) return true;\n return row.agentId.trim().toLowerCase() === normalizedAgentId;\n });\n}\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n","import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n","const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst shouldDispatchFromDevtools = (api) => !!api.dispatchFromDevtools && typeof api.dispatch === \"function\";\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst v8StackLineRe = /^at (?:new |async )?(.+?) \\(/;\nconst geckoStackLineRe = /^([^@]+)@/;\nfunction findCallerName(stack) {\n var _a, _b, _c;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return ((_b = v8StackLineRe.exec(callerLine)) == null ? void 0 : _b[1]) || ((_c = geckoStackLineRe.exec(callerLine)) == null ? void 0 : _c[1]);\n}\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (shouldDispatchFromDevtools(api)) {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (shouldDispatchFromDevtools(api)) {\n api.dispatch(action);\n }\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => window.localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n let hydrationVersion = 0;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n const currentVersion = ++hydrationVersion;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n if (currentVersion !== hydrationVersion) {\n return;\n }\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(get(), void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n ++hydrationVersion;\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n","import type { AuthUser } from './auth-types';\n\n/** Zustand persist key — must stay aligned with {@link useAuthStore}. */\nexport const AUTH_STORAGE_KEY = 'agent-chat-auth';\n\n/** CustomEvent name for browser-extension token sync. */\nexport const AUTH_CHANGED_EVENT = 'omnix:auth-changed';\n\nexport type OmnixAuthBridgeDetail = {\n loggedIn: boolean;\n dsn: string | null;\n accessToken: string | null;\n user: AuthUser | null;\n};\n\n/** Notify Omnix Token Sync extension (and other host listeners) on auth changes. */\nexport function notifyOmnixAuthBridge(detail: OmnixAuthBridgeDetail): void {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n window.dispatchEvent(new CustomEvent(AUTH_CHANGED_EVENT, { detail }));\n } catch {\n /* non-browser / locked-down environments */\n }\n}\n","import { create } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { AUTH_STORAGE_KEY, notifyOmnixAuthBridge } from './auth-bridge';\nimport type { AppClientAuthData, AppClientInfo, AuthUser } from './auth-types';\n\nexport { AUTH_STORAGE_KEY, AUTH_CHANGED_EVENT } from './auth-bridge';\nexport type { OmnixAuthBridgeDetail } from './auth-bridge';\n\nexport interface AuthStoreState {\n dsn: string | null;\n accessToken: string | null;\n user: AuthUser | null;\n appClient: AppClientInfo | null;\n accountTokenBound: boolean | null;\n setAuth: (dsn: string, data: AppClientAuthData) => void;\n clearAuth: () => void;\n getAccessTokenForDsn: (dsn: string) => string | null;\n}\n\nconst initialState = {\n dsn: null,\n accessToken: null,\n user: null,\n appClient: null,\n accountTokenBound: null,\n} as const;\n\nexport const useAuthStore = create<AuthStoreState>()(\n persist(\n (set, get) => ({\n ...initialState,\n setAuth(dsn, data) {\n const accessToken = data.accessToken ?? null;\n const user = data.user ?? null;\n set({\n dsn,\n accessToken,\n user,\n appClient: data.appClient ?? null,\n accountTokenBound: data.accountTokenBound ?? null,\n });\n notifyOmnixAuthBridge({\n loggedIn: Boolean(accessToken?.trim()),\n dsn,\n accessToken,\n user,\n });\n },\n clearAuth() {\n set({ ...initialState });\n notifyOmnixAuthBridge({\n loggedIn: false,\n dsn: null,\n accessToken: null,\n user: null,\n });\n },\n getAccessTokenForDsn(dsn) {\n const state = get();\n if (state.dsn === dsn && state.accessToken) return state.accessToken;\n return null;\n },\n }),\n { name: AUTH_STORAGE_KEY },\n ),\n);\n","import { AgentChatError } from '../lib/errors';\nimport { useAuthStore } from './auth-store';\n\n/** 宿主 UI / Hook 统一展示的未登录文案 */\nexport const AUTH_REQUIRED_USER_MESSAGE = '请在本页完成 Omnix 登录(SDK)';\n\n/**\n * 等待 Zustand persist 从 localStorage 恢复完成。\n * init 前必须 await,否则 reload 后会误判为未登录。\n */\nexport function waitForAuthStoreRehydration(timeoutMs = 3_000): Promise<void> {\n if (useAuthStore.persist.hasHydrated()) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, timeoutMs);\n const unsub = useAuthStore.persist.onFinishHydration(() => {\n clearTimeout(timer);\n unsub();\n resolve();\n });\n });\n}\n\n/** SDK 用户 JWT 是否对应当前 DSN(SSOT:`useAuthStore`) */\nexport function isSdkAuthenticatedForDsn(dsn: string | null | undefined): boolean {\n if (!dsn?.trim()) {\n return false;\n }\n const { dsn: storeDsn, accessToken } = useAuthStore.getState();\n return storeDsn === dsn && Boolean(accessToken?.trim());\n}\n\n/** 读取当前 DSN 对应的 accessToken(无则 null) */\nexport function getSdkAccessTokenForDsn(dsn: string): string | null {\n return useAuthStore.getState().getAccessTokenForDsn(dsn);\n}\n\n/** 命令式校验 — 未登录时同步抛 `AUTH_REQUIRED`(不走 {@link LoginGate} 挂起) */\nexport function assertSdkAuthenticatedForDsn(\n dsn: string | null | undefined,\n method = 'operation',\n): void {\n if (isSdkAuthenticatedForDsn(dsn)) {\n return;\n }\n throw new AgentChatError(\n 'AUTH_REQUIRED',\n `${AUTH_REQUIRED_USER_MESSAGE}(${method} 需要登录)`,\n );\n}\n","import { AgentChatError } from '../lib/errors';\n\nexport type PendingGateJobKind = 'init' | 'login';\n\n/** SDK 门禁挂起中的任务(等待 init 或 login) */\nexport type PendingGateJob = {\n id: string;\n label: string;\n kind: PendingGateJobKind;\n createdAt: number;\n};\n\nexport type LoginGateWaitOptions = {\n /** 用于超时 / 取消错误文案 */\n label?: string;\n timeoutMs?: number;\n signal?: AbortSignal;\n};\n\ntype LoginWaiter = {\n jobId: string;\n fulfill: () => void;\n reject: (err: AgentChatError) => void;\n dispose: () => void;\n};\n\n/**\n * 就绪门禁:未就绪时挂起 Promise;就绪谓词为真时 reconcile 唤醒等待者;destroy 时 cancelAll。\n * AgentChatClient 用两个实例分别等待 init 与 login。\n */\nexport class LoginGate {\n private waiters: LoginWaiter[] = [];\n private pendingJobs: PendingGateJob[] = [];\n private pendingSeq = 0;\n\n private readonly isReady: () => boolean;\n private readonly kind: PendingGateJobKind;\n private readonly onPendingChange?: () => void;\n\n constructor(\n isReady: () => boolean,\n kind: PendingGateJobKind,\n onPendingChange?: () => void,\n ) {\n this.isReady = isReady;\n this.kind = kind;\n this.onPendingChange = onPendingChange;\n }\n\n /** 当前挂起任务快照 */\n getPendingJobs(): PendingGateJob[] {\n return [...this.pendingJobs];\n }\n\n /** 就绪谓词为真时唤醒所有等待者(未就绪则 no-op) */\n reconcile(): void {\n if (!this.isReady() || this.waiters.length === 0) return;\n const pending = this.waiters.splice(0);\n this.pendingJobs = [];\n this.onPendingChange?.();\n for (const waiter of pending) {\n waiter.dispose();\n waiter.fulfill();\n }\n }\n\n /** 实例销毁 — 拒绝所有等待者 */\n cancelAll(message = '登录等待已取消'): void {\n if (this.waiters.length === 0) return;\n const pending = this.waiters.splice(0);\n this.pendingJobs = [];\n this.onPendingChange?.();\n const err = new AgentChatError('CANCELLED', message);\n for (const waiter of pending) {\n waiter.dispose();\n waiter.reject(err);\n }\n }\n\n /** 已就绪立即返回;否则挂起直到 reconcile / cancelAll / 超时 / signal abort */\n wait(options: LoginGateWaitOptions = {}): Promise<void> {\n const label = options.label ?? 'operation';\n const timeoutMs = options.timeoutMs ?? 300_000;\n const { signal } = options;\n\n if (this.isReady()) {\n return Promise.resolve();\n }\n\n if (signal?.aborted) {\n return Promise.reject(new AgentChatError('CANCELLED', `${label} 已取消`));\n }\n\n return new Promise<void>((resolve, reject) => {\n let disposed = false;\n this.pendingSeq += 1;\n const jobId = `gate-${this.kind}-${Date.now()}-${this.pendingSeq}`;\n const job: PendingGateJob = {\n id: jobId,\n label,\n kind: this.kind,\n createdAt: Date.now(),\n };\n this.pendingJobs.push(job);\n this.onPendingChange?.();\n\n const removeJob = () => {\n const idx = this.pendingJobs.findIndex((entry) => entry.id === jobId);\n if (idx >= 0) {\n this.pendingJobs.splice(idx, 1);\n this.onPendingChange?.();\n }\n };\n\n const dispose = () => {\n if (disposed) return;\n disposed = true;\n clearTimeout(timer);\n signal?.removeEventListener('abort', onAbort);\n const idx = this.waiters.findIndex((w) => w.jobId === jobId);\n if (idx >= 0) this.waiters.splice(idx, 1);\n removeJob();\n };\n\n const waiter: LoginWaiter = {\n jobId,\n fulfill: () => {\n dispose();\n resolve();\n },\n reject: (err: AgentChatError) => {\n dispose();\n reject(err);\n },\n dispose,\n };\n\n const timer = setTimeout(() => {\n waiter.reject(new AgentChatError(\n 'PENDING_TIMEOUT',\n `${label} 等待${this.kind === 'init' ? '初始化' : '登录'}超时(${Math.round(timeoutMs / 1000)}s)`,\n ));\n }, timeoutMs);\n\n const onAbort = () => {\n waiter.reject(new AgentChatError('CANCELLED', `${label} 已取消`));\n };\n signal?.addEventListener('abort', onAbort);\n\n this.waiters.push(waiter);\n });\n }\n\n /** 等待就绪后执行 */\n async run<T>(\n options: LoginGateWaitOptions,\n fn: () => T | Promise<T>,\n ): Promise<T> {\n await this.wait(options);\n return fn();\n }\n}\n","/**\n * SDK ↔ Omnix Token Sync 扩展 契约(SSOT)\n *\n * - **认证**:以 SDK `useAuthStore` / localStorage 为准;扩展通过 `omnix:auth-changed` 镜像\n * - **能力**:业务侧只调 SDK 封装(trackGofoWaybill 等),不直接调 chrome.runtime\n * - **插件**:只读 SDK 认证、只暴露 `window.OmnixExtension`(由 SDK 内部消费)\n * - **门禁**:PMS 同步须 SDK 已登录;GOFO 查询不依赖登录\n */\nimport { isSdkAuthenticatedForDsn } from '../auth/auth-session';\nimport { useAuthStore } from '../auth/auth-store';\n\nexport { AUTH_STORAGE_KEY, AUTH_CHANGED_EVENT } from '../auth/auth-bridge';\n\n/** 扩展注入页面 MAIN world 后派发 */\nexport const EXTENSION_READY_EVENT = 'omnix:extension-ready';\n\n/** 页面/SDK 请求 content script 重新注入 bridge(late install / 注入失败时) */\nexport const EXTENSION_BRIDGE_REQUEST_EVENT = 'omnix:request-extension-bridge';\n\n/** SDK persist 存储 key — config.json `omnixAuthStorageKey` 须与此一致 */\nexport const SDK_AUTH_STORAGE_KEY = 'agent-chat-auth';\n\n/** 扩展是否要求 SDK 已登录后才允许 PMS 等能力(任意 DSN 有 token 即视为已登录) */\nexport function isOmnixSdkAuthenticated(): boolean {\n return isSdkAuthenticatedForDsn(useAuthStore.getState().dsn);\n}\n\n/** 未登录时抛错 — SDK 调用扩展能力前必须校验 */\nexport function requireOmnixSdkAuthentication(): void {\n if (!isOmnixSdkAuthenticated()) {\n throw new Error('请先登录 Omnix');\n }\n}\n","import { notifyOmnixAuthBridge } from '../auth/auth-bridge';\nimport { useAuthStore } from '../auth/auth-store';\nimport {\n EXTENSION_BRIDGE_REQUEST_EVENT,\n EXTENSION_READY_EVENT,\n} from './extension-contract';\n\nlet extensionAuthResyncBound = false;\n\n/**\n * 插件 late-install / programmatic inject 后派发 `omnix:extension-ready` 时,\n * 让 SDK 再广播一次当前登录态,避免用户刷新页面。\n */\nexport function ensureExtensionAuthResyncListener(): void {\n if (extensionAuthResyncBound || typeof window === 'undefined') {\n return;\n }\n extensionAuthResyncBound = true;\n\n try {\n window.dispatchEvent(new CustomEvent(EXTENSION_BRIDGE_REQUEST_EVENT));\n } catch {\n /* non-browser */\n }\n\n window.addEventListener(EXTENSION_READY_EVENT, () => {\n const { dsn, accessToken, user } = useAuthStore.getState();\n notifyOmnixAuthBridge({\n loggedIn: Boolean(accessToken?.trim()),\n dsn,\n accessToken,\n user,\n });\n });\n}\n","/**\n * Tiny typed event bus.\n *\n * Design notes:\n * - `on()` returns an unsubscribe function for ergonomic teardown.\n * - Re-registering the same `(event, handler)` pair is idempotent.\n * - During `emit()` we iterate over a snapshot, so handlers added or removed\n * while a broadcast is in progress do not affect the current pass — the\n * newly added handler will fire on the *next* `emit`.\n */\nexport class EventBus<EventMap extends Record<string, unknown> = Record<string, unknown>> {\n private handlers: Map<keyof EventMap, Set<(payload: never) => void>> = new Map();\n\n on<K extends keyof EventMap>(\n event: K,\n handler: (payload: EventMap[K]) => void,\n ): () => void {\n let bucket = this.handlers.get(event);\n if (!bucket) {\n bucket = new Set();\n this.handlers.set(event, bucket);\n }\n bucket.add(handler as (payload: never) => void);\n return () => this.off(event, handler);\n }\n\n off<K extends keyof EventMap>(\n event: K,\n handler: (payload: EventMap[K]) => void,\n ): void {\n const bucket = this.handlers.get(event);\n if (!bucket) return;\n bucket.delete(handler as (payload: never) => void);\n if (bucket.size === 0) {\n this.handlers.delete(event);\n }\n }\n\n emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void {\n const bucket = this.handlers.get(event);\n if (!bucket || bucket.size === 0) return;\n const snapshot = Array.from(bucket);\n for (const handler of snapshot) {\n try {\n (handler as (payload: EventMap[K]) => void)(payload);\n } catch (err) {\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error('[agent-chat] event handler threw:', err);\n }\n }\n }\n }\n\n listenerCount<K extends keyof EventMap>(event: K): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n\n clear(): void {\n this.handlers.clear();\n }\n}\n","/**\n * Host Tool 流式 DSL 协议类型(规范 v1)。\n * 规范文档:agent-server/docs/host-tool-dsl-frontend-guide.md\n */\n\nexport const HOST_TOOL_STREAM_PROTOCOL_VERSION = 1 as const;\n\n/** 与 message SSE 对齐的流控模式。 */\nexport type HostToolStreamMode =\n | 'begin'\n | 'delta'\n | 'commit'\n | 'end'\n | 'full';\n\nexport type HostToolStreamControl = {\n mode: HostToolStreamMode;\n /** 单轮 host 流内单调递增,用于去重与排序。 */\n seq: number;\n};\n\nexport type HostToolDslSessionBegin = {\n op: 'session.begin';\n streamId: string;\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n reason?: string;\n planStepId?: string;\n runId?: number;\n turnId?: number;\n};\n\nexport type HostToolDslSessionEnd = {\n op: 'session.end';\n streamId: string;\n};\n\nexport type HostToolDslToolBegin = {\n op: 'tool.begin';\n streamId: string;\n callId: string;\n index: number;\n name: string;\n};\n\nexport type HostToolDslArgSet = {\n op: 'arg.set';\n streamId: string;\n callId: string;\n path: string;\n value: unknown;\n};\n\nexport type HostToolDslArgAppend = {\n op: 'arg.append';\n streamId: string;\n callId: string;\n path: string;\n chunk: string;\n};\n\nexport type HostToolDslToolCommit = {\n op: 'tool.commit';\n streamId: string;\n callId: string;\n};\n\nexport type HostToolDslToolFlush = {\n op: 'tool.flush';\n streamId: string;\n callId: string;\n name: string;\n args: Record<string, unknown>;\n};\n\nexport type HostToolDslOp =\n | HostToolDslSessionBegin\n | HostToolDslSessionEnd\n | HostToolDslToolBegin\n | HostToolDslArgSet\n | HostToolDslArgAppend\n | HostToolDslToolCommit\n | HostToolDslToolFlush;\n\nexport type HostActionHostToolInvocation = {\n name: string;\n args: Record<string, unknown>;\n};\n\n/** 批量快照(v0 兼容;流式轮次末尾权威帧)。 */\nexport type HostActionBatchPayload = {\n action: 'host_action';\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n hostTools: HostActionHostToolInvocation[];\n planStepId?: string;\n reason?: string;\n runId?: number;\n turnId?: number;\n generation?: number;\n};\n\n/** 流式 DSL 帧(v1)。 */\nexport type HostActionStreamPayload = {\n action: 'host_action';\n v?: typeof HOST_TOOL_STREAM_PROTOCOL_VERSION;\n stream: HostToolStreamControl;\n dsl?: HostToolDslOp;\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n hostTools?: HostActionHostToolInvocation[];\n planStepId?: string;\n reason?: string;\n runId?: number;\n turnId?: number;\n generation?: number;\n};\n\nexport type HostActionSsePayload = HostActionBatchPayload | HostActionStreamPayload;\n\n/** Per-tool streaming policy from {@link HostToolDefinition}. */\nexport type HostToolStreamConfig = {\n enabled?: boolean;\n policy?: 'stream' | 'batch';\n /** When true, registry handler runs on each arg.append / arg.set. Default false. */\n invokeOnAppend?: boolean;\n};\n\nexport function isHostActionStreamPayload(\n payload: HostActionSsePayload,\n): payload is HostActionStreamPayload {\n return (\n 'stream' in payload &&\n payload.stream != null &&\n typeof payload.stream.mode === 'string'\n );\n}\n\nexport function isHostActionBatchPayload(\n payload: HostActionSsePayload,\n): payload is HostActionBatchPayload {\n return !isHostActionStreamPayload(payload);\n}\n\nexport type HostToolStreamProfile = 'fill_stream' | 'instant';\n\n/** Detect DSL profile from accumulated ops (see host-tool-dsl-frontend-guide §2.3). */\nexport function detectHostToolStreamProfile(\n ops: Iterable<HostToolDslOp>,\n): HostToolStreamProfile {\n for (const op of ops) {\n if (op.op === 'tool.flush') return 'instant';\n }\n return 'fill_stream';\n}\n","import type { AgentChatHostAction, AgentChatHostToolCall } from '../../types';\nimport type { HostActionSsePayload, HostToolDslOp, HostToolStreamMode } from './stream/host-tool-stream.types';\nimport { isHostActionStreamPayload } from './stream/host-tool-stream.types';\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readEntity(\n value: unknown,\n): AgentChatHostAction['entity'] | undefined {\n if (!isRecord(value)) return undefined;\n const type = readString(value.type);\n const id = readString(value.id);\n if (!type && !id && Object.keys(value).length === 0) return undefined;\n return { ...value, ...(type ? { type } : {}), ...(id ? { id } : {}) };\n}\n\nfunction readMetadata(value: unknown): Record<string, unknown> | undefined {\n if (!isRecord(value)) return undefined;\n return value;\n}\n\nfunction normalizeHostToolInvocation(item: unknown): AgentChatHostToolCall | null {\n if (!isRecord(item)) return null;\n const name = readString(item.name);\n if (!name) return null;\n const args = isRecord(item.args) ? item.args : {};\n return { name, args };\n}\n\nfunction readHostTools(record: Record<string, unknown>): AgentChatHostToolCall[] {\n if (!Array.isArray(record.hostTools)) return [];\n const items: AgentChatHostToolCall[] = [];\n for (const item of record.hostTools) {\n const normalized = normalizeHostToolInvocation(item);\n if (normalized) items.push(normalized);\n }\n return items;\n}\n\nfunction readHostActionEnvelope(\n record: Record<string, unknown>,\n): Record<string, unknown> {\n if (record.hostAction && typeof record.hostAction === 'object') {\n return record.hostAction as Record<string, unknown>;\n }\n return record;\n}\n\nfunction isHostActionMarker(record: Record<string, unknown>): boolean {\n const action = readString(record.action);\n if (action === 'host_action' || action === 'host-action') return true;\n if (record.hostAction && typeof record.hostAction === 'object') return true;\n return false;\n}\n\nfunction readMessageId(\n nested: Record<string, unknown>,\n record: Record<string, unknown>,\n): string | undefined {\n return (\n readString(nested.messageId) ??\n readString(nested.message_id) ??\n readString(record.messageId) ??\n readString(record.message_id)\n );\n}\n\nfunction parseModernHostAction(record: Record<string, unknown>): AgentChatHostAction | null {\n const nested = readHostActionEnvelope(record);\n const actionField = readString(nested.action) ?? readString(record.action);\n const hasNestedHostAction =\n record.hostAction && typeof record.hostAction === 'object';\n\n if (\n actionField !== 'host_action' &&\n actionField !== 'host-action' &&\n !hasNestedHostAction\n ) {\n return null;\n }\n\n const hostTools = readHostTools(nested);\n if (hostTools.length === 0) return null;\n\n const scope = readString(nested.scope);\n if (!scope) return null;\n\n const runId = typeof nested.runId === 'number' ? nested.runId : undefined;\n const turnId = typeof nested.turnId === 'number' ? nested.turnId : undefined;\n\n return {\n action: 'host_action',\n scope,\n entity: readEntity(nested.entity),\n metadata: readMetadata(nested.metadata),\n hostTools,\n planStepId: readString(nested.planStepId),\n reason: readString(nested.reason),\n runId,\n turnId,\n messageId: readMessageId(nested, record),\n };\n}\n\n/**\n * Transitional adapter for legacy payloads that used `status: 'completed'`.\n * Remove once all agent-server instances emit the modern envelope.\n */\nfunction parseLegacyHostAction(record: Record<string, unknown>): AgentChatHostAction | null {\n const nested = readHostActionEnvelope(record);\n const status = readString(nested.status) ?? readString(record.status);\n if (status !== 'completed') return null;\n\n const withAction: Record<string, unknown> = {\n ...record,\n action: 'host_action',\n };\n if (record.hostAction && typeof record.hostAction === 'object') {\n withAction.hostAction = {\n ...(record.hostAction as Record<string, unknown>),\n action: 'host_action',\n };\n }\n return parseModernHostAction(withAction);\n}\n\n/** True when the action can be emitted and dispatched to handlers / host tools. */\nexport function isDispatchableHostAction(action: AgentChatHostAction): boolean {\n return (\n action.action === 'host_action' &&\n Boolean(action.scope?.trim()) &&\n action.hostTools.length > 0\n );\n}\n\n/**\n * Parse a backend SSE / JSON payload into a host action.\n * Requires `action: host_action`, non-empty `hostTools`, and `scope`.\n */\nexport function parseHostActionPayload(\n raw: unknown,\n): AgentChatHostAction | null {\n if (!isRecord(raw)) return null;\n const modern = parseModernHostAction(raw);\n if (modern) return modern;\n return parseLegacyHostAction(raw);\n}\n\n/** @alias {@link parseHostActionPayload} */\nexport const normalizeHostAction = parseHostActionPayload;\n\n/**\n * Parse a host_action SSE payload (v0 batch or v1 stream frame).\n * Returns null when the envelope is not a host action.\n */\nexport function parseHostActionSsePayload(raw: unknown): HostActionSsePayload | null {\n if (!isRecord(raw)) return null;\n const nested = readHostActionEnvelope(raw);\n const actionField = readString(nested.action) ?? readString(raw.action);\n const hasNestedHostAction =\n raw.hostAction && typeof raw.hostAction === 'object';\n\n if (\n actionField !== 'host_action' &&\n actionField !== 'host-action' &&\n !hasNestedHostAction\n ) {\n return null;\n }\n\n const source = nested;\n const action = readString(source.action) ?? 'host_action';\n const base = {\n action: action === 'host-action' ? 'host_action' : action,\n scope: readString(source.scope),\n entity: readEntity(source.entity),\n metadata: readMetadata(source.metadata),\n planStepId: readString(source.planStepId),\n reason: readString(source.reason),\n runId: typeof source.runId === 'number' ? source.runId : undefined,\n turnId: typeof source.turnId === 'number' ? source.turnId : undefined,\n generation:\n typeof source.generation === 'number' && Number.isFinite(source.generation)\n ? source.generation\n : undefined,\n } as HostActionSsePayload;\n\n if (isHostActionStreamPayload(source as HostActionSsePayload)) {\n const streamRaw = source.stream as Record<string, unknown> | undefined;\n const mode = streamRaw?.mode;\n const seq = streamRaw?.seq;\n const validModes: HostToolStreamMode[] = ['begin', 'delta', 'commit', 'end', 'full'];\n if (\n typeof mode !== 'string' ||\n !validModes.includes(mode as HostToolStreamMode) ||\n typeof seq !== 'number' ||\n !Number.isFinite(seq)\n ) {\n return null;\n }\n const hostTools = readHostTools(source);\n const streamPayload: HostActionSsePayload = {\n ...base,\n action: 'host_action',\n v: source.v === 1 ? 1 : undefined,\n stream: { mode: mode as HostToolStreamMode, seq },\n ...(source.dsl && typeof source.dsl === 'object'\n ? { dsl: source.dsl as HostToolDslOp }\n : {}),\n ...(hostTools.length > 0 ? { hostTools } : {}),\n };\n return streamPayload;\n }\n\n const hostTools = readHostTools(source);\n if (hostTools.length === 0) return null;\n\n return {\n ...base,\n action: 'host_action',\n hostTools,\n };\n}\n\n/** Convert v0 / full SSE payload to {@link AgentChatHostAction}. */\nexport function hostActionSseToAgentAction(\n payload: HostActionSsePayload,\n sessionId?: string,\n): AgentChatHostAction | null {\n if (isHostActionStreamPayload(payload) && payload.stream.mode !== 'full') {\n return null;\n }\n const hostTools = payload.hostTools ?? [];\n if (hostTools.length === 0) return null;\n const scope = payload.scope?.trim();\n if (!scope) return null;\n return {\n action: 'host_action',\n scope,\n entity: payload.entity as AgentChatHostAction['entity'],\n metadata: payload.metadata,\n hostTools,\n planStepId: payload.planStepId,\n reason: payload.reason,\n runId: payload.runId,\n turnId: payload.turnId,\n sessionId,\n streamPhase: 'complete',\n };\n}\n\nexport function isHostActionEnvelope(record: Record<string, unknown>): boolean {\n return (\n isHostActionMarker(readHostActionEnvelope(record)) || isHostActionMarker(record)\n );\n}\n","/**\n * Maps backend SSE events to UI actions.\n *\n * Preferred SSE events: `think` | `message` | `complete` | `error`\n * Backward compatible: `result` | `message.delta` | `message.done`\n */\n\nimport { isHostActionEnvelope, normalizeHostAction, parseHostActionSsePayload } from '../host-tool/host-action';\nimport { parseEditPolicyPublic, type EditPolicyPublic } from '../draft-review/edit-policy';\nimport { parseDraftReviewBundles } from '../draft-review/draft-review-bundle';\nimport { parseWriteDraftPublic, type WriteDraftPublic } from '../draft-review/write-draft';\nimport type { AgentChatHostAction } from '../../types';\nimport type { HostActionSsePayload } from '../host-tool/stream/host-tool-stream.types';\n\nexport interface ServerMessagePayload {\n id?: string | number;\n role?: string;\n content?: string;\n createdAt?: string | number | Date;\n}\n\nexport type SseMessageBlock = Record<string, unknown> & { type: string; id?: string };\nexport interface SseMessageBlockPatch {\n replaceId: string;\n block: SseMessageBlock;\n}\n\nexport type ChatSseUiAction =\n | {\n type: 'think';\n text: string;\n mode: 'replace' | 'append';\n messageId?: string;\n runId?: number;\n generation?: number;\n }\n | {\n type: 'result';\n text: string;\n mode: 'replace' | 'append';\n messageId?: string;\n runId?: number;\n generation?: number;\n }\n | {\n type: 'message-blocks';\n runId?: number;\n turnId?: number;\n generation?: number;\n action: 'stream' | 'patch';\n streamMode?: 'delta' | 'full' | 'patch';\n seq?: number;\n blocks?: SseMessageBlock[];\n patches?: SseMessageBlockPatch[];\n messageId?: string;\n }\n | {\n type: 'write-confirmation-required';\n runId: number;\n turnId?: number;\n message: string;\n code?: string;\n generation?: number;\n draftRetryCount?: number;\n draftRetryMax?: number;\n canRetry?: boolean;\n writeDraft?: WriteDraftPublic;\n writeDrafts?: WriteDraftPublic[];\n editPolicy?: EditPolicyPublic;\n editPolicies?: Array<EditPolicyPublic | null>;\n }\n | {\n type: 'write-confirmation-cancelled';\n runId?: number;\n turnId?: number;\n message: string;\n code?: string;\n generation?: number;\n }\n | {\n type: 'host-action';\n action?: AgentChatHostAction;\n ssePayload?: HostActionSsePayload;\n runId?: number;\n generation?: number;\n }\n | {\n type: 'complete';\n serverMessage?: ServerMessagePayload;\n messageId?: string;\n runId?: number;\n generation?: number;\n status?: string;\n reason?: string;\n }\n | {\n type: 'error';\n message: string;\n code?: string;\n runId?: number;\n generation?: number;\n }\n | { type: 'noop' };\n\nfunction tryParseJson(raw: string): unknown {\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return null;\n }\n}\n\nfunction readGeneration(parsed: Record<string, unknown> | null): number | undefined {\n if (!parsed) return undefined;\n const raw = parsed.generation ?? parsed.runGeneration ?? parsed.run_generation;\n return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;\n}\n\nfunction readRunId(parsed: Record<string, unknown> | null): number | undefined {\n if (!parsed) return undefined;\n const raw = parsed.runId ?? parsed.run_id;\n return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;\n}\n\nfunction readHostActionRunMeta(\n parsed: Record<string, unknown>,\n ssePayload: HostActionSsePayload,\n): { generation?: number; runId?: number } {\n return {\n generation: readGeneration(parsed) ?? ssePayload.generation,\n runId: readRunId(parsed) ?? ssePayload.runId,\n };\n}\n\nfunction readSseRunMeta(data: string): { generation?: number; runId?: number } {\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n return {\n generation: readGeneration(parsed),\n runId: readRunId(parsed),\n };\n}\nfunction readMessageId(data: string): string | undefined {\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n if (!parsed) return undefined;\n const raw =\n parsed.messageId ??\n parsed.message_id ??\n parsed.outputMessageId ??\n parsed.output_message_id ??\n parsed.id;\n if (raw == null) return undefined;\n return String(raw);\n}\n\nfunction readContentField(data: string): string {\n const parsed = tryParseJson(data) as { content?: string } | null;\n if (parsed?.content != null) return String(parsed.content);\n return data.trim();\n}\n\nfunction readErrorFromData(data: string): { message: string; code?: string } {\n const parsed = tryParseJson(data) as { message?: string; code?: string } | null;\n return {\n message: parsed?.message?.trim() || data.trim() || 'Stream failed',\n code: typeof parsed?.code === 'string' ? parsed.code : undefined,\n };\n}\n\nconst STREAM_APPEND_MODES = new Set([\n 'delta',\n 'stream',\n 'chunk',\n 'token',\n 'append',\n 'message.delta',\n]);\n\nfunction resolveStreamTextMode(modeRaw: string | undefined): 'replace' | 'append' {\n if (!modeRaw) return 'append';\n if (modeRaw === 'full' || modeRaw === 'replace') return 'replace';\n if (STREAM_APPEND_MODES.has(modeRaw)) return 'append';\n return 'append';\n}\n\nfunction parseThinkEnvelope(data: string): ChatSseUiAction {\n const messageId = readMessageId(data);\n const runMeta = readSseRunMeta(data);\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n if (parsed && typeof parsed === 'object') {\n const text =\n typeof parsed.content === 'string'\n ? parsed.content\n : typeof parsed.text === 'string'\n ? parsed.text\n : '';\n if (!text) return { type: 'noop' };\n const mode = resolveStreamTextMode(\n typeof parsed.mode === 'string' ? parsed.mode : undefined,\n );\n return { type: 'think', text, mode, messageId, ...runMeta };\n }\n const plain = readContentField(data);\n return plain\n ? { type: 'think', text: plain, mode: 'append', messageId, ...runMeta }\n : { type: 'noop' };\n}\n\nfunction readResultChunkText(record: Record<string, unknown>): string {\n const blocks = record.blocks;\n if (Array.isArray(blocks) && blocks.length > 0) {\n const text = blocks\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const content = (block as { content?: unknown }).content;\n return typeof content === 'string' ? content : '';\n })\n .join('');\n if (text) return text;\n }\n\n for (const key of ['output', 'content', 'text', 'delta', 'token'] as const) {\n const value = record[key];\n if (typeof value === 'string' && value.length > 0) return value;\n }\n return '';\n}\n\nfunction parseResultEnvelope(data: string): ChatSseUiAction {\n const messageId = readMessageId(data);\n const runMeta = readSseRunMeta(data);\n const outer = tryParseJson(data) as { content?: string } | null;\n const innerRaw = outer?.content ?? data;\n const inner = typeof innerRaw === 'string' ? tryParseJson(innerRaw) : innerRaw;\n\n if (inner && typeof inner === 'object') {\n const record = inner as Record<string, unknown>;\n const source = typeof record.source === 'string' ? record.source : undefined;\n const action = typeof record.action === 'string' ? record.action : undefined;\n const streamMode =\n typeof (record.stream as { mode?: unknown } | undefined)?.mode === 'string'\n ? String((record.stream as { mode?: unknown }).mode)\n : undefined;\n const chunkText = readResultChunkText(record);\n const shouldAppend =\n (action ? STREAM_APPEND_MODES.has(action) : false) ||\n (streamMode ? STREAM_APPEND_MODES.has(streamMode) : false);\n\n if (source === 'agent-run') {\n if (action === 'final') {\n if (!chunkText.trim()) return { type: 'noop' };\n return { type: 'result', text: chunkText, mode: 'replace', messageId, ...runMeta };\n }\n if (shouldAppend) {\n if (!chunkText) return { type: 'noop' };\n return { type: 'result', text: chunkText, mode: 'append', messageId, ...runMeta };\n }\n if (chunkText) {\n return { type: 'result', text: chunkText, mode: 'append', messageId, ...runMeta };\n }\n }\n\n if ((source === 'message' || nameLooksLikeMessage(record)) && chunkText) {\n return { type: 'result', text: chunkText, mode: 'append', messageId };\n }\n\n if (chunkText) {\n return {\n type: 'result',\n text: chunkText,\n mode: shouldAppend ? 'append' : 'append',\n messageId,\n };\n }\n }\n\n const plain = readContentField(data);\n if (plain) {\n return { type: 'result', text: plain, mode: 'append', messageId };\n }\n\n return { type: 'noop' };\n}\n\nfunction parseHostActionEnvelope(data: string): ChatSseUiAction {\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n if (!parsed || !isHostActionEnvelope(parsed)) return { type: 'noop' };\n const ssePayload = parseHostActionSsePayload(parsed);\n if (!ssePayload) return { type: 'noop' };\n const action = normalizeHostAction(parsed) ?? undefined;\n const runMeta = readHostActionRunMeta(parsed, ssePayload);\n return {\n type: 'host-action',\n action,\n ssePayload,\n generation: runMeta.generation,\n runId: runMeta.runId,\n };\n}\n\nfunction parseWriteConfirmationEnvelope(\n parsed: Record<string, unknown>,\n): ChatSseUiAction | null {\n const action = typeof parsed.action === 'string' ? parsed.action : undefined;\n const message =\n typeof parsed.message === 'string' ? parsed.message.trim() : '';\n const code = typeof parsed.code === 'string' ? parsed.code : undefined;\n const runId = typeof parsed.runId === 'number' ? parsed.runId : undefined;\n const turnId = typeof parsed.turnId === 'number' ? parsed.turnId : undefined;\n const generation = readGeneration(parsed);\n const draftRetryCount =\n typeof parsed.draftRetryCount === 'number' ? parsed.draftRetryCount : undefined;\n const draftRetryMax =\n typeof parsed.draftRetryMax === 'number' ? parsed.draftRetryMax : undefined;\n const canRetry = typeof parsed.canRetry === 'boolean' ? parsed.canRetry : undefined;\n const writeDraft = parseWriteDraftPublic(parsed.writeDraft) ?? undefined;\n const editPolicy = parseEditPolicyPublic(parsed.editPolicy) ?? undefined;\n const bundles = parseDraftReviewBundles({\n writeDraft,\n writeDrafts: parsed.writeDrafts,\n editPolicy,\n editPolicies: parsed.editPolicies,\n });\n\n if (action === 'confirmation_required' && runId != null && message) {\n const primary = bundles[0]?.writeDraft;\n const provenance = primary?.provenance;\n return {\n type: 'write-confirmation-required',\n runId,\n turnId,\n message,\n code,\n generation,\n draftRetryCount: draftRetryCount ?? provenance?.draftRetryCount,\n draftRetryMax: draftRetryMax ?? provenance?.draftRetryMax,\n canRetry: canRetry ?? provenance?.canRetry,\n writeDraft: primary,\n writeDrafts: bundles.length > 1 ? bundles.map((bundle) => bundle.writeDraft) : undefined,\n editPolicy: bundles[0]?.editPolicy ?? undefined,\n editPolicies:\n bundles.length > 1 ? bundles.map((bundle) => bundle.editPolicy) : undefined,\n };\n }\n if (action === 'write_confirmation_cancelled' && message) {\n return {\n type: 'write-confirmation-cancelled',\n runId,\n turnId,\n message,\n code,\n generation,\n };\n }\n return null;\n}\n\nfunction parseMessageBlocksEnvelope(data: string): ChatSseUiAction {\n const messageId = readMessageId(data);\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n if (!parsed) return parseResultEnvelope(data);\n if (parsed.source === 'message') return { type: 'noop' };\n\n if (isHostActionEnvelope(parsed)) {\n const ssePayload = parseHostActionSsePayload(parsed);\n if (!ssePayload) return { type: 'noop' };\n const hostAction = normalizeHostAction(parsed) ?? undefined;\n const runMeta = readHostActionRunMeta(parsed, ssePayload);\n return {\n type: 'host-action',\n action: hostAction,\n ssePayload,\n generation: runMeta.generation,\n runId: runMeta.runId,\n };\n }\n\n const writeAction = parseWriteConfirmationEnvelope(parsed);\n if (writeAction) return writeAction;\n\n const actionRaw = parsed.action;\n const action = actionRaw === 'patch' ? 'patch' : actionRaw === 'stream' ? 'stream' : undefined;\n if (!action) return parseResultEnvelope(data);\n\n const runId = typeof parsed.runId === 'number' ? parsed.runId : undefined;\n const turnId = typeof parsed.turnId === 'number' ? parsed.turnId : undefined;\n const generation = readGeneration(parsed);\n const stream = (parsed.stream as Record<string, unknown> | undefined) ?? undefined;\n const modeRaw = stream?.mode;\n const streamMode = modeRaw === 'delta' || modeRaw === 'full' || modeRaw === 'patch' ? modeRaw : undefined;\n const seq = typeof stream?.seq === 'number' ? stream.seq : undefined;\n const blocks = Array.isArray(parsed.blocks)\n ? parsed.blocks.filter(\n (item): item is SseMessageBlock =>\n !!item && typeof item === 'object' && typeof (item as { type?: unknown }).type === 'string',\n )\n : undefined;\n const patches = Array.isArray(parsed.patches)\n ? parsed.patches\n .map((item) => {\n if (!item || typeof item !== 'object') return null;\n const row = item as { replaceId?: unknown; block?: unknown };\n if (typeof row.replaceId !== 'string') return null;\n if (!row.block || typeof row.block !== 'object') return null;\n const block = row.block as { type?: unknown };\n if (typeof block.type !== 'string') return null;\n return { replaceId: row.replaceId, block: row.block as SseMessageBlock };\n })\n .filter((item): item is SseMessageBlockPatch => item != null)\n : undefined;\n\n return {\n type: 'message-blocks',\n action,\n runId,\n turnId,\n generation,\n streamMode,\n seq,\n blocks,\n patches,\n messageId,\n };\n}\n\nfunction nameLooksLikeMessage(record: Record<string, unknown>): boolean {\n const kind = record.type;\n if (typeof kind !== 'string') return false;\n return kind === 'message' || kind === 'result';\n}\n\n/** Map a raw SSE chunk to a UI action. */\nexport function parseChatSseEvent(event: string, data: string): ChatSseUiAction {\n const name = event.trim() || 'message';\n const messageId = readMessageId(data);\n\n switch (name) {\n case 'think':\n return parseThinkEnvelope(data);\n case 'message':\n case 'result': {\n const parsed = name === 'message' ? parseMessageBlocksEnvelope(data) : parseResultEnvelope(data);\n if (parsed.type === 'result' && !parsed.messageId && messageId) {\n return { ...parsed, messageId };\n }\n return parsed;\n }\n case 'message.delta': {\n const text = readContentField(data);\n return text ? { type: 'result', text, mode: 'append', messageId } : { type: 'noop' };\n }\n case 'complete': {\n const envelope = tryParseJson(data) as Record<string, unknown> | null;\n const parsed = envelope as ServerMessagePayload | null;\n const status = typeof envelope?.status === 'string' ? envelope.status : undefined;\n const reason = typeof envelope?.reason === 'string' ? envelope.reason : undefined;\n const generation = readGeneration(envelope);\n const runId = readRunId(envelope);\n if (parsed && (parsed.content != null || parsed.id != null || parsed.role != null)) {\n return {\n type: 'complete',\n serverMessage: parsed,\n messageId: parsed.id != null ? String(parsed.id) : messageId,\n status,\n reason,\n generation,\n runId,\n };\n }\n return { type: 'complete', messageId, status, reason, generation, runId };\n }\n case 'host_action':\n case 'host-action':\n return parseHostActionEnvelope(data);\n case 'error': {\n const err = readErrorFromData(data);\n const runMeta = readSseRunMeta(data);\n return { type: 'error', message: err.message, code: err.code, ...runMeta };\n }\n case 'message.done': {\n const parsed = tryParseJson(data) as ServerMessagePayload | null;\n return {\n type: 'complete',\n serverMessage: parsed ?? undefined,\n messageId: parsed?.id != null ? String(parsed.id) : messageId,\n };\n }\n default:\n return { type: 'noop' };\n }\n}\n","import type { AgentChatHostAction, HostToolHandler } from '../../types';\nimport type { HostToolStreamConfig } from './stream/host-tool-stream.types';\n\ntype ToolEntry = {\n handler: HostToolHandler;\n invokeOnAppend?: boolean;\n onPreview?: HostToolHandler;\n};\n\nconst toolRegistry = new Map<string, Map<string, ToolEntry>>();\nconst declaredTools = new Map<string, Set<string>>();\n\nfunction registryScope(scope: string): string {\n const trimmed = scope.trim();\n return trimmed || '*';\n}\n\nfunction registryName(name: string): string {\n const trimmed = name.trim();\n if (!trimmed) {\n throw new Error('registerHostTool: name is required');\n }\n return trimmed;\n}\n\nfunction resolveEntry(scope: string, name: string): ToolEntry | undefined {\n const toolName = registryName(name);\n const scopeKey = registryScope(scope);\n return (\n toolRegistry.get(scopeKey)?.get(toolName) ??\n toolRegistry.get('*')?.get(toolName)\n );\n}\n\nexport type RegisterHostToolMeta = {\n invokeOnAppend?: boolean;\n onPreview?: HostToolHandler;\n};\n\n/**\n * Register a local host-tool handler for a scope (use `*` for app-wide generic tools).\n */\nexport function registerHostTool(\n scope: string,\n name: string,\n handler: HostToolHandler,\n meta?: RegisterHostToolMeta,\n): void {\n const scopeKey = registryScope(scope);\n const toolName = registryName(name);\n let bucket = toolRegistry.get(scopeKey);\n if (!bucket) {\n bucket = new Map();\n toolRegistry.set(scopeKey, bucket);\n }\n bucket.set(toolName, {\n handler,\n ...(meta?.invokeOnAppend !== undefined ? { invokeOnAppend: meta.invokeOnAppend } : {}),\n ...(meta?.onPreview ? { onPreview: meta.onPreview } : {}),\n });\n}\n\n/** Remove a page-scoped handler (call on component unmount). */\nexport function unregisterHostTool(scope: string, name: string): void {\n const toolName = name.trim();\n if (!toolName) return;\n const bucket = toolRegistry.get(registryScope(scope));\n bucket?.delete(toolName);\n if (bucket && bucket.size === 0) {\n toolRegistry.delete(registryScope(scope));\n }\n}\n\nexport function unregisterHostTools(scope: string, names: string[]): void {\n for (const name of names) {\n unregisterHostTool(scope, name);\n }\n}\n\nexport function getHostToolStreamConfig(\n scope: string,\n name: string,\n): HostToolStreamConfig | undefined {\n const entry = resolveEntry(scope, name);\n if (!entry) return undefined;\n return {\n invokeOnAppend: entry.invokeOnAppend === true,\n };\n}\n\n/**\n * Run a registered host tool. Falls back from page scope to `*`. Returns false when not found.\n */\nexport async function runHostTool(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n): Promise<boolean> {\n const entry = resolveEntry(scope, name);\n if (!entry) return false;\n await entry.handler(args);\n return true;\n}\n\n/** Streaming preview callback (`invokeOnAppend: false`). */\nexport async function runHostToolPreview(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n): Promise<boolean> {\n const entry = resolveEntry(scope, name);\n if (!entry?.onPreview) return false;\n await entry.onPreview(args);\n return true;\n}\n\n/** Execute every `hostTools` entry from a host action. */\nexport async function executeHostToolsFromAction(\n action: AgentChatHostAction,\n): Promise<void> {\n if (action.action !== 'host_action') return;\n const tools = action.hostTools;\n if (!tools.length) return;\n\n const scope = registryScope(action.scope ?? '*');\n for (const tool of tools) {\n const ran = await runHostTool(scope, tool.name, tool.args);\n if (!ran && typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(\n '[agent-chat] hostTool not registered:',\n tool.name,\n '(scope:',\n scope,\n ')',\n );\n }\n }\n}\n\n/**\n * Declare host-tool metadata without a local handler (e.g. app-root sync-only tools).\n * Page scopes may still register handlers via {@link registerHostTool}.\n */\nexport function declareHostTool(scope: string, name: string): void {\n const scopeKey = registryScope(scope);\n const toolName = registryName(name);\n let bucket = declaredTools.get(scopeKey);\n if (!bucket) {\n bucket = new Set();\n declaredTools.set(scopeKey, bucket);\n }\n bucket.add(toolName);\n}\n\n/** Remove a metadata-only declaration (e.g. app-root tool on unmount). */\nexport function undeclareHostTool(scope: string, name: string): void {\n const toolName = name.trim();\n if (!toolName) return;\n const bucket = declaredTools.get(registryScope(scope));\n bucket?.delete(toolName);\n if (bucket && bucket.size === 0) {\n declaredTools.delete(registryScope(scope));\n }\n}\n\nexport function undeclareHostTools(scope: string, names: string[]): void {\n for (const name of names) {\n undeclareHostTool(scope, name);\n }\n}\n\n/** Test helper — clears all registered host tools. */\nexport function clearHostTools(): void {\n toolRegistry.clear();\n declaredTools.clear();\n}\n\n/** Whether `name` is registered under the exact scope bucket (no fallback to `*`). */\nexport function isHostToolRegisteredInScope(scope: string, name: string): boolean {\n const toolName = name.trim();\n if (!toolName) return false;\n return toolRegistry.get(registryScope(scope))?.has(toolName) ?? false;\n}\n\n/** Whether `name` is registered in the app-wide `*` scope. */\nexport function isHostToolRegisteredGlobally(name: string): boolean {\n return isHostToolRegisteredInScope('*', name);\n}\n\n/** Whether `name` was declared (metadata-only) under the exact scope bucket. */\nexport function isHostToolDeclaredInScope(scope: string, name: string): boolean {\n const toolName = name.trim();\n if (!toolName) return false;\n return declaredTools.get(registryScope(scope))?.has(toolName) ?? false;\n}\n\n/** Whether `name` was declared in the app-wide `*` scope. */\nexport function isHostToolDeclaredGlobally(name: string): boolean {\n return isHostToolDeclaredInScope('*', name);\n}\n\n/** Registered or metadata-only declaration in app-wide `*` scope. */\nexport function isHostToolKnownGlobally(name: string): boolean {\n return isHostToolRegisteredGlobally(name) || isHostToolDeclaredGlobally(name);\n}\n","import type { AgentChatHostAction } from '../../types';\nimport {\n isHostToolRegisteredGlobally,\n isHostToolRegisteredInScope,\n} from './host-tool-registry';\n\nexport type HostActionHandler = (action: AgentChatHostAction) => void | Promise<void>;\n\nconst scopedHandlers = new Map<string, Set<HostActionHandler>>();\nconst globalHandlers = new Set<HostActionHandler>();\n\nfunction addHandler(bucket: Set<HostActionHandler>, handler: HostActionHandler): () => void {\n bucket.add(handler);\n return () => {\n bucket.delete(handler);\n };\n}\n\n/**\n * Register a host-page handler for a business scope (usually `pageContext.page`).\n * Returns an unsubscribe function — call on component unmount.\n */\nexport function registerHostAction(scope: string, handler: HostActionHandler): () => void;\n/** Register a global handler (runs for every host action, after scoped handlers). */\nexport function registerHostAction(handler: HostActionHandler): () => void;\nexport function registerHostAction(\n scopeOrHandler: string | HostActionHandler,\n handler?: HostActionHandler,\n): () => void {\n if (typeof scopeOrHandler === 'function') {\n return addHandler(globalHandlers, scopeOrHandler);\n }\n if (!handler) {\n throw new Error('registerHostAction(scope, handler): handler is required');\n }\n const scope = scopeOrHandler.trim();\n if (!scope) {\n throw new Error('registerHostAction(scope, handler): scope is required');\n }\n let bucket = scopedHandlers.get(scope);\n if (!bucket) {\n bucket = new Set();\n scopedHandlers.set(scope, bucket);\n }\n const off = addHandler(bucket, handler);\n return () => {\n off();\n const current = scopedHandlers.get(scope);\n if (current && current.size === 0) {\n scopedHandlers.delete(scope);\n }\n };\n}\n\n/**\n * Dispatch a host action to registered page handlers.\n * Scoped handlers run when `action.scope` matches; global handlers always run.\n */\nexport async function dispatchHostAction(action: AgentChatHostAction): Promise<void> {\n if (action.action !== 'host_action') return;\n if (action.streamPhase === 'streaming') return;\n if (!action.hostTools.length) return;\n\n const scope = action.scope?.trim();\n if (!scope) return;\n\n const tasks: Array<void | Promise<void>> = [];\n\n const bucket = scopedHandlers.get(scope);\n if (bucket?.size) {\n for (const handler of bucket) {\n tasks.push(handler(action));\n }\n } else {\n const hasLocalToolHandlers = action.hostTools.some(\n (tool) =>\n isHostToolRegisteredInScope(scope, tool.name) ||\n isHostToolRegisteredGlobally(tool.name),\n );\n if (\n !hasLocalToolHandlers &&\n typeof console !== 'undefined' &&\n typeof console.warn === 'function'\n ) {\n console.warn('[agent-chat] hostAction: no handler registered for scope:', scope);\n }\n }\n\n for (const handler of globalHandlers) {\n tasks.push(handler(action));\n }\n\n await Promise.all(tasks);\n}\n\n/** Alias of {@link registerHostAction} — listen for host actions by scope. */\nexport const onHostAction = registerHostAction;\n\n/** Test helper — clears all registered handlers. */\nexport function clearHostActionHandlers(): void {\n scopedHandlers.clear();\n globalHandlers.clear();\n}\n","/** 点路径写入,如 `payload.body` → nested object */\nexport function setByDotPath(\n root: Record<string, unknown>,\n path: string,\n value: unknown,\n): Record<string, unknown> {\n const segments = path.split('.').filter(Boolean);\n if (segments.length === 0) return root;\n let cursor: Record<string, unknown> = root;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const key = segments[i]!;\n const next = cursor[key];\n if (next == null || typeof next !== 'object' || Array.isArray(next)) {\n cursor[key] = {};\n }\n cursor = cursor[key] as Record<string, unknown>;\n }\n cursor[segments[segments.length - 1]!] = value;\n return root;\n}\n\n/** 点路径字符串追加;路径不存在视为 \"\" */\nexport function appendByDotPath(\n root: Record<string, unknown>,\n path: string,\n chunk: string,\n): Record<string, unknown> {\n const segments = path.split('.').filter(Boolean);\n if (segments.length === 0) return root;\n let cursor: Record<string, unknown> = root;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const key = segments[i]!;\n const next = cursor[key];\n if (next == null || typeof next !== 'object' || Array.isArray(next)) {\n cursor[key] = {};\n }\n cursor = cursor[key] as Record<string, unknown>;\n }\n const leaf = segments[segments.length - 1]!;\n const prev = cursor[leaf];\n const base = typeof prev === 'string' ? prev : '';\n cursor[leaf] = base + chunk;\n return root;\n}\n\nexport function getByDotPath(root: Record<string, unknown>, path: string): unknown {\n const segments = path.split('.').filter(Boolean);\n let current: unknown = root;\n for (const seg of segments) {\n if (current == null || typeof current !== 'object' || Array.isArray(current)) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[seg];\n }\n return current;\n}\n","import type {\n HostActionHostToolInvocation,\n HostActionSsePayload,\n HostActionStreamPayload,\n HostToolDslOp,\n HostToolStreamConfig,\n} from './host-tool-stream.types';\nimport { isHostActionStreamPayload } from './host-tool-stream.types';\nimport { appendByDotPath, setByDotPath } from '../host-tool-path-args';\nimport type { StreamSessionGate } from './host-tool-stream-gate';\n\nexport type CallAccumulator = {\n name: string;\n index: number;\n args: Record<string, unknown>;\n committed: boolean;\n flushed: boolean;\n};\n\nexport type HostToolStreamSession = {\n streamId: string;\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n reason?: string;\n planStepId?: string;\n runId?: number;\n turnId?: number;\n calls: Map<string, CallAccumulator>;\n ended: boolean;\n lastSeq: number;\n};\n\nexport type HostToolStreamReducerState = {\n session: HostToolStreamSession | null;\n authoritative: HostActionHostToolInvocation[] | null;\n /** Last streamId finalized via `stream.mode: full` — dedupe replay full frames. */\n finalizedStreamId: string | null;\n /** Fingerprint of last `full` when `streamId` is absent (SSE replay). */\n finalizedFullFingerprint: string | null;\n};\n\nexport type HostActionSseMeta = {\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n reason?: string;\n planStepId?: string;\n runId?: number;\n turnId?: number;\n};\n\nexport type HostToolStreamEffect =\n | { type: 'round-start'; streamId: string; meta: HostActionSseMeta }\n | {\n type: 'tool-start';\n streamId: string;\n callId: string;\n name: string;\n meta: HostActionSseMeta;\n }\n | {\n type: 'preview';\n callId: string;\n name: string;\n args: Record<string, unknown>;\n invokeHandler: boolean;\n meta: HostActionSseMeta;\n }\n | { type: 'session-ended'; streamId: string; meta: HostActionSseMeta }\n | { type: 'batch'; payload: HostActionHostToolInvocation[]; reason?: string; meta: HostActionSseMeta }\n | {\n type: 'reconcile';\n payload: HostActionHostToolInvocation[];\n meta: HostActionSseMeta;\n sessionCalls?: Map<string, CallAccumulator>;\n }\n | { type: 'warn'; message: string };\n\nexport type HostToolStreamReducerOptions = {\n getStreamConfig?: (toolName: string) => HostToolStreamConfig | undefined;\n onEffect?: (effect: HostToolStreamEffect) => void;\n};\n\nexport function createInitialHostToolStreamState(): HostToolStreamReducerState {\n return {\n session: null,\n authoritative: null,\n finalizedStreamId: null,\n finalizedFullFingerprint: null,\n };\n}\n\nfunction computeFullFingerprint(\n payload: HostActionStreamPayload,\n tools: HostActionHostToolInvocation[],\n): string | null {\n if (!tools.length) return null;\n const toolSig = tools\n .map((tool) => `${tool.name}:${JSON.stringify(tool.args)}`)\n .join(';');\n return [\n payload.runId ?? '',\n payload.turnId ?? '',\n payload.planStepId ?? '',\n payload.reason ?? '',\n toolSig,\n ].join('|');\n}\n\nfunction isDuplicateFullFrame(\n state: HostToolStreamReducerState,\n streamId: string | undefined,\n fingerprint: string | null,\n hasActiveSession: boolean,\n): boolean {\n if (hasActiveSession) return false;\n if (streamId && state.finalizedStreamId === streamId) return true;\n if (fingerprint && state.finalizedFullFingerprint === fingerprint) return true;\n return false;\n}\n\nfunction readSseMeta(payload: HostActionSsePayload): HostActionSseMeta {\n return {\n scope: payload.scope,\n entity: payload.entity,\n metadata: payload.metadata,\n reason: payload.reason,\n planStepId: payload.planStepId,\n runId: payload.runId,\n turnId: payload.turnId,\n };\n}\n\nfunction readSessionMeta(session: HostToolStreamSession): HostActionSseMeta {\n return {\n scope: session.scope,\n entity: session.entity,\n metadata: session.metadata,\n reason: session.reason,\n planStepId: session.planStepId,\n runId: session.runId,\n turnId: session.turnId,\n };\n}\n\nfunction ensureCall(\n session: HostToolStreamSession,\n callId: string,\n seed?: Partial<CallAccumulator>,\n): CallAccumulator {\n let call = session.calls.get(callId);\n if (!call) {\n call = {\n name: seed?.name ?? '',\n index: seed?.index ?? session.calls.size,\n args: {},\n committed: false,\n flushed: false,\n };\n session.calls.set(callId, call);\n }\n if (seed?.name) call.name = seed.name;\n if (seed?.index != null) call.index = seed.index;\n return call;\n}\n\nfunction shouldInvokeOnAppend(\n toolName: string,\n opts: HostToolStreamReducerOptions,\n): boolean {\n return opts.getStreamConfig?.(toolName)?.invokeOnAppend === true;\n}\n\nfunction emitPreview(\n session: HostToolStreamSession,\n callId: string,\n opts: HostToolStreamReducerOptions,\n): void {\n const call = session.calls.get(callId);\n if (!call?.name) return;\n opts.onEffect?.({\n type: 'preview',\n callId,\n name: call.name,\n args: { ...call.args },\n invokeHandler: shouldInvokeOnAppend(call.name, opts),\n meta: readSessionMeta(session),\n });\n}\n\nfunction applyDslOp(\n session: HostToolStreamSession,\n dsl: HostToolDslOp,\n opts: HostToolStreamReducerOptions,\n): void {\n switch (dsl.op) {\n case 'session.begin':\n break;\n case 'session.end':\n if (session.streamId === dsl.streamId) {\n session.ended = true;\n opts.onEffect?.({\n type: 'session-ended',\n streamId: session.streamId,\n meta: readSessionMeta(session),\n });\n }\n break;\n case 'tool.begin': {\n if (dsl.streamId !== session.streamId) return;\n ensureCall(session, dsl.callId, { name: dsl.name, index: dsl.index });\n opts.onEffect?.({\n type: 'tool-start',\n streamId: session.streamId,\n callId: dsl.callId,\n name: dsl.name,\n meta: readSessionMeta(session),\n });\n break;\n }\n case 'arg.set': {\n if (dsl.streamId !== session.streamId) return;\n const call = ensureCall(session, dsl.callId);\n setByDotPath(call.args, dsl.path, dsl.value);\n emitPreview(session, dsl.callId, opts);\n break;\n }\n case 'arg.append': {\n if (dsl.streamId !== session.streamId) return;\n const call = ensureCall(session, dsl.callId);\n appendByDotPath(call.args, dsl.path, dsl.chunk);\n emitPreview(session, dsl.callId, opts);\n break;\n }\n case 'tool.commit': {\n if (dsl.streamId !== session.streamId) return;\n const call = ensureCall(session, dsl.callId);\n call.committed = true;\n break;\n }\n case 'tool.flush': {\n if (dsl.streamId !== session.streamId) return;\n const call = ensureCall(session, dsl.callId, {\n name: dsl.name,\n index: session.calls.size,\n });\n call.args = { ...dsl.args };\n call.flushed = true;\n break;\n }\n default:\n break;\n }\n}\n\nfunction readFrameStreamId(dsl?: HostToolDslOp): string | undefined {\n if (!dsl || !('streamId' in dsl)) return undefined;\n const id = dsl.streamId;\n return typeof id === 'string' && id.trim() ? id.trim() : undefined;\n}\n\nfunction isIdempotentSessionEnd(\n stream: HostActionStreamPayload['stream'],\n dsl: HostToolDslOp | undefined,\n session: HostToolStreamSession,\n): boolean {\n return (\n stream.mode === 'end' &&\n dsl?.op === 'session.end' &&\n dsl.streamId === session.streamId\n );\n}\n\nfunction handleStreamPayload(\n state: HostToolStreamReducerState,\n payload: HostActionStreamPayload,\n opts: HostToolStreamReducerOptions,\n): HostToolStreamReducerState {\n const { stream, dsl } = payload;\n const seq = stream.seq;\n\n if (stream.mode === 'begin' && dsl?.op === 'session.begin') {\n if (state.session && !state.session.ended) {\n opts.onEffect?.({\n type: 'warn',\n message: `host_tool stream: session.begin while stream ${state.session.streamId} is still active`,\n });\n }\n const session: HostToolStreamSession = {\n streamId: dsl.streamId,\n scope: dsl.scope ?? payload.scope,\n entity: dsl.entity ?? payload.entity,\n metadata: dsl.metadata ?? payload.metadata,\n reason: dsl.reason ?? payload.reason,\n planStepId: dsl.planStepId ?? payload.planStepId,\n runId: dsl.runId ?? payload.runId,\n turnId: dsl.turnId ?? payload.turnId,\n calls: new Map(),\n ended: false,\n lastSeq: seq,\n };\n opts.onEffect?.({\n type: 'round-start',\n streamId: session.streamId,\n meta: readSessionMeta(session),\n });\n return {\n session,\n authoritative: null,\n finalizedStreamId: null,\n finalizedFullFingerprint: null,\n };\n }\n\n const next: HostToolStreamReducerState = {\n ...state,\n session: state.session ? { ...state.session, calls: new Map(state.session.calls) } : null,\n };\n\n if (stream.mode === 'full') {\n const streamId = next.session?.streamId ?? readFrameStreamId(dsl);\n const tools = payload.hostTools ?? [];\n const fingerprint = computeFullFingerprint(payload, tools);\n if (isDuplicateFullFrame(state, streamId, fingerprint, Boolean(next.session))) {\n return state;\n }\n if (next.session && seq <= next.session.lastSeq) {\n return state;\n }\n const meta = readSseMeta(payload);\n const sessionCalls = next.session?.calls\n ? new Map(next.session.calls)\n : undefined;\n opts.onEffect?.({ type: 'reconcile', payload: tools, meta, sessionCalls });\n return {\n session: null,\n authoritative: tools,\n finalizedStreamId: streamId ?? state.finalizedStreamId,\n finalizedFullFingerprint: fingerprint ?? state.finalizedFullFingerprint,\n };\n }\n\n if (!next.session) {\n opts.onEffect?.({\n type: 'warn',\n message: `host_tool stream delta before session.begin (seq=${seq})`,\n });\n return state;\n }\n\n const frameStreamId = readFrameStreamId(dsl);\n if (frameStreamId && frameStreamId !== next.session.streamId) {\n opts.onEffect?.({\n type: 'warn',\n message: `host_tool stream streamId mismatch (frame=${frameStreamId}, session=${next.session.streamId}, seq=${seq})`,\n });\n return state;\n }\n\n if (seq <= next.session.lastSeq) {\n return state;\n }\n\n if (next.session.ended && !isIdempotentSessionEnd(stream, dsl, next.session)) {\n opts.onEffect?.({\n type: 'warn',\n message: `host_tool stream frame after session.end (mode=${stream.mode}, seq=${seq})`,\n });\n return state;\n }\n\n next.session = { ...next.session, lastSeq: seq };\n\n if (dsl) {\n applyDslOp(next.session, dsl, opts);\n }\n\n return next;\n}\n\n/** 主入口:处理单帧 host_action SSE payload。 */\nexport function reduceHostToolStream(\n state: HostToolStreamReducerState,\n payload: HostActionSsePayload,\n opts: HostToolStreamReducerOptions = {},\n): HostToolStreamReducerState {\n if (!isHostActionStreamPayload(payload)) {\n const batch = payload.hostTools ?? [];\n const meta = readSseMeta(payload);\n opts.onEffect?.({ type: 'batch', payload: batch, reason: payload.reason, meta });\n return {\n session: null,\n authoritative: batch,\n finalizedStreamId: null,\n finalizedFullFingerprint: null,\n };\n }\n\n return handleStreamPayload(state, payload, opts);\n}\n\nexport function toStreamSessionGate(\n session: HostToolStreamSession | null,\n): StreamSessionGate {\n if (!session) return null;\n return {\n streamId: session.streamId,\n scope: session.scope,\n entity: session.entity,\n ended: session.ended,\n };\n}\n","import type { HostActionSsePayload, HostActionStreamPayload } from './host-tool-stream.types';\nimport { isHostActionStreamPayload } from './host-tool-stream.types';\n\nexport type PageContextGate = {\n page?: string;\n entity?: { type?: string; id?: string | number };\n};\n\n/** Snapshot of the in-flight DSL session used for mid-stream / post-end gating. */\nexport type StreamSessionGate = {\n streamId: string;\n scope?: string;\n entity?: Record<string, unknown>;\n ended: boolean;\n} | null;\n\nexport type StreamIngestContext = {\n page: PageContextGate;\n streamSession: StreamSessionGate;\n};\n\nfunction entityIdsMatch(\n payloadId: unknown,\n ctxId: string | number | undefined,\n): boolean {\n if (payloadId == null || ctxId == null) return true;\n return String(payloadId) === String(ctxId);\n}\n\nfunction scopeMatches(payloadScope: string | undefined, page: string | undefined): boolean {\n const scope = payloadScope?.trim();\n const ctxPage = page?.trim();\n if (!scope || !ctxPage) return true;\n return scope === ctxPage;\n}\n\nfunction gateScopeEntity(\n scope: string | undefined,\n entity: Record<string, unknown> | undefined,\n page: PageContextGate,\n): boolean {\n return (\n scopeMatches(scope, page.page) &&\n entityIdsMatch(entity?.id, page.entity?.id)\n );\n}\n\n/**\n * Gate for v0 batch / full frames — requires non-empty hostTools when not mid-stream.\n */\nexport function passesHostActionGate(\n payload: HostActionSsePayload,\n page: PageContextGate,\n): boolean {\n if (payload.action !== 'host_action') return false;\n\n const scope = payload.scope ?? undefined;\n const entity = payload.entity;\n\n if (!gateScopeEntity(scope, entity, page)) return false;\n\n if (\n (!isHostActionStreamPayload(payload) || payload.stream.mode === 'full') &&\n (!payload.hostTools || payload.hostTools.length === 0)\n ) {\n return false;\n }\n\n return true;\n}\n\nfunction resolveFullFrameGate(\n payload: HostActionStreamPayload,\n streamSession: StreamSessionGate,\n page: PageContextGate,\n): boolean {\n const scope = payload.scope ?? streamSession?.scope;\n const entity = payload.entity ?? streamSession?.entity;\n if (!gateScopeEntity(scope, entity, page)) return false;\n return Boolean(payload.hostTools?.length);\n}\n\n/**\n * Whether to ingest a host_action SSE frame.\n * Mid-stream frames may omit top-level scope when a reducer session is active.\n * After `session.end`, only `full` (and idempotent `session.end`) are accepted.\n */\nexport function shouldIngestHostActionStreamFrame(\n payload: HostActionSsePayload,\n ctx: StreamIngestContext,\n): boolean {\n const { page, streamSession } = ctx;\n\n if (!isHostActionStreamPayload(payload)) {\n return passesHostActionGate(payload, page);\n }\n\n const { stream, dsl } = payload;\n\n if (stream.mode === 'full') {\n return resolveFullFrameGate(payload, streamSession, page);\n }\n\n if (stream.mode === 'begin' && dsl?.op === 'session.begin') {\n return gateScopeEntity(\n dsl.scope ?? payload.scope,\n dsl.entity ?? payload.entity,\n page,\n );\n }\n\n if (streamSession) {\n if (streamSession.ended) {\n return stream.mode === 'end' && dsl?.op === 'session.end';\n }\n return true;\n }\n\n return gateScopeEntity(payload.scope, payload.entity, page);\n}\n","/**\n * Tracks which tool calls were already executed in the current DSL stream round.\n * Lifecycle: {@link begin} → mark on invokeOnAppend preview → {@link finalize} at full/v0.\n */\nexport class HostToolStreamRound {\n private executedCallIds = new Set<string>();\n\n begin(): void {\n this.executedCallIds.clear();\n }\n\n has(callId: string): boolean {\n return this.executedCallIds.has(callId);\n }\n\n mark(callId: string): void {\n this.executedCallIds.add(callId);\n }\n\n /**\n * Snapshot executed callIds for async batch finalize, then start a fresh round tracker.\n */\n finalize(): ReadonlySet<string> {\n const snapshot = new Set(this.executedCallIds);\n this.executedCallIds.clear();\n return snapshot;\n }\n\n reset(): void {\n this.executedCallIds.clear();\n }\n}\n","import type { HostActionHostToolInvocation } from './host-tool-stream.types';\nimport type { CallAccumulator } from './host-tool-stream-reducer';\nimport { runHostTool } from '../host-tool-registry';\n\nexport type HostToolInvocation = HostActionHostToolInvocation;\n\nexport type BatchRunPlan = {\n tool: HostToolInvocation;\n callId?: string;\n skip: boolean;\n};\n\nfunction orderedCallEntries(\n sessionCalls: Map<string, CallAccumulator>,\n): Array<[string, CallAccumulator]> {\n return [...sessionCalls.entries()].sort(([, a], [, b]) => a.index - b.index);\n}\n\n/** Align authoritative `hostTools[]` with DSL call order for deduped finalize. */\nexport function planBatchExecution(\n tools: HostToolInvocation[],\n sessionCalls: Map<string, CallAccumulator> | undefined,\n executedCallIds: ReadonlySet<string>,\n): BatchRunPlan[] {\n if (!sessionCalls || sessionCalls.size === 0) {\n return tools.map((tool) => ({ tool, skip: false }));\n }\n\n const ordered = orderedCallEntries(sessionCalls);\n const plans: BatchRunPlan[] = [];\n\n for (let i = 0; i < tools.length; i += 1) {\n const tool = tools[i]!;\n const entry = ordered[i];\n if (!entry) {\n plans.push({ tool, skip: false });\n continue;\n }\n const [callId] = entry;\n plans.push({\n tool,\n callId,\n skip: executedCallIds.has(callId),\n });\n }\n\n return plans;\n}\n\nfunction shallowEqualArgs(\n a: Record<string, unknown>,\n b: Record<string, unknown>,\n): boolean {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (JSON.stringify(a[key]) !== JSON.stringify(b[key])) return false;\n }\n return true;\n}\n\n/** Debug helper — compare DSL accumulator vs authoritative full snapshot. */\nexport function warnAccumulatorMismatch(\n tools: HostToolInvocation[],\n sessionCalls: Map<string, CallAccumulator> | undefined,\n debug?: boolean,\n): void {\n if (!debug || !sessionCalls?.size || typeof console === 'undefined') return;\n\n const ordered = orderedCallEntries(sessionCalls);\n if (tools.length !== ordered.length) {\n console.warn(\n '[agent-chat] host_tool stream: full hostTools length',\n tools.length,\n '≠ DSL calls',\n ordered.length,\n );\n return;\n }\n\n for (let i = 0; i < tools.length; i += 1) {\n const tool = tools[i]!;\n const [, call] = ordered[i]!;\n if (tool.name !== call.name) {\n console.warn(\n '[agent-chat] host_tool stream: full tool name mismatch at index',\n i,\n `full=${tool.name}`,\n `dsl=${call.name}`,\n );\n continue;\n }\n if (!shallowEqualArgs(tool.args, call.args)) {\n console.warn(\n '[agent-chat] host_tool stream: full args differ from DSL accumulator at index',\n i,\n 'tool=',\n tool.name,\n );\n }\n }\n}\n\nexport async function executeBatchPlan(\n scope: string,\n plans: BatchRunPlan[],\n debug?: boolean,\n): Promise<void> {\n for (const plan of plans) {\n if (plan.skip) continue;\n try {\n const ran = await runHostTool(scope, plan.tool.name, plan.tool.args);\n if (!ran && debug && typeof console !== 'undefined') {\n console.warn(\n '[agent-chat] hostTool not registered:',\n plan.tool.name,\n '(scope:',\n scope,\n ')',\n );\n }\n } catch (err) {\n if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool execution failed:', plan.tool.name, err);\n }\n }\n }\n}\n","import type {\n AgentChatHostAction,\n PageAgentLifecyclePayload,\n PageAgentSource,\n PageAgentCompleteContext,\n PageAgentStartContext,\n PageAgentStreamContext,\n} from '../../../types';\nimport type { HostActionSsePayload } from './host-tool-stream.types';\nimport { isHostActionStreamPayload } from './host-tool-stream.types';\nimport {\n createInitialHostToolStreamState,\n reduceHostToolStream,\n toStreamSessionGate,\n type HostActionSseMeta,\n type HostToolStreamEffect,\n type HostToolStreamReducerState,\n} from './host-tool-stream-reducer';\nimport {\n shouldIngestHostActionStreamFrame,\n type PageContextGate,\n} from './host-tool-stream-gate';\nimport { getHostToolStreamConfig, runHostTool, runHostToolPreview } from '../host-tool-registry';\nimport { HostToolStreamRound } from './host-tool-stream-round';\nimport {\n executeBatchPlan,\n planBatchExecution,\n warnAccumulatorMismatch,\n type HostToolInvocation,\n} from './host-tool-stream-reconcile';\n\nexport type HostToolStreamManagerOptions = {\n pageContext: PageContextGate;\n sessionId?: string;\n debug?: boolean;\n};\n\nexport type HostToolStreamHooks = {\n source: PageAgentSource;\n emitLifecycle: (payload: PageAgentLifecyclePayload) => void;\n emitHostAction: (\n action: AgentChatHostAction,\n phase: 'streaming' | 'complete',\n options?: { skipToolExecution?: boolean },\n ) => void;\n};\n\nasync function runHostToolSafe(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n debug?: boolean,\n): Promise<void> {\n try {\n const ran = await runHostTool(scope, name, args);\n if (!ran && debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool not registered:', name, '(scope:', scope, ')');\n }\n } catch (err) {\n if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool execution failed:', name, err);\n }\n }\n}\n\n/**\n * Per-session Host Tool DSL v1: reducer state + round-scoped execution.\n */\nexport class HostToolStreamManager {\n private state: HostToolStreamReducerState = createInitialHostToolStreamState();\n private readonly round = new HostToolStreamRound();\n private options: HostToolStreamManagerOptions;\n\n constructor(options: HostToolStreamManagerOptions) {\n this.options = options;\n }\n\n updateOptions(patch: Partial<HostToolStreamManagerOptions>): void {\n this.options = { ...this.options, ...patch };\n }\n\n reset(): void {\n this.state = createInitialHostToolStreamState();\n this.round.reset();\n }\n\n getReducerState(): HostToolStreamReducerState {\n return this.state;\n }\n\n ingest(payload: HostActionSsePayload, hooks: HostToolStreamHooks): void {\n const streamSession = toStreamSessionGate(this.state.session);\n if (\n !shouldIngestHostActionStreamFrame(payload, {\n page: this.options.pageContext,\n streamSession,\n })\n ) {\n return;\n }\n\n const scope = this.resolveScope(payload);\n\n this.state = reduceHostToolStream(this.state, payload, {\n getStreamConfig: (name) => getHostToolStreamConfig(scope, name),\n onEffect: (effect) => {\n this.dispatchEffect(effect, scope, hooks);\n },\n });\n }\n\n private resolveScope(payload: HostActionSsePayload): string {\n return (\n payload.scope?.trim() ??\n this.state.session?.scope?.trim() ??\n this.options.pageContext.page?.trim() ??\n '*'\n );\n }\n\n private dispatchEffect(\n effect: HostToolStreamEffect,\n scope: string,\n hooks: HostToolStreamHooks,\n ): void {\n const debug = this.options.debug;\n\n switch (effect.type) {\n case 'round-start':\n this.round.begin();\n this.emitLifecycleStart(hooks, scope, effect.streamId, effect.meta);\n break;\n\n case 'tool-start':\n this.emitLifecycleStart(\n hooks,\n scope,\n effect.streamId,\n effect.meta,\n effect.name,\n effect.callId,\n );\n break;\n\n case 'preview':\n this.emitLifecycleStream(hooks, scope, effect.meta, {\n streamId: this.state.session?.streamId ?? '',\n callId: effect.callId,\n name: effect.name,\n args: effect.args,\n });\n if (effect.invokeHandler) {\n this.round.mark(effect.callId);\n void runHostToolSafe(scope, effect.name, effect.args, debug);\n } else {\n void this.runStreamingPreview(scope, effect, debug);\n }\n break;\n\n case 'session-ended':\n if (debug && typeof console !== 'undefined') {\n console.debug(\n '[agent-chat] host_tool stream: session.end — awaiting stream.full',\n effect.streamId,\n );\n }\n break;\n\n case 'batch':\n this.finalizeBatch(hooks, scope, effect.payload, effect.meta, undefined, debug);\n break;\n\n case 'reconcile':\n warnAccumulatorMismatch(effect.payload, effect.sessionCalls, debug);\n this.finalizeBatch(\n hooks,\n scope,\n effect.payload,\n effect.meta,\n effect.sessionCalls,\n debug,\n );\n break;\n\n case 'warn':\n if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] host_tool stream:', effect.message);\n }\n break;\n\n default:\n break;\n }\n }\n\n private async runStreamingPreview(\n scope: string,\n effect: Extract<HostToolStreamEffect, { type: 'preview' }>,\n debug?: boolean,\n ): Promise<void> {\n try {\n const previewRan = await runHostToolPreview(scope, effect.name, effect.args);\n if (previewRan) return;\n\n const handlerRan = await runHostTool(scope, effect.name, effect.args);\n if (handlerRan) {\n this.round.mark(effect.callId);\n } else if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool not registered:', effect.name, '(scope:', scope, ')');\n }\n } catch (err) {\n if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool streaming preview failed:', effect.name, err);\n }\n }\n }\n\n private finalizeBatch(\n hooks: HostToolStreamHooks,\n scope: string,\n tools: HostToolInvocation[],\n meta: HostActionSseMeta,\n sessionCalls: Map<string, import('./host-tool-stream-reducer').CallAccumulator> | undefined,\n debug?: boolean,\n ): void {\n const action = this.buildCompleteAction(meta, scope, tools);\n if (!action) return;\n\n const executedSnapshot = this.round.finalize();\n const plans = planBatchExecution(tools, sessionCalls, executedSnapshot);\n\n this.emitLifecycleComplete(hooks, scope, meta, tools, action);\n hooks.emitHostAction(action, 'complete', { skipToolExecution: true });\n void executeBatchPlan(scope, plans, debug);\n }\n\n private emitLifecycleStart(\n hooks: HostToolStreamHooks,\n scope: string,\n streamId: string,\n meta: HostActionSseMeta,\n toolName?: string,\n callId?: string,\n ): void {\n const resolvedScope = meta.scope?.trim() ?? scope;\n if (!resolvedScope || !streamId) return;\n hooks.emitLifecycle({\n type: 'start',\n context: {\n streamId,\n scope: resolvedScope,\n source: hooks.source,\n toolName,\n callId,\n entity: meta.entity as PageAgentStartContext['entity'],\n reason: meta.reason,\n runId: meta.runId,\n turnId: meta.turnId,\n },\n });\n }\n\n private emitLifecycleStream(\n hooks: HostToolStreamHooks,\n scope: string,\n meta: HostActionSseMeta,\n preview: { streamId: string; callId: string; name: string; args: Record<string, unknown> },\n ): void {\n const resolvedScope = meta.scope?.trim() ?? scope;\n if (!resolvedScope || !preview.streamId || !preview.callId || !preview.name) return;\n hooks.emitLifecycle({\n type: 'stream',\n context: {\n streamId: preview.streamId,\n scope: resolvedScope,\n source: hooks.source,\n callId: preview.callId,\n toolName: preview.name,\n args: preview.args,\n entity: meta.entity as PageAgentStreamContext['entity'],\n reason: meta.reason,\n },\n });\n }\n\n private emitLifecycleComplete(\n hooks: HostToolStreamHooks,\n scope: string,\n meta: HostActionSseMeta,\n hostTools: HostToolInvocation[],\n action: AgentChatHostAction,\n ): void {\n const resolvedScope = meta.scope?.trim() ?? scope;\n if (!resolvedScope) return;\n hooks.emitLifecycle({\n type: 'complete',\n context: {\n streamId: this.state.finalizedStreamId ?? this.state.session?.streamId,\n scope: resolvedScope,\n source: hooks.source,\n hostTools,\n action,\n entity: meta.entity as PageAgentCompleteContext['entity'],\n reason: meta.reason ?? action.reason,\n },\n });\n }\n\n private buildCompleteAction(\n meta: HostActionSseMeta,\n scope: string,\n hostTools: HostToolInvocation[],\n ): AgentChatHostAction | null {\n const resolvedScope = meta.scope?.trim() ?? scope;\n if (!resolvedScope || hostTools.length === 0) return null;\n return {\n action: 'host_action',\n scope: resolvedScope,\n entity: meta.entity as AgentChatHostAction['entity'],\n metadata: meta.metadata,\n hostTools,\n reason: meta.reason,\n planStepId: meta.planStepId,\n runId: meta.runId,\n turnId: meta.turnId,\n sessionId: this.options.sessionId,\n streamPhase: 'complete',\n };\n }\n}\n\nexport function isHostToolStreamEnabled(\n option: boolean | undefined,\n payload: HostActionSsePayload,\n): boolean {\n if (option === false) {\n return (\n !isHostActionStreamPayload(payload) || payload.stream.mode === 'full'\n );\n }\n return true;\n}\n","import type { AgentChatClient } from '../client/instance';\nimport {\n declareHostTool,\n isHostToolDeclaredInScope,\n isHostToolRegisteredInScope,\n registerHostTool,\n} from './host-tool-registry';\nimport type {\n AppHostToolDefinition,\n HostToolDefinition,\n RegisterHostToolsOptions,\n} from '../../types';\n\nconst serverSyncedKeys = new Set<string>();\nconst pendingSyncByClientId = new Map<string, RegisterHostToolsOptions[]>();\n\nfunction syncKey(appClientId: number, name: string): string {\n return `${appClientId}:${name}`;\n}\n\nfunction resolveToolScope(\n scope: string | undefined,\n generic: boolean | undefined,\n): string {\n if (generic) return '*';\n return scope?.trim() || '*';\n}\n\nfunction toServerToolMeta(\n tool: HostToolDefinition | AppHostToolDefinition,\n appLevel: boolean,\n): Omit<HostToolDefinition, 'handler'> {\n const {\n name,\n description,\n argsSchema,\n argsTemplate,\n definitionKey,\n } = tool;\n const generic =\n appLevel ? true : 'generic' in tool && tool.generic !== undefined ? tool.generic : undefined;\n return {\n name,\n description,\n argsSchema,\n ...(generic !== undefined ? { generic } : {}),\n ...(argsTemplate !== undefined ? { argsTemplate } : {}),\n ...(definitionKey !== undefined ? { definitionKey } : {}),\n };\n}\n\nfunction queuePendingHostToolSync(\n clientId: string,\n options: RegisterHostToolsOptions,\n): void {\n const bucket = pendingSyncByClientId.get(clientId) ?? [];\n bucket.push(options);\n pendingSyncByClientId.set(clientId, bucket);\n}\n\nasync function syncHostToolMetadataToServer(\n chat: AgentChatClient,\n options: RegisterHostToolsOptions,\n): Promise<number> {\n const { scope, tools, appLevel = false } = options;\n const appClientId = chat.getAppClientId();\n if (appClientId == null) return 0;\n\n const toSync = tools.filter(\n (tool) => !serverSyncedKeys.has(syncKey(appClientId, tool.name)),\n );\n if (toSync.length === 0) return 0;\n\n const res = await chat.syncHostToolsToServer({\n scope: appLevel ? '*' : scope,\n pageLabel: options.pageLabel,\n routePattern: options.routePattern,\n tools: toSync.map((tool) => toServerToolMeta(tool, appLevel)),\n });\n\n for (const item of [...res.created, ...res.skipped]) {\n if (item.name) {\n serverSyncedKeys.add(syncKey(appClientId, item.name));\n }\n }\n\n return toSync.length;\n}\n\n/**\n * Retry host-tool metadata sync queued before auth was ready.\n * Called automatically after `init` (when already logged in) and `login`.\n */\nexport async function flushPendingHostToolSyncs(\n chat: AgentChatClient,\n): Promise<void> {\n if (!chat.isHostToolServerSyncReady()) return;\n\n const pending = pendingSyncByClientId.get(chat.id);\n if (!pending?.length) return;\n\n pendingSyncByClientId.delete(chat.id);\n for (const options of pending) {\n await syncHostToolMetadataToServer(chat, options);\n }\n}\n\n/**\n * Register host tools locally and optionally sync metadata to the server (idempotent per tool name).\n * Server sync requires app-client auth + logged-in user (`Authorization: Bearer`); otherwise\n * the sync is queued until {@link flushPendingHostToolSyncs}.\n *\n * @example\n * ```ts\n * await registerHostToolsWithSync(chat, {\n * scope: 'review-detail',\n * tools: [{ name: 'fillReplyDraft', description: '...', argsSchema: {}, handler: () => {} }],\n * });\n * ```\n */\nexport async function registerHostToolsWithSync(\n chat: AgentChatClient,\n options: RegisterHostToolsOptions,\n): Promise<void> {\n const { scope, tools, syncToServer = true, appLevel = false } = options;\n\n let localRegistrationChanged = false;\n\n for (const tool of tools) {\n const toolScope = appLevel ? '*' : resolveToolScope(scope, 'generic' in tool ? tool.generic : undefined);\n const hadLocal =\n tool.handler != null\n ? isHostToolRegisteredInScope(toolScope, tool.name)\n : isHostToolDeclaredInScope(toolScope, tool.name);\n\n if (tool.handler) {\n registerHostTool(toolScope, tool.name, tool.handler, {\n ...(tool.invokeOnAppend !== undefined ? { invokeOnAppend: tool.invokeOnAppend } : {}),\n ...(tool.onPreview ? { onPreview: tool.onPreview } : {}),\n });\n } else {\n declareHostTool(toolScope, tool.name);\n }\n\n if (!hadLocal) {\n localRegistrationChanged = true;\n }\n }\n\n if (!syncToServer) {\n if (localRegistrationChanged) {\n schedulePrepareSession(chat);\n }\n return;\n }\n\n if (!chat.isHostToolServerSyncReady()) {\n queuePendingHostToolSync(chat.id, options);\n if (typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(\n '[agent-chat] registerHostToolsWithSync: waiting for authentication before server sync.',\n );\n }\n if (localRegistrationChanged) {\n schedulePrepareSession(chat);\n }\n return;\n }\n\n const serverSyncedCount = await syncHostToolMetadataToServer(chat, options);\n\n if (localRegistrationChanged || serverSyncedCount > 0) {\n schedulePrepareSession(chat);\n }\n}\n\nfunction schedulePrepareSession(chat: AgentChatClient): void {\n const sessionId = chat.getState().activeSessionId?.trim();\n if (sessionId) {\n void chat.prepareSession(sessionId, { force: true });\n }\n}\n\n/** Test helper — clears the in-process server sync dedupe set and pending queue. */\nexport function clearHostToolServerSyncKeys(): void {\n serverSyncedKeys.clear();\n pendingSyncByClientId.clear();\n}\n","import type { AgentChatPageContext, ContextMentionAttachment } from '../../types';\n\n/** Merge selected @ mentions into pageContext.metadata for a single message send. */\nexport function mergePageContextWithMentions(\n base: AgentChatPageContext | null | undefined,\n mentions: ContextMentionAttachment[],\n): AgentChatPageContext | null {\n if (mentions.length === 0) return base ?? null;\n\n const out: AgentChatPageContext = { ...(base ?? {}) };\n const metadata: Record<string, unknown> = {};\n\n for (const mention of mentions) {\n metadata[mention.kind] = {\n ...mention.payload,\n content:\n typeof mention.payload.content === 'string'\n ? mention.payload.content\n : String(mention.payload.content ?? ''),\n _mentionLabel: mention.label,\n _mentionId: mention.id,\n };\n }\n\n out.metadata = metadata;\n return Object.keys(out).length > 0 ? out : null;\n}\n","import type {\n ContextMentionDefinition,\n ContextMentionRegistration,\n} from '../../types';\n\nconst HOST_ID_PREFIX = 'host:';\n\n/** Stable metadata / registry key from a human label (no manual slug in host code). */\nexport function slugContextMentionKey(label: string): string {\n const slug = label\n .trim()\n .toLowerCase()\n .replace(/[^\\w\\u4e00-\\u9fff]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 48);\n return slug || 'mention';\n}\n\n/** Coerce host `resolve()` output into inline-read payload (server reads `.content`). */\nexport function coerceContextMentionPayload(\n value: string | Record<string, unknown>,\n): Record<string, unknown> {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n return trimmed ? { content: trimmed } : { content: '' };\n }\n if (typeof value.content === 'string' && value.content.trim()) {\n return { ...value, content: value.content.trim() };\n }\n try {\n const serialized = JSON.stringify(value, null, 2);\n return { ...value, content: serialized };\n } catch {\n return { ...value, content: String(value) };\n }\n}\n\nfunction hostMentionId(key: string): string {\n const trimmed = key.trim();\n if (!trimmed) return `${HOST_ID_PREFIX}mention`;\n return trimmed.startsWith(HOST_ID_PREFIX) ? trimmed : `${HOST_ID_PREFIX}${trimmed}`;\n}\n\n/** Normalize a full registration (optional `kind`, optional payload shaping). */\nexport function normalizeContextMentionRegistration(\n item: ContextMentionRegistration,\n): ContextMentionRegistration {\n const id = hostMentionId(item.id || slugContextMentionKey(item.label));\n const key = id.startsWith(HOST_ID_PREFIX) ? id.slice(HOST_ID_PREFIX.length) : id;\n const kind = item.kind?.trim() || key;\n const payload =\n item.payload != null\n ? coerceContextMentionPayload(item.payload as Record<string, unknown>)\n : item.description\n ? coerceContextMentionPayload(item.description)\n : undefined;\n\n return {\n ...item,\n id,\n kind,\n group: item.group ?? 'host',\n payload,\n resolve: item.resolve\n ? async () => coerceContextMentionPayload(await item.resolve!())\n : undefined,\n };\n}\n\n/**\n * Declare one host @ mention — only `label` (+ `resolve` or `value`) required.\n * `id` / `kind` / `content` are derived by the SDK.\n */\nexport function defineContextMention(\n def: ContextMentionDefinition,\n): ContextMentionRegistration {\n const key = def.key?.trim() || slugContextMentionKey(def.label);\n const id = hostMentionId(key);\n const description =\n def.description ??\n (typeof def.value === 'string' ? def.value : undefined);\n\n let payload: Record<string, unknown> | undefined;\n if (def.value != null) {\n payload = coerceContextMentionPayload(def.value);\n }\n\n return normalizeContextMentionRegistration({\n id,\n label: def.label,\n kind: key,\n group: def.group ?? 'host',\n description,\n payload,\n resolve: def.resolve\n ? async () => coerceContextMentionPayload(await def.resolve!())\n : undefined,\n });\n}\n\nexport type PageContextMentionSnippet = {\n label: string;\n body: string;\n};\n\n/**\n * Build `pageContext.metadata` snippets for the @ picker from labels + bodies only.\n * Keys and `content` field are assigned by the SDK.\n */\nexport function definePageContextMentions(\n snippets: PageContextMentionSnippet[],\n): Record<string, unknown> {\n const metadata: Record<string, unknown> = {};\n const used = new Set<string>();\n\n for (const snippet of snippets) {\n let key = slugContextMentionKey(snippet.label);\n if (used.has(key)) {\n let n = 2;\n while (used.has(`${key}-${n}`)) n += 1;\n key = `${key}-${n}`;\n }\n used.add(key);\n metadata[key] = coerceContextMentionPayload({\n title: snippet.label,\n content: snippet.body,\n });\n }\n\n return metadata;\n}\n\nexport function isContextMentionDefinition(\n item: ContextMentionDefinition | ContextMentionRegistration,\n): item is ContextMentionDefinition {\n return !('id' in item && typeof item.id === 'string' && item.id.trim().length > 0);\n}\n\nexport function normalizeContextMentionInput(\n item: ContextMentionDefinition | ContextMentionRegistration,\n): ContextMentionRegistration {\n return isContextMentionDefinition(item)\n ? defineContextMention(item)\n : normalizeContextMentionRegistration(item);\n}\n","import type {\n ContextMentionAttachment,\n ContextMentionRegistration,\n RegisteredContextMention,\n} from '../../types';\nimport { coerceContextMentionPayload } from './context-mention-define';\n\nexport function toRegisteredContextMention(\n item: ContextMentionRegistration,\n): RegisteredContextMention {\n return {\n id: item.id,\n label: item.label,\n kind: item.kind ?? item.id.replace(/^host:/, ''),\n group: item.group,\n description: item.description,\n payload: item.payload,\n lazy: Boolean(item.resolve),\n };\n}\n\nexport function mergeContextMentionRegistrations(\n current: Map<string, ContextMentionRegistration>,\n items: ContextMentionRegistration[],\n replace = false,\n): Map<string, ContextMentionRegistration> {\n const next = replace ? new Map<string, ContextMentionRegistration>() : new Map(current);\n for (const item of items) {\n const id = item.id.trim();\n if (!id) continue;\n next.set(id, { ...item, id });\n }\n return next;\n}\n\nexport async function resolveContextMentionsForSend(\n mentions: ContextMentionAttachment[],\n registry: Map<string, ContextMentionRegistration>,\n): Promise<ContextMentionAttachment[]> {\n if (mentions.length === 0) return mentions;\n\n const resolved: ContextMentionAttachment[] = [];\n for (const mention of mentions) {\n const registration = registry.get(mention.id);\n if (!registration?.resolve) {\n resolved.push(mention);\n continue;\n }\n\n const dynamic = await registration.resolve();\n const coerced = coerceContextMentionPayload(dynamic);\n const content =\n typeof coerced.content === 'string'\n ? coerced.content\n : typeof registration.payload?.content === 'string'\n ? registration.payload.content\n : typeof mention.payload.content === 'string'\n ? mention.payload.content\n : mention.label;\n\n resolved.push({\n ...mention,\n label: registration.label,\n kind: registration.kind ?? registration.id.replace(/^host:/, ''),\n payload: {\n ...registration.payload,\n ...mention.payload,\n ...coerced,\n content,\n },\n });\n }\n return resolved;\n}\n","export class HTTPError extends Error {\n response;\n request;\n options;\n constructor(response, request, options) {\n const code = (response.status || response.status === 0) ? response.status : '';\n const title = response.statusText ?? '';\n const status = `${code} ${title}`.trim();\n const reason = status ? `status code ${status}` : 'an unknown error';\n super(`Request failed with ${reason}: ${request.method} ${request.url}`);\n this.name = 'HTTPError';\n this.response = response;\n this.request = request;\n this.options = options;\n }\n}\n//# sourceMappingURL=HTTPError.js.map","/**\nWrapper for non-Error values that were thrown.\n\nIn JavaScript, any value can be thrown (not just Error instances). This class wraps such values to ensure consistent error handling.\n*/\nexport class NonError extends Error {\n name = 'NonError';\n value;\n constructor(value) {\n let message = 'Non-error value was thrown';\n // Intentionally minimal as this error is just an edge-case.\n try {\n if (typeof value === 'string') {\n message = value;\n }\n else if (value && typeof value === 'object' && 'message' in value && typeof value.message === 'string') {\n message = value.message;\n }\n }\n catch {\n // Use default message if accessing properties throws\n }\n super(message);\n this.value = value;\n }\n}\n//# sourceMappingURL=NonError.js.map","import { NonError } from './NonError.js';\n/**\nInternal error used to signal a forced retry from afterResponse hooks.\nThis is thrown when a user returns ky.retry() from an afterResponse hook.\n*/\nexport class ForceRetryError extends Error {\n name = 'ForceRetryError';\n customDelay;\n code;\n customRequest;\n constructor(options) {\n // Runtime protection: wrap non-Error causes in NonError\n // TypeScript type is Error for guidance, but JS users can pass anything\n const cause = options?.cause\n ? (options.cause instanceof Error ? options.cause : new NonError(options.cause))\n : undefined;\n super(options?.code ? `Forced retry: ${options.code}` : 'Forced retry', cause ? { cause } : undefined);\n this.customDelay = options?.delay;\n this.code = options?.code;\n this.customRequest = options?.request;\n }\n}\n//# sourceMappingURL=ForceRetryError.js.map","export const supportsRequestStreams = (() => {\n let duplexAccessed = false;\n let hasContentType = false;\n const supportsReadableStream = typeof globalThis.ReadableStream === 'function';\n const supportsRequest = typeof globalThis.Request === 'function';\n if (supportsReadableStream && supportsRequest) {\n try {\n hasContentType = new globalThis.Request('https://empty.invalid', {\n body: new globalThis.ReadableStream(),\n method: 'POST',\n // @ts-expect-error - Types are outdated.\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n }\n catch (error) {\n // QQBrowser on iOS throws \"unsupported BodyInit type\" error (see issue #581)\n if (error instanceof Error && error.message === 'unsupported BodyInit type') {\n return false;\n }\n throw error;\n }\n }\n return duplexAccessed && !hasContentType;\n})();\nexport const supportsAbortController = typeof globalThis.AbortController === 'function';\nexport const supportsAbortSignal = typeof globalThis.AbortSignal === 'function' && typeof globalThis.AbortSignal.any === 'function';\nexport const supportsResponseStreams = typeof globalThis.ReadableStream === 'function';\nexport const supportsFormData = typeof globalThis.FormData === 'function';\nexport const requestMethods = ['get', 'post', 'put', 'patch', 'head', 'delete'];\nconst validate = () => undefined;\nvalidate();\nexport const responseTypes = {\n json: 'application/json',\n text: 'text/*',\n formData: 'multipart/form-data',\n arrayBuffer: '*/*',\n blob: '*/*',\n // Supported in modern Fetch implementations (for example, browsers and recent Node.js/undici).\n // We still feature-check at runtime before exposing the shortcut.\n bytes: '*/*',\n};\n// The maximum value of a 32bit int (see issue #117)\nexport const maxSafeTimeout = 2_147_483_647;\n// Size in bytes of a typical form boundary, used to help estimate upload size\nexport const usualFormBoundarySize = new TextEncoder().encode('------WebKitFormBoundaryaxpyiPgbbPti10Rw').length;\nexport const stop = Symbol('stop');\n/**\nMarker returned by ky.retry() to signal a forced retry from afterResponse hooks.\n*/\nexport class RetryMarker {\n options;\n constructor(options) {\n this.options = options;\n }\n}\n/**\nForce a retry from an `afterResponse` hook.\n\nThis allows you to retry a request based on the response content, even if the response has a successful status code. The retry will respect the `retry.limit` option and skip the `shouldRetry` check. The forced retry is observable in `beforeRetry` hooks, where the error will be a `ForceRetryError`.\n\n@param options - Optional configuration for the retry.\n\n@example\n```\nimport ky, {isForceRetryError} from 'ky';\n\nconst api = ky.extend({\n hooks: {\n afterResponse: [\n async (request, options, response) => {\n // Retry based on response body content\n if (response.status === 200) {\n const data = await response.clone().json();\n\n // Simple retry with default delay\n if (data.error?.code === 'TEMPORARY_ERROR') {\n return ky.retry();\n }\n\n // Retry with custom delay from API response\n if (data.error?.code === 'RATE_LIMIT') {\n return ky.retry({\n delay: data.error.retryAfter * 1000,\n code: 'RATE_LIMIT'\n });\n }\n\n // Retry with a modified request (e.g., fallback endpoint)\n if (data.error?.code === 'FALLBACK_TO_BACKUP') {\n return ky.retry({\n request: new Request('https://backup-api.com/endpoint', {\n method: request.method,\n headers: request.headers,\n }),\n code: 'BACKUP_ENDPOINT'\n });\n }\n\n // Retry with refreshed authentication\n if (data.error?.code === 'TOKEN_REFRESH' && data.newToken) {\n return ky.retry({\n request: new Request(request, {\n headers: {\n ...Object.fromEntries(request.headers),\n 'Authorization': `Bearer ${data.newToken}`\n }\n }),\n code: 'TOKEN_REFRESHED'\n });\n }\n\n // Retry with cause to preserve error chain\n try {\n validateResponse(data);\n } catch (error) {\n return ky.retry({\n code: 'VALIDATION_FAILED',\n cause: error\n });\n }\n }\n }\n ],\n beforeRetry: [\n ({error, retryCount}) => {\n // Observable in beforeRetry hooks\n if (isForceRetryError(error)) {\n console.log(`Forced retry #${retryCount}: ${error.message}`);\n // Example output: \"Forced retry #1: Forced retry: RATE_LIMIT\"\n }\n }\n ]\n }\n});\n\nconst response = await api.get('https://example.com/api');\n```\n*/\nexport const retry = (options) => new RetryMarker(options);\nexport const kyOptionKeys = {\n json: true,\n parseJson: true,\n stringifyJson: true,\n searchParams: true,\n prefixUrl: true,\n retry: true,\n timeout: true,\n hooks: true,\n throwHttpErrors: true,\n onDownloadProgress: true,\n onUploadProgress: true,\n fetch: true,\n context: true,\n};\n// Vendor-specific fetch options that should always be passed to fetch()\n// even if they appear on the Request object due to vendor patching.\n// See: https://github.com/sindresorhus/ky/issues/541\nexport const vendorSpecificOptions = {\n next: true, // Next.js cache revalidation (revalidate, tags)\n};\n// Standard RequestInit options that should NOT be passed separately to fetch()\n// because they're already applied to the Request object.\n// Note: `dispatcher` and `priority` are NOT included here - they're fetch-only\n// options that the Request constructor doesn't accept, so they need to be passed\n// separately to fetch().\nexport const requestOptionsRegistry = {\n method: true,\n headers: true,\n body: true,\n mode: true,\n credentials: true,\n cache: true,\n redirect: true,\n referrer: true,\n referrerPolicy: true,\n integrity: true,\n keepalive: true,\n signal: true,\n window: true,\n duplex: true,\n};\n//# sourceMappingURL=constants.js.map","import { usualFormBoundarySize } from '../core/constants.js';\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const getBodySize = (body) => {\n if (!body) {\n return 0;\n }\n if (body instanceof FormData) {\n // This is an approximation, as FormData size calculation is not straightforward\n let size = 0;\n for (const [key, value] of body) {\n size += usualFormBoundarySize;\n size += new TextEncoder().encode(`Content-Disposition: form-data; name=\"${key}\"`).length;\n size += typeof value === 'string'\n ? new TextEncoder().encode(value).length\n : value.size;\n }\n return size;\n }\n if (body instanceof Blob) {\n return body.size;\n }\n if (body instanceof ArrayBuffer) {\n return body.byteLength;\n }\n if (typeof body === 'string') {\n return new TextEncoder().encode(body).length;\n }\n if (body instanceof URLSearchParams) {\n return new TextEncoder().encode(body.toString()).length;\n }\n if ('byteLength' in body) {\n return (body).byteLength;\n }\n if (typeof body === 'object' && body !== null) {\n try {\n const jsonString = JSON.stringify(body);\n return new TextEncoder().encode(jsonString).length;\n }\n catch {\n return 0;\n }\n }\n return 0; // Default case, unable to determine size\n};\nconst withProgress = (stream, totalBytes, onProgress) => {\n let previousChunk;\n let transferredBytes = 0;\n return stream.pipeThrough(new TransformStream({\n transform(currentChunk, controller) {\n controller.enqueue(currentChunk);\n if (previousChunk) {\n transferredBytes += previousChunk.byteLength;\n let percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;\n // Avoid reporting 100% progress before the stream is actually finished (in case totalBytes is inaccurate)\n if (percent >= 1) {\n // Epsilon is used here to get as close as possible to 100% without reaching it.\n // If we were to use 0.99 here, percent could potentially go backwards.\n percent = 1 - Number.EPSILON;\n }\n onProgress?.({ percent, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes }, previousChunk);\n }\n previousChunk = currentChunk;\n },\n flush() {\n if (previousChunk) {\n transferredBytes += previousChunk.byteLength;\n onProgress?.({ percent: 1, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes }, previousChunk);\n }\n },\n }));\n};\nexport const streamResponse = (response, onDownloadProgress) => {\n if (!response.body) {\n return response;\n }\n if (response.status === 204) {\n return new Response(null, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n const totalBytes = Math.max(0, Number(response.headers.get('content-length')) || 0);\n return new Response(withProgress(response.body, totalBytes, onDownloadProgress), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n};\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const streamRequest = (request, onUploadProgress, originalBody) => {\n if (!request.body) {\n return request;\n }\n // Use original body for size calculation since request.body is already a stream\n const totalBytes = getBodySize(originalBody ?? request.body);\n return new Request(request, {\n // @ts-expect-error - Types are outdated.\n duplex: 'half',\n body: withProgress(request.body, totalBytes, onUploadProgress),\n });\n};\n//# sourceMappingURL=body.js.map","// eslint-disable-next-line @typescript-eslint/ban-types\nexport const isObject = (value) => value !== null && typeof value === 'object';\n//# sourceMappingURL=is.js.map","import { supportsAbortSignal } from '../core/constants.js';\nimport { isObject } from './is.js';\nexport const validateAndMerge = (...sources) => {\n for (const source of sources) {\n if ((!isObject(source) || Array.isArray(source)) && source !== undefined) {\n throw new TypeError('The `options` argument must be an object');\n }\n }\n return deepMerge({}, ...sources);\n};\nexport const mergeHeaders = (source1 = {}, source2 = {}) => {\n const result = new globalThis.Headers(source1);\n const isHeadersInstance = source2 instanceof globalThis.Headers;\n const source = new globalThis.Headers(source2);\n for (const [key, value] of source.entries()) {\n if ((isHeadersInstance && value === 'undefined') || value === undefined) {\n result.delete(key);\n }\n else {\n result.set(key, value);\n }\n }\n return result;\n};\nfunction newHookValue(original, incoming, property) {\n return (Object.hasOwn(incoming, property) && incoming[property] === undefined)\n ? []\n : deepMerge(original[property] ?? [], incoming[property] ?? []);\n}\nexport const mergeHooks = (original = {}, incoming = {}) => ({\n beforeRequest: newHookValue(original, incoming, 'beforeRequest'),\n beforeRetry: newHookValue(original, incoming, 'beforeRetry'),\n afterResponse: newHookValue(original, incoming, 'afterResponse'),\n beforeError: newHookValue(original, incoming, 'beforeError'),\n});\nconst appendSearchParameters = (target, source) => {\n const result = new URLSearchParams();\n for (const input of [target, source]) {\n if (input === undefined) {\n continue;\n }\n if (input instanceof URLSearchParams) {\n for (const [key, value] of input.entries()) {\n result.append(key, value);\n }\n }\n else if (Array.isArray(input)) {\n for (const pair of input) {\n if (!Array.isArray(pair) || pair.length !== 2) {\n throw new TypeError('Array search parameters must be provided in [[key, value], ...] format');\n }\n result.append(String(pair[0]), String(pair[1]));\n }\n }\n else if (isObject(input)) {\n for (const [key, value] of Object.entries(input)) {\n if (value !== undefined) {\n result.append(key, String(value));\n }\n }\n }\n else {\n // String\n const parameters = new URLSearchParams(input);\n for (const [key, value] of parameters.entries()) {\n result.append(key, value);\n }\n }\n }\n return result;\n};\n// TODO: Make this strongly-typed (no `any`).\nexport const deepMerge = (...sources) => {\n let returnValue = {};\n let headers = {};\n let hooks = {};\n let searchParameters;\n const signals = [];\n for (const source of sources) {\n if (Array.isArray(source)) {\n if (!Array.isArray(returnValue)) {\n returnValue = [];\n }\n returnValue = [...returnValue, ...source];\n }\n else if (isObject(source)) {\n for (let [key, value] of Object.entries(source)) {\n // Special handling for AbortSignal instances\n if (key === 'signal' && value instanceof globalThis.AbortSignal) {\n signals.push(value);\n continue;\n }\n // Special handling for context - shallow merge only\n if (key === 'context') {\n if (value !== undefined && value !== null && (!isObject(value) || Array.isArray(value))) {\n throw new TypeError('The `context` option must be an object');\n }\n // Shallow merge: always create a new object to prevent mutation bugs\n returnValue = {\n ...returnValue,\n context: (value === undefined || value === null)\n ? {}\n : { ...returnValue.context, ...value },\n };\n continue;\n }\n // Special handling for searchParams\n if (key === 'searchParams') {\n if (value === undefined || value === null) {\n // Explicit undefined or null removes searchParams\n searchParameters = undefined;\n }\n else {\n // First source: keep as-is to preserve type (string/object/URLSearchParams)\n // Subsequent sources: merge and convert to URLSearchParams\n searchParameters = searchParameters === undefined ? value : appendSearchParameters(searchParameters, value);\n }\n continue;\n }\n if (isObject(value) && key in returnValue) {\n value = deepMerge(returnValue[key], value);\n }\n returnValue = { ...returnValue, [key]: value };\n }\n if (isObject(source.hooks)) {\n hooks = mergeHooks(hooks, source.hooks);\n returnValue.hooks = hooks;\n }\n if (isObject(source.headers)) {\n headers = mergeHeaders(headers, source.headers);\n returnValue.headers = headers;\n }\n }\n }\n if (searchParameters !== undefined) {\n returnValue.searchParams = searchParameters;\n }\n if (signals.length > 0) {\n if (signals.length === 1) {\n returnValue.signal = signals[0];\n }\n else if (supportsAbortSignal) {\n returnValue.signal = AbortSignal.any(signals);\n }\n else {\n // When AbortSignal.any is not available, use the last signal\n // This maintains the previous behavior before signal merging was added\n // This can be remove when the `supportsAbortSignal` check is removed.`\n returnValue.signal = signals.at(-1);\n }\n }\n return returnValue;\n};\n//# sourceMappingURL=merge.js.map","import { requestMethods } from '../core/constants.js';\nexport const normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input;\nconst retryMethods = ['get', 'put', 'head', 'delete', 'options', 'trace'];\nconst retryStatusCodes = [408, 413, 429, 500, 502, 503, 504];\nconst retryAfterStatusCodes = [413, 429, 503];\nconst defaultRetryOptions = {\n limit: 2,\n methods: retryMethods,\n statusCodes: retryStatusCodes,\n afterStatusCodes: retryAfterStatusCodes,\n maxRetryAfter: Number.POSITIVE_INFINITY,\n backoffLimit: Number.POSITIVE_INFINITY,\n delay: attemptCount => 0.3 * (2 ** (attemptCount - 1)) * 1000,\n jitter: undefined,\n retryOnTimeout: false,\n};\nexport const normalizeRetryOptions = (retry = {}) => {\n if (typeof retry === 'number') {\n return {\n ...defaultRetryOptions,\n limit: retry,\n };\n }\n if (retry.methods && !Array.isArray(retry.methods)) {\n throw new Error('retry.methods must be an array');\n }\n retry.methods &&= retry.methods.map(method => method.toLowerCase());\n if (retry.statusCodes && !Array.isArray(retry.statusCodes)) {\n throw new Error('retry.statusCodes must be an array');\n }\n const normalizedRetry = Object.fromEntries(Object.entries(retry).filter(([, value]) => value !== undefined));\n return {\n ...defaultRetryOptions,\n ...normalizedRetry,\n };\n};\n//# sourceMappingURL=normalize.js.map","export class TimeoutError extends Error {\n request;\n constructor(request) {\n super(`Request timed out: ${request.method} ${request.url}`);\n this.name = 'TimeoutError';\n this.request = request;\n }\n}\n//# sourceMappingURL=TimeoutError.js.map","import { TimeoutError } from '../errors/TimeoutError.js';\n// `Promise.race()` workaround (#91)\nexport default async function timeout(request, init, abortController, options) {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n if (abortController) {\n abortController.abort();\n }\n reject(new TimeoutError(request));\n }, options.timeout);\n void options\n .fetch(request, init)\n .then(resolve)\n .catch(reject)\n .then(() => {\n clearTimeout(timeoutId);\n });\n });\n}\n//# sourceMappingURL=timeout.js.map","// https://github.com/sindresorhus/delay/tree/ab98ae8dfcb38e1593286c94d934e70d14a4e111\nexport default async function delay(ms, { signal }) {\n return new Promise((resolve, reject) => {\n if (signal) {\n signal.throwIfAborted();\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n function abortHandler() {\n clearTimeout(timeoutId);\n reject(signal.reason);\n }\n const timeoutId = setTimeout(() => {\n signal?.removeEventListener('abort', abortHandler);\n resolve();\n }, ms);\n });\n}\n//# sourceMappingURL=delay.js.map","import { kyOptionKeys, requestOptionsRegistry, vendorSpecificOptions } from '../core/constants.js';\nexport const findUnknownOptions = (request, options) => {\n const unknownOptions = {};\n for (const key in options) {\n // Skip inherited properties\n if (!Object.hasOwn(options, key)) {\n continue;\n }\n // An option is passed to fetch() if:\n // 1. It's not a standard RequestInit option (not in requestOptionsRegistry)\n // 2. It's not a ky-specific option (not in kyOptionKeys)\n // 3. Either:\n // a. It's not on the Request object, OR\n // b. It's a vendor-specific option that should always be passed (in vendorSpecificOptions)\n if (!(key in requestOptionsRegistry) && !(key in kyOptionKeys) && (!(key in request) || key in vendorSpecificOptions)) {\n unknownOptions[key] = options[key];\n }\n }\n return unknownOptions;\n};\nexport const hasSearchParameters = (search) => {\n if (search === undefined) {\n return false;\n }\n // The `typeof array` still gives \"object\", so we need different checking for array.\n if (Array.isArray(search)) {\n return search.length > 0;\n }\n if (search instanceof URLSearchParams) {\n return search.size > 0;\n }\n // Record\n if (typeof search === 'object') {\n return Object.keys(search).length > 0;\n }\n if (typeof search === 'string') {\n return search.trim().length > 0;\n }\n return Boolean(search);\n};\n//# sourceMappingURL=options.js.map","import { HTTPError } from '../errors/HTTPError.js';\nimport { TimeoutError } from '../errors/TimeoutError.js';\nimport { ForceRetryError } from '../errors/ForceRetryError.js';\n/**\nType guard to check if an error is a Ky error.\n\n@param error - The error to check\n@returns `true` if the error is a Ky error, `false` otherwise\n\n@example\n```\nimport ky, {isKyError} from 'ky';\ntry {\n const response = await ky.get('/api/data');\n} catch (error) {\n if (isKyError(error)) {\n // Handle Ky-specific errors\n console.log('Ky error occurred:', error.message);\n } else {\n // Handle other errors\n console.log('Unknown error:', error);\n }\n}\n```\n*/\nexport function isKyError(error) {\n return isHTTPError(error) || isTimeoutError(error) || isForceRetryError(error);\n}\n/**\nType guard to check if an error is an HTTPError.\n\n@param error - The error to check\n@returns `true` if the error is an HTTPError, `false` otherwise\n\n@example\n```\nimport ky, {isHTTPError} from 'ky';\ntry {\n const response = await ky.get('/api/data');\n} catch (error) {\n if (isHTTPError(error)) {\n console.log('HTTP error status:', error.response.status);\n }\n}\n```\n*/\nexport function isHTTPError(error) {\n return error instanceof HTTPError || (error?.name === HTTPError.name);\n}\n/**\nType guard to check if an error is a TimeoutError.\n\n@param error - The error to check\n@returns `true` if the error is a TimeoutError, `false` otherwise\n\n@example\n```\nimport ky, {isTimeoutError} from 'ky';\ntry {\n const response = await ky.get('/api/data', { timeout: 1000 });\n} catch (error) {\n if (isTimeoutError(error)) {\n console.log('Request timed out:', error.request.url);\n }\n}\n```\n*/\nexport function isTimeoutError(error) {\n return error instanceof TimeoutError || (error?.name === TimeoutError.name);\n}\n/**\nType guard to check if an error is a ForceRetryError.\n\n@param error - The error to check\n@returns `true` if the error is a ForceRetryError, `false` otherwise\n\n@example\n```\nimport ky, {isForceRetryError} from 'ky';\n\nconst api = ky.extend({\n hooks: {\n beforeRetry: [\n ({error, retryCount}) => {\n if (isForceRetryError(error)) {\n console.log(`Forced retry #${retryCount}: ${error.code}`);\n }\n }\n ]\n }\n});\n```\n*/\nexport function isForceRetryError(error) {\n return error instanceof ForceRetryError || (error?.name === ForceRetryError.name);\n}\n//# sourceMappingURL=type-guards.js.map","import { HTTPError } from '../errors/HTTPError.js';\nimport { NonError } from '../errors/NonError.js';\nimport { ForceRetryError } from '../errors/ForceRetryError.js';\nimport { streamRequest, streamResponse } from '../utils/body.js';\nimport { mergeHeaders, mergeHooks } from '../utils/merge.js';\nimport { normalizeRequestMethod, normalizeRetryOptions } from '../utils/normalize.js';\nimport timeout from '../utils/timeout.js';\nimport delay from '../utils/delay.js';\nimport { findUnknownOptions, hasSearchParameters } from '../utils/options.js';\nimport { isHTTPError, isTimeoutError } from '../utils/type-guards.js';\nimport { maxSafeTimeout, responseTypes, stop, RetryMarker, supportsAbortController, supportsAbortSignal, supportsFormData, supportsResponseStreams, supportsRequestStreams, } from './constants.js';\nexport class Ky {\n static create(input, options) {\n const ky = new Ky(input, options);\n const function_ = async () => {\n if (typeof ky.#options.timeout === 'number' && ky.#options.timeout > maxSafeTimeout) {\n throw new RangeError(`The \\`timeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n // Delay the fetch so that body method shortcuts can set the Accept header\n await Promise.resolve();\n // Before using ky.request, _fetch clones it and saves the clone for future retries to use.\n // If retry is not needed, close the cloned request's ReadableStream for memory safety.\n let response = await ky.#fetch();\n for (const hook of ky.#options.hooks.afterResponse) {\n // Clone the response before passing to hook so we can cancel it if needed\n const clonedResponse = ky.#decorateResponse(response.clone());\n let modifiedResponse;\n try {\n // eslint-disable-next-line no-await-in-loop\n modifiedResponse = await hook(ky.request, ky.#getNormalizedOptions(), clonedResponse, { retryCount: ky.#retryCount });\n }\n catch (error) {\n // Cancel both responses to prevent memory leaks when hook throws\n ky.#cancelResponseBody(clonedResponse);\n ky.#cancelResponseBody(response);\n throw error;\n }\n if (modifiedResponse instanceof RetryMarker) {\n // Cancel both the cloned response passed to the hook and the current response to prevent resource leaks (especially important in Deno/Bun).\n // Do not await cancellation since hooks can clone the response, leaving extra tee branches that keep cancel promises pending per the Streams spec.\n ky.#cancelResponseBody(clonedResponse);\n ky.#cancelResponseBody(response);\n throw new ForceRetryError(modifiedResponse.options);\n }\n // Determine which response to use going forward\n const nextResponse = modifiedResponse instanceof globalThis.Response ? modifiedResponse : response;\n // Cancel any response bodies we won't use to prevent memory leaks.\n // Uses fire-and-forget since hooks may have cloned the response, creating tee branches that block cancellation.\n if (clonedResponse !== nextResponse) {\n ky.#cancelResponseBody(clonedResponse);\n }\n if (response !== nextResponse) {\n ky.#cancelResponseBody(response);\n }\n response = nextResponse;\n }\n ky.#decorateResponse(response);\n if (!response.ok && (typeof ky.#options.throwHttpErrors === 'function'\n ? ky.#options.throwHttpErrors(response.status)\n : ky.#options.throwHttpErrors)) {\n let error = new HTTPError(response, ky.request, ky.#getNormalizedOptions());\n for (const hook of ky.#options.hooks.beforeError) {\n // eslint-disable-next-line no-await-in-loop\n error = await hook(error, { retryCount: ky.#retryCount });\n }\n throw error;\n }\n // If `onDownloadProgress` is passed, it uses the stream API internally\n if (ky.#options.onDownloadProgress) {\n if (typeof ky.#options.onDownloadProgress !== 'function') {\n throw new TypeError('The `onDownloadProgress` option must be a function');\n }\n if (!supportsResponseStreams) {\n throw new Error('Streams are not supported in your environment. `ReadableStream` is missing.');\n }\n const progressResponse = response.clone();\n ky.#cancelResponseBody(response);\n return streamResponse(progressResponse, ky.#options.onDownloadProgress);\n }\n return response;\n };\n // Always wrap in #retry to catch forced retries from afterResponse hooks\n // Method retriability is checked in #calculateRetryDelay for non-forced retries\n const result = ky.#retry(function_)\n .finally(() => {\n const originalRequest = ky.#originalRequest;\n // Ignore cancellation errors from already-locked or already-consumed streams.\n ky.#cancelBody(originalRequest?.body ?? undefined);\n ky.#cancelBody(ky.request.body ?? undefined);\n });\n for (const [type, mimeType] of Object.entries(responseTypes)) {\n // Only expose `.bytes()` when the environment implements it.\n if (type === 'bytes'\n && typeof globalThis.Response?.prototype?.bytes !== 'function') {\n continue;\n }\n result[type] = async () => {\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n ky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType);\n const response = await result;\n if (type === 'json') {\n if (response.status === 204) {\n return '';\n }\n const text = await response.text();\n if (text === '') {\n return '';\n }\n if (options.parseJson) {\n return options.parseJson(text);\n }\n return JSON.parse(text);\n }\n return response[type]();\n };\n }\n return result;\n }\n // eslint-disable-next-line unicorn/prevent-abbreviations\n static #normalizeSearchParams(searchParams) {\n // Filter out undefined values from plain objects\n if (searchParams && typeof searchParams === 'object' && !Array.isArray(searchParams) && !(searchParams instanceof URLSearchParams)) {\n return Object.fromEntries(Object.entries(searchParams).filter(([, value]) => value !== undefined));\n }\n return searchParams;\n }\n request;\n #abortController;\n #retryCount = 0;\n // eslint-disable-next-line @typescript-eslint/prefer-readonly -- False positive: #input is reassigned on line 202\n #input;\n #options;\n #originalRequest;\n #userProvidedAbortSignal;\n #cachedNormalizedOptions;\n // eslint-disable-next-line complexity\n constructor(input, options = {}) {\n this.#input = input;\n this.#options = {\n ...options,\n headers: mergeHeaders(this.#input.headers, options.headers),\n hooks: mergeHooks({\n beforeRequest: [],\n beforeRetry: [],\n beforeError: [],\n afterResponse: [],\n }, options.hooks),\n method: normalizeRequestMethod(options.method ?? this.#input.method ?? 'GET'),\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n prefixUrl: String(options.prefixUrl || ''),\n retry: normalizeRetryOptions(options.retry),\n throwHttpErrors: options.throwHttpErrors ?? true,\n timeout: options.timeout ?? 10_000,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n context: options.context ?? {},\n };\n if (typeof this.#input !== 'string' && !(this.#input instanceof URL || this.#input instanceof globalThis.Request)) {\n throw new TypeError('`input` must be a string, URL, or Request');\n }\n if (this.#options.prefixUrl && typeof this.#input === 'string') {\n if (this.#input.startsWith('/')) {\n throw new Error('`input` must not begin with a slash when using `prefixUrl`');\n }\n if (!this.#options.prefixUrl.endsWith('/')) {\n this.#options.prefixUrl += '/';\n }\n this.#input = this.#options.prefixUrl + this.#input;\n }\n if (supportsAbortController && supportsAbortSignal) {\n this.#userProvidedAbortSignal = this.#options.signal ?? this.#input.signal;\n this.#abortController = new globalThis.AbortController();\n this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;\n }\n if (supportsRequestStreams) {\n // @ts-expect-error - Types are outdated.\n this.#options.duplex = 'half';\n }\n if (this.#options.json !== undefined) {\n this.#options.body = this.#options.stringifyJson?.(this.#options.json) ?? JSON.stringify(this.#options.json);\n this.#options.headers.set('content-type', this.#options.headers.get('content-type') ?? 'application/json');\n }\n // To provide correct form boundary, Content-Type header should be deleted when creating Request from another Request with FormData/URLSearchParams body\n // Only delete if user didn't explicitly provide a custom content-type\n const userProvidedContentType = options.headers && new globalThis.Headers(options.headers).has('content-type');\n if (this.#input instanceof globalThis.Request\n && ((supportsFormData && this.#options.body instanceof globalThis.FormData) || this.#options.body instanceof URLSearchParams)\n && !userProvidedContentType) {\n this.#options.headers.delete('content-type');\n }\n this.request = new globalThis.Request(this.#input, this.#options);\n if (hasSearchParameters(this.#options.searchParams)) {\n // eslint-disable-next-line unicorn/prevent-abbreviations\n const textSearchParams = typeof this.#options.searchParams === 'string'\n ? this.#options.searchParams.replace(/^\\?/, '')\n : new URLSearchParams(Ky.#normalizeSearchParams(this.#options.searchParams)).toString();\n // eslint-disable-next-line unicorn/prevent-abbreviations\n const searchParams = '?' + textSearchParams;\n const url = this.request.url.replace(/(?:\\?.*?)?(?=#|$)/, searchParams);\n // Recreate request with the updated URL. We already have all options in this.#options, including duplex.\n this.request = new globalThis.Request(url, this.#options);\n }\n // If `onUploadProgress` is passed, it uses the stream API internally\n if (this.#options.onUploadProgress) {\n if (typeof this.#options.onUploadProgress !== 'function') {\n throw new TypeError('The `onUploadProgress` option must be a function');\n }\n if (!supportsRequestStreams) {\n throw new Error('Request streams are not supported in your environment. The `duplex` option for `Request` is not available.');\n }\n this.request = this.#wrapRequestWithUploadProgress(this.request, this.#options.body ?? undefined);\n }\n }\n #calculateDelay() {\n const retryDelay = this.#options.retry.delay(this.#retryCount);\n let jitteredDelay = retryDelay;\n if (this.#options.retry.jitter === true) {\n jitteredDelay = Math.random() * retryDelay;\n }\n else if (typeof this.#options.retry.jitter === 'function') {\n jitteredDelay = this.#options.retry.jitter(retryDelay);\n if (!Number.isFinite(jitteredDelay) || jitteredDelay < 0) {\n jitteredDelay = retryDelay;\n }\n }\n // Handle undefined backoffLimit by treating it as no limit (Infinity)\n const backoffLimit = this.#options.retry.backoffLimit ?? Number.POSITIVE_INFINITY;\n return Math.min(backoffLimit, jitteredDelay);\n }\n async #calculateRetryDelay(error) {\n this.#retryCount++;\n if (this.#retryCount > this.#options.retry.limit) {\n throw error;\n }\n // Wrap non-Error throws to ensure consistent error handling\n const errorObject = error instanceof Error ? error : new NonError(error);\n // Handle forced retry from afterResponse hook - skip method check and shouldRetry\n if (errorObject instanceof ForceRetryError) {\n return errorObject.customDelay ?? this.#calculateDelay();\n }\n // Check if method is retriable for non-forced retries\n if (!this.#options.retry.methods.includes(this.request.method.toLowerCase())) {\n throw error;\n }\n // User-provided shouldRetry function takes precedence over all other checks\n if (this.#options.retry.shouldRetry !== undefined) {\n const result = await this.#options.retry.shouldRetry({ error: errorObject, retryCount: this.#retryCount });\n // Strict boolean checking - only exact true/false are handled specially\n if (result === false) {\n throw error;\n }\n if (result === true) {\n // Force retry - skip all other validation and return delay\n return this.#calculateDelay();\n }\n // If undefined or any other value, fall through to default behavior\n }\n // Default timeout behavior\n if (isTimeoutError(error) && !this.#options.retry.retryOnTimeout) {\n throw error;\n }\n if (isHTTPError(error)) {\n if (!this.#options.retry.statusCodes.includes(error.response.status)) {\n throw error;\n }\n const retryAfter = error.response.headers.get('Retry-After')\n ?? error.response.headers.get('RateLimit-Reset')\n ?? error.response.headers.get('X-RateLimit-Retry-After') // Symfony-based services\n ?? error.response.headers.get('X-RateLimit-Reset') // GitHub\n ?? error.response.headers.get('X-Rate-Limit-Reset'); // Twitter\n if (retryAfter && this.#options.retry.afterStatusCodes.includes(error.response.status)) {\n let after = Number(retryAfter) * 1000;\n if (Number.isNaN(after)) {\n after = Date.parse(retryAfter) - Date.now();\n }\n else if (after >= Date.parse('2024-01-01')) {\n // A large number is treated as a timestamp (fixed threshold protects against clock skew)\n after -= Date.now();\n }\n const max = this.#options.retry.maxRetryAfter ?? after;\n // Don't apply jitter when server provides explicit retry timing\n return after < max ? after : max;\n }\n if (error.response.status === 413) {\n throw error;\n }\n }\n return this.#calculateDelay();\n }\n #decorateResponse(response) {\n if (this.#options.parseJson) {\n response.json = async () => this.#options.parseJson(await response.text());\n }\n return response;\n }\n #cancelBody(body) {\n if (!body) {\n return;\n }\n // Ignore cancellation failures from already-locked or already-consumed streams.\n void body.cancel().catch(() => undefined);\n }\n #cancelResponseBody(response) {\n // Ignore cancellation failures from already-locked or already-consumed streams.\n this.#cancelBody(response.body ?? undefined);\n }\n async #retry(function_) {\n try {\n return await function_();\n }\n catch (error) {\n const ms = Math.min(await this.#calculateRetryDelay(error), maxSafeTimeout);\n if (this.#retryCount < 1) {\n throw error;\n }\n // Only use user-provided signal for delay, not our internal abortController\n await delay(ms, this.#userProvidedAbortSignal ? { signal: this.#userProvidedAbortSignal } : {});\n // Apply custom request from forced retry before beforeRetry hooks\n // Ensure the custom request has the correct managed signal for timeouts and user aborts\n if (error instanceof ForceRetryError && error.customRequest) {\n const managedRequest = this.#options.signal\n ? new globalThis.Request(error.customRequest, { signal: this.#options.signal })\n : new globalThis.Request(error.customRequest);\n this.#assignRequest(managedRequest);\n }\n for (const hook of this.#options.hooks.beforeRetry) {\n // eslint-disable-next-line no-await-in-loop\n const hookResult = await hook({\n request: this.request,\n options: this.#getNormalizedOptions(),\n error: error,\n retryCount: this.#retryCount,\n });\n if (hookResult instanceof globalThis.Request) {\n this.#assignRequest(hookResult);\n break;\n }\n // If a Response is returned, use it and skip the retry\n if (hookResult instanceof globalThis.Response) {\n return hookResult;\n }\n // If `stop` is returned from the hook, the retry process is stopped\n if (hookResult === stop) {\n return;\n }\n }\n return this.#retry(function_);\n }\n }\n async #fetch() {\n // Reset abortController if it was aborted (happens on timeout retry)\n if (this.#abortController?.signal.aborted) {\n this.#abortController = new globalThis.AbortController();\n this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;\n // Recreate request with new signal\n this.request = new globalThis.Request(this.request, { signal: this.#options.signal });\n }\n for (const hook of this.#options.hooks.beforeRequest) {\n // eslint-disable-next-line no-await-in-loop\n const result = await hook(this.request, this.#getNormalizedOptions(), { retryCount: this.#retryCount });\n if (result instanceof Response) {\n return result;\n }\n if (result instanceof globalThis.Request) {\n this.#assignRequest(result);\n break;\n }\n }\n const nonRequestOptions = findUnknownOptions(this.request, this.#options);\n // Cloning is done here to prepare in advance for retries\n this.#originalRequest = this.request;\n this.request = this.#originalRequest.clone();\n if (this.#options.timeout === false) {\n return this.#options.fetch(this.#originalRequest, nonRequestOptions);\n }\n return timeout(this.#originalRequest, nonRequestOptions, this.#abortController, this.#options);\n }\n #getNormalizedOptions() {\n if (!this.#cachedNormalizedOptions) {\n const { hooks, ...normalizedOptions } = this.#options;\n this.#cachedNormalizedOptions = Object.freeze(normalizedOptions);\n }\n return this.#cachedNormalizedOptions;\n }\n #assignRequest(request) {\n this.#cachedNormalizedOptions = undefined;\n this.request = this.#wrapRequestWithUploadProgress(request);\n }\n #wrapRequestWithUploadProgress(request, originalBody) {\n if (!this.#options.onUploadProgress || !request.body) {\n return request;\n }\n return streamRequest(request, this.#options.onUploadProgress, originalBody ?? this.#options.body ?? undefined);\n }\n}\n//# sourceMappingURL=Ky.js.map","/*! MIT License © Sindre Sorhus */\nimport { Ky } from './core/Ky.js';\nimport { requestMethods, stop, retry } from './core/constants.js';\nimport { validateAndMerge } from './utils/merge.js';\nconst createInstance = (defaults) => {\n // eslint-disable-next-line @typescript-eslint/promise-function-async\n const ky = (input, options) => Ky.create(input, validateAndMerge(defaults, options));\n for (const method of requestMethods) {\n // eslint-disable-next-line @typescript-eslint/promise-function-async\n ky[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, { method }));\n }\n ky.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));\n ky.extend = (newDefaults) => {\n if (typeof newDefaults === 'function') {\n newDefaults = newDefaults(defaults ?? {});\n }\n return createInstance(validateAndMerge(defaults, newDefaults));\n };\n ky.stop = stop;\n ky.retry = retry;\n return ky;\n};\nconst ky = createInstance();\nexport default ky;\nexport { HTTPError } from './errors/HTTPError.js';\nexport { TimeoutError } from './errors/TimeoutError.js';\nexport { ForceRetryError } from './errors/ForceRetryError.js';\nexport { isKyError, isHTTPError, isTimeoutError, isForceRetryError, } from './utils/type-guards.js';\n// Intentionally not exporting this for now as it's just an implementation detail and we don't want to commit to a certain API yet at least.\n// export {NonError} from './errors/NonError.js';\n//# sourceMappingURL=index.js.map","import { AgentChatError } from '../lib/errors';\n\ninterface ServerErrorBody {\n error?: { code?: string; message?: string };\n message?: string | string[];\n data?: { message?: string | string[] };\n code?: string;\n}\n\nfunction normalizeServerMessage(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (Array.isArray(value)) {\n const joined = value.filter((item): item is string => typeof item === 'string').join('; ');\n return joined || undefined;\n }\n return undefined;\n}\n\nfunction isJsonContent(headers: Headers): boolean {\n const ct = headers.get('content-type') ?? '';\n return ct.includes('application/json');\n}\n\nexport async function readHttpError(response: Response): Promise<AgentChatError> {\n let serverCode: string | undefined;\n let serverMessage: string | undefined;\n let body: unknown;\n try {\n if (isJsonContent(response.headers)) {\n body = (await response.json()) as ServerErrorBody;\n const parsed = body as ServerErrorBody;\n const nestedData =\n parsed.data != null && typeof parsed.data === 'object' && !Array.isArray(parsed.data)\n ? (parsed.data as { code?: string; message?: string | string[] })\n : undefined;\n serverCode = parsed.error?.code ?? parsed.code ?? nestedData?.code;\n serverMessage =\n normalizeServerMessage(parsed.error?.message) ??\n normalizeServerMessage(parsed.message) ??\n normalizeServerMessage(parsed.data?.message) ??\n normalizeServerMessage(nestedData?.message);\n } else {\n serverMessage = (await response.text()).slice(0, 500);\n }\n } catch {\n // ignore parse errors and fall back to status text\n }\n\n const message = serverMessage\n ? `HTTP ${response.status}: ${serverMessage}`\n : `HTTP ${response.status}: ${response.statusText || 'request failed'}`;\n\n const data =\n body != null && typeof body === 'object' && !Array.isArray(body) && 'data' in body\n ? (body as { data: unknown }).data\n : body;\n\n return new AgentChatError('TRANSPORT_FAILED', message, {\n details: {\n status: response.status,\n serverCode,\n url: response.url,\n /** Full JSON body — needed for 409 `PAGE_ACTION_ALREADY_ACTIVE` soft handling. */\n body,\n data,\n },\n });\n}\n\nexport function toTransportAbortError(err: unknown, label = 'Request aborted'): AgentChatError {\n return new AgentChatError('TRANSPORT_ABORTED', label, { cause: err });\n}\n\nexport function toNetworkError(err: unknown, label = 'Network error'): AgentChatError {\n return new AgentChatError('TRANSPORT_FAILED', label, { cause: err });\n}\n\nexport function isAbortError(err: unknown): boolean {\n if (err instanceof AgentChatError && err.code === 'TRANSPORT_ABORTED') return true;\n const name = (err as { name?: string })?.name;\n return name === 'AbortError';\n}\n","class ParseError extends Error {\n constructor(message, options) {\n super(message), this.name = \"ParseError\", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line;\n }\n}\nconst LF = 10, CR = 13, SPACE = 32;\nfunction noop(_arg) {\n}\nfunction createParser(config) {\n if (typeof config == \"function\")\n throw new TypeError(\n \"`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?\"\n );\n const { onEvent = noop, onError = noop, onRetry = noop, onComment, maxBufferSize } = config, pendingFragments = [];\n let pendingFragmentsLength = 0, isFirstChunk = !0, id, data = \"\", dataLines = 0, eventType, terminated = !1;\n function feed(chunk) {\n if (terminated)\n throw new Error(\n \"Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing.\"\n );\n if (isFirstChunk && (isFirstChunk = !1, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) {\n const trailing2 = processLines(chunk);\n trailing2 !== \"\" && (pendingFragments.push(trailing2), pendingFragmentsLength = trailing2.length), checkBufferSize();\n return;\n }\n if (chunk.indexOf(`\n`) === -1 && chunk.indexOf(\"\\r\") === -1) {\n pendingFragments.push(chunk), pendingFragmentsLength += chunk.length, checkBufferSize();\n return;\n }\n pendingFragments.push(chunk);\n const input = pendingFragments.join(\"\");\n pendingFragments.length = 0, pendingFragmentsLength = 0;\n const trailing = processLines(input);\n trailing !== \"\" && (pendingFragments.push(trailing), pendingFragmentsLength = trailing.length), checkBufferSize();\n }\n function checkBufferSize() {\n maxBufferSize !== void 0 && (pendingFragmentsLength + data.length <= maxBufferSize || (terminated = !0, pendingFragments.length = 0, pendingFragmentsLength = 0, id = void 0, data = \"\", dataLines = 0, eventType = void 0, onError(\n new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {\n type: \"max-buffer-size-exceeded\"\n })\n )));\n }\n function processLines(chunk) {\n let searchIndex = 0;\n if (chunk.indexOf(\"\\r\") === -1) {\n let lfIndex = chunk.indexOf(`\n`, searchIndex);\n for (; lfIndex !== -1; ) {\n if (searchIndex === lfIndex) {\n dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = \"\", dataLines = 0, eventType = void 0, searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`\n`, searchIndex);\n continue;\n }\n const firstCharCode = chunk.charCodeAt(searchIndex);\n if (isDataPrefix(chunk, searchIndex, firstCharCode)) {\n const valueStart = chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5, value = chunk.slice(valueStart, lfIndex);\n if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {\n onEvent({ id, event: eventType, data: value }), id = void 0, data = \"\", eventType = void 0, searchIndex = lfIndex + 2, lfIndex = chunk.indexOf(`\n`, searchIndex);\n continue;\n }\n data = dataLines === 0 ? value : `${data}\n${value}`, dataLines++;\n } else isEventPrefix(chunk, searchIndex, firstCharCode) ? eventType = chunk.slice(\n chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,\n lfIndex\n ) || void 0 : parseLine(chunk, searchIndex, lfIndex);\n searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`\n`, searchIndex);\n }\n return chunk.slice(searchIndex);\n }\n for (; searchIndex < chunk.length; ) {\n const crIndex = chunk.indexOf(\"\\r\", searchIndex), lfIndex = chunk.indexOf(`\n`, searchIndex);\n let lineEnd = -1;\n if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = crIndex < lfIndex ? crIndex : lfIndex : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1)\n break;\n parseLine(chunk, searchIndex, lineEnd), searchIndex = lineEnd + 1, chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF && searchIndex++;\n }\n return chunk.slice(searchIndex);\n }\n function parseLine(chunk, start, end) {\n if (start === end) {\n dispatchEvent();\n return;\n }\n const firstCharCode = chunk.charCodeAt(start);\n if (isDataPrefix(chunk, start, firstCharCode)) {\n const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5, value2 = chunk.slice(valueStart, end);\n data = dataLines === 0 ? value2 : `${data}\n${value2}`, dataLines++;\n return;\n }\n if (isEventPrefix(chunk, start, firstCharCode)) {\n eventType = chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || void 0;\n return;\n }\n if (firstCharCode === 105 && chunk.charCodeAt(start + 1) === 100 && chunk.charCodeAt(start + 2) === 58) {\n const value2 = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end);\n value2.includes(\"\\0\") || (id = value2);\n return;\n }\n if (firstCharCode === 58) {\n if (onComment) {\n const line2 = chunk.slice(start, end);\n onComment(line2.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1));\n }\n return;\n }\n const line = chunk.slice(start, end), fieldSeparatorIndex = line.indexOf(\":\");\n if (fieldSeparatorIndex === -1) {\n processField(line, \"\", line);\n return;\n }\n const field = line.slice(0, fieldSeparatorIndex), offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset);\n processField(field, value, line);\n }\n function processField(field, value, line) {\n switch (field) {\n case \"event\":\n eventType = value || void 0;\n break;\n case \"data\":\n data = dataLines === 0 ? value : `${data}\n${value}`, dataLines++;\n break;\n case \"id\":\n value.includes(\"\\0\") || (id = value);\n break;\n case \"retry\":\n /^\\d+$/.test(value) ? onRetry(parseInt(value, 10)) : onError(\n new ParseError(`Invalid \\`retry\\` value: \"${value}\"`, {\n type: \"invalid-retry\",\n value,\n line\n })\n );\n break;\n default:\n onError(\n new ParseError(\n `Unknown field \"${field.length > 20 ? `${field.slice(0, 20)}\\u2026` : field}\"`,\n { type: \"unknown-field\", field, value, line }\n )\n );\n break;\n }\n }\n function dispatchEvent() {\n dataLines > 0 && onEvent({\n id,\n event: eventType,\n data\n }), id = void 0, data = \"\", dataLines = 0, eventType = void 0;\n }\n function reset(options = {}) {\n if (options.consume && pendingFragments.length > 0) {\n const incompleteLine = pendingFragments.join(\"\");\n parseLine(incompleteLine, 0, incompleteLine.length);\n }\n isFirstChunk = !0, id = void 0, data = \"\", dataLines = 0, eventType = void 0, pendingFragments.length = 0, pendingFragmentsLength = 0, terminated = !1;\n }\n return { feed, reset };\n}\nfunction isDataPrefix(chunk, i, firstCharCode) {\n return firstCharCode === 100 && chunk.charCodeAt(i + 1) === 97 && chunk.charCodeAt(i + 2) === 116 && chunk.charCodeAt(i + 3) === 97 && chunk.charCodeAt(i + 4) === 58;\n}\nfunction isEventPrefix(chunk, i, firstCharCode) {\n return firstCharCode === 101 && chunk.charCodeAt(i + 1) === 118 && chunk.charCodeAt(i + 2) === 101 && chunk.charCodeAt(i + 3) === 110 && chunk.charCodeAt(i + 4) === 116 && chunk.charCodeAt(i + 5) === 58;\n}\nexport {\n ParseError,\n createParser\n};\n//# sourceMappingURL=index.js.map\n","import { createParser, type EventSourceMessage } from 'eventsource-parser';\nimport { AgentChatError } from '../lib/errors';\nimport { readHttpError, toNetworkError } from './errors';\nimport type { HttpStreamOptions, SseEventChunk } from './types';\n\nfunction buildUrl(apiBase: string, path: string): string {\n const base = apiBase.replace(/\\/+$/, '');\n const tail = path.startsWith('/') ? path : `/${path}`;\n return `${base}${tail}`;\n}\n\nexport async function* readSseStream(\n fetchImpl: typeof fetch,\n url: string,\n headers: Record<string, string>,\n init: HttpStreamOptions = {},\n): AsyncIterable<SseEventChunk> {\n const method = init.method ?? (init.body !== undefined ? 'POST' : 'GET');\n\n const requestHeaders = new Headers(headers);\n for (const [key, value] of Object.entries(init.headers ?? {})) {\n requestHeaders.set(key, value);\n }\n requestHeaders.set('accept', 'text/event-stream');\n\n let body: BodyInit | undefined;\n if (init.body !== undefined && method !== 'GET' && method !== 'HEAD') {\n body = typeof init.body === 'string' ? init.body : JSON.stringify(init.body);\n if (!requestHeaders.has('content-type') && typeof init.body !== 'string') {\n requestHeaders.set('content-type', 'application/json');\n }\n }\n\n let response: Response;\n try {\n response = await fetchImpl(url, {\n method,\n headers: requestHeaders,\n body,\n signal: init.signal,\n });\n } catch (err) {\n throw toNetworkError(err);\n }\n\n if (!response.ok) throw await readHttpError(response);\n if (!response.body) {\n throw new AgentChatError('TRANSPORT_FAILED', 'SSE response has no body');\n }\n\n init.onConnected?.();\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8');\n const queue: SseEventChunk[] = [];\n const parser = createParser({\n onEvent(evt: EventSourceMessage) {\n const eventName = evt.event?.trim() ? evt.event.trim() : 'message';\n queue.push({ event: eventName, data: evt.data, id: evt.id });\n },\n });\n\n const drainQueue = (): SseEventChunk[] => queue.splice(0, queue.length);\n\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n const tail = decoder.decode();\n if (tail) parser.feed(tail);\n for (const chunk of drainQueue()) yield chunk;\n break;\n }\n parser.feed(decoder.decode(value, { stream: true }));\n for (const chunk of drainQueue()) yield chunk;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport { buildUrl };\n","import ky, { HTTPError } from 'ky';\nimport { AgentChatError } from '../lib/errors';\nimport {\n isAbortError,\n readHttpError,\n toNetworkError,\n toTransportAbortError,\n} from './errors';\nimport { buildUrl, readSseStream } from './sse';\nimport type {\n HttpClient,\n HttpClientOptions,\n HttpRequestOptions,\n HttpStreamOptions,\n SseEventChunk,\n} from './types';\n\nfunction normalizePath(path: string): string {\n return path.replace(/^\\//, '');\n}\n\nfunction mergeRequestHeaders(\n defaults: Record<string, string>,\n init: HttpRequestOptions,\n): Record<string, string> {\n const omit = new Set(\n (init.omitDefaultHeaders ?? []).map((name) => name.toLowerCase()),\n );\n const merged: Record<string, string> = {};\n for (const [name, value] of Object.entries(defaults)) {\n if (!omit.has(name.toLowerCase())) merged[name] = value;\n }\n return { ...merged, ...(init.headers ?? {}) };\n}\n\nexport function createHttpClient(options: HttpClientOptions): HttpClient {\n const apiBase = options.apiBase.replace(/\\/+$/, '');\n const defaultHeaders: Record<string, string> = { ...(options.defaultHeaders ?? {}) };\n const fetchImpl =\n options.fetch ?? (typeof fetch !== 'undefined' ? fetch.bind(globalThis) : undefined);\n\n if (!fetchImpl) {\n throw new AgentChatError(\n 'TRANSPORT_FAILED',\n 'No fetch implementation available. Provide one via HttpClientOptions.fetch.',\n );\n }\n\n const api = ky.create({\n prefixUrl: `${apiBase}/`,\n retry: { limit: 0 },\n timeout: false,\n fetch: fetchImpl,\n hooks: {\n beforeError: [\n async (error) => {\n if (error instanceof HTTPError) {\n throw await readHttpError(error.response);\n }\n if (isAbortError(error)) {\n throw toTransportAbortError(error);\n }\n throw toNetworkError(error);\n },\n ],\n },\n });\n\n return {\n setDefaultHeader(name, value) {\n if (value === undefined) delete defaultHeaders[name];\n else defaultHeaders[name] = value;\n },\n\n async request<T>(path: string, init: HttpRequestOptions = {}): Promise<T> {\n const method = init.method ?? (init.body !== undefined ? 'POST' : 'GET');\n const headers = {\n accept: 'application/json',\n ...mergeRequestHeaders(defaultHeaders, init),\n };\n\n const searchParams: Record<string, string> | undefined = init.searchParams\n ? Object.fromEntries(\n Object.entries(init.searchParams)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => [key, String(value)]),\n )\n : undefined;\n\n try {\n const response = await api(normalizePath(path), {\n method,\n headers,\n searchParams,\n json: method === 'GET' || method === 'HEAD' ? undefined : init.body,\n signal: init.signal,\n });\n\n if (response.status === 204) return undefined as T;\n\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n return await response.json<T>();\n }\n return (await response.text()) as unknown as T;\n } catch (err) {\n if (err instanceof AgentChatError) throw err;\n if (isAbortError(err)) throw toTransportAbortError(err);\n throw toNetworkError(err);\n }\n },\n\n stream(path: string, init: HttpStreamOptions = {}): AsyncIterable<SseEventChunk> {\n const url = buildUrl(apiBase, path);\n return readSseStream(fetchImpl, url, defaultHeaders, init);\n },\n };\n}\n","import { buildAppClientAuthHeaders } from '../auth/auth-headers';\nimport { parseAuthResponse } from '../auth/auth-response';\nimport type { AppClientAuthData } from '../auth/auth-types';\nimport { AgentChatError } from '../lib/errors';\nimport type { HttpClient } from '../http';\n\nexport class AuthService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /**\n * Exchange `x-app-dsn` (+ optional `x-account-token`) for a user access token\n * via `POST /app-client/auth`.\n */\n async authenticate(dsn: string, accountToken?: string | null): Promise<AppClientAuthData> {\n const body = await this.http.request<unknown>('/app-client/auth', {\n method: 'POST',\n headers: buildAppClientAuthHeaders(dsn, accountToken),\n });\n const authData = parseAuthResponse(body);\n if (!authData?.ok) {\n throw new AgentChatError('AUTH_REQUIRED', 'App client authentication failed');\n }\n return authData;\n }\n\n /** Email/password login via `POST /user/login`. */\n async login(email: string, password: string): Promise<AppClientAuthData> {\n const body = await this.http.request<unknown>('/user/login', {\n method: 'POST',\n body: { email, password },\n });\n const loginAuth = parseAuthResponse(body);\n if (!loginAuth?.accessToken) {\n throw new AgentChatError('LOGIN_FAILED', 'Login succeeded but accessToken is missing');\n }\n return loginAuth;\n }\n}\n","import type { QueryClientAvailableAgents, QueryClientSkillByAgent } from '../../types';\nimport { buildAgentClientHeaders } from '../auth/auth-headers';\nimport type { HttpClient } from '../http';\nimport { DSN_AUTH_HEADER } from '../lib/resolve';\n\nexport type AgentClientAuthContext = () => {\n dsn: string;\n};\n\nfunction compactSearchParams(\n query?: QueryClientAvailableAgents | QueryClientSkillByAgent,\n): Record<string, string | number | boolean | undefined> | undefined {\n if (!query) return undefined;\n const entries = Object.entries(query).filter(\n ([, value]) => value !== undefined && value !== '',\n );\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\nexport class AgentService {\n private http: HttpClient;\n private resolveAuth: AgentClientAuthContext;\n\n constructor(http: HttpClient, resolveAuth: AgentClientAuthContext) {\n this.http = http;\n this.resolveAuth = resolveAuth;\n }\n\n private agentRequestInit(\n dsn: string,\n init: { signal?: AbortSignal; searchParams?: Record<string, string | number | boolean | undefined> },\n ) {\n return {\n method: 'GET' as const,\n signal: init.signal,\n searchParams: init.searchParams,\n omitDefaultHeaders: [DSN_AUTH_HEADER],\n headers: buildAgentClientHeaders(dsn),\n };\n }\n\n /** `GET /agent/client/available` — role-filtered agents for C-end picker. */\n listAvailableAgents(\n query?: QueryClientAvailableAgents,\n signal?: AbortSignal,\n ): Promise<unknown> {\n const { dsn } = this.resolveAuth();\n return this.http.request(\n '/agent/client/available',\n this.agentRequestInit(dsn, { signal, searchParams: compactSearchParams(query) }),\n );\n }\n\n /** `GET /agent/client/list` — all app agents (no role filter); used for empty-state hints. */\n listAllClientAgents(signal?: AbortSignal): Promise<unknown> {\n const { dsn } = this.resolveAuth();\n return this.http.request('/agent/client/list', this.agentRequestInit(dsn, { signal }));\n }\n\n /** `GET /agent/:agentId/skills/client` — role-filtered skills for the selected agent. */\n listClientSkills(\n agentId: string,\n query?: QueryClientSkillByAgent,\n signal?: AbortSignal,\n ): Promise<unknown> {\n const { dsn } = this.resolveAuth();\n const id = agentId.trim();\n return this.http.request(\n `/agent/${id}/skills/client`,\n this.agentRequestInit(dsn, { signal, searchParams: compactSearchParams(query) }),\n );\n }\n}\n","import { AgentChatError } from '../lib/errors';\nimport type { HttpClient, HttpStreamOptions, SseEventChunk } from '../http';\nimport type { AgentChatPageContext, WriteGate } from '../../types';\nimport type { CancelRunResult } from '../chat/session-run';\nimport { parseCancelRunResponse } from '../chat/session-run';\n\nexport const DEFAULT_SESSION_PAGE_SIZE = 20;\nexport const DEFAULT_MESSAGE_PAGE_SIZE = 20;\n\nexport interface MessageSendContext {\n agentId?: string;\n skillId?: string;\n page?: string;\n routePath?: string;\n routeParams?: Record<string, string>;\n flowId?: number;\n programName?: string;\n entity?: AgentChatPageContext['entity'];\n metadata?: Record<string, unknown>;\n /** Brain clarify continuation — structured entity pick. */\n entityCommit?: { entityType: string; selectedId: string };\n}\n\n/** Response from `POST /chat/{sessionId}/prepare` (host-tool warm + runtime cache). */\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\n/** Build nested + flat pageContext fields for prepare / message bodies. */\nexport function buildPageContextRequestBody(\n pageContext: AgentChatPageContext,\n): Record<string, unknown> {\n const body: Record<string, unknown> = { pageContext };\n if (pageContext.page) body.page = pageContext.page;\n if (pageContext.routePath) body.routePath = pageContext.routePath;\n if (pageContext.routeParams) body.routeParams = pageContext.routeParams;\n if (pageContext.flowId != null) body.flowId = pageContext.flowId;\n if (pageContext.programName) body.programName = pageContext.programName;\n if (pageContext.entity) body.entity = pageContext.entity;\n if (pageContext.metadata) body.metadata = pageContext.metadata;\n return body;\n}\n\nfunction isContentFieldRejected(error: unknown): boolean {\n if (!(error instanceof AgentChatError)) return false;\n if (error.code !== 'TRANSPORT_FAILED') return false;\n const msg = error.message.toLowerCase();\n return msg.includes('property content should not exist');\n}\n\nfunction normalizeSessionId(sessionId: string): string {\n return sessionId.trim().toLowerCase();\n}\n\nexport class ChatService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n listSessions(\n page: number,\n size: number,\n signal?: AbortSignal,\n ): Promise<unknown> {\n return this.http.request('/chat', {\n method: 'GET',\n signal,\n searchParams: { page, size },\n });\n }\n\n getSession(\n sessionId: string,\n page: number,\n size: number,\n signal?: AbortSignal,\n ): Promise<unknown> {\n return this.http.request(`/chat/${normalizeSessionId(sessionId)}`, {\n method: 'GET',\n signal,\n searchParams: { page, size },\n });\n }\n\n prepareSession(\n sessionId: string,\n pageContext?: AgentChatPageContext | null,\n signal?: AbortSignal,\n ): Promise<PrepareSessionResult> {\n const body =\n pageContext && Object.keys(pageContext).length > 0\n ? buildPageContextRequestBody(pageContext)\n : undefined;\n return this.http.request(`/chat/${normalizeSessionId(sessionId)}/prepare`, {\n method: 'POST',\n body,\n signal,\n }) as Promise<PrepareSessionResult>;\n }\n\n deleteSession(sessionId: string): Promise<void> {\n return this.http.request(`/chat/${normalizeSessionId(sessionId)}`, {\n method: 'DELETE',\n });\n }\n\n streamSession(\n sessionId: string,\n init?: Omit<HttpStreamOptions, 'method'>,\n ): AsyncIterable<SseEventChunk> {\n return this.http.stream(`/chat/${normalizeSessionId(sessionId)}/stream`, init);\n }\n\n /** `GET /chat/{sessionId}/run-state` — authoritative session generation for SSE filtering. */\n getRunState(sessionId: string, signal?: AbortSignal): Promise<unknown> {\n return this.http.request(`/chat/${normalizeSessionId(sessionId)}/run-state`, {\n method: 'GET',\n signal,\n });\n }\n\n /** `POST /chat` — create session with the first user message. */\n createSession(\n content: string,\n signal: AbortSignal,\n context?: MessageSendContext,\n ): Promise<unknown> {\n return this.postUserPayload('/chat', content, signal, context);\n }\n\n /** `POST /chat/{sessionId}/messages` */\n postMessage(\n sessionId: string,\n content: string,\n signal: AbortSignal,\n context?: MessageSendContext,\n ): Promise<unknown> {\n return this.postUserPayload(`/chat/${sessionId}/messages`, content, signal, context);\n }\n\n postWriteGateDecision(\n sessionId: string,\n writeGate: WriteGate,\n signal: AbortSignal,\n ): Promise<unknown> {\n const path = `/chat/${normalizeSessionId(sessionId)}/messages`;\n const body = { role: 'user', content: '', writeGate };\n return this.postUserPayload(path, '', signal, undefined, body);\n }\n\n /** @deprecated Use `postWriteGateDecision` with `writeGate.action`. */\n postWriteConfirmation(\n sessionId: string,\n flags: { confirmWrite?: true; cancelWrite?: true },\n signal: AbortSignal,\n ): Promise<unknown> {\n const writeGate: WriteGate =\n flags.cancelWrite === true ? { action: 'cancel' } : { action: 'confirm' };\n return this.postWriteGateDecision(sessionId, writeGate, signal);\n }\n\n /** `POST /chat/{sessionId}/cancel-run` — stop the active agent run (SUPERSEDE). */\n async cancelRun(sessionId: string, runId?: number): Promise<CancelRunResult> {\n const body: Record<string, unknown> = {};\n if (runId != null) body.runId = runId;\n const response = await this.http.request(`/chat/${normalizeSessionId(sessionId)}/cancel-run`, {\n method: 'POST',\n body: Object.keys(body).length > 0 ? body : undefined,\n });\n return parseCancelRunResponse(response);\n }\n\n private async postUserPayload(\n path: string,\n text: string,\n signal: AbortSignal,\n context?: MessageSendContext,\n bodyOverride?: Record<string, unknown>,\n ): Promise<unknown> {\n const body = bodyOverride ?? this.buildUserMessageBody(text, context);\n try {\n return await this.http.request(path, {\n method: 'POST',\n body,\n signal,\n });\n } catch (error) {\n if (!isContentFieldRejected(error)) throw error;\n const { content, ...rest } = body;\n return this.http.request(path, {\n method: 'POST',\n body: { ...rest, message: content },\n signal,\n });\n }\n }\n\n private buildUserMessageBody(\n text: string,\n context?: MessageSendContext,\n ): Record<string, unknown> {\n const body: Record<string, unknown> = { role: 'user', content: text };\n const agentId = context?.agentId?.trim();\n const skillId = context?.skillId?.trim();\n if (agentId) {\n body.agentId = /^\\d+$/.test(agentId) ? Number(agentId) : agentId;\n }\n if (skillId) {\n body.skillId = /^\\d+$/.test(skillId) ? Number(skillId) : skillId;\n }\n const pageContext = pickPageContextFields(context);\n if (pageContext) {\n Object.assign(body, buildPageContextRequestBody(pageContext));\n }\n if (\n context?.entityCommit?.entityType?.trim() &&\n context?.entityCommit?.selectedId?.trim()\n ) {\n body.entityCommit = {\n entityType: context.entityCommit.entityType.trim(),\n selectedId: context.entityCommit.selectedId.trim(),\n };\n }\n return body;\n }\n}\n\nfunction pickPageContextFields(\n context?: MessageSendContext,\n): AgentChatPageContext | null {\n if (!context) return null;\n const pageContext: AgentChatPageContext = {};\n if (context.page) pageContext.page = context.page;\n if (context.routePath) pageContext.routePath = context.routePath;\n if (context.routeParams) pageContext.routeParams = context.routeParams;\n if (context.flowId != null) pageContext.flowId = context.flowId;\n if (context.programName) pageContext.programName = context.programName;\n if (context.entity) pageContext.entity = context.entity;\n if (context.metadata) pageContext.metadata = context.metadata;\n return Object.keys(pageContext).length > 0 ? pageContext : null;\n}\n","import { AgentChatError } from './errors';\nimport { unwrapApiData } from '../auth/auth-response';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object';\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\n/**\n * Unwrap `{ status, message, data }` from ReqInterceptor. Throws when\n * `status !== 200` even if HTTP status is 200.\n */\nexport function parseApiEnvelope<T>(body: unknown): T {\n if (!isRecord(body)) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid API response');\n }\n\n const status = readNumber(body.status);\n if (status !== undefined && status !== 200) {\n throw new AgentChatError(\n 'TRANSPORT_FAILED',\n readString(body.message) ?? 'request failed',\n { details: { status, data: body.data } },\n );\n }\n\n if ('data' in body && body.data === null) {\n return null as T;\n }\n\n const data = unwrapApiData(body);\n if (data !== null) return data as T;\n return body as T;\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport {\n parseDownReasonTags,\n parseMessageFeedbackBatch,\n parseMessageFeedbackView,\n} from '../chat/chat-response';\nimport type { HttpClient } from '../http';\nimport type {\n MessageFeedbackBatchData,\n MessageFeedbackDownReasonTag,\n MessageFeedbackView,\n UpsertMessageFeedbackBody,\n} from '../../types';\n\nfunction normalizeSessionId(sessionId: string): string {\n return sessionId.trim().toLowerCase();\n}\n\nexport class FeedbackService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `GET /chat/feedback/down-reason-tags` */\n async getDownReasonTags(signal?: AbortSignal): Promise<MessageFeedbackDownReasonTag[]> {\n const body = await this.http.request<unknown>('/chat/feedback/down-reason-tags', {\n method: 'GET',\n signal,\n });\n return parseDownReasonTags(parseApiEnvelope(body)).items;\n }\n\n /** `GET /chat/:sessionId/messages/feedbacks?messageIds=…` */\n async batchFeedbacks(\n sessionId: string,\n messageIds: number[],\n signal?: AbortSignal,\n ): Promise<MessageFeedbackBatchData> {\n if (messageIds.length === 0) return { items: [] };\n const body = await this.http.request<unknown>(\n `/chat/${normalizeSessionId(sessionId)}/messages/feedbacks`,\n {\n method: 'GET',\n signal,\n searchParams: { messageIds: messageIds.join(',') },\n },\n );\n return parseMessageFeedbackBatch(parseApiEnvelope(body));\n }\n\n /** `PUT /chat/:sessionId/messages/:messageId/feedback` */\n async upsert(\n sessionId: string,\n messageId: number,\n payload: UpsertMessageFeedbackBody,\n signal?: AbortSignal,\n ): Promise<MessageFeedbackView> {\n const body = await this.http.request<unknown>(\n `/chat/${normalizeSessionId(sessionId)}/messages/${messageId}/feedback`,\n {\n method: 'PUT',\n body: payload,\n signal,\n },\n );\n return parseMessageFeedbackView(parseApiEnvelope(body));\n }\n\n /** `DELETE /chat/:sessionId/messages/:messageId/feedback` */\n async remove(\n sessionId: string,\n messageId: number,\n signal?: AbortSignal,\n ): Promise<void> {\n const body = await this.http.request<unknown>(\n `/chat/${normalizeSessionId(sessionId)}/messages/${messageId}/feedback`,\n {\n method: 'DELETE',\n signal,\n },\n );\n parseApiEnvelope<null>(body);\n }\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport type { HttpClient } from '../http';\nimport type { HostToolDefinition } from '../../types';\n\nexport type HostToolRegisterBody = {\n scope?: string;\n pageLabel?: string;\n routePattern?: string;\n tools: Array<Omit<HostToolDefinition, 'handler'>>;\n};\n\nexport type HostToolRegisterItem = {\n name: string;\n id?: number;\n created?: boolean;\n reason?: string;\n};\n\nexport type HostToolRegisterResult = {\n created: HostToolRegisterItem[];\n skipped: HostToolRegisterItem[];\n};\n\nexport type HostToolCatalogQuery = {\n scope?: string;\n agentId?: number;\n};\n\nexport class HostToolService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `POST /host-tool/client/register` — idempotent metadata sync (no handler). */\n async register(body: HostToolRegisterBody): Promise<HostToolRegisterResult> {\n const raw = await this.http.request<unknown>('/host-tool/client/register', {\n method: 'POST',\n body,\n });\n const data = parseApiEnvelope<Partial<HostToolRegisterResult>>(raw);\n return {\n created: Array.isArray(data?.created) ? data.created : [],\n skipped: Array.isArray(data?.skipped) ? data.skipped : [],\n };\n }\n\n /** `GET /host-tool/client/catalog` — optional local vs server catalog check. */\n async getCatalog(query?: HostToolCatalogQuery): Promise<unknown> {\n const raw = await this.http.request<unknown>('/host-tool/client/catalog', {\n method: 'GET',\n searchParams: query,\n });\n return parseApiEnvelope(raw);\n }\n}\n","import type { HttpClient } from '../http';\n\n/** `GET /agent-run/by-app-client/:appClientId/:id` */\nexport class AgentRunService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n getRun(appClientId: number, runId: number, signal?: AbortSignal): Promise<unknown> {\n return this.http.request(`/agent-run/by-app-client/${appClientId}/${runId}`, {\n method: 'GET',\n signal,\n });\n }\n}\n","import type { AgentChatPageContext, AgentChatRouteContext } from '../../types';\n\nfunction isNonEmptyRecord(\n value: Record<string, string> | null | undefined,\n): value is Record<string, string> {\n return Boolean(value && Object.keys(value).length > 0);\n}\n\n/**\n * Build the pageContext snapshot written on PageAction invoke.\n * Prefer host-provided fields; fill missing route from {@link AgentChatRouteContext}.\n */\nexport function buildPageActionInvokePageContextSnapshot(input: {\n pageContext?: AgentChatPageContext | null;\n routeContext?: AgentChatRouteContext | null;\n}): AgentChatPageContext | undefined {\n const page = input.pageContext;\n const route = input.routeContext;\n const out: AgentChatPageContext = {};\n\n if (page?.page?.trim()) out.page = page.page.trim();\n if (page?.flowId != null) out.flowId = page.flowId;\n if (page?.programName?.trim()) out.programName = page.programName.trim();\n if (page?.entity) out.entity = page.entity;\n if (page?.metadata && Object.keys(page.metadata).length > 0) {\n out.metadata = page.metadata;\n }\n\n const routePath = page?.routePath?.trim() || route?.routePath?.trim();\n if (routePath) out.routePath = routePath;\n\n const routeParams =\n (isNonEmptyRecord(page?.routeParams) ? page!.routeParams : undefined) ??\n (isNonEmptyRecord(route?.routeParams) ? route!.routeParams : undefined);\n if (routeParams) out.routeParams = routeParams;\n\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/** Parse API / unknown JSON into {@link AgentChatPageContext} (best-effort). */\nexport function parseAgentChatPageContext(value: unknown): AgentChatPageContext | null {\n if (value == null) return null;\n if (typeof value !== 'object' || Array.isArray(value)) return null;\n const row = value as Record<string, unknown>;\n const out: AgentChatPageContext = {};\n\n if (typeof row.page === 'string' && row.page.trim()) out.page = row.page.trim();\n if (typeof row.routePath === 'string' && row.routePath.trim()) {\n out.routePath = row.routePath.trim();\n }\n if (typeof row.programName === 'string' && row.programName.trim()) {\n out.programName = row.programName.trim();\n }\n if (typeof row.flowId === 'number' && Number.isFinite(row.flowId)) {\n out.flowId = row.flowId;\n }\n\n if (row.routeParams && typeof row.routeParams === 'object' && !Array.isArray(row.routeParams)) {\n const params: Record<string, string> = {};\n for (const [key, raw] of Object.entries(row.routeParams as Record<string, unknown>)) {\n if (typeof raw === 'string') params[key] = raw;\n else if (typeof raw === 'number' || typeof raw === 'boolean') params[key] = String(raw);\n }\n if (Object.keys(params).length > 0) out.routeParams = params;\n }\n\n if (row.entity && typeof row.entity === 'object' && !Array.isArray(row.entity)) {\n out.entity = row.entity as AgentChatPageContext['entity'];\n }\n\n if (row.metadata && typeof row.metadata === 'object' && !Array.isArray(row.metadata)) {\n out.metadata = row.metadata as Record<string, unknown>;\n }\n\n return Object.keys(out).length > 0 ? out : null;\n}\n","import type {\n AutomationTaskDetail,\n AutomationTaskList,\n AutomationTaskListItem,\n AutomationTaskRef,\n AutomationTaskStatus,\n AutomationTaskTimelineEntry,\n AutomationTriggerSource,\n InvokePageActionAccepted,\n PageActionAlreadyActive,\n PageActionInvokeResult,\n PageActionReusableItem,\n PageActionReuseHint,\n} from '../../types';\nimport { parseAgentChatPageContext } from '../page/page-context-snapshot';\nimport { parseBrainClarifyPayload } from '../page/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 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 readTaskStatus(value: unknown): AutomationTaskStatus | undefined {\n const raw = readString(value);\n if (\n raw === 'running' ||\n raw === 'awaiting_approval' ||\n raw === 'completed' ||\n raw === 'failed' ||\n raw === 'cancelled'\n ) {\n return raw;\n }\n return undefined;\n}\n\nfunction readTriggerSource(value: unknown): AutomationTriggerSource | undefined {\n const raw = readString(value);\n if (raw === 'page_action' || raw === 'webhook') return raw;\n return undefined;\n}\n\nfunction parseTaskRef(value: unknown): AutomationTaskRef | null {\n if (!isRecord(value)) return null;\n const kind = readString(value.kind);\n const id = readNumber(value.id);\n if (id == null) return null;\n if (kind === 'page_action_run') return { kind: 'page_action_run', id };\n if (kind === 'webhook_approval') return { kind: 'webhook_approval', id };\n return null;\n}\n\nfunction parseOutputs(value: unknown): AutomationTaskListItem['outputs'] {\n if (!isRecord(value)) {\n return { preview: null, hasFillText: false };\n }\n const preview =\n value.preview === null ? null : (readString(value.preview) ?? null);\n return {\n preview,\n hasFillText: value.hasFillText === true,\n };\n}\n\nfunction parseApproval(value: unknown): AutomationTaskListItem['approval'] {\n if (!isRecord(value)) return null;\n const id = readNumber(value.id);\n const status = readString(value.status);\n if (id == null || !status) return null;\n return { id, status };\n}\n\nfunction parseTimelineEntry(value: unknown): AutomationTaskTimelineEntry | null {\n if (!isRecord(value)) return null;\n const step = readNumber(value.step);\n const type = readString(value.type);\n const name = readString(value.name);\n const at = readString(value.at);\n if (step == null || !type || !name || !at) return null;\n const status = readString(value.status);\n return {\n step,\n type,\n name,\n at,\n ...(status === 'ok' || status === 'failed' || status === 'skipped'\n ? { status }\n : {}),\n };\n}\n\nfunction parseListItem(row: unknown): AutomationTaskListItem | null {\n if (!isRecord(row)) return null;\n const ref = parseTaskRef(row.ref);\n const triggerSource = readTriggerSource(row.triggerSource);\n const taskStatus = readTaskStatus(row.taskStatus);\n const title = readString(row.title);\n const createdAt = readString(row.createdAt);\n if (!ref || !triggerSource || !taskStatus || !title || !createdAt) return null;\n return {\n ref,\n triggerSource,\n taskStatus,\n title,\n subtitle: row.subtitle === null ? null : (readString(row.subtitle) ?? null),\n workflowKey: row.workflowKey === null ? null : (readString(row.workflowKey) ?? null),\n workflowName:\n row.workflowName === null ? null : (readString(row.workflowName) ?? null),\n pageActionKey: row.pageActionKey === null ? null : (readString(row.pageActionKey) ?? null),\n createdAt,\n finishedAt: row.finishedAt === null ? null : (readString(row.finishedAt) ?? null),\n durationMs: row.durationMs === null ? null : (readNumber(row.durationMs) ?? null),\n approval: parseApproval(row.approval),\n outputs: parseOutputs(row.outputs),\n };\n}\n\n/** Parse `GET /automation/tasks` body. */\nexport function parseAutomationTaskList(body: unknown, limit = 20): AutomationTaskList {\n const record = isRecord(body) ? body : null;\n const total = readNumber(record?.total) ?? readNumber(record?.totalCount) ?? 0;\n const itemsRaw = Array.isArray(record?.items) ? record.items : [];\n const items = itemsRaw\n .map((row) => parseListItem(row))\n .filter((row): row is AutomationTaskListItem => row != null);\n return {\n items,\n total,\n hasMore: resolveAutomationTaskListHasMore(items.length, items.length, total, limit),\n };\n}\n\n/** Whether more pages exist after merging the latest page into the loaded list. */\nexport function resolveAutomationTaskListHasMore(\n loadedItemCount: number,\n pageItemCount: number,\n total: number,\n limit: number,\n): boolean {\n if (total > 0) return loadedItemCount < total;\n return pageItemCount >= limit;\n}\n\nfunction parseReplayBlock(\n raw: unknown,\n base: AutomationTaskListItem,\n body: Record<string, unknown>,\n): AutomationTaskDetail['replay'] {\n if (isRecord(raw)) {\n return {\n canReplay: raw.canReplay === true,\n hasHostAction: raw.hasHostAction === true,\n dslOutcome: typeof raw.dslOutcome === 'string' ? raw.dslOutcome : null,\n };\n }\n const hasFillText = Boolean(base.outputs?.hasFillText);\n return {\n canReplay: base.taskStatus === 'completed' && hasFillText,\n hasHostAction: hasFillText,\n dslOutcome: typeof body.dslOutcome === 'string' ? body.dslOutcome : null,\n };\n}\n\n/** Parse `GET /automation/tasks/page_action_run/:id` body. */\nexport function parseAutomationTaskDetail(body: unknown): AutomationTaskDetail | null {\n if (!isRecord(body)) return null;\n const base = parseListItem(body);\n if (!base) return null;\n const actionKey = readString(body.actionKey);\n const streamUrl = readString(body.streamUrl);\n if (!actionKey || !streamUrl) return null;\n const timelineRaw = Array.isArray(body.timeline) ? body.timeline : [];\n const timeline = timelineRaw\n .map((row) => parseTimelineEntry(row))\n .filter((row): row is AutomationTaskTimelineEntry => row != null);\n return {\n ...base,\n actionKey,\n instruction: body.instruction === null ? null : (readString(body.instruction) ?? null),\n errorCode: body.errorCode === null ? null : (readString(body.errorCode) ?? null),\n errorMessage:\n body.errorMessage === null ? null : (readString(body.errorMessage) ?? null),\n streamUrl,\n timeline,\n workflowRun: body.workflowRun ?? null,\n brainClarify: parseBrainClarifyPayload(body.brainClarify),\n pageContext:\n body.pageContext === null || body.pageContext === undefined\n ? null\n : parseAgentChatPageContext(body.pageContext),\n replay: parseReplayBlock(body.replay, base, body),\n };\n}\n\n/** Parse `POST /page-action/brain-invoke` accepted payload. */\nexport function parseInvokePageActionAccepted(body: unknown): InvokePageActionAccepted {\n if (!isRecord(body)) {\n throw new Error('Invalid page-action invoke response');\n }\n const runId = readNumber(body.runId);\n const generation = readNumber(body.generation);\n const streamUrl = readString(body.streamUrl);\n const status = readTaskStatus(body.status);\n if (runId == null || generation == null || !streamUrl || !status) {\n throw new Error('Invalid page-action invoke response');\n }\n return {\n runId,\n generation,\n clientActionId:\n body.clientActionId === null\n ? null\n : (readString(body.clientActionId) ?? null),\n pageActionKey: body.pageActionKey === null ? null : (readString(body.pageActionKey) ?? null),\n streamUrl,\n status,\n };\n}\n\nfunction parseExistingStatus(\n value: unknown,\n): 'running' | 'awaiting_approval' | undefined {\n const raw = readString(value);\n if (raw === 'running' || raw === 'awaiting_approval') return raw;\n return undefined;\n}\n\n/** Parse `POST /page-action/brain-invoke` conflict payload (`PAGE_ACTION_ALREADY_ACTIVE`). */\nexport function parsePageActionAlreadyActive(body: unknown): PageActionAlreadyActive {\n if (!isRecord(body)) {\n throw new Error('Invalid page-action already-active response');\n }\n const code = readString(body.code);\n const pageActionKey = readString(body.pageActionKey);\n const existingRunId = readNumber(body.existingRunId);\n const existingStatus = parseExistingStatus(body.existingStatus);\n const streamUrl = readString(body.streamUrl);\n if (\n code !== 'PAGE_ACTION_ALREADY_ACTIVE' ||\n !pageActionKey ||\n existingRunId == null ||\n !existingStatus ||\n !streamUrl\n ) {\n throw new Error('Invalid page-action already-active response');\n }\n const approvalRequestId = readNumber(body.approvalRequestId);\n return {\n code: 'PAGE_ACTION_ALREADY_ACTIVE',\n message: readString(body.message) ?? 'An active PageAction run already exists',\n pageActionKey,\n existingRunId,\n existingStatus,\n approvalRequestId: approvalRequestId ?? null,\n streamUrl,\n };\n}\n\n/** Parse invoke envelope — accepted (200) or already active (409). */\nexport function parsePageActionInvokeResult(body: unknown): PageActionInvokeResult {\n if (!isRecord(body)) {\n throw new Error('Invalid page-action invoke response');\n }\n const status = readNumber(body.status);\n if (status === 409) {\n return { kind: 'already_active', ...parsePageActionAlreadyActive(body.data) };\n }\n if (status !== undefined && status !== 200) {\n throw new Error(readString(body.message) ?? 'page-action invoke failed');\n }\n const data = isRecord(body.data) ? body.data : body;\n return { kind: 'accepted', ...parseInvokePageActionAccepted(data) };\n}\n\nfunction parseReusableItem(row: unknown): PageActionReusableItem | null {\n if (!isRecord(row)) return null;\n const ref = parseTaskRef(row.ref);\n const triggerSource = readTriggerSource(row.triggerSource);\n const taskStatus = readTaskStatus(row.taskStatus);\n const title = readString(row.title);\n const createdAt = readString(row.createdAt);\n if (!ref || ref.kind !== 'page_action_run' || !triggerSource || !taskStatus || !title || !createdAt) {\n return null;\n }\n const outputsRaw = isRecord(row.outputs) ? row.outputs : null;\n const preview =\n outputsRaw?.preview === null ? null : (readString(outputsRaw?.preview) ?? null);\n const fillText =\n outputsRaw?.fillText === null ? null : (readString(outputsRaw?.fillText) ?? null);\n const runUserId = readNumber(row.runUserId);\n return {\n ref,\n triggerSource,\n taskStatus,\n title,\n subtitle: row.subtitle === null ? null : (readString(row.subtitle) ?? null),\n pageActionKey:\n row.pageActionKey === null ? null : (readString(row.pageActionKey) ?? null),\n createdAt,\n finishedAt: row.finishedAt === null ? null : (readString(row.finishedAt) ?? null),\n outputs: {\n preview,\n fillText: fillText ?? undefined,\n hasFillText: outputsRaw?.hasFillText === true || Boolean(fillText?.trim()),\n },\n ...(row.succeeded === true || row.succeeded === false ? { succeeded: row.succeeded } : {}),\n ...(runUserId != null ? { runUserId } : {}),\n };\n}\n\n/** Parse `POST /page-action/reuse-hint` body. */\nexport function parsePageActionReuseHint(body: unknown): PageActionReuseHint {\n const root = isRecord(body) ? body : null;\n if (!root) {\n throw new Error('Invalid page-action reuse-hint response');\n }\n\n // Envelope `{ status, data }` — non-200 (e.g. route missing) must not look like a hint.\n const envelopeStatus = readNumber(root.status);\n if (envelopeStatus !== undefined && envelopeStatus !== 200) {\n throw new Error(\n readString(root.message) ?? `page-action reuse-hint failed (${envelopeStatus})`,\n );\n }\n\n const data = isRecord(root.data) ? root.data : root;\n const pageActionKey = readString(data.pageActionKey);\n const actionKey = readString(data.actionKey);\n if (!pageActionKey || !actionKey) {\n throw new Error('Invalid page-action reuse-hint response');\n }\n const reusableRaw = isRecord(data.reusable) ? data.reusable : null;\n const itemsRaw = Array.isArray(reusableRaw?.items) ? reusableRaw.items : [];\n const items = itemsRaw\n .map((row) => parseReusableItem(row))\n .filter((row): row is PageActionReusableItem => row != null);\n const total = readNumber(reusableRaw?.total) ?? items.length;\n return {\n pageActionKey,\n actionKey,\n reusable: { total, items },\n };\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport type {\n PageActionCatalogMyFeedback,\n PageActionFeedbackCatalogItem,\n PageActionFeedbackSummary,\n PageActionFeedbackView,\n PageActionWishList,\n PageActionWishStatus,\n PageActionWishView,\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 | 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\nconst WISH_STATUSES: ReadonlySet<string> = new Set([\n 'submitted',\n 'reviewing',\n 'planned',\n 'in_progress',\n 'done',\n 'rejected',\n 'cancelled',\n]);\n\nfunction readWishStatus(value: unknown): PageActionWishStatus | undefined {\n const raw = readString(value);\n if (raw && WISH_STATUSES.has(raw)) return raw as PageActionWishStatus;\n return undefined;\n}\n\nfunction parseCatalogMyFeedback(raw: unknown): PageActionCatalogMyFeedback | null {\n if (raw == null) return null;\n if (!isRecord(raw)) return null;\n const rating = readNumber(raw.rating);\n const updatedAt = readString(raw.updatedAt);\n if (rating == null || rating < 1 || rating > 5 || !updatedAt) return null;\n return {\n rating,\n comment: raw.comment === null ? null : (readString(raw.comment) ?? null),\n updatedAt,\n };\n}\n\nfunction parseCatalogItem(raw: unknown): PageActionFeedbackCatalogItem | null {\n if (!isRecord(raw)) return null;\n const actionKey = readString(raw.actionKey);\n const name = readString(raw.name);\n const pageActionId = readNumber(raw.pageActionId);\n if (!actionKey || !name || pageActionId == null) return null;\n return {\n pageActionId,\n actionKey,\n name,\n description: raw.description === null ? null : (readString(raw.description) ?? null),\n pageScope: raw.pageScope === null ? null : (readString(raw.pageScope) ?? null),\n sortOrder: readNumber(raw.sortOrder) ?? 0,\n myFeedback: parseCatalogMyFeedback(raw.myFeedback),\n };\n}\n\nfunction parseFeedbackView(raw: unknown): PageActionFeedbackView | null {\n if (!isRecord(raw)) return null;\n const id = readNumber(raw.id);\n const pageActionId = readNumber(raw.pageActionId);\n const actionKey = readString(raw.actionKey);\n const pageActionName = readString(raw.pageActionName);\n const appClientId = readNumber(raw.appClientId);\n const userId = readNumber(raw.userId);\n const rating = readNumber(raw.rating);\n const createdAt = readString(raw.createdAt);\n const updatedAt = readString(raw.updatedAt);\n if (\n id == null ||\n pageActionId == null ||\n !actionKey ||\n !pageActionName ||\n appClientId == null ||\n userId == null ||\n rating == null ||\n !createdAt ||\n !updatedAt\n ) {\n return null;\n }\n return {\n id,\n pageActionId,\n actionKey,\n pageActionName,\n appClientId,\n userId,\n rating,\n comment: raw.comment === null ? null : (readString(raw.comment) ?? null),\n createdAt,\n updatedAt,\n };\n}\n\nfunction emptyDistribution(): PageActionFeedbackSummary['ratingDistribution'] {\n return { '1': 0, '2': 0, '3': 0, '4': 0, '5': 0 };\n}\n\nfunction parseDistribution(\n raw: unknown,\n): PageActionFeedbackSummary['ratingDistribution'] {\n const base = emptyDistribution();\n if (!isRecord(raw)) return base;\n for (const key of ['1', '2', '3', '4', '5'] as const) {\n const n = readNumber(raw[key]);\n if (n != null) base[key] = n;\n }\n return base;\n}\n\nfunction parseFeedbackSummary(raw: unknown): PageActionFeedbackSummary | null {\n if (!isRecord(raw)) return null;\n const pageActionId = readNumber(raw.pageActionId);\n const actionKey = readString(raw.actionKey);\n const pageActionName = readString(raw.pageActionName);\n const count = readNumber(raw.count);\n if (pageActionId == null || !actionKey || !pageActionName || count == null) {\n return null;\n }\n const avg =\n raw.avgRating === null || raw.avgRating === undefined\n ? null\n : (readNumber(raw.avgRating) ?? null);\n return {\n pageActionId,\n actionKey,\n pageActionName,\n count,\n avgRating: avg,\n ratingDistribution: parseDistribution(raw.ratingDistribution),\n };\n}\n\nfunction parseWishView(raw: unknown): PageActionWishView | null {\n if (!isRecord(raw)) return null;\n const id = readNumber(raw.id);\n const appClientId = readNumber(raw.appClientId);\n const userId = readNumber(raw.userId);\n const title = readString(raw.title);\n const description = readString(raw.description);\n const status = readWishStatus(raw.status);\n const createdAt = readString(raw.createdAt);\n const updatedAt = readString(raw.updatedAt);\n if (\n id == null ||\n appClientId == null ||\n userId == null ||\n !title ||\n !description ||\n !status ||\n !createdAt ||\n !updatedAt\n ) {\n return null;\n }\n return {\n id,\n appClientId,\n userId,\n title,\n description,\n pageScope: raw.pageScope === null ? null : (readString(raw.pageScope) ?? null),\n relatedActionKey:\n raw.relatedActionKey === null\n ? null\n : (readString(raw.relatedActionKey) ?? null),\n status,\n developerNote:\n raw.developerNote === null ? null : (readString(raw.developerNote) ?? null),\n statusUpdatedAt:\n raw.statusUpdatedAt === null\n ? null\n : (readString(raw.statusUpdatedAt) ?? null),\n createdAt,\n updatedAt,\n };\n}\n\n/** Parse `GET /page-action/catalog` (`data.items`; keep server sort order). */\nexport function parsePageActionFeedbackCatalog(body: unknown): PageActionFeedbackCatalogItem[] {\n const data = parseApiEnvelope<unknown>(body);\n const rows = Array.isArray(data)\n ? data\n : isRecord(data) && Array.isArray(data.items)\n ? data.items\n : [];\n const seen = new Set<string>();\n const items: PageActionFeedbackCatalogItem[] = [];\n for (const row of rows) {\n const item = parseCatalogItem(row);\n if (!item || seen.has(item.actionKey)) continue;\n seen.add(item.actionKey);\n items.push(item);\n }\n return items;\n}\n\n/** Parse `GET|PUT /page-action/feedback/:actionKey` (`data` may be null). */\nexport function parsePageActionFeedbackView(body: unknown): PageActionFeedbackView | null {\n const data = parseApiEnvelope<unknown>(body);\n if (data == null) return null;\n return parseFeedbackView(data);\n}\n\n/** Parse `GET /page-action/feedback/:actionKey/summary`. */\nexport function parsePageActionFeedbackSummary(body: unknown): PageActionFeedbackSummary {\n const data = parseApiEnvelope<unknown>(body);\n const parsed = parseFeedbackSummary(data);\n if (!parsed) {\n throw new Error('Invalid page-action feedback summary');\n }\n return parsed;\n}\n\n/** Parse wish create / detail / cancel. */\nexport function parsePageActionWishView(body: unknown): PageActionWishView {\n const data = parseApiEnvelope<unknown>(body);\n const parsed = parseWishView(data);\n if (!parsed) {\n throw new Error('Invalid page-action wish');\n }\n return parsed;\n}\n\n/** Parse `GET /page-action/wishes` paginated list. */\nexport function parsePageActionWishList(body: unknown): PageActionWishList {\n const data = parseApiEnvelope<unknown>(body);\n if (!isRecord(data)) {\n return { items: [], total: 0, page: 1, pageSize: 20, hasMore: false };\n }\n const itemsRaw = Array.isArray(data.items) ? data.items : [];\n const items = itemsRaw\n .map((row) => parseWishView(row))\n .filter((row): row is PageActionWishView => row != null);\n const total = readNumber(data.total) ?? items.length;\n const page = readNumber(data.page) ?? 1;\n const pageSize = readNumber(data.pageSize) ?? 20;\n const hasMore =\n typeof data.hasMore === 'boolean'\n ? data.hasMore\n : page * pageSize < total;\n return { items, total, page, pageSize, hasMore };\n}\n","import { AgentChatError } from '../lib/errors';\nimport {\n parsePageActionAlreadyActive,\n parsePageActionInvokeResult,\n parsePageActionReuseHint,\n} from '../automation/automation-response';\nimport {\n parsePageActionFeedbackCatalog,\n parsePageActionFeedbackSummary,\n parsePageActionFeedbackView,\n parsePageActionWishList,\n parsePageActionWishView,\n} from '../page/page-action-feedback-wish-response';\nimport type { HttpClient } from '../http';\nimport type {\n CreatePageActionWishInput,\n InvokePageActionRequest,\n PageActionFeedbackCatalogItem,\n PageActionFeedbackCatalogQuery,\n PageActionFeedbackSummary,\n PageActionFeedbackView,\n PageActionInvokeResult,\n PageActionReuseHint,\n PageActionWishList,\n PageActionWishQuery,\n PageActionWishView,\n UpsertPageActionFeedbackInput,\n} from '../../types';\n\nfunction encodeActionKeyPath(actionKey: string): string {\n return encodeURIComponent(actionKey.trim());\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Map HTTP 409 / TRANSPORT_FAILED carrying `PAGE_ACTION_ALREADY_ACTIVE` to a soft\n * invoke result — never throw that conflict to host PageAction buttons.\n */\nfunction tryParseAlreadyActiveFromTransportError(\n err: unknown,\n): PageActionInvokeResult | null {\n if (!(err instanceof AgentChatError) || err.code !== 'TRANSPORT_FAILED') {\n return null;\n }\n const details = err.details;\n if (!isRecord(details)) return null;\n const envelopeStatus = details.status;\n if (envelopeStatus !== 409) return null;\n\n const candidates: unknown[] = [];\n if (details.data != null) candidates.push(details.data);\n if (isRecord(details.body)) {\n if (details.body.data != null) candidates.push(details.body.data);\n candidates.push(details.body);\n }\n\n for (const candidate of candidates) {\n if (!isRecord(candidate)) continue;\n try {\n if (candidate.code === 'PAGE_ACTION_ALREADY_ACTIVE') {\n return { kind: 'already_active', ...parsePageActionAlreadyActive(candidate) };\n }\n // Envelope-shaped `{ status: 409, data: { code: ... } }`\n if (isRecord(candidate.data) && candidate.data.code === 'PAGE_ACTION_ALREADY_ACTIVE') {\n return {\n kind: 'already_active',\n ...parsePageActionAlreadyActive(candidate.data),\n };\n }\n } catch {\n /* try next candidate */\n }\n }\n\n // Last resort: serverCode alone (body may have been partially parsed).\n if (details.serverCode === 'PAGE_ACTION_ALREADY_ACTIVE' && isRecord(details.data)) {\n try {\n return { kind: 'already_active', ...parsePageActionAlreadyActive(details.data) };\n } catch {\n return null;\n }\n }\n return null;\n}\n\n/** PageAction C-end APIs (`/page-action/*`). */\nexport class PageActionService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `POST /page-action/brain-invoke` — accepted or `PAGE_ACTION_ALREADY_ACTIVE`. */\n async invoke(\n body: InvokePageActionRequest,\n signal?: AbortSignal,\n ): Promise<PageActionInvokeResult> {\n try {\n const response = await this.http.request<unknown>('/page-action/brain-invoke', {\n method: 'POST',\n signal,\n body,\n });\n return parsePageActionInvokeResult(response);\n } catch (err) {\n const soft = tryParseAlreadyActiveFromTransportError(err);\n if (soft) return soft;\n throw err;\n }\n }\n\n /**\n * `POST /page-action/reuse-hint` — same entity key as invoke; no run created.\n * Returns recent successful runs (same App, cross-user when scope=app).\n */\n async reuseHint(\n body: InvokePageActionRequest,\n signal?: AbortSignal,\n ): Promise<PageActionReuseHint> {\n const response = await this.http.request<unknown>('/page-action/reuse-hint', {\n method: 'POST',\n signal,\n body,\n });\n return parsePageActionReuseHint(response);\n }\n\n /** @deprecated Use {@link invoke}. */\n async invokeAccepted(\n body: InvokePageActionRequest,\n signal?: AbortSignal,\n ): Promise<PageActionInvokeResult> {\n return this.invoke(body, signal);\n }\n\n /** `GET /page-action/runs/:runId/stream` — SSE lifecycle + host_action. */\n streamRun(runId: number, signal?: AbortSignal) {\n return this.http.stream(`/page-action/runs/${runId}/stream`, { signal });\n }\n\n /** `GET /page-action/catalog` — enabled PageActions for this App (no run). */\n async listCatalog(\n query: PageActionFeedbackCatalogQuery = {},\n signal?: AbortSignal,\n ): Promise<PageActionFeedbackCatalogItem[]> {\n const pageScope = query.pageScope?.trim();\n const response = await this.http.request<unknown>('/page-action/catalog', {\n method: 'GET',\n signal,\n searchParams: pageScope ? { pageScope } : undefined,\n });\n return parsePageActionFeedbackCatalog(response);\n }\n\n /** `PUT /page-action/feedback/:actionKey` — upsert my rating. */\n async upsertFeedback(\n actionKey: string,\n body: UpsertPageActionFeedbackInput,\n signal?: AbortSignal,\n ): Promise<PageActionFeedbackView> {\n const response = await this.http.request<unknown>(\n `/page-action/feedback/${encodeActionKeyPath(actionKey)}`,\n { method: 'PUT', signal, body },\n );\n const parsed = parsePageActionFeedbackView(response);\n if (!parsed) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid feedback response');\n }\n return parsed;\n }\n\n /** `GET /page-action/feedback/:actionKey` — my rating (`null` if none). */\n async getMyFeedback(\n actionKey: string,\n signal?: AbortSignal,\n ): Promise<PageActionFeedbackView | null> {\n const response = await this.http.request<unknown>(\n `/page-action/feedback/${encodeActionKeyPath(actionKey)}`,\n { method: 'GET', signal },\n );\n return parsePageActionFeedbackView(response);\n }\n\n /** `DELETE /page-action/feedback/:actionKey`. */\n async removeMyFeedback(actionKey: string, signal?: AbortSignal): Promise<void> {\n await this.http.request<unknown>(\n `/page-action/feedback/${encodeActionKeyPath(actionKey)}`,\n { method: 'DELETE', signal },\n );\n }\n\n /** `GET /page-action/feedback/:actionKey/summary`. */\n async getFeedbackSummary(\n actionKey: string,\n signal?: AbortSignal,\n ): Promise<PageActionFeedbackSummary> {\n const response = await this.http.request<unknown>(\n `/page-action/feedback/${encodeActionKeyPath(actionKey)}/summary`,\n { method: 'GET', signal },\n );\n return parsePageActionFeedbackSummary(response);\n }\n\n /** `POST /page-action/wishes`. */\n async createWish(\n body: CreatePageActionWishInput,\n signal?: AbortSignal,\n ): Promise<PageActionWishView> {\n const response = await this.http.request<unknown>('/page-action/wishes', {\n method: 'POST',\n signal,\n body,\n });\n return parsePageActionWishView(response);\n }\n\n /** `GET /page-action/wishes`. */\n async listWishes(\n query: PageActionWishQuery = {},\n signal?: AbortSignal,\n ): Promise<PageActionWishList> {\n const searchParams: Record<string, string | number> = {};\n if (query.page != null) searchParams.page = query.page;\n if (query.pageSize != null) searchParams.pageSize = query.pageSize;\n if (query.status) searchParams.status = query.status;\n if (query.keyword) searchParams.keyword = query.keyword;\n if (query.pageScope) searchParams.pageScope = query.pageScope;\n if (query.relatedActionKey) searchParams.relatedActionKey = query.relatedActionKey;\n const response = await this.http.request<unknown>('/page-action/wishes', {\n method: 'GET',\n signal,\n searchParams,\n });\n return parsePageActionWishList(response);\n }\n\n /** `GET /page-action/wishes/:id`. */\n async getWish(id: number, signal?: AbortSignal): Promise<PageActionWishView> {\n const response = await this.http.request<unknown>(`/page-action/wishes/${id}`, {\n method: 'GET',\n signal,\n });\n return parsePageActionWishView(response);\n }\n\n /** `PATCH /page-action/wishes/:id/cancel`. */\n async cancelWish(id: number, signal?: AbortSignal): Promise<PageActionWishView> {\n const response = await this.http.request<unknown>(\n `/page-action/wishes/${id}/cancel`,\n { method: 'PATCH', signal },\n );\n return parsePageActionWishView(response);\n }\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport {\n parseAutomationTaskDetail,\n parseAutomationTaskList,\n} from '../automation/automation-response';\nimport type { HttpClient } from '../http';\nimport type {\n AutomationTaskDetail,\n AutomationTaskList,\n AutomationTaskStatusFilter,\n AutomationTriggerSourceFilter,\n} from '../../types';\n\nexport interface AutomationTaskQuery {\n status?: AutomationTaskStatusFilter;\n triggerSource?: AutomationTriggerSourceFilter;\n actionKey?: string;\n workflowKey?: string;\n limit?: number;\n offset?: number;\n signal?: AbortSignal;\n}\n\nexport class AutomationService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `GET /automation/tasks` */\n async listTasks(query: AutomationTaskQuery = {}): Promise<AutomationTaskList> {\n const limit = query.limit ?? 20;\n const searchParams: Record<string, string> = {\n limit: String(limit),\n offset: String(query.offset ?? 0),\n };\n if (query.status) searchParams.status = query.status;\n if (query.triggerSource) searchParams.triggerSource = query.triggerSource;\n if (query.actionKey?.trim()) searchParams.actionKey = query.actionKey.trim();\n if (query.workflowKey?.trim()) searchParams.workflowKey = query.workflowKey.trim();\n const body = await this.http.request<unknown>('/automation/tasks', {\n method: 'GET',\n signal: query.signal,\n searchParams,\n });\n return parseAutomationTaskList(parseApiEnvelope(body), limit);\n }\n\n /** `GET /automation/tasks/page_action_run/:id` */\n async getPageActionRunTask(\n id: number,\n signal?: AbortSignal,\n ): Promise<AutomationTaskDetail | null> {\n const body = await this.http.request<unknown>(\n `/automation/tasks/page_action_run/${id}`,\n {\n method: 'GET',\n signal,\n },\n );\n return parseAutomationTaskDetail(parseApiEnvelope(body));\n }\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport {\n parseApprovalConfirmResult,\n parseApprovalDecideResult,\n parseApprovalDetail,\n parseApprovalInboxList,\n parseApprovalRejectResult,\n} from '../approval/approval-response';\nimport type { HttpClient } from '../http';\nimport type {\n ApprovalConfirmResult,\n ApprovalDecideResult,\n ApprovalDetail,\n ApprovalInboxList,\n ApprovalInboxStatusFilter,\n ApprovalRejectResult,\n DraftReviewDecision,\n} from '../../types';\n\nexport interface ApprovalInboxQuery {\n status?: ApprovalInboxStatusFilter;\n limit?: number;\n offset?: number;\n signal?: AbortSignal;\n}\n\nexport class ApprovalService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `GET /approval/inbox` — page_action / webhook items for current user. */\n async listInbox(query: ApprovalInboxQuery = {}): Promise<ApprovalInboxList> {\n const limit = query.limit ?? 50;\n const searchParams: Record<string, string> = {\n limit: String(limit),\n offset: String(query.offset ?? 0),\n };\n if (query.status) searchParams.status = query.status;\n const body = await this.http.request<unknown>('/approval/inbox', {\n method: 'GET',\n signal: query.signal,\n searchParams,\n });\n return parseApprovalInboxList(parseApiEnvelope(body), limit);\n }\n\n /** `GET /approval/:id` */\n async getById(id: number, signal?: AbortSignal): Promise<ApprovalDetail | null> {\n const body = await this.http.request<unknown>(`/approval/${id}`, {\n method: 'GET',\n signal,\n });\n return parseApprovalDetail(parseApiEnvelope(body));\n }\n\n /** `POST /approval/:id/decide` */\n async decide(\n id: number,\n decision: DraftReviewDecision,\n reason?: string,\n signal?: AbortSignal,\n ): Promise<ApprovalDecideResult> {\n const body: Record<string, unknown> = { decision };\n if (reason?.trim()) body.reason = reason.trim();\n const response = await this.http.request<unknown>(`/approval/${id}/decide`, {\n method: 'POST',\n signal,\n body,\n });\n return parseApprovalDecideResult(parseApiEnvelope(response));\n }\n\n /** `POST /approval/:id/confirm` */\n async confirm(id: number, signal?: AbortSignal): Promise<ApprovalConfirmResult> {\n const body = await this.http.request<unknown>(`/approval/${id}/confirm`, {\n method: 'POST',\n signal,\n });\n return parseApprovalConfirmResult(parseApiEnvelope(body));\n }\n\n /** `POST /approval/:id/reject` */\n async reject(\n id: number,\n reason?: string,\n signal?: AbortSignal,\n ): Promise<ApprovalRejectResult> {\n const body = await this.http.request<unknown>(`/approval/${id}/reject`, {\n method: 'POST',\n signal,\n body: reason?.trim() ? { reason: reason.trim() } : {},\n });\n return parseApprovalRejectResult(parseApiEnvelope(body));\n }\n}\n","import { AgentChatError } from '../lib/errors';\nimport { parseApiEnvelope } from '../lib/api-envelope';\nimport type { HttpClient } from '../http';\n\n/** `GET /app/tools/callable` 单项 — 用 `definitionKey` 调用,勿硬编码 `toolId`。 */\nexport type AppToolCallableItem = {\n definitionKey: string;\n name: string;\n description: string;\n riskLevel: string;\n method: string;\n path: string;\n inputSchema: unknown;\n /** 仅调试用 */\n toolId: number;\n};\n\nexport type AppToolCallableList = {\n items: AppToolCallableItem[];\n};\n\n/** `POST /app/tools/invoke` 结果(含下游非 2xx 的结构化失败)。 */\nexport type AppToolInvokeResult = {\n ok: boolean;\n definitionKey: string;\n toolId: number;\n name: string;\n latencyMs: number;\n output: unknown;\n httpStatus?: number;\n error?: string;\n};\n\nexport type AppToolInvokeInput = {\n definitionKey: string;\n parameters?: Record<string, unknown>;\n signal?: AbortSignal;\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() ? 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 parseCallableItem(raw: unknown): AppToolCallableItem | null {\n if (!isRecord(raw)) return null;\n const definitionKey = readString(raw.definitionKey);\n const name = readString(raw.name);\n const toolId = readNumber(raw.toolId);\n if (!definitionKey || !name || toolId === undefined) return null;\n return {\n definitionKey,\n name,\n description: readString(raw.description) ?? '',\n riskLevel: readString(raw.riskLevel) ?? 'L1',\n method: readString(raw.method) ?? '',\n path: readString(raw.path) ?? '',\n inputSchema: raw.inputSchema ?? null,\n toolId,\n };\n}\n\nfunction parseInvokeResult(raw: unknown): AppToolInvokeResult {\n if (!isRecord(raw)) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid app tool invoke response');\n }\n const definitionKey = readString(raw.definitionKey);\n const name = readString(raw.name);\n const toolId = readNumber(raw.toolId);\n const latencyMs = readNumber(raw.latencyMs) ?? 0;\n if (!definitionKey || !name || toolId === undefined) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid app tool invoke response shape');\n }\n return {\n ok: raw.ok === true,\n definitionKey,\n toolId,\n name,\n latencyMs,\n output: raw.output,\n httpStatus: readNumber(raw.httpStatus),\n error: readString(raw.error),\n };\n}\n\n/**\n * 从 `AgentChatError.details.serverCode` 读取网关门禁码\n *(如 `INTEGRATION_USER_TOKEN_REQUIRED`)。\n */\nexport function getAppToolServerErrorCode(err: unknown): string | null {\n if (!(err instanceof AgentChatError)) return null;\n const code = err.details?.serverCode;\n return typeof code === 'string' && code.trim() ? code.trim() : null;\n}\n\n/** C 端 Tool 代调:`/app/tools/callable`、`/app/tools/invoke`。 */\nexport class AppToolService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `GET /app/tools/callable` — 当前用户可代调的 L1 Tool 列表。 */\n async listCallable(signal?: AbortSignal): Promise<AppToolCallableList> {\n const raw = await this.http.request<unknown>('/app/tools/callable', {\n method: 'GET',\n signal,\n });\n const data = parseApiEnvelope<{ items?: unknown }>(raw);\n const items = Array.isArray(data?.items)\n ? data.items.map(parseCallableItem).filter((row): row is AppToolCallableItem => row != null)\n : [];\n return { items };\n }\n\n /**\n * `POST /app/tools/invoke` — 按 definitionKey 代调。\n * 下游非 2xx 时 HTTP 仍为 200,`ok: false`;网关门禁失败则抛 `AgentChatError`。\n */\n async invoke(input: AppToolInvokeInput): Promise<AppToolInvokeResult> {\n const definitionKey = input.definitionKey.trim();\n if (!definitionKey) {\n throw new AgentChatError('INVALID_OPTIONS', 'definitionKey is required');\n }\n const raw = await this.http.request<unknown>('/app/tools/invoke', {\n method: 'POST',\n signal: input.signal,\n body: {\n definitionKey,\n ...(input.parameters !== undefined ? { parameters: input.parameters } : {}),\n },\n });\n const data = parseApiEnvelope<unknown>(raw);\n return parseInvokeResult(data);\n }\n}\n","import type { SessionInfo, UserContext, AgentMessage } from '../../types';\n\nexport interface SessionContext {\n sdkVersion: string;\n origin: string;\n locale: string;\n user?: UserContext;\n}\n\nexport interface SessionManagerOptions {\n context: SessionContext;\n}\n\n/**\n * Lightweight in-memory holder for active chat session metadata.\n */\nexport class SessionManager {\n private context: SessionContext;\n\n private sessionId: string | null = null;\n private initialMessages: AgentMessage[] = [];\n\n constructor(options: SessionManagerOptions) {\n this.context = options.context;\n }\n\n updateContext(partial: Partial<SessionContext>): void {\n this.context = { ...this.context, ...partial };\n }\n\n getSession(): SessionInfo | null {\n if (!this.sessionId) return null;\n return { sessionId: this.sessionId, conversationId: this.sessionId };\n }\n\n getInitialMessages(): AgentMessage[] {\n return this.initialMessages;\n }\n\n setSession(sessionId: string, initialMessages: AgentMessage[] = []): void {\n this.sessionId = sessionId.trim().toLowerCase();\n this.initialMessages = initialMessages;\n }\n\n reset(): void {\n this.sessionId = null;\n this.initialMessages = [];\n }\n}\n","import { unwrapApiData } from '../auth/auth-response';\nimport type {\n PageContextPlanKind,\n SkillIntentAlignmentSnapshot,\n SkillIntentMismatchCode,\n SkillTurnContractView,\n TurnScopedToolsSource,\n TurnSkillSelect,\n} from '../../types';\n\nexport type AgentRunStepLike = {\n type: string;\n output?: unknown;\n name?: string;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction normalizeSteps(value: unknown): AgentRunStepLike[] {\n if (typeof value === 'string') {\n try {\n return normalizeSteps(JSON.parse(value));\n } catch {\n return [];\n }\n }\n if (!Array.isArray(value)) return [];\n return value.filter(\n (item): item is AgentRunStepLike =>\n isRecord(item) && typeof item.type === 'string',\n );\n}\n\nexport interface ParsedAgentRunDetail {\n steps: AgentRunStepLike[];\n turnExecutionTimeline: AgentRunStepLike[];\n}\n\nexport function parseAgentRunDetail(body: unknown): ParsedAgentRunDetail | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n return {\n steps: normalizeSteps(raw.steps),\n turnExecutionTimeline: normalizeSteps(raw.turnExecutionTimeline),\n };\n}\n\nexport function resolveAlignmentSteps(run: ParsedAgentRunDetail): AgentRunStepLike[] {\n if (run.turnExecutionTimeline.length > 0) return run.turnExecutionTimeline;\n return run.steps;\n}\n\nfunction parseSkillAlignment(value: unknown): SkillIntentAlignmentSnapshot | null {\n if (!isRecord(value)) return null;\n const status = value.status;\n if (\n status !== 'none' &&\n status !== 'aligned' &&\n status !== 'intent_first' &&\n status !== 'clarified'\n ) {\n return null;\n }\n const snapshot: SkillIntentAlignmentSnapshot = { status };\n if (typeof value.code === 'string') {\n snapshot.code = value.code as SkillIntentMismatchCode;\n }\n const requestedSkillId = value.requestedSkillId;\n if (typeof requestedSkillId === 'number' && Number.isFinite(requestedSkillId)) {\n snapshot.requestedSkillId = requestedSkillId;\n }\n if (value.droppedExplicitSkill === true) {\n snapshot.droppedExplicitSkill = true;\n }\n return snapshot;\n}\n\nfunction parseSkillSelect(value: unknown): TurnSkillSelect {\n if (value === 'explicit' || value === 'page_host' || value === 'llm') {\n return value;\n }\n return 'llm';\n}\n\nfunction parseScopedToolsSource(value: unknown): TurnScopedToolsSource {\n if (value === 'explicit_skill' || value === 'intent') {\n return value;\n }\n return 'intent';\n}\n\nfunction parsePageContextPlan(value: unknown): PageContextPlanKind {\n if (value === 'inline_answer' || value === 'entity_read_detail' || value === 'none') {\n return value;\n }\n return 'none';\n}\n\nexport function readRoutePlanStep(\n steps: AgentRunStepLike[] | null | undefined,\n): Record<string, unknown> | null {\n if (!steps?.length) return null;\n const route = steps.find((step) => step.type === 'route_plan');\n if (!route?.output || !isRecord(route.output)) return null;\n return route.output;\n}\n\nexport function readSkillTurnContract(\n steps: AgentRunStepLike[] | null | undefined,\n): SkillTurnContractView | null {\n const out = readRoutePlanStep(steps);\n if (!out) return null;\n const align = parseSkillAlignment(out.skillAlignment);\n if (!align) return null;\n const requestedSkillId =\n typeof out.requestedSkillId === 'number' && Number.isFinite(out.requestedSkillId)\n ? out.requestedSkillId\n : null;\n return {\n skillAlignment: align,\n skillSelect: parseSkillSelect(out.skillSelect),\n scopedToolsSource: parseScopedToolsSource(out.scopedToolsSource),\n pageContextPlan: parsePageContextPlan(out.pageContextPlan),\n hostMutationIntent: Boolean(out.hostMutationIntent),\n requestedSkillId,\n };\n}\n\n/** @deprecated Use {@link readSkillTurnContract} */\nexport function readSkillAlignment(\n steps: AgentRunStepLike[] | null | undefined,\n): SkillIntentAlignmentSnapshot | null {\n return readSkillTurnContract(steps)?.skillAlignment ?? null;\n}\n\n/** True when the pre-selected skill was actually used this turn (three-field gate). */\nexport function isRequestedSkillActuallyUsed(\n contract: SkillTurnContractView | null | undefined,\n): boolean {\n if (!contract) return false;\n return (\n contract.scopedToolsSource === 'explicit_skill' &&\n contract.skillAlignment.status === 'aligned' &&\n contract.skillSelect === 'explicit'\n );\n}\n\nexport function shouldShowIntentFirstBanner(\n contract: SkillTurnContractView | null | undefined,\n): boolean {\n return contract?.skillAlignment.status === 'intent_first';\n}\n\n/** @deprecated Use {@link shouldShowIntentFirstBanner} */\nexport function shouldShowIntentFirstHint(\n align: SkillIntentAlignmentSnapshot | null | undefined,\n): boolean {\n return align?.status === 'intent_first';\n}\n\nexport function shouldShowSkillClarifyCard(\n contract: SkillTurnContractView | null | undefined,\n): boolean {\n return contract?.skillAlignment.status === 'clarified';\n}\n\n/** @deprecated Use {@link shouldShowSkillClarifyCard} */\nexport function shouldShowClarifyCard(\n align: SkillIntentAlignmentSnapshot | null | undefined,\n): boolean {\n return align?.status === 'clarified';\n}\n\nexport function mismatchI18nKey(code: SkillIntentMismatchCode): string {\n return `skill_intent_mismatch.${code}`;\n}\n\nexport interface SkillIntentMismatchObservation {\n userMessage?: string;\n mismatchCode?: SkillIntentMismatchCode;\n requestedSkillId?: number;\n requestedSkillName?: string;\n routingReason?: string;\n}\n\n/** Read `skill_intent_mismatch` from summarize step observations (debug / fallback). */\nexport function readSkillIntentMismatchObservation(\n steps: AgentRunStepLike[] | null | undefined,\n): SkillIntentMismatchObservation | null {\n if (!steps?.length) return null;\n for (let i = steps.length - 1; i >= 0; i -= 1) {\n const step = steps[i];\n if (step.type !== 'summarize') continue;\n const output = step.output;\n if (!isRecord(output)) continue;\n const observations = output.observations;\n if (!Array.isArray(observations)) continue;\n for (const item of observations) {\n if (!isRecord(item)) continue;\n if (item.name !== 'skill_intent_mismatch') continue;\n const obsOutput = item.output;\n if (!isRecord(obsOutput)) continue;\n return {\n userMessage:\n typeof obsOutput.userMessage === 'string' ? obsOutput.userMessage : undefined,\n mismatchCode:\n typeof obsOutput.mismatchCode === 'string'\n ? (obsOutput.mismatchCode as SkillIntentMismatchCode)\n : undefined,\n requestedSkillId:\n typeof obsOutput.requestedSkillId === 'number'\n ? obsOutput.requestedSkillId\n : undefined,\n requestedSkillName:\n typeof obsOutput.requestedSkillName === 'string'\n ? obsOutput.requestedSkillName\n : undefined,\n routingReason:\n typeof obsOutput.routingReason === 'string' ? obsOutput.routingReason : undefined,\n };\n }\n }\n return null;\n}\n","import { AgentChatError } from '../lib/errors';\nimport { parseHostActionSsePayload } from '../host-tool/host-action';\nimport { isHostActionStreamPayload } from '../host-tool/stream/host-tool-stream.types';\nimport type { HostActionSsePayload } from '../host-tool/stream/host-tool-stream.types';\nimport type { SseEventChunk } from '../http';\nimport type { AgentChatPageContext, PageBotStreamResult } from '../../types';\nimport type { PageActionSseLifecycle } from '../../types';\nimport type { PageContextGate } from '../host-tool/stream/host-tool-stream-gate';\nimport {\n parsePageWorkflowEvent,\n type PageWorkflowEvent,\n} from './page-action-workflow-progress';\nimport {\n isBrainAskUserErrorCode,\n parseBrainClarifyPayload,\n} from './brain-clarify';\n\nexport const PAGE_ACTION_STREAM_KEY_PREFIX = 'page-action:';\n/** @deprecated Use per-invoke keys under {@link PAGE_ACTION_STREAM_KEY_PREFIX}. */\nexport const PAGE_ACTION_STREAM_SESSION_KEY = '__page_action__';\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 tryParseJson(raw: string): unknown {\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return null;\n }\n}\n\nfunction throwPageActionFailed(\n message: string,\n details: Record<string, unknown>,\n): never {\n throw new AgentChatError('PAGE_ACTION_FAILED', message, { details });\n}\n\n/** Map HTTP / transport failures from `/page-action/*` to {@link AgentChatError} `PAGE_ACTION_FAILED`. */\nexport function rethrowPageActionError(err: unknown): never {\n if (err instanceof AgentChatError) {\n if (err.code === 'TRANSPORT_ABORTED' || err.code === 'PAGE_ACTION_FAILED') {\n throw err;\n }\n if (err.code === 'TRANSPORT_FAILED') {\n throw new AgentChatError('PAGE_ACTION_FAILED', err.message, {\n cause: err,\n details: err.details,\n });\n }\n }\n throw err;\n}\n\nexport function pageGateFromPageContext(\n pageContext: AgentChatPageContext | null | undefined,\n): PageContextGate {\n if (!pageContext) return {};\n return {\n ...(pageContext.page ? { page: pageContext.page } : {}),\n ...(pageContext.entity ? { entity: pageContext.entity } : {}),\n };\n}\n\nfunction readArgAppendChunk(payload: HostActionSsePayload): string | undefined {\n if (!isHostActionStreamPayload(payload)) return undefined;\n const dsl = payload.dsl;\n if (!dsl || dsl.op !== 'arg.append') return undefined;\n const chunk = dsl.chunk;\n return typeof chunk === 'string' ? chunk : undefined;\n}\n\nexport type PageActionStreamHooks = {\n onHostAction: (payload: HostActionSsePayload) => void;\n onChunk?: (chunk: string) => void;\n onLifecycle?: (lifecycle: PageActionSseLifecycle) => void;\n /** Process loading narrative (`page_workflow`) — UI only. */\n onWorkflowProgress?: (event: PageWorkflowEvent) => void;\n /** Log malformed `host_action` SSE payloads when true. */\n debug?: boolean;\n};\n\nfunction readLifecycle(body: Record<string, unknown>): PageActionSseLifecycle | null {\n const phase = readString(body.phase);\n const actionRunId = typeof body.actionRunId === 'number' ? body.actionRunId : null;\n const actionKey = readString(body.actionKey);\n const generation = typeof body.generation === 'number' ? body.generation : null;\n if (\n !phase ||\n actionRunId == null ||\n !actionKey ||\n generation == null ||\n (phase !== 'started' &&\n phase !== 'stream' &&\n phase !== 'completed' &&\n phase !== 'failed' &&\n phase !== 'awaiting_approval')\n ) {\n return null;\n }\n return {\n phase,\n actionRunId,\n actionKey,\n generation,\n clientActionId: readString(body.clientActionId) ?? null,\n streamId: readString(body.streamId) ?? null,\n text: typeof body.text === 'string' ? body.text : undefined,\n dslOutcome:\n typeof body.dslOutcome === 'string'\n ? body.dslOutcome\n : body.dslOutcome === null\n ? null\n : undefined,\n errorCode: readString(body.errorCode),\n errorMessage: readString(body.errorMessage),\n brainClarify: parseBrainClarifyPayload(body.brainClarify),\n };\n}\n\n/** Consume PageAction run SSE (`page_action` + `page_workflow` + optional `host_action`). */\nexport async function consumePageActionRunStream(\n chunks: AsyncIterable<SseEventChunk>,\n hooks: PageActionStreamHooks,\n): Promise<PageBotStreamResult> {\n let actionRunId = 0;\n let finalText = '';\n let dslOutcome: string | null = null;\n let completed = false;\n\n for await (const evt of chunks) {\n if (evt.event === 'ping') {\n continue;\n }\n\n if (evt.event === 'page_workflow') {\n const parsed = tryParseJson(evt.data);\n const workflow = parsePageWorkflowEvent(parsed);\n if (workflow) {\n hooks.onWorkflowProgress?.(workflow);\n }\n continue;\n }\n\n if (evt.event === 'host_action') {\n const parsed = tryParseJson(evt.data);\n const payload = parseHostActionSsePayload(parsed);\n if (payload) {\n hooks.onHostAction(payload);\n const chunk = readArgAppendChunk(payload);\n if (chunk) hooks.onChunk?.(chunk);\n } else if (\n hooks.debug &&\n typeof console !== 'undefined' &&\n typeof console.warn === 'function'\n ) {\n console.warn('[agent-chat] page_action: ignored malformed host_action SSE frame');\n }\n continue;\n }\n\n if (evt.event !== 'page_action') continue;\n\n const body = tryParseJson(evt.data);\n if (!isRecord(body)) continue;\n\n const lifecycle = readLifecycle(body);\n if (lifecycle) {\n hooks.onLifecycle?.(lifecycle);\n }\n\n if (typeof body.actionRunId === 'number' && Number.isFinite(body.actionRunId)) {\n actionRunId = body.actionRunId;\n }\n\n if (body.phase === 'stream') {\n const chunk = typeof body.text === 'string' ? body.text : '';\n if (chunk) {\n finalText += chunk;\n hooks.onChunk?.(chunk);\n }\n continue;\n }\n\n if (body.phase === 'completed') {\n completed = true;\n finalText = typeof body.text === 'string' ? body.text : '';\n dslOutcome =\n typeof body.dslOutcome === 'string'\n ? body.dslOutcome\n : body.dslOutcome === null\n ? null\n : dslOutcome;\n }\n\n if (body.phase === 'failed') {\n const errorCode = readString(body.errorCode);\n const errorMessage =\n readString(body.errorMessage) ?? 'Page action invoke failed';\n const brainClarify = parseBrainClarifyPayload(body.brainClarify);\n // Brain ASK_USER is a soft pause for entity pick — not a hard stream failure.\n if (isBrainAskUserErrorCode(errorCode) && brainClarify) {\n return {\n actionRunId,\n text: brainClarify.question,\n dslOutcome: null,\n awaitingClarify: true,\n actionKey: readString(body.actionKey),\n clientActionId: readString(body.clientActionId),\n brainClarify,\n message: brainClarify.question,\n };\n }\n throwPageActionFailed(errorMessage, {\n serverCode: errorCode,\n actionRunId: actionRunId || undefined,\n phase: 'failed',\n brainClarify: brainClarify ?? undefined,\n });\n }\n\n if (body.phase === 'awaiting_approval') {\n return {\n actionRunId,\n text: '',\n dslOutcome: null,\n awaitingApproval: true,\n status: 'awaiting_approval',\n actionKey: readString(body.actionKey),\n clientActionId: readString(body.clientActionId),\n };\n }\n }\n\n if (!completed) {\n throwPageActionFailed('Page action stream ended without completion', {\n actionRunId: actionRunId || undefined,\n phase: 'incomplete',\n });\n }\n\n return { actionRunId, text: finalText, dslOutcome };\n}\n\nexport type { PageWorkflowEvent };\n\n/** @deprecated Use {@link consumePageActionRunStream}. */\nexport const consumePageActionInvokeStream = consumePageActionRunStream;\n","import type { InvokePageActionRequest, PageActionReuseHint } from '../../types';\n\n/** Stable cache key for reuse-hint — same fields the server hashes into pageActionKey. */\nexport function pageActionReuseHintCacheKey(body: InvokePageActionRequest): string {\n return JSON.stringify({\n actionKey: body.actionKey.trim(),\n pageContext: body.pageContext ?? null,\n instruction: body.instruction?.trim() || null,\n context: body.context && Object.keys(body.context).length > 0 ? body.context : null,\n });\n}\n\nexport class PageActionReuseHintCache {\n private readonly byBodyKey = new Map<string, PageActionReuseHint>();\n private readonly bodyKeyByPageActionKey = new Map<string, string>();\n\n get(body: InvokePageActionRequest): PageActionReuseHint | null {\n return this.byBodyKey.get(pageActionReuseHintCacheKey(body)) ?? null;\n }\n\n set(body: InvokePageActionRequest, hint: PageActionReuseHint): void {\n const key = pageActionReuseHintCacheKey(body);\n this.byBodyKey.set(key, hint);\n const pageActionKey = hint.pageActionKey.trim();\n if (pageActionKey) {\n this.bodyKeyByPageActionKey.set(pageActionKey, key);\n }\n }\n\n /** Drop cached hint after a fresh successful run for this key. */\n invalidateByPageActionKey(pageActionKey: string | null | undefined): void {\n const pak = pageActionKey?.trim();\n if (!pak) return;\n const bodyKey = this.bodyKeyByPageActionKey.get(pak);\n if (!bodyKey) return;\n this.byBodyKey.delete(bodyKey);\n this.bodyKeyByPageActionKey.delete(pak);\n }\n\n invalidateByBody(body: InvokePageActionRequest): void {\n const key = pageActionReuseHintCacheKey(body);\n const hint = this.byBodyKey.get(key);\n this.byBodyKey.delete(key);\n if (hint?.pageActionKey) {\n this.bodyKeyByPageActionKey.delete(hint.pageActionKey.trim());\n }\n }\n\n clear(): void {\n this.byBodyKey.clear();\n this.bodyKeyByPageActionKey.clear();\n }\n}\n","import type { AgentChatPageContext } from '../../types';\n\n/**\n * Navigation target from a task `pageContext` snapshot.\n * Only `routePath` is used — host must pass it on invoke.\n */\nexport type PageContextNavigateTarget =\n | { kind: 'routePath'; path: string }\n | { kind: 'none' };\n\nexport function resolvePageContextNavigateTarget(\n pageContext: AgentChatPageContext | null | undefined,\n): PageContextNavigateTarget {\n const routePath = pageContext?.routePath?.trim();\n if (routePath) {\n return { kind: 'routePath', path: routePath };\n }\n return { kind: 'none' };\n}\n\n/** Host-facing payload for「应用到页面」navigation. */\nexport type NavigateForPageActionInput = {\n runId: number;\n actionKey: string;\n pageContext: AgentChatPageContext | null;\n target: PageContextNavigateTarget;\n /**\n * `true` when SDK wrote pendingApply — target `usePageAction({ ready })`\n * will auto `replayPageAction` when ready.\n */\n canReplay: boolean;\n};\n\nexport type ApplyPageActionToPageResult = {\n runId: number;\n actionKey: string;\n pageContext: AgentChatPageContext | null;\n target: PageContextNavigateTarget;\n /** Host `onNavigateForPageAction` was invoked successfully. */\n navigated: boolean;\n /**\n * `true` when pendingApply was written for the target page to consume.\n */\n canReplay: boolean;\n ok: boolean;\n reason?:\n | 'missing_route_path'\n | 'no_replayable_output'\n | 'not_completed'\n | 'navigate_only';\n};\n","import type { AgentChatPageContext } from '../../types';\n\nconst STORAGE_PREFIX = 'omnix-chat:pending-page-action-apply:';\n/** Drop stale pending applies after 30 minutes. */\nconst PENDING_TTL_MS = 30 * 60 * 1000;\n\n/** Intent left by「应用到页面」until the target page is ready to replay. */\nexport type PendingPageActionApply = {\n runId: number;\n actionKey: string;\n pageContext: AgentChatPageContext | null;\n createdAt: string;\n};\n\nfunction storageKey(dsn: string): string {\n return `${STORAGE_PREFIX}${dsn.trim()}`;\n}\n\nfunction isFresh(pending: PendingPageActionApply): boolean {\n const created = Date.parse(pending.createdAt);\n if (!Number.isFinite(created)) return false;\n return Date.now() - created <= PENDING_TTL_MS;\n}\n\nexport function readPendingPageActionApply(dsn: string): PendingPageActionApply | null {\n if (typeof sessionStorage === 'undefined') return null;\n try {\n const raw = sessionStorage.getItem(storageKey(dsn));\n if (!raw) return null;\n const parsed = JSON.parse(raw) as PendingPageActionApply;\n if (\n !parsed ||\n typeof parsed.runId !== 'number' ||\n !Number.isFinite(parsed.runId) ||\n typeof parsed.actionKey !== 'string' ||\n !parsed.actionKey.trim()\n ) {\n return null;\n }\n if (!isFresh(parsed)) {\n sessionStorage.removeItem(storageKey(dsn));\n return null;\n }\n return {\n runId: Math.trunc(parsed.runId),\n actionKey: parsed.actionKey.trim(),\n pageContext: parsed.pageContext ?? null,\n createdAt: typeof parsed.createdAt === 'string' ? parsed.createdAt : new Date().toISOString(),\n };\n } catch {\n return null;\n }\n}\n\nexport function writePendingPageActionApply(\n dsn: string,\n pending: PendingPageActionApply,\n): void {\n if (typeof sessionStorage === 'undefined') return;\n try {\n sessionStorage.setItem(storageKey(dsn), JSON.stringify(pending));\n } catch {\n /* quota / private mode */\n }\n}\n\nexport function clearPendingPageActionApplyStorage(dsn: string): void {\n if (typeof sessionStorage === 'undefined') return;\n try {\n sessionStorage.removeItem(storageKey(dsn));\n } catch {\n /* ignore */\n }\n}\n\nfunction normalizeEntityId(value: unknown): string | null {\n if (value == null) return null;\n const s = String(value).trim();\n return s || null;\n}\n\n/**\n * Whether a pending apply belongs to this page slot.\n * If pending carries `page` / `entity.id`, the hook opts must match (missing = no match).\n */\nexport function matchesPendingPageActionApply(\n pending: PendingPageActionApply | null | undefined,\n opts: {\n actionKey: string;\n pageContext?: AgentChatPageContext | null;\n },\n): boolean {\n if (!pending) return false;\n const actionKey = opts.actionKey.trim();\n if (!actionKey || pending.actionKey !== actionKey) return false;\n\n const page = opts.pageContext?.page?.trim() || null;\n const pendingPage = pending.pageContext?.page?.trim() || null;\n if (pendingPage && page !== pendingPage) return false;\n\n const entityId = normalizeEntityId(opts.pageContext?.entity?.id);\n const pendingEntityId = normalizeEntityId(pending.pageContext?.entity?.id);\n if (pendingEntityId && entityId !== pendingEntityId) return false;\n\n return true;\n}\n","import type {\n AutomationTaskListItem,\n AutomationTaskStatus,\n AutomationTaskStatusFilter,\n InvokePageActionAccepted,\n PageActionLifecyclePhase,\n} from '../../types';\n\nexport type TrackedAutomationRun = {\n runId: number;\n actionKey: string;\n /** Server-issued de-duplication key (`pageActionKey`). */\n pageActionKey: string | null;\n /** Host list-row key (optional; set by {@link AgentChatInstance.invokePageAction}). */\n rowKey: string | null;\n status: AutomationTaskStatus;\n registeredAt: string;\n updatedAt: string;\n clientActionId: string | null;\n};\n\nexport const AUTOMATION_RECONCILE_STALE_MS = 60_000;\nexport const AUTOMATION_TRACKED_RUN_TTL_MS = 30 * 60_000;\n\nexport function isActiveAutomationTaskStatus(status: AutomationTaskStatus): boolean {\n return status === 'running' || status === 'awaiting_approval';\n}\n\nexport function countActiveTrackedRuns(registry: Map<number, TrackedAutomationRun>): number {\n let count = 0;\n for (const run of registry.values()) {\n if (isActiveAutomationTaskStatus(run.status)) count += 1;\n }\n return count;\n}\n\nexport function collectActivePageActionKeys(\n registry: Map<number, TrackedAutomationRun>,\n): Set<string> {\n const keys = new Set<string>();\n for (const run of registry.values()) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n const key = run.pageActionKey?.trim();\n if (key) keys.add(key);\n }\n return keys;\n}\n\nexport function findActivePageActionKeyForActionKey(\n registry: Map<number, TrackedAutomationRun>,\n actionKey: string,\n): string | null {\n const key = actionKey.trim();\n if (!key) return null;\n for (const run of registry.values()) {\n if (run.actionKey !== key) continue;\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n const pageActionKey = run.pageActionKey?.trim();\n if (pageActionKey) return pageActionKey;\n }\n return null;\n}\n\nexport function pruneStaleTrackedRuns(registry: Map<number, TrackedAutomationRun>): void {\n const cutoff = Date.now() - AUTOMATION_TRACKED_RUN_TTL_MS;\n for (const [runId, run] of registry) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n const updatedAt = Date.parse(run.updatedAt);\n if (Number.isFinite(updatedAt) && updatedAt < cutoff) {\n registry.delete(runId);\n }\n }\n}\n\nexport function taskMatchesStatusFilter(\n status: AutomationTaskStatus,\n filter: AutomationTaskStatusFilter,\n): boolean {\n switch (filter) {\n case 'active':\n return isActiveAutomationTaskStatus(status);\n case 'all':\n return true;\n default:\n return status === filter;\n }\n}\n\nexport function lifecyclePhaseToTaskStatus(\n phase: PageActionLifecyclePhase,\n): AutomationTaskStatus | null {\n switch (phase) {\n case 'started':\n case 'stream':\n return 'running';\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'awaiting_approval':\n return 'awaiting_approval';\n default:\n return null;\n }\n}\n\nexport function buildOptimisticAutomationTaskItem(\n accepted: InvokePageActionAccepted,\n actionKey: string,\n opts?: { title?: string | null; subtitle?: string | null },\n): AutomationTaskListItem {\n const now = new Date().toISOString();\n const taskStatus =\n accepted.status === 'awaiting_approval'\n ? 'awaiting_approval'\n : accepted.status === 'running'\n ? 'running'\n : accepted.status;\n const title = opts?.title?.trim() || formatPageActionDisplayTitle(actionKey);\n return {\n ref: { kind: 'page_action_run', id: accepted.runId },\n triggerSource: 'page_action',\n taskStatus,\n title,\n subtitle: opts?.subtitle?.trim() || null,\n workflowKey: null,\n workflowName: null,\n pageActionKey: accepted.pageActionKey,\n createdAt: now,\n finishedAt: null,\n durationMs: null,\n approval: null,\n outputs: {\n preview: null,\n hasFillText: false,\n },\n };\n}\n\n/**\n * Prefer catalog display name; otherwise last segment of `actionKey`\n * (`campaign-detail.analyze` → `analyze`). Never show a bare hash.\n */\nexport function formatPageActionDisplayTitle(\n actionKey: string,\n catalogName?: string | null,\n): string {\n const named = catalogName?.trim();\n const key = actionKey.trim();\n if (named && named !== key && !looksLikeOpaqueKey(named)) return named;\n if (!key) return 'PageAction';\n if (looksLikeOpaqueKey(key)) return 'PageAction';\n const last = key.includes('.') ? key.slice(key.lastIndexOf('.') + 1) : key;\n return last || key;\n}\n\nfunction looksLikeOpaqueKey(value: string): boolean {\n return /^[a-f0-9]{32,}$/i.test(value.trim());\n}\n\n/** Find all active tracked runs for an actionKey (list pages may have several). */\nexport function findActiveTrackedRunsForActionKey(\n registry: Map<number, TrackedAutomationRun>,\n actionKey: string,\n): TrackedAutomationRun[] {\n const key = actionKey.trim();\n if (!key) return [];\n const rows: TrackedAutomationRun[] = [];\n for (const run of registry.values()) {\n if (run.actionKey !== key) continue;\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n rows.push(run);\n }\n return rows;\n}\n\nexport function findPageActionRunIndex(\n items: AutomationTaskListItem[],\n runId: number,\n): number {\n return items.findIndex(\n (item) => item.ref.kind === 'page_action_run' && item.ref.id === runId,\n );\n}\n\nexport function upsertAutomationTaskListItem(\n items: AutomationTaskListItem[],\n item: AutomationTaskListItem,\n): AutomationTaskListItem[] {\n const index = findPageActionRunIndex(items, item.ref.id);\n if (index >= 0) {\n const next = [...items];\n next[index] = { ...next[index], ...item };\n return next;\n }\n return [item, ...items];\n}\n\nexport function patchAutomationTaskListItem(\n items: AutomationTaskListItem[],\n runId: number,\n patch: Partial<AutomationTaskListItem>,\n): AutomationTaskListItem[] {\n const index = findPageActionRunIndex(items, runId);\n if (index < 0) return items;\n const next = [...items];\n const current = next[index]!;\n next[index] = {\n ...current,\n ...patch,\n outputs: patch.outputs ? { ...current.outputs, ...patch.outputs } : current.outputs,\n approval: patch.approval === undefined ? current.approval : patch.approval,\n };\n return next;\n}\n\nexport function removeAutomationTaskListItem(\n items: AutomationTaskListItem[],\n runId: number,\n): AutomationTaskListItem[] {\n return items.filter(\n (item) => !(item.ref.kind === 'page_action_run' && item.ref.id === runId),\n );\n}\n\nexport function mergeOptimisticRunsIntoList(\n serverItems: AutomationTaskListItem[],\n registry: Map<number, TrackedAutomationRun>,\n): AutomationTaskListItem[] {\n const serverRunIds = new Set(\n serverItems\n .filter((item) => item.ref.kind === 'page_action_run')\n .map((item) => item.ref.id),\n );\n const optimistic: AutomationTaskListItem[] = [];\n for (const run of registry.values()) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n if (serverRunIds.has(run.runId)) continue;\n optimistic.push(\n buildOptimisticAutomationTaskItem(\n {\n runId: run.runId,\n generation: 0,\n clientActionId: run.clientActionId,\n pageActionKey: run.pageActionKey,\n streamUrl: '',\n status: run.status,\n },\n run.actionKey,\n ),\n );\n }\n if (optimistic.length === 0) return serverItems;\n const merged = [...optimistic];\n for (const item of serverItems) {\n if (item.ref.kind === 'page_action_run' && optimistic.some((row) => row.ref.id === item.ref.id)) {\n continue;\n }\n merged.push(item);\n }\n return merged;\n}\n\nexport function mergeRegistryFromActiveListItems(\n registry: Map<number, TrackedAutomationRun>,\n items: AutomationTaskListItem[],\n opts: { fallbackActionKey?: string } = {},\n): void {\n const activeRunIds = new Set<number>();\n const now = new Date().toISOString();\n const nowMs = Date.now();\n const fallbackActionKey = opts.fallbackActionKey?.trim() || null;\n for (const item of items) {\n if (item.ref.kind !== 'page_action_run') continue;\n if (!isActiveAutomationTaskStatus(item.taskStatus)) continue;\n activeRunIds.add(item.ref.id);\n const existing = registry.get(item.ref.id);\n // List items only expose `title` (often == actionKey when optimistic). Prefer\n // tracked actionKey, then caller filter (GET ?actionKey=), then title.\n const actionKey =\n fallbackActionKey || existing?.actionKey || item.title;\n registry.set(item.ref.id, {\n runId: item.ref.id,\n actionKey,\n pageActionKey: existing?.pageActionKey ?? item.pageActionKey ?? null,\n rowKey: existing?.rowKey ?? null,\n status: item.taskStatus,\n registeredAt: existing?.registeredAt ?? item.createdAt ?? now,\n updatedAt: now,\n clientActionId: existing?.clientActionId ?? null,\n });\n }\n for (const runId of registry.keys()) {\n if (activeRunIds.has(runId)) continue;\n const tracked = registry.get(runId);\n if (!tracked) continue;\n const registeredAt = Date.parse(tracked.registeredAt);\n if (Number.isFinite(registeredAt) && nowMs - registeredAt < 30_000) {\n continue;\n }\n registry.delete(runId);\n }\n}\n","import type { AutomationTaskListItem, AutomationTaskStatusFilter } from '../../types';\n\nexport const AUTOMATION_TASK_CENTER_TABS = [\n 'active',\n 'awaiting_approval',\n 'completed',\n 'failed',\n] as const satisfies readonly AutomationTaskStatusFilter[];\n\nexport type AutomationTaskTabCache = {\n items: AutomationTaskListItem[];\n hasMore: boolean;\n total: number;\n /** Whether this tab has completed at least one list fetch. */\n hydrated: boolean;\n};\n\nexport function createAutomationTaskTabCaches(): Map<\n AutomationTaskStatusFilter,\n AutomationTaskTabCache\n> {\n const map = new Map<AutomationTaskStatusFilter, AutomationTaskTabCache>();\n for (const tab of AUTOMATION_TASK_CENTER_TABS) {\n map.set(tab, emptyAutomationTaskTabCache());\n }\n return map;\n}\n\nexport function emptyAutomationTaskTabCache(): AutomationTaskTabCache {\n return { items: [], hasMore: false, total: 0, hydrated: false };\n}\n\nexport function getAutomationTaskTabCache(\n caches: Map<AutomationTaskStatusFilter, AutomationTaskTabCache>,\n filter: AutomationTaskStatusFilter,\n): AutomationTaskTabCache {\n return caches.get(filter) ?? emptyAutomationTaskTabCache();\n}\n\nexport function writeAutomationTaskTabCache(\n caches: Map<AutomationTaskStatusFilter, AutomationTaskTabCache>,\n filter: AutomationTaskStatusFilter,\n patch: Partial<AutomationTaskTabCache> & { items?: AutomationTaskListItem[] },\n): void {\n const prev = getAutomationTaskTabCache(caches, filter);\n caches.set(filter, {\n items: patch.items ?? prev.items,\n hasMore: patch.hasMore ?? prev.hasMore,\n total: patch.total ?? prev.total,\n hydrated: patch.hydrated ?? prev.hydrated,\n });\n}\n","import type {\n AutomationTaskStatus,\n PageActionPhase,\n PageActionRowState,\n} from '../../types';\nimport type { TrackedAutomationRun } from '../automation/automation-run-tracker';\nimport { isActiveAutomationTaskStatus } from '../automation/automation-run-tracker';\n\nexport function createIdlePageActionRowState(\n rowKey: string,\n actionKey: string,\n): PageActionRowState {\n return {\n rowKey,\n actionKey,\n runId: null,\n pageActionKey: null,\n phase: 'idle',\n awaitingApproval: false,\n awaitingClarify: false,\n loading: false,\n disabled: false,\n error: null,\n message: null,\n progressLabel: null,\n narrativeItems: [],\n approvalRequestId: null,\n brainClarify: null,\n updatedAt: Date.now(),\n };\n}\n\nexport function derivePageActionRowFlags(\n phase: PageActionPhase,\n): Pick<PageActionRowState, 'awaitingApproval' | 'awaitingClarify' | 'loading' | 'disabled'> {\n const awaitingApproval = phase === 'awaiting_approval';\n const awaitingClarify = phase === 'awaiting_clarify';\n const awaitingReuse = phase === 'awaiting_reuse';\n // Reuse picker must NOT disable the trigger — outside-dismiss + re-click was\n // getting stuck when React row state lagged behind the client unlock.\n const loading =\n !awaitingApproval &&\n !awaitingClarify &&\n !awaitingReuse &&\n (phase === 'submitting' || phase === 'launched' || phase === 'streaming');\n return {\n awaitingApproval,\n awaitingClarify,\n loading,\n // awaiting_reuse stays clickable so dismiss → re-open works even if UI state lags.\n disabled: loading || awaitingApproval || awaitingClarify,\n };\n}\n\nexport function taskStatusToPageActionPhase(\n status: AutomationTaskStatus,\n): PageActionPhase {\n switch (status) {\n case 'awaiting_approval':\n return 'awaiting_approval';\n case 'running':\n return 'streaming';\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'cancelled':\n return 'idle';\n default:\n return 'idle';\n }\n}\n\nexport function resolvePageActionRowKey(input: {\n rowKey?: string | null;\n entityId?: string | number | null;\n}): string | null {\n const explicit = input.rowKey?.trim();\n if (explicit) return explicit;\n if (input.entityId == null) return null;\n const asString = String(input.entityId).trim();\n return asString || null;\n}\n\n/** Synthetic fallback when no host row slot is known before detail is loaded. */\nexport function syntheticPageActionRunRowKey(runId: number): string {\n return `run:${Math.trunc(runId)}`;\n}\n\n/**\n * Resolve list/detail row slot after refresh — prefer host `entity.id` over `run:{id}`.\n */\nexport function resolveRestoredPageActionRowKey(\n runId: number,\n input: {\n rowKey?: string | null;\n entityId?: string | number | null;\n findRowKeyByRunId?: () => string | null | undefined;\n } = {},\n): string {\n const id = Math.trunc(runId);\n const synthetic = syntheticPageActionRunRowKey(id);\n const explicit = input.rowKey?.trim();\n if (explicit && explicit !== synthetic) return explicit;\n const fromRun = input.findRowKeyByRunId?.()?.trim();\n if (fromRun) return fromRun;\n const fromEntity = resolvePageActionRowKey({ entityId: input.entityId ?? null });\n if (fromEntity) return fromEntity;\n return explicit || synthetic;\n}\n\nexport function buildPageActionRowState(\n partial: Omit<\n PageActionRowState,\n | 'awaitingApproval'\n | 'awaitingClarify'\n | 'loading'\n | 'disabled'\n | 'updatedAt'\n | 'message'\n | 'progressLabel'\n | 'narrativeItems'\n | 'brainClarify'\n > & {\n awaitingApproval?: boolean;\n awaitingClarify?: boolean;\n loading?: boolean;\n disabled?: boolean;\n updatedAt?: number;\n message?: string | null;\n progressLabel?: string | null;\n narrativeItems?: PageActionRowState['narrativeItems'];\n brainClarify?: PageActionRowState['brainClarify'];\n },\n): PageActionRowState {\n const flags = derivePageActionRowFlags(partial.phase);\n return {\n ...partial,\n message: partial.message ?? null,\n progressLabel: partial.progressLabel ?? null,\n narrativeItems: partial.narrativeItems ?? [],\n brainClarify: partial.brainClarify ?? null,\n awaitingApproval: partial.awaitingApproval ?? flags.awaitingApproval,\n awaitingClarify: partial.awaitingClarify ?? flags.awaitingClarify,\n loading: partial.loading ?? flags.loading,\n disabled: partial.disabled ?? flags.disabled,\n updatedAt: partial.updatedAt ?? Date.now(),\n };\n}\n\nexport function findTrackedRunsByActionKey(\n registry: Map<number, TrackedAutomationRun>,\n actionKey: string,\n): TrackedAutomationRun[] {\n const key = actionKey.trim();\n if (!key) return [];\n const rows: TrackedAutomationRun[] = [];\n for (const run of registry.values()) {\n if (run.actionKey !== key) continue;\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n rows.push(run);\n }\n return rows;\n}\n\nexport function findTrackedRunByPageActionKey(\n registry: Map<number, TrackedAutomationRun>,\n pageActionKey: string,\n): TrackedAutomationRun | null {\n const key = pageActionKey.trim();\n if (!key) return null;\n for (const run of registry.values()) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n if (run.pageActionKey?.trim() === key) return run;\n }\n return null;\n}\n\nexport function findTrackedRunByRowKey(\n registry: Map<number, TrackedAutomationRun>,\n rowKey: string,\n): TrackedAutomationRun | null {\n const key = rowKey.trim();\n if (!key) return null;\n for (const run of registry.values()) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n if (run.rowKey?.trim() === key) return run;\n }\n return null;\n}\n","import { matchesPendingPageActionApply } from './pending-page-action-apply';\nimport type {\n AgentChatPageContext,\n PageActionApplyPhase,\n PendingPageActionApply,\n} from '../../types';\n\n/** List-level bind: reconcile all rows for an actionKey (no per-row apply). */\nexport const PAGE_ACTION_ACTION_SCOPE_ROW_KEY = '*';\n\n/** Host-registered PageAction UI slot (one button / one list row). */\nexport type PageActionSlotBinding = {\n actionKey: string;\n rowKey: string;\n pageContext?: AgentChatPageContext | null;\n ready: boolean;\n autoResume: boolean;\n autoApplyPending: boolean;\n};\n\nexport type PageActionSlotSyncResult = {\n applyPhase: PageActionApplyPhase;\n};\n\nexport type PageActionCoordinatorDeps = {\n ensureLoggedIn: () => Promise<void>;\n reconcileActivePageActions: (opts: { actionKey: string }) => Promise<unknown>;\n resumeActivePageActionStreams: (opts: { actionKey: string }) => Promise<number>;\n replayPageAction: (runId: number) => Promise<void>;\n getPendingPageActionApply: () => PendingPageActionApply | null;\n onApplyPhaseChanged: (slotKey: string, phase: PageActionApplyPhase) => void;\n};\n\nexport function pageActionSlotKey(binding: Pick<PageActionSlotBinding, 'actionKey' | 'rowKey'>): string {\n return `${binding.actionKey.trim()}::${binding.rowKey.trim()}`;\n}\n\nfunction isActionScopeRowKey(rowKey: string): boolean {\n const key = rowKey.trim();\n return !key || key === PAGE_ACTION_ACTION_SCOPE_ROW_KEY;\n}\n\n/**\n * Owns PageAction slot bindings and the **single** restore pipeline:\n * auth ready → reconcile server active runs → attach SSE → consume pending apply.\n *\n * Hooks only register/unregister slots; they do not run parallel reconcile effects.\n */\nexport class PageActionCoordinator {\n private readonly slots = new Map<string, PageActionSlotBinding>();\n private readonly syncInflight = new Map<string, Promise<PageActionSlotSyncResult>>();\n /** Slots that need another sync after the current inflight run (pending apply race). */\n private readonly syncDirty = new Set<string>();\n private readonly liveRestoreInflight = new Map<string, Promise<void>>();\n private readonly applyPhaseBySlot = new Map<string, PageActionApplyPhase>();\n private readonly replayInflight = new Set<number>();\n private readonly deps: PageActionCoordinatorDeps;\n\n constructor(deps: PageActionCoordinatorDeps) {\n this.deps = deps;\n }\n\n getApplyPhase(slotKey: string): PageActionApplyPhase {\n return this.applyPhaseBySlot.get(slotKey) ?? 'idle';\n }\n\n bind(binding: PageActionSlotBinding): () => void {\n const key = pageActionSlotKey(binding);\n this.slots.set(key, binding);\n void this.syncSlot(key);\n return () => {\n this.slots.delete(key);\n this.syncInflight.delete(key);\n this.syncDirty.delete(key);\n this.applyPhaseBySlot.delete(key);\n };\n }\n\n patch(slotKey: string, patch: Partial<PageActionSlotBinding>): void {\n const prev = this.slots.get(slotKey);\n if (!prev) return;\n this.slots.set(slotKey, { ...prev, ...patch });\n void this.syncSlot(slotKey);\n }\n\n /** After init / login — restore every registered slot once. */\n onAuthReady(): void {\n for (const key of this.slots.keys()) {\n void this.syncSlot(key);\n }\n }\n\n onPendingApplyChanged(): void {\n for (const [key, binding] of this.slots) {\n if (!binding.autoApplyPending) continue;\n void this.syncSlot(key);\n }\n }\n\n /** Debug: currently registered slots (demo / integration). */\n listBindings(): PageActionSlotBinding[] {\n return [...this.slots.values()];\n }\n\n private setApplyPhase(slotKey: string, phase: PageActionApplyPhase): PageActionSlotSyncResult {\n this.applyPhaseBySlot.set(slotKey, phase);\n this.deps.onApplyPhaseChanged(slotKey, phase);\n return { applyPhase: phase };\n }\n\n private matchesPending(binding: PageActionSlotBinding): PendingPageActionApply | null {\n if (isActionScopeRowKey(binding.rowKey)) return null;\n const pending = this.deps.getPendingPageActionApply();\n if (!pending) return null;\n const matched = matchesPendingPageActionApply(pending, {\n actionKey: binding.actionKey,\n pageContext: binding.pageContext,\n });\n return matched ? pending : null;\n }\n\n /**\n * Coalesce concurrent syncs, but re-run when a sync was requested while one\n * was already in flight (e.g.「应用到页面」pending arrives mid live-restore).\n */\n private async syncSlot(slotKey: string): Promise<PageActionSlotSyncResult> {\n const existing = this.syncInflight.get(slotKey);\n if (existing) {\n this.syncDirty.add(slotKey);\n return existing;\n }\n\n const runHolder: { current: Promise<PageActionSlotSyncResult> | null } = {\n current: null,\n };\n const run = (async (): Promise<PageActionSlotSyncResult> => {\n let last: PageActionSlotSyncResult = { applyPhase: this.getApplyPhase(slotKey) };\n try {\n do {\n this.syncDirty.delete(slotKey);\n last = await this.runSlotSync(slotKey);\n } while (this.syncDirty.has(slotKey) && this.slots.has(slotKey));\n return last;\n } finally {\n if (this.syncInflight.get(slotKey) === runHolder.current) {\n this.syncInflight.delete(slotKey);\n }\n }\n })();\n runHolder.current = run;\n\n this.syncInflight.set(slotKey, run);\n return run;\n }\n\n /** Path A — dedupe reconcile + SSE attach per actionKey across slots. */\n private async runLiveRestore(actionKey: string): Promise<void> {\n const key = actionKey.trim();\n if (!key) return;\n\n const existing = this.liveRestoreInflight.get(key);\n if (existing) {\n await existing;\n return;\n }\n\n const run = (async () => {\n await this.deps.reconcileActivePageActions({ actionKey: key });\n await this.deps.resumeActivePageActionStreams({ actionKey: key });\n })().finally(() => {\n if (this.liveRestoreInflight.get(key) === run) {\n this.liveRestoreInflight.delete(key);\n }\n });\n this.liveRestoreInflight.set(key, run);\n await run;\n }\n\n private async runSlotSync(slotKey: string): Promise<PageActionSlotSyncResult> {\n const binding = this.slots.get(slotKey);\n if (!binding) return { applyPhase: 'idle' };\n\n try {\n await this.deps.ensureLoggedIn();\n } catch {\n return this.setApplyPhase(slotKey, 'idle');\n }\n\n // Re-read binding after await — patch/unbind may have raced.\n const latest = this.slots.get(slotKey);\n if (!latest) return { applyPhase: 'idle' };\n\n // Path B —「应用到页面」:completed replay(与 live SSE 无关)\n if (latest.autoApplyPending && !isActionScopeRowKey(latest.rowKey)) {\n const pending = this.matchesPending(latest);\n if (pending) {\n if (!latest.ready) {\n return this.setApplyPhase(slotKey, 'waiting_ready');\n }\n if (this.replayInflight.has(pending.runId)) {\n return this.setApplyPhase(slotKey, 'replaying');\n }\n this.replayInflight.add(pending.runId);\n this.setApplyPhase(slotKey, 'replaying');\n try {\n await this.deps.replayPageAction(pending.runId);\n return this.setApplyPhase(slotKey, 'done');\n } catch {\n return this.setApplyPhase(slotKey, 'error');\n } finally {\n this.replayInflight.delete(pending.runId);\n }\n }\n if (this.getApplyPhase(slotKey) !== 'idle') {\n this.setApplyPhase(slotKey, 'idle');\n }\n }\n\n // Path A — live run:refresh / mount reconnect\n if (!latest.autoResume) {\n return { applyPhase: this.getApplyPhase(slotKey) };\n }\n\n await this.runLiveRestore(latest.actionKey);\n return { applyPhase: this.getApplyPhase(slotKey) };\n }\n}\n","/**\n * Source-of-truth SDK version string. Kept here (rather than importing\n * package.json) so the library can be consumed without JSON imports.\n *\n * This must be bumped together with `package.json.version` and the\n * `CHANGELOG.md` entry on every release.\n */\nexport const SDK_VERSION = '2.4.7';\n","/**\n * Generate a short, URL-safe random id. Uses `crypto.randomUUID` when\n * available (modern browsers + Node 19+) and falls back to `Math.random`\n * for very old engines or test environments.\n */\nexport function nanoId(prefix = 'id'): string {\n const cryptoLike = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (cryptoLike?.randomUUID) {\n return `${prefix}_${cryptoLike.randomUUID().replace(/-/g, '').slice(0, 12)}`;\n }\n const rand = Math.random().toString(36).slice(2, 14);\n return `${prefix}_${rand}`;\n}\n","import {\n applyAccessTokenHeader,\n clearAccessTokenHeader,\n} from '../auth/auth-headers';\nimport {\n parseAgentList,\n parseChatSessionDetailPage,\n parseChatSessionListPage,\n parseCreateSessionResponse,\n parsePostedMessage,\n parseSkillList,\n} from '../chat/chat-response';\nimport { useAuthStore } from '../auth/auth-store';\nimport {\n getSdkAccessTokenForDsn,\n isSdkAuthenticatedForDsn,\n waitForAuthStoreRehydration,\n} from '../auth/auth-session';\nimport { LoginGate, type PendingGateJob } from '../auth/login-gate';\nimport type { AppClientAuthData } from '../auth/auth-types';\nimport { ensureExtensionAuthResyncListener } from '../extension/auth-extension-resync';\nimport { AgentChatError } from '../lib/errors';\nimport { EventBus } from '../lib/events';\nimport { normalizeDsn, DSN_AUTH_HEADER, DEFAULT_BASE_URL } from '../lib/resolve';\nimport { parseChatSseEvent, type ChatSseUiAction } from '../chat/chat-sse';\nimport { isStaleAgentRunEvent, parseRunGeneration, parseSessionRunState, type SessionRunStateSnapshot } from '../chat/session-run';\nimport { buildClientSkillListQuery, resolveDefaultSkillId } from '../page/skill-client';\nimport { dispatchHostAction } from '../host-tool/host-action-registry';\nimport { hostActionSseToAgentAction, isDispatchableHostAction } from '../host-tool/host-action';\nimport { executeHostToolsFromAction, registerHostTool, runHostTool, undeclareHostTool, unregisterHostTool } from '../host-tool/host-tool-registry';\nimport {\n HostToolStreamManager,\n isHostToolStreamEnabled,\n} from '../host-tool/stream/host-tool-stream';\nimport type { HostActionSsePayload } from '../host-tool/stream/host-tool-stream.types';\nimport { isHostActionStreamPayload } from '../host-tool/stream/host-tool-stream.types';\nimport type { PageContextGate } from '../host-tool/stream/host-tool-stream-gate';\nimport { registerHostToolsWithSync, flushPendingHostToolSyncs } from '../host-tool/register-host-tools';\nimport {\n mergeRouteContext,\n readWindowRouteContext,\n} from '../page/route-context';\nimport { mergePageContextWithMentions } from '../page/context-mention';\nimport {\n mergeContextMentionRegistrations,\n resolveContextMentionsForSend,\n toRegisteredContextMention,\n} from '../page/context-mention-registry';\nimport { normalizeContextMentionInput } from '../page/context-mention-define';\nimport { createHttpClient } from '../http';\nimport { AuthService, AgentService, ChatService, FeedbackService, HostToolService, AgentRunService, PageActionService, ApprovalService, AutomationService, AppToolService, DEFAULT_MESSAGE_PAGE_SIZE, DEFAULT_SESSION_PAGE_SIZE } from '../services';\nimport type {\n AppToolCallableList,\n AppToolInvokeInput,\n AppToolInvokeResult,\n} from '../services/app-tool.service';\nimport type { MessageSendContext } from '../services/chat.service';\nimport { SessionManager } from '../auth/auth';\nimport {\n isPersistedMessageId,\n parsePersistedMessageId,\n} from '../feedback/feedback-utils';\nimport {\n applyPatches,\n applyStreamDelta,\n applyStreamFull,\n blocksToText,\n parseStoredBlocks,\n unwrapBlocksJsonEnvelope,\n type CoreMessageBlock,\n} from '../chat/message-blocks';\nimport {\n parseAgentRunDetail,\n readSkillIntentMismatchObservation,\n readSkillTurnContract,\n resolveAlignmentSteps,\n isRequestedSkillActuallyUsed,\n shouldShowIntentFirstBanner,\n shouldShowSkillClarifyCard,\n} from '../chat/skill-intent-alignment';\nimport {\n consumePageActionRunStream,\n pageGateFromPageContext,\n rethrowPageActionError,\n PAGE_ACTION_STREAM_KEY_PREFIX,\n} from '../page/page-action-client';\nimport {\n buildEntityCommit,\n extractBrainClarifyFromRunSteps,\n formatBrainClarifyCandidateLabel,\n isBrainAskUserErrorCode,\n} from '../page/brain-clarify';\nimport {\n defaultPageActionProgressLabel,\n pageActionAwaitingClarifyLabel,\n pageActionAlreadyAwaitingApprovalTip,\n pageActionAlreadyRunningTip,\n pageActionReuseCheckingLabel,\n pageActionReusedMessage,\n pageActionReusingLabel,\n pageActionTaskAwaitingApprovalSubtitle,\n pageActionTaskRunningSubtitle,\n appendPageActionNarrativeItems,\n resolvePageWorkflowProgressLabel,\n type PageWorkflowEvent,\n} from '../page/page-action-workflow-progress';\nimport { readLaunchSourceRect } from '../page/page-action-launch';\nimport { PageActionReuseHintCache } from '../page/page-action-reuse-cache';\nimport { buildPageActionInvokePageContextSnapshot } from '../page/page-context-snapshot';\nimport {\n resolvePageContextNavigateTarget,\n type ApplyPageActionToPageResult,\n} from '../page/page-context-navigate';\nimport {\n clearPendingPageActionApplyStorage,\n matchesPendingPageActionApply,\n readPendingPageActionApply,\n writePendingPageActionApply,\n} from '../page/pending-page-action-apply';\nimport {\n AUTOMATION_RECONCILE_STALE_MS,\n buildOptimisticAutomationTaskItem,\n collectActivePageActionKeys,\n findActivePageActionKeyForActionKey,\n formatPageActionDisplayTitle,\n countActiveTrackedRuns,\n isActiveAutomationTaskStatus,\n lifecyclePhaseToTaskStatus,\n mergeOptimisticRunsIntoList,\n mergeRegistryFromActiveListItems,\n patchAutomationTaskListItem,\n pruneStaleTrackedRuns,\n removeAutomationTaskListItem,\n taskMatchesStatusFilter,\n upsertAutomationTaskListItem,\n type TrackedAutomationRun,\n} from '../automation/automation-run-tracker';\nimport { resolveAutomationTaskListHasMore } from '../automation/automation-response';\nimport {\n createAutomationTaskTabCaches,\n getAutomationTaskTabCache,\n writeAutomationTaskTabCache,\n type AutomationTaskTabCache,\n} from '../automation/automation-task-tab-store';\nimport type {\n AgentChatEventMap,\n AgentChatErrorPayload,\n AgentChatInstance,\n AgentChatLoginCredentials,\n AgentChatLifecycle,\n AgentChatOptions,\n AgentChatPageContext,\n AgentChatHostAction,\n AgentChatRouteContext,\n AgentChatState,\n AgentMessage,\n ContextMentionAttachment,\n ContextMentionDefinition,\n ContextMentionRegistration,\n RegisteredContextMention,\n RegisterContextMentionsOptions,\n AgentStreamState,\n AgentsEmptyReason,\n ChatAgentSummary,\n ChatSessionSummary,\n ChatSkillSummary,\n HostToolHandler,\n MessageFeedbackDownReasonTag,\n MessageFeedbackView,\n PrepareSessionOptions,\n PrepareSessionResult,\n RegisterHostToolsOptions,\n SkillIntentBannerState,\n SkillIntentClarifyState,\n BrainClarifyUiState,\n BrainClarifyPayload,\n SkillTurnActiveState,\n SkillTurnContractView,\n UpsertMessageFeedbackBody,\n UserContext,\n WriteConfirmationState,\n WriteGate,\n SessionRunSnapshot,\n PageBotInvokeInput,\n PageBotStreamResult,\n PendingPageActionApply,\n InvokePageActionRequest,\n ApprovalInboxList,\n ApprovalInboxStatusFilter,\n ApprovalDetail,\n ApprovalConfirmResult,\n ApprovalDecideResult,\n ApprovalRejectResult,\n ApprovalExecutionCompletedPayload,\n ApprovalExecutionOutcome,\n DraftReviewDecision,\n PageAgentLifecyclePayload,\n PageAgentSource,\n PageAgentErrorContext,\n PageAgentAwaitingApprovalPayload,\n OpenApprovalInboxPayload,\n OpenAutomationTaskCenterPayload,\n OpenPageActionFeedbackPayload,\n PageActionFeedbackCatalogItem,\n PageActionFeedbackCatalogQuery,\n PageActionFeedbackSummary,\n PageActionFeedbackView,\n UpsertPageActionFeedbackInput,\n CreatePageActionWishInput,\n PageActionWishList,\n PageActionWishQuery,\n PageActionWishView,\n AutoAgentBinding,\n AutomationTaskList,\n AutomationTaskListItem,\n AutomationTaskDetail,\n AutomationTaskStatus,\n AutomationTaskStatusFilter,\n InvokePageActionAccepted,\n PageActionSubmittedPayload,\n PageActionSseLifecycle,\n PageActionRowState,\n PageActionPhase,\n PageActionReuseHint,\n PageActionReusePromptHandler,\n PageActionReusePromptRequest,\n PageActionReusableItem,\n PageActionBrainClarifyInvokeSnapshot,\n PageActionBrainClarifyPromptRequest,\n EntityCommit,\n} from '../../types';\nimport {\n buildPageActionRowState,\n derivePageActionRowFlags,\n resolvePageActionRowKey,\n resolveRestoredPageActionRowKey,\n taskStatusToPageActionPhase,\n} from '../page/page-action-rows';\nimport {\n PageActionCoordinator,\n type PageActionSlotBinding,\n} from '../page/page-action-coordinator';\nimport { SDK_VERSION } from '../../utils/sdk-version';\nimport { nanoId } from '../../utils/id';\n\nfunction trimRight(s: string): string {\n return s.replace(/\\/+$/, '');\n}\n\nconst APPROVAL_INBOX_PAGE_SIZE = 20;\nconst AUTOMATION_TASK_PAGE_SIZE = 20;\nconst MAX_RECENT_AUTOMATION_RUN_IDS = 20;\n\nfunction normalizeSessionId(sessionId: string): string {\n return sessionId.trim().toLowerCase();\n}\n\nfunction mergeSessionSummaries(\n existing: ChatSessionSummary[],\n incoming: ChatSessionSummary[],\n): ChatSessionSummary[] {\n const seen = new Set(existing.map((row) => normalizeSessionId(row.sessionId)));\n const merged = [...existing];\n for (const row of incoming) {\n const key = normalizeSessionId(row.sessionId);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(row);\n }\n return merged;\n}\n\nfunction mergeOlderMessages(\n existing: AgentMessage[],\n older: AgentMessage[],\n): AgentMessage[] {\n const seen = new Set(existing.map((message) => String(message.id)));\n const prepended: AgentMessage[] = [];\n for (const message of older) {\n const key = String(message.id);\n if (seen.has(key)) continue;\n seen.add(key);\n prepended.push(message);\n }\n return [...prepended, ...existing];\n}\n\ninterface SessionMessagesCacheEntry {\n messages: AgentMessage[];\n page: number;\n hasMore: boolean;\n agentId?: string;\n}\n\nfunction createEmptyAgentStream(): AgentStreamState {\n return { phase: 'thinking', thinkText: '', resultText: '' };\n}\n\n/** Finalize a streamed assistant turn (result only; thinking is not kept). */\nfunction finalizeAgentReply(\n message: AgentMessage,\n stream: AgentStreamState,\n overrides: Partial<AgentMessage> = {},\n): AgentMessage {\n const resultText =\n (overrides.content?.type === 'text' ? overrides.content.text : undefined) ??\n (stream.resultText || message.content.text);\n const rawBlocks = overrides.blocks ?? stream.resultBlocks ?? message.blocks;\n const parsedFromText = parseStoredBlocks(resultText);\n const blocks = parsedFromText ?? unwrapBlocksJsonEnvelope((rawBlocks ?? []) as CoreMessageBlock[]);\n const text = parsedFromText ? blocksToText(blocks) : resultText;\n return {\n ...message,\n ...overrides,\n status: overrides.status ?? 'sent',\n content: { type: 'text', text },\n blocks,\n thinkText: undefined,\n stream: undefined,\n };\n}\n\ninterface ServerMessage {\n id: number | string;\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string | null;\n createdAt: string | number | Date;\n}\n\ninterface SessionStreamHandle {\n abort: AbortController;\n targetMessageId: string | null;\n}\n\ninterface SessionRunState {\n sessionGeneration: number;\n activeRunId: number | null;\n activeTurnId: number | null;\n pendingJobCount: number;\n redisBacked: boolean;\n}\n\ninterface InternalState {\n options: AgentChatOptions;\n /** Opaque DSN string the consumer supplied; forwarded as `x-app-dsn`. */\n dsn: string;\n /**\n * Backend base URL used for **all** API calls (sessions, messages, login,\n * and the init-time `/app-client/auth` ping). Normalized to have no\n * trailing slash. Mirrors the value of {@link InternalState.options.baseUrl}\n * after applying defaults.\n */\n apiBaseUrl: string;\n http: ReturnType<typeof createHttpClient>;\n auth: AuthService;\n chat: ChatService;\n agent: AgentService;\n feedback: FeedbackService;\n hostTool: HostToolService;\n agentRun: AgentRunService;\n pageAction: PageActionService;\n approval: ApprovalService;\n automation: AutomationService;\n appTool: AppToolService;\n session: SessionManager;\n abortControllers: Set<AbortController>;\n isOpen: boolean;\n /** `POST /app-client/auth` succeeded at init; gates the floating launcher. */\n isClientAuthenticated: boolean;\n isLoggedIn: boolean;\n /** Sessions/agents/messages bootstrap completed for the current login. */\n catalogHydrated: boolean;\n sessions: ChatSessionSummary[];\n sessionsPage: number;\n sessionsPageSize: number;\n sessionsHasMore: boolean;\n sessionsLoadingMore: boolean;\n activeSessionId: string | null;\n activeSessionMessagesPage: number;\n activeSessionMessagesHasMore: boolean;\n sessionMessagesLoadingMore: boolean;\n sessionMessagesPageSize: number;\n sessionMessagesCache: Map<string, SessionMessagesCacheEntry>;\n agents: ChatAgentSummary[];\n skills: ChatSkillSummary[];\n selectedAgentId: string | null;\n autoAgent: AutoAgentBinding | null;\n selectedSkillId: string | null;\n agentsLoading: boolean;\n skillsLoading: boolean;\n agentsEmptyReason: AgentsEmptyReason;\n /** User JWT used as `Authorization: Bearer` on C-end APIs. */\n userJwt: string | null;\n /** Open SSE connections keyed by normalized session id. */\n sessionStreams: Map<string, SessionStreamHandle>;\n /** Per-session run coordinator state (`generation` / active `runId`). */\n sessionRuns: Map<string, SessionRunState>;\n messages: AgentMessage[];\n lastError: AgentChatErrorPayload | null;\n writeConfirmation: WriteConfirmationState | null;\n /** Pending write confirmations keyed by normalized session id. */\n writeConfirmationsBySession: Map<string, WriteConfirmationState>;\n approvalInboxLoading: boolean;\n approvalInboxLoadingMore: boolean;\n approvalInboxHasMore: boolean;\n approvalInboxStatusFilter: ApprovalInboxStatusFilter;\n approvalInboxPendingCount: number;\n approvalInboxItems: ApprovalInboxList['items'];\n automationTaskLoading: boolean;\n automationTaskLoadingMore: boolean;\n automationTaskHasMore: boolean;\n automationTaskTotal: number;\n automationTaskStatusFilter: AutomationTaskStatusFilter;\n automationTaskActiveCount: number;\n automationTaskItems: AutomationTaskList['items'];\n /** Per-tab list cache — switching tabs restores without refetching page 1. */\n automationTaskTabCaches: Map<AutomationTaskStatusFilter, AutomationTaskTabCache>;\n automationRecentRunIds: number[];\n automationTaskSelectedDetail: AutomationTaskDetail | null;\n automationTaskDetailLoading: boolean;\n skillIntentBanner: SkillIntentBannerState | null;\n skillIntentClarify: SkillIntentClarifyState | null;\n brainClarify: BrainClarifyUiState | null;\n skillTurnContract: SkillTurnContractView | null;\n skillTurnActive: SkillTurnActiveState | null;\n /** Last user message text for the active turn (skill clarify resend). */\n lastTurnUserMessage: string | null;\n skillPickerOpen: boolean;\n downReasonTagsCache: MessageFeedbackDownReasonTag[] | null;\n /** Latest extended page context (prop or {@link setPageContext}). */\n pageContext: AgentChatPageContext | null;\n /** Host override for route path / params (merged with window on sync). */\n routeContextOverride: AgentChatRouteContext | null;\n /** Resolved route sent with every message. */\n routeContext: AgentChatRouteContext | null;\n attachPageContext: boolean;\n appClientId: number | null;\n contextMentionRegistry: Map<string, ContextMentionRegistration>;\n}\n\nfunction defaultLocale(): string {\n if (typeof navigator !== 'undefined' && navigator.language) return navigator.language;\n return 'en';\n}\n\nfunction browserOrigin(): string {\n if (typeof window !== 'undefined' && window.location?.origin) return window.location.origin;\n return 'unknown://sdk';\n}\n\nexport class AgentChatClient implements AgentChatInstance {\n readonly id: string;\n private bus = new EventBus<AgentChatEventMap>();\n private lifecycle: AgentChatLifecycle = 'uninitialized';\n private state: InternalState | null = null;\n private stateChangeListeners = new Set<() => void>();\n /** Bumped when session/messages are changed locally; stale `selectSession` loads are ignored. */\n private sessionEpoch = 0;\n /**\n * Cached `AgentChatState` snapshot returned by {@link getState}. React's\n * `useSyncExternalStore` requires `getSnapshot` to return the same object\n * reference until the store actually changes — otherwise concurrent\n * rendering treats it as torn state, repeatedly remounts the subtree, and\n * (combined with antd's cssinjs cache) the launcher visibly flashes and\n * disappears. We invalidate this cache from {@link notifyStateChange}.\n */\n private stateSnapshot: AgentChatState | null = null;\n private authStoreUnsub: (() => void) | undefined;\n private prepareAbort: AbortController | null = null;\n private prepareTimer: ReturnType<typeof setTimeout> | null = null;\n private lastPrepareFingerprint: string | null = null;\n /** Ignores stale `refreshSkills` results when page or agent changes quickly. */\n private skillsLoadToken = 0;\n /** Target assistant message id before SSE connect registers a stream handle. */\n private pendingStreamTargets = new Map<string, string>();\n /** In-flight `connectSessionStream` per session (prevents duplicate SSE). */\n private sessionStreamConnects = new Map<string, Promise<void>>();\n /** Skip auto-reconnect after intentional `abortSessionStream` (e.g. session switch). */\n private sessionStreamSuppressReconnect = new Set<string>();\n /** Debounced reconnect timers per session. */\n private sessionStreamReconnectTimers = new Map<string, ReturnType<typeof setTimeout>>();\n /** Exponential backoff attempt counter per session. */\n private sessionStreamReconnectAttempts = new Map<string, number>();\n /** Per-session Host Tool DSL v1 reducer state. */\n private hostToolStreamManagers = new Map<string, HostToolStreamManager>();\n /** In-flight Page Bot invokes keyed by `clientActionId`. */\n private pageActionInFlightKeys = new Set<string>();\n /** Coalesce concurrent `GET /approval/inbox` refreshes (list + badge filter). */\n private approvalInboxRefreshPromise: Promise<ApprovalInboxList> | null = null;\n /** Coalesce concurrent pending-count badge refreshes. */\n private approvalPendingCountRefreshPromise: Promise<void> | null = null;\n /**\n * PageAction runs that already emitted awaiting-approval UI for this session.\n * Prevents duplicate notifications + inbox fetches when both early return and\n * run SSE report the same pause (common on 409 / awaitStream:false).\n */\n private pageActionAwaitingApprovalNotified = new Set<number>();\n /** Coalesce concurrent `GET /automation/tasks` refreshes. */\n private automationTaskRefreshPromise: Promise<AutomationTaskList> | null = null;\n private automationTaskRefreshCacheKey: string | null = null;\n /** Bumps on full refresh to drop stale in-flight append publishes. */\n private automationTaskListPublishSeq = 0;\n /** Background PageAction run stream abort controllers keyed by runId. */\n private pageActionRunAborts = new Map<number, AbortController>();\n /** In-flight consume promises keyed by runId — dedupe concurrent attach/replay. */\n private pageActionRunStreamPromises = new Map<number, Promise<PageBotStreamResult>>();\n /** 「应用到页面」pending intent (also mirrored to sessionStorage). */\n private pendingPageActionApply: PendingPageActionApply | null = null;\n /** Built-in reuse popover (registered by ChatRoot). */\n private pageActionReusePromptHandler: PageActionReusePromptHandler | null = null;\n /**\n * Bumped when the user dismisses a docked reuse apply (`撤销`).\n * `applyPageActionReuse` skips post-await row locks when the epoch changed.\n */\n private pageActionReuseDismissEpochByRowKey = new Map<string, number>();\n /** Per-entity reuse-hint cache — avoid re-query on popover close + re-click. */\n private pageActionReuseHintCache = new PageActionReuseHintCache();\n /** Last invoke snapshots for Brain clarify re-invoke (keyed by rowKey / runId). */\n private pageActionInvokeSnapshotsByRowKey = new Map<\n string,\n PageActionBrainClarifyInvokeSnapshot & { launchAnchor?: HTMLElement | null }\n >();\n private pageActionInvokeSnapshotsByRunId = new Map<\n number,\n PageActionBrainClarifyInvokeSnapshot & { launchAnchor?: HTMLElement | null }\n >();\n /** Last `GET /page-action/catalog` (global feedback list). */\n private pageActionFeedbackCatalogItems: PageActionFeedbackCatalogItem[] = [];\n /** Display names for optimistic task-center titles. */\n private pageActionFeedbackNames = new Map<string, string>();\n /** In-memory active PageAction runs for badge + optimistic task center updates. */\n private automationRunRegistry = new Map<number, TrackedAutomationRun>();\n /** Per-row PageAction UI slots keyed by host rowKey (list pages). */\n private pageActionRows = new Map<string, PageActionRowState>();\n /** Maps runId → rowKey for lifecycle / hydrate updates. */\n private pageActionRunToRowKey = new Map<number, string>();\n /** Last `GET /automation/tasks` reconcile timestamp (visibility fallback). */\n private automationTasksLastSyncedAt = 0;\n /** Host calls before `init()` completes — applied when state is created. */\n private pendingRouteContextOverride: AgentChatRouteContext | null | undefined;\n private pendingPageContext: AgentChatPageContext | null | undefined;\n private pendingAttachPageContext: boolean | undefined;\n private pendingContextMentionRegistry = new Map<string, ContextMentionRegistration>();\n\n private initGate: LoginGate;\n private loginGate: LoginGate;\n private pageActionCoordinator: PageActionCoordinator;\n\n constructor(id: string = nanoId('inst')) {\n this.id = id;\n this.pageActionCoordinator = new PageActionCoordinator({\n ensureLoggedIn: () => this.ensureLoggedIn('pageActionSlotSync'),\n reconcileActivePageActions: (opts) => this.reconcileActivePageActions(opts),\n resumeActivePageActionStreams: (opts) => this.resumeActivePageActionStreams(opts),\n replayPageAction: (runId) => this.replayPageAction(runId),\n getPendingPageActionApply: () => this.getPendingPageActionApply(),\n onApplyPhaseChanged: (slotKey, phase) => {\n this.bus.emit('pageActionSlotApplyPhaseChanged', { slotKey, phase });\n },\n });\n const notifyPending = () => this.notifyStateChange();\n this.initGate = new LoginGate(\n () => this.state != null && this.lifecycle === 'initialized',\n 'init',\n notifyPending,\n );\n this.loginGate = new LoginGate(\n () => Boolean(this.state?.isLoggedIn),\n 'login',\n notifyPending,\n );\n }\n\n // ------------------------------------------------------------------ public\n\n /**\n * Merge React prop / option changes without a full re-init (same DSN).\n * Keeps `pageContext` / `attachPageContext` in sync when StrictMode or\n * `<AgentChat>` re-runs `init()` on an already-initialized client.\n */\n applyRuntimeOptions(\n options: Pick<AgentChatOptions, 'attachPageContext' | 'pageContext'>,\n ): void {\n const state = this.state;\n if (!state) {\n if (options.attachPageContext !== undefined) {\n this.pendingAttachPageContext = options.attachPageContext === true;\n }\n if (options.pageContext !== undefined) {\n this.pendingPageContext = options.pageContext;\n }\n this.notifyStateChange();\n return;\n }\n\n let changed = false;\n if (options.attachPageContext !== undefined) {\n const attach = options.attachPageContext === true;\n if (state.attachPageContext !== attach) {\n state.attachPageContext = attach;\n changed = true;\n }\n }\n if (options.pageContext !== undefined) {\n state.pageContext = options.pageContext;\n state.options = { ...state.options, pageContext: options.pageContext ?? undefined };\n changed = true;\n this.schedulePrepareSession();\n }\n if (changed) {\n this.notifyStateChange();\n }\n }\n\n async init(options: AgentChatOptions): Promise<this> {\n ensureExtensionAuthResyncListener();\n\n if (this.state) {\n if (this.state.options.dsn === options.dsn) {\n if (typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(\n '[agent-chat] init() called twice with the same DSN — keeping existing instance state.',\n );\n }\n this.applyRuntimeOptions({\n attachPageContext: options.attachPageContext,\n pageContext: options.pageContext,\n });\n return this;\n }\n throw new AgentChatError(\n 'ALREADY_INITIALIZED',\n 'AgentChat is already initialized with a different DSN. Call destroy() first.',\n );\n }\n\n if (!options || typeof options !== 'object') {\n throw new AgentChatError('INVALID_OPTIONS', 'init(options): options object is required');\n }\n\n // `baseUrl` is the single root for every SDK request.\n const apiBaseUrl = trimRight(\n (options.baseUrl?.trim() || DEFAULT_BASE_URL).replace(/\\s+/g, ''),\n );\n\n const dsn = normalizeDsn(options.dsn);\n await waitForAuthStoreRehydration();\n const storedAccountToken = useAuthStore.getState().getAccessTokenForDsn(dsn);\n const accountToken =\n (typeof options.accountToken === 'string' && options.accountToken.trim()) ||\n (typeof options.userAccessToken === 'string' && options.userAccessToken.trim()) ||\n storedAccountToken ||\n null;\n\n const http = createHttpClient({\n apiBase: apiBaseUrl,\n defaultHeaders: {\n [DSN_AUTH_HEADER]: dsn,\n 'X-Agent-Sdk-Version': SDK_VERSION,\n ...(options.headers ?? {}),\n },\n });\n const auth = new AuthService(http);\n const chat = new ChatService(http);\n const feedback = new FeedbackService(http);\n const hostTool = new HostToolService(http);\n const agentRun = new AgentRunService(http);\n const pageAction = new PageActionService(http);\n const approval = new ApprovalService(http);\n const automation = new AutomationService(http);\n const appTool = new AppToolService(http);\n\n let authData: AppClientAuthData | null = null;\n let clientAuthenticated = false;\n let resolvedUserJwt: string | null = null;\n let initAuthError: AgentChatErrorPayload | null = null;\n\n try {\n authData = await auth.authenticate(dsn, accountToken);\n clientAuthenticated = true;\n resolvedUserJwt = authData.accessToken?.trim() ?? null;\n useAuthStore.getState().setAuth(dsn, authData);\n if (resolvedUserJwt) {\n applyAccessTokenHeader(http, resolvedUserJwt);\n }\n } catch (err) {\n initAuthError = toAgentChatErrorPayload(err);\n if (options.debug) {\n console.warn('[agent-chat] app-client auth failed during init:', initAuthError);\n }\n }\n\n const agent = new AgentService(http, () => ({\n dsn: this.state?.dsn ?? dsn,\n }));\n\n const sdkVersion = SDK_VERSION;\n\n const session = new SessionManager({\n context: {\n sdkVersion,\n origin: browserOrigin(),\n locale: options.locale ?? defaultLocale(),\n user: options.user ?? authUserToContext(authData?.user),\n },\n });\n\n this.state = {\n options,\n dsn,\n apiBaseUrl,\n http,\n auth,\n chat,\n agent,\n feedback,\n hostTool,\n agentRun,\n pageAction,\n approval,\n automation,\n appTool,\n session,\n abortControllers: new Set(),\n isOpen: false,\n isClientAuthenticated: clientAuthenticated,\n isLoggedIn: Boolean(resolvedUserJwt) || isSdkAuthenticatedForDsn(dsn),\n catalogHydrated: false,\n sessions: [],\n sessionsPage: 0,\n sessionsPageSize: DEFAULT_SESSION_PAGE_SIZE,\n sessionsHasMore: false,\n sessionsLoadingMore: false,\n activeSessionId: null,\n activeSessionMessagesPage: 0,\n activeSessionMessagesHasMore: false,\n sessionMessagesLoadingMore: false,\n sessionMessagesPageSize: DEFAULT_MESSAGE_PAGE_SIZE,\n sessionMessagesCache: new Map(),\n agents: options.agents ? [...options.agents] : [],\n skills: [],\n selectedAgentId: options.defaultAgentId?.trim() ?? null,\n autoAgent: null,\n selectedSkillId: options.defaultSkillId?.trim() ?? null,\n agentsLoading: false,\n skillsLoading: false,\n agentsEmptyReason: null,\n userJwt: resolvedUserJwt ?? getSdkAccessTokenForDsn(dsn),\n sessionStreams: new Map(),\n sessionRuns: new Map(),\n messages: [],\n lastError: initAuthError,\n writeConfirmation: null,\n writeConfirmationsBySession: new Map(),\n approvalInboxLoading: false,\n approvalInboxLoadingMore: false,\n approvalInboxHasMore: false,\n approvalInboxStatusFilter: 'pending',\n approvalInboxPendingCount: 0,\n approvalInboxItems: [],\n automationTaskLoading: false,\n automationTaskLoadingMore: false,\n automationTaskHasMore: false,\n automationTaskTotal: 0,\n automationTaskStatusFilter: 'active',\n automationTaskActiveCount: 0,\n automationTaskItems: [],\n automationTaskTabCaches: createAutomationTaskTabCaches(),\n automationRecentRunIds: [],\n automationTaskSelectedDetail: null,\n automationTaskDetailLoading: false,\n skillIntentBanner: null,\n skillIntentClarify: null,\n brainClarify: null,\n skillTurnContract: null,\n skillTurnActive: null,\n lastTurnUserMessage: null,\n skillPickerOpen: false,\n downReasonTagsCache: null,\n pageContext: options.pageContext ?? null,\n routeContextOverride: null,\n routeContext: null,\n attachPageContext: options.attachPageContext === true,\n appClientId: authData?.appClient?.id ?? null,\n contextMentionRegistry: new Map(),\n };\n this.lifecycle = 'initialized';\n this.stateSnapshot = null;\n this.initGate.reconcile();\n\n this.authStoreUnsub = useAuthStore.subscribe(() => {\n this.syncAuthFromStore();\n });\n this.syncAuthFromStore();\n\n this.applyPendingRuntimeConfig(this.state);\n this.syncRouteContextFromWindow();\n\n this.applyStaticSkills(this.state);\n this.syncDefaultAgentSelection(this.state);\n\n if (options.onReady) {\n this.bus.on('ready', options.onReady);\n }\n\n queueMicrotask(() => this.bus.emit('ready', undefined));\n\n if (this.isHostToolServerSyncReady()) {\n void flushPendingHostToolSyncs(this).catch((err) => {\n if (options.debug) {\n console.warn('[agent-chat] flushPendingHostToolSyncs failed:', err);\n }\n });\n }\n\n if (options.autoOpen) {\n this.open();\n }\n\n this.refreshApprovalBadgeBestEffort();\n this.notifyPageActionAuthReady();\n this.scheduleAutomationTasksBestEffort();\n\n return this;\n }\n\n async login(credentials: AgentChatLoginCredentials): Promise<void> {\n await this.ensureInitialized('login');\n const state = this.requireState('login');\n const email = credentials?.email?.trim();\n const password = credentials?.password?.trim();\n if (!email || !password) {\n throw new AgentChatError('INVALID_OPTIONS', 'login requires email and password');\n }\n\n let loginAuth: AppClientAuthData;\n try {\n loginAuth = await state.auth.login(email, password);\n } catch (err) {\n if (err instanceof AgentChatError && err.code === 'TRANSPORT_FAILED') {\n throw new AgentChatError('LOGIN_FAILED', err.message, { cause: err, details: err.details });\n }\n throw err;\n }\n\n const accountToken = loginAuth.accessToken?.trim();\n if (!accountToken) {\n throw new AgentChatError('LOGIN_FAILED', 'Login succeeded but no access token was returned.');\n }\n\n clearAccessTokenHeader(state.http);\n const authData = await state.auth.authenticate(state.dsn, accountToken);\n this.commitAuthSession(authData);\n\n void flushPendingHostToolSyncs(this).catch((err) => {\n if (state.options.debug) {\n console.warn('[agent-chat] flushPendingHostToolSyncs failed:', err);\n }\n });\n if (state.isOpen) {\n void this.refreshAgentCatalog().catch(() => {\n /* catalog is optional */\n });\n }\n this.refreshApprovalBadgeBestEffort();\n this.scheduleAutomationTasksBestEffort();\n }\n\n logout(): void {\n const state = this.state;\n if (!state) return;\n this.abortAllSessionStreams(state);\n this.cancelAllSessionStreamReconnects();\n state.isLoggedIn = false;\n clearAccessTokenHeader(state.http);\n useAuthStore.getState().clearAuth();\n state.session.reset();\n state.sessions = [];\n state.sessionsPage = 0;\n state.sessionsHasMore = false;\n state.sessionsLoadingMore = false;\n state.activeSessionId = null;\n state.activeSessionMessagesPage = 0;\n state.activeSessionMessagesHasMore = false;\n state.sessionMessagesLoadingMore = false;\n state.sessionMessagesCache.clear();\n state.agents = [];\n state.skills = [];\n state.selectedAgentId = null;\n state.autoAgent = null;\n state.selectedSkillId = null;\n state.agentsLoading = false;\n state.skillsLoading = false;\n state.agentsEmptyReason = null;\n state.userJwt = null;\n state.messages = [];\n state.sessionStreams.clear();\n state.sessionRuns.clear();\n state.writeConfirmationsBySession.clear();\n state.approvalInboxItems = [];\n state.approvalInboxLoading = false;\n state.approvalInboxLoadingMore = false;\n state.approvalInboxHasMore = false;\n state.approvalInboxStatusFilter = 'pending';\n state.approvalInboxPendingCount = 0;\n state.automationTaskItems = [];\n state.automationTaskLoading = false;\n state.automationTaskLoadingMore = false;\n state.automationTaskHasMore = false;\n state.automationTaskTotal = 0;\n state.automationTaskStatusFilter = 'active';\n state.automationTaskTabCaches = createAutomationTaskTabCaches();\n state.automationTaskActiveCount = 0;\n state.automationRecentRunIds = [];\n state.automationTaskSelectedDetail = null;\n state.automationTaskDetailLoading = false;\n this.abortAllPageActionRunStreams();\n this.pageActionInFlightKeys.clear();\n this.pageActionAwaitingApprovalNotified.clear();\n this.clearAutomationRunRegistry();\n state.catalogHydrated = false;\n this.pendingStreamTargets.clear();\n this.sessionStreamConnects.clear();\n this.hostToolStreamManagers.clear();\n this.notifyStateChange();\n }\n\n isLoggedIn(): boolean {\n this.syncAuthFromStore();\n return this.state?.isLoggedIn ?? false;\n }\n\n /** 当前因 init / login 门禁而挂起的任务快照(调试 / UI 用) */\n getPendingGateJobs(): PendingGateJob[] {\n return [...this.initGate.getPendingJobs(), ...this.loginGate.getPendingJobs()];\n }\n\n private snapshotPendingGateJobs(): PendingGateJob[] {\n return this.getPendingGateJobs();\n }\n\n /** 将 persist auth store 与 instance HTTP 头对齐(SSOT:useAuthStore) */\n syncAuthFromStore(): void {\n const state = this.state;\n if (!state) {\n return;\n }\n const token = useAuthStore.getState().getAccessTokenForDsn(state.dsn);\n const shouldBeLoggedIn = Boolean(token?.trim());\n if (shouldBeLoggedIn) {\n if (state.userJwt !== token || !state.isLoggedIn) {\n state.userJwt = token;\n state.isLoggedIn = true;\n applyAccessTokenHeader(state.http, token!);\n this.notifyStateChange();\n this.loginGate.reconcile();\n this.notifyPageActionAuthReady();\n }\n return;\n }\n if (state.isLoggedIn || state.userJwt) {\n state.userJwt = null;\n state.isLoggedIn = false;\n clearAccessTokenHeader(state.http);\n this.notifyStateChange();\n }\n }\n\n /**\n * 登录 / 认证完成后的唯一提交点:写 store、对齐 instance、唤醒 login 门禁。\n * login() 在 authenticate 成功前不写 store,避免中途误触发 reconcile。\n */\n private commitAuthSession(authData: AppClientAuthData): void {\n const state = this.requireState('commitAuthSession');\n const userJwt = authData.accessToken?.trim();\n if (!userJwt) {\n throw new AgentChatError('LOGIN_FAILED', 'App client auth succeeded but accessToken is missing');\n }\n\n useAuthStore.getState().setAuth(state.dsn, authData);\n applyAccessTokenHeader(state.http, userJwt);\n state.userJwt = userJwt;\n state.isLoggedIn = true;\n state.isClientAuthenticated = true;\n state.appClientId = authData.appClient?.id ?? state.appClientId;\n this.notifyStateChange();\n this.loginGate.reconcile();\n this.notifyPageActionAuthReady();\n }\n\n private notifyPageActionAuthReady(): void {\n if (!this.state?.isLoggedIn) return;\n this.pageActionCoordinator.onAuthReady();\n }\n\n bindPageActionSlot(\n binding: {\n actionKey: string;\n rowKey: string;\n pageContext?: AgentChatPageContext | null;\n ready?: boolean;\n autoResume?: boolean;\n autoApplyPending?: boolean;\n },\n ): () => void {\n const normalized: PageActionSlotBinding = {\n actionKey: binding.actionKey.trim(),\n rowKey: binding.rowKey.trim(),\n pageContext: binding.pageContext ?? null,\n ready: binding.ready !== false,\n autoResume: binding.autoResume !== false,\n autoApplyPending: binding.autoApplyPending !== false,\n };\n return this.pageActionCoordinator.bind(normalized);\n }\n\n patchPageActionSlot(\n slotKey: string,\n patch: {\n pageContext?: AgentChatPageContext | null;\n ready?: boolean;\n autoResume?: boolean;\n autoApplyPending?: boolean;\n },\n ): void {\n this.pageActionCoordinator.patch(slotKey, patch);\n }\n\n /** @internal demo / integration — registered PageAction slots */\n listBoundPageActionSlots(): PageActionSlotBinding[] {\n return this.pageActionCoordinator.listBindings();\n }\n\n destroy(): void {\n this.pendingRouteContextOverride = undefined;\n this.pendingPageContext = undefined;\n this.pendingAttachPageContext = undefined;\n this.pendingContextMentionRegistry = new Map();\n this.pageActionReuseHintCache.clear();\n this.initGate.cancelAll();\n this.loginGate.cancelAll();\n if (!this.state) return;\n\n this.authStoreUnsub?.();\n this.authStoreUnsub = undefined;\n\n this.cancelScheduledPrepare();\n this.abortAllSessionStreams(this.state);\n this.cancelAllSessionStreamReconnects();\n this.pendingStreamTargets.clear();\n this.sessionStreamConnects.clear();\n this.hostToolStreamManagers.clear();\n this.pageActionInFlightKeys.clear();\n this.pageActionAwaitingApprovalNotified.clear();\n this.abortAllPageActionRunStreams();\n this.clearAutomationRunRegistry();\n this.pendingPageActionApply = null;\n\n for (const ctrl of this.state.abortControllers) {\n try {\n ctrl.abort();\n } catch {\n /* noop */\n }\n }\n this.state.abortControllers.clear();\n\n this.state.session.reset();\n this.state.isOpen = false;\n this.state = null;\n this.lifecycle = 'destroyed';\n this.stateSnapshot = null;\n\n this.bus.emit('destroyed', undefined);\n this.bus.clear();\n this.stateChangeListeners.clear();\n }\n\n open(): void {\n // Graceful when called against a destroyed/uninitialized client. This\n // happens in dev when a stale launcher (e.g. left behind by an HMR or\n // StrictMode race) is clicked after destroy() has run — we don't want\n // those clicks to crash the host page.\n const state = this.state;\n if (!state) {\n if (typeof console !== 'undefined') {\n console.warn(\n '[agent-chat] open() called before init() (or after destroy()) — ignoring.',\n );\n }\n return;\n }\n if (state.isOpen) return;\n state.isOpen = true;\n this.notifyStateChange();\n this.bus.emit('open', undefined);\n }\n\n close(): void {\n const state = this.state;\n if (!state || !state.isOpen) return;\n state.isOpen = false;\n this.notifyStateChange();\n this.bus.emit('close', undefined);\n }\n\n toggle(): void {\n if (this.isOpen()) this.close();\n else this.open();\n }\n\n openApprovalInbox(opts?: OpenApprovalInboxPayload): void {\n this.bus.emit('openApprovalInbox', opts);\n }\n\n openAutomationTaskCenter(opts?: OpenAutomationTaskCenterPayload): void {\n this.bus.emit('openAutomationTaskCenter', opts);\n }\n\n openPageActionFeedback(opts?: OpenPageActionFeedbackPayload): void {\n this.bus.emit('openPageActionFeedback', opts);\n }\n\n /**\n * @deprecated Rating list is `GET /page-action/catalog`.\n * Optional name overlay for optimistic task-center titles only.\n */\n registerPageActionFeedbackCatalog(\n items: Array<{ actionKey: string; name?: string | null }>,\n ): void {\n for (const item of items) {\n const actionKey = item.actionKey?.trim();\n const name = item.name?.trim();\n if (!actionKey || !name || name === actionKey) continue;\n this.pageActionFeedbackNames.set(actionKey, name);\n }\n }\n\n /**\n * `GET /page-action/catalog`. Global「我的反馈」omits `pageScope`.\n */\n async fetchPageActionFeedbackCatalog(\n query: PageActionFeedbackCatalogQuery = {},\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackCatalogItem[]> {\n await this.ensureInitialized('fetchPageActionFeedbackCatalog', {\n signal: opts?.signal,\n });\n await this.ensureLoggedIn('fetchPageActionFeedbackCatalog', {\n signal: opts?.signal,\n });\n const state = this.requireState('fetchPageActionFeedbackCatalog');\n const items = await state.pageAction.listCatalog(query, opts?.signal);\n this.pageActionFeedbackCatalogItems = items;\n for (const item of items) {\n this.pageActionFeedbackNames.set(item.actionKey, item.name);\n }\n return items;\n }\n\n listPageActionFeedbackCatalog(): PageActionFeedbackCatalogItem[] {\n return this.pageActionFeedbackCatalogItems.slice();\n }\n\n async getPageActionFeedback(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackView | null> {\n await this.ensureInitialized('getPageActionFeedback', { signal: opts?.signal });\n await this.ensureLoggedIn('getPageActionFeedback', { signal: opts?.signal });\n const state = this.requireState('getPageActionFeedback');\n return state.pageAction.getMyFeedback(actionKey, opts?.signal);\n }\n\n async upsertPageActionFeedback(\n actionKey: string,\n body: UpsertPageActionFeedbackInput,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackView> {\n await this.ensureInitialized('upsertPageActionFeedback', { signal: opts?.signal });\n await this.ensureLoggedIn('upsertPageActionFeedback', { signal: opts?.signal });\n const state = this.requireState('upsertPageActionFeedback');\n const result = await state.pageAction.upsertFeedback(actionKey, body, opts?.signal);\n if (result.pageActionName) {\n this.pageActionFeedbackNames.set(result.actionKey, result.pageActionName);\n }\n return result;\n }\n\n async removePageActionFeedback(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<void> {\n await this.ensureInitialized('removePageActionFeedback', { signal: opts?.signal });\n await this.ensureLoggedIn('removePageActionFeedback', { signal: opts?.signal });\n const state = this.requireState('removePageActionFeedback');\n await state.pageAction.removeMyFeedback(actionKey, opts?.signal);\n }\n\n async getPageActionFeedbackSummary(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackSummary> {\n await this.ensureInitialized('getPageActionFeedbackSummary', {\n signal: opts?.signal,\n });\n await this.ensureLoggedIn('getPageActionFeedbackSummary', { signal: opts?.signal });\n const state = this.requireState('getPageActionFeedbackSummary');\n const summary = await state.pageAction.getFeedbackSummary(actionKey, opts?.signal);\n if (summary.pageActionName) {\n this.pageActionFeedbackNames.set(summary.actionKey, summary.pageActionName);\n }\n return summary;\n }\n\n async createPageActionWish(\n body: CreatePageActionWishInput,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView> {\n await this.ensureInitialized('createPageActionWish', { signal: opts?.signal });\n await this.ensureLoggedIn('createPageActionWish', { signal: opts?.signal });\n const state = this.requireState('createPageActionWish');\n return state.pageAction.createWish(body, opts?.signal);\n }\n\n async listPageActionWishes(\n query?: PageActionWishQuery,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishList> {\n await this.ensureInitialized('listPageActionWishes', { signal: opts?.signal });\n await this.ensureLoggedIn('listPageActionWishes', { signal: opts?.signal });\n const state = this.requireState('listPageActionWishes');\n return state.pageAction.listWishes(query ?? {}, opts?.signal);\n }\n\n async getPageActionWish(\n id: number,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView> {\n await this.ensureInitialized('getPageActionWish', { signal: opts?.signal });\n await this.ensureLoggedIn('getPageActionWish', { signal: opts?.signal });\n const state = this.requireState('getPageActionWish');\n return state.pageAction.getWish(id, opts?.signal);\n }\n\n async cancelPageActionWish(\n id: number,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView> {\n await this.ensureInitialized('cancelPageActionWish', { signal: opts?.signal });\n await this.ensureLoggedIn('cancelPageActionWish', { signal: opts?.signal });\n const state = this.requireState('cancelPageActionWish');\n return state.pageAction.cancelWish(id, opts?.signal);\n }\n\n isOpen(): boolean {\n return this.state?.isOpen ?? false;\n }\n\n identify(user: UserContext): void {\n const state = this.requireState('identify');\n const previous = state.session.getSession();\n state.session.updateContext({ user });\n\n const previousUserId = state.options.user?.id;\n state.options = { ...state.options, user };\n\n if (previous && previousUserId && previousUserId !== user.id) {\n this.abortAllSessionStreams(state);\n this.sessionStreamConnects.clear();\n this.pendingStreamTargets.clear();\n state.session.reset();\n state.sessions = [];\n state.sessionMessagesCache.clear();\n state.sessionRuns.clear();\n state.writeConfirmationsBySession.clear();\n state.writeConfirmation = null;\n state.activeSessionId = null;\n state.messages = [];\n this.notifyStateChange();\n }\n }\n\n setPageContext(pageContext: AgentChatPageContext | null): void {\n if (!this.state) {\n this.pendingPageContext = pageContext;\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n const prevPage = this.getPageScope(state);\n state.pageContext = pageContext;\n state.options = { ...state.options, pageContext: pageContext ?? undefined };\n const nextPage = this.getPageScope(state);\n this.notifyStateChange();\n this.schedulePrepareSession();\n\n if (prevPage !== nextPage && !state.options.skills?.length) {\n state.selectedSkillId = null;\n void this.refreshSkills(state.selectedAgentId ?? undefined);\n }\n }\n\n setRouteContext(routeContext: AgentChatRouteContext | null): void {\n if (!this.state) {\n this.pendingRouteContextOverride = routeContext;\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n state.routeContextOverride = routeContext;\n this.syncRouteContextFromWindow();\n }\n\n registerContextMentions(\n items: Array<ContextMentionRegistration | ContextMentionDefinition>,\n options: RegisterContextMentionsOptions = {},\n ): void {\n const normalized = items.map(normalizeContextMentionInput);\n if (!this.state) {\n this.pendingContextMentionRegistry = mergeContextMentionRegistrations(\n this.pendingContextMentionRegistry,\n normalized,\n options.replace === true,\n );\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n state.contextMentionRegistry = mergeContextMentionRegistrations(\n state.contextMentionRegistry,\n normalized,\n options.replace === true,\n );\n this.notifyStateChange();\n }\n\n unregisterContextMentions(ids: string[]): void {\n if (!this.state) {\n let changed = false;\n for (const raw of ids) {\n const id = raw.trim();\n if (!id) continue;\n if (this.pendingContextMentionRegistry.delete(id)) changed = true;\n }\n if (changed) this.notifyStateChange();\n return;\n }\n const state = this.state;\n let changed = false;\n for (const raw of ids) {\n const id = raw.trim();\n if (!id) continue;\n if (state.contextMentionRegistry.delete(id)) changed = true;\n }\n if (changed) this.notifyStateChange();\n }\n\n clearContextMentions(): void {\n if (!this.state) {\n if (this.pendingContextMentionRegistry.size === 0) return;\n this.pendingContextMentionRegistry = new Map();\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n if (state.contextMentionRegistry.size === 0) return;\n state.contextMentionRegistry = new Map();\n this.notifyStateChange();\n }\n\n syncRouteContextFromWindow(): void {\n if (!this.state) return;\n const state = this.state;\n const merged = mergeRouteContext(\n readWindowRouteContext(),\n state.routeContextOverride,\n );\n const prev = JSON.stringify(state.routeContext ?? null);\n const next = JSON.stringify(\n Object.keys(merged).length > 0 ? merged : null,\n );\n state.routeContext = Object.keys(merged).length > 0 ? merged : null;\n if (prev !== next) {\n this.notifyStateChange();\n this.schedulePrepareSession();\n }\n }\n\n setAttachPageContext(attach: boolean): void {\n if (!this.state) {\n this.pendingAttachPageContext = attach;\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n if (state.attachPageContext === attach) return;\n state.attachPageContext = attach;\n state.options = { ...state.options, attachPageContext: attach };\n this.notifyStateChange();\n }\n\n getPageContext(): AgentChatPageContext | null {\n const state = this.state;\n if (!state) return null;\n return state.pageContext ?? state.options.pageContext ?? null;\n }\n\n getAppClientId(): number | null {\n const fromStore = useAuthStore.getState().appClient?.id;\n if (fromStore != null) return fromStore;\n return this.state?.appClientId ?? null;\n }\n\n /**\n * Whether host-tool metadata can be synced to the server\n * (`POST /host-tool/client/register` requires Bearer + app client).\n */\n isHostToolServerSyncReady(): boolean {\n const state = this.state;\n if (!state?.isClientAuthenticated) return false;\n if (!state.isLoggedIn || !state.userJwt?.trim()) return false;\n return this.getAppClientId() != null;\n }\n\n registerHostTool(scope: string, name: string, handler: HostToolHandler): void {\n registerHostTool(scope, name, handler);\n }\n\n unregisterHostTool(scope: string, name: string): void {\n unregisterHostTool(scope, name);\n }\n\n undeclareHostTool(scope: string, name: string): void {\n undeclareHostTool(scope, name);\n }\n\n runHostTool(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n ): Promise<boolean> {\n return runHostTool(scope, name, args);\n }\n\n registerHostToolsWithSync(options: RegisterHostToolsOptions): Promise<void> {\n return registerHostToolsWithSync(this, options);\n }\n\n async syncHostToolsToServer(\n body: Parameters<HostToolService['register']>[0],\n ): Promise<import('../services/host-tool.service').HostToolRegisterResult> {\n await this.ensureLoggedIn('syncHostToolsToServer');\n const state = this.requireState('syncHostToolsToServer');\n if (!state.isClientAuthenticated || state.appClientId == null) {\n throw new AgentChatError(\n 'AUTH_REQUIRED',\n 'Host tool server sync requires app client authentication.',\n );\n }\n return state.hostTool.register(body);\n }\n\n getHostToolCatalog(query?: { scope?: string; agentId?: number }): Promise<unknown> {\n const state = this.requireState('getHostToolCatalog');\n return state.hostTool.getCatalog(query);\n }\n\n /**\n * `GET /app/tools/callable` — 当前用户可代调的 Integration Tool(须登录)。\n * 用返回的 `definitionKey` 调 {@link invokeAppTool},勿硬编码 `toolId`。\n */\n async listCallableTools(signal?: AbortSignal): Promise<AppToolCallableList> {\n await this.ensureLoggedIn('listCallableTools', { signal });\n const state = this.requireState('listCallableTools');\n return state.appTool.listCallable(signal);\n }\n\n /**\n * `POST /app/tools/invoke` — 按 `definitionKey` 代调 Tool。\n * 未登录时自动挂起,登录后继续执行(默认等待 5 分钟,超时抛 `PENDING_TIMEOUT`)。\n * 下游非 2xx 时返回 `{ ok: false, httpStatus, error }`;网关门禁失败抛 `AgentChatError`\n *(`details.serverCode` 如 `INTEGRATION_USER_TOKEN_REQUIRED`)。\n */\n async invokeAppTool(input: AppToolInvokeInput): Promise<AppToolInvokeResult> {\n await this.ensureLoggedIn('invokeAppTool', { signal: input.signal });\n const state = this.requireState('invokeAppTool');\n return state.appTool.invoke(input);\n }\n\n isPageActionKeyActive(pageActionKey: string | null | undefined): boolean {\n const key = pageActionKey?.trim();\n if (!key) return false;\n return collectActivePageActionKeys(this.automationRunRegistry).has(key);\n }\n\n getActivePageActionKeyForActionKey(actionKey: string): string | null {\n return findActivePageActionKeyForActionKey(this.automationRunRegistry, actionKey);\n }\n\n getPageActionRowState(rowKey: string): PageActionRowState | null {\n const key = rowKey.trim();\n if (!key) return null;\n return this.pageActionRows.get(key) ?? null;\n }\n\n getPageActionRowsForActionKey(actionKey: string): PageActionRowState[] {\n const key = actionKey.trim();\n if (!key) return [];\n return [...this.pageActionRows.values()].filter((row) => row.actionKey === key);\n }\n\n isPageActionRowActive(rowKey: string): boolean {\n const row = this.getPageActionRowState(rowKey);\n if (!row) return false;\n // Reuse picker (`awaiting_reuse`) is interruptible — never soft-lock re-clicks.\n if (row.phase === 'awaiting_reuse') return false;\n // Stale soft-lock: idle/loading with no run (legacy reuse path). Allow re-invoke.\n if (row.loading && row.phase === 'idle' && row.runId == null && !row.awaitingApproval) {\n return false;\n }\n return row.loading || row.awaitingApproval;\n }\n\n /** Clear soft error / tip text on a row slot without changing phase. */\n clearPageActionRowError(rowKey: string): void {\n const key = rowKey.trim();\n const current = this.pageActionRows.get(key);\n if (!current?.error && !current?.message) return;\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...current,\n error: null,\n message: null,\n }),\n );\n }\n\n async hydratePageActionByRunId(\n runId: number,\n opts: { rowKey?: string; actionKey?: string; signal?: AbortSignal } = {},\n ): Promise<PageActionRowState | null> {\n await this.ensureLoggedIn('hydratePageActionByRunId');\n this.requireState('hydratePageActionByRunId');\n if (!Number.isFinite(runId)) return null;\n const id = Math.trunc(runId);\n const detail = await this.getAutomationTaskDetail(id, opts.signal);\n if (!detail) return null;\n\n const mappedRowKey = resolveRestoredPageActionRowKey(id, {\n rowKey: opts.rowKey,\n entityId: detail.pageContext?.entity?.id ?? null,\n findRowKeyByRunId: () =>\n this.findRowKeyByRunId(id) || this.findRowKeyByPageActionKey(detail.pageActionKey),\n });\n const actionKey =\n opts.actionKey?.trim() ||\n detail.actionKey?.trim() ||\n this.automationRunRegistry.get(id)?.actionKey ||\n detail.title;\n\n const isBrainClarify =\n detail.taskStatus === 'failed' &&\n isBrainAskUserErrorCode(detail.errorCode) &&\n detail.brainClarify != null;\n const phase: PageActionPhase = isBrainClarify\n ? 'awaiting_clarify'\n : taskStatusToPageActionPhase(detail.taskStatus);\n const flags = derivePageActionRowFlags(phase);\n const prevRow = this.pageActionRows.get(mappedRowKey);\n const progressLabel = flags.loading\n ? (prevRow?.progressLabel ??\n defaultPageActionProgressLabel(this.state?.options.locale))\n : phase === 'awaiting_clarify'\n ? pageActionAwaitingClarifyLabel(this.state?.options.locale)\n : phase === 'awaiting_approval'\n ? resolvePageWorkflowProgressLabel(\n {\n phase: 'awaiting_approval',\n actionRunId: id,\n actionKey,\n generation: id,\n nodeId: '',\n stageKind: 'other',\n },\n this.state?.options.locale,\n )\n : null;\n const row = buildPageActionRowState({\n rowKey: mappedRowKey,\n actionKey,\n runId: id,\n pageActionKey: detail.pageActionKey,\n phase,\n error: isBrainClarify ? null : detail.errorMessage,\n message: prevRow?.message ?? null,\n progressLabel,\n narrativeItems: prevRow?.narrativeItems ?? [],\n approvalRequestId: detail.approval?.id ?? null,\n brainClarify: isBrainClarify ? detail.brainClarify : null,\n });\n this.upsertPageActionRow(row);\n this.bindPageActionRunToRow(id, mappedRowKey);\n const tracked = this.automationRunRegistry.get(id);\n if (tracked) {\n tracked.rowKey = mappedRowKey;\n tracked.actionKey = actionKey;\n tracked.pageActionKey = detail.pageActionKey;\n tracked.status = detail.taskStatus;\n tracked.updatedAt = new Date().toISOString();\n if (!isActiveAutomationTaskStatus(detail.taskStatus)) {\n this.automationRunRegistry.delete(id);\n }\n } else if (isActiveAutomationTaskStatus(detail.taskStatus)) {\n this.automationRunRegistry.set(id, {\n runId: id,\n actionKey,\n pageActionKey: detail.pageActionKey,\n rowKey: mappedRowKey,\n status: detail.taskStatus,\n registeredAt: detail.createdAt ?? new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n clientActionId: null,\n });\n }\n if (isBrainClarify && detail.brainClarify) {\n const snap = this.pageActionInvokeSnapshotsByRunId.get(id) ?? {\n pageContext: detail.pageContext ?? undefined,\n rowKey: mappedRowKey,\n awaitStream: false,\n };\n if (!this.pageActionInvokeSnapshotsByRunId.has(id)) {\n this.pageActionInvokeSnapshotsByRunId.set(id, {\n ...snap,\n launchAnchor: snap.launchAnchor ?? null,\n });\n this.pageActionInvokeSnapshotsByRowKey.set(mappedRowKey, {\n ...snap,\n launchAnchor: snap.launchAnchor ?? null,\n });\n }\n this.emitPageActionBrainClarifyFromPayload({\n actionKey,\n runId: id,\n brainClarify: detail.brainClarify,\n rowKey: mappedRowKey,\n });\n } else if (phase === 'completed' || phase === 'failed') {\n this.schedulePageActionRowIdleReset(\n mappedRowKey,\n phase === 'failed' ? 1_600 : 900,\n );\n }\n return row;\n }\n\n async reconcileActivePageActions(\n opts: { actionKey?: string; signal?: AbortSignal } = {},\n ): Promise<PageActionRowState[]> {\n await this.ensureLoggedIn('reconcileActivePageActions');\n this.requireState('reconcileActivePageActions');\n const actionKey = opts.actionKey?.trim();\n await this.refreshAutomationTasks({\n status: 'active',\n actionKey: actionKey || undefined,\n offset: 0,\n signal: opts.signal,\n });\n\n const updated: PageActionRowState[] = [];\n for (const [runId, tracked] of this.automationRunRegistry) {\n if (!isActiveAutomationTaskStatus(tracked.status)) continue;\n const row = await this.hydratePageActionByRunId(runId, {\n rowKey: tracked.rowKey ?? undefined,\n actionKey: tracked.actionKey,\n signal: opts.signal,\n });\n if (!row) continue;\n if (actionKey && row.actionKey !== actionKey) continue;\n updated.push(row);\n }\n return updated;\n }\n\n async invokePageAction(input: PageBotInvokeInput): Promise<PageBotStreamResult> {\n await this.ensureInitialized('invokePageAction', { signal: input.signal });\n const state = this.requireState('invokePageAction');\n this.requirePageActionKey(input);\n\n const rowKey = this.resolveInvokeRowKey(input);\n if (rowKey) {\n const existing = this.pageActionRows.get(rowKey);\n // Legacy reuse path left idle+loading after a dismissed picker; unlock before gate.\n if (\n existing &&\n existing.phase === 'idle' &&\n existing.loading &&\n existing.runId == null &&\n !existing.awaitingApproval\n ) {\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: existing.actionKey || input.actionKey.trim(),\n runId: null,\n pageActionKey: existing.pageActionKey,\n phase: 'idle',\n loading: false,\n disabled: false,\n error: null,\n message: null,\n progressLabel: null,\n approvalRequestId: existing.approvalRequestId,\n }),\n );\n }\n }\n if (rowKey && this.isPageActionRowActive(rowKey)) {\n return this.finishAlreadyActiveInvoke(input, rowKey, {\n source: 'local',\n });\n }\n\n const lockKey = this.acquirePageActionLock(input.clientActionId);\n\n try {\n const preferReuse =\n input.preferReuse !== false && this.pageActionReusePromptHandler != null;\n const invokeBody = preferReuse\n ? this.buildPageActionInvokeBody(state, input)\n : null;\n const cachedHint = invokeBody ? this.pageActionReuseHintCache.get(invokeBody) : null;\n /** Skip network + checking label when we already know this entity's hint. */\n const reuseCacheHit = cachedHint != null;\n const reuseHasItems =\n (cachedHint?.reusable.items.length ?? 0) > 0 ||\n (cachedHint?.reusable.total ?? 0) > 0;\n const needsReuseFetch = preferReuse && !reuseCacheHit;\n const showReusePrompt = preferReuse && (needsReuseFetch || reuseHasItems);\n\n if (rowKey) {\n this.clearPageActionNarrativeClearTimer(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: this.pageActionRows.get(rowKey)?.runId ?? null,\n pageActionKey:\n cachedHint?.pageActionKey ??\n this.pageActionRows.get(rowKey)?.pageActionKey ??\n null,\n phase: showReusePrompt ? 'awaiting_reuse' : 'submitting',\n error: null,\n message: null,\n progressLabel: needsReuseFetch\n ? pageActionReuseCheckingLabel(this.state?.options.locale)\n : showReusePrompt\n ? null\n : defaultPageActionProgressLabel(this.state?.options.locale),\n narrativeItems: [],\n approvalRequestId: this.pageActionRows.get(rowKey)?.approvalRequestId ?? null,\n }),\n );\n }\n\n await this.ensureLoggedIn('invokePageAction', { signal: input.signal });\n\n if (showReusePrompt) {\n const reuseResult = await this.tryPageActionReusePrompt(state, input, rowKey, {\n body: invokeBody!,\n cached: cachedHint,\n });\n if (reuseResult) return reuseResult;\n }\n\n if (rowKey) {\n this.clearPageActionNarrativeClearTimer(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: this.pageActionRows.get(rowKey)?.runId ?? null,\n pageActionKey: this.pageActionRows.get(rowKey)?.pageActionKey ?? null,\n phase: 'submitting',\n error: null,\n message: null,\n progressLabel: defaultPageActionProgressLabel(this.state?.options.locale),\n narrativeItems: [],\n approvalRequestId: this.pageActionRows.get(rowKey)?.approvalRequestId ?? null,\n }),\n );\n }\n\n // Do not invalidate reuse-hint here — empty/positive cache survives cancel + re-click.\n // Cache is dropped on「重新执行」and when a run completes (see below).\n\n return await this.invokePageActionStream(state, input, rowKey);\n } catch (err) {\n if (rowKey && !(err instanceof AgentChatError && err.code === 'PAGE_ACTION_ALREADY_ACTIVE')) {\n const message = err instanceof Error ? err.message : String(err);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: this.pageActionRows.get(rowKey)?.runId ?? null,\n pageActionKey: this.pageActionRows.get(rowKey)?.pageActionKey ?? null,\n phase: 'failed',\n error: message,\n message: null,\n progressLabel: null,\n approvalRequestId: this.pageActionRows.get(rowKey)?.approvalRequestId ?? null,\n }),\n );\n this.schedulePageActionRowIdleReset(rowKey, 1_600);\n }\n throw err;\n } finally {\n this.releasePageActionLock(lockKey);\n }\n }\n\n /**\n * Register the built-in reuse popover handler (ChatRoot).\n * Without a handler, {@link invokePageAction} skips reuse and invokes directly.\n */\n setPageActionReusePromptHandler(\n handler: PageActionReusePromptHandler | null,\n ): () => void {\n this.pageActionReusePromptHandler = handler;\n return () => {\n if (this.pageActionReusePromptHandler === handler) {\n this.pageActionReusePromptHandler = null;\n }\n };\n }\n\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 const runId =\n typeof input?.runId === 'number' && Number.isFinite(input.runId)\n ? Math.trunc(input.runId)\n : null;\n const rowKey =\n input?.rowKey?.trim() ||\n (runId != null ? this.findRowKeyByRunId(runId) : null);\n if (!rowKey) return;\n const prev = this.pageActionRows.get(rowKey);\n if (!prev || prev.phase !== 'awaiting_clarify') return;\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n phase: 'idle',\n loading: false,\n disabled: false,\n error: null,\n progressLabel: null,\n brainClarify: null,\n }),\n );\n }\n\n /**\n * After a reused result was applied (docked「撤销」/「继续执行」), force the\n * trigger row back to clickable idle and abort any in-flight replay for that run.\n */\n dismissPageActionReuse(input?: {\n rowKey?: string | null;\n runId?: number | null;\n }): void {\n const runId =\n typeof input?.runId === 'number' && Number.isFinite(input.runId)\n ? Math.trunc(input.runId)\n : null;\n const rowKey =\n input?.rowKey?.trim() ||\n (runId != null ? this.findRowKeyByRunId(runId) : null);\n if (!rowKey) return;\n\n const prevEpoch = this.pageActionReuseDismissEpochByRowKey.get(rowKey) ?? 0;\n this.pageActionReuseDismissEpochByRowKey.set(rowKey, prevEpoch + 1);\n\n const idleTimer = this.pageActionRowIdleTimers.get(rowKey);\n if (idleTimer != null) {\n clearTimeout(idleTimer);\n this.pageActionRowIdleTimers.delete(rowKey);\n }\n\n const prev = this.pageActionRows.get(rowKey);\n const abortRunId = runId ?? prev?.runId ?? null;\n if (abortRunId != null) {\n this.pageActionRunAborts.get(abortRunId)?.abort();\n }\n\n if (!prev) return;\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: prev.actionKey,\n runId: prev.runId,\n pageActionKey: prev.pageActionKey,\n phase: 'idle',\n loading: false,\n disabled: false,\n error: null,\n message: null,\n progressLabel: null,\n approvalRequestId: prev.approvalRequestId,\n brainClarify: null,\n }),\n );\n }\n\n /** `POST /page-action/reuse-hint` — soft check for reusable successful runs. */\n async reusePageActionHint(\n input: Pick<\n PageBotInvokeInput,\n 'actionKey' | 'pageContext' | 'instruction' | 'context' | 'signal'\n > & { refresh?: boolean },\n ): Promise<PageActionReuseHint> {\n await this.ensureInitialized('reusePageActionHint', { signal: input.signal });\n const state = this.requireState('reusePageActionHint');\n await this.ensureLoggedIn('reusePageActionHint', { signal: input.signal });\n const body = this.buildPageActionInvokeBody(state, {\n actionKey: input.actionKey,\n pageContext: input.pageContext,\n instruction: input.instruction,\n context: input.context,\n });\n if (!input.refresh) {\n const cached = this.pageActionReuseHintCache.get(body);\n if (cached) return cached;\n }\n const hint = await state.pageAction.reuseHint(body, input.signal);\n this.pageActionReuseHintCache.set(body, hint);\n return hint;\n }\n\n async prefetch(): Promise<void> {\n await this.ensureLoggedIn('prefetch');\n const state = this.requireState('prefetch');\n const ctrl = this.makeAbortController();\n try {\n await Promise.all([\n this.refreshSessions(ctrl.signal),\n this.refreshAgentCatalog(ctrl.signal),\n this.refreshApprovalPendingCount(ctrl.signal).catch(() => {\n /* inbox badge is optional */\n }),\n this.refreshApprovalInbox({ signal: ctrl.signal }).catch(() => {\n /* inbox is optional */\n }),\n ]);\n if (!state.sessions.length) return;\n const targetId =\n state.activeSessionId && state.sessions.some((s) => s.sessionId === state.activeSessionId)\n ? state.activeSessionId\n : state.sessions[0]!.sessionId;\n await this.selectSession(targetId, { signal: ctrl.signal, skipAbortStream: true });\n } finally {\n state.catalogHydrated = true;\n state.abortControllers.delete(ctrl);\n this.notifyStateChange();\n }\n }\n\n async selectSession(\n sessionId: string,\n opts: { signal?: AbortSignal; skipAbortStream?: boolean } = {},\n ): Promise<void> {\n await this.ensureLoggedIn('selectSession');\n const state = this.requireState('selectSession');\n const id = sessionId.trim();\n if (!id) {\n throw new AgentChatError('INVALID_OPTIONS', 'selectSession: sessionId is required');\n }\n\n this.sessionEpoch += 1;\n const loadEpoch = this.sessionEpoch;\n const normalizedTarget = normalizeSessionId(id);\n\n if (state.activeSessionId && state.activeSessionId !== id) {\n this.writeSessionMessagesCache(state, state.activeSessionId);\n if (!opts.skipAbortStream && !this.sessionHasPendingAgent(state.messages)) {\n this.abortSessionStream(state, state.activeSessionId, { suppressReconnect: true });\n }\n }\n\n state.lastError = null;\n const leavingSession =\n state.activeSessionId != null &&\n normalizeSessionId(state.activeSessionId) !== normalizedTarget;\n if (leavingSession) {\n // Chat turn UI is session-scoped — drop clarify/banner from the previous session.\n this.clearSkillIntentUi(state);\n }\n\n const cached =\n state.sessionMessagesCache.get(normalizedTarget) ??\n state.sessionMessagesCache.get(id);\n if (cached) {\n if (loadEpoch === this.sessionEpoch) {\n state.activeSessionId = id;\n state.messages = cached.messages;\n state.activeSessionMessagesPage = cached.page;\n state.activeSessionMessagesHasMore = cached.hasMore;\n if (cached.agentId) {\n this.applyAutoAgentBinding(state, {\n id: cached.agentId,\n source: 'session',\n reason: 'restored from session detail cache',\n });\n }\n state.session.setSession(id, cached.messages);\n this.syncActiveWriteConfirmation(state, id);\n this.notifyStateChange();\n this.bus.emit('session', state.session.getSession()!);\n if (!opts.signal?.aborted) {\n await this.syncSessionRunState(state, id, opts.signal);\n this.reconcilePendingRepliesAfterSessionSwitch(state, id, normalizedTarget);\n void this.ensureSessionStream(id).catch(() => {\n /* stream error already reported */\n });\n void this.syncMessageFeedbacks(state, id).catch(() => {\n /* feedback sync is best-effort */\n });\n this.schedulePrepareSession();\n }\n }\n return;\n }\n\n const ctrl = this.makeAbortController();\n const signal = opts.signal;\n if (signal) {\n signal.addEventListener('abort', () => ctrl.abort(), { once: true });\n }\n try {\n const detailPage = await this.fetchSessionMessagesPage(state, id, 1, ctrl.signal);\n const mapped = detailPage.messages.map((m) => this.toAgentMessage(m as ServerMessage));\n const cacheEntry: SessionMessagesCacheEntry = {\n messages: mapped,\n page: detailPage.page,\n hasMore: detailPage.hasMore,\n agentId: detailPage.agentId,\n };\n state.sessionMessagesCache.set(normalizedTarget, cacheEntry);\n if (loadEpoch !== this.sessionEpoch) return;\n state.activeSessionId = id;\n state.activeSessionMessagesPage = detailPage.page;\n state.activeSessionMessagesHasMore = detailPage.hasMore;\n state.session.setSession(detailPage.sessionId, mapped);\n state.messages = mapped;\n if (detailPage.agentId) {\n this.applyAutoAgentBinding(state, {\n id: detailPage.agentId,\n source: 'session',\n reason: 'restored from session detail',\n });\n }\n this.syncActiveWriteConfirmation(state, id);\n this.notifyStateChange();\n this.bus.emit('session', state.session.getSession()!);\n if (!opts.signal?.aborted) {\n await this.syncSessionRunState(state, id, ctrl.signal);\n this.reconcilePendingRepliesAfterSessionSwitch(state, id, normalizedTarget);\n void this.ensureSessionStream(id).catch(() => {\n /* stream error already reported */\n });\n void this.syncMessageFeedbacks(state, id).catch(() => {\n /* feedback sync is best-effort */\n });\n this.schedulePrepareSession();\n }\n } finally {\n state.abortControllers.delete(ctrl);\n }\n }\n\n /**\n * Send a user turn end-to-end:\n *\n * 1. Optimistic user bubble (`pending`) → `notifyStateChange` → React re-render\n * 2. Ensure `sessionId` (create via `POST /chat` on first send)\n * 3. `POST /chat/{sessionId}/messages` (existing session) or skip (new session: message already in `POST /chat`)\n * 4. Append empty assistant placeholder (`pending`) with a new id\n * 5. `POST` user message (existing session) → `GET /chat/{sessionId}/stream`\n * 6. SSE updates **only** the placeholder message by id (`think` / `result` / `complete`)\n */\n async sendMessage(\n text: string,\n opts: {\n id?: string;\n contextMentions?: ContextMentionAttachment[];\n entityCommit?: EntityCommit;\n } = {},\n ): Promise<AgentMessage> {\n await this.ensureLoggedIn('sendMessage');\n const state = this.requireState('sendMessage');\n const trimmed = text.trim();\n if (trimmed.length === 0) {\n throw new AgentChatError('INVALID_OPTIONS', 'sendMessage: text must not be empty');\n }\n\n this.settlePendingAgentReplies(state, state.activeSessionId ?? undefined);\n if (state.activeSessionId) {\n this.persistWriteConfirmation(state, state.activeSessionId, null);\n }\n state.lastTurnUserMessage = trimmed;\n this.clearSkillIntentUi(state);\n state.brainClarify = null;\n\n const resolvedMentions = opts.contextMentions?.length\n ? await resolveContextMentionsForSend(\n opts.contextMentions,\n state.contextMentionRegistry,\n )\n : undefined;\n\n const sendPageContext = resolvedMentions?.length\n ? mergePageContextWithMentions(\n this.buildOutboundPageContext(state),\n resolvedMentions,\n )\n : undefined;\n\n const userMessage = this.appendOptimisticUserMessage(\n state,\n trimmed,\n opts.id,\n opts.contextMentions,\n );\n const agentPlaceholder = this.appendAgentPlaceholder(state);\n const ctrl = this.makeAbortController();\n\n try {\n let sessionId = state.activeSessionId ?? state.session.getSession()?.sessionId ?? null;\n\n if (!sessionId) {\n sessionId = await this.createChatSession(\n state,\n trimmed,\n ctrl.signal,\n sendPageContext,\n opts.entityCommit,\n );\n void this.refreshSessions(ctrl.signal).catch(() => {\n /* sidebar refresh is best-effort */\n });\n this.setStreamTargetMessageId(state, sessionId, agentPlaceholder.id);\n await this.ensureSessionStream(sessionId);\n return this.applyUserMessageSent(state, userMessage);\n }\n\n this.setStreamTargetMessageId(state, sessionId, agentPlaceholder.id);\n const sentUser = await this.postUserMessageAndApply(\n state,\n sessionId,\n trimmed,\n ctrl.signal,\n userMessage,\n sendPageContext,\n opts.entityCommit,\n );\n await this.ensureSessionStream(sessionId);\n return sentUser;\n } catch (err) {\n const sessionId = state.activeSessionId;\n const updated = state.messages\n .filter((m) => m.id !== agentPlaceholder.id)\n .map((m) => (m.id === userMessage.id ? { ...userMessage, status: 'failed' as const } : m));\n state.messages = updated;\n if (sessionId) {\n this.commitSessionMessages(state, sessionId, updated);\n } else {\n this.notifyStateChange();\n }\n\n const wrapped =\n err instanceof AgentChatError\n ? new AgentChatError('MESSAGE_FAILED', err.message, {\n cause: err,\n details: { ...(err.details ?? {}), messageId: userMessage.id },\n })\n : new AgentChatError('MESSAGE_FAILED', 'Failed to send message', {\n cause: err,\n details: { messageId: userMessage.id },\n });\n this.reportError(wrapped);\n throw wrapped;\n } finally {\n state.abortControllers.delete(ctrl);\n }\n }\n\n async confirmWrite(): Promise<void> {\n await this.submitWriteGate({ action: 'confirm' });\n }\n\n async confirmWriteWithEdits(input: {\n editedPreviewSerialized?: string;\n editedPendingWriteArguments?: Record<string, unknown>;\n }): Promise<void> {\n const { editedPreviewSerialized, editedPendingWriteArguments } = input;\n if (!editedPreviewSerialized?.trim() && !editedPendingWriteArguments) {\n throw new AgentChatError(\n 'INVALID_OPTIONS',\n 'confirmWriteWithEdits: editedPreviewSerialized or editedPendingWriteArguments is required',\n );\n }\n await this.submitWriteGate({\n action: 'confirm_with_edits',\n editedPreviewSerialized: editedPreviewSerialized?.trim() || undefined,\n editedPendingWriteArguments,\n });\n }\n\n async retryWrite(retryInstruction: string): Promise<void> {\n const instruction = retryInstruction.trim();\n if (!instruction) {\n throw new AgentChatError('INVALID_OPTIONS', 'retryWrite: retryInstruction must not be empty');\n }\n await this.submitWriteGate({ action: 'retry', retryInstruction: instruction });\n }\n\n async cancelWrite(): Promise<void> {\n await this.submitWriteGate({ action: 'cancel' });\n }\n\n private async submitWriteGate(writeGate: WriteGate): Promise<void> {\n const label = `submitWriteGate:${writeGate.action}`;\n await this.ensureLoggedIn(label);\n const state = this.requireState(label);\n const pending = state.writeConfirmation;\n if (!pending?.awaiting) {\n throw new AgentChatError('INVALID_OPTIONS', 'No pending write confirmation');\n }\n\n if (writeGate.action === 'retry' && pending.canRetry === false) {\n throw new AgentChatError('INVALID_OPTIONS', 'Draft retry limit exceeded');\n }\n\n const sessionId = state.activeSessionId ?? state.session.getSession()?.sessionId ?? null;\n if (!sessionId) {\n throw new AgentChatError('INVALID_OPTIONS', `${label}: no active session`);\n }\n\n const keepsGateOpen = writeGate.action === 'retry';\n state.writeConfirmation = {\n ...pending,\n awaiting: keepsGateOpen,\n submitting: true,\n gateError: undefined,\n gateErrorCode: undefined,\n };\n this.persistWriteConfirmation(state, sessionId, state.writeConfirmation);\n this.notifyStateChange();\n\n const needsStreamPlaceholder =\n writeGate.action === 'confirm' || writeGate.action === 'confirm_with_edits';\n if (needsStreamPlaceholder) {\n const agentPlaceholder = this.appendAgentPlaceholder(state);\n this.setStreamTargetMessageId(state, sessionId, agentPlaceholder.id);\n }\n\n const ctrl = this.makeAbortController();\n\n try {\n await this.postWriteGateAction(state, sessionId, writeGate, ctrl.signal);\n } catch (err) {\n const serverCode = readWriteGateServerCode(err);\n const gateLevel =\n serverCode === 'DRAFT_RETRY_LIMIT_EXCEEDED' ||\n serverCode === 'INVALID_DRAFT_REVIEW_DECISION' ||\n serverCode === 'EDITED_WRITE_ARGS_INVALID' ||\n serverCode === 'EDITED_LOCKED_FIELD' ||\n serverCode === 'EDITED_FIELD_NOT_ALLOWED' ||\n serverCode === 'MULTI_WRITE_EDIT_NOT_SUPPORTED';\n\n const restored: WriteConfirmationState = {\n ...pending,\n awaiting: true,\n submitting: false,\n gateError: err instanceof AgentChatError ? err.message : undefined,\n gateErrorCode: serverCode,\n canRetry: serverCode === 'DRAFT_RETRY_LIMIT_EXCEEDED' ? false : pending.canRetry,\n };\n state.writeConfirmation = restored;\n this.persistWriteConfirmation(state, sessionId, restored);\n this.notifyStateChange();\n\n if (gateLevel) return;\n\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to submit write gate decision', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n } finally {\n state.abortControllers.delete(ctrl);\n }\n }\n\n async refreshApprovalInbox(\n opts: {\n signal?: AbortSignal;\n status?: ApprovalInboxStatusFilter;\n limit?: number;\n offset?: number;\n append?: boolean;\n } = {},\n ): Promise<ApprovalInboxList> {\n if (this.approvalInboxRefreshPromise && !opts.append) {\n return this.approvalInboxRefreshPromise;\n }\n const run = this.fetchApprovalInbox(opts);\n if (!opts.append) {\n this.approvalInboxRefreshPromise = run;\n }\n try {\n return await run;\n } finally {\n if (!opts.append && this.approvalInboxRefreshPromise === run) {\n this.approvalInboxRefreshPromise = null;\n }\n }\n }\n\n setApprovalInboxStatusFilter(status: ApprovalInboxStatusFilter): void {\n const state = this.state;\n if (!state || state.approvalInboxStatusFilter === status) return;\n state.approvalInboxStatusFilter = status;\n state.approvalInboxItems = [];\n state.approvalInboxHasMore = false;\n this.notifyStateChange();\n }\n\n /** Refresh badge count without replacing the visible inbox list. */\n async refreshApprovalPendingCount(signal?: AbortSignal): Promise<void> {\n if (this.approvalPendingCountRefreshPromise && !signal) {\n return this.approvalPendingCountRefreshPromise;\n }\n const run = this.fetchApprovalPendingCount(signal);\n if (!signal) {\n this.approvalPendingCountRefreshPromise = run;\n }\n try {\n await run;\n } finally {\n if (!signal && this.approvalPendingCountRefreshPromise === run) {\n this.approvalPendingCountRefreshPromise = null;\n }\n }\n }\n\n private async fetchApprovalPendingCount(signal?: AbortSignal): Promise<void> {\n await this.ensureLoggedIn('refreshApprovalPendingCount');\n const state = this.requireState('refreshApprovalPendingCount');\n const list = await state.approval.listInbox({ status: 'pending', limit: 50, signal });\n state.approvalInboxPendingCount = list.hasMore\n ? Math.max(state.approvalInboxPendingCount, list.items.length)\n : list.items.length;\n this.notifyStateChange();\n }\n\n private async fetchApprovalInbox(\n opts: {\n signal?: AbortSignal;\n status?: ApprovalInboxStatusFilter;\n limit?: number;\n offset?: number;\n append?: boolean;\n } = {},\n ): Promise<ApprovalInboxList> {\n await this.ensureLoggedIn('refreshApprovalInbox');\n const state = this.requireState('refreshApprovalInbox');\n const status = opts.status ?? state.approvalInboxStatusFilter;\n const limit = opts.limit ?? APPROVAL_INBOX_PAGE_SIZE;\n const offset = opts.offset ?? (opts.append ? state.approvalInboxItems.length : 0);\n const append = opts.append === true;\n if (append) {\n state.approvalInboxLoadingMore = true;\n } else {\n state.approvalInboxLoading = true;\n }\n this.notifyStateChange();\n try {\n const list = await state.approval.listInbox({\n status,\n limit,\n offset,\n signal: opts.signal,\n });\n state.approvalInboxStatusFilter = status;\n state.approvalInboxHasMore = list.hasMore;\n state.approvalInboxItems = append\n ? [...state.approvalInboxItems, ...list.items]\n : list.items;\n if (status === 'pending' && offset === 0 && !append) {\n state.approvalInboxPendingCount = list.hasMore\n ? Math.max(state.approvalInboxPendingCount, list.items.length)\n : list.items.length;\n }\n return list;\n } finally {\n if (append) {\n state.approvalInboxLoadingMore = false;\n } else {\n state.approvalInboxLoading = false;\n }\n this.notifyStateChange();\n }\n }\n\n async getApproval(id: number, signal?: AbortSignal): Promise<ApprovalDetail | null> {\n await this.ensureLoggedIn('getApproval');\n const state = this.requireState('getApproval');\n return state.approval.getById(id, signal);\n }\n\n /** `GET /approval/:id` — merge fresh `writeDraft` into cached inbox (e.g. after retry). */\n async hydrateApprovalInboxItem(\n id: number,\n signal?: AbortSignal,\n ): Promise<ApprovalDetail | null> {\n await this.ensureLoggedIn('hydrateApprovalInboxItem');\n const state = this.requireState('hydrateApprovalInboxItem');\n const detail = await state.approval.getById(id, signal);\n if (!detail) {\n state.approvalInboxItems = state.approvalInboxItems.filter((item) => item.id !== id);\n this.notifyStateChange();\n return null;\n }\n const index = state.approvalInboxItems.findIndex((item) => item.id === id);\n if (index >= 0) {\n const next = [...state.approvalInboxItems];\n next[index] = detail;\n state.approvalInboxItems = next;\n } else {\n state.approvalInboxItems = [detail, ...state.approvalInboxItems];\n }\n this.notifyStateChange();\n return detail;\n }\n\n async confirmApproval(id: number, signal?: AbortSignal): Promise<ApprovalConfirmResult> {\n await this.ensureLoggedIn('confirmApproval');\n const state = this.requireState('confirmApproval');\n const runId = this.resolveApprovalPageActionRunId(id);\n const identity = this.resolveApprovalIdentity(id);\n const result = await state.approval.confirm(id, signal);\n void this.refreshApprovalPendingCount(signal).catch(() => {\n /* badge refresh is best-effort */\n });\n void this.refreshApprovalInbox().catch(() => {\n /* inbox refresh is best-effort */\n });\n this.bus.emit('approvalInboxChanged', undefined);\n void this.refreshPageActionRowsAfterApprovalDecision(runId, id);\n if (result.resumed) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'resumed');\n void this.emitApprovalExecutionCompleted({\n approvalId: id,\n runId,\n decision: { action: 'confirm' },\n result,\n identity,\n }).catch(() => {\n /* execution notice is best-effort */\n });\n } else if (!result.suspended) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'cancelled');\n }\n return result;\n }\n\n async decideApproval(\n id: number,\n decision: DraftReviewDecision,\n opts?: { reason?: string; signal?: AbortSignal },\n ): Promise<ApprovalDecideResult> {\n await this.ensureLoggedIn('decideApproval');\n const state = this.requireState('decideApproval');\n const runId = this.resolveApprovalPageActionRunId(id);\n const identity = this.resolveApprovalIdentity(id);\n const result = await state.approval.decide(id, decision, opts?.reason, opts?.signal);\n if (result.suspended) {\n await this.hydrateApprovalInboxItem(id, opts?.signal).catch(() => {\n /* detail refresh is best-effort */\n });\n } else {\n void this.refreshApprovalPendingCount(opts?.signal).catch(() => {\n /* badge refresh is best-effort */\n });\n void this.refreshApprovalInbox().catch(() => {\n /* inbox refresh is best-effort */\n });\n }\n this.bus.emit('approvalInboxChanged', undefined);\n void this.refreshPageActionRowsAfterApprovalDecision(runId, id);\n void this.emitApprovalExecutionCompleted({\n approvalId: id,\n runId,\n decision,\n result,\n identity,\n }).catch(() => {\n /* execution notice is best-effort */\n });\n if (result.suspended) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'suspended');\n } else if (decision.action === 'cancel') {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'cancelled');\n } else if (result.resumed) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'resumed');\n }\n return result;\n }\n\n async rejectApproval(\n id: number,\n reason?: string,\n signal?: AbortSignal,\n ): Promise<ApprovalRejectResult> {\n await this.ensureLoggedIn('rejectApproval');\n const state = this.requireState('rejectApproval');\n const runId = this.resolveApprovalPageActionRunId(id);\n const identity = this.resolveApprovalIdentity(id);\n const result = await state.approval.reject(id, reason, signal);\n void this.refreshApprovalPendingCount(signal).catch(() => {\n /* badge refresh is best-effort */\n });\n void this.refreshApprovalInbox().catch(() => {\n /* inbox refresh is best-effort */\n });\n this.bus.emit('approvalInboxChanged', undefined);\n void this.refreshPageActionRowsAfterApprovalDecision(runId, id);\n if (result.ok) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'cancelled');\n this.bus.emit('approvalExecutionCompleted', {\n approvalId: id,\n runId,\n outcome: 'cancelled',\n title: identity.approvalTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n });\n }\n return result;\n }\n\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 if (meta?.accepted) {\n this.trackAutomationRun(meta.accepted, {\n actionKey: meta.actionKey?.trim() || meta.accepted.runId.toString(),\n pageActionKey: meta.pageActionKey ?? meta.accepted.pageActionKey ?? null,\n rowKey: meta.rowKey ?? null,\n });\n return;\n }\n if (!Number.isFinite(runId)) return;\n const id = Math.trunc(runId);\n const now = new Date().toISOString();\n const rowKey = meta?.rowKey?.trim() || null;\n this.automationRunRegistry.set(id, {\n runId: id,\n actionKey: meta?.actionKey?.trim() || `Run ${id}`,\n pageActionKey: meta?.pageActionKey ?? null,\n rowKey,\n status: 'running',\n registeredAt: now,\n updatedAt: now,\n clientActionId: null,\n });\n if (rowKey) this.bindPageActionRunToRow(id, rowKey);\n const state = this.state;\n if (state) {\n this.syncAutomationActiveCount(state);\n state.automationRecentRunIds = [\n id,\n ...state.automationRecentRunIds.filter((row) => row !== id),\n ].slice(0, MAX_RECENT_AUTOMATION_RUN_IDS);\n this.notifyStateChange();\n }\n this.bus.emit('automationTaskCenterChanged', undefined);\n }\n\n reconcileAutomationTasksIfNeeded(): void {\n const state = this.state;\n if (!state?.isLoggedIn) return;\n pruneStaleTrackedRuns(this.automationRunRegistry);\n if (this.automationRunRegistry.size === 0) return;\n const stale =\n Date.now() - this.automationTasksLastSyncedAt > AUTOMATION_RECONCILE_STALE_MS;\n if (!stale) return;\n void this.refreshAutomationTasks({ status: 'active', offset: 0 }).catch(() => {\n /* reconcile is best-effort */\n });\n }\n\n async refreshAutomationTasks(\n opts: {\n signal?: AbortSignal;\n status?: AutomationTaskStatusFilter;\n actionKey?: string;\n limit?: number;\n offset?: number;\n append?: boolean;\n } = {},\n ): Promise<AutomationTaskList> {\n const cacheKey = opts.append ? null : this.buildAutomationTaskRefreshCacheKey(opts);\n if (\n this.automationTaskRefreshPromise &&\n cacheKey &&\n this.automationTaskRefreshCacheKey === cacheKey\n ) {\n return this.automationTaskRefreshPromise;\n }\n const run = this.fetchAutomationTasks(opts);\n if (!opts.append) {\n this.automationTaskRefreshCacheKey = cacheKey;\n this.automationTaskRefreshPromise = run;\n }\n try {\n return await run;\n } finally {\n if (!opts.append && this.automationTaskRefreshPromise === run) {\n this.automationTaskRefreshPromise = null;\n this.automationTaskRefreshCacheKey = null;\n }\n }\n }\n\n private buildAutomationTaskRefreshCacheKey(opts: {\n status?: AutomationTaskStatusFilter;\n actionKey?: string;\n offset?: number;\n }): string {\n const status = opts.status ?? 'active';\n const actionKey = opts.actionKey?.trim() ?? '';\n const offset = opts.offset ?? 0;\n return `${status}|${actionKey}|${offset}`;\n }\n\n setAutomationTaskStatusFilter(status: AutomationTaskStatusFilter): void {\n const state = this.state;\n if (!state || state.automationTaskStatusFilter === status) return;\n this.commitAutomationTaskTabCache(state);\n state.automationTaskStatusFilter = status;\n this.restoreAutomationTaskTabView(state);\n state.automationTaskSelectedDetail = null;\n this.notifyStateChange();\n }\n\n /**\n * Show a task-center tab — restore cached list or fetch page 1 when never loaded.\n */\n async ensureAutomationTaskTabLoaded(\n status?: AutomationTaskStatusFilter,\n opts: { refresh?: boolean; signal?: AbortSignal } = {},\n ): Promise<void> {\n await this.ensureLoggedIn('ensureAutomationTaskTabLoaded', { signal: opts.signal });\n const state = this.requireState('ensureAutomationTaskTabLoaded');\n const filter = status ?? state.automationTaskStatusFilter;\n if (filter !== state.automationTaskStatusFilter) {\n this.commitAutomationTaskTabCache(state);\n state.automationTaskStatusFilter = filter;\n this.restoreAutomationTaskTabView(state);\n state.automationTaskSelectedDetail = null;\n }\n const cache = getAutomationTaskTabCache(state.automationTaskTabCaches, filter);\n if (!cache.hydrated || opts.refresh) {\n await this.refreshAutomationTasks({ status: filter, offset: 0, signal: opts.signal });\n return;\n }\n this.notifyStateChange();\n }\n\n /** Append next page for the active task-center tab. */\n async loadAutomationTaskNextPage(opts: { signal?: AbortSignal } = {}): Promise<void> {\n await this.ensureLoggedIn('loadAutomationTaskNextPage', { signal: opts.signal });\n const state = this.requireState('loadAutomationTaskNextPage');\n if (state.automationTaskLoading || state.automationTaskLoadingMore || !state.automationTaskHasMore) {\n return;\n }\n await this.refreshAutomationTasks({\n status: state.automationTaskStatusFilter,\n append: true,\n signal: opts.signal,\n });\n }\n\n private commitAutomationTaskTabCache(state: InternalState): void {\n writeAutomationTaskTabCache(state.automationTaskTabCaches, state.automationTaskStatusFilter, {\n items: state.automationTaskItems,\n hasMore: state.automationTaskHasMore,\n total: state.automationTaskTotal,\n hydrated: getAutomationTaskTabCache(\n state.automationTaskTabCaches,\n state.automationTaskStatusFilter,\n ).hydrated,\n });\n }\n\n private restoreAutomationTaskTabView(state: InternalState): void {\n const cache = getAutomationTaskTabCache(\n state.automationTaskTabCaches,\n state.automationTaskStatusFilter,\n );\n state.automationTaskItems = [...cache.items];\n state.automationTaskHasMore = cache.hasMore;\n state.automationTaskTotal = cache.total;\n state.automationTaskLoading = false;\n state.automationTaskLoadingMore = false;\n }\n\n private publishAutomationTaskTabCache(\n state: InternalState,\n filter: AutomationTaskStatusFilter,\n items: AutomationTaskListItem[],\n hasMore: boolean,\n total?: number,\n ): void {\n const prev = getAutomationTaskTabCache(state.automationTaskTabCaches, filter);\n const resolvedTotal = total ?? prev.total;\n writeAutomationTaskTabCache(state.automationTaskTabCaches, filter, {\n items,\n hasMore,\n total: resolvedTotal,\n hydrated: true,\n });\n if (state.automationTaskStatusFilter === filter) {\n state.automationTaskItems = items;\n state.automationTaskHasMore = hasMore;\n state.automationTaskTotal = resolvedTotal;\n }\n }\n\n async refreshAutomationActiveCount(signal?: AbortSignal): Promise<void> {\n const state = this.state;\n if (!state) return;\n await this.ensureLoggedIn('refreshAutomationActiveCount', { signal });\n this.syncAutomationActiveCount(state);\n this.notifyStateChange();\n }\n\n async getAutomationTaskDetail(\n runId: number,\n signal?: AbortSignal,\n ): Promise<AutomationTaskDetail | null> {\n await this.ensureLoggedIn('getAutomationTaskDetail');\n const state = this.requireState('getAutomationTaskDetail');\n return state.automation.getPageActionRunTask(runId, signal);\n }\n\n async hydrateAutomationTaskDetail(\n runId: number,\n signal?: AbortSignal,\n ): Promise<AutomationTaskDetail | null> {\n await this.ensureLoggedIn('hydrateAutomationTaskDetail');\n const state = this.requireState('hydrateAutomationTaskDetail');\n state.automationTaskDetailLoading = true;\n this.notifyStateChange();\n try {\n const detail = await state.automation.getPageActionRunTask(runId, signal);\n state.automationTaskSelectedDetail = detail;\n if (detail) {\n const index = state.automationTaskItems.findIndex(\n (item) =>\n item.ref.kind === 'page_action_run' && item.ref.id === detail.ref.id,\n );\n if (index >= 0) {\n const next = [...state.automationTaskItems];\n next[index] = detail;\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n next,\n state.automationTaskHasMore,\n );\n }\n }\n return detail;\n } finally {\n state.automationTaskDetailLoading = false;\n this.notifyStateChange();\n }\n }\n\n clearAutomationTaskDetail(): void {\n const state = this.state;\n if (!state || !state.automationTaskSelectedDetail) return;\n state.automationTaskSelectedDetail = null;\n this.notifyStateChange();\n }\n\n /**\n * 任务中心「应用到页面」—— 只导航 + 写入 pendingApply,不直接 replay。\n * 目标页 `usePageAction({ ready })` 就绪后自动调用 `replayPageAction`。\n */\n async applyPageActionToPage(\n runId: number,\n opts: { signal?: AbortSignal } = {},\n ): Promise<ApplyPageActionToPageResult> {\n await this.ensureLoggedIn('applyPageActionToPage', { signal: opts.signal });\n const state = this.requireState('applyPageActionToPage');\n const id = Math.trunc(runId);\n if (!Number.isFinite(id)) {\n throw new AgentChatError('INVALID_OPTIONS', 'applyPageActionToPage requires a valid runId');\n }\n\n const detail =\n (await this.hydrateAutomationTaskDetail(id, opts.signal)) ??\n (await this.getAutomationTaskDetail(id, opts.signal));\n if (!detail || detail.ref.kind !== 'page_action_run') {\n throw new AgentChatError('PAGE_ACTION_FAILED', `PageAction run ${id} not found`);\n }\n\n const pageContext = detail.pageContext;\n const target = resolvePageContextNavigateTarget(pageContext);\n const base = {\n runId: id,\n actionKey: detail.actionKey,\n pageContext,\n target,\n };\n\n if (target.kind !== 'routePath') {\n return { ...base, navigated: false, canReplay: false, ok: false, reason: 'missing_route_path' };\n }\n\n if (detail.taskStatus !== 'completed') {\n const onNavigateEarly = state.options.onNavigateForPageAction;\n let navigated = false;\n if (onNavigateEarly) {\n await onNavigateEarly({ ...base, canReplay: false });\n navigated = true;\n }\n return { ...base, navigated, canReplay: false, ok: false, reason: 'not_completed' };\n }\n\n const canReplay = detail.replay.canReplay;\n if (!canReplay) {\n const onNavigateEmpty = state.options.onNavigateForPageAction;\n let navigated = false;\n if (onNavigateEmpty) {\n await onNavigateEmpty({ ...base, canReplay: false });\n navigated = true;\n }\n return { ...base, navigated, canReplay: false, ok: false, reason: 'no_replayable_output' };\n }\n\n // Write pending before navigate so the target page can see it on mount.\n this.setPendingPageActionApply({\n runId: id,\n actionKey: detail.actionKey,\n pageContext,\n createdAt: new Date().toISOString(),\n });\n\n const onNavigate = state.options.onNavigateForPageAction;\n let navigated = false;\n try {\n if (onNavigate) {\n await onNavigate({ ...base, canReplay: true });\n navigated = true;\n }\n } catch (err) {\n this.clearPendingPageActionApply();\n throw err;\n }\n\n // Same-page apply: navigate is often a no-op and mount sync may have been\n // in-flight when pending was written — kick coordinator again after settle.\n this.pageActionCoordinator.onPendingApplyChanged();\n\n return { ...base, navigated, canReplay: true, ok: true, reason: 'navigate_only' };\n }\n\n /**\n * 重放已完成 PageAction 的 stream 产出。\n * 成功或明确不可重放时清除匹配的 pendingApply;失败时保留 pending 以便重试。\n */\n async replayPageAction(\n runId: number,\n opts: { signal?: AbortSignal } = {},\n ): Promise<void> {\n await this.ensureLoggedIn('replayPageAction', { signal: opts.signal });\n const state = this.requireState('replayPageAction');\n const id = Math.trunc(runId);\n\n const clearIfPending = () => {\n const pending = this.getPendingPageActionApply();\n if (pending?.runId === id) {\n this.clearPendingPageActionApply();\n }\n };\n\n const detail =\n state.automationTaskSelectedDetail?.ref.id === id\n ? state.automationTaskSelectedDetail\n : await this.getAutomationTaskDetail(id, opts.signal);\n if (!detail || detail.ref.kind !== 'page_action_run') {\n clearIfPending();\n throw new AgentChatError('PAGE_ACTION_FAILED', `PageAction run ${id} not found`);\n }\n if (detail.taskStatus !== 'completed' || !detail.replay.canReplay) {\n clearIfPending();\n return;\n }\n\n const accepted: InvokePageActionAccepted = {\n runId: id,\n generation: id,\n clientActionId: null,\n pageActionKey: detail.pageActionKey,\n streamUrl: detail.streamUrl,\n status: 'completed',\n };\n const pageContext = detail.pageContext;\n const pageGate = pageGateFromPageContext(pageContext);\n const rowKey =\n this.pageActionRunToRowKey.get(id) ??\n (pageContext?.entity?.id != null ? String(pageContext.entity.id).trim() : null);\n try {\n await this.consumePageActionRunStream(\n state,\n {\n actionKey: detail.actionKey,\n pageContext: pageContext ?? undefined,\n signal: opts.signal,\n },\n accepted,\n pageGate,\n pageContext,\n );\n clearIfPending();\n this.bus.emit('pageActionApplyCompleted', {\n runId: id,\n actionKey: detail.actionKey,\n rowKey,\n });\n } catch (err) {\n this.bus.emit('pageActionRunFailed', {\n runId: id,\n actionKey: detail.actionKey,\n rowKey,\n errorMessage: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n }\n\n getPendingPageActionApply(): PendingPageActionApply | null {\n if (this.pendingPageActionApply) return this.pendingPageActionApply;\n const state = this.state;\n if (!state?.dsn) return null;\n const fromStorage = readPendingPageActionApply(state.dsn);\n if (fromStorage) {\n this.pendingPageActionApply = fromStorage;\n }\n return this.pendingPageActionApply;\n }\n\n clearPendingPageActionApply(): void {\n const state = this.state;\n this.pendingPageActionApply = null;\n if (state?.dsn) {\n clearPendingPageActionApplyStorage(state.dsn);\n }\n this.bus.emit('pendingPageActionApplyChanged', null);\n this.pageActionCoordinator.onPendingApplyChanged();\n }\n\n /**\n * Attach to a running PageAction SSE (no-op if already attached).\n * @returns true when a new attach was started\n */\n async attachPageActionStream(\n runId: number,\n opts: { signal?: AbortSignal; rowKey?: string } = {},\n ): Promise<boolean> {\n await this.ensureLoggedIn('attachPageActionStream', { signal: opts.signal });\n const state = this.requireState('attachPageActionStream');\n const id = Math.trunc(runId);\n if (!Number.isFinite(id)) return false;\n if (this.pageActionRunAborts.has(id) || this.pageActionRunStreamPromises.has(id)) {\n return false;\n }\n\n const detail = await this.getAutomationTaskDetail(id, opts.signal);\n if (!detail || detail.ref.kind !== 'page_action_run') return false;\n if (detail.taskStatus !== 'running') return false;\n\n const rowKey = resolveRestoredPageActionRowKey(id, {\n rowKey: opts.rowKey,\n entityId: detail.pageContext?.entity?.id ?? null,\n findRowKeyByRunId: () =>\n this.findRowKeyByRunId(id) || this.findRowKeyByPageActionKey(detail.pageActionKey),\n });\n\n await this.hydratePageActionByRunId(id, {\n rowKey,\n actionKey: detail.actionKey,\n signal: opts.signal,\n });\n\n // Re-check after await — another attach/replay may have started.\n if (this.pageActionRunAborts.has(id) || this.pageActionRunStreamPromises.has(id)) {\n return false;\n }\n\n const accepted: InvokePageActionAccepted = {\n runId: id,\n generation: id,\n clientActionId: null,\n pageActionKey: detail.pageActionKey,\n streamUrl: detail.streamUrl,\n status: 'running',\n };\n const pageContext = detail.pageContext;\n const pageGate = pageGateFromPageContext(pageContext);\n\n void this.consumePageActionRunStream(\n state,\n {\n actionKey: detail.actionKey,\n pageContext: pageContext ?? undefined,\n rowKey,\n },\n accepted,\n pageGate,\n pageContext,\n ).catch((err) => {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n detail.actionKey.split('.')[0]?.trim();\n this.markTrackedAutomationRunFailed(id, detail.actionKey);\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n });\n\n this.bus.emit('pageActionStreamResumed', {\n runId: id,\n actionKey: detail.actionKey,\n rowKey,\n });\n\n return true;\n }\n\n async resumeActivePageActionStreams(\n opts: { actionKey?: string; signal?: AbortSignal } = {},\n ): Promise<number> {\n await this.ensureLoggedIn('resumeActivePageActionStreams', { signal: opts.signal });\n this.requireState('resumeActivePageActionStreams');\n const actionKey = opts.actionKey?.trim();\n let attached = 0;\n for (const [runId, tracked] of this.automationRunRegistry) {\n if (tracked.status !== 'running') continue;\n if (actionKey && tracked.actionKey !== actionKey) {\n await this.hydratePageActionByRunId(runId, {\n rowKey: tracked.rowKey ?? undefined,\n actionKey: tracked.actionKey,\n signal: opts.signal,\n });\n const refreshed = this.automationRunRegistry.get(runId);\n if (!refreshed || refreshed.actionKey !== actionKey) continue;\n }\n if (this.pageActionRunAborts.has(runId) || this.pageActionRunStreamPromises.has(runId)) {\n continue;\n }\n const ok = await this.attachPageActionStream(runId, {\n signal: opts.signal,\n rowKey: tracked.rowKey ?? undefined,\n });\n if (ok) attached += 1;\n }\n return attached;\n }\n\n private setPendingPageActionApply(pending: PendingPageActionApply): void {\n const state = this.requireState('setPendingPageActionApply');\n this.pendingPageActionApply = pending;\n writePendingPageActionApply(state.dsn, pending);\n this.bus.emit('pendingPageActionApplyChanged', pending);\n this.pageActionCoordinator.onPendingApplyChanged();\n }\n\n /** @internal exposed for hooks — whether pending matches this page slot */\n matchesPendingPageActionApply(opts: {\n actionKey: string;\n pageContext?: AgentChatPageContext | null;\n }): boolean {\n return matchesPendingPageActionApply(this.getPendingPageActionApply(), opts);\n }\n\n async getDownReasonTags(): Promise<MessageFeedbackDownReasonTag[]> {\n await this.ensureLoggedIn('getDownReasonTags');\n const state = this.requireState('getDownReasonTags');\n if (state.downReasonTagsCache) return state.downReasonTagsCache;\n const items = await state.feedback.getDownReasonTags();\n state.downReasonTagsCache = items;\n return items;\n }\n\n async submitMessageFeedback(\n messageId: string,\n body: UpsertMessageFeedbackBody,\n ): Promise<void> {\n await this.ensureLoggedIn('submitMessageFeedback');\n const state = this.requireState('submitMessageFeedback');\n const sessionId = state.activeSessionId ?? state.session.getSession()?.sessionId ?? null;\n if (!sessionId) {\n throw new AgentChatError('INVALID_OPTIONS', 'submitMessageFeedback: no active session');\n }\n const numericId = parsePersistedMessageId(messageId);\n if (numericId === null) {\n throw new AgentChatError('INVALID_OPTIONS', 'submitMessageFeedback: invalid messageId');\n }\n\n const current = state.messages.find((m) => m.id === messageId);\n if (!current || current.role !== 'agent') {\n throw new AgentChatError('INVALID_OPTIONS', 'submitMessageFeedback: not an assistant message');\n }\n\n const previousFeedback = current.feedback ?? null;\n const optimistic = this.buildOptimisticFeedback(numericId, body);\n this.patchMessageFeedback(state, messageId, optimistic);\n\n try {\n const saved = await state.feedback.upsert(sessionId, numericId, body);\n this.patchMessageFeedback(state, messageId, saved);\n } catch (err) {\n this.patchMessageFeedback(state, messageId, previousFeedback);\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to submit feedback', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n }\n }\n\n async removeMessageFeedback(messageId: string): Promise<void> {\n await this.ensureLoggedIn('removeMessageFeedback');\n const state = this.requireState('removeMessageFeedback');\n const sessionId = state.activeSessionId ?? state.session.getSession()?.sessionId ?? null;\n if (!sessionId) {\n throw new AgentChatError('INVALID_OPTIONS', 'removeMessageFeedback: no active session');\n }\n const numericId = parsePersistedMessageId(messageId);\n if (numericId === null) {\n throw new AgentChatError('INVALID_OPTIONS', 'removeMessageFeedback: invalid messageId');\n }\n\n const current = state.messages.find((m) => m.id === messageId);\n if (!current || current.role !== 'agent') {\n throw new AgentChatError('INVALID_OPTIONS', 'removeMessageFeedback: not an assistant message');\n }\n\n const previousFeedback = current.feedback ?? null;\n this.patchMessageFeedback(state, messageId, null);\n\n try {\n await state.feedback.remove(sessionId, numericId);\n } catch (err) {\n this.patchMessageFeedback(state, messageId, previousFeedback);\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to remove feedback', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n }\n }\n\n /** Internal: read the immutable options snapshot supplied at init time. */\n getOptions(): AgentChatOptions | null {\n return this.state?.options ?? null;\n }\n\n getState(): AgentChatState {\n if (this.stateSnapshot) return this.stateSnapshot;\n if (!this.state) {\n this.stateSnapshot = {\n lifecycle: this.lifecycle,\n dsn: null,\n isOpen: false,\n isClientAuthenticated: false,\n isLoggedIn: false,\n catalogHydrated: false,\n streamingSessionIds: [],\n pendingReplySessionIds: [],\n session: null,\n sessions: [],\n sessionsHasMore: false,\n sessionsLoadingMore: false,\n activeSessionId: null,\n messages: [],\n sessionMessagesHasMore: false,\n sessionMessagesLoadingMore: false,\n agents: [],\n skills: [],\n selectedAgentId: null,\n autoAgent: null,\n selectedSkillId: null,\n agentsLoading: false,\n skillsLoading: false,\n agentsEmptyReason: null,\n lastError: null,\n writeConfirmation: null,\n approvalInbox: {\n items: [],\n loading: false,\n loadingMore: false,\n hasMore: false,\n statusFilter: 'pending',\n pendingCount: 0,\n },\n automationTaskCenter: {\n items: [],\n loading: false,\n loadingMore: false,\n hasMore: false,\n total: 0,\n statusFilter: 'active',\n recentRunIds: [],\n activeCount: 0,\n selectedDetail: null,\n detailLoading: false,\n },\n skillIntentBanner: null,\n skillIntentClarify: null,\n brainClarify: null,\n skillTurnContract: null,\n skillTurnActive: null,\n skillPickerOpen: false,\n pageContext:\n this.pendingPageContext !== undefined ? this.pendingPageContext : null,\n routeContext: this.resolvePendingRouteContext(),\n registeredContextMentions: this.listPendingRegisteredContextMentions(),\n attachPageContext: this.pendingAttachPageContext ?? false,\n activeSessionRun: null,\n pendingGateJobs: this.snapshotPendingGateJobs(),\n };\n } else {\n this.stateSnapshot = {\n lifecycle: this.lifecycle,\n dsn: this.state.dsn,\n isOpen: this.state.isOpen,\n isClientAuthenticated: this.state.isClientAuthenticated,\n isLoggedIn: this.state.isLoggedIn,\n catalogHydrated: this.state.catalogHydrated,\n streamingSessionIds: this.listStreamingSessionIds(this.state),\n pendingReplySessionIds: this.collectSessionsWithPendingReplies(this.state),\n session: this.state.session.getSession(),\n sessions: this.state.sessions,\n sessionsHasMore: this.state.sessionsHasMore,\n sessionsLoadingMore: this.state.sessionsLoadingMore,\n activeSessionId: this.state.activeSessionId,\n messages: [...this.state.messages],\n sessionMessagesHasMore: this.state.activeSessionMessagesHasMore,\n sessionMessagesLoadingMore: this.state.sessionMessagesLoadingMore,\n agents: [...this.state.agents],\n skills: [...this.state.skills],\n selectedAgentId: this.state.selectedAgentId,\n autoAgent: this.state.autoAgent,\n selectedSkillId: this.state.selectedSkillId,\n agentsLoading: this.state.agentsLoading,\n skillsLoading: this.state.skillsLoading,\n agentsEmptyReason: this.state.agentsEmptyReason,\n lastError: this.state.lastError,\n writeConfirmation: this.state.writeConfirmation,\n approvalInbox: {\n items: [...this.state.approvalInboxItems],\n loading: this.state.approvalInboxLoading,\n loadingMore: this.state.approvalInboxLoadingMore,\n hasMore: this.state.approvalInboxHasMore,\n statusFilter: this.state.approvalInboxStatusFilter,\n pendingCount: this.state.approvalInboxPendingCount,\n },\n automationTaskCenter: {\n items: [...this.state.automationTaskItems],\n loading: this.state.automationTaskLoading,\n loadingMore: this.state.automationTaskLoadingMore,\n hasMore: this.state.automationTaskHasMore,\n total: this.state.automationTaskTotal,\n statusFilter: this.state.automationTaskStatusFilter,\n recentRunIds: [...this.state.automationRecentRunIds],\n activeCount: this.state.automationTaskActiveCount,\n selectedDetail: this.state.automationTaskSelectedDetail,\n detailLoading: this.state.automationTaskDetailLoading,\n },\n skillIntentBanner: this.state.skillIntentBanner,\n skillIntentClarify: this.state.skillIntentClarify,\n brainClarify: this.state.brainClarify,\n skillTurnContract: this.state.skillTurnContract,\n skillTurnActive: this.state.skillTurnActive,\n skillPickerOpen: this.state.skillPickerOpen,\n pageContext: this.state.pageContext ?? this.state.options.pageContext ?? null,\n routeContext: this.state.routeContext,\n registeredContextMentions: this.listRegisteredContextMentions(this.state),\n attachPageContext: this.state.attachPageContext,\n activeSessionRun: this.getActiveSessionRunSnapshot(this.state),\n pendingGateJobs: this.snapshotPendingGateJobs(),\n };\n }\n return this.stateSnapshot;\n }\n\n on<K extends keyof AgentChatEventMap>(\n event: K,\n handler: (payload: AgentChatEventMap[K]) => void,\n ): () => void {\n return this.bus.on(event, handler);\n }\n\n off<K extends keyof AgentChatEventMap>(\n event: K,\n handler: (payload: AgentChatEventMap[K]) => void,\n ): void {\n this.bus.off(event, handler);\n }\n\n // ------------------------------------------------------------- internal API\n\n /**\n * Subscribe to internal state changes (open/close, messages, session, error).\n * Used by the UI layer's `useSyncExternalStore` integration.\n */\n subscribeStateChange(listener: () => void): () => void {\n this.stateChangeListeners.add(listener);\n return () => this.stateChangeListeners.delete(listener);\n }\n\n /** Internal: append a message produced outside `sendMessage` (e.g. system). */\n appendMessage(message: AgentMessage): void {\n const state = this.state;\n if (!state) return;\n state.messages = [...state.messages, message];\n this.notifyStateChange();\n this.bus.emit('message', { message, source: message.role });\n }\n\n // ----------------------------------------------------------------- helpers\n\n private applyPendingRuntimeConfig(state: InternalState): void {\n if (this.pendingRouteContextOverride !== undefined) {\n state.routeContextOverride = this.pendingRouteContextOverride;\n this.pendingRouteContextOverride = undefined;\n }\n if (this.pendingPageContext !== undefined) {\n state.pageContext = this.pendingPageContext;\n state.options = { ...state.options, pageContext: this.pendingPageContext ?? undefined };\n this.pendingPageContext = undefined;\n }\n if (this.pendingAttachPageContext !== undefined) {\n state.attachPageContext = this.pendingAttachPageContext;\n state.options = { ...state.options, attachPageContext: this.pendingAttachPageContext };\n this.pendingAttachPageContext = undefined;\n }\n if (this.pendingContextMentionRegistry.size > 0) {\n state.contextMentionRegistry = mergeContextMentionRegistrations(\n state.contextMentionRegistry,\n [...this.pendingContextMentionRegistry.values()],\n false,\n );\n this.pendingContextMentionRegistry = new Map();\n }\n }\n\n private resolvePendingRouteContext(): AgentChatRouteContext | null {\n if (this.pendingRouteContextOverride === undefined) return null;\n const merged = mergeRouteContext(\n readWindowRouteContext(),\n this.pendingRouteContextOverride,\n );\n return Object.keys(merged).length > 0 ? merged : null;\n }\n\n /** Drop write-gate UI superseded by a newer session `generation`. */\n private discardStaleWriteConfirmations(\n state: InternalState,\n sessionId: string,\n generation: number,\n prevGeneration: number,\n ): void {\n const key = normalizeSessionId(sessionId);\n const gate = state.writeConfirmationsBySession.get(key);\n if (!gate) return;\n const stale =\n gate.generation != null\n ? gate.generation < generation\n : generation > prevGeneration;\n if (stale) {\n this.persistWriteConfirmation(state, sessionId, null);\n }\n }\n\n private notifyStateChange(): void {\n this.stateSnapshot = null;\n for (const listener of Array.from(this.stateChangeListeners)) {\n try {\n listener();\n } catch (err) {\n if (this.state?.options.debug) console.error('[agent-chat] state listener threw:', err);\n }\n }\n }\n\n private reportError(err: AgentChatError): void {\n const payload: AgentChatErrorPayload = {\n code: err.code,\n message: err.message,\n cause: (err as { cause?: unknown }).cause,\n };\n if (this.state) {\n this.state.lastError = payload;\n this.notifyStateChange();\n }\n if (this.state?.options.debug && typeof console !== 'undefined') {\n console.error('[agent-chat]', err);\n if (this.bus.listenerCount('error') === 0) {\n console.warn('[agent-chat] Unhandled AgentChat error (no `error` listeners attached)');\n }\n }\n this.bus.emit('error', payload);\n }\n\n /** 等待 init 完成 */\n private ensureInitialized(\n label: string,\n options?: { timeoutMs?: number; signal?: AbortSignal },\n ): Promise<void> {\n return this.initGate.wait({ label, ...options });\n }\n\n /** 等待 init + 登录 — 所有需要 JWT 的 public API 统一入口 */\n private async ensureLoggedIn(\n label: string,\n options?: { timeoutMs?: number; signal?: AbortSignal },\n ): Promise<void> {\n await this.initGate.wait({ label, ...options });\n this.syncAuthFromStore();\n await this.loginGate.wait({ label, ...options });\n }\n\n private requireState(method: string): InternalState {\n if (!this.state) {\n throw new AgentChatError(\n 'NOT_INITIALIZED',\n `AgentChat.${method}() called before init(). Call AgentChat.init({ dsn }) first.`,\n );\n }\n return this.state;\n }\n\n /** Pull pending approval count for launcher badge — best-effort, never throws. */\n private refreshApprovalBadgeBestEffort(): void {\n if (!this.isLoggedIn()) return;\n void this.refreshApprovalPendingCount().catch(() => {\n /* badge sync is best-effort */\n });\n }\n\n /** Pull active automation tasks for badge + pageActionKey reconcile — best-effort. */\n private shouldSkipActiveAutomationReconcile(): boolean {\n if (this.automationTasksLastSyncedAt === 0) return false;\n return Date.now() - this.automationTasksLastSyncedAt < AUTOMATION_RECONCILE_STALE_MS;\n }\n\n private refreshAutomationTasksBestEffort(): void {\n if (!this.isLoggedIn()) return;\n if (this.shouldSkipActiveAutomationReconcile()) return;\n void this.refreshAutomationTasks({ status: 'active', offset: 0 }).catch(() => {\n /* task center sync is best-effort */\n });\n }\n\n /**\n * Defer unscoped active-task fetch so PageAction hook binds can own scoped reconcile first.\n */\n private scheduleAutomationTasksBestEffort(): void {\n const run = () => {\n if (this.pageActionCoordinator.listBindings().length > 0) {\n const state = this.state;\n if (state) this.syncAutomationActiveCount(state);\n return;\n }\n this.refreshAutomationTasksBestEffort();\n };\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(run);\n } else {\n queueMicrotask(run);\n }\n }\n\n private makeAbortController(): AbortController {\n const ctrl = new AbortController();\n this.state?.abortControllers.add(ctrl);\n return ctrl;\n }\n\n /**\n * Warm session runtime + host-tool page cache (`POST /chat/{sessionId}/prepare`).\n * Automatically includes {@link buildPreparePageContext} when the host has set\n * `pageContext.page`. Best-effort: failures are swallowed unless `debug` is on.\n */\n async prepareSession(\n sessionId: string,\n signalOrOptions?: AbortSignal | PrepareSessionOptions,\n ): Promise<PrepareSessionResult | null> {\n await this.ensureLoggedIn('prepareSession');\n const state = this.requireState('prepareSession');\n const id = sessionId.trim();\n if (!id) return null;\n\n const options = normalizePrepareSessionOptions(signalOrOptions);\n const signal = options.signal;\n const pageContext = this.buildPreparePageContext(state);\n const fingerprint = this.buildPrepareFingerprint(id, pageContext);\n\n if (!options.force && fingerprint === this.lastPrepareFingerprint) {\n return null;\n }\n\n try {\n const result = await state.chat.prepareSession(id, pageContext, signal);\n if (signal?.aborted) return null;\n this.lastPrepareFingerprint = fingerprint;\n if (state.options.debug) {\n console.debug(\n '[agent-chat] prepareSession',\n result.pageScope,\n `hostTools=${result.hostToolsCount}`,\n result.fromCache ? 'fromCache' : 'warmed',\n );\n }\n return result;\n } catch (err) {\n if (signal?.aborted) return null;\n if (state.options.debug) {\n console.warn('[agent-chat] prepareSession failed:', err);\n }\n return null;\n }\n }\n\n /** Debounced prepare for the active session after page/route/session changes. */\n private schedulePrepareSession(): void {\n const state = this.state;\n if (!state?.isLoggedIn) return;\n const sessionId = state.activeSessionId?.trim();\n if (!sessionId) return;\n\n this.cancelScheduledPrepare();\n this.prepareAbort = new AbortController();\n const signal = this.prepareAbort.signal;\n\n this.prepareTimer = setTimeout(() => {\n this.prepareTimer = null;\n void this.prepareSession(sessionId, { signal });\n }, 200);\n }\n\n private cancelScheduledPrepare(): void {\n if (this.prepareTimer != null) {\n clearTimeout(this.prepareTimer);\n this.prepareTimer = null;\n }\n if (this.prepareAbort) {\n try {\n this.prepareAbort.abort();\n } catch {\n /* noop */\n }\n this.prepareAbort = null;\n }\n }\n\n /**\n * Page context for prepare — always includes host `page` when set (not gated\n * by {@link attachPageContext}); route fields are always merged.\n */\n private buildPreparePageContext(state: InternalState): AgentChatPageContext | null {\n const out: AgentChatPageContext = {};\n const route = state.routeContext;\n if (route?.routePath) out.routePath = route.routePath;\n if (route?.routeParams && Object.keys(route.routeParams).length > 0) {\n out.routeParams = route.routeParams;\n }\n\n const ext = state.pageContext ?? state.options.pageContext ?? null;\n if (ext?.page) out.page = ext.page;\n if (ext?.flowId != null) out.flowId = ext.flowId;\n if (ext?.programName) out.programName = ext.programName;\n if (ext?.entity) out.entity = ext.entity;\n if (ext?.metadata) out.metadata = ext.metadata;\n\n return Object.keys(out).length > 0 ? out : null;\n }\n\n private buildPrepareFingerprint(\n sessionId: string,\n pageContext: AgentChatPageContext | null,\n ): string {\n return JSON.stringify({\n sessionId: sessionId.trim().toLowerCase(),\n page: pageContext?.page ?? '',\n entityId: pageContext?.entity?.id ?? '',\n entityType: pageContext?.entity?.type ?? '',\n routePath: pageContext?.routePath ?? '',\n routeParams: pageContext?.routeParams ?? null,\n });\n }\n\n /** Delete a chat session (`DELETE /chat/{sessionId}`) and update the sidebar locally. */\n async deleteSession(sessionId: string): Promise<void> {\n await this.ensureLoggedIn('deleteSession');\n const state = this.requireState('deleteSession');\n const id = sessionId.trim();\n if (!id) {\n throw new AgentChatError('INVALID_OPTIONS', 'deleteSession: sessionId is required');\n }\n\n const normalizedId = normalizeSessionId(id);\n const isActive =\n state.activeSessionId != null &&\n normalizeSessionId(state.activeSessionId) === normalizedId;\n\n try {\n await state.chat.deleteSession(id);\n } catch (err) {\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('TRANSPORT_FAILED', 'Failed to delete session', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n }\n\n this.abortSessionStream(state, normalizedId);\n state.writeConfirmationsBySession.delete(normalizedId);\n state.sessionRuns.delete(normalizedId);\n\n for (const key of [...state.sessionMessagesCache.keys()]) {\n if (normalizeSessionId(key) === normalizedId) {\n state.sessionMessagesCache.delete(key);\n }\n }\n\n state.sessions = state.sessions.filter(\n (row) => normalizeSessionId(row.sessionId) !== normalizedId,\n );\n this.notifyStateChange();\n this.bus.emit('sessions', { sessions: state.sessions });\n\n if (isActive) {\n this.sessionEpoch += 1;\n state.activeSessionId = null;\n state.activeSessionMessagesPage = 0;\n state.activeSessionMessagesHasMore = false;\n state.session.reset();\n state.messages = [];\n state.writeConfirmation = null;\n const next = state.sessions[0];\n if (next) {\n await this.selectSession(next.sessionId);\n }\n }\n }\n\n /** Load session list via `GET /chat?page=1&size=` and update sidebar state. */\n async refreshSessions(signal?: AbortSignal): Promise<void> {\n await this.ensureLoggedIn('refreshSessions');\n const state = this.requireState('refreshSessions');\n const page = await this.fetchSessionsPage(state, 1, signal);\n state.sessions = page.sessions;\n state.sessionsPage = page.page;\n state.sessionsHasMore = page.hasMore;\n state.sessionsLoadingMore = false;\n this.notifyStateChange();\n this.bus.emit('sessions', { sessions: state.sessions });\n }\n\n /** Append the next page when the session sidebar is scrolled to the bottom. */\n async loadMoreSessions(signal?: AbortSignal): Promise<void> {\n await this.ensureLoggedIn('loadMoreSessions');\n const state = this.requireState('loadMoreSessions');\n if (!state.sessionsHasMore || state.sessionsLoadingMore) return;\n\n state.sessionsLoadingMore = true;\n this.notifyStateChange();\n try {\n const page = await this.fetchSessionsPage(state, state.sessionsPage + 1, signal);\n state.sessions = mergeSessionSummaries(state.sessions, page.sessions);\n state.sessionsPage = page.page;\n state.sessionsHasMore = page.hasMore;\n this.bus.emit('sessions', { sessions: state.sessions });\n } finally {\n state.sessionsLoadingMore = false;\n this.notifyStateChange();\n }\n }\n\n private async fetchSessionsPage(\n state: InternalState,\n page: number,\n signal?: AbortSignal,\n ) {\n const body = await state.chat.listSessions(page, state.sessionsPageSize, signal);\n return parseChatSessionListPage(body, page, state.sessionsPageSize);\n }\n\n /** Append older messages when the message list is scrolled to the top. */\n async loadMoreSessionMessages(signal?: AbortSignal): Promise<void> {\n await this.ensureLoggedIn('loadMoreSessionMessages');\n const state = this.requireState('loadMoreSessionMessages');\n const sessionId = state.activeSessionId;\n if (!sessionId || !state.activeSessionMessagesHasMore || state.sessionMessagesLoadingMore) {\n return;\n }\n\n state.sessionMessagesLoadingMore = true;\n this.notifyStateChange();\n try {\n const detailPage = await this.fetchSessionMessagesPage(\n state,\n sessionId,\n state.activeSessionMessagesPage + 1,\n signal,\n );\n const older = detailPage.messages.map((m) => this.toAgentMessage(m as ServerMessage));\n const merged = mergeOlderMessages(state.messages, older);\n state.messages = merged;\n state.activeSessionMessagesPage = detailPage.page;\n state.activeSessionMessagesHasMore = detailPage.hasMore;\n state.session.setSession(sessionId, merged);\n this.writeSessionMessagesCache(state, sessionId, merged, detailPage.page, detailPage.hasMore);\n this.notifyStateChange();\n void this.syncMessageFeedbacks(state, sessionId).catch(() => {\n /* feedback sync is best-effort */\n });\n } finally {\n state.sessionMessagesLoadingMore = false;\n this.notifyStateChange();\n }\n }\n\n async selectAgent(agentId: string): Promise<void> {\n await this.ensureLoggedIn('selectAgent');\n const state = this.requireState('selectAgent');\n const id = agentId.trim();\n if (!id) {\n if (!state.selectedAgentId && !state.autoAgent && !state.selectedSkillId) return;\n state.selectedAgentId = null;\n state.autoAgent = null;\n state.selectedSkillId = null;\n state.skills = [];\n state.skillsLoading = false;\n this.notifyStateChange();\n return;\n }\n if (state.selectedAgentId === id && state.autoAgent?.source === 'requested') return;\n\n state.selectedAgentId = id;\n state.autoAgent = { id, source: 'requested', reason: 'selected in UI' };\n state.selectedSkillId = null;\n this.notifyStateChange();\n await this.refreshSkills(id);\n }\n\n selectSkill(skillId: string): void {\n const state = this.requireState('selectSkill');\n const id = skillId.trim();\n if (!id) {\n if (state.selectedSkillId == null) return;\n state.selectedSkillId = null;\n state.skillPickerOpen = false;\n this.notifyStateChange();\n return;\n }\n if (state.selectedSkillId === id) return;\n state.selectedSkillId = id;\n state.skillPickerOpen = false;\n state.skillIntentClarify = null;\n this.notifyStateChange();\n }\n\n dismissSkillIntentBanner(): void {\n const state = this.state;\n if (!state?.skillIntentBanner) return;\n state.skillIntentBanner = null;\n this.notifyStateChange();\n }\n\n clearSkillFromIntentBanner(): void {\n this.selectSkill('');\n const state = this.state;\n if (!state) return;\n state.skillIntentBanner = null;\n this.notifyStateChange();\n }\n\n dismissSkillIntentClarify(): void {\n const state = this.state;\n if (!state?.skillIntentClarify) return;\n state.skillIntentClarify = null;\n this.notifyStateChange();\n }\n\n dismissBrainClarify(): void {\n const state = this.state;\n if (!state?.brainClarify) return;\n state.brainClarify = null;\n this.notifyStateChange();\n }\n\n async commitBrainClarify(selectedId: string): Promise<void> {\n await this.ensureLoggedIn('commitBrainClarify');\n const state = this.requireState('commitBrainClarify');\n const clarify = state.brainClarify;\n if (!clarify) return;\n const id = selectedId.trim();\n if (!id) {\n throw new AgentChatError('INVALID_OPTIONS', 'commitBrainClarify: selectedId required');\n }\n const candidate =\n clarify.brainClarify.candidates.find((row) => row.id === id) ?? null;\n const label = candidate\n ? formatBrainClarifyCandidateLabel(candidate)\n : id;\n const entityCommit = buildEntityCommit(clarify.brainClarify, id);\n state.brainClarify = null;\n this.notifyStateChange();\n try {\n await this.sendMessage(label, { entityCommit });\n } catch (err) {\n // Restore pick UI if send failed (footer was cleared optimistically).\n if (this.state === state && !state.brainClarify) {\n state.brainClarify = clarify;\n this.notifyStateChange();\n }\n throw err;\n }\n }\n\n async followSkillIntentClarify(): Promise<void> {\n await this.ensureLoggedIn('followSkillIntentClarify');\n const state = this.requireState('followSkillIntentClarify');\n const text =\n state.skillIntentClarify?.userMessage?.trim() ?? state.lastTurnUserMessage?.trim() ?? '';\n if (!text) {\n throw new AgentChatError('INVALID_OPTIONS', 'No user message to resend');\n }\n state.skillIntentClarify = null;\n this.selectSkill('');\n await this.sendMessage(text);\n }\n\n openSkillPicker(): void {\n const state = this.state;\n if (!state) return;\n state.skillPickerOpen = true;\n state.skillIntentClarify = null;\n this.notifyStateChange();\n }\n\n closeSkillPicker(): void {\n const state = this.state;\n if (!state?.skillPickerOpen) return;\n state.skillPickerOpen = false;\n this.notifyStateChange();\n }\n\n private resolveSkillName(state: InternalState, skillId: number | undefined): string | undefined {\n if (skillId == null) return undefined;\n const id = String(skillId);\n return state.skills.find((skill) => skill.id === id)?.name;\n }\n\n private clearSkillIntentUi(state: InternalState): void {\n state.skillIntentBanner = null;\n state.skillIntentClarify = null;\n state.brainClarify = null;\n state.skillTurnActive = null;\n }\n\n private applySkillTurnContract(\n state: InternalState,\n contract: SkillTurnContractView,\n input: {\n assistantMessageId: string;\n runId: number;\n steps: ReturnType<typeof resolveAlignmentSteps>;\n },\n ): void {\n const align = contract.skillAlignment;\n const observation = readSkillIntentMismatchObservation(input.steps);\n const skillId =\n contract.requestedSkillId ??\n align.requestedSkillId ??\n observation?.requestedSkillId;\n\n if (shouldShowSkillClarifyCard(contract) && align.code) {\n const userMessage =\n state.lastTurnUserMessage?.trim() ??\n observation?.userMessage?.trim() ??\n '';\n if (!userMessage) return;\n state.skillIntentClarify = {\n code: align.code,\n requestedSkillId: skillId ?? undefined,\n requestedSkillName:\n observation?.requestedSkillName ?? this.resolveSkillName(state, skillId),\n userMessage,\n messageId: input.assistantMessageId,\n runId: input.runId,\n };\n state.skillIntentBanner = null;\n state.skillTurnActive = null;\n return;\n }\n\n if (shouldShowIntentFirstBanner(contract)) {\n state.skillIntentBanner = {\n code: align.code ?? observation?.mismatchCode,\n requestedSkillId: skillId ?? undefined,\n requestedSkillName:\n observation?.requestedSkillName ?? this.resolveSkillName(state, skillId),\n };\n state.skillIntentClarify = null;\n state.skillTurnActive = null;\n return;\n }\n\n if (isRequestedSkillActuallyUsed(contract)) {\n state.skillTurnActive = {\n requestedSkillId: skillId ?? undefined,\n requestedSkillName:\n observation?.requestedSkillName ?? this.resolveSkillName(state, skillId),\n };\n state.skillIntentBanner = null;\n state.skillIntentClarify = null;\n return;\n }\n\n state.skillTurnActive = null;\n }\n\n private applySkillIntentAlignment(\n state: InternalState,\n input: {\n sessionId: string;\n runId: number;\n assistantMessageId: string;\n },\n ): void {\n if (!this.isViewingSession(state, input.sessionId)) return;\n\n void this.loadSkillIntentAlignment(state, input).catch(() => {\n /* best-effort UX hint */\n });\n }\n\n private async loadSkillIntentAlignment(\n state: InternalState,\n input: {\n sessionId: string;\n runId: number;\n assistantMessageId: string;\n },\n ): Promise<void> {\n const appClientId = state.appClientId;\n if (appClientId == null) return;\n\n const body = await state.agentRun.getRun(appClientId, input.runId);\n const detail = parseAgentRunDetail(body);\n if (!detail) return;\n\n const steps = resolveAlignmentSteps(detail);\n const brainClarify = extractBrainClarifyFromRunSteps({ steps });\n if (brainClarify && this.isViewingSession(state, input.sessionId)) {\n state.brainClarify = {\n messageId: input.assistantMessageId,\n runId: input.runId,\n brainClarify,\n };\n } else if (\n state.brainClarify?.runId === input.runId ||\n state.brainClarify?.messageId === input.assistantMessageId\n ) {\n state.brainClarify = null;\n }\n\n const contract = readSkillTurnContract(steps);\n if (!contract) {\n if (brainClarify) this.notifyStateChange();\n return;\n }\n\n state.skillTurnContract = contract;\n this.applySkillTurnContract(state, contract, {\n assistantMessageId: input.assistantMessageId,\n runId: input.runId,\n steps,\n });\n this.notifyStateChange();\n }\n\n async refreshAgentCatalog(signal?: AbortSignal): Promise<void> {\n await this.ensureInitialized('refreshAgentCatalog', { signal });\n const state = this.requireState('refreshAgentCatalog');\n\n if (state.options.agents?.length) {\n state.agents = [...state.options.agents];\n state.agentsEmptyReason = null;\n this.syncDefaultAgentSelection(state);\n if (!state.options.skills?.length) {\n await this.refreshSkills(state.selectedAgentId ?? undefined, signal);\n }\n return;\n }\n\n await this.ensureLoggedIn('refreshAgentCatalog', { signal });\n\n state.agentsLoading = true;\n state.agentsEmptyReason = null;\n this.notifyStateChange();\n try {\n const body = await state.agent.listAvailableAgents(\n state.options.agentListQuery,\n signal,\n );\n const agents = parseAgentList(body);\n state.agents = agents;\n if (agents.length === 0) {\n state.agentsEmptyReason = await this.resolveAgentsEmptyReason(state, signal);\n }\n this.syncDefaultAgentSelection(state);\n await this.refreshSkills(state.selectedAgentId ?? undefined, signal);\n } catch {\n state.agents = [];\n state.agentsEmptyReason = null;\n this.applyStaticSkills(state);\n } finally {\n state.agentsLoading = false;\n this.notifyStateChange();\n }\n }\n\n private async resolveAgentsEmptyReason(\n state: InternalState,\n signal?: AbortSignal,\n ): Promise<AgentsEmptyReason> {\n try {\n const allBody = await state.agent.listAllClientAgents(signal);\n const allAgents = parseAgentList(allBody);\n return allAgents.length > 0 ? 'permission' : 'not_configured';\n } catch {\n return null;\n }\n }\n\n private async refreshSkills(agentId?: string, signal?: AbortSignal): Promise<void> {\n const state = this.requireState('refreshSkills');\n const normalizedAgentId = agentId?.trim() || state.selectedAgentId || undefined;\n const loadToken = ++this.skillsLoadToken;\n\n if (state.options.skills?.length) {\n state.skills = normalizedAgentId\n ? state.options.skills.filter(\n (skill) => !skill.agentId || skill.agentId === normalizedAgentId,\n )\n : [...state.options.skills];\n this.syncDefaultSkillSelection(state);\n this.notifyStateChange();\n return;\n }\n\n if (!normalizedAgentId) {\n state.skills = [];\n state.selectedSkillId = null;\n this.notifyStateChange();\n return;\n }\n\n state.skillsLoading = true;\n this.notifyStateChange();\n const isCurrentSkillsLoad = () => loadToken === this.skillsLoadToken;\n try {\n const pageContext = state.pageContext ?? state.options.pageContext ?? null;\n const query = buildClientSkillListQuery(state.options.skillListQuery, pageContext);\n const body = await state.agent.listClientSkills(normalizedAgentId, query, signal);\n if (!isCurrentSkillsLoad()) return;\n state.skills = parseSkillList(body);\n this.syncDefaultSkillSelection(state);\n } catch {\n if (isCurrentSkillsLoad()) {\n state.skills = [];\n state.selectedSkillId = null;\n }\n } finally {\n if (isCurrentSkillsLoad()) {\n state.skillsLoading = false;\n this.notifyStateChange();\n }\n }\n }\n\n private applyStaticSkills(state: InternalState): void {\n const staticSkills = state.options.skills;\n if (!staticSkills?.length) return;\n const agentId = state.selectedAgentId;\n state.skills = agentId\n ? staticSkills.filter((skill) => !skill.agentId || skill.agentId === agentId)\n : [...staticSkills];\n this.syncDefaultSkillSelection(state);\n }\n\n private syncDefaultAgentSelection(state: InternalState): void {\n const defaultAgentId = state.options.defaultAgentId?.trim();\n if (state.selectedAgentId && state.agents.length > 0) {\n if (!state.agents.some((agent) => agent.id === state.selectedAgentId)) {\n state.selectedAgentId =\n defaultAgentId && state.agents.some((agent) => agent.id === defaultAgentId)\n ? defaultAgentId\n : null;\n if (!state.selectedAgentId) {\n state.selectedSkillId = null;\n }\n }\n } else if (defaultAgentId && state.agents.some((agent) => agent.id === defaultAgentId)) {\n state.selectedAgentId = defaultAgentId;\n }\n this.applyStaticSkills(state);\n }\n\n private applyAutoAgentBinding(\n state: InternalState,\n binding: AutoAgentBinding | null | undefined,\n ): void {\n if (!binding?.id) return;\n const previousAgentId = state.selectedAgentId;\n state.autoAgent = binding;\n state.selectedAgentId = binding.id;\n if (previousAgentId !== binding.id) {\n state.selectedSkillId = null;\n void this.refreshSkills(binding.id).catch(() => {\n /* skill refresh after Auto-Agent binding is best-effort */\n });\n }\n }\n\n private syncDefaultSkillSelection(state: InternalState): void {\n const defaultSkillId = state.options.defaultSkillId?.trim();\n if (\n state.selectedSkillId &&\n state.skills.some((skill) => skill.id === state.selectedSkillId)\n ) {\n return;\n }\n if (defaultSkillId && state.skills.some((skill) => skill.id === defaultSkillId)) {\n state.selectedSkillId = defaultSkillId;\n return;\n }\n\n const pageScope = this.getPageScope(state);\n if (pageScope) {\n const pageDefault = resolveDefaultSkillId(state.skills);\n state.selectedSkillId = pageDefault ?? null;\n return;\n }\n\n state.selectedSkillId = state.skills[0]?.id ?? null;\n }\n\n private getPageScope(state: InternalState): string {\n return (state.pageContext?.page ?? state.options.pageContext?.page ?? '').trim();\n }\n\n private syncActiveWriteConfirmation(state: InternalState, sessionId: string): void {\n const key = normalizeSessionId(sessionId);\n state.writeConfirmation = state.writeConfirmationsBySession.get(key) ?? null;\n }\n\n private persistWriteConfirmation(\n state: InternalState,\n sessionId: string,\n confirmation: WriteConfirmationState | null,\n ): void {\n const key = normalizeSessionId(sessionId);\n if (confirmation) {\n state.writeConfirmationsBySession.set(key, confirmation);\n } else {\n state.writeConfirmationsBySession.delete(key);\n }\n if (this.isViewingSession(state, sessionId)) {\n state.writeConfirmation = confirmation;\n }\n }\n\n private maybeNotifyBackgroundReply(state: InternalState, sessionId: string): void {\n if (state.isOpen && this.isViewingSession(state, sessionId)) return;\n const normalizedId = normalizeSessionId(sessionId);\n const session = state.sessions.find(\n (item) => normalizeSessionId(item.sessionId) === normalizedId,\n );\n this.bus.emit('backgroundReplyReady', {\n sessionId: normalizedId,\n sessionTitle: session?.title ?? null,\n });\n }\n\n private emitHostAction(\n state: InternalState,\n action: AgentChatHostAction,\n phase: 'streaming' | 'complete' = 'complete',\n options?: { skipToolExecution?: boolean },\n ): void {\n const isStreaming = phase === 'streaming';\n if (isStreaming) return;\n if (!isDispatchableHostAction(action)) return;\n\n const enriched: AgentChatHostAction = {\n ...action,\n sessionId: action.sessionId ?? state.activeSessionId ?? undefined,\n streamPhase: action.streamPhase ?? phase,\n };\n this.bus.emit('hostAction', { action: enriched, phase: 'complete' });\n\n void (async () => {\n await dispatchHostAction(enriched);\n if (!options?.skipToolExecution) {\n await executeHostToolsFromAction(enriched);\n }\n })().catch((err) => {\n if (state.options.debug) {\n console.warn('[agent-chat] hostAction dispatch failed:', err);\n }\n });\n }\n\n private emitPageAgentLifecycle(payload: PageAgentLifecyclePayload): void {\n this.bus.emit('pageAgentLifecycle', payload);\n }\n\n private emitPageAgentCompleteFromAction(\n action: AgentChatHostAction,\n source: PageAgentSource,\n ): void {\n const scope = action.scope?.trim();\n if (!scope) return;\n this.emitPageAgentLifecycle({\n type: 'complete',\n context: {\n scope,\n source,\n hostTools: action.hostTools,\n action,\n entity: action.entity,\n reason: action.reason,\n },\n });\n }\n\n private emitPageAgentError(\n scope: string | undefined,\n source: PageAgentSource,\n phase: PageAgentErrorContext['phase'],\n err: unknown,\n ): void {\n const message =\n err instanceof AgentChatError\n ? err.message\n : err instanceof Error\n ? err.message\n : String(err);\n const code = err instanceof AgentChatError ? err.code : undefined;\n this.emitPageAgentLifecycle({\n type: 'error',\n context: {\n scope,\n source,\n phase,\n code,\n message,\n },\n });\n }\n\n private buildHostActionPageGate(state: InternalState): {\n page?: string;\n entity?: { type?: string; id?: string | number };\n } {\n const ext = state.pageContext ?? state.options.pageContext ?? null;\n return {\n ...(ext?.page ? { page: ext.page } : {}),\n ...(ext?.entity ? { entity: ext.entity } : {}),\n };\n }\n\n private getHostToolStreamManager(\n state: InternalState,\n sessionId: string,\n pageGate?: PageContextGate,\n ): HostToolStreamManager {\n const key = normalizeSessionId(sessionId);\n const gate = pageGate ?? this.buildHostActionPageGate(state);\n let manager = this.hostToolStreamManagers.get(key);\n if (!manager) {\n manager = new HostToolStreamManager({\n pageContext: gate,\n sessionId,\n debug: state.options.debug,\n });\n this.hostToolStreamManagers.set(key, manager);\n } else {\n manager.updateOptions({\n pageContext: gate,\n sessionId,\n debug: state.options.debug,\n });\n }\n return manager;\n }\n\n private ingestHostActionSse(\n state: InternalState,\n sessionId: string,\n payload: HostActionSsePayload,\n pageGate?: PageContextGate,\n source: PageAgentSource = 'chat',\n ): void {\n if (!isHostToolStreamEnabled(state.options.hostToolStream, payload)) {\n const action = hostActionSseToAgentAction(payload, sessionId);\n if (action) {\n this.emitHostAction(state, action);\n this.emitPageAgentCompleteFromAction(action, source);\n }\n return;\n }\n\n if (!isHostActionStreamPayload(payload)) {\n const action = hostActionSseToAgentAction(payload, sessionId);\n if (action) {\n this.getHostToolStreamManager(state, sessionId, pageGate).reset();\n this.emitHostAction(state, action);\n this.emitPageAgentCompleteFromAction(action, source);\n }\n return;\n }\n\n const manager = this.getHostToolStreamManager(state, sessionId, pageGate);\n manager.ingest(payload, {\n source,\n emitLifecycle: (lifecycle) => this.emitPageAgentLifecycle(lifecycle),\n emitHostAction: (action, phase, options) => {\n this.emitHostAction(state, action, phase, options);\n },\n });\n }\n\n private acquirePageActionLock(clientActionId: string | undefined): string | null {\n const id = clientActionId?.trim();\n if (!id) return null;\n if (this.pageActionInFlightKeys.has(id)) {\n throw new AgentChatError(\n 'INVALID_OPTIONS',\n `Page action invoke already in flight for clientActionId: ${id}`,\n );\n }\n this.pageActionInFlightKeys.add(id);\n return id;\n }\n\n private releasePageActionLock(lockKey: string | null): void {\n if (lockKey) this.pageActionInFlightKeys.delete(lockKey);\n }\n\n private requirePageActionKey(\n input: Pick<PageBotInvokeInput, 'actionKey'>,\n ): string {\n const actionKey = input.actionKey?.trim();\n if (!actionKey) {\n throw new AgentChatError('INVALID_OPTIONS', 'Page action: actionKey is required');\n }\n return actionKey;\n }\n\n private resolvePageActionStreamSessionKey(\n input: PageBotInvokeInput,\n runId?: number,\n ): string {\n const clientActionId = input.clientActionId?.trim();\n if (clientActionId) {\n return `${PAGE_ACTION_STREAM_KEY_PREFIX}${clientActionId}`;\n }\n if (runId != null) {\n return `${PAGE_ACTION_STREAM_KEY_PREFIX}${runId}`;\n }\n return `${PAGE_ACTION_STREAM_KEY_PREFIX}${nanoId()}`;\n }\n\n private releasePageActionStreamManager(sessionKey: string): void {\n this.hostToolStreamManagers.delete(normalizeSessionId(sessionKey));\n }\n\n private resolvePageActionContext(\n state: InternalState,\n input: PageBotInvokeInput,\n ): AgentChatPageContext | undefined {\n const fromState = state.pageContext ?? state.options.pageContext ?? null;\n const fromInput = input.pageContext;\n if (fromInput && fromState) {\n return { ...fromState, ...fromInput };\n }\n return fromInput ?? fromState ?? undefined;\n }\n\n private buildPageActionInvokeBody(\n state: InternalState,\n input: PageBotInvokeInput,\n ): InvokePageActionRequest {\n const actionKey = this.requirePageActionKey(input);\n const pageContext = buildPageActionInvokePageContextSnapshot({\n pageContext: this.resolvePageActionContext(state, input),\n routeContext: state.routeContext,\n });\n const body: InvokePageActionRequest = { actionKey };\n if (pageContext) body.pageContext = pageContext;\n if (input.instruction?.trim()) body.instruction = input.instruction.trim();\n if (input.context && Object.keys(input.context).length > 0) {\n body.context = input.context;\n }\n if (input.idempotencyKey?.trim()) body.idempotencyKey = input.idempotencyKey.trim();\n if (input.clientActionId?.trim()) body.clientActionId = input.clientActionId.trim();\n if (input.entityCommit?.entityType?.trim() && input.entityCommit?.selectedId?.trim()) {\n body.entityCommit = {\n entityType: input.entityCommit.entityType.trim(),\n selectedId: input.entityCommit.selectedId.trim(),\n };\n }\n return body;\n }\n\n /**\n * Hint + popover gate. Returns a result when reuse/cancel handled the click;\n * `null` means fall through to a fresh invoke (no items, or user chose rerun).\n */\n private async tryPageActionReusePrompt(\n state: InternalState,\n input: PageBotInvokeInput,\n rowKey: string | null,\n opts: {\n body: InvokePageActionRequest;\n cached: PageActionReuseHint | null;\n },\n ): Promise<PageBotStreamResult | null> {\n const handler = this.pageActionReusePromptHandler;\n if (!handler) return null;\n\n let hint = opts.cached;\n if (!hint) {\n try {\n hint = await state.pageAction.reuseHint(opts.body, input.signal);\n this.pageActionReuseHintCache.set(opts.body, hint);\n } catch {\n // Hint is best-effort — never block a real invoke.\n return null;\n }\n }\n\n if (hint.reusable.total <= 0 || hint.reusable.items.length === 0) {\n return null;\n }\n\n if (rowKey) {\n const prev = this.pageActionRows.get(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: prev?.runId ?? null,\n pageActionKey: hint.pageActionKey,\n phase: 'awaiting_reuse',\n error: null,\n message: null,\n progressLabel: null,\n approvalRequestId: prev?.approvalRequestId ?? null,\n }),\n );\n }\n\n const prompt: PageActionReusePromptRequest = {\n actionKey: hint.actionKey,\n pageActionKey: hint.pageActionKey,\n items: hint.reusable.items,\n sourceRect: readLaunchSourceRect(input.launchAnchor),\n launchAnchor: input.launchAnchor ?? null,\n invokeSnapshot: {\n pageContext: input.pageContext,\n instruction: input.instruction,\n context: input.context,\n clientActionId: input.clientActionId,\n idempotencyKey: input.idempotencyKey,\n rowKey: rowKey ?? input.rowKey,\n awaitStream: input.awaitStream,\n },\n };\n\n const decision = await handler(prompt);\n if (decision.type === 'rerun') {\n // Fall through to a fresh POST /page-action/brain-invoke in invokePageAction.\n this.pageActionReuseHintCache.invalidateByBody(opts.body);\n if (rowKey) {\n const prev = this.pageActionRows.get(rowKey);\n this.clearPageActionNarrativeClearTimer(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: prev?.runId ?? null,\n pageActionKey: prev?.pageActionKey ?? hint.pageActionKey,\n phase: 'submitting',\n error: null,\n message: null,\n progressLabel: defaultPageActionProgressLabel(this.state?.options.locale),\n narrativeItems: [],\n approvalRequestId: prev?.approvalRequestId ?? null,\n }),\n );\n }\n return null;\n }\n\n if (decision.type === 'cancel') {\n // Keep cache — closing the popover must not force another reuse-hint.\n if (rowKey) {\n const prev = this.pageActionRows.get(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: prev?.runId ?? null,\n pageActionKey: prev?.pageActionKey ?? hint.pageActionKey,\n phase: 'idle',\n loading: false,\n disabled: false,\n error: null,\n message: null,\n progressLabel: null,\n approvalRequestId: prev?.approvalRequestId ?? null,\n }),\n );\n }\n return {\n actionRunId: 0,\n text: '',\n dslOutcome: null,\n actionKey: input.actionKey.trim(),\n clientActionId: input.clientActionId,\n cancelled: true,\n };\n }\n\n const item =\n hint.reusable.items.find((row) => row.ref.id === decision.runId) ??\n hint.reusable.items[0];\n if (!item) return null;\n\n return this.applyPageActionReuse(input, rowKey, hint, item);\n }\n\n private async applyPageActionReuse(\n input: PageBotInvokeInput,\n rowKey: string | null,\n hint: PageActionReuseHint,\n item: PageActionReusableItem,\n ): Promise<PageBotStreamResult> {\n const runId = item.ref.id;\n const locale = this.state?.options.locale;\n const tip = pageActionReusedMessage(locale);\n const actionKey = input.actionKey.trim();\n const dismissEpoch = rowKey\n ? (this.pageActionReuseDismissEpochByRowKey.get(rowKey) ?? 0)\n : 0;\n\n const wasDismissed = () =>\n rowKey != null &&\n (this.pageActionReuseDismissEpochByRowKey.get(rowKey) ?? 0) !== dismissEpoch;\n\n const setRow = (patch: {\n phase: PageActionPhase;\n loading?: boolean;\n disabled?: boolean;\n error?: string | null;\n message?: string | null;\n progressLabel?: string | null;\n }) => {\n if (!rowKey || wasDismissed()) return;\n const prev = this.pageActionRows.get(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey,\n runId,\n pageActionKey: hint.pageActionKey,\n phase: patch.phase,\n loading: patch.loading,\n disabled: patch.disabled,\n error: patch.error ?? null,\n message: patch.message ?? null,\n progressLabel: patch.progressLabel ?? null,\n approvalRequestId: prev?.approvalRequestId ?? null,\n }),\n );\n };\n\n // Selecting a historical run must actually apply it (replay), not only show a tip.\n setRow({\n phase: 'streaming',\n loading: true,\n disabled: true,\n progressLabel: pageActionReusingLabel(locale),\n message: null,\n error: null,\n });\n\n this.bus.emit('pageActionApplyStarted', {\n runId,\n actionKey,\n rowKey,\n });\n\n let text =\n item.outputs.fillText?.trim() ||\n item.outputs.preview?.trim() ||\n '';\n\n try {\n const detail = await this.getAutomationTaskDetail(runId, input.signal);\n if (wasDismissed()) {\n return {\n actionRunId: runId,\n text: '',\n dslOutcome: null,\n actionKey,\n clientActionId: input.clientActionId,\n cancelled: true,\n reused: true,\n };\n }\n if (!detail || detail.ref.kind !== 'page_action_run') {\n throw new AgentChatError(\n 'PAGE_ACTION_FAILED',\n `PageAction run ${runId} not found`,\n );\n }\n if (detail.taskStatus !== 'completed') {\n throw new AgentChatError(\n 'PAGE_ACTION_FAILED',\n `PageAction run ${runId} is not completed`,\n );\n }\n\n const detailText =\n detail.outputs.preview?.trim() ||\n text;\n if (detailText) text = detailText;\n\n const canReplay =\n detail.replay.canReplay ||\n detail.outputs.hasFillText === true ||\n Boolean(text);\n\n if (canReplay && (detail.replay.canReplay || detail.outputs.hasFillText)) {\n // 有 fill 产出:走 stream replay(服务端会尽量重放 host_action)\n await this.replayPageAction(runId, { signal: input.signal });\n if (wasDismissed()) {\n return {\n actionRunId: runId,\n text: '',\n dslOutcome: null,\n actionKey,\n clientActionId: input.clientActionId,\n cancelled: true,\n reused: true,\n };\n }\n // 宿主若挂了 onChunk,再补一份全文(分析页 / 无 host tool 时也能看到)\n if (text && input.onChunk) {\n try {\n input.onChunk(text);\n } catch {\n /* host onChunk must not break reuse */\n }\n }\n } else if (text && input.onChunk) {\n input.onChunk(text);\n this.bus.emit('pageActionApplyCompleted', {\n runId,\n actionKey,\n rowKey,\n });\n } else {\n // 无可重放 fill、也无 onChunk:打开任务中心看详情,避免「点了没效果」\n this.openAutomationTaskCenter({ runId });\n this.bus.emit('pageActionApplyCompleted', {\n runId,\n actionKey,\n rowKey,\n });\n }\n\n setRow({\n phase: 'completed',\n loading: false,\n disabled: false,\n message: tip,\n progressLabel: null,\n error: null,\n });\n if (rowKey && !wasDismissed()) this.schedulePageActionRowIdleReset(rowKey, 1_800);\n\n return {\n actionRunId: runId,\n text,\n dslOutcome: detail.replay.dslOutcome,\n actionKey,\n clientActionId: input.clientActionId,\n message: tip,\n reused: true,\n };\n } catch (err) {\n if (wasDismissed()) {\n return {\n actionRunId: runId,\n text: '',\n dslOutcome: null,\n actionKey,\n clientActionId: input.clientActionId,\n cancelled: true,\n reused: true,\n };\n }\n const message = err instanceof Error ? err.message : String(err);\n setRow({\n phase: 'failed',\n loading: false,\n disabled: false,\n error: message,\n message: null,\n progressLabel: null,\n });\n if (rowKey) this.schedulePageActionRowIdleReset(rowKey, 1_600);\n this.bus.emit('pageActionRunFailed', {\n runId,\n actionKey,\n rowKey,\n errorMessage: message,\n });\n throw err instanceof AgentChatError\n ? err\n : new AgentChatError('PAGE_ACTION_FAILED', message);\n }\n }\n\n private async invokePageActionStream(\n state: InternalState,\n input: PageBotInvokeInput,\n rowKey: string | null = null,\n ): Promise<PageBotStreamResult> {\n const pageContext = this.resolvePageActionContext(state, input);\n const pageGate = pageGateFromPageContext(pageContext);\n const requestBody = this.buildPageActionInvokeBody(state, input);\n const resolvedRowKey = rowKey ?? this.resolveInvokeRowKey(input);\n\n let invokeResult;\n try {\n invokeResult = await state.pageAction.invoke(requestBody, input.signal);\n } catch (err) {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim();\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n rethrowPageActionError(err);\n }\n\n if (invokeResult.kind === 'already_active') {\n const active = invokeResult;\n const accepted: InvokePageActionAccepted = {\n runId: active.existingRunId,\n generation: active.existingRunId,\n clientActionId: input.clientActionId?.trim() ?? null,\n pageActionKey: active.pageActionKey,\n streamUrl: active.streamUrl,\n status: active.existingStatus,\n };\n this.registerAutomationRun(accepted.runId, {\n actionKey: input.actionKey,\n accepted,\n pageActionKey: active.pageActionKey,\n rowKey: resolvedRowKey,\n });\n\n const tip =\n active.existingStatus === 'awaiting_approval'\n ? pageActionAlreadyAwaitingApprovalTip(this.state?.options.locale)\n : pageActionAlreadyRunningTip(this.state?.options.locale);\n\n if (resolvedRowKey) {\n this.syncPageActionRowFromAccepted(resolvedRowKey, input.actionKey, accepted, {\n approvalRequestId: active.approvalRequestId,\n message: tip,\n });\n }\n\n this.bus.emit('pageActionSoftNotice', {\n kind:\n active.existingStatus === 'awaiting_approval'\n ? 'already_awaiting_approval'\n : 'already_running',\n message: tip,\n runId: accepted.runId,\n actionKey: input.actionKey,\n approvalRequestId: active.approvalRequestId,\n });\n\n // Already paused for approval — notify once and skip run SSE (no progress until decided).\n if (active.existingStatus === 'awaiting_approval') {\n const result = this.buildEarlyPageActionResult(accepted, {\n actionKey: input.actionKey,\n approvalRequestId: active.approvalRequestId,\n message: tip,\n alreadyActive: true,\n });\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, result);\n return result;\n }\n\n // Duplicate running invoke: attach SSE in background, return tip immediately\n // (even when awaitStream is true — do not block on the existing run).\n const streamPromise = this.consumePageActionRunStream(\n state,\n input,\n accepted,\n pageGate,\n pageContext,\n );\n void streamPromise\n .then((result) => {\n if (result?.awaitingApproval) {\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, {\n ...result,\n approvalRequestId: result.approvalRequestId ?? active.approvalRequestId,\n });\n }\n })\n .catch((err) => {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim();\n this.markTrackedAutomationRunFailed(accepted.runId, input.actionKey);\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n });\n return this.buildEarlyPageActionResult(accepted, {\n actionKey: input.actionKey,\n approvalRequestId: active.approvalRequestId,\n message: tip,\n alreadyActive: true,\n });\n }\n\n const accepted = invokeResult;\n this.registerAutomationRun(accepted.runId, {\n actionKey: input.actionKey,\n accepted,\n pageActionKey: accepted.pageActionKey,\n rowKey: resolvedRowKey,\n });\n if (resolvedRowKey) {\n this.syncPageActionRowFromAccepted(resolvedRowKey, input.actionKey, accepted);\n }\n this.rememberPageActionInvokeSnapshot(input, resolvedRowKey, accepted.runId);\n const payload: PageActionSubmittedPayload = {\n ...accepted,\n sourceRect: readLaunchSourceRect(input.launchAnchor),\n launchAnchor: input.launchAnchor ?? null,\n rowKey: resolvedRowKey,\n actionKey: input.actionKey.trim(),\n };\n this.bus.emit('pageActionSubmitted', payload);\n\n const awaitStream = input.awaitStream !== false;\n const streamPromise = this.consumePageActionRunStream(\n state,\n input,\n accepted,\n pageGate,\n pageContext,\n );\n if (!awaitStream) {\n void streamPromise\n .then((result) => {\n if (result?.awaitingApproval) {\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, result);\n }\n // Brain clarify is emitted from applyPageActionRunLifecycle; no extra work.\n })\n .catch((err) => {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim();\n this.markTrackedAutomationRunFailed(accepted.runId, input.actionKey);\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n });\n const early = this.buildEarlyPageActionResult(accepted, { actionKey: input.actionKey });\n if (early.awaitingApproval) {\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, early);\n }\n return early;\n }\n\n try {\n return await streamPromise;\n } catch (err) {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim();\n this.markTrackedAutomationRunFailed(accepted.runId, input.actionKey);\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n rethrowPageActionError(err);\n }\n }\n\n private buildEarlyPageActionResult(\n accepted: InvokePageActionAccepted,\n meta?: {\n actionKey?: string;\n approvalRequestId?: number | null;\n message?: string | null;\n alreadyActive?: boolean;\n },\n ): PageBotStreamResult {\n const awaitingApproval = accepted.status === 'awaiting_approval';\n return {\n actionRunId: accepted.runId,\n text: '',\n dslOutcome: null,\n awaitingApproval: awaitingApproval ? true : undefined,\n status: awaitingApproval ? 'awaiting_approval' : undefined,\n actionKey: meta?.actionKey,\n clientActionId: accepted.clientActionId ?? undefined,\n approvalRequestId: meta?.approvalRequestId ?? null,\n message: meta?.message ?? null,\n alreadyActive: meta?.alreadyActive === true ? true : undefined,\n };\n }\n\n /**\n * Duplicate invoke (local row still active): soft message, no throw.\n * Existing SSE from the first invoke continues to drive row phase.\n */\n private finishAlreadyActiveInvoke(\n input: PageBotInvokeInput,\n rowKey: string,\n _meta: { source: 'local' },\n ): PageBotStreamResult {\n const row = this.pageActionRows.get(rowKey);\n const awaitingApproval = row?.awaitingApproval === true || row?.phase === 'awaiting_approval';\n const tip = awaitingApproval\n ? pageActionAlreadyAwaitingApprovalTip(this.state?.options.locale)\n : pageActionAlreadyRunningTip(this.state?.options.locale);\n\n if (row) {\n const { loading: _loading, disabled: _disabled, ...rest } = row;\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...rest,\n error: null,\n message: tip,\n }),\n );\n }\n\n this.bus.emit('pageActionSoftNotice', {\n kind: awaitingApproval ? 'already_awaiting_approval' : 'already_running',\n message: tip,\n runId: row?.runId ?? null,\n actionKey: input.actionKey.trim(),\n approvalRequestId: row?.approvalRequestId ?? null,\n });\n\n if (awaitingApproval && row?.runId != null) {\n if (!this.pageActionAwaitingApprovalNotified.has(row.runId)) {\n this.pageActionAwaitingApprovalNotified.add(row.runId);\n this.bus.emit('pageActionAwaitingApproval', {\n actionRunId: row.runId,\n actionKey: input.actionKey.trim(),\n approvalRequestId: row.approvalRequestId ?? null,\n });\n }\n }\n\n return {\n actionRunId: row?.runId ?? 0,\n text: '',\n dslOutcome: null,\n awaitingApproval: awaitingApproval ? true : undefined,\n status: awaitingApproval ? 'awaiting_approval' : undefined,\n actionKey: input.actionKey.trim(),\n clientActionId: input.clientActionId?.trim() || undefined,\n approvalRequestId: row?.approvalRequestId ?? null,\n message: tip,\n alreadyActive: true,\n };\n }\n\n private async consumePageActionRunStream(\n state: InternalState,\n input: PageBotInvokeInput,\n accepted: InvokePageActionAccepted,\n pageGate: PageContextGate,\n pageContext: AgentChatPageContext | null | undefined,\n ): Promise<PageBotStreamResult> {\n const existing = this.pageActionRunStreamPromises.get(accepted.runId);\n if (existing) {\n return existing;\n }\n\n const runPromise = this.runPageActionConsumeStream(\n state,\n input,\n accepted,\n pageGate,\n pageContext,\n ).finally(() => {\n if (this.pageActionRunStreamPromises.get(accepted.runId) === runPromise) {\n this.pageActionRunStreamPromises.delete(accepted.runId);\n }\n });\n this.pageActionRunStreamPromises.set(accepted.runId, runPromise);\n return runPromise;\n }\n\n private async runPageActionConsumeStream(\n state: InternalState,\n input: PageBotInvokeInput,\n accepted: InvokePageActionAccepted,\n pageGate: PageContextGate,\n pageContext: AgentChatPageContext | null | undefined,\n ): Promise<PageBotStreamResult> {\n const sessionKey = this.resolvePageActionStreamSessionKey(input, accepted.runId);\n this.getHostToolStreamManager(state, sessionKey, pageGate).reset();\n\n const runAbort = new AbortController();\n this.pageActionRunAborts.set(accepted.runId, runAbort);\n if (input.signal) {\n if (input.signal.aborted) runAbort.abort();\n else {\n input.signal.addEventListener('abort', () => runAbort.abort(), { once: true });\n }\n }\n\n try {\n const stream = state.pageAction.streamRun(accepted.runId, runAbort.signal);\n const result = await consumePageActionRunStream(stream, {\n onHostAction: (payload) => {\n this.ingestHostActionSse(state, sessionKey, payload, pageGate, 'page_action');\n },\n onChunk: input.onChunk,\n onLifecycle: (lifecycle) => {\n this.applyPageActionRunLifecycle(state, lifecycle);\n },\n onWorkflowProgress: (event) => {\n this.syncPageActionRowFromWorkflow(event);\n },\n debug: state.options.debug,\n });\n if (result.awaitingApproval) {\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, result);\n }\n this.bus.emit('automationTaskCenterChanged', undefined);\n return result;\n } finally {\n this.pageActionRunAborts.delete(accepted.runId);\n this.releasePageActionStreamManager(sessionKey);\n }\n }\n\n private notifyPageActionAwaitingApproval(\n pageGate: PageContextGate,\n pageContext: AgentChatPageContext | null | undefined,\n input: PageBotInvokeInput,\n result: PageBotStreamResult,\n ): void {\n const runId = result.actionRunId;\n if (typeof runId === 'number' && Number.isFinite(runId)) {\n if (this.pageActionAwaitingApprovalNotified.has(runId)) {\n return;\n }\n this.pageActionAwaitingApprovalNotified.add(runId);\n }\n this.emitPageActionAwaitingApproval(pageGate, pageContext, input, result);\n const rowKey =\n input.rowKey?.trim() ||\n resolvePageActionRowKey({\n rowKey: input.rowKey,\n entityId: pageContext?.entity?.id ?? null,\n }) ||\n (typeof result.actionRunId === 'number'\n ? this.pageActionRunToRowKey.get(result.actionRunId)\n : null);\n if (rowKey) {\n const prev = this.pageActionRows.get(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: result.actionKey ?? input.actionKey,\n runId: result.actionRunId ?? prev?.runId ?? null,\n pageActionKey: prev?.pageActionKey ?? null,\n phase: 'awaiting_approval',\n error: null,\n message: prev?.message ?? null,\n progressLabel:\n prev?.progressLabel ??\n resolvePageWorkflowProgressLabel(\n {\n phase: 'awaiting_approval',\n actionRunId: result.actionRunId ?? prev?.runId ?? 0,\n actionKey: (result.actionKey ?? input.actionKey).trim(),\n generation: 0,\n nodeId: '',\n stageKind: 'other',\n },\n this.state?.options.locale,\n ),\n narrativeItems: prev?.narrativeItems ?? [],\n approvalRequestId: result.approvalRequestId ?? null,\n brainClarify: prev?.brainClarify ?? null,\n }),\n );\n }\n this.bus.emit('pageActionAwaitingApproval', {\n actionRunId: result.actionRunId,\n actionKey: result.actionKey ?? input.actionKey,\n approvalRequestId: result.approvalRequestId ?? null,\n });\n }\n\n private rememberPageActionInvokeSnapshot(\n input: PageBotInvokeInput,\n rowKey: string | null,\n runId?: number | null,\n ): void {\n const snapshot: PageActionBrainClarifyInvokeSnapshot & {\n launchAnchor?: HTMLElement | null;\n } = {\n pageContext: input.pageContext,\n instruction: input.instruction,\n context: input.context,\n clientActionId: input.clientActionId,\n idempotencyKey: input.idempotencyKey,\n rowKey: input.rowKey ?? rowKey ?? undefined,\n awaitStream: input.awaitStream,\n launchAnchor: input.launchAnchor ?? null,\n };\n if (rowKey) {\n this.pageActionInvokeSnapshotsByRowKey.set(rowKey, snapshot);\n }\n if (typeof runId === 'number' && Number.isFinite(runId)) {\n this.pageActionInvokeSnapshotsByRunId.set(Math.trunc(runId), snapshot);\n }\n }\n\n private emitPageActionBrainClarify(\n _state: InternalState,\n lifecycle: PageActionSseLifecycle,\n rowKey: string | null,\n ): void {\n if (!lifecycle.brainClarify) return;\n this.emitPageActionBrainClarifyFromPayload({\n actionKey: lifecycle.actionKey,\n runId: lifecycle.actionRunId,\n brainClarify: lifecycle.brainClarify,\n rowKey,\n });\n }\n\n private emitPageActionBrainClarifyFromPayload(input: {\n actionKey: string;\n runId: number;\n brainClarify: BrainClarifyPayload;\n rowKey: string | null;\n }): void {\n const runId = input.runId;\n const rowKey = input.rowKey;\n const snap =\n this.pageActionInvokeSnapshotsByRunId.get(runId) ??\n (rowKey ? this.pageActionInvokeSnapshotsByRowKey.get(rowKey) : undefined) ??\n null;\n const prompt: PageActionBrainClarifyPromptRequest = {\n actionKey: input.actionKey,\n runId,\n brainClarify: input.brainClarify,\n sourceRect: readLaunchSourceRect(snap?.launchAnchor ?? null),\n launchAnchor: snap?.launchAnchor ?? null,\n invokeSnapshot: snap\n ? {\n pageContext: snap.pageContext,\n instruction: snap.instruction,\n context: snap.context,\n clientActionId: snap.clientActionId,\n // Intentionally omit idempotencyKey — clarify continuation must open a new run.\n rowKey: snap.rowKey,\n awaitStream: snap.awaitStream,\n }\n : undefined,\n };\n this.bus.emit('pageActionBrainClarify', prompt);\n }\n\n private syncPageActionRowAfterApprovalDecision(\n runId: number | null | undefined,\n approvalId: number | null | undefined,\n transition: 'resumed' | 'cancelled' | 'suspended',\n ): void {\n const resolvedRunId = this.resolvePageActionRunIdForApproval(runId, approvalId);\n if (resolvedRunId != null) {\n this.pageActionAwaitingApprovalNotified.delete(resolvedRunId);\n }\n\n const rowKey = this.findRowKeyForApproval(resolvedRunId, approvalId);\n if (!rowKey) return;\n\n const prev = this.pageActionRows.get(rowKey);\n const approvalKey =\n approvalId != null && Number.isFinite(approvalId) ? Math.trunc(approvalId) : null;\n const canSync =\n prev?.awaitingApproval ||\n prev?.phase === 'awaiting_approval' ||\n (resolvedRunId != null && prev?.runId === resolvedRunId) ||\n (approvalKey != null && prev?.approvalRequestId === approvalKey);\n if (!prev || !canSync) return;\n\n if (transition === 'resumed') {\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n rowKey,\n runId: resolvedRunId ?? prev.runId,\n phase: 'streaming',\n error: null,\n approvalRequestId: null,\n }),\n );\n return;\n }\n\n if (transition === 'suspended') {\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n rowKey,\n runId: resolvedRunId ?? prev.runId,\n phase: 'awaiting_approval',\n error: null,\n approvalRequestId: approvalId ?? prev.approvalRequestId,\n }),\n );\n return;\n }\n\n // cancelled / rejected — unlock row immediately; hydrate will refine terminal status.\n if (resolvedRunId != null) {\n this.automationRunRegistry.delete(resolvedRunId);\n }\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n rowKey,\n runId: null,\n phase: 'idle',\n error: null,\n approvalRequestId: null,\n }),\n );\n }\n\n private findRowKeyByRunId(runId: number): string | null {\n const id = Math.trunc(runId);\n const mapped =\n this.pageActionRunToRowKey.get(id)?.trim() ||\n this.automationRunRegistry.get(id)?.rowKey?.trim() ||\n null;\n if (mapped) return mapped;\n for (const row of this.pageActionRows.values()) {\n if (row.runId === id) return row.rowKey;\n }\n return null;\n }\n\n private findRowKeyForApproval(\n runId: number | null,\n approvalId: number | null | undefined,\n ): string | null {\n if (runId != null && Number.isFinite(runId)) {\n const mapped = this.findRowKeyByRunId(Math.trunc(runId));\n if (mapped) return mapped;\n }\n if (approvalId != null && Number.isFinite(approvalId)) {\n const approvalKey = Math.trunc(approvalId);\n for (const row of this.pageActionRows.values()) {\n if (row.approvalRequestId === approvalKey) return row.rowKey;\n }\n }\n return null;\n }\n\n private resolvePageActionRunIdForApproval(\n runId: number | null | undefined,\n approvalId: number | null | undefined,\n ): number | null {\n if (typeof runId === 'number' && Number.isFinite(runId)) {\n return Math.trunc(runId);\n }\n if (approvalId != null && Number.isFinite(approvalId)) {\n return this.resolveApprovalPageActionRunId(Math.trunc(approvalId));\n }\n return null;\n }\n\n private refreshPageActionRowsAfterApprovalDecision(\n runId: number | null | undefined,\n approvalId: number | null | undefined,\n ): void {\n void (async () => {\n try {\n if (this.automationRunRegistry.size > 0) {\n await this.refreshAutomationTasks({ status: 'active', offset: 0 });\n }\n const resolvedRunId = this.resolvePageActionRunIdForApproval(runId, approvalId);\n if (resolvedRunId != null) {\n await this.hydratePageActionByRunId(resolvedRunId);\n return;\n }\n const awaitingRows = [...this.pageActionRows.values()].filter(\n (row) => row.awaitingApproval || row.phase === 'awaiting_approval',\n );\n await Promise.all(\n awaitingRows\n .filter((row) => row.runId != null)\n .map((row) => this.hydratePageActionByRunId(row.runId!)),\n );\n } catch {\n /* approval-driven row refresh is best-effort */\n }\n })();\n }\n\n private emitPageActionAwaitingApproval(\n pageGate: PageContextGate,\n pageContext: AgentChatPageContext | null | undefined,\n input: PageBotInvokeInput,\n result: PageBotStreamResult,\n ): void {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim() ??\n '';\n if (scope) {\n this.bus.emit('pageAgentAwaitingApproval', {\n scope,\n actionRunId: result.actionRunId,\n actionKey: result.actionKey,\n clientActionId: result.clientActionId,\n approvalRequestId: result.approvalRequestId ?? null,\n } satisfies PageAgentAwaitingApprovalPayload);\n }\n // Badge only — list refresh waits until user opens the inbox drawer.\n void this.refreshApprovalPendingCount().catch(() => {\n /* badge refresh is best-effort */\n });\n this.bus.emit('approvalInboxChanged', undefined);\n }\n\n private clearAutomationRunRegistry(): void {\n this.automationRunRegistry.clear();\n this.automationTasksLastSyncedAt = 0;\n this.pageActionRows.clear();\n this.pageActionRunToRowKey.clear();\n this.pageActionReuseHintCache.clear();\n this.clearPageActionRowIdleTimers();\n }\n\n private syncAutomationActiveCount(state: InternalState): void {\n pruneStaleTrackedRuns(this.automationRunRegistry);\n state.automationTaskActiveCount = countActiveTrackedRuns(this.automationRunRegistry);\n }\n\n private resolveInvokeRowKey(input: PageBotInvokeInput): string | null {\n const state = this.state;\n if (!state) {\n return resolvePageActionRowKey({\n rowKey: input.rowKey,\n entityId: input.pageContext?.entity?.id ?? null,\n });\n }\n const pageContext = this.resolvePageActionContext(state, input);\n return resolvePageActionRowKey({\n rowKey: input.rowKey,\n entityId: pageContext?.entity?.id ?? null,\n });\n }\n\n private bindPageActionRunToRow(runId: number, rowKey: string): void {\n const key = rowKey.trim();\n if (!key || !Number.isFinite(runId)) return;\n this.pageActionRunToRowKey.set(Math.trunc(runId), key);\n }\n\n private findRowKeyByPageActionKey(pageActionKey: string | null | undefined): string | null {\n const key = pageActionKey?.trim();\n if (!key) return null;\n for (const row of this.pageActionRows.values()) {\n if (row.pageActionKey?.trim() === key) return row.rowKey;\n }\n for (const run of this.automationRunRegistry.values()) {\n if (run.pageActionKey?.trim() === key && run.rowKey?.trim()) return run.rowKey.trim();\n }\n return null;\n }\n\n private upsertPageActionRow(row: PageActionRowState): void {\n const existingTimer = this.pageActionRowIdleTimers.get(row.rowKey);\n if (\n existingTimer != null &&\n row.phase !== 'completed' &&\n row.phase !== 'failed'\n ) {\n clearTimeout(existingTimer);\n this.pageActionRowIdleTimers.delete(row.rowKey);\n }\n // Strictly increasing updatedAt so React row sync cannot skip a loading/disabled unlock\n // when Date.now() collides with the previous upsert in the same ms.\n const prev = this.pageActionRows.get(row.rowKey);\n const next: PageActionRowState =\n prev && row.updatedAt <= prev.updatedAt\n ? { ...row, updatedAt: prev.updatedAt + 1 }\n : row;\n this.pageActionRows.set(next.rowKey, next);\n if (next.runId != null) this.bindPageActionRunToRow(next.runId, next.rowKey);\n this.bus.emit('pageActionRowChanged', { rowKey: next.rowKey, state: next });\n }\n\n private syncPageActionRowFromAccepted(\n rowKey: string,\n actionKey: string,\n accepted: InvokePageActionAccepted,\n opts: {\n approvalRequestId?: number | null;\n error?: string | null;\n message?: string | null;\n } = {},\n ): void {\n const phase: PageActionPhase =\n accepted.status === 'awaiting_approval'\n ? 'awaiting_approval'\n : accepted.status === 'running'\n ? 'launched'\n : taskStatusToPageActionPhase(accepted.status);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: actionKey.trim(),\n runId: accepted.runId,\n pageActionKey: accepted.pageActionKey,\n phase,\n error: opts.error ?? null,\n message: opts.message ?? null,\n progressLabel:\n phase === 'awaiting_approval'\n ? resolvePageWorkflowProgressLabel(\n {\n phase: 'awaiting_approval',\n actionRunId: accepted.runId,\n actionKey: actionKey.trim(),\n generation: accepted.generation,\n nodeId: '',\n stageKind: 'other',\n },\n this.state?.options.locale,\n )\n : phase === 'launched' || phase === 'streaming'\n ? (this.pageActionRows.get(rowKey)?.progressLabel ??\n defaultPageActionProgressLabel(this.state?.options.locale))\n : null,\n narrativeItems: this.pageActionRows.get(rowKey)?.narrativeItems ?? [],\n approvalRequestId: opts.approvalRequestId ?? null,\n }),\n );\n }\n\n private syncPageActionRowFromWorkflow(event: PageWorkflowEvent): void {\n const runId = event.actionRunId;\n const rowKey =\n this.pageActionRunToRowKey.get(runId) ||\n this.automationRunRegistry.get(runId)?.rowKey?.trim() ||\n null;\n if (!rowKey) return;\n const prev = this.pageActionRows.get(rowKey);\n if (!prev) return;\n\n if (event.phase === 'failed') {\n // Terminal failure is owned by page_action.failed; keep current label.\n return;\n }\n\n if (\n prev.phase === 'idle' ||\n prev.phase === 'completed' ||\n prev.phase === 'failed' ||\n prev.phase === 'awaiting_reuse'\n ) {\n return;\n }\n\n const nextItems = appendPageActionNarrativeItems(\n prev.narrativeItems,\n event.narrativeItems,\n );\n const nextLabel = resolvePageWorkflowProgressLabel(event, this.state?.options.locale);\n const labelUnchanged = nextLabel == null || nextLabel === prev.progressLabel;\n const itemsUnchanged = nextItems === prev.narrativeItems;\n if (labelUnchanged && itemsUnchanged) {\n return;\n }\n\n const phase: PageActionPhase =\n event.phase === 'awaiting_approval'\n ? 'awaiting_approval'\n : prev.phase === 'submitting' || prev.phase === 'launched'\n ? 'streaming'\n : prev.loading || prev.phase === 'streaming'\n ? 'streaming'\n : prev.phase;\n\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n phase,\n progressLabel: nextLabel ?? prev.progressLabel,\n narrativeItems: nextItems,\n // Duplicate-click tip is ephemeral; clear once real workflow narrative arrives.\n message: null,\n }),\n );\n }\n\n private syncPageActionRowFromLifecycle(lifecycle: PageActionSseLifecycle): void {\n const runId = lifecycle.actionRunId;\n const rowKey =\n this.pageActionRunToRowKey.get(runId) ||\n this.automationRunRegistry.get(runId)?.rowKey?.trim() ||\n null;\n if (!rowKey) return;\n const prev = this.pageActionRows.get(rowKey);\n // Late replay / aborted-reuse frames must not re-lock a settled trigger button.\n if (\n (lifecycle.phase === 'started' || lifecycle.phase === 'stream') &&\n (prev?.phase === 'idle' ||\n prev?.phase === 'completed' ||\n prev?.phase === 'failed' ||\n prev?.phase === 'awaiting_reuse')\n ) {\n return;\n }\n const isBrainClarify =\n lifecycle.phase === 'failed' &&\n isBrainAskUserErrorCode(lifecycle.errorCode) &&\n lifecycle.brainClarify != null;\n const phase: PageActionPhase =\n lifecycle.phase === 'started' || lifecycle.phase === 'stream'\n ? 'streaming'\n : lifecycle.phase === 'awaiting_approval'\n ? 'awaiting_approval'\n : lifecycle.phase === 'completed'\n ? 'completed'\n : isBrainClarify\n ? 'awaiting_clarify'\n : lifecycle.phase === 'failed'\n ? 'failed'\n : 'idle';\n // Skip redundant upsert for high-frequency stream frames when row is already streaming.\n if (\n lifecycle.phase === 'stream' &&\n prev?.phase === 'streaming' &&\n prev.progressLabel\n ) {\n return;\n }\n const progressLabel =\n phase === 'completed' || phase === 'failed'\n ? null\n : phase === 'awaiting_clarify'\n ? pageActionAwaitingClarifyLabel(this.state?.options.locale)\n : phase === 'awaiting_approval'\n ? resolvePageWorkflowProgressLabel(\n {\n phase: 'awaiting_approval',\n actionRunId: runId,\n actionKey: lifecycle.actionKey || prev?.actionKey || '',\n generation: lifecycle.generation,\n nodeId: '',\n stageKind: 'other',\n },\n this.state?.options.locale,\n )\n : (prev?.progressLabel ??\n defaultPageActionProgressLabel(this.state?.options.locale));\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: lifecycle.actionKey || prev?.actionKey || `Run ${runId}`,\n runId,\n pageActionKey: prev?.pageActionKey ?? this.automationRunRegistry.get(runId)?.pageActionKey ?? null,\n phase,\n error: isBrainClarify\n ? null\n : lifecycle.errorMessage ?? (phase === 'failed' ? 'Page action failed' : null),\n message:\n phase === 'failed' ||\n phase === 'completed' ||\n phase === 'awaiting_clarify' ||\n lifecycle.phase === 'started'\n ? null\n : (prev?.message ?? null),\n progressLabel,\n narrativeItems: prev?.narrativeItems ?? [],\n approvalRequestId: prev?.approvalRequestId ?? null,\n brainClarify: isBrainClarify ? lifecycle.brainClarify ?? null : null,\n }),\n );\n if (phase === 'completed' || phase === 'failed') {\n this.schedulePageActionRowIdleReset(rowKey, phase === 'failed' ? 1_600 : 900);\n }\n }\n\n private pageActionRowIdleTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n private schedulePageActionRowIdleReset(\n rowKey: string,\n delayMs: number,\n fromPhases: PageActionPhase[] = ['completed', 'failed'],\n ): void {\n const key = rowKey.trim();\n if (!key) return;\n const existing = this.pageActionRowIdleTimers.get(key);\n if (existing != null) clearTimeout(existing);\n const allowed = new Set(fromPhases);\n const timer = setTimeout(() => {\n this.pageActionRowIdleTimers.delete(key);\n const current = this.pageActionRows.get(key);\n if (!current) return;\n if (!allowed.has(current.phase)) return;\n if (current.phase === 'launched' && current.runId != null) {\n const tracked = this.automationRunRegistry.get(current.runId);\n if (tracked && isActiveAutomationTaskStatus(tracked.status)) {\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...current,\n phase: 'streaming',\n }),\n );\n return;\n }\n }\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...current,\n phase: 'idle',\n runId: current.runId,\n // Never carry a stale soft-lock from a prior streaming/completed frame.\n loading: false,\n disabled: false,\n // Keep failed message after soft unlock; clear ephemeral launched/completed state.\n error: current.phase === 'failed' ? current.error : null,\n message: current.phase === 'failed' ? current.message : null,\n progressLabel: null,\n // Keep storyline so「查看过程」remains usable after the button unlocks.\n narrativeItems: current.narrativeItems ?? [],\n }),\n );\n if ((current.narrativeItems?.length ?? 0) > 0) {\n this.schedulePageActionNarrativeClear(key, 12_000);\n }\n }, delayMs);\n this.pageActionRowIdleTimers.set(key, timer);\n }\n\n private pageActionNarrativeClearTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n /** Drop retained storyline after the button has been idle for a while. */\n private schedulePageActionNarrativeClear(rowKey: string, delayMs: number): void {\n const key = rowKey.trim();\n if (!key) return;\n const existing = this.pageActionNarrativeClearTimers.get(key);\n if (existing != null) clearTimeout(existing);\n const timer = setTimeout(() => {\n this.pageActionNarrativeClearTimers.delete(key);\n const current = this.pageActionRows.get(key);\n if (!current) return;\n if (current.phase !== 'idle') return;\n if ((current.narrativeItems?.length ?? 0) === 0) return;\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...current,\n narrativeItems: [],\n }),\n );\n }, delayMs);\n this.pageActionNarrativeClearTimers.set(key, timer);\n }\n\n private clearPageActionNarrativeClearTimer(rowKey: string): void {\n const key = rowKey.trim();\n if (!key) return;\n const existing = this.pageActionNarrativeClearTimers.get(key);\n if (existing == null) return;\n clearTimeout(existing);\n this.pageActionNarrativeClearTimers.delete(key);\n }\n\n private clearPageActionRowIdleTimers(): void {\n for (const timer of this.pageActionRowIdleTimers.values()) clearTimeout(timer);\n this.pageActionRowIdleTimers.clear();\n for (const timer of this.pageActionNarrativeClearTimers.values()) clearTimeout(timer);\n this.pageActionNarrativeClearTimers.clear();\n this.pageActionReuseDismissEpochByRowKey.clear();\n }\n\n private trackAutomationRun(\n accepted: InvokePageActionAccepted,\n meta: { actionKey: string; pageActionKey: string | null; rowKey?: string | null },\n ): void {\n const state = this.state;\n if (!state) return;\n const now = new Date().toISOString();\n const catalogName = this.pageActionFeedbackNames.get(meta.actionKey.trim());\n const locale = state.options.locale;\n const subtitle =\n accepted.status === 'awaiting_approval'\n ? pageActionTaskAwaitingApprovalSubtitle(locale)\n : pageActionTaskRunningSubtitle(locale);\n const item = buildOptimisticAutomationTaskItem(accepted, meta.actionKey, {\n title: formatPageActionDisplayTitle(meta.actionKey, catalogName),\n subtitle,\n });\n const rowKey = meta.rowKey?.trim() || null;\n\n if (isActiveAutomationTaskStatus(accepted.status)) {\n this.automationRunRegistry.set(accepted.runId, {\n runId: accepted.runId,\n actionKey: meta.actionKey,\n pageActionKey: meta.pageActionKey,\n rowKey,\n status: accepted.status,\n registeredAt: now,\n updatedAt: now,\n clientActionId: accepted.clientActionId,\n });\n if (rowKey) this.bindPageActionRunToRow(accepted.runId, rowKey);\n }\n\n if (taskMatchesStatusFilter(item.taskStatus, state.automationTaskStatusFilter)) {\n const nextItems = upsertAutomationTaskListItem(state.automationTaskItems, item);\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n nextItems,\n state.automationTaskHasMore,\n );\n }\n\n state.automationRecentRunIds = [\n accepted.runId,\n ...state.automationRecentRunIds.filter((row) => row !== accepted.runId),\n ].slice(0, MAX_RECENT_AUTOMATION_RUN_IDS);\n this.syncAutomationActiveCount(state);\n this.notifyStateChange();\n this.bus.emit('automationTaskCenterChanged', undefined);\n }\n\n private applyPageActionRunLifecycle(\n state: InternalState,\n lifecycle: PageActionSseLifecycle,\n ): void {\n const taskStatus = lifecyclePhaseToTaskStatus(lifecycle.phase);\n if (!taskStatus) return;\n\n const runId = lifecycle.actionRunId;\n const now = new Date().toISOString();\n const tracked = this.automationRunRegistry.get(runId);\n\n // Skip redundant processing for high-frequency `stream` frames when run is already tracked as running.\n if (lifecycle.phase === 'stream' && tracked?.status === 'running') {\n this.syncPageActionRowFromLifecycle(lifecycle);\n return;\n }\n\n if (tracked) {\n tracked.status = taskStatus;\n tracked.updatedAt = now;\n if (lifecycle.actionKey) tracked.actionKey = lifecycle.actionKey;\n if (!isActiveAutomationTaskStatus(taskStatus)) {\n this.automationRunRegistry.delete(runId);\n }\n } else if (isActiveAutomationTaskStatus(taskStatus)) {\n this.automationRunRegistry.set(runId, {\n runId,\n actionKey: lifecycle.actionKey,\n pageActionKey: null,\n rowKey: this.pageActionRunToRowKey.get(runId) ?? null,\n status: taskStatus,\n registeredAt: now,\n updatedAt: now,\n clientActionId: lifecycle.clientActionId ?? null,\n });\n }\n\n this.syncPageActionRowFromLifecycle(lifecycle);\n\n const lifecycleRowKey =\n this.pageActionRunToRowKey.get(runId) ??\n this.automationRunRegistry.get(runId)?.rowKey?.trim() ??\n null;\n if (lifecycle.phase === 'completed') {\n const pageActionKey =\n tracked?.pageActionKey ??\n (lifecycleRowKey\n ? this.pageActionRows.get(lifecycleRowKey)?.pageActionKey\n : null) ??\n null;\n this.pageActionReuseHintCache.invalidateByPageActionKey(pageActionKey);\n this.bus.emit('pageActionRunCompleted', {\n runId,\n actionKey: lifecycle.actionKey,\n rowKey: lifecycleRowKey,\n });\n } else if (lifecycle.phase === 'failed') {\n if (\n isBrainAskUserErrorCode(lifecycle.errorCode) &&\n lifecycle.brainClarify\n ) {\n this.emitPageActionBrainClarify(state, lifecycle, lifecycleRowKey);\n } else {\n this.bus.emit('pageActionRunFailed', {\n runId,\n actionKey: lifecycle.actionKey,\n rowKey: lifecycleRowKey,\n errorMessage: lifecycle.errorMessage ?? null,\n errorCode: lifecycle.errorCode ?? null,\n });\n }\n }\n\n const preview =\n lifecycle.phase === 'completed' && typeof lifecycle.text === 'string'\n ? lifecycle.text.trim().slice(0, 120) || null\n : undefined;\n const patch = {\n taskStatus,\n ...(isActiveAutomationTaskStatus(taskStatus)\n ? { finishedAt: null }\n : { finishedAt: now }),\n ...(preview\n ? {\n outputs: {\n preview,\n hasFillText: preview.length > 0,\n },\n }\n : {}),\n };\n\n if (\n state.automationTaskStatusFilter === 'active' &&\n !isActiveAutomationTaskStatus(taskStatus)\n ) {\n const nextItems = removeAutomationTaskListItem(state.automationTaskItems, runId);\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n nextItems,\n state.automationTaskHasMore,\n );\n } else if (taskMatchesStatusFilter(taskStatus, state.automationTaskStatusFilter)) {\n const existingIndex = state.automationTaskItems.findIndex(\n (item) => item.ref.kind === 'page_action_run' && item.ref.id === runId,\n );\n if (existingIndex >= 0) {\n const nextItems = patchAutomationTaskListItem(state.automationTaskItems, runId, patch);\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n nextItems,\n state.automationTaskHasMore,\n );\n } else {\n const nextItems = upsertAutomationTaskListItem(state.automationTaskItems, {\n ...buildOptimisticAutomationTaskItem(\n {\n runId,\n generation: lifecycle.generation,\n clientActionId: lifecycle.clientActionId ?? null,\n pageActionKey: tracked?.pageActionKey ?? null,\n streamUrl: '',\n status: taskStatus,\n },\n lifecycle.actionKey,\n {\n title: formatPageActionDisplayTitle(\n lifecycle.actionKey,\n this.pageActionFeedbackNames.get(lifecycle.actionKey.trim()),\n ),\n },\n ),\n ...patch,\n });\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n nextItems,\n state.automationTaskHasMore,\n );\n }\n }\n\n if (\n state.automationTaskSelectedDetail?.ref.kind === 'page_action_run' &&\n state.automationTaskSelectedDetail.ref.id === runId\n ) {\n state.automationTaskSelectedDetail = {\n ...state.automationTaskSelectedDetail,\n ...patch,\n outputs: patch.outputs\n ? { ...state.automationTaskSelectedDetail.outputs, ...patch.outputs }\n : state.automationTaskSelectedDetail.outputs,\n };\n }\n\n this.syncAutomationActiveCount(state);\n this.notifyStateChange();\n\n if (\n !isActiveAutomationTaskStatus(taskStatus) &&\n state.automationTaskSelectedDetail?.ref.kind === 'page_action_run' &&\n state.automationTaskSelectedDetail.ref.id === runId\n ) {\n void this.hydrateAutomationTaskDetail(runId).catch(() => {\n /* detail refresh is best-effort */\n });\n }\n }\n\n private markTrackedAutomationRunFailed(runId: number, actionKey?: string): void {\n const state = this.state;\n if (!state) return;\n this.applyPageActionRunLifecycle(state, {\n phase: 'failed',\n actionRunId: runId,\n actionKey: actionKey?.trim() || this.automationRunRegistry.get(runId)?.actionKey || `Run ${runId}`,\n generation: 0,\n clientActionId: this.automationRunRegistry.get(runId)?.clientActionId ?? null,\n });\n }\n\n private resolveApprovalPageActionRunId(approvalId: number): number | null {\n const state = this.state;\n if (!state) return null;\n const item = state.approvalInboxItems.find((row) => row.id === approvalId);\n if (item?.pageActionRunId != null && Number.isFinite(item.pageActionRunId)) {\n return Math.trunc(item.pageActionRunId);\n }\n for (const row of this.pageActionRows.values()) {\n if (row.approvalRequestId === approvalId && row.runId != null) {\n return row.runId;\n }\n }\n return null;\n }\n\n private taskStatusToExecutionOutcome(\n status: AutomationTaskStatus,\n ): ApprovalExecutionOutcome {\n switch (status) {\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'running':\n return 'running';\n case 'awaiting_approval':\n return 'awaiting_approval';\n case 'cancelled':\n return 'cancelled';\n default:\n return 'completed';\n }\n }\n\n private resolveApprovalIdentity(approvalId: number): {\n approvalTitle: string | null;\n approvalSummary: string | null;\n } {\n const item = this.state?.approvalInboxItems.find((row) => row.id === approvalId);\n return {\n approvalTitle: item?.title?.trim() || null,\n approvalSummary: item?.summary?.trim() || null,\n };\n }\n\n private async emitApprovalExecutionCompleted(input: {\n approvalId: number;\n runId: number | null;\n decision: DraftReviewDecision;\n result: ApprovalDecideResult | ApprovalConfirmResult;\n identity?: { approvalTitle: string | null; approvalSummary: string | null };\n }): Promise<void> {\n const { approvalId, runId, decision, result } = input;\n const identity = input.identity ?? this.resolveApprovalIdentity(approvalId);\n\n if (decision.action === 'cancel') {\n this.bus.emit('approvalExecutionCompleted', {\n approvalId,\n runId,\n outcome: 'cancelled',\n title: identity.approvalTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n });\n return;\n }\n\n if (decision.action === 'retry') {\n if (!result.resumed) return;\n if (result.suspended) {\n this.bus.emit('approvalExecutionCompleted', {\n approvalId,\n runId,\n outcome: 'awaiting_approval',\n title: identity.approvalTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n });\n } else {\n await this.emitApprovalRunExecutionOutcome(approvalId, runId, identity);\n }\n return;\n }\n\n if (\n (decision.action === 'confirm' || decision.action === 'confirm_with_edits') &&\n result.resumed\n ) {\n await this.emitApprovalRunExecutionOutcome(approvalId, runId, identity);\n }\n }\n\n private async emitApprovalRunExecutionOutcome(\n approvalId: number,\n runId: number | null,\n identity: { approvalTitle: string | null; approvalSummary: string | null } = {\n approvalTitle: null,\n approvalSummary: null,\n },\n ): Promise<void> {\n const state = this.state;\n if (!runId) {\n this.bus.emit('approvalExecutionCompleted', {\n approvalId,\n runId: null,\n outcome: 'completed',\n title: identity.approvalTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n });\n return;\n }\n\n const detail = await this.getAutomationTaskDetail(runId).catch(() => null);\n if (detail && state) {\n const index = state.automationTaskItems.findIndex(\n (item) => item.ref.kind === 'page_action_run' && item.ref.id === runId,\n );\n if (index >= 0) {\n const next = [...state.automationTaskItems];\n next[index] = detail;\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n next,\n state.automationTaskHasMore,\n );\n }\n if (!isActiveAutomationTaskStatus(detail.taskStatus)) {\n this.automationRunRegistry.delete(runId);\n }\n this.syncAutomationActiveCount(state);\n this.notifyStateChange();\n await this.hydratePageActionByRunId(runId).catch(() => {\n /* row slot refresh is best-effort */\n });\n }\n\n const taskTitle = detail?.title?.trim() || null;\n const displayTitle = identity.approvalTitle || taskTitle;\n const preview =\n detail?.outputs.preview?.trim() ||\n identity.approvalSummary ||\n null;\n\n const payload: ApprovalExecutionCompletedPayload = {\n approvalId,\n runId,\n outcome: detail\n ? this.taskStatusToExecutionOutcome(detail.taskStatus)\n : 'completed',\n title: displayTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n preview,\n ...(detail ? { taskStatus: detail.taskStatus } : {}),\n };\n this.bus.emit('approvalExecutionCompleted', payload);\n }\n\n private abortAllPageActionRunStreams(): void {\n for (const ctrl of this.pageActionRunAborts.values()) {\n try {\n ctrl.abort();\n } catch {\n /* noop */\n }\n }\n this.pageActionRunAborts.clear();\n this.pageActionRunStreamPromises.clear();\n }\n\n private async fetchAutomationTasks(\n opts: {\n signal?: AbortSignal;\n status?: AutomationTaskStatusFilter;\n actionKey?: string;\n limit?: number;\n offset?: number;\n append?: boolean;\n } = {},\n ): Promise<AutomationTaskList> {\n await this.ensureLoggedIn('refreshAutomationTasks');\n const state = this.requireState('refreshAutomationTasks');\n const status = opts.status ?? state.automationTaskStatusFilter;\n const limit = opts.limit ?? AUTOMATION_TASK_PAGE_SIZE;\n const tabCache = getAutomationTaskTabCache(state.automationTaskTabCaches, status);\n const offset = opts.offset ?? (opts.append ? tabCache.items.length : 0);\n const append = opts.append === true;\n if (append && state.automationTaskLoading) {\n return {\n items: tabCache.items,\n total: tabCache.total,\n hasMore: tabCache.hasMore,\n };\n }\n const publishSeq = append ? this.automationTaskListPublishSeq : ++this.automationTaskListPublishSeq;\n if (append) {\n state.automationTaskLoadingMore = true;\n } else {\n state.automationTaskLoading = true;\n }\n this.notifyStateChange();\n try {\n const list = await state.automation.listTasks({\n status,\n triggerSource: 'page_action',\n actionKey: opts.actionKey,\n limit,\n offset,\n signal: opts.signal,\n });\n if (publishSeq !== this.automationTaskListPublishSeq) {\n return list;\n }\n state.automationTaskStatusFilter = status;\n const nextItems = append\n ? [...tabCache.items, ...list.items]\n : status === 'active' && offset === 0\n ? mergeOptimisticRunsIntoList(list.items, this.automationRunRegistry)\n : list.items;\n const hasMore = resolveAutomationTaskListHasMore(\n nextItems.length,\n list.items.length,\n list.total,\n limit,\n );\n this.publishAutomationTaskTabCache(state, status, nextItems, hasMore, list.total);\n if (status === 'active' && offset === 0 && !append) {\n mergeRegistryFromActiveListItems(this.automationRunRegistry, list.items, {\n fallbackActionKey: opts.actionKey,\n });\n this.automationTasksLastSyncedAt = Date.now();\n }\n this.syncAutomationActiveCount(state);\n return list;\n } finally {\n if (append) {\n state.automationTaskLoadingMore = false;\n } else {\n state.automationTaskLoading = false;\n }\n this.notifyStateChange();\n }\n }\n\n private getMessageSendContext(\n state: InternalState,\n pageContextOverride?: AgentChatPageContext | null,\n entityCommit?: EntityCommit | null,\n ): MessageSendContext | undefined {\n const ctx: MessageSendContext = {};\n const agentId = state.selectedAgentId?.trim();\n const skillId = state.selectedSkillId?.trim();\n const agentWasAutoBound =\n agentId &&\n state.autoAgent?.id === agentId &&\n state.autoAgent.source !== 'requested';\n if (agentId && !agentWasAutoBound) ctx.agentId = agentId;\n if (skillId) ctx.skillId = skillId;\n\n const page = pageContextOverride ?? this.buildOutboundPageContext(state);\n if (page?.page) ctx.page = page.page;\n if (page?.routePath) ctx.routePath = page.routePath;\n if (page?.routeParams) ctx.routeParams = page.routeParams;\n if (page?.flowId != null) ctx.flowId = page.flowId;\n if (page?.programName) ctx.programName = page.programName;\n if (page?.entity) ctx.entity = page.entity;\n if (page?.metadata) ctx.metadata = page.metadata;\n if (entityCommit?.entityType?.trim() && entityCommit?.selectedId?.trim()) {\n ctx.entityCommit = {\n entityType: entityCommit.entityType.trim(),\n selectedId: entityCommit.selectedId.trim(),\n };\n }\n\n return Object.keys(ctx).length > 0 ? ctx : undefined;\n }\n\n private buildOutboundPageContext(state: InternalState): AgentChatPageContext | null {\n return this.buildPreparePageContext(state);\n }\n\n private listRegisteredContextMentions(\n state: InternalState,\n ): RegisteredContextMention[] {\n return [...state.contextMentionRegistry.values()].map(toRegisteredContextMention);\n }\n\n private listPendingRegisteredContextMentions(): RegisteredContextMention[] {\n return [...this.pendingContextMentionRegistry.values()].map(toRegisteredContextMention);\n }\n\n private async fetchSessionMessagesPage(\n state: InternalState,\n sessionId: string,\n page: number,\n signal?: AbortSignal,\n ) {\n const body = await state.chat.getSession(\n sessionId,\n page,\n state.sessionMessagesPageSize,\n signal,\n );\n const detailPage = parseChatSessionDetailPage(\n body,\n sessionId,\n page,\n state.sessionMessagesPageSize,\n );\n if (!detailPage) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid session detail response', {\n details: { sessionId, page },\n });\n }\n return detailPage;\n }\n\n /** Clear the active session so the next send creates a new chat. */\n async startNewChat(): Promise<void> {\n await this.ensureLoggedIn('startNewChat');\n const state = this.requireState('startNewChat');\n this.sessionEpoch += 1;\n if (state.activeSessionId) {\n this.abortSessionStream(state, state.activeSessionId);\n this.writeSessionMessagesCache(state, state.activeSessionId);\n }\n state.activeSessionId = null;\n state.activeSessionMessagesPage = 0;\n state.activeSessionMessagesHasMore = false;\n state.session.reset();\n state.messages = [];\n state.writeConfirmation = null;\n state.autoAgent = null;\n state.selectedAgentId = state.options.defaultAgentId?.trim() ?? null;\n state.selectedSkillId = null;\n if (state.options.skills?.length) {\n this.applyStaticSkills(state);\n } else {\n state.skills = [];\n state.skillsLoading = false;\n }\n this.notifyStateChange();\n }\n\n /** Stop the active agent run via `POST .../cancel-run` (does not close the session SSE). */\n async cancelGeneration(): Promise<void> {\n const state = this.state;\n if (!state?.activeSessionId) return;\n await this.ensureLoggedIn('cancelGeneration');\n const sessionId = state.activeSessionId;\n const runId = this.resolveActiveRunIdForCancel(state, sessionId);\n\n try {\n const result = await state.chat.cancelRun(sessionId, runId);\n if (!result.superseded) return;\n this.applySessionRunGeneration(state, sessionId, result.generation);\n this.finalizeStreamingTarget(state, sessionId, {\n cancelled: true,\n systemHint: '已停止生成。',\n });\n } catch (err) {\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to cancel generation', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n }\n }\n\n private isViewingSession(state: InternalState, sessionId: string): boolean {\n return (\n state.activeSessionId != null &&\n normalizeSessionId(state.activeSessionId) === normalizeSessionId(sessionId)\n );\n }\n\n private getSessionRunState(state: InternalState, sessionId: string): SessionRunState {\n const key = normalizeSessionId(sessionId);\n let runState = state.sessionRuns.get(key);\n if (!runState) {\n runState = { sessionGeneration: 0, activeRunId: null, activeTurnId: null, pendingJobCount: 0, redisBacked: false };\n state.sessionRuns.set(key, runState);\n }\n return runState;\n }\n\n private applySessionRunGeneration(\n state: InternalState,\n sessionId: string,\n generation: number,\n opts: { clearActiveRun?: boolean } = {},\n ): void {\n const runState = this.getSessionRunState(state, sessionId);\n const prevGeneration = runState.sessionGeneration;\n runState.sessionGeneration = generation;\n if (generation > prevGeneration) {\n this.discardStaleWriteConfirmations(state, sessionId, generation, prevGeneration);\n }\n if (opts.clearActiveRun !== false) {\n runState.activeRunId = null;\n runState.activeTurnId = null;\n }\n }\n\n private applySessionRunSnapshot(\n state: InternalState,\n sessionId: string,\n snapshot: SessionRunStateSnapshot,\n ): void {\n const runState = this.getSessionRunState(state, sessionId);\n const prevGeneration = runState.sessionGeneration;\n runState.sessionGeneration = snapshot.generation;\n if (snapshot.generation > prevGeneration) {\n this.discardStaleWriteConfirmations(\n state,\n sessionId,\n snapshot.generation,\n prevGeneration,\n );\n }\n runState.activeRunId = snapshot.activeRunId;\n runState.activeTurnId = snapshot.activeTurnId;\n runState.pendingJobCount = snapshot.pendingJobCount;\n runState.redisBacked = snapshot.redisBacked;\n this.syncWriteGateFromRunState(\n state,\n sessionId,\n snapshot.generation,\n snapshot.pendingWriteGate,\n );\n }\n\n /** Restore Chat write gate from `GET run-state` `pendingWriteGate` (page refresh). */\n private syncWriteGateFromRunState(\n state: InternalState,\n sessionId: string,\n generation: number,\n pendingWriteGate: SessionRunStateSnapshot['pendingWriteGate'],\n ): void {\n const key = normalizeSessionId(sessionId);\n const current = state.writeConfirmationsBySession.get(key);\n if (current?.submitting) return;\n\n if (!pendingWriteGate) {\n if (current?.awaiting) {\n this.persistWriteConfirmation(state, sessionId, null);\n }\n return;\n }\n\n const message =\n pendingWriteGate.writeDraft?.presentation.summaryText?.trim() ||\n '即将执行写操作,请确认。';\n\n this.persistWriteConfirmation(state, sessionId, {\n awaiting: true,\n submitting: false,\n runId: pendingWriteGate.runId,\n turnId: pendingWriteGate.turnId,\n message,\n generation,\n draftRetryCount: pendingWriteGate.draftRetryCount,\n draftRetryMax: pendingWriteGate.draftRetryMax,\n canRetry: pendingWriteGate.canRetry,\n writeDraft: pendingWriteGate.writeDraft,\n writeDrafts: pendingWriteGate.writeDrafts,\n editPolicy: pendingWriteGate.editPolicy,\n editPolicies: pendingWriteGate.editPolicies,\n });\n }\n\n /** Align local `sessionGeneration` with Redis before opening or after switching sessions. */\n private async syncSessionRunState(\n state: InternalState,\n sessionId: string,\n signal?: AbortSignal,\n ): Promise<void> {\n try {\n const body = await state.chat.getRunState(sessionId, signal);\n const snapshot = parseSessionRunState(body);\n if (!snapshot) return;\n this.applySessionRunSnapshot(state, sessionId, snapshot);\n this.notifyStateChange();\n } catch (err) {\n if (signal?.aborted) return;\n if (state.options.debug) {\n console.warn('[agent-chat] syncSessionRunState failed:', err);\n }\n }\n }\n\n private getActiveSessionRunSnapshot(state: InternalState): SessionRunSnapshot | null {\n const sessionId = state.activeSessionId;\n if (!sessionId) return null;\n const runState = state.sessionRuns.get(normalizeSessionId(sessionId));\n if (!runState) return null;\n return {\n generation: runState.sessionGeneration,\n activeRunId: runState.activeRunId,\n pendingJobCount: runState.pendingJobCount,\n redisBacked: runState.redisBacked,\n };\n }\n\n private noteActiveRunId(state: InternalState, sessionId: string, runId: number): void {\n this.getSessionRunState(state, sessionId).activeRunId = runId;\n }\n\n private isStaleSseGeneration(\n state: InternalState,\n sessionId: string,\n generation?: number,\n ): boolean {\n const runState = this.getSessionRunState(state, sessionId);\n return isStaleAgentRunEvent(runState.sessionGeneration, generation);\n }\n\n private resolveActiveRunIdForCancel(\n state: InternalState,\n sessionId: string,\n ): number | undefined {\n const runState = this.getSessionRunState(state, sessionId);\n if (runState.activeRunId != null) return runState.activeRunId;\n\n const key = normalizeSessionId(sessionId);\n const pending = state.writeConfirmationsBySession.get(key);\n if (pending?.runId != null) return pending.runId;\n\n const messages = this.getSessionMessagesList(state, sessionId);\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (message?.role === 'agent' && message.status === 'pending') {\n const runId = message.stream?.runId;\n if (runId != null) return runId;\n }\n }\n return undefined;\n }\n\n private shouldFilterAgentRunSse(action: ChatSseUiAction): boolean {\n switch (action.type) {\n case 'think':\n case 'result':\n case 'message-blocks':\n case 'complete':\n case 'error':\n case 'host-action':\n case 'write-confirmation-required':\n case 'write-confirmation-cancelled':\n return true;\n default:\n return false;\n }\n }\n\n private applySseRunGate(\n state: InternalState,\n sessionId: string,\n action: ChatSseUiAction,\n ): 'skip' | 'proceed' {\n if (!this.shouldFilterAgentRunSse(action)) return 'proceed';\n\n const generation = 'generation' in action ? action.generation : undefined;\n const runId = 'runId' in action ? action.runId : undefined;\n\n if (action.type === 'error' && action.code === 'RUN_CANCELLED') {\n if (!this.isStaleSseGeneration(state, sessionId, generation)) {\n const targetId = this.resolveStreamTargetMessageId(state, sessionId);\n this.finalizeStreamingTarget(state, sessionId, {\n cancelled: true,\n systemHint: targetId ? action.message : undefined,\n });\n this.hostToolStreamManagers.get(normalizeSessionId(sessionId))?.reset();\n }\n return 'skip';\n }\n\n if (this.isStaleSseGeneration(state, sessionId, generation)) {\n return 'skip';\n }\n\n if (runId != null) {\n this.noteActiveRunId(state, sessionId, runId);\n }\n return 'proceed';\n }\n\n private finalizeStreamingTarget(\n state: InternalState,\n sessionId: string,\n opts: { cancelled?: boolean; systemHint?: string } = {},\n ): void {\n const targetId = this.resolveStreamTargetMessageId(state, sessionId);\n if (!targetId) {\n if (opts.systemHint) {\n this.appendSystemMessageInSession(state, sessionId, opts.systemHint);\n }\n this.getSessionRunState(state, sessionId).activeRunId = null;\n return;\n }\n\n const snapshot = this.getSessionMessagesList(state, sessionId).find((m) => m.id === targetId);\n if (!snapshot || snapshot.role !== 'agent') return;\n\n const stream = snapshot.stream;\n const text = (stream?.resultText || snapshot.content.text || '').trim();\n if (!text) {\n this.removeAgentMessageInSession(state, sessionId, targetId);\n } else {\n this.replaceMessageInSession(\n state,\n sessionId,\n finalizeAgentReply(\n snapshot,\n { ...(stream ?? createEmptyAgentStream()), phase: 'complete' },\n { status: 'sent' },\n ),\n targetId,\n );\n }\n\n this.setStreamTargetMessageId(state, sessionId, null);\n this.getSessionRunState(state, sessionId).activeRunId = null;\n\n if (opts.systemHint) {\n this.appendSystemMessageInSession(state, sessionId, opts.systemHint);\n }\n this.notifyStateChange();\n }\n\n private getStreamHandle(\n state: InternalState,\n sessionId: string,\n ): SessionStreamHandle | undefined {\n return state.sessionStreams.get(normalizeSessionId(sessionId));\n }\n\n private setStreamTargetMessageId(\n state: InternalState,\n sessionId: string,\n messageId: string | null,\n ): void {\n const key = normalizeSessionId(sessionId);\n const handle = state.sessionStreams.get(key);\n if (handle) {\n handle.targetMessageId = messageId;\n return;\n }\n if (messageId) {\n this.pendingStreamTargets.set(key, messageId);\n } else {\n this.pendingStreamTargets.delete(key);\n }\n }\n\n private abortSessionStream(\n state: InternalState,\n sessionId: string,\n opts: { suppressReconnect?: boolean } = {},\n ): void {\n const key = normalizeSessionId(sessionId);\n if (opts.suppressReconnect !== false) {\n this.sessionStreamSuppressReconnect.add(key);\n this.cancelSessionStreamReconnect(key);\n }\n const handle = state.sessionStreams.get(key);\n if (!handle) return;\n try {\n handle.abort.abort();\n } catch {\n /* noop */\n }\n state.sessionStreams.delete(key);\n }\n\n private abortAllSessionStreams(state: InternalState): void {\n for (const key of [...state.sessionStreams.keys()]) {\n this.abortSessionStream(state, key, { suppressReconnect: true });\n }\n }\n\n private listStreamingSessionIds(state: InternalState): string[] {\n return [...state.sessionStreams.keys()];\n }\n\n private collectSessionsWithPendingReplies(state: InternalState): string[] {\n const ids = new Set<string>();\n if (state.activeSessionId && this.sessionHasPendingAgent(state.messages)) {\n ids.add(normalizeSessionId(state.activeSessionId));\n }\n for (const [sessionId, entry] of state.sessionMessagesCache) {\n if (this.sessionHasPendingAgent(entry.messages)) {\n ids.add(normalizeSessionId(sessionId));\n }\n }\n return [...ids];\n }\n\n private sessionHasPendingAgent(messages: AgentMessage[]): boolean {\n return messages.some(\n (m) => m.role === 'agent' && m.status === 'pending' && m.stream != null,\n );\n }\n\n /** Whether a session should keep (or restore) its SSE listener. */\n private sessionNeedsLiveStream(state: InternalState, sessionId: string): boolean {\n const key = normalizeSessionId(sessionId);\n if (this.sessionStreamSuppressReconnect.has(key)) return false;\n if (this.isViewingSession(state, sessionId)) return true;\n return this.sessionHasPendingAgent(this.getSessionMessagesList(state, sessionId));\n }\n\n /**\n * After switching sessions, finalize stale pending bubbles when the server\n * reports no active run (stream may have ended while the user was away).\n */\n private reconcilePendingRepliesAfterSessionSwitch(\n state: InternalState,\n sessionId: string,\n normalizedSessionId: string,\n ): void {\n if (!this.sessionHasPendingAgent(state.messages)) return;\n const runState = state.sessionRuns.get(normalizedSessionId);\n if (runState?.activeRunId != null) return;\n this.settlePendingAgentReplies(state, sessionId);\n }\n\n private cancelSessionStreamReconnect(sessionId: string): void {\n const key = normalizeSessionId(sessionId);\n const timer = this.sessionStreamReconnectTimers.get(key);\n if (timer == null) return;\n clearTimeout(timer);\n this.sessionStreamReconnectTimers.delete(key);\n }\n\n private cancelAllSessionStreamReconnects(): void {\n for (const timer of this.sessionStreamReconnectTimers.values()) {\n clearTimeout(timer);\n }\n this.sessionStreamReconnectTimers.clear();\n this.sessionStreamReconnectAttempts.clear();\n this.sessionStreamSuppressReconnect.clear();\n }\n\n private scheduleSessionStreamReconnect(state: InternalState, sessionId: string): void {\n const key = normalizeSessionId(sessionId);\n if (!this.sessionNeedsLiveStream(state, sessionId)) {\n this.sessionStreamReconnectAttempts.delete(key);\n return;\n }\n if (state.sessionStreams.has(key) || this.sessionStreamConnects.has(key)) return;\n if (this.sessionStreamReconnectTimers.has(key)) return;\n\n const attempt = (this.sessionStreamReconnectAttempts.get(key) ?? 0) + 1;\n if (attempt > 5) {\n this.sessionStreamReconnectAttempts.delete(key);\n if (state.options.debug && typeof console !== 'undefined') {\n console.warn(`[agent-chat] Session stream reconnect gave up for ${sessionId}`);\n }\n return;\n }\n this.sessionStreamReconnectAttempts.set(key, attempt);\n const delayMs = Math.min(500 * 2 ** (attempt - 1), 8_000);\n\n const timer = setTimeout(() => {\n this.sessionStreamReconnectTimers.delete(key);\n if (!this.state || this.state !== state) return;\n if (!this.sessionNeedsLiveStream(state, sessionId)) {\n this.sessionStreamReconnectAttempts.delete(key);\n return;\n }\n void this.ensureSessionStream(sessionId, { clearReconnectSuppress: false }).catch(() => {\n /* reported or suppressed in consumeSessionStream */\n });\n }, delayMs);\n this.sessionStreamReconnectTimers.set(key, timer);\n }\n\n private getSessionMessagesList(state: InternalState, sessionId: string): AgentMessage[] {\n if (this.isViewingSession(state, sessionId)) {\n return state.messages;\n }\n const key = normalizeSessionId(sessionId);\n return (\n state.sessionMessagesCache.get(key)?.messages ??\n state.sessionMessagesCache.get(sessionId)?.messages ??\n []\n );\n }\n\n private getSessionCacheMeta(\n state: InternalState,\n sessionId: string,\n ): { page: number; hasMore: boolean } {\n if (this.isViewingSession(state, sessionId)) {\n return {\n page: state.activeSessionMessagesPage,\n hasMore: state.activeSessionMessagesHasMore,\n };\n }\n const key = normalizeSessionId(sessionId);\n const cached =\n state.sessionMessagesCache.get(key) ?? state.sessionMessagesCache.get(sessionId);\n return { page: cached?.page ?? 1, hasMore: cached?.hasMore ?? false };\n }\n\n private commitSessionMessages(\n state: InternalState,\n sessionId: string,\n messages: AgentMessage[],\n meta?: { page?: number; hasMore?: boolean },\n ): void {\n const key = normalizeSessionId(sessionId);\n const fallback = this.getSessionCacheMeta(state, sessionId);\n const page = meta?.page ?? fallback.page;\n const hasMore = meta?.hasMore ?? fallback.hasMore;\n state.sessionMessagesCache.set(key, { messages, page, hasMore });\n if (this.isViewingSession(state, sessionId)) {\n state.messages = messages;\n state.activeSessionMessagesPage = page;\n state.activeSessionMessagesHasMore = hasMore;\n state.session.setSession(sessionId, messages);\n }\n this.notifyStateChange();\n }\n\n private patchMessageInSession(\n state: InternalState,\n sessionId: string,\n messageId: string,\n patch: (current: AgentMessage) => AgentMessage,\n ): AgentMessage | null {\n const messages = this.getSessionMessagesList(state, sessionId);\n const current = messages.find((m) => m.id === messageId);\n if (!current) return null;\n const next = patch(current);\n const updated = messages.map((m) => (m.id === messageId ? next : m));\n this.commitSessionMessages(state, sessionId, updated);\n this.bus.emit('message', { message: next, source: next.role === 'user' ? 'user' : 'agent' });\n return next;\n }\n\n private replaceMessageInSession(\n state: InternalState,\n sessionId: string,\n next: AgentMessage,\n previousId: string,\n ): void {\n const messages = this.getSessionMessagesList(state, sessionId);\n const updated = messages.map((m) => (m.id === previousId ? next : m));\n this.syncWriteConfirmationMessageId(state, previousId, next.id);\n this.commitSessionMessages(state, sessionId, updated);\n this.bus.emit('message', { message: next, source: 'agent' });\n }\n\n private removeAgentMessageInSession(\n state: InternalState,\n sessionId: string,\n messageId: string,\n ): void {\n const messages = this.getSessionMessagesList(state, sessionId);\n const updated = messages.filter((m) => m.id !== messageId);\n if (updated.length === messages.length) return;\n this.commitSessionMessages(state, sessionId, updated);\n }\n\n private appendAgentPlaceholderInSession(\n state: InternalState,\n sessionId: string,\n ): AgentMessage {\n const agentMessage: AgentMessage = {\n id: nanoId('msg'),\n role: 'agent',\n content: { type: 'text', text: '' },\n createdAt: Date.now(),\n status: 'pending',\n };\n const messages = [...this.getSessionMessagesList(state, sessionId), agentMessage];\n this.commitSessionMessages(state, sessionId, messages);\n this.bus.emit('message', { message: agentMessage, source: 'agent' });\n return agentMessage;\n }\n\n private appendSystemMessageInSession(\n state: InternalState,\n sessionId: string,\n text: string,\n ): void {\n const hint: AgentMessage = {\n id: nanoId('msg'),\n role: 'system',\n content: { type: 'text', text },\n createdAt: Date.now(),\n status: 'sent',\n };\n const messages = [...this.getSessionMessagesList(state, sessionId), hint];\n this.commitSessionMessages(state, sessionId, messages);\n this.bus.emit('message', { message: hint, source: 'agent' });\n }\n\n private async ensureSessionStream(\n sessionId: string,\n opts: { clearReconnectSuppress?: boolean } = {},\n ): Promise<void> {\n const state = this.requireState('ensureSessionStream');\n const normalizedId = normalizeSessionId(sessionId);\n if (opts.clearReconnectSuppress !== false) {\n this.sessionStreamSuppressReconnect.delete(normalizedId);\n this.cancelSessionStreamReconnect(normalizedId);\n }\n if (state.sessionStreams.has(normalizedId)) {\n return;\n }\n const inFlight = this.sessionStreamConnects.get(normalizedId);\n if (inFlight) {\n await inFlight;\n return;\n }\n const streamCtrl = new AbortController();\n const connectPromise = (async () => {\n await this.syncSessionRunState(state, sessionId, streamCtrl.signal);\n await this.connectSessionStream(sessionId, streamCtrl);\n })().finally(() => {\n this.sessionStreamConnects.delete(normalizedId);\n });\n this.sessionStreamConnects.set(normalizedId, connectPromise);\n await connectPromise;\n this.sessionStreamReconnectAttempts.delete(normalizedId);\n }\n\n private writeSessionMessagesCache(\n state: InternalState,\n sessionId: string,\n messages = state.messages,\n page = state.activeSessionMessagesPage,\n hasMore = state.activeSessionMessagesHasMore,\n ): void {\n state.sessionMessagesCache.set(normalizeSessionId(sessionId), { messages, page, hasMore });\n }\n\n private cacheActiveSessionMessages(state: InternalState): void {\n if (!state.activeSessionId) return;\n this.writeSessionMessagesCache(state, state.activeSessionId);\n }\n\n /** Finalize in-flight assistant turns; drop only empty placeholders. */\n private settlePendingAgentReplies(state: InternalState, sessionId?: string): void {\n const targetSessionId = sessionId ?? state.activeSessionId;\n if (!targetSessionId) return;\n\n const messages = this.getSessionMessagesList(state, targetSessionId);\n const next: AgentMessage[] = [];\n let changed = false;\n\n for (const message of messages) {\n if (message.role !== 'agent' || message.status !== 'pending') {\n next.push(message);\n continue;\n }\n changed = true;\n const stream = message.stream ?? createEmptyAgentStream();\n const text = (stream.resultText || message.content.text).trim();\n if (!text) continue;\n next.push(finalizeAgentReply(message, stream, { status: 'sent' }));\n }\n\n if (!changed) return;\n this.commitSessionMessages(state, targetSessionId, next);\n }\n\n private isExistingSentAssistantText(\n state: InternalState,\n sessionId: string,\n text: string,\n excludeId: string,\n ): boolean {\n const normalized = text.trim();\n if (!normalized) return false;\n return this.getSessionMessagesList(state, sessionId).some(\n (m) =>\n m.role === 'agent' &&\n m.id !== excludeId &&\n m.status === 'sent' &&\n m.content.text.trim() === normalized,\n );\n }\n\n private resolveStreamTargetMessageId(\n state: InternalState,\n sessionId: string,\n messageId?: string,\n ): string | null {\n if (messageId) return messageId;\n const key = normalizeSessionId(sessionId);\n const explicit =\n state.sessionStreams.get(key)?.targetMessageId ??\n this.pendingStreamTargets.get(key) ??\n null;\n const messages = this.getSessionMessagesList(state, sessionId);\n if (explicit && messages.some((m) => m.id === explicit)) return explicit;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (message?.role === 'agent' && (message.status ?? 'pending') === 'pending') {\n this.setStreamTargetMessageId(state, sessionId, message.id);\n return message.id;\n }\n }\n return null;\n }\n\n /** Empty assistant bubble for the in-flight turn (shown before SSE events arrive). */\n private appendAgentPlaceholder(state: InternalState): AgentMessage {\n const agentMessage: AgentMessage = {\n id: nanoId('msg'),\n role: 'agent',\n content: { type: 'text', text: '' },\n createdAt: Date.now(),\n status: 'pending',\n };\n state.messages = [...state.messages, agentMessage];\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n this.bus.emit('message', { message: agentMessage, source: 'agent' });\n return agentMessage;\n }\n\n private appendOptimisticUserMessage(\n state: InternalState,\n text: string,\n id?: string,\n contextMentions?: ContextMentionAttachment[],\n ): AgentMessage {\n const userMessage: AgentMessage = {\n id: id ?? nanoId('msg'),\n role: 'user',\n content: { type: 'text', text },\n createdAt: Date.now(),\n status: 'pending',\n contextMentions:\n contextMentions && contextMentions.length > 0 ? [...contextMentions] : undefined,\n };\n state.messages = [...state.messages, userMessage];\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n this.bus.emit('message', { message: userMessage, source: 'user' });\n return userMessage;\n }\n\n private async createChatSession(\n state: InternalState,\n content: string,\n signal: AbortSignal,\n pageContextOverride?: AgentChatPageContext | null,\n entityCommit?: EntityCommit | null,\n ): Promise<string> {\n const createBody = await state.chat.createSession(\n content,\n signal,\n this.getMessageSendContext(state, pageContextOverride, entityCommit),\n );\n const created = parseCreateSessionResponse(createBody);\n if (!created?.sessionId) {\n throw new AgentChatError('TRANSPORT_FAILED', 'POST /chat did not return sessionId', {\n details: { body: createBody },\n });\n }\n state.activeSessionId = created.sessionId;\n this.applyAutoAgentBinding(state, created.agent);\n const runGeneration = parseRunGeneration(createBody);\n if (runGeneration != null) {\n this.applySessionRunGeneration(state, created.sessionId, runGeneration);\n }\n state.activeSessionMessagesPage = 1;\n state.activeSessionMessagesHasMore = false;\n state.session.setSession(created.sessionId, state.messages);\n this.writeSessionMessagesCache(state, created.sessionId);\n this.bus.emit('session', state.session.getSession()!);\n this.schedulePrepareSession();\n return created.sessionId;\n }\n\n private applyUserMessageSent(state: InternalState, userMessage: AgentMessage): AgentMessage {\n const sentUser: AgentMessage = { ...userMessage, status: 'sent' };\n state.messages = state.messages.map((m) => (m.id === userMessage.id ? sentUser : m));\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n this.bus.emit('message', { message: sentUser, source: 'user' });\n return sentUser;\n }\n\n private async postUserMessageAndApply(\n state: InternalState,\n sessionId: string,\n content: string,\n signal: AbortSignal,\n userMessage: AgentMessage,\n pageContextOverride?: AgentChatPageContext | null,\n entityCommit?: EntityCommit | null,\n ): Promise<AgentMessage> {\n const postBody = await state.chat.postMessage(\n sessionId,\n content,\n signal,\n this.getMessageSendContext(state, pageContextOverride, entityCommit),\n );\n const posted = parsePostedMessage(postBody);\n const sentUser: AgentMessage = posted\n ? {\n ...this.toAgentMessage(posted as ServerMessage),\n status: 'sent',\n contextMentions: userMessage.contextMentions,\n }\n : { ...userMessage, status: 'sent' };\n if (posted?.runGeneration != null) {\n this.applySessionRunGeneration(state, sessionId, posted.runGeneration);\n }\n state.messages = state.messages.map((m) => (m.id === userMessage.id ? sentUser : m));\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n this.bus.emit('message', { message: sentUser, source: sentUser.role });\n return sentUser;\n }\n\n private syncWriteConfirmationMessageId(\n state: InternalState,\n previousId: string,\n nextId: string,\n ): void {\n if (previousId === nextId) return;\n\n for (const [sessionKey, confirmation] of state.writeConfirmationsBySession) {\n if (confirmation.messageId !== previousId) continue;\n const updated = { ...confirmation, messageId: nextId };\n state.writeConfirmationsBySession.set(sessionKey, updated);\n if (\n state.activeSessionId &&\n normalizeSessionId(state.activeSessionId) === sessionKey\n ) {\n state.writeConfirmation = updated;\n }\n return;\n }\n\n if (state.writeConfirmation?.messageId === previousId) {\n state.writeConfirmation = { ...state.writeConfirmation, messageId: nextId };\n }\n }\n\n private async postWriteGateAction(\n state: InternalState,\n sessionId: string,\n writeGate: WriteGate,\n signal: AbortSignal,\n ): Promise<void> {\n const body = await state.chat.postWriteGateDecision(sessionId, writeGate, signal);\n const posted = parsePostedMessage(body);\n if (posted?.runGeneration != null) {\n this.applySessionRunGeneration(state, sessionId, posted.runGeneration, {\n clearActiveRun: false,\n });\n }\n }\n\n /**\n * Open `GET /chat/{sessionId}/stream` and resolve once the SSE connection is up.\n * Consumption continues in the background until the stream ends or is aborted.\n */\n private connectSessionStream(\n sessionId: string,\n streamCtrl: AbortController,\n ): Promise<void> {\n const state = this.requireState('connectSessionStream');\n const normalizedId = normalizeSessionId(sessionId);\n state.sessionStreams.set(normalizedId, {\n abort: streamCtrl,\n targetMessageId: this.pendingStreamTargets.get(normalizedId) ?? null,\n });\n this.pendingStreamTargets.delete(normalizedId);\n state.abortControllers.add(streamCtrl);\n\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n const settleResolve = () => {\n if (settled) return;\n settled = true;\n resolve();\n };\n const settleReject = (err: unknown) => {\n if (settled) return;\n settled = true;\n reject(err);\n };\n\n void this.consumeSessionStream(sessionId, streamCtrl, settleResolve)\n .catch((err) => {\n if (!settled) settleReject(err);\n })\n .finally(() => {\n state.abortControllers.delete(streamCtrl);\n state.sessionStreams.delete(normalizedId);\n this.scheduleSessionStreamReconnect(state, sessionId);\n });\n });\n }\n\n private async consumeSessionStream(\n sessionId: string,\n ctrl: AbortController,\n onConnected?: () => void,\n ): Promise<void> {\n const state = this.requireState('consumeSessionStream');\n\n const getAgent = (id: string | null): AgentMessage | undefined => {\n if (!id) return undefined;\n return this.getSessionMessagesList(state, sessionId).find((m) => m.id === id);\n };\n\n const replaceAgentMessage = (next: AgentMessage, previousId: string): void => {\n this.replaceMessageInSession(state, sessionId, next, previousId);\n };\n\n try {\n for await (const chunk of state.chat.streamSession(sessionId, {\n signal: ctrl.signal,\n onConnected,\n })) {\n if (state.options.debug) {\n console.debug('[agent-chat] SSE', chunk.event, chunk.data.slice(0, 120));\n }\n\n const action = parseChatSseEvent(chunk.event, chunk.data);\n const gate = this.applySseRunGate(state, sessionId, action);\n if (gate === 'skip') continue;\n\n let currentTargetId =\n action.type === 'think' ||\n action.type === 'result' ||\n action.type === 'message-blocks' ||\n action.type === 'complete'\n ? this.resolveStreamTargetMessageId(state, sessionId, action.messageId)\n : null;\n currentTargetId = this.maybeRebindStreamMessageId(\n state,\n sessionId,\n currentTargetId,\n action.type === 'think' ||\n action.type === 'result' ||\n action.type === 'message-blocks' ||\n action.type === 'complete'\n ? action.messageId\n : undefined,\n );\n\n switch (action.type) {\n case 'think': {\n if (!currentTargetId) break;\n this.patchMessageInSession(state, sessionId, currentTargetId, (current) => {\n const stream = { ...(current.stream ?? createEmptyAgentStream()) };\n const thinkText =\n action.mode === 'append'\n ? `${stream.thinkText}${action.text}`\n : action.text;\n const hasResult =\n Boolean(stream.resultText?.trim()) ||\n Boolean((stream.resultBlocks ?? current.blocks ?? []).length);\n return {\n ...current,\n status: 'pending',\n content: hasResult ? current.content : { type: 'text', text: '' },\n stream: {\n ...stream,\n thinkText,\n runId: action.runId ?? stream.runId,\n phase: hasResult ? 'result' : 'thinking',\n },\n };\n });\n break;\n }\n case 'result': {\n if (!currentTargetId) break;\n if (\n action.mode === 'replace' &&\n this.isExistingSentAssistantText(state, sessionId, action.text, currentTargetId)\n ) {\n break;\n }\n this.patchMessageInSession(state, sessionId, currentTargetId, (current) => {\n const stream = { ...(current.stream ?? createEmptyAgentStream()) };\n const nextResult =\n action.mode === 'append' ? `${stream.resultText}${action.text}` : action.text;\n return {\n ...current,\n status: 'pending',\n content: { type: 'text', text: nextResult },\n stream: {\n ...stream,\n resultText: nextResult,\n runId: action.runId ?? stream.runId,\n phase: 'result',\n },\n };\n });\n break;\n }\n case 'message-blocks': {\n const sessionConfirmation = state.writeConfirmationsBySession.get(\n normalizeSessionId(sessionId),\n );\n if (\n !currentTargetId &&\n action.runId != null &&\n sessionConfirmation?.submitting\n ) {\n const placeholder = this.appendAgentPlaceholderInSession(state, sessionId);\n this.setStreamTargetMessageId(state, sessionId, placeholder.id);\n currentTargetId = placeholder.id;\n }\n if (!currentTargetId) break;\n const streamSeq = action.seq;\n this.patchMessageInSession(state, sessionId, currentTargetId, (current) => {\n const stream = { ...(current.stream ?? createEmptyAgentStream()) };\n const seenSeq = new Set<number>(stream.seenSeq ?? []);\n if (streamSeq != null && seenSeq.has(streamSeq)) return current;\n if (streamSeq != null) seenSeq.add(streamSeq);\n\n const previousBlocks = (stream.resultBlocks ?? current.blocks ?? []) as CoreMessageBlock[];\n let nextBlocks = previousBlocks;\n if (action.action === 'stream') {\n if (action.streamMode === 'full') {\n nextBlocks = applyStreamFull(previousBlocks, (action.blocks ?? []) as CoreMessageBlock[]);\n } else {\n nextBlocks = applyStreamDelta(previousBlocks, (action.blocks ?? []) as CoreMessageBlock[]);\n }\n } else if (action.action === 'patch') {\n nextBlocks = applyPatches(\n previousBlocks,\n (action.patches ?? []).map((patch) => ({\n replaceId: patch.replaceId,\n block: patch.block as CoreMessageBlock,\n })),\n );\n }\n\n nextBlocks = unwrapBlocksJsonEnvelope(nextBlocks);\n const nextResult = blocksToText(nextBlocks);\n return {\n ...current,\n status: 'pending',\n content: { type: 'text', text: nextResult },\n blocks: nextBlocks,\n stream: {\n ...stream,\n runId: action.runId ?? stream.runId,\n resultBlocks: nextBlocks,\n resultText: nextResult,\n phase: 'result',\n seenSeq: [...seenSeq],\n },\n };\n });\n break;\n }\n case 'write-confirmation-required': {\n const messages = this.getSessionMessagesList(state, sessionId);\n const messageId =\n this.getStreamHandle(state, sessionId)?.targetMessageId ??\n [...messages].reverse().find((m) => m.role === 'agent')?.id;\n this.persistWriteConfirmation(state, sessionId, {\n awaiting: true,\n submitting: false,\n runId: action.runId,\n turnId: action.turnId,\n message: action.message,\n messageId,\n generation: action.generation,\n draftRetryCount: action.draftRetryCount,\n draftRetryMax: action.draftRetryMax,\n canRetry: action.canRetry,\n writeDraft: action.writeDraft ?? null,\n writeDrafts: action.writeDrafts ?? null,\n editPolicy: action.editPolicy ?? null,\n editPolicies: action.editPolicies ?? null,\n });\n this.notifyStateChange();\n break;\n }\n case 'write-confirmation-cancelled': {\n this.persistWriteConfirmation(state, sessionId, null);\n this.appendSystemMessageInSession(state, sessionId, action.message);\n break;\n }\n case 'host-action': {\n if (action.ssePayload) {\n this.ingestHostActionSse(state, sessionId, action.ssePayload, undefined, 'chat');\n } else if (action.action) {\n this.emitHostAction(state, action.action);\n this.emitPageAgentCompleteFromAction(action.action, 'chat');\n }\n break;\n }\n case 'complete': {\n if (action.status === 'cancelled') {\n if (currentTargetId) {\n this.finalizeStreamingTarget(state, sessionId);\n } else {\n this.getSessionRunState(state, sessionId).activeRunId = null;\n }\n this.hostToolStreamManagers.get(normalizeSessionId(sessionId))?.reset();\n break;\n }\n if (action.status === 'failed') {\n if (currentTargetId) {\n const current = getAgent(currentTargetId);\n if (current) {\n const stream = current.stream ?? createEmptyAgentStream();\n replaceAgentMessage(\n {\n ...current,\n status: 'failed',\n stream: {\n ...stream,\n phase: 'error',\n errorMessage: action.reason ?? 'Generation failed',\n },\n },\n currentTargetId,\n );\n }\n }\n this.setStreamTargetMessageId(state, sessionId, null);\n this.getSessionRunState(state, sessionId).activeRunId = null;\n this.hostToolStreamManagers.get(normalizeSessionId(sessionId))?.reset();\n break;\n }\n if (!currentTargetId) break;\n const current = getAgent(currentTargetId);\n if (!current) break;\n const sessionKey = normalizeSessionId(sessionId);\n const awaitingConfirm = state.writeConfirmationsBySession.get(sessionKey)?.awaiting;\n const stream = { ...(current.stream ?? createEmptyAgentStream()), phase: 'complete' as const };\n let finalized: AgentMessage;\n if (action.serverMessage) {\n const parsed = this.toAgentMessage(action.serverMessage as ServerMessage);\n finalized = finalizeAgentReply(\n { ...current, content: parsed.content, blocks: parsed.blocks ?? current.blocks },\n { ...stream, resultText: parsed.content.text, resultBlocks: parsed.blocks ?? stream.resultBlocks },\n { status: 'sent' },\n );\n } else {\n finalized = finalizeAgentReply(current, stream, { status: 'sent' });\n }\n const serverId = this.resolveCompleteServerMessageId(action);\n if (\n serverId &&\n serverId !== currentTargetId &&\n !this.getSessionMessagesList(state, sessionId).some((m) => m.id === serverId)\n ) {\n replaceAgentMessage({ ...finalized, id: serverId }, currentTargetId);\n } else {\n replaceAgentMessage(finalized, currentTargetId);\n }\n this.setStreamTargetMessageId(state, sessionId, null);\n this.getSessionRunState(state, sessionId).activeRunId = null;\n this.hostToolStreamManagers.get(normalizeSessionId(sessionId))?.reset();\n if (!awaitingConfirm) {\n this.persistWriteConfirmation(state, sessionId, null);\n }\n void this.alignPersistedMessageIds(state, sessionId, {\n preferLocalId: currentTargetId,\n preferServerId: serverId,\n }).catch(() => {\n /* best-effort id alignment for feedback */\n });\n const finalizedId = serverId && serverId !== currentTargetId ? serverId : currentTargetId;\n if (action.runId != null) {\n this.applySkillIntentAlignment(state, {\n sessionId,\n runId: action.runId,\n assistantMessageId: finalizedId,\n });\n }\n this.maybeNotifyBackgroundReply(state, sessionId);\n break;\n }\n case 'error': {\n if (action.code === 'WRITE_CONFIRMATION_EXPIRED') {\n this.persistWriteConfirmation(state, sessionId, null);\n this.notifyStateChange();\n } else if (\n action.code === 'EDITED_WRITE_ARGS_INVALID' ||\n action.code === 'EDITED_LOCKED_FIELD' ||\n action.code === 'EDITED_FIELD_NOT_ALLOWED' ||\n action.code === 'MULTI_WRITE_EDIT_NOT_SUPPORTED' ||\n action.code === 'DRAFT_RETRY_LIMIT_EXCEEDED'\n ) {\n const key = normalizeSessionId(sessionId);\n const current = state.writeConfirmationsBySession.get(key);\n if (current) {\n const updated: WriteConfirmationState = {\n ...current,\n awaiting: true,\n submitting: false,\n gateError: action.message,\n gateErrorCode: action.code,\n canRetry:\n action.code === 'DRAFT_RETRY_LIMIT_EXCEEDED' ? false : current.canRetry,\n };\n this.persistWriteConfirmation(state, sessionId, updated);\n this.notifyStateChange();\n break;\n }\n }\n throw new AgentChatError('MESSAGE_FAILED', action.message, {\n details: action.code ? { code: action.code } : undefined,\n });\n }\n case 'noop':\n break;\n default:\n break;\n }\n }\n\n const snapshot = getAgent(this.resolveStreamTargetMessageId(state, sessionId));\n if (snapshot && (snapshot.status ?? 'pending') === 'pending') {\n const stream = snapshot.stream;\n const text = (stream?.resultText || snapshot.content.text || '').trim();\n if (!text) {\n this.removeAgentMessageInSession(state, sessionId, snapshot.id);\n } else {\n replaceAgentMessage(\n finalizeAgentReply(\n snapshot,\n { ...(stream ?? createEmptyAgentStream()), phase: 'complete' as const },\n { status: 'sent' },\n ),\n snapshot.id,\n );\n }\n this.maybeNotifyBackgroundReply(state, sessionId);\n }\n void this.alignPersistedMessageIds(state, sessionId).catch(() => {\n /* best-effort id alignment for feedback */\n });\n } catch (err) {\n if ((err as { name?: string })?.name === 'AbortError') {\n const snapshot = getAgent(this.resolveStreamTargetMessageId(state, sessionId));\n if (!snapshot) return;\n const stream = snapshot.stream ?? createEmptyAgentStream();\n const text = (stream.resultText || snapshot.content.text).trim();\n if (!text) {\n this.removeAgentMessageInSession(state, sessionId, snapshot.id);\n } else {\n replaceAgentMessage(\n finalizeAgentReply(snapshot, { ...stream, phase: 'complete' }, { status: 'sent' }),\n snapshot.id,\n );\n }\n return;\n }\n const snapshot = getAgent(this.resolveStreamTargetMessageId(state, sessionId));\n if (snapshot) {\n const stream = snapshot.stream ?? createEmptyAgentStream();\n replaceAgentMessage(\n {\n ...snapshot,\n status: 'failed',\n stream: {\n ...stream,\n phase: 'error',\n errorMessage: err instanceof Error ? err.message : 'Stream failed',\n },\n },\n snapshot.id,\n );\n }\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to receive assistant reply', {\n cause: err,\n });\n if (this.isViewingSession(state, sessionId)) {\n this.reportError(wrapped);\n } else if (state.options.debug && typeof console !== 'undefined') {\n console.warn(\n `[agent-chat] Background stream error for session ${sessionId} (suppressed from UI):`,\n wrapped,\n );\n }\n }\n }\n\n private toAgentMessage(input: ServerMessage): AgentMessage {\n const role =\n input.role === 'assistant' ? 'agent' : input.role === 'user' ? 'user' : 'system';\n const createdAtRaw = input.createdAt;\n const createdAt =\n typeof createdAtRaw === 'number'\n ? createdAtRaw\n : new Date(createdAtRaw as string | Date).getTime();\n const blocks = parseStoredBlocks(input.content);\n const text = blocks ? blocksToText(blocks) : input.content ?? '';\n return {\n id: String(input.id),\n role,\n content: { type: 'text', text },\n blocks,\n createdAt: Number.isFinite(createdAt) ? createdAt : Date.now(),\n status: 'sent',\n };\n }\n\n private resolveCompleteServerMessageId(action: {\n serverMessage?: { id?: string | number };\n messageId?: string;\n }): string | undefined {\n if (action.serverMessage?.id != null) {\n return String(action.serverMessage.id);\n }\n if (action.messageId && isPersistedMessageId(action.messageId)) {\n return action.messageId;\n }\n return undefined;\n }\n\n /**\n * SSE placeholders use client ids until the assistant message is persisted.\n * Match unresolved local agent bubbles to server ids from the latest session page.\n */\n private async alignPersistedMessageIds(\n state: InternalState,\n sessionId: string,\n opts: { preferLocalId?: string; preferServerId?: string } = {},\n ): Promise<void> {\n const preferLocalId = opts.preferLocalId?.trim();\n const preferServerId =\n opts.preferServerId && isPersistedMessageId(opts.preferServerId)\n ? opts.preferServerId\n : undefined;\n\n if (preferLocalId && preferServerId) {\n const messages = this.getSessionMessagesList(state, sessionId);\n const current = messages.find((message) => message.id === preferLocalId);\n if (current && !isPersistedMessageId(current.id) && !messages.some((m) => m.id === preferServerId)) {\n const updated = messages.map((message) =>\n message.id === preferLocalId ? { ...message, id: preferServerId } : message,\n );\n this.syncWriteConfirmationMessageId(state, preferLocalId, preferServerId);\n const handle = this.getStreamHandle(state, sessionId);\n if (handle?.targetMessageId === preferLocalId) {\n handle.targetMessageId = preferServerId;\n }\n this.commitSessionMessages(state, sessionId, updated);\n void this.syncMessageFeedbacks(state, sessionId).catch(() => {\n /* best-effort */\n });\n return;\n }\n }\n\n const messages = this.getSessionMessagesList(state, sessionId);\n const unresolved = messages.filter(\n (message) =>\n message.role === 'agent' &&\n message.status === 'sent' &&\n !message.stream &&\n !isPersistedMessageId(message.id),\n );\n if (unresolved.length === 0) return;\n\n const detailPage = await this.fetchSessionMessagesPage(state, sessionId, 1);\n const serverAgents = detailPage.messages\n .map((raw) => this.toAgentMessage(raw as ServerMessage))\n .filter((message) => message.role === 'agent');\n\n const claimedServerIds = new Set(\n messages\n .filter((message) => message.role === 'agent' && isPersistedMessageId(message.id))\n .map((message) => message.id),\n );\n\n const available = serverAgents.filter((message) => !claimedServerIds.has(message.id));\n if (available.length === 0) return;\n\n const pairsStart = Math.max(0, available.length - unresolved.length);\n let changed = false;\n\n const updated = messages.map((message) => {\n const unresolvedIndex = unresolved.findIndex((candidate) => candidate.id === message.id);\n if (unresolvedIndex < 0) return message;\n const server = available[pairsStart + unresolvedIndex];\n if (!server || !isPersistedMessageId(server.id)) return message;\n changed = true;\n this.syncWriteConfirmationMessageId(state, message.id, server.id);\n return {\n ...message,\n id: server.id,\n createdAt: server.createdAt,\n };\n });\n\n if (!changed) return;\n this.commitSessionMessages(state, sessionId, updated);\n void this.syncMessageFeedbacks(state, sessionId).catch(() => {\n /* best-effort */\n });\n }\n\n private maybeRebindStreamMessageId(\n state: InternalState,\n sessionId: string,\n currentTargetId: string | null,\n incomingMessageId?: string,\n ): string | null {\n if (!currentTargetId || !incomingMessageId || !isPersistedMessageId(incomingMessageId)) {\n return currentTargetId;\n }\n if (currentTargetId === incomingMessageId) return currentTargetId;\n if (isPersistedMessageId(currentTargetId)) return currentTargetId;\n\n const messages = this.getSessionMessagesList(state, sessionId);\n if (messages.some((message) => message.id === incomingMessageId)) {\n return currentTargetId;\n }\n\n const current = messages.find((message) => message.id === currentTargetId);\n if (!current) return incomingMessageId;\n\n const updated = messages.map((message) =>\n message.id === currentTargetId ? { ...message, id: incomingMessageId } : message,\n );\n const handle = this.getStreamHandle(state, sessionId);\n if (handle?.targetMessageId === currentTargetId) {\n handle.targetMessageId = incomingMessageId;\n }\n this.commitSessionMessages(state, sessionId, updated);\n return incomingMessageId;\n }\n\n private buildOptimisticFeedback(\n messageId: number,\n body: UpsertMessageFeedbackBody,\n ): MessageFeedbackView {\n const now = new Date().toISOString();\n if (body.rating === 'up') {\n return {\n messageId,\n rating: 'up',\n reasonTags: [],\n comment: null,\n createdAt: now,\n updatedAt: now,\n };\n }\n return {\n messageId,\n rating: 'down',\n reasonTags: body.reasonTags ?? [],\n comment: body.comment?.trim() || null,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n private patchMessageFeedback(\n state: InternalState,\n messageId: string,\n feedback: MessageFeedbackView | null,\n ): void {\n const next = state.messages.map((message) =>\n message.id === messageId ? { ...message, feedback } : message,\n );\n if (next.every((message, index) => message === state.messages[index])) return;\n state.messages = next;\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n }\n\n private collectFeedbackMessageIds(messages: AgentMessage[]): number[] {\n const ids: number[] = [];\n for (const message of messages) {\n if (message.role !== 'agent' || message.status !== 'sent' || message.stream) continue;\n const numericId = parsePersistedMessageId(message.id);\n if (numericId !== null) ids.push(numericId);\n }\n return ids;\n }\n\n private async syncMessageFeedbacks(state: InternalState, sessionId: string): Promise<void> {\n const messages = this.getSessionMessagesList(state, sessionId);\n const messageIds = this.collectFeedbackMessageIds(messages);\n if (messageIds.length === 0) return;\n\n const batch = await state.feedback.batchFeedbacks(sessionId, messageIds);\n const map = new Map<string, MessageFeedbackView>(\n batch.items.map((row: MessageFeedbackView) => [String(row.messageId), row]),\n );\n let changed = false;\n\n const updated = messages.map((message) => {\n if (message.role !== 'agent' || !isPersistedMessageId(message.id)) return message;\n const nextFeedback: MessageFeedbackView | null = map.get(message.id) ?? null;\n const prev = message.feedback ?? null;\n if (prev === null && nextFeedback === null) return message;\n if (\n prev &&\n nextFeedback &&\n prev.rating === nextFeedback.rating &&\n prev.updatedAt === nextFeedback.updatedAt\n ) {\n return message;\n }\n changed = true;\n return { ...message, feedback: nextFeedback };\n });\n\n if (!changed) return;\n this.commitSessionMessages(state, sessionId, updated);\n }\n\n}\n\nfunction normalizePrepareSessionOptions(\n signalOrOptions?: AbortSignal | PrepareSessionOptions,\n): PrepareSessionOptions {\n if (signalOrOptions == null) return {};\n if (\n typeof signalOrOptions === 'object' &&\n 'aborted' in signalOrOptions &&\n typeof (signalOrOptions as AbortSignal).addEventListener === 'function'\n ) {\n return { signal: signalOrOptions as AbortSignal };\n }\n return signalOrOptions as PrepareSessionOptions;\n}\n\nfunction authUserToContext(user: AppClientAuthData['user']): UserContext | undefined {\n if (!user) return undefined;\n return {\n id: String(user.id),\n email: user.email,\n name: user.username,\n };\n}\n\nfunction toAgentChatErrorPayload(err: unknown): AgentChatErrorPayload {\n if (err instanceof AgentChatError) {\n return {\n code: err.code,\n message: err.message,\n cause: (err as { cause?: unknown }).cause,\n };\n }\n return {\n code: 'TRANSPORT_FAILED',\n message: err instanceof Error ? err.message : 'Unknown error',\n cause: err,\n };\n}\n\nfunction readWriteGateServerCode(err: unknown): string | undefined {\n if (!(err instanceof AgentChatError)) return undefined;\n const details = err.details;\n if (!details) return undefined;\n if (typeof details.serverCode === 'string') return details.serverCode;\n if (typeof details.code === 'string') return details.code;\n return undefined;\n}\n\nexport function createAgentChat(): AgentChatClient {\n return new AgentChatClient();\n}\n","import { createContext } from 'react';\nimport type { AgentChatClient } from '../core/client/instance';\n\nexport const AgentChatContext = createContext<AgentChatClient | null>(null);\n\nexport const MISSING_PROVIDER_MESSAGE =\n 'useAgentChat must be used within <AgentChatProvider>. ' +\n 'Wrap your app: <AgentChatProvider dsn=\"...\"><App /></AgentChatProvider>, ' +\n 'or use <AgentChat dsn=\"...\" /> for the all-in-one integration.';\n","import {\n Suspense,\n lazy,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { createAgentChat, type AgentChatClient } from '../core/client/instance';\nimport type { AgentChatOptions } from '../types';\nimport { AgentChatContext } from './context';\n\n/** Chat shell (antd) — separate async chunk so sync entry stays light for Umi/webpack. */\nconst AgentChatEmbedded = lazy(() => import('./AgentChatEmbedded'));\n\nexport interface AgentChatProps extends AgentChatOptions {\n children?: ReactNode;\n}\n\nfunction syncRuntimeOptions(\n client: AgentChatClient,\n options: Pick<AgentChatOptions, 'attachPageContext' | 'pageContext'>,\n): void {\n client.applyRuntimeOptions({\n attachPageContext: options.attachPageContext,\n pageContext: options.pageContext,\n });\n}\n\n/**\n * Recommended React integration — import and render directly.\n *\n * Host app content passed as `children` always renders, even when SDK init or\n * app-client auth fails. Only the portaled chat widget is gated on init.\n * The widget UI (antd) loads in an async chunk after init — still out-of-the-box,\n * without pulling the full UI into the host's sync dependency graph.\n *\n * @example\n * ```tsx\n * import { AgentChat } from 'omnix-chat/react';\n *\n * export function App() {\n * return (\n * <AgentChat dsn=\"your-dsn\" baseUrl=\"http://localhost:3030\">\n * <YourHostApp />\n * </AgentChat>\n * );\n * }\n * ```\n */\nexport function AgentChat({ children, dsn, ...options }: AgentChatProps) {\n if (!dsn) {\n throw new Error('<AgentChat> requires a `dsn` prop.');\n }\n\n const [client] = useState<AgentChatClient>(() => createAgentChat());\n const [chatReady, setChatReady] = useState(false);\n const generationRef = useRef(0);\n const initKeyRef = useRef<string | null>(null);\n\n const pageContextKey = useMemo(\n () => JSON.stringify(options.pageContext ?? null),\n [options.pageContext],\n );\n\n useEffect(() => {\n const key = JSON.stringify({\n dsn,\n baseUrl: options.baseUrl,\n token: options.accountToken ?? options.userAccessToken,\n });\n const gen = ++generationRef.current;\n let cancelled = false;\n\n void (async () => {\n if (initKeyRef.current === key) {\n syncRuntimeOptions(client, options);\n setChatReady(true);\n return;\n }\n if (initKeyRef.current !== null) {\n client.destroy();\n initKeyRef.current = null;\n setChatReady(false);\n }\n\n await client.init({\n ...options,\n dsn,\n });\n if (cancelled || gen !== generationRef.current) return;\n\n initKeyRef.current = key;\n syncRuntimeOptions(client, options);\n setChatReady(true);\n if (options.autoOpen) client.open();\n })().catch((err) => {\n if (options.debug) {\n console.error('[agent-chat] AgentChat init failed:', err);\n }\n if (!cancelled && gen === generationRef.current) {\n setChatReady(true);\n }\n });\n\n return () => {\n cancelled = true;\n const effectGen = gen;\n queueMicrotask(() => {\n if (effectGen !== generationRef.current) return;\n if (initKeyRef.current === key) {\n client.destroy();\n initKeyRef.current = null;\n setChatReady(false);\n }\n });\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- re-init when connection identity changes\n }, [dsn, options.baseUrl, options.accountToken, options.userAccessToken]);\n\n useEffect(() => {\n syncRuntimeOptions(client, {\n attachPageContext: options.attachPageContext,\n pageContext: options.pageContext,\n });\n }, [\n client,\n options.attachPageContext,\n pageContextKey,\n options.pageContext,\n ]);\n\n return (\n <AgentChatContext.Provider value={client}>\n {children}\n {chatReady ? (\n <Suspense fallback={null}>\n <AgentChatEmbedded client={client} position={options.position} />\n </Suspense>\n ) : null}\n </AgentChatContext.Provider>\n );\n}\n","import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { createAgentChat, type AgentChatClient } from '../core/client/instance';\nimport type { AgentChatOptions } from '../types';\nimport { AgentChatContext } from './context';\n\nexport interface AgentChatProviderProps extends AgentChatOptions {\n children?: ReactNode;\n}\n\n/**\n * Wraps an `AgentChatClient` lifecycle with React semantics:\n * - Creates one client per mount (or per `dsn` change).\n * - In Strict Mode the effect is intentionally double-invoked; we use a\n * `mountedRef` guard so `init()` runs at most once per logical mount.\n * - Re-runs init() if the `dsn` prop changes between renders, after first\n * destroying the previous instance to avoid `ALREADY_INITIALIZED`.\n */\nexport function AgentChatProvider({ children, ...options }: AgentChatProviderProps) {\n const { dsn } = options;\n // Stash the latest non-dsn options in a ref so we can re-init on dsn changes\n // without triggering effects on every render.\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const [client] = useState<AgentChatClient>(() => createAgentChat());\n const initializedDsnRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (initializedDsnRef.current === dsn) return; // Strict Mode guard\n let cancelled = false;\n let initialized = false;\n\n const run = async () => {\n if (initializedDsnRef.current !== null) {\n client.destroy();\n }\n await client.init({ ...optionsRef.current, dsn });\n if (cancelled) {\n client.destroy();\n return;\n }\n initialized = true;\n initializedDsnRef.current = dsn;\n };\n void run().catch((err) => {\n if (optionsRef.current.debug) {\n console.error('[agent-chat] failed to initialize provider instance:', err);\n }\n });\n\n return () => {\n // Effect cleanup runs on dsn change AND on unmount; in Strict Mode the\n // first cleanup happens after the first synchronous double-invocation.\n // We let dsn-change handle its own destroy() above (before re-init), so\n // here we only destroy on real unmount: detected by the ref still\n // matching the dsn we just initialized with.\n cancelled = true;\n if (initialized || initializedDsnRef.current === dsn) {\n client.destroy();\n initializedDsnRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- intentional: only react to dsn\n }, [dsn]);\n\n const ctxValue = useMemo(() => client, [client]);\n\n return <AgentChatContext.Provider value={ctxValue}>{children}</AgentChatContext.Provider>;\n}\n","import { useContext, useRef, useSyncExternalStore } from 'react';\nimport { AgentChatContext, MISSING_PROVIDER_MESSAGE } from './context';\nimport type { AgentChatClient } from '../core/client/instance';\nimport type { AgentChatState } from '../types';\n\n/** Client instance only — does not subscribe to {@link AgentChatState} updates. */\nexport function useAgentChatClient(): AgentChatClient {\n const instance = useContext(AgentChatContext);\n if (!instance) {\n throw new Error(MISSING_PROVIDER_MESSAGE);\n }\n return instance;\n}\n\n/**\n * Subscribe to a slice of {@link AgentChatState}. Re-renders only when the selected\n * value changes (`isEqual`). Use in hooks that do not need the full chat state.\n */\nexport function useAgentChatStore<T>(\n selector: (state: AgentChatState) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n const instance = useAgentChatClient();\n const selectorRef = useRef(selector);\n selectorRef.current = selector;\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n const sliceRef = useRef<T | undefined>(undefined);\n\n const getSnapshot = (): T => {\n const next = selectorRef.current(instance.getState());\n const prev = sliceRef.current;\n if (prev !== undefined && isEqualRef.current(prev, next)) {\n return prev;\n }\n sliceRef.current = next;\n return next;\n };\n\n const subscribe = (onStoreChange: () => void) =>\n instance.subscribeStateChange(() => {\n const next = selectorRef.current(instance.getState());\n const prev = sliceRef.current;\n if (prev !== undefined && isEqualRef.current(prev, next)) {\n return;\n }\n sliceRef.current = next;\n onStoreChange();\n });\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n","import { useCallback, useSyncExternalStore } from 'react';\nimport { useAgentChatClient } from './useAgentChatClient';\nimport type { AgentChatClient } from '../core/client/instance';\nimport type {\n AgentChatErrorPayload,\n AgentChatState,\n AgentChatRouteContext,\n AgentMessage,\n AgentChatLoginCredentials,\n} from '../types';\n\nexport interface UseAgentChatResult {\n instance: AgentChatClient;\n state: AgentChatState;\n isOpen: boolean;\n open: () => void;\n close: () => void;\n toggle: () => void;\n login: (credentials: AgentChatLoginCredentials) => Promise<void>;\n logout: () => void;\n isLoggedIn: boolean;\n sendMessage: (text: string) => Promise<AgentMessage>;\n selectSession: (sessionId: string) => Promise<void>;\n refreshSessions: () => Promise<void>;\n loadMoreSessions: () => Promise<void>;\n loadMoreSessionMessages: () => Promise<void>;\n selectAgent: (agentId: string) => Promise<void>;\n selectSkill: (skillId: string) => void;\n sessions: AgentChatState['sessions'];\n agents: AgentChatState['agents'];\n skills: AgentChatState['skills'];\n selectedAgentId: AgentChatState['selectedAgentId'];\n selectedSkillId: AgentChatState['selectedSkillId'];\n agentsLoading: AgentChatState['agentsLoading'];\n skillsLoading: AgentChatState['skillsLoading'];\n agentsEmptyReason: AgentChatState['agentsEmptyReason'];\n sessionsHasMore: AgentChatState['sessionsHasMore'];\n sessionsLoadingMore: AgentChatState['sessionsLoadingMore'];\n sessionMessagesHasMore: AgentChatState['sessionMessagesHasMore'];\n sessionMessagesLoadingMore: AgentChatState['sessionMessagesLoadingMore'];\n activeSessionId: AgentChatState['activeSessionId'];\n lastError: AgentChatErrorPayload | null;\n pageContext: AgentChatState['pageContext'];\n routeContext: AgentChatState['routeContext'];\n attachPageContext: AgentChatState['attachPageContext'];\n setAttachPageContext: (attach: boolean) => void;\n setRouteContext: (routeContext: AgentChatRouteContext | null) => void;\n syncRouteContextFromWindow: () => void;\n}\n\nexport function useAgentChat(): UseAgentChatResult {\n const instance = useAgentChatClient();\n\n const state = useSyncExternalStore(\n (listener) => instance.subscribeStateChange(listener),\n () => instance.getState(),\n () => instance.getState(),\n );\n\n const open = useCallback(() => instance.open(), [instance]);\n const close = useCallback(() => instance.close(), [instance]);\n const toggle = useCallback(() => instance.toggle(), [instance]);\n const login = useCallback(\n (credentials: AgentChatLoginCredentials) => instance.login(credentials),\n [instance],\n );\n const logout = useCallback(() => instance.logout(), [instance]);\n const sendMessage = useCallback((text: string) => instance.sendMessage(text), [instance]);\n const selectSession = useCallback(\n (sessionId: string) => instance.selectSession(sessionId),\n [instance],\n );\n const refreshSessions = useCallback(() => instance.refreshSessions(), [instance]);\n const loadMoreSessions = useCallback(() => instance.loadMoreSessions(), [instance]);\n const loadMoreSessionMessages = useCallback(\n () => instance.loadMoreSessionMessages(),\n [instance],\n );\n const selectAgent = useCallback(\n (agentId: string) => instance.selectAgent(agentId),\n [instance],\n );\n const selectSkill = useCallback((skillId: string) => instance.selectSkill(skillId), [instance]);\n const setAttachPageContext = useCallback(\n (attach: boolean) => instance.setAttachPageContext(attach),\n [instance],\n );\n const setRouteContext = useCallback(\n (routeContext: AgentChatRouteContext | null) => instance.setRouteContext(routeContext),\n [instance],\n );\n const syncRouteContextFromWindow = useCallback(\n () => instance.syncRouteContextFromWindow(),\n [instance],\n );\n\n return {\n instance,\n state,\n isOpen: state.isOpen,\n open,\n close,\n toggle,\n login,\n logout,\n isLoggedIn: state.isLoggedIn,\n sendMessage,\n selectSession,\n refreshSessions,\n loadMoreSessions,\n loadMoreSessionMessages,\n selectAgent,\n selectSkill,\n sessions: state.sessions,\n agents: state.agents,\n skills: state.skills,\n selectedAgentId: state.selectedAgentId,\n selectedSkillId: state.selectedSkillId,\n agentsLoading: state.agentsLoading,\n skillsLoading: state.skillsLoading,\n agentsEmptyReason: state.agentsEmptyReason,\n sessionsHasMore: state.sessionsHasMore,\n sessionsLoadingMore: state.sessionsLoadingMore,\n sessionMessagesHasMore: state.sessionMessagesHasMore,\n sessionMessagesLoadingMore: state.sessionMessagesLoadingMore,\n activeSessionId: state.activeSessionId,\n lastError: state.lastError,\n pageContext: state.pageContext,\n routeContext: state.routeContext,\n attachPageContext: state.attachPageContext,\n setAttachPageContext,\n setRouteContext,\n syncRouteContextFromWindow,\n };\n}\n","import { useEffect, useRef } from 'react';\nimport { registerHostAction } from '../core/host-tool/host-action-registry';\nimport type { AgentChatHostAction } from '../types';\n\ntype HostActionHandler = (action: AgentChatHostAction) => void | Promise<void>;\n\n/**\n * Register a page-level host action handler for the lifetime of a component.\n *\n * `hostTools` from the server are executed automatically by the SDK after handlers run.\n * Use this hook for extra logic (entity guard, toast, branching on `reason`).\n *\n * @example\n * ```tsx\n * useHostAction('review-detail', async (action) => {\n * if (action.entity?.id !== reviewId) return;\n * if (action.reason === 'agent_mutation_success') await refetch();\n * });\n * ```\n */\nexport function useHostAction(scope: string, handler: HostActionHandler): void;\n/** Register a global handler that receives every host action. */\nexport function useHostAction(handler: HostActionHandler): void;\nexport function useHostAction(\n scopeOrHandler: string | HostActionHandler,\n handler?: HostActionHandler,\n): void {\n const isGlobal = typeof scopeOrHandler === 'function';\n const scope = isGlobal ? '' : scopeOrHandler.trim();\n const globalRef = useRef<HostActionHandler | null>(isGlobal ? scopeOrHandler : null);\n const handlerRef = useRef(handler);\n if (isGlobal) {\n globalRef.current = scopeOrHandler;\n }\n handlerRef.current = handler;\n\n useEffect(() => {\n const wrapped: HostActionHandler = (action) => {\n const fn = isGlobal ? globalRef.current : handlerRef.current;\n return fn?.(action);\n };\n\n if (isGlobal) {\n return registerHostAction(wrapped);\n }\n if (!scope) return;\n return registerHostAction(scope, wrapped);\n }, [isGlobal, scope]);\n}\n","import type { AgentChatClient } from '../core/client/instance';\nimport {\n isHostToolKnownGlobally,\n isHostToolRegisteredInScope,\n} from '../core/host-tool/host-tool-registry';\nimport type {\n PageAgentAwaitingApprovalPayload,\n PageAgentCompleteContext,\n PageAgentErrorContext,\n PageAgentLifecyclePayload,\n PageAgentStartContext,\n PageAgentStreamContext,\n} from '../types';\n\nconst DEFAULT_STREAM_THROTTLE_MS = 16;\n\nexport type PageAgentLifecycleCallbacks = {\n onStart?: (context: PageAgentStartContext) => void;\n onStream?: (context: PageAgentStreamContext) => void;\n onComplete?: (context: PageAgentCompleteContext) => void;\n onError?: (context: PageAgentErrorContext) => void;\n};\n\nexport function lifecycleTouchesGlobalTool(payload: PageAgentLifecyclePayload): boolean {\n switch (payload.type) {\n case 'start':\n return payload.context.toolName\n ? isHostToolKnownGlobally(payload.context.toolName)\n : false;\n case 'stream':\n return isHostToolKnownGlobally(payload.context.toolName);\n case 'complete':\n return payload.context.hostTools.some((tool) =>\n isHostToolKnownGlobally(tool.name),\n );\n case 'error':\n return false;\n default:\n return false;\n }\n}\n\nexport function lifecycleMatchesPageScope(\n payload: PageAgentLifecyclePayload,\n pageScope: string,\n): boolean {\n const scope =\n payload.type === 'error'\n ? payload.context.scope?.trim()\n : payload.context.scope?.trim();\n return scope === pageScope;\n}\n\nexport function lifecycleTouchesPageTool(\n payload: PageAgentLifecyclePayload,\n pageScope: string,\n): boolean {\n if (!lifecycleMatchesPageScope(payload, pageScope)) return false;\n switch (payload.type) {\n case 'start':\n return payload.context.toolName\n ? isHostToolRegisteredInScope(pageScope, payload.context.toolName)\n : true;\n case 'stream':\n return isHostToolRegisteredInScope(pageScope, payload.context.toolName);\n case 'complete':\n return payload.context.hostTools.some((tool) =>\n isHostToolRegisteredInScope(pageScope, tool.name),\n );\n case 'error':\n return true;\n default:\n return false;\n }\n}\n\n/** Page scope: all lifecycle on this `host_action.scope` (incl. global tools running here). */\nexport function shouldDeliverPageLifecycle(\n payload: PageAgentLifecyclePayload,\n pageScope: string,\n): boolean {\n return lifecycleMatchesPageScope(payload, pageScope);\n}\n\n/** App root: global tool registry (`scope *`) on any page. */\nexport function shouldDeliverAppLifecycle(payload: PageAgentLifecyclePayload): boolean {\n return lifecycleTouchesGlobalTool(payload);\n}\n\nexport function subscribePageAgentLifecycle(\n instance: AgentChatClient,\n options: {\n shouldDeliver: (payload: PageAgentLifecyclePayload) => boolean;\n streamThrottleMs?: number;\n callbacks: PageAgentLifecycleCallbacks;\n onAwaitingApproval?: (payload: PageAgentAwaitingApprovalPayload) => void;\n approvalScope?: string;\n },\n): () => void {\n const streamThrottleMs = options.streamThrottleMs ?? DEFAULT_STREAM_THROTTLE_MS;\n const callbacksRef = { current: options.callbacks };\n callbacksRef.current = options.callbacks;\n\n let pendingStream: PageAgentStreamContext | null = null;\n let streamTimer: ReturnType<typeof setTimeout> | null = null;\n\n const flushStream = () => {\n const pending = pendingStream;\n if (!pending) return;\n pendingStream = null;\n callbacksRef.current.onStream?.(pending);\n };\n\n const scheduleStream = (context: PageAgentStreamContext) => {\n if (streamThrottleMs <= 0) {\n callbacksRef.current.onStream?.(context);\n return;\n }\n pendingStream = context;\n if (streamTimer != null) return;\n streamTimer = setTimeout(() => {\n streamTimer = null;\n flushStream();\n }, streamThrottleMs);\n };\n\n const clearStreamState = () => {\n if (streamTimer != null) {\n clearTimeout(streamTimer);\n streamTimer = null;\n }\n pendingStream = null;\n };\n\n const handleLifecycle = (payload: PageAgentLifecyclePayload) => {\n if (!options.shouldDeliver(payload)) return;\n\n switch (payload.type) {\n case 'start':\n callbacksRef.current.onStart?.(payload.context);\n break;\n case 'stream':\n scheduleStream(payload.context);\n break;\n case 'complete':\n clearStreamState();\n flushStream();\n callbacksRef.current.onComplete?.(payload.context);\n break;\n case 'error':\n clearStreamState();\n callbacksRef.current.onError?.(payload.context);\n break;\n default:\n break;\n }\n };\n\n const offLifecycle = instance.on('pageAgentLifecycle', handleLifecycle);\n const offApproval = options.onAwaitingApproval\n ? instance.on('pageAgentAwaitingApproval', (payload) => {\n const scope = options.approvalScope?.trim();\n if (scope && payload.scope?.trim() !== scope) return;\n options.onAwaitingApproval?.(payload);\n })\n : () => {};\n\n return () => {\n offLifecycle();\n offApproval();\n clearStreamState();\n };\n}\n","/** Stable dependency key from tool names (order-independent). */\nexport function hostToolNamesKey(tools: Array<{ name: string }> | undefined): string {\n if (!tools?.length) return '';\n return [...tools].map((t) => t.name.trim()).sort().join('\\0');\n}\n\nexport function splitHostToolNamesKey(key: string): string[] {\n return key ? key.split('\\0') : [];\n}\n","import { useEffect, useRef } from 'react';\nimport { useAgentChatClient, useAgentChatStore } from './useAgentChatClient';\nimport {\n shouldDeliverPageLifecycle,\n subscribePageAgentLifecycle,\n} from './page-agent-lifecycle';\nimport { hostToolNamesKey, splitHostToolNamesKey } from './host-agent-registration';\nimport type {\n AgentChatPageContext,\n HostToolDefinition,\n HostToolHandler,\n PageAgentAwaitingApprovalPayload,\n PageAgentCompleteContext,\n PageAgentErrorContext,\n PageAgentStartContext,\n PageAgentStreamContext,\n} from '../types';\n\nexport interface UsePageAgentOptions {\n /** Business page scope — matches `pageContext.page` and `host_action.scope`. */\n scope: string;\n /** Synced on init; also pass to `<AgentChat pageContext={...} />` when possible. */\n pageContext?: AgentChatPageContext | null;\n /** Page-scoped host tools (fill form, etc.). Global tools → {@link useAppAgent}. */\n tools?: HostToolDefinition[];\n /**\n * Local handlers for app-declared tools on this page (no server sync).\n * Use when {@link useAppAgent} registered metadata without `handler`.\n */\n handlers?: Record<string, HostToolHandler>;\n /**\n * @deprecated Register global tools with {@link useAppAgent} at the app root.\n */\n genericTools?: HostToolDefinition[];\n pageLabel?: string;\n routePattern?: string;\n /**\n * Throttle `onStream` callbacks (ms). Tool `handler` is never throttled.\n * `0` disables throttling. Default `16` (~one frame).\n */\n streamThrottleMs?: number;\n /** `session.begin` / `tool.begin` on this scope */\n onStart?: (context: PageAgentStartContext) => void;\n /** `arg.append` on this scope (page + global tools running here) */\n onStream?: (context: PageAgentStreamContext) => void;\n /** `stream.full` on this scope */\n onComplete?: (context: PageAgentCompleteContext) => void;\n onError?: (context: PageAgentErrorContext) => void;\n onAwaitingApproval?: (context: PageAgentAwaitingApprovalPayload) => void;\n}\n\nfunction bindPageToolsFromRef(\n toolsRef: { current: HostToolDefinition[] | undefined },\n): HostToolDefinition[] {\n const tools = toolsRef.current;\n if (!tools?.length) return [];\n return tools.map((tool) => ({\n ...tool,\n handler: (args: Record<string, unknown>) =>\n toolsRef.current?.find((t) => t.name === tool.name)?.handler(args),\n ...(tool.onPreview\n ? {\n onPreview: (args: Record<string, unknown>) =>\n toolsRef.current?.find((t) => t.name === tool.name)?.onPreview?.(args),\n }\n : {}),\n }));\n}\n\n/**\n * Business-page hook: page context, page-scoped tools, lifecycle on current `scope`.\n *\n * Receives events for **all** tools executing on this page (including app-wide tools\n * declared via {@link useAppAgent}). Use `handlers` to execute app-level tools here.\n */\nexport function usePageAgent(options: UsePageAgentOptions): void {\n const instance = useAgentChatClient();\n const lifecycle = useAgentChatStore((state) => state.lifecycle);\n const scope = options.scope.trim();\n\n const callbacksRef = useRef(options);\n callbacksRef.current = options;\n\n const toolsRef = useRef(options.tools);\n toolsRef.current = options.tools;\n const toolNamesKey = hostToolNamesKey(options.tools);\n\n const genericToolsRef = useRef(options.genericTools);\n genericToolsRef.current = options.genericTools;\n const genericToolNamesKey = hostToolNamesKey(options.genericTools);\n const genericWarnedRef = useRef(false);\n\n useEffect(() => {\n if (lifecycle !== 'initialized') return;\n if (options.pageContext) {\n instance.setPageContext(options.pageContext);\n }\n }, [instance, options.pageContext, lifecycle]);\n\n useEffect(() => {\n if (!genericToolNamesKey) return;\n if (!genericWarnedRef.current) {\n genericWarnedRef.current = true;\n console.warn(\n '[agent-chat] usePageAgent: genericTools is deprecated — use useAppAgent at the app root.',\n );\n }\n let cancelled = false;\n void (async () => {\n try {\n await instance.registerHostToolsWithSync({\n appLevel: true,\n tools: bindPageToolsFromRef(genericToolsRef),\n });\n } catch (err) {\n if (!cancelled) {\n console.warn('[agent-chat] usePageAgent: genericTools register failed:', err);\n }\n }\n })();\n return () => {\n cancelled = true;\n for (const name of splitHostToolNamesKey(genericToolNamesKey)) {\n instance.unregisterHostTool('*', name);\n }\n };\n }, [instance, genericToolNamesKey]);\n\n useEffect(() => {\n if (!scope || !toolNamesKey) return;\n let cancelled = false;\n const names = splitHostToolNamesKey(toolNamesKey);\n\n void (async () => {\n try {\n await instance.registerHostToolsWithSync({\n scope,\n pageLabel: options.pageLabel,\n routePattern: options.routePattern,\n tools: bindPageToolsFromRef(toolsRef),\n });\n } catch (err) {\n if (!cancelled) {\n console.warn('[agent-chat] usePageAgent: registerHostToolsWithSync failed:', err);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n for (const name of names) {\n instance.unregisterHostTool(scope, name);\n }\n };\n }, [instance, scope, options.pageLabel, options.routePattern, toolNamesKey]);\n\n const handlersRef = useRef(options.handlers);\n handlersRef.current = options.handlers;\n const handlerNamesKey = options.handlers\n ? Object.keys(options.handlers).sort().join('\\0')\n : '';\n\n useEffect(() => {\n if (!scope || !handlerNamesKey) return;\n const names = splitHostToolNamesKey(handlerNamesKey);\n for (const name of names) {\n instance.registerHostTool(scope, name, (args) => handlersRef.current?.[name]?.(args));\n }\n return () => {\n for (const name of names) {\n instance.unregisterHostTool(scope, name);\n }\n };\n }, [instance, scope, handlerNamesKey]);\n\n useEffect(() => {\n if (!scope) return;\n\n return subscribePageAgentLifecycle(instance, {\n shouldDeliver: (payload) => shouldDeliverPageLifecycle(payload, scope),\n streamThrottleMs: options.streamThrottleMs,\n approvalScope: scope,\n onAwaitingApproval: (payload) => callbacksRef.current.onAwaitingApproval?.(payload),\n callbacks: {\n onStart: (ctx) => callbacksRef.current.onStart?.(ctx),\n onStream: (ctx) => callbacksRef.current.onStream?.(ctx),\n onComplete: (ctx) => callbacksRef.current.onComplete?.(ctx),\n onError: (ctx) => callbacksRef.current.onError?.(ctx),\n },\n });\n }, [instance, scope, options.streamThrottleMs]);\n}\n","import type { PageActionRowState } from '../../types';\n\n/** Skip React updates when row slots are unchanged (by `updatedAt` + visible flags). */\nexport function pageActionRowsShallowEqual(\n a: Record<string, PageActionRowState>,\n b: Record<string, PageActionRowState>,\n): boolean {\n const aKeys = Object.keys(a);\n if (aKeys.length !== Object.keys(b).length) {\n return false;\n }\n for (const key of aKeys) {\n const ar = a[key];\n const br = b[key];\n if (!br) return false;\n if (\n ar.updatedAt !== br.updatedAt ||\n ar.phase !== br.phase ||\n ar.error !== br.error ||\n ar.message !== br.message ||\n ar.progressLabel !== br.progressLabel ||\n ar.loading !== br.loading ||\n ar.disabled !== br.disabled ||\n ar.awaitingApproval !== br.awaitingApproval ||\n ar.runId !== br.runId ||\n ar.pageActionKey !== br.pageActionKey\n ) {\n return false;\n }\n }\n return true;\n}\n\nexport function buildPageActionRowsMap(\n rows: PageActionRowState[],\n): Record<string, PageActionRowState> {\n const next: Record<string, PageActionRowState> = {};\n for (const row of rows) {\n next[row.rowKey] = row;\n }\n return next;\n}\n","import { useCallback, useEffect, useRef, useState, type RefObject } from 'react';\nimport {\n buildPageActionRowsMap,\n pageActionRowsShallowEqual,\n} from '../core/page/page-action-row-sync';\nimport { createIdlePageActionRowState } from '../core/page/page-action-rows';\nimport { PAGE_ACTION_ACTION_SCOPE_ROW_KEY } from '../core/page/page-action-coordinator';\nimport { useAgentChatClient, useAgentChatStore } from './useAgentChatClient';\nimport type {\n AgentChatPageContext,\n OpenAutomationTaskCenterPayload,\n PageActionRowState,\n PageBotInvokeInput,\n PageBotStreamResult,\n} from '../types';\nimport {\n toPageActionProcessView,\n type PageActionProcessView,\n} from '../core/page/page-action-process-view';\n\nexport interface UsePageActionsOptions {\n actionKey: string;\n /** Default page scope; merged into invoke pageContext when page is omitted. */\n page?: string;\n defaultInstruction?: string;\n context?: Record<string, unknown>;\n requireInstruction?: boolean;\n /** Reconcile active rows from server on mount (default true). */\n reconcileOnMount?: boolean;\n /**\n * Register action-level restore with {@link PageActionCoordinator} (list pages).\n * Default `false` — set `true` when the list should reconnect running tasks after refresh.\n */\n autoResume?: boolean;\n}\n\nexport interface UsePageActionsInvokeOverride {\n /** Required for list rows — typically `String(entity.id)`. */\n rowKey: string;\n instruction?: string;\n context?: Record<string, unknown>;\n clientActionId?: string;\n pageContext?: AgentChatPageContext;\n signal?: AbortSignal;\n onChunk?: (chunk: string) => void;\n launchAnchor?: HTMLElement | RefObject<HTMLElement | null> | null;\n /**\n * When `true` (default), check reuse-hint before invoke when the chat UI is mounted.\n * Set `false` to skip the popover and invoke immediately.\n */\n preferReuse?: boolean;\n}\n\nexport interface UsePageActionsResult {\n instruction: string;\n setInstruction: (value: string) => void;\n /** Reactive map of known row slots for this actionKey. */\n rows: Record<string, PageActionRowState>;\n /** Row state; returns idle defaults when the slot is unknown. */\n getRow: (rowKey: string) => PageActionRowState;\n /** Normalized process view for custom rendering (scheme B). */\n getProcessView: (rowKey: string) => PageActionProcessView;\n invoke: (override: UsePageActionsInvokeOverride) => Promise<PageBotStreamResult | undefined>;\n reconcile: () => Promise<PageActionRowState[]>;\n openTaskCenter: (opts?: OpenAutomationTaskCenterPayload) => void;\n clearRowError: (rowKey: string) => void;\n}\n\nfunction resolveLaunchAnchor(\n anchor: UsePageActionsInvokeOverride['launchAnchor'],\n): HTMLElement | null {\n if (!anchor) return null;\n if ('current' in anchor) return anchor.current;\n return anchor;\n}\n\n/**\n * List-page PageAction helper — one UI slot per `rowKey` (usually entity id).\n *\n * Prefer this over {@link usePageAction} when multiple rows share an `actionKey`.\n */\nexport function usePageActions(options: UsePageActionsOptions): UsePageActionsResult {\n const instance = useAgentChatClient();\n const isLoggedIn = useAgentChatStore((state) => state.isLoggedIn);\n const requireInstruction = options.requireInstruction !== false;\n const autoResume = options.autoResume === true;\n /** Coordinator owns restore when `autoResume`; avoid parallel reconcile on mount. */\n const reconcileOnMount =\n options.reconcileOnMount ?? (autoResume ? false : true);\n\n const [instruction, setInstruction] = useState(options.defaultInstruction ?? '');\n const [rows, setRows] = useState<Record<string, PageActionRowState>>({});\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const seqRef = useRef(0);\n\n const actionKey = options.actionKey.trim();\n\n const syncRowsFromClient = useCallback(() => {\n const list = instance.getPageActionRowsForActionKey(actionKey);\n const next = buildPageActionRowsMap(list);\n setRows((current) => (pageActionRowsShallowEqual(current, next) ? current : next));\n }, [actionKey, instance]);\n\n useEffect(() => {\n syncRowsFromClient();\n const offRow = instance.on('pageActionRowChanged', (payload) => {\n if (payload.state.actionKey !== actionKey) return;\n setRows((current) => {\n const prev = current[payload.rowKey];\n if (\n prev &&\n prev.updatedAt === payload.state.updatedAt &&\n prev.phase === payload.state.phase &&\n prev.message === payload.state.message &&\n prev.progressLabel === payload.state.progressLabel &&\n prev.error === payload.state.error &&\n prev.loading === payload.state.loading &&\n prev.disabled === payload.state.disabled &&\n prev.narrativeItems === payload.state.narrativeItems\n ) {\n return current;\n }\n return { ...current, [payload.rowKey]: payload.state };\n });\n });\n const offCenter = instance.on('automationTaskCenterChanged', syncRowsFromClient);\n const offApproval = instance.on('approvalExecutionCompleted', syncRowsFromClient);\n const offInbox = instance.on('approvalInboxChanged', syncRowsFromClient);\n return () => {\n offRow();\n offCenter();\n offApproval();\n offInbox();\n };\n }, [actionKey, instance, syncRowsFromClient]);\n\n useEffect(() => {\n if (!isLoggedIn) {\n setRows({});\n }\n }, [isLoggedIn]);\n\n useEffect(() => {\n if (!reconcileOnMount || !isLoggedIn || !actionKey) return;\n void instance.reconcileActivePageActions({ actionKey }).then(syncRowsFromClient).catch(() => {\n /* reconcile is best-effort */\n });\n }, [actionKey, instance, isLoggedIn, reconcileOnMount, syncRowsFromClient]);\n\n useEffect(() => {\n if (!autoResume || !actionKey) return;\n return instance.bindPageActionSlot({\n actionKey,\n rowKey: PAGE_ACTION_ACTION_SCOPE_ROW_KEY,\n pageContext: options.page ? { page: options.page } : null,\n ready: true,\n autoResume: true,\n autoApplyPending: false,\n });\n }, [actionKey, autoResume, instance, options.page]);\n\n const getRow = useCallback(\n (rowKey: string): PageActionRowState => {\n const key = rowKey.trim();\n if (!key) return createIdlePageActionRowState('', actionKey);\n return rows[key] ?? instance.getPageActionRowState(key) ?? createIdlePageActionRowState(key, actionKey);\n },\n [actionKey, instance, rows],\n );\n\n const reconcile = useCallback(async () => {\n const updated = await instance.reconcileActivePageActions({ actionKey });\n syncRowsFromClient();\n return updated;\n }, [actionKey, instance, syncRowsFromClient]);\n\n const openTaskCenter = useCallback(\n (opts?: OpenAutomationTaskCenterPayload) => {\n instance.openAutomationTaskCenter(opts);\n },\n [instance],\n );\n\n const clearRowError = useCallback(\n (rowKey: string) => {\n instance.clearPageActionRowError(rowKey);\n },\n [instance],\n );\n\n const invoke = useCallback(\n async (override: UsePageActionsInvokeOverride): Promise<PageBotStreamResult | undefined> => {\n const rowKey = override.rowKey.trim();\n if (!rowKey) return undefined;\n\n const resolvedInstruction = (override.instruction ?? instruction).trim();\n if (requireInstruction && !resolvedInstruction) return undefined;\n if (!actionKey) return undefined;\n\n seqRef.current += 1;\n const pageFromOpts = optionsRef.current.page?.trim();\n const pageContext: AgentChatPageContext | undefined = override.pageContext\n ? {\n ...override.pageContext,\n ...(pageFromOpts && !override.pageContext.page ? { page: pageFromOpts } : {}),\n }\n : pageFromOpts\n ? { page: pageFromOpts }\n : undefined;\n\n const baseContext = optionsRef.current.context;\n const extraContext = override.context;\n const body: PageBotInvokeInput = {\n actionKey,\n rowKey,\n clientActionId: override.clientActionId?.trim() || `page-action-${rowKey}-${seqRef.current}`,\n awaitStream: false,\n launchAnchor: resolveLaunchAnchor(override.launchAnchor),\n pageContext,\n };\n if (override.preferReuse === false) body.preferReuse = false;\n if (resolvedInstruction) body.instruction = resolvedInstruction;\n if (baseContext || extraContext) {\n body.context = { ...baseContext, ...extraContext };\n }\n if (override.signal) body.signal = override.signal;\n if (override.onChunk) body.onChunk = override.onChunk;\n\n try {\n const result = await instance.invokePageAction(body);\n syncRowsFromClient();\n return result;\n } catch (err) {\n syncRowsFromClient();\n throw err;\n }\n },\n [actionKey, instance, instruction, requireInstruction, syncRowsFromClient],\n );\n\n return {\n instruction,\n setInstruction,\n rows,\n getRow,\n getProcessView: (rowKey: string) => toPageActionProcessView(getRow(rowKey)),\n invoke,\n reconcile,\n openTaskCenter,\n clearRowError,\n };\n}\n","import { useEffect, useRef, useState, type RefObject } from 'react';\nimport {\n usePageActions,\n type UsePageActionsInvokeOverride,\n} from './usePageActions';\nimport { pageActionSlotKey } from '../core/page/page-action-coordinator';\nimport { matchesPendingPageActionApply } from '../core/page/pending-page-action-apply';\nimport { useAgentChatClient } from './useAgentChatClient';\nimport type {\n AgentChatPageContext,\n PageActionApplyPhase,\n PageActionPhase,\n PendingPageActionApply,\n PageBotStreamResult,\n} from '../types';\nimport type { NarrativeItem } from '../core/page/page-action-workflow-progress';\nimport { toPageActionProcessView } from '../core/page/page-action-process-view';\nimport type { PageActionProcessView } from '../core/page/page-action-process-view';\n\nexport interface UsePageActionOptions {\n actionKey: string;\n pageContext?: AgentChatPageContext | null;\n /** Initial value for user-editable instruction. */\n defaultInstruction?: string;\n /** Merged into every invoke (overridable per call). */\n context?: Record<string, unknown>;\n /**\n * When `true` (default), `invoke` rejects empty instruction before calling the API.\n * Set `false` to let the server apply its default.\n */\n requireInstruction?: boolean;\n /** How long the `launched` phase lasts before returning to `idle` (ms). Kept for API compat. */\n launchedDurationMs?: number;\n /**\n * Whether this page slot is ready to receive apply / host_action replay.\n * Default `true`. Pass drawer/tab open state for pages that need a prepare step.\n */\n ready?: boolean;\n /**\n * After mount reconcile, attach SSE for active `running` tasks (refresh reconnect).\n * Default `true`.\n */\n autoResume?: boolean;\n /**\n * When pending「应用到页面」matches this slot and {@link ready}, auto `replayPageAction`.\n * Default `true`.\n */\n autoApplyPending?: boolean;\n}\n\nexport interface UsePageActionInvokeOverride {\n instruction?: string;\n context?: Record<string, unknown>;\n clientActionId?: string;\n pageContext?: AgentChatPageContext;\n signal?: AbortSignal;\n onChunk?: (chunk: string) => void;\n launchAnchor?: HTMLElement | RefObject<HTMLElement | null> | null;\n /**\n * When `true` (default), check reuse-hint before invoke when the chat UI is mounted.\n * Set `false` to skip the popover and invoke immediately.\n */\n preferReuse?: boolean;\n /** Optional; defaults to `entity.id` or `'default'`. */\n rowKey?: string;\n}\n\nexport interface UsePageActionResult {\n instruction: string;\n setInstruction: (value: string) => void;\n phase: PageActionPhase;\n /** Server-issued de-duplication key from the latest invoke (or restored active run). */\n pageActionKey: string | null;\n lastRunId: number | null;\n /** Invoke Page Bot; uses current `instruction` unless overridden. */\n invoke: (override?: UsePageActionInvokeOverride) => Promise<PageBotStreamResult | undefined>;\n openTaskCenter: () => void;\n /** True while submitting, streaming, or an active non-approval run exists. */\n loading: boolean;\n /** True when invoke paused at inbox approval (`phase === 'awaiting_approval'`). */\n awaitingApproval: boolean;\n /** Recommended button `disabled` — {@link loading} or {@link awaitingApproval}. */\n disabled: boolean;\n error: string | null;\n /** Soft tip (e.g. duplicate invoke); not a failure. */\n message: string | null;\n /**\n * SSE workflow loading copy for the trigger button (`page_workflow` / `stageKind`).\n * Prefer this over raw phase for loading copy.\n */\n progressLabel: string | null;\n /**\n * Accumulated storyline from `page_workflow.narrativeItems`.\n * Optional; do not replace {@link progressLabel}.\n */\n narrativeItems: NarrativeItem[];\n /**\n * Normalized execution-process snapshot for custom UI (scheme B).\n * Built-in process chrome is gated by `pageActionProcessUi` on AgentChat options.\n */\n process: PageActionProcessView;\n clearError: () => void;\n /** Whether a matching「应用到页面」pending intent exists for this slot. */\n pendingApply: boolean;\n /** Pending apply payload when matched; otherwise null. */\n pendingApplyIntent: PendingPageActionApply | null;\n /** Apply/replay lifecycle for this slot. */\n applyPhase: PageActionApplyPhase;\n}\n\nfunction defaultRowKey(pageContext?: AgentChatPageContext | null): string {\n const id = pageContext?.entity?.id;\n if (id != null && String(id).trim()) return String(id).trim();\n return 'default';\n}\n\n/**\n * Page Bot invoke helper for a **single** entity / page slot.\n *\n * Pair with {@link usePageAgent} on the same page for tool execution and lifecycle.\n * For list pages with one button per row, use {@link usePageActions} instead.\n *\n * Restore / apply is owned by {@link PageActionCoordinator} via slot bind — not hook effects.\n */\nexport function usePageAction(options: UsePageActionOptions): UsePageActionResult {\n const instance = useAgentChatClient();\n const ready = options.ready !== false;\n const autoResume = options.autoResume !== false;\n const autoApplyPending = options.autoApplyPending !== false;\n const actionKey = options.actionKey.trim();\n const rowKey = defaultRowKey(options.pageContext);\n const slotKey = pageActionSlotKey({ actionKey, rowKey });\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const multi = usePageActions({\n actionKey: options.actionKey,\n page: options.pageContext?.page,\n defaultInstruction: options.defaultInstruction,\n context: options.context,\n requireInstruction: options.requireInstruction,\n reconcileOnMount: false,\n });\n\n const row = multi.getRow(rowKey);\n const [pendingApplyIntent, setPendingApplyIntent] = useState<PendingPageActionApply | null>(\n null,\n );\n const [applyPhase, setApplyPhase] = useState<PageActionApplyPhase>('idle');\n\n useEffect(() => {\n const syncPending = () => {\n const pending = instance.getPendingPageActionApply();\n const matched = matchesPendingPageActionApply(pending, {\n actionKey,\n pageContext: optionsRef.current.pageContext,\n });\n setPendingApplyIntent(matched ? pending : null);\n };\n syncPending();\n return instance.on('pendingPageActionApplyChanged', syncPending);\n }, [actionKey, instance]);\n\n useEffect(() => {\n return instance.on('pageActionSlotApplyPhaseChanged', (payload) => {\n if (payload.slotKey !== slotKey) return;\n setApplyPhase(payload.phase);\n });\n }, [instance, slotKey]);\n\n useEffect(() => {\n const o = optionsRef.current;\n return instance.bindPageActionSlot({\n actionKey,\n rowKey,\n pageContext: o.pageContext,\n ready: o.ready !== false,\n autoResume: o.autoResume !== false,\n autoApplyPending: o.autoApplyPending !== false,\n });\n }, [actionKey, instance, rowKey]);\n\n useEffect(() => {\n instance.patchPageActionSlot(slotKey, {\n pageContext: options.pageContext,\n ready,\n autoResume,\n autoApplyPending,\n });\n }, [slotKey, instance, options.pageContext, ready, autoResume, autoApplyPending]);\n\n return {\n instruction: multi.instruction,\n setInstruction: multi.setInstruction,\n phase: row.phase,\n pageActionKey: row.pageActionKey,\n lastRunId: row.runId,\n invoke: (override) => {\n const resolvedRowKey = override?.rowKey?.trim() || rowKey;\n const pageContext = override?.pageContext ?? options.pageContext ?? undefined;\n const body: UsePageActionsInvokeOverride = {\n rowKey: resolvedRowKey,\n instruction: override?.instruction,\n context: override?.context,\n clientActionId: override?.clientActionId,\n pageContext: pageContext ?? undefined,\n signal: override?.signal,\n onChunk: override?.onChunk,\n launchAnchor: override?.launchAnchor,\n preferReuse: override?.preferReuse,\n };\n return multi.invoke(body);\n },\n openTaskCenter: () =>\n multi.openTaskCenter(row.runId != null ? { runId: row.runId } : undefined),\n loading: row.loading,\n awaitingApproval: row.awaitingApproval,\n disabled: row.disabled,\n error: row.error,\n message: row.message,\n progressLabel: row.progressLabel,\n narrativeItems: row.narrativeItems,\n process: toPageActionProcessView(row),\n clearError: () => multi.clearRowError(rowKey),\n pendingApply: pendingApplyIntent != null,\n pendingApplyIntent,\n applyPhase,\n };\n}\n","import {\n EXTENSION_BRIDGE_REQUEST_EVENT,\n EXTENSION_READY_EVENT,\n requireOmnixSdkAuthentication,\n} from './extension-contract';\n\nexport {\n EXTENSION_BRIDGE_REQUEST_EVENT,\n EXTENSION_READY_EVENT,\n} from './extension-contract';\nexport { isOmnixSdkAuthenticated, requireOmnixSdkAuthentication } from './extension-contract';\n\nexport type GofoTrackEvent = {\n title?: string;\n date?: string;\n time?: string;\n location?: string;\n};\n\nexport type GofoTrackResult = {\n /** 查询入参 waybillNo */\n waybillNo?: string;\n /** 关联单号(查 G1253-… 得到 GFUS…,或反过来) */\n relatedNo?: string;\n /** @deprecated 请用 relatedNo */\n trackingNumber?: string;\n};\n\nexport type GofoTrackResponse = {\n ok: true;\n waybillNo: string;\n result: GofoTrackResult | null;\n jobId: string;\n /** @deprecated 与 waybillNo 相同;请改用 waybillNo */\n trackNumber?: string;\n};\n\n/** GOFO 查询入参:只需 waybillNo(也可直接传字符串) */\nexport type GofoTrackInput =\n | string\n | {\n waybillNo?: string;\n reuseTab?: boolean;\n activateGofoTab?: boolean;\n pollTimeoutMs?: number;\n /** @deprecated 请用 waybillNo */\n trackNumber?: string;\n /** @deprecated 请用 waybillNo */\n warehouseNo?: string;\n };\n\nexport type OmnixExtensionGofoApi = {\n track(input: GofoTrackInput): Promise<GofoTrackResponse>;\n start(input: GofoTrackInput): Promise<{ jobId: string; pending: boolean }>;\n getJob(jobId: string): Promise<Record<string, unknown> | null>;\n waitForJob(jobId: string, timeoutMs?: number): Promise<Record<string, unknown>>;\n};\n\n/** 插件在页面注入的内部 API — 业务请使用 SDK 封装,勿直接依赖 window.OmnixExtension */\nexport type OmnixExtensionApi = {\n VERSION: string;\n isAvailable(): boolean;\n ping(): Promise<{ ok: boolean; version?: string }>;\n getStatus(): Promise<Record<string, unknown>>;\n syncPmsIntegration(): Promise<Record<string, unknown>>;\n gofo: OmnixExtensionGofoApi;\n};\n\ndeclare global {\n interface Window {\n OmnixExtension?: OmnixExtensionApi;\n }\n}\n\nfunction readExtensionApi(): OmnixExtensionApi | null {\n if (typeof window === 'undefined') {\n return null;\n }\n const ext = window.OmnixExtension;\n return ext && typeof ext.ping === 'function' ? ext : null;\n}\n\n/** 插件 content bridge 是否已注入(不要求已登录) */\nexport function isOmnixExtensionAvailable(): boolean {\n return readExtensionApi() != null;\n}\n\n/** 通知已注入的 content script 重新挂载 page bridge */\nexport function requestOmnixExtensionBridge(): void {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n window.dispatchEvent(new CustomEvent(EXTENSION_BRIDGE_REQUEST_EVENT));\n } catch {\n /* non-browser */\n }\n}\n\n/** 等待插件 bridge 就绪(不要求已登录) */\nexport function waitForOmnixExtensionAvailable(timeoutMs = 8_000): Promise<boolean> {\n if (isOmnixExtensionAvailable()) {\n return Promise.resolve(true);\n }\n if (typeof window === 'undefined') {\n return Promise.resolve(false);\n }\n\n requestOmnixExtensionBridge();\n\n return new Promise((resolve) => {\n let settled = false;\n const finish = (ok: boolean) => {\n if (settled) {\n return;\n }\n settled = true;\n window.removeEventListener(EXTENSION_READY_EVENT, onReady);\n clearInterval(pollTimer);\n clearTimeout(timer);\n resolve(ok);\n };\n\n const onReady = () => finish(isOmnixExtensionAvailable());\n window.addEventListener(EXTENSION_READY_EVENT, onReady);\n\n const pollTimer = window.setInterval(() => {\n requestOmnixExtensionBridge();\n if (isOmnixExtensionAvailable()) {\n finish(true);\n }\n }, 500);\n\n const timer = window.setTimeout(() => finish(isOmnixExtensionAvailable()), timeoutMs);\n });\n}\n\nasync function resolveExtensionApi(waitMs = 3_000): Promise<OmnixExtensionApi> {\n const ext = readExtensionApi() ?? (await waitForOmnixExtensionAvailable(waitMs)\n ? readExtensionApi()\n : null);\n if (!ext) {\n throw new Error(\n '未检测到 Omnix 浏览器插件。请安装 omnix-token-sync 并刷新页面。',\n );\n }\n return ext;\n}\n\nasync function invokeExtension<T>(\n fn: (ext: OmnixExtensionApi) => Promise<T>,\n options?: { waitMs?: number; requireAuth?: boolean },\n): Promise<T> {\n if (options?.requireAuth !== false) {\n requireOmnixSdkAuthentication();\n }\n const ext = await resolveExtensionApi(options?.waitMs);\n return fn(ext);\n}\n\n/** 探测插件是否在线(不要求登录) */\nexport async function pingOmnixExtension(options?: { waitMs?: number }) {\n return invokeExtension((ext) => ext.ping(), { ...options, requireAuth: false });\n}\n\n/** 读取插件状态(含 Omnix 登录镜像;不要求调用方已登录) */\nexport async function getOmnixExtensionStatus(options?: { waitMs?: number }) {\n return invokeExtension((ext) => ext.getStatus(), { ...options, requireAuth: false });\n}\n\n/** PMS · 同步 OMS 等业务 token(须 SDK 已登录) */\nexport async function syncOmnixPmsIntegration(options?: { waitMs?: number }) {\n return invokeExtension((ext) => ext.syncPmsIntegration(), options);\n}\n\n/** GOFO waybillNo 轨迹查询 — 不依赖 SDK 登录,有插件即可 */\nexport async function trackGofoWaybill(\n input: GofoTrackInput,\n options?: { waitMs?: number },\n): Promise<GofoTrackResponse> {\n return invokeExtension((ext) => ext.gofo.track(input), {\n ...options,\n requireAuth: false,\n });\n}\n\nexport async function startGofoTrack(\n input: GofoTrackInput,\n options?: { waitMs?: number },\n) {\n return invokeExtension((ext) => ext.gofo.start(input), {\n ...options,\n requireAuth: false,\n });\n}\n\nexport async function getGofoTrackJob(jobId: string, options?: { waitMs?: number }) {\n return invokeExtension((ext) => ext.gofo.getJob(jobId), {\n ...options,\n requireAuth: false,\n });\n}\n\nexport async function waitForGofoTrackJob(\n jobId: string,\n timeoutMs?: number,\n options?: { waitMs?: number },\n) {\n return invokeExtension((ext) => ext.gofo.waitForJob(jobId, timeoutMs), {\n ...options,\n requireAuth: false,\n });\n}\n\n/**\n * @deprecated 请使用 `isOmnixExtensionAvailable` / SDK 封装方法,勿直接访问插件 API。\n */\nexport function getOmnixExtension(): OmnixExtensionApi | null {\n return readExtensionApi();\n}\n\n/**\n * @deprecated 请使用 `waitForOmnixExtensionAvailable`。\n */\nexport function waitForOmnixExtension(timeoutMs = 8_000): Promise<OmnixExtensionApi | null> {\n return waitForOmnixExtensionAvailable(timeoutMs).then(() => readExtensionApi());\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport {\n EXTENSION_READY_EVENT,\n isOmnixExtensionAvailable,\n requestOmnixExtensionBridge,\n syncOmnixPmsIntegration,\n trackGofoWaybill,\n waitForOmnixExtensionAvailable,\n type GofoTrackInput,\n type GofoTrackResponse,\n} from '../core/extension/omnix-extension-client';\nimport { useAgentChatStore } from './useAgentChatClient';\n\nexport type UseOmnixExtensionOptions = {\n /** 等待插件 bridge 注入的最长时间 */\n waitMs?: number;\n};\n\nexport type UseOmnixExtensionResult = {\n /** 插件 bridge 是否已注入(`window.OmnixExtension`) */\n extensionAvailable: boolean;\n isLoggedIn: boolean;\n canUseGofo: boolean;\n canUsePms: boolean;\n /** @deprecated 请用 `canUseGofo` */\n canUse: boolean;\n trackGofoWaybill: (\n input: GofoTrackInput,\n options?: { waitMs?: number },\n ) => Promise<GofoTrackResponse>;\n syncPmsIntegration: (options?: { waitMs?: number }) => Promise<Record<string, unknown>>;\n};\n\n/**\n * React 侧接入 Omnix 浏览器插件(经 SDK)。\n * - 会检测 `extensionAvailable`(插件是否已注入 bridge)\n * - GOFO 不依赖登录;PMS 须 `isLoggedIn`\n */\nexport function useOmnixExtension(\n options: UseOmnixExtensionOptions = {},\n): UseOmnixExtensionResult {\n const waitMs = options.waitMs ?? 10_000;\n const isLoggedIn = useAgentChatStore((s) => s.isLoggedIn);\n const [extensionAvailable, setExtensionAvailable] = useState(() =>\n isOmnixExtensionAvailable(),\n );\n\n useEffect(() => {\n const sync = () => setExtensionAvailable(isOmnixExtensionAvailable());\n window.addEventListener(EXTENSION_READY_EVENT, sync);\n return () => window.removeEventListener(EXTENSION_READY_EVENT, sync);\n }, []);\n\n useEffect(() => {\n if (isOmnixExtensionAvailable()) {\n setExtensionAvailable(true);\n return;\n }\n let cancelled = false;\n requestOmnixExtensionBridge();\n void waitForOmnixExtensionAvailable(waitMs).then((ok) => {\n if (!cancelled) {\n setExtensionAvailable(ok);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [waitMs]);\n\n const track = useCallback(\n (input: GofoTrackInput, invokeOptions?: { waitMs?: number }) =>\n trackGofoWaybill(input, invokeOptions),\n [],\n );\n\n const syncPms = useCallback(\n (invokeOptions?: { waitMs?: number }) => syncOmnixPmsIntegration(invokeOptions),\n [],\n );\n\n const canUseGofo = extensionAvailable;\n const canUsePms = extensionAvailable && isLoggedIn;\n\n return {\n extensionAvailable,\n isLoggedIn,\n canUseGofo,\n canUsePms,\n canUse: canUseGofo,\n trackGofoWaybill: track,\n syncPmsIntegration: syncPms,\n };\n}\n","import { useCallback, useState } from 'react';\nimport type {\n AppToolCallableItem,\n AppToolInvokeInput,\n AppToolInvokeResult,\n} from '../core/services/app-tool.service';\nimport { getAppToolServerErrorCode } from '../core/services/app-tool.service';\nimport { useAgentChatClient, useAgentChatStore } from './useAgentChatClient';\n\nexport type UseAppToolResult = {\n isLoggedIn: boolean;\n loading: boolean;\n error: string | null;\n /** 最近一次 listCallable 结果 */\n items: AppToolCallableItem[];\n /** 最近一次 invoke 结果 */\n lastResult: AppToolInvokeResult | null;\n /** 网关门禁码,如 INTEGRATION_USER_TOKEN_REQUIRED */\n lastServerCode: string | null;\n listCallable: (signal?: AbortSignal) => Promise<AppToolCallableItem[]>;\n invoke: (input: AppToolInvokeInput) => Promise<AppToolInvokeResult>;\n clearError: () => void;\n};\n\n/**\n * C 端 Tool 代调 — `listCallableTools` / `invokeAppTool`(须 SDK 已登录)。\n *\n * `invoke` 内置登录挂起:未登录时自动等待,登录后继续执行。\n * @see agent-server/v2/docs/c-end-app-tool-invoke.md\n */\nexport function useAppTool(): UseAppToolResult {\n const instance = useAgentChatClient();\n const isLoggedIn = useAgentChatStore((s) => s.isLoggedIn);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [items, setItems] = useState<AppToolCallableItem[]>([]);\n const [lastResult, setLastResult] = useState<AppToolInvokeResult | null>(null);\n const [lastServerCode, setLastServerCode] = useState<string | null>(null);\n\n const listCallable = useCallback(\n async (signal?: AbortSignal) => {\n setLoading(true);\n setError(null);\n setLastServerCode(null);\n try {\n const { items: next } = await instance.listCallableTools(signal);\n setItems(next);\n return next;\n } catch (err) {\n setLastServerCode(getAppToolServerErrorCode(err));\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [instance],\n );\n\n const invoke = useCallback(\n async (input: AppToolInvokeInput) => {\n setError(null);\n setLastServerCode(null);\n try {\n const result = await instance.invokeAppTool(input);\n setLastResult(result);\n if (!result.ok) {\n setError(result.error ?? `下游失败 HTTP ${result.httpStatus ?? '?'}`);\n }\n return result;\n } catch (err) {\n setLastServerCode(getAppToolServerErrorCode(err));\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n throw err;\n }\n },\n [instance],\n );\n\n return {\n isLoggedIn,\n loading,\n error,\n items,\n lastResult,\n lastServerCode,\n listCallable,\n invoke,\n clearError: useCallback(() => {\n setError(null);\n setLastServerCode(null);\n }, []),\n };\n}\n","import { useEffect } from 'react';\nimport type { AgentChatInstance, ContextMentionDefinition } from '../types';\nimport { defineContextMention } from '../core/page/context-mention-define';\n\n/**\n * Register host @ mention catalog entries for the chat composer.\n * Pass a **memoized** `definitions` array (`useMemo`) when `resolve` closes over props/state.\n */\nexport function useContextMentions(\n instance: AgentChatInstance,\n definitions: ContextMentionDefinition[],\n): void {\n useEffect(() => {\n if (definitions.length === 0) {\n instance.clearContextMentions();\n return;\n }\n instance.registerContextMentions(\n definitions.map((def) => defineContextMention(def)),\n { replace: true },\n );\n return () => {\n instance.clearContextMentions();\n };\n }, [definitions, instance]);\n}\n","import { useEffect, useRef } from 'react';\nimport { useAgentChatClient } from './useAgentChatClient';\nimport {\n shouldDeliverAppLifecycle,\n subscribePageAgentLifecycle,\n type PageAgentLifecycleCallbacks,\n} from './page-agent-lifecycle';\nimport { hostToolNamesKey, splitHostToolNamesKey } from './host-agent-registration';\nimport type { AppHostToolDefinition } from '../types';\n\nexport interface UseAppAgentOptions extends PageAgentLifecycleCallbacks {\n /**\n * App-wide host tools. Syncs metadata to the server (scope `*`);\n * `handler` is optional — register execution on the business page via\n * {@link usePageAgent} `handlers`.\n */\n tools?: AppHostToolDefinition[];\n /**\n * Throttle `onStream` (ms). Tool handlers are never throttled.\n * @default 16\n */\n streamThrottleMs?: number;\n}\n\nfunction bindAppToolsFromRef(\n toolsRef: { current: AppHostToolDefinition[] | undefined },\n): AppHostToolDefinition[] {\n const tools = toolsRef.current;\n if (!tools?.length) return [];\n return tools.map((tool) => ({\n ...tool,\n ...(tool.handler\n ? {\n handler: (args: Record<string, unknown>) =>\n toolsRef.current?.find((t) => t.name === tool.name)?.handler?.(args),\n }\n : {}),\n ...(tool.onPreview\n ? {\n onPreview: (args: Record<string, unknown>) =>\n toolsRef.current?.find((t) => t.name === tool.name)?.onPreview?.(args),\n }\n : {}),\n }));\n}\n\n/**\n * App-root hook: register global host tools and listen for their lifecycle on **any** page.\n *\n * Typical App layout:\n *\n * ```tsx\n * useAppAgent({\n * tools: [{ name: 'refreshEntity', description: '...', argsSchema: {} }],\n * onComplete: () => analytics.track('refreshed'),\n * });\n *\n * // CampaignDetail.tsx — page executes app-declared tools\n * usePageAgent({\n * scope: 'campaign-detail',\n * handlers: { refreshEntity: ({ entityId }) => refetch(String(entityId)) },\n * });\n * ```\n *\n * `handler` in app `tools` is optional; page `handlers` run the business logic.\n * Lifecycle callbacks (`onComplete`, …) are listen-only.\n */\nexport function useAppAgent(options: UseAppAgentOptions): void {\n const instance = useAgentChatClient();\n const callbacksRef = useRef(options);\n callbacksRef.current = options;\n\n const toolsRef = useRef(options.tools);\n toolsRef.current = options.tools;\n const toolNamesKey = hostToolNamesKey(options.tools);\n\n useEffect(() => {\n if (!toolNamesKey) return;\n let cancelled = false;\n const names = splitHostToolNamesKey(toolNamesKey);\n\n void (async () => {\n try {\n await instance.registerHostToolsWithSync({\n appLevel: true,\n tools: bindAppToolsFromRef(toolsRef),\n });\n } catch (err) {\n if (!cancelled) {\n console.warn('[agent-chat] useAppAgent: registerHostToolsWithSync failed:', err);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n for (const name of names) {\n const tool = toolsRef.current?.find((t) => t.name === name);\n if (tool?.handler) {\n instance.unregisterHostTool('*', name);\n } else {\n instance.undeclareHostTool('*', name);\n }\n }\n };\n }, [instance, toolNamesKey]);\n\n useEffect(() => {\n return subscribePageAgentLifecycle(instance, {\n shouldDeliver: shouldDeliverAppLifecycle,\n streamThrottleMs: options.streamThrottleMs,\n callbacks: {\n onStart: (ctx) => callbacksRef.current.onStart?.(ctx),\n onStream: (ctx) => callbacksRef.current.onStream?.(ctx),\n onComplete: (ctx) => callbacksRef.current.onComplete?.(ctx),\n onError: (ctx) => callbacksRef.current.onError?.(ctx),\n },\n });\n }, [instance, options.streamThrottleMs]);\n}\n"],"x_google_ignoreList":[6,7,8,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,47],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.cjs.js","names":["React"],"sources":["../src/core/lib/errors.ts","../src/core/lib/resolve.ts","../src/core/auth/auth-headers.ts","../src/core/auth/auth-response.ts","../src/core/chat/session-run.ts","../src/core/chat/chat-response.ts","../node_modules/.pnpm/zustand@5.0.15_@types+react@19.2.18_immer@11.1.18_react@19.2.8_use-sync-external-store@1.6.0_react@19.2.8_/node_modules/zustand/esm/vanilla.mjs","../node_modules/.pnpm/zustand@5.0.15_@types+react@19.2.18_immer@11.1.18_react@19.2.8_use-sync-external-store@1.6.0_react@19.2.8_/node_modules/zustand/esm/react.mjs","../node_modules/.pnpm/zustand@5.0.15_@types+react@19.2.18_immer@11.1.18_react@19.2.8_use-sync-external-store@1.6.0_react@19.2.8_/node_modules/zustand/esm/middleware.mjs","../src/core/auth/auth-bridge.ts","../src/core/auth/auth-store.ts","../src/core/auth/auth-session.ts","../src/core/auth/login-gate.ts","../src/core/extension/extension-contract.ts","../src/core/extension/auth-extension-resync.ts","../src/core/lib/events.ts","../src/core/host-tool/stream/host-tool-stream.types.ts","../src/core/host-tool/host-action.ts","../src/core/chat/chat-sse.ts","../src/core/host-tool/host-tool-registry.ts","../src/core/host-tool/host-action-registry.ts","../src/core/host-tool/host-tool-path-args.ts","../src/core/host-tool/stream/host-tool-stream-reducer.ts","../src/core/host-tool/stream/host-tool-stream-gate.ts","../src/core/host-tool/stream/host-tool-stream-round.ts","../src/core/host-tool/stream/host-tool-stream-reconcile.ts","../src/core/host-tool/stream/host-tool-stream.ts","../src/core/host-tool/register-host-tools.ts","../src/core/page/context-mention.ts","../src/core/page/context-mention-define.ts","../src/core/page/context-mention-registry.ts","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/HTTPError.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/NonError.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/ForceRetryError.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/core/constants.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/body.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/is.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/merge.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/normalize.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/errors/TimeoutError.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/timeout.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/delay.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/options.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/type-guards.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/core/Ky.js","../node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/index.js","../src/core/http/errors.ts","../node_modules/.pnpm/eventsource-parser@3.1.1/node_modules/eventsource-parser/dist/index.js","../src/core/http/sse.ts","../src/core/http/client.ts","../src/core/services/auth.service.ts","../src/core/services/agent.service.ts","../src/core/services/chat.service.ts","../src/core/lib/api-envelope.ts","../src/core/services/feedback.service.ts","../src/core/services/host-tool.service.ts","../src/core/services/agent-run.service.ts","../src/core/page/page-context-snapshot.ts","../src/core/automation/automation-response.ts","../src/core/page/page-action-feedback-wish-response.ts","../src/core/services/page-action.service.ts","../src/core/services/automation.service.ts","../src/core/services/approval.service.ts","../src/core/services/app-tool.service.ts","../src/core/auth/auth.ts","../src/core/chat/skill-intent-alignment.ts","../src/core/page/page-action-client.ts","../src/core/page/page-action-reuse-cache.ts","../src/core/page/page-context-navigate.ts","../src/core/page/pending-page-action-apply.ts","../src/core/automation/automation-run-tracker.ts","../src/core/automation/automation-task-tab-store.ts","../src/core/page/page-action-rows.ts","../src/core/page/page-action-coordinator.ts","../src/utils/sdk-version.ts","../src/utils/id.ts","../src/core/client/instance.ts","../src/react/context.ts","../src/react/AgentChat.tsx","../src/react/AgentChatProvider.tsx","../src/react/useAgentChatClient.ts","../src/react/useAgentChat.ts","../src/react/useHostAction.ts","../src/react/page-agent-lifecycle.ts","../src/react/host-agent-registration.ts","../src/react/usePageAgent.ts","../src/core/page/page-action-row-sync.ts","../src/react/usePageActions.ts","../src/react/usePageAction.ts","../src/core/extension/omnix-extension-client.ts","../src/react/useOmnixExtension.ts","../src/react/useAppTool.ts","../src/react/useContextMentions.ts","../src/react/useAppAgent.ts"],"sourcesContent":["export type AgentChatErrorCode =\n | 'INVALID_DSN'\n | 'DSN_RESOLVE_FAILED'\n | 'INVALID_OPTIONS'\n | 'AUTH_REQUIRED'\n | 'LOGIN_FAILED'\n | 'ALREADY_INITIALIZED'\n | 'NOT_INITIALIZED'\n | 'SESSION_HANDSHAKE_FAILED'\n | 'MESSAGE_FAILED'\n | 'PAGE_ACTION_FAILED'\n | 'PAGE_ACTION_ALREADY_ACTIVE'\n | 'PAGE_ACTION_ROLLOUT_DENIED'\n | 'TRANSPORT_ABORTED'\n | 'TRANSPORT_FAILED'\n | 'PENDING_TIMEOUT'\n | 'CANCELLED'\n | 'DESTROYED';\n\nexport interface AgentChatErrorOptions {\n cause?: unknown;\n details?: Record<string, unknown>;\n}\n\n/**\n * Single error class used everywhere in the SDK. The `code` field is the\n * stable contract — it is what consumers should `switch` on. The `message`\n * is human readable and may evolve between versions.\n */\nexport class AgentChatError extends Error {\n readonly code: AgentChatErrorCode;\n readonly details?: Record<string, unknown>;\n\n constructor(code: AgentChatErrorCode, message: string, options: AgentChatErrorOptions = {}) {\n super(message);\n this.name = 'AgentChatError';\n this.code = code;\n if (options.cause !== undefined) {\n (this as { cause?: unknown }).cause = options.cause;\n }\n if (options.details !== undefined) {\n this.details = options.details;\n }\n if (typeof Object.setPrototypeOf === 'function') {\n Object.setPrototypeOf(this, AgentChatError.prototype);\n }\n }\n}\n","import { AgentChatError } from './errors';\n\nexport const DEFAULT_BASE_URL = 'http://localhost:3030';\n\n/** Header name through which the opaque DSN is forwarded as a credential. */\nexport const DSN_AUTH_HEADER = 'x-app-dsn';\n\nexport function normalizeDsn(dsn: unknown): string {\n if (typeof dsn !== 'string' || dsn.trim() === '') {\n throw new AgentChatError('INVALID_DSN', 'DSN must be a non-empty string', {\n details: { received: typeof dsn },\n });\n }\n return dsn.trim();\n}\n","import type { HttpClient } from '../http';\nimport { DSN_AUTH_HEADER } from '../lib/resolve';\n\n/** Sent on the first `/app-client/auth` call when an account token already exists. */\nexport const ACCOUNT_TOKEN_HEADER = 'x-account-token';\n\nexport const AUTHORIZATION_HEADER = 'Authorization';\n\n/** C-end client API DSN header (`AppClientDsnGuard`). */\nexport const CLIENT_DSN_HEADER = 'X-App-Dsn';\n\n/** Headers for `POST /app-client/auth` — `x-app-dsn` (+ optional `x-account-token`). */\nexport function buildAppClientAuthHeaders(\n dsn: string,\n accountToken?: string | null,\n): Record<string, string> {\n const headers: Record<string, string> = {\n [DSN_AUTH_HEADER]: dsn.trim(),\n };\n if (accountToken?.trim()) {\n headers[ACCOUNT_TOKEN_HEADER] = normalizeAccessToken(accountToken);\n }\n return headers;\n}\n\nexport function normalizeAccessToken(accessToken: string): string {\n return accessToken.trim().replace(/^Bearer\\s+/i, '');\n}\n\nexport function formatBearerToken(accessToken: string): string {\n return `Bearer ${normalizeAccessToken(accessToken)}`;\n}\n\n/**\n * Attach the access token returned by `/app-client/auth` for all subsequent API\n * calls (`/chat`, messages, etc.).\n */\nexport function applyAccessTokenHeader(http: HttpClient, accessToken: string): void {\n http.setDefaultHeader(AUTHORIZATION_HEADER, formatBearerToken(accessToken));\n}\n\nexport function clearAccessTokenHeader(http: HttpClient): void {\n http.setDefaultHeader(AUTHORIZATION_HEADER, undefined);\n}\n\n/** Headers for `/agent/*` client APIs (`X-App-Dsn` only; Bearer comes from defaults). */\nexport function buildAgentClientHeaders(dsn: string): Record<string, string> {\n return { [CLIENT_DSN_HEADER]: dsn.trim() };\n}\n","import type { AppClientAuthData } from './auth-types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object';\n}\n\n/**\n * Unwrap `{ data: T }` envelopes from the backend. Falls back to the root\n * object when no `data` key is present.\n */\nexport function unwrapApiData<T extends Record<string, unknown>>(body: unknown): T | null {\n if (!isRecord(body)) return null;\n if (isRecord(body.data)) return body.data as T;\n return body as T;\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction parseAppClient(value: unknown): AppClientAuthData['appClient'] {\n if (!isRecord(value)) return undefined;\n const id = value.id;\n const dsn = readString(value.dsn);\n const name = readString(value.name);\n if (typeof id !== 'number' || !dsn || !name) return undefined;\n return { id, dsn, name };\n}\n\nfunction parseUser(value: unknown): AppClientAuthData['user'] {\n if (!isRecord(value)) return undefined;\n const id = value.id;\n const email = readString(value.email);\n const username = readString(value.username);\n const userType = readString(value.userType);\n const userRole = readString(value.userRole);\n if (typeof id !== 'number' || !email || !username || !userType || !userRole) {\n return undefined;\n }\n return {\n id,\n employeeId: readString(value.employeeId),\n email,\n username,\n userType,\n userRole,\n mustChangePassword:\n typeof value.mustChangePassword === 'boolean' ? value.mustChangePassword : undefined,\n createdAt: readString(value.createdAt),\n };\n}\n\n/** Parse `/app-client/auth` or `/user/login` JSON into a normalized auth payload. */\nexport function parseAuthResponse(body: unknown): AppClientAuthData | null {\n const raw = unwrapApiData<Record<string, unknown>>(body);\n if (!raw) return null;\n\n const accessToken = readString(raw.accessToken);\n const ok = raw.ok === true || (raw.ok !== false && accessToken !== undefined);\n\n return {\n ok,\n accessToken,\n appClient: parseAppClient(raw.appClient),\n user: parseUser(raw.user),\n accountTokenBound:\n typeof raw.accountTokenBound === 'boolean' ? raw.accountTokenBound : undefined,\n };\n}\n","import { unwrapApiData } from '../auth/auth-response';\nimport { parseDraftReviewBundles } from '../draft-review/draft-review-bundle';\nimport { parseWriteDraftPublic } from '../draft-review/write-draft';\nimport { parseEditPolicyPublic } from '../draft-review/edit-policy';\nimport type { WriteDraftPublic } from '../draft-review/write-draft';\nimport type { EditPolicyPublic } from '../draft-review/edit-policy';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object';\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\n/** Discard agent-run SSE when the session has moved on (supersede / cancel-run). */\nexport function isStaleAgentRunEvent(\n sessionGeneration: number,\n generation?: number,\n): boolean {\n if (generation == null) return false;\n return generation < sessionGeneration;\n}\n\n/** Read `runGeneration` from `POST .../messages` or `POST /chat` bodies. */\nexport function parseRunGeneration(body: unknown): number | undefined {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return undefined;\n return readNumber(raw.runGeneration) ?? readNumber(raw.run_generation);\n}\n\nexport interface CancelRunResult {\n superseded: boolean;\n generation: number;\n cancelledRunId: number | null;\n}\n\n/** `GET /chat/:sessionId/run-state` — pending write gate (page refresh / multi-tab). */\nexport interface PendingWriteGateSnapshot {\n runId: number;\n turnId: number;\n draftRetryCount: number;\n draftRetryMax: number;\n canRetry: boolean;\n writeDraft: WriteDraftPublic | null;\n writeDrafts: WriteDraftPublic[] | null;\n editPolicy: EditPolicyPublic | null;\n editPolicies: Array<EditPolicyPublic | null> | null;\n}\n\n/** `GET /chat/:sessionId/run-state` snapshot. */\nexport interface SessionRunStateSnapshot {\n generation: number;\n activeRunId: number | null;\n activeTurnId: number | null;\n pendingJobCount: number;\n redisBacked: boolean;\n pendingWriteGate: PendingWriteGateSnapshot | null;\n}\n\nfunction parsePendingWriteGate(value: unknown): PendingWriteGateSnapshot | null {\n if (!isRecord(value)) return null;\n const runId = readNumber(value.runId);\n const turnId = readNumber(value.turnId);\n if (runId == null || turnId == null) return null;\n const draftRetryCount = readNumber(value.draftRetryCount) ?? 0;\n const draftRetryMax = readNumber(value.draftRetryMax) ?? 3;\n const canRetry =\n value.canRetry === false\n ? false\n : value.canRetry === true\n ? true\n : draftRetryCount < draftRetryMax;\n const bundles = parseDraftReviewBundles({\n writeDraft: parseWriteDraftPublic(value.writeDraft),\n writeDrafts: value.writeDrafts,\n editPolicy: parseEditPolicyPublic(value.editPolicy),\n editPolicies: value.editPolicies,\n });\n const primary = bundles[0] ?? null;\n return {\n runId,\n turnId,\n draftRetryCount,\n draftRetryMax,\n canRetry,\n writeDraft: primary?.writeDraft ?? null,\n writeDrafts: bundles.length > 1 ? bundles.map((bundle) => bundle.writeDraft) : null,\n editPolicy: primary?.editPolicy ?? null,\n editPolicies: bundles.length > 1 ? bundles.map((bundle) => bundle.editPolicy) : null,\n };\n}\n\n/** Parse `GET /chat/:sessionId/run-state` response. */\nexport function parseSessionRunState(body: unknown): SessionRunStateSnapshot | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n const generation = readNumber(raw.generation);\n if (generation == null) return null;\n const activeRunId = readNumber(raw.activeRunId) ?? readNumber(raw.active_run_id) ?? null;\n const activeTurnId = readNumber(raw.activeTurnId) ?? readNumber(raw.active_turn_id) ?? null;\n const pendingJobCount =\n readNumber(raw.pendingJobCount) ?? readNumber(raw.pending_job_count) ?? 0;\n return {\n generation,\n activeRunId,\n activeTurnId,\n pendingJobCount,\n redisBacked: raw.redisBacked === true || raw.redis_backed === true,\n pendingWriteGate:\n raw.pendingWriteGate === null\n ? null\n : parsePendingWriteGate(raw.pendingWriteGate),\n };\n}\n\n/** Parse `POST /chat/:sessionId/cancel-run` response. */\nexport function parseCancelRunResponse(body: unknown): CancelRunResult {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) {\n return { superseded: false, generation: 0, cancelledRunId: null };\n }\n const cancelledRunId = readNumber(raw.cancelledRunId) ?? readNumber(raw.cancelled_run_id) ?? null;\n return {\n superseded: raw.superseded === true,\n generation: readNumber(raw.generation) ?? 0,\n cancelledRunId,\n };\n}\n","import { unwrapApiData } from '../auth/auth-response';\nimport { parseRunGeneration } from './session-run';\nimport type {\n AutoAgentBinding,\n AutoAgentSource,\n ChatAgentSummary,\n ChatSessionSummary,\n ChatSkillSummary,\n} from '../../types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object';\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction parseSessionRow(row: unknown): ChatSessionSummary | null {\n if (!isRecord(row)) return null;\n\n const sessionId =\n readString(row.sessionId) ??\n readString(row.id) ??\n (typeof row.sessionId === 'number' ? String(row.sessionId) : undefined) ??\n (typeof row.id === 'number' ? String(row.id) : undefined);\n if (!sessionId) return null;\n\n const updatedAtRaw = row.updatedAt ?? row.updated_at ?? row.lastMessageAt;\n let updatedAt: number | undefined;\n if (typeof updatedAtRaw === 'number') {\n updatedAt = updatedAtRaw;\n } else if (updatedAtRaw !== undefined) {\n const parsed = new Date(updatedAtRaw as string | Date).getTime();\n updatedAt = Number.isFinite(parsed) ? parsed : undefined;\n }\n\n return {\n sessionId,\n title: readString(row.title) ?? readString(row.name),\n preview:\n readString(row.preview) ??\n readString(row.lastMessage) ??\n readString(row.summary),\n updatedAt,\n };\n}\n\nfunction rowsFromBody(body: unknown): unknown[] {\n if (Array.isArray(body)) return body;\n if (!isRecord(body)) return [];\n\n if (Array.isArray(body.data)) return body.data;\n\n if (isRecord(body.data)) {\n for (const key of ['sessions', 'agents', 'skills', 'list', 'items', 'records'] as const) {\n const candidate = body.data[key];\n if (Array.isArray(candidate)) return candidate;\n }\n }\n\n for (const key of ['sessions', 'agents', 'skills', 'list', 'items', 'records'] as const) {\n const candidate = body[key];\n if (Array.isArray(candidate)) return candidate;\n }\n\n return [];\n}\n\n/** Parse `GET /chat` response into sidebar session summaries. */\nexport function parseChatSessionList(body: unknown): ChatSessionSummary[] {\n return rowsFromBody(body)\n .map((row) => parseSessionRow(row))\n .filter((row): row is ChatSessionSummary => row !== null);\n}\n\nexport interface ChatSessionListPage {\n sessions: ChatSessionSummary[];\n page: number;\n size: number;\n total?: number;\n hasMore: boolean;\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 readBoolean(value: unknown): boolean | undefined {\n if (typeof value === 'boolean') return value;\n return undefined;\n}\n\nfunction metaRoot(body: unknown): Record<string, unknown> | null {\n if (!isRecord(body)) return null;\n if (isRecord(body.data)) return body.data;\n return body;\n}\n\n/** Parse paginated `GET /chat?page=&size=` response. */\nexport function parseChatSessionListPage(\n body: unknown,\n requestedPage: number,\n requestedSize: number,\n): ChatSessionListPage {\n const sessions = parseChatSessionList(body);\n const root = metaRoot(body);\n\n const page = readNumber(root?.page) ?? readNumber(root?.current) ?? requestedPage;\n const size =\n readNumber(root?.size) ?? readNumber(root?.pageSize) ?? requestedSize;\n const total = readNumber(root?.total) ?? readNumber(root?.totalCount);\n\n let hasMore =\n readBoolean(root?.hasMore) ??\n readBoolean(root?.hasNext) ??\n (total !== undefined ? page * size < total : sessions.length >= requestedSize);\n\n if (sessions.length < requestedSize) {\n hasMore = false;\n }\n\n return { sessions, page, size, total, hasMore };\n}\n\nexport interface ChatSessionDetail {\n sessionId: string;\n messages: unknown[];\n}\n\nexport interface ChatSessionDetailPage {\n sessionId: string;\n agentId?: string;\n messages: unknown[];\n page: number;\n size: number;\n total?: number;\n hasMore: boolean;\n}\n\ninterface DetailMessagesPageSlice {\n messages: unknown[];\n page?: number;\n size?: number;\n total?: number;\n totalPages?: number;\n hasMore?: boolean;\n}\n\nfunction messagesPageFromDetailRaw(raw: Record<string, unknown>): DetailMessagesPageSlice {\n const messagesField = raw.messages;\n\n if (Array.isArray(messagesField)) {\n return { messages: messagesField };\n }\n\n if (isRecord(messagesField)) {\n const messages = Array.isArray(messagesField.items)\n ? messagesField.items\n : Array.isArray(messagesField.list)\n ? messagesField.list\n : Array.isArray(messagesField.records)\n ? messagesField.records\n : [];\n\n const page = readNumber(messagesField.page) ?? readNumber(messagesField.current);\n const size =\n readNumber(messagesField.pageSize) ??\n readNumber(messagesField.size);\n const total =\n readNumber(messagesField.total) ?? readNumber(messagesField.totalCount);\n const totalPages = readNumber(messagesField.totalPages);\n\n let hasMore =\n readBoolean(messagesField.hasMore) ?? readBoolean(messagesField.hasNext);\n if (hasMore === undefined && page !== undefined && totalPages !== undefined) {\n hasMore = page < totalPages;\n }\n if (hasMore === undefined && page !== undefined && size !== undefined && total !== undefined) {\n hasMore = page * size < total;\n }\n\n return { messages, page, size, total, totalPages, hasMore };\n }\n\n for (const key of ['list', 'items', 'records'] as const) {\n const candidate = raw[key];\n if (Array.isArray(candidate)) return { messages: candidate };\n }\n\n return { messages: [] };\n}\n\nfunction resolveSessionIdFromRaw(raw: Record<string, unknown>): string | undefined {\n return (\n readString(raw.sessionId) ??\n readString(raw.id) ??\n (typeof raw.sessionId === 'number' ? String(raw.sessionId) : undefined)\n );\n}\n\nfunction readCatalogIdFromValue(value: unknown): string | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n return readString(value);\n}\n\nfunction readAutoAgentSource(value: unknown): AutoAgentSource | undefined {\n return value === 'requested' ||\n value === 'session' ||\n value === 'auto' ||\n value === 'default' ||\n value === 'fallback'\n ? value\n : undefined;\n}\n\nfunction parseAutoAgentBinding(raw: unknown): AutoAgentBinding | null {\n if (!isRecord(raw)) return null;\n const id = readCatalogIdFromValue(raw.id) ?? readCatalogIdFromValue(raw.agentId);\n if (!id) return null;\n return {\n id,\n source: readAutoAgentSource(raw.source),\n reason: readString(raw.reason) ?? null,\n };\n}\n\n/** Parse paginated `GET /chat/{sessionId}?page=&size=` response. */\nexport function parseChatSessionDetailPage(\n body: unknown,\n fallbackSessionId: string,\n requestedPage: number,\n requestedSize: number,\n): ChatSessionDetailPage | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n\n const sessionId = resolveSessionIdFromRaw(raw) ?? fallbackSessionId.trim();\n if (!sessionId) return null;\n const agentId = readCatalogIdFromValue(raw.agentId);\n\n const slice = messagesPageFromDetailRaw(raw);\n const messages = slice.messages;\n const root = metaRoot(body);\n\n const page =\n slice.page ??\n readNumber(root?.page) ??\n readNumber(root?.current) ??\n requestedPage;\n const size =\n slice.size ??\n readNumber(root?.size) ??\n readNumber(root?.pageSize) ??\n requestedSize;\n const total = slice.total ?? readNumber(root?.total) ?? readNumber(root?.totalCount);\n\n let hasMore =\n slice.hasMore ??\n readBoolean(root?.hasMore) ??\n readBoolean(root?.hasNext);\n\n if (hasMore === undefined && slice.totalPages !== undefined) {\n hasMore = page < slice.totalPages;\n }\n if (hasMore === undefined && total !== undefined) {\n hasMore = page * size < total;\n }\n if (hasMore === undefined) {\n hasMore = messages.length >= requestedSize;\n }\n\n if (messages.length < requestedSize) {\n hasMore = false;\n }\n\n return { sessionId, agentId, messages, page, size, total, hasMore };\n}\n\nexport interface CreateSessionResult {\n sessionId: string;\n agent?: AutoAgentBinding | null;\n}\n\n/** Parse `POST /chat` response (`{ data: { sessionId } }` or bare `{ sessionId }`). */\nexport function parseCreateSessionResponse(body: unknown): CreateSessionResult | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n\n const sessionId =\n readString(raw.sessionId) ??\n readString(raw.id) ??\n (typeof raw.sessionId === 'number' ? String(raw.sessionId) : undefined);\n if (!sessionId) return null;\n\n return { sessionId, agent: parseAutoAgentBinding(raw.agent) };\n}\n\nexport interface PostedMessagePayload {\n id: string | number;\n role: string;\n content: string | null;\n createdAt: string | number | Date;\n /** Session generation after this user turn was enqueued (SUPERSEDE or QUEUE). */\n runGeneration?: number;\n}\n\n/** Parse `POST /chat/{sessionId}/messages` response. */\nexport function parsePostedMessage(body: unknown): PostedMessagePayload | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n\n const idRaw = raw.id;\n if (\n idRaw === undefined ||\n idRaw === null ||\n (typeof idRaw !== 'string' && typeof idRaw !== 'number')\n ) {\n return null;\n }\n\n const role = readString(raw.role) ?? 'user';\n const content =\n typeof raw.content === 'string' ? raw.content : raw.content == null ? null : String(raw.content);\n\n const createdAt = (raw.createdAt ?? raw.created_at ?? Date.now()) as string | number | Date;\n\n const runGeneration = parseRunGeneration(raw);\n\n return { id: idRaw, role, content, createdAt, runGeneration };\n}\n\n/** Parse `GET /chat/{sessionId}` response. */\nexport function parseChatSessionDetail(body: unknown): ChatSessionDetail | null {\n const page = parseChatSessionDetailPage(body, '', 1, Number.MAX_SAFE_INTEGER);\n if (!page || !page.sessionId) return null;\n return { sessionId: page.sessionId, messages: page.messages };\n}\n\nfunction readCatalogId(\n row: Record<string, unknown>,\n ...keys: string[]\n): string | undefined {\n for (const key of keys) {\n const value = row[key];\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n const text = readString(value);\n if (text) return text;\n }\n return undefined;\n}\n\nfunction parseAgentRow(row: unknown): ChatAgentSummary | null {\n if (!isRecord(row)) return null;\n const id = readCatalogId(row, 'id', 'agentId');\n const name =\n readString(row.name) ?? readString(row.title) ?? readString(row.label);\n if (!id || !name) return null;\n return {\n id,\n name,\n description: readString(row.description) ?? readString(row.desc) ?? null,\n };\n}\n\nfunction parseSkillRow(row: unknown): ChatSkillSummary | null {\n if (!isRecord(row)) return null;\n const id = readCatalogId(row, 'id', 'skillId');\n const name =\n readString(row.name) ?? readString(row.title) ?? readString(row.label);\n if (!id || !name) return null;\n const agentId = readCatalogId(row, 'agentId', 'agent_id');\n const riskLevelRaw = readString(row.riskLevel);\n const riskLevel =\n riskLevelRaw === 'L1' || riskLevelRaw === 'L2' || riskLevelRaw === 'L3'\n ? riskLevelRaw\n : undefined;\n const toolIds = Array.isArray(row.toolIds)\n ? row.toolIds.filter((value): value is number => typeof value === 'number')\n : undefined;\n const hostToolIds = Array.isArray(row.hostToolIds)\n ? row.hostToolIds.filter((value): value is number => typeof value === 'number')\n : undefined;\n const pageMatched =\n typeof row.pageMatched === 'boolean' ? row.pageMatched : undefined;\n return {\n id,\n name,\n description: readString(row.description) ?? readString(row.desc) ?? null,\n agentId,\n capabilityKey: readString(row.capabilityKey) ?? null,\n riskLevel,\n requiresWriteConfirmation:\n typeof row.requiresWriteConfirmation === 'boolean'\n ? row.requiresWriteConfirmation\n : undefined,\n toolIds,\n hostToolIds,\n pageMatched,\n };\n}\n\n/** Parse `GET /agent/client/available` (or bare JSON array) response. */\nexport function parseAgentList(body: unknown): ChatAgentSummary[] {\n return rowsFromBody(body)\n .map((row) => parseAgentRow(row))\n .filter((row): row is ChatAgentSummary => row !== null);\n}\n\nfunction readStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === 'string' && item.trim().length > 0);\n}\n\nfunction parseDownReasonTagRow(row: unknown): { key: string; label: string } | null {\n if (!isRecord(row)) return null;\n const key = readString(row.key);\n const label = readString(row.label);\n if (!key || !label) return null;\n return { key, label };\n}\n\n/** Parse `GET /chat/feedback/down-reason-tags` `data`. */\nexport function parseDownReasonTags(data: unknown): { items: { key: string; label: string }[] } {\n if (!isRecord(data)) return { items: [] };\n const rows = Array.isArray(data.items) ? data.items : [];\n return {\n items: rows\n .map((row) => parseDownReasonTagRow(row))\n .filter((row): row is { key: string; label: string } => row !== null),\n };\n}\n\n/** Parse `MessageFeedbackView` from API `data`. */\nexport function parseMessageFeedbackView(data: unknown): {\n messageId: number;\n rating: 'up' | 'down';\n reasonTags: string[];\n comment: string | null;\n createdAt: string;\n updatedAt: string;\n} {\n if (!isRecord(data)) {\n throw new Error('Invalid message feedback payload');\n }\n const messageId = readNumber(data.messageId);\n const rating = data.rating === 'up' || data.rating === 'down' ? data.rating : null;\n const createdAt = readString(data.createdAt);\n const updatedAt = readString(data.updatedAt);\n if (messageId === undefined || !rating || !createdAt || !updatedAt) {\n throw new Error('Invalid message feedback payload');\n }\n return {\n messageId,\n rating,\n reasonTags: readStringArray(data.reasonTags),\n comment: typeof data.comment === 'string' ? data.comment : data.comment == null ? null : String(data.comment),\n createdAt,\n updatedAt,\n };\n}\n\n/** Parse `GET .../messages/feedbacks` `data`. */\nexport function parseMessageFeedbackBatch(data: unknown): {\n items: ReturnType<typeof parseMessageFeedbackView>[];\n} {\n if (!isRecord(data)) return { items: [] };\n const rows = Array.isArray(data.items) ? data.items : [];\n const items: ReturnType<typeof parseMessageFeedbackView>[] = [];\n for (const row of rows) {\n try {\n items.push(parseMessageFeedbackView(row));\n } catch {\n /* skip malformed row */\n }\n }\n return { items };\n}\n\n/** Parse `GET /agent/:agentId/skills/client` (or bare JSON array) response. */\nexport function parseSkillList(body: unknown, agentId?: string): ChatSkillSummary[] {\n const normalizedAgentId = agentId?.trim().toLowerCase();\n return rowsFromBody(body)\n .map((row) => parseSkillRow(row))\n .filter((row): row is ChatSkillSummary => row !== null)\n .filter((row) => {\n if (!normalizedAgentId) return true;\n if (!row.agentId) return true;\n return row.agentId.trim().toLowerCase() === normalizedAgentId;\n });\n}\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n","import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n","const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst shouldDispatchFromDevtools = (api) => !!api.dispatchFromDevtools && typeof api.dispatch === \"function\";\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst v8StackLineRe = /^at (?:new |async )?(.+?) \\(/;\nconst geckoStackLineRe = /^([^@]+)@/;\nfunction findCallerName(stack) {\n var _a, _b, _c;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return ((_b = v8StackLineRe.exec(callerLine)) == null ? void 0 : _b[1]) || ((_c = geckoStackLineRe.exec(callerLine)) == null ? void 0 : _c[1]);\n}\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (shouldDispatchFromDevtools(api)) {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (shouldDispatchFromDevtools(api)) {\n api.dispatch(action);\n }\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => window.localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n let hydrationVersion = 0;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n const currentVersion = ++hydrationVersion;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n if (currentVersion !== hydrationVersion) {\n return;\n }\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(get(), void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n ++hydrationVersion;\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n","import type { AuthUser } from './auth-types';\n\n/** Zustand persist key — must stay aligned with {@link useAuthStore}. */\nexport const AUTH_STORAGE_KEY = 'agent-chat-auth';\n\n/** CustomEvent name for browser-extension token sync. */\nexport const AUTH_CHANGED_EVENT = 'omnix:auth-changed';\n\nexport type OmnixAuthBridgeDetail = {\n loggedIn: boolean;\n dsn: string | null;\n accessToken: string | null;\n user: AuthUser | null;\n};\n\n/** Notify Omnix Token Sync extension (and other host listeners) on auth changes. */\nexport function notifyOmnixAuthBridge(detail: OmnixAuthBridgeDetail): void {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n window.dispatchEvent(new CustomEvent(AUTH_CHANGED_EVENT, { detail }));\n } catch {\n /* non-browser / locked-down environments */\n }\n}\n","import { create } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { AUTH_STORAGE_KEY, notifyOmnixAuthBridge } from './auth-bridge';\nimport type { AppClientAuthData, AppClientInfo, AuthUser } from './auth-types';\n\nexport { AUTH_STORAGE_KEY, AUTH_CHANGED_EVENT } from './auth-bridge';\nexport type { OmnixAuthBridgeDetail } from './auth-bridge';\n\nexport interface AuthStoreState {\n dsn: string | null;\n accessToken: string | null;\n user: AuthUser | null;\n appClient: AppClientInfo | null;\n accountTokenBound: boolean | null;\n setAuth: (dsn: string, data: AppClientAuthData) => void;\n clearAuth: () => void;\n getAccessTokenForDsn: (dsn: string) => string | null;\n}\n\nconst initialState = {\n dsn: null,\n accessToken: null,\n user: null,\n appClient: null,\n accountTokenBound: null,\n} as const;\n\nexport const useAuthStore = create<AuthStoreState>()(\n persist(\n (set, get) => ({\n ...initialState,\n setAuth(dsn, data) {\n const accessToken = data.accessToken ?? null;\n const user = data.user ?? null;\n set({\n dsn,\n accessToken,\n user,\n appClient: data.appClient ?? null,\n accountTokenBound: data.accountTokenBound ?? null,\n });\n notifyOmnixAuthBridge({\n loggedIn: Boolean(accessToken?.trim()),\n dsn,\n accessToken,\n user,\n });\n },\n clearAuth() {\n set({ ...initialState });\n notifyOmnixAuthBridge({\n loggedIn: false,\n dsn: null,\n accessToken: null,\n user: null,\n });\n },\n getAccessTokenForDsn(dsn) {\n const state = get();\n if (state.dsn === dsn && state.accessToken) return state.accessToken;\n return null;\n },\n }),\n { name: AUTH_STORAGE_KEY },\n ),\n);\n","import { AgentChatError } from '../lib/errors';\nimport { useAuthStore } from './auth-store';\n\n/** 宿主 UI / Hook 统一展示的未登录文案 */\nexport const AUTH_REQUIRED_USER_MESSAGE = '请在本页完成 Omnix 登录(SDK)';\n\n/**\n * 等待 Zustand persist 从 localStorage 恢复完成。\n * init 前必须 await,否则 reload 后会误判为未登录。\n */\nexport function waitForAuthStoreRehydration(timeoutMs = 3_000): Promise<void> {\n if (useAuthStore.persist.hasHydrated()) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, timeoutMs);\n const unsub = useAuthStore.persist.onFinishHydration(() => {\n clearTimeout(timer);\n unsub();\n resolve();\n });\n });\n}\n\n/** SDK 用户 JWT 是否对应当前 DSN(SSOT:`useAuthStore`) */\nexport function isSdkAuthenticatedForDsn(dsn: string | null | undefined): boolean {\n if (!dsn?.trim()) {\n return false;\n }\n const { dsn: storeDsn, accessToken } = useAuthStore.getState();\n return storeDsn === dsn && Boolean(accessToken?.trim());\n}\n\n/** 读取当前 DSN 对应的 accessToken(无则 null) */\nexport function getSdkAccessTokenForDsn(dsn: string): string | null {\n return useAuthStore.getState().getAccessTokenForDsn(dsn);\n}\n\n/** 命令式校验 — 未登录时同步抛 `AUTH_REQUIRED`(不走 {@link LoginGate} 挂起) */\nexport function assertSdkAuthenticatedForDsn(\n dsn: string | null | undefined,\n method = 'operation',\n): void {\n if (isSdkAuthenticatedForDsn(dsn)) {\n return;\n }\n throw new AgentChatError(\n 'AUTH_REQUIRED',\n `${AUTH_REQUIRED_USER_MESSAGE}(${method} 需要登录)`,\n );\n}\n","import { AgentChatError } from '../lib/errors';\n\nexport type PendingGateJobKind = 'init' | 'login';\n\n/** SDK 门禁挂起中的任务(等待 init 或 login) */\nexport type PendingGateJob = {\n id: string;\n label: string;\n kind: PendingGateJobKind;\n createdAt: number;\n};\n\nexport type LoginGateWaitOptions = {\n /** 用于超时 / 取消错误文案 */\n label?: string;\n timeoutMs?: number;\n signal?: AbortSignal;\n};\n\ntype LoginWaiter = {\n jobId: string;\n fulfill: () => void;\n reject: (err: AgentChatError) => void;\n dispose: () => void;\n};\n\n/**\n * 就绪门禁:未就绪时挂起 Promise;就绪谓词为真时 reconcile 唤醒等待者;destroy 时 cancelAll。\n * AgentChatClient 用两个实例分别等待 init 与 login。\n */\nexport class LoginGate {\n private waiters: LoginWaiter[] = [];\n private pendingJobs: PendingGateJob[] = [];\n private pendingSeq = 0;\n\n private readonly isReady: () => boolean;\n private readonly kind: PendingGateJobKind;\n private readonly onPendingChange?: () => void;\n\n constructor(\n isReady: () => boolean,\n kind: PendingGateJobKind,\n onPendingChange?: () => void,\n ) {\n this.isReady = isReady;\n this.kind = kind;\n this.onPendingChange = onPendingChange;\n }\n\n /** 当前挂起任务快照 */\n getPendingJobs(): PendingGateJob[] {\n return [...this.pendingJobs];\n }\n\n /** 就绪谓词为真时唤醒所有等待者(未就绪则 no-op) */\n reconcile(): void {\n if (!this.isReady() || this.waiters.length === 0) return;\n const pending = this.waiters.splice(0);\n this.pendingJobs = [];\n this.onPendingChange?.();\n for (const waiter of pending) {\n waiter.dispose();\n waiter.fulfill();\n }\n }\n\n /** 实例销毁 — 拒绝所有等待者 */\n cancelAll(message = '登录等待已取消'): void {\n if (this.waiters.length === 0) return;\n const pending = this.waiters.splice(0);\n this.pendingJobs = [];\n this.onPendingChange?.();\n const err = new AgentChatError('CANCELLED', message);\n for (const waiter of pending) {\n waiter.dispose();\n waiter.reject(err);\n }\n }\n\n /** 已就绪立即返回;否则挂起直到 reconcile / cancelAll / 超时 / signal abort */\n wait(options: LoginGateWaitOptions = {}): Promise<void> {\n const label = options.label ?? 'operation';\n const timeoutMs = options.timeoutMs ?? 300_000;\n const { signal } = options;\n\n if (this.isReady()) {\n return Promise.resolve();\n }\n\n if (signal?.aborted) {\n return Promise.reject(new AgentChatError('CANCELLED', `${label} 已取消`));\n }\n\n return new Promise<void>((resolve, reject) => {\n let disposed = false;\n this.pendingSeq += 1;\n const jobId = `gate-${this.kind}-${Date.now()}-${this.pendingSeq}`;\n const job: PendingGateJob = {\n id: jobId,\n label,\n kind: this.kind,\n createdAt: Date.now(),\n };\n this.pendingJobs.push(job);\n this.onPendingChange?.();\n\n const removeJob = () => {\n const idx = this.pendingJobs.findIndex((entry) => entry.id === jobId);\n if (idx >= 0) {\n this.pendingJobs.splice(idx, 1);\n this.onPendingChange?.();\n }\n };\n\n const dispose = () => {\n if (disposed) return;\n disposed = true;\n clearTimeout(timer);\n signal?.removeEventListener('abort', onAbort);\n const idx = this.waiters.findIndex((w) => w.jobId === jobId);\n if (idx >= 0) this.waiters.splice(idx, 1);\n removeJob();\n };\n\n const waiter: LoginWaiter = {\n jobId,\n fulfill: () => {\n dispose();\n resolve();\n },\n reject: (err: AgentChatError) => {\n dispose();\n reject(err);\n },\n dispose,\n };\n\n const timer = setTimeout(() => {\n waiter.reject(new AgentChatError(\n 'PENDING_TIMEOUT',\n `${label} 等待${this.kind === 'init' ? '初始化' : '登录'}超时(${Math.round(timeoutMs / 1000)}s)`,\n ));\n }, timeoutMs);\n\n const onAbort = () => {\n waiter.reject(new AgentChatError('CANCELLED', `${label} 已取消`));\n };\n signal?.addEventListener('abort', onAbort);\n\n this.waiters.push(waiter);\n });\n }\n\n /** 等待就绪后执行 */\n async run<T>(\n options: LoginGateWaitOptions,\n fn: () => T | Promise<T>,\n ): Promise<T> {\n await this.wait(options);\n return fn();\n }\n}\n","/**\n * SDK ↔ Omnix Token Sync 扩展 契约(SSOT)\n *\n * - **认证**:以 SDK `useAuthStore` / localStorage 为准;扩展通过 `omnix:auth-changed` 镜像\n * - **能力**:业务侧只调 SDK 封装(trackGofoWaybill 等),不直接调 chrome.runtime\n * - **插件**:只读 SDK 认证、只暴露 `window.OmnixExtension`(由 SDK 内部消费)\n * - **门禁**:PMS 同步须 SDK 已登录;GOFO 查询不依赖登录\n */\nimport { isSdkAuthenticatedForDsn } from '../auth/auth-session';\nimport { useAuthStore } from '../auth/auth-store';\n\nexport { AUTH_STORAGE_KEY, AUTH_CHANGED_EVENT } from '../auth/auth-bridge';\n\n/** 扩展注入页面 MAIN world 后派发 */\nexport const EXTENSION_READY_EVENT = 'omnix:extension-ready';\n\n/** 页面/SDK 请求 content script 重新注入 bridge(late install / 注入失败时) */\nexport const EXTENSION_BRIDGE_REQUEST_EVENT = 'omnix:request-extension-bridge';\n\n/** SDK persist 存储 key — config.json `omnixAuthStorageKey` 须与此一致 */\nexport const SDK_AUTH_STORAGE_KEY = 'agent-chat-auth';\n\n/** 扩展是否要求 SDK 已登录后才允许 PMS 等能力(任意 DSN 有 token 即视为已登录) */\nexport function isOmnixSdkAuthenticated(): boolean {\n return isSdkAuthenticatedForDsn(useAuthStore.getState().dsn);\n}\n\n/** 未登录时抛错 — SDK 调用扩展能力前必须校验 */\nexport function requireOmnixSdkAuthentication(): void {\n if (!isOmnixSdkAuthenticated()) {\n throw new Error('请先登录 Omnix');\n }\n}\n","import { notifyOmnixAuthBridge } from '../auth/auth-bridge';\nimport { useAuthStore } from '../auth/auth-store';\nimport {\n EXTENSION_BRIDGE_REQUEST_EVENT,\n EXTENSION_READY_EVENT,\n} from './extension-contract';\n\nlet extensionAuthResyncBound = false;\n\n/**\n * 插件 late-install / programmatic inject 后派发 `omnix:extension-ready` 时,\n * 让 SDK 再广播一次当前登录态,避免用户刷新页面。\n */\nexport function ensureExtensionAuthResyncListener(): void {\n if (extensionAuthResyncBound || typeof window === 'undefined') {\n return;\n }\n extensionAuthResyncBound = true;\n\n try {\n window.dispatchEvent(new CustomEvent(EXTENSION_BRIDGE_REQUEST_EVENT));\n } catch {\n /* non-browser */\n }\n\n window.addEventListener(EXTENSION_READY_EVENT, () => {\n const { dsn, accessToken, user } = useAuthStore.getState();\n notifyOmnixAuthBridge({\n loggedIn: Boolean(accessToken?.trim()),\n dsn,\n accessToken,\n user,\n });\n });\n}\n","/**\n * Tiny typed event bus.\n *\n * Design notes:\n * - `on()` returns an unsubscribe function for ergonomic teardown.\n * - Re-registering the same `(event, handler)` pair is idempotent.\n * - During `emit()` we iterate over a snapshot, so handlers added or removed\n * while a broadcast is in progress do not affect the current pass — the\n * newly added handler will fire on the *next* `emit`.\n */\nexport class EventBus<EventMap extends Record<string, unknown> = Record<string, unknown>> {\n private handlers: Map<keyof EventMap, Set<(payload: never) => void>> = new Map();\n\n on<K extends keyof EventMap>(\n event: K,\n handler: (payload: EventMap[K]) => void,\n ): () => void {\n let bucket = this.handlers.get(event);\n if (!bucket) {\n bucket = new Set();\n this.handlers.set(event, bucket);\n }\n bucket.add(handler as (payload: never) => void);\n return () => this.off(event, handler);\n }\n\n off<K extends keyof EventMap>(\n event: K,\n handler: (payload: EventMap[K]) => void,\n ): void {\n const bucket = this.handlers.get(event);\n if (!bucket) return;\n bucket.delete(handler as (payload: never) => void);\n if (bucket.size === 0) {\n this.handlers.delete(event);\n }\n }\n\n emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void {\n const bucket = this.handlers.get(event);\n if (!bucket || bucket.size === 0) return;\n const snapshot = Array.from(bucket);\n for (const handler of snapshot) {\n try {\n (handler as (payload: EventMap[K]) => void)(payload);\n } catch (err) {\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error('[agent-chat] event handler threw:', err);\n }\n }\n }\n }\n\n listenerCount<K extends keyof EventMap>(event: K): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n\n clear(): void {\n this.handlers.clear();\n }\n}\n","/**\n * Host Tool 流式 DSL 协议类型(规范 v1)。\n * 规范文档:agent-server/docs/host-tool-dsl-frontend-guide.md\n */\n\nexport const HOST_TOOL_STREAM_PROTOCOL_VERSION = 1 as const;\n\n/** 与 message SSE 对齐的流控模式。 */\nexport type HostToolStreamMode =\n | 'begin'\n | 'delta'\n | 'commit'\n | 'end'\n | 'full';\n\nexport type HostToolStreamControl = {\n mode: HostToolStreamMode;\n /** 单轮 host 流内单调递增,用于去重与排序。 */\n seq: number;\n};\n\nexport type HostToolDslSessionBegin = {\n op: 'session.begin';\n streamId: string;\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n reason?: string;\n planStepId?: string;\n runId?: number;\n turnId?: number;\n};\n\nexport type HostToolDslSessionEnd = {\n op: 'session.end';\n streamId: string;\n};\n\nexport type HostToolDslToolBegin = {\n op: 'tool.begin';\n streamId: string;\n callId: string;\n index: number;\n name: string;\n};\n\nexport type HostToolDslArgSet = {\n op: 'arg.set';\n streamId: string;\n callId: string;\n path: string;\n value: unknown;\n};\n\nexport type HostToolDslArgAppend = {\n op: 'arg.append';\n streamId: string;\n callId: string;\n path: string;\n chunk: string;\n};\n\nexport type HostToolDslToolCommit = {\n op: 'tool.commit';\n streamId: string;\n callId: string;\n};\n\nexport type HostToolDslToolFlush = {\n op: 'tool.flush';\n streamId: string;\n callId: string;\n name: string;\n args: Record<string, unknown>;\n};\n\nexport type HostToolDslOp =\n | HostToolDslSessionBegin\n | HostToolDslSessionEnd\n | HostToolDslToolBegin\n | HostToolDslArgSet\n | HostToolDslArgAppend\n | HostToolDslToolCommit\n | HostToolDslToolFlush;\n\nexport type HostActionHostToolInvocation = {\n name: string;\n args: Record<string, unknown>;\n};\n\n/** 批量快照(v0 兼容;流式轮次末尾权威帧)。 */\nexport type HostActionBatchPayload = {\n action: 'host_action';\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n hostTools: HostActionHostToolInvocation[];\n planStepId?: string;\n reason?: string;\n runId?: number;\n turnId?: number;\n generation?: number;\n};\n\n/** 流式 DSL 帧(v1)。 */\nexport type HostActionStreamPayload = {\n action: 'host_action';\n v?: typeof HOST_TOOL_STREAM_PROTOCOL_VERSION;\n stream: HostToolStreamControl;\n dsl?: HostToolDslOp;\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n hostTools?: HostActionHostToolInvocation[];\n planStepId?: string;\n reason?: string;\n runId?: number;\n turnId?: number;\n generation?: number;\n};\n\nexport type HostActionSsePayload = HostActionBatchPayload | HostActionStreamPayload;\n\n/** Per-tool streaming policy from {@link HostToolDefinition}. */\nexport type HostToolStreamConfig = {\n enabled?: boolean;\n policy?: 'stream' | 'batch';\n /** When true, registry handler runs on each arg.append / arg.set. Default false. */\n invokeOnAppend?: boolean;\n};\n\nexport function isHostActionStreamPayload(\n payload: HostActionSsePayload,\n): payload is HostActionStreamPayload {\n return (\n 'stream' in payload &&\n payload.stream != null &&\n typeof payload.stream.mode === 'string'\n );\n}\n\nexport function isHostActionBatchPayload(\n payload: HostActionSsePayload,\n): payload is HostActionBatchPayload {\n return !isHostActionStreamPayload(payload);\n}\n\nexport type HostToolStreamProfile = 'fill_stream' | 'instant';\n\n/** Detect DSL profile from accumulated ops (see host-tool-dsl-frontend-guide §2.3). */\nexport function detectHostToolStreamProfile(\n ops: Iterable<HostToolDslOp>,\n): HostToolStreamProfile {\n for (const op of ops) {\n if (op.op === 'tool.flush') return 'instant';\n }\n return 'fill_stream';\n}\n","import type { AgentChatHostAction, AgentChatHostToolCall } from '../../types';\nimport type { HostActionSsePayload, HostToolDslOp, HostToolStreamMode } from './stream/host-tool-stream.types';\nimport { isHostActionStreamPayload } from './stream/host-tool-stream.types';\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readEntity(\n value: unknown,\n): AgentChatHostAction['entity'] | undefined {\n if (!isRecord(value)) return undefined;\n const type = readString(value.type);\n const id = readString(value.id);\n if (!type && !id && Object.keys(value).length === 0) return undefined;\n return { ...value, ...(type ? { type } : {}), ...(id ? { id } : {}) };\n}\n\nfunction readMetadata(value: unknown): Record<string, unknown> | undefined {\n if (!isRecord(value)) return undefined;\n return value;\n}\n\nfunction normalizeHostToolInvocation(item: unknown): AgentChatHostToolCall | null {\n if (!isRecord(item)) return null;\n const name = readString(item.name);\n if (!name) return null;\n const args = isRecord(item.args) ? item.args : {};\n return { name, args };\n}\n\nfunction readHostTools(record: Record<string, unknown>): AgentChatHostToolCall[] {\n if (!Array.isArray(record.hostTools)) return [];\n const items: AgentChatHostToolCall[] = [];\n for (const item of record.hostTools) {\n const normalized = normalizeHostToolInvocation(item);\n if (normalized) items.push(normalized);\n }\n return items;\n}\n\nfunction readHostActionEnvelope(\n record: Record<string, unknown>,\n): Record<string, unknown> {\n if (record.hostAction && typeof record.hostAction === 'object') {\n return record.hostAction as Record<string, unknown>;\n }\n return record;\n}\n\nfunction isHostActionMarker(record: Record<string, unknown>): boolean {\n const action = readString(record.action);\n if (action === 'host_action' || action === 'host-action') return true;\n if (record.hostAction && typeof record.hostAction === 'object') return true;\n return false;\n}\n\nfunction readMessageId(\n nested: Record<string, unknown>,\n record: Record<string, unknown>,\n): string | undefined {\n return (\n readString(nested.messageId) ??\n readString(nested.message_id) ??\n readString(record.messageId) ??\n readString(record.message_id)\n );\n}\n\nfunction parseModernHostAction(record: Record<string, unknown>): AgentChatHostAction | null {\n const nested = readHostActionEnvelope(record);\n const actionField = readString(nested.action) ?? readString(record.action);\n const hasNestedHostAction =\n record.hostAction && typeof record.hostAction === 'object';\n\n if (\n actionField !== 'host_action' &&\n actionField !== 'host-action' &&\n !hasNestedHostAction\n ) {\n return null;\n }\n\n const hostTools = readHostTools(nested);\n if (hostTools.length === 0) return null;\n\n const scope = readString(nested.scope);\n if (!scope) return null;\n\n const runId = typeof nested.runId === 'number' ? nested.runId : undefined;\n const turnId = typeof nested.turnId === 'number' ? nested.turnId : undefined;\n\n return {\n action: 'host_action',\n scope,\n entity: readEntity(nested.entity),\n metadata: readMetadata(nested.metadata),\n hostTools,\n planStepId: readString(nested.planStepId),\n reason: readString(nested.reason),\n runId,\n turnId,\n messageId: readMessageId(nested, record),\n };\n}\n\n/**\n * Transitional adapter for legacy payloads that used `status: 'completed'`.\n * Remove once all agent-server instances emit the modern envelope.\n */\nfunction parseLegacyHostAction(record: Record<string, unknown>): AgentChatHostAction | null {\n const nested = readHostActionEnvelope(record);\n const status = readString(nested.status) ?? readString(record.status);\n if (status !== 'completed') return null;\n\n const withAction: Record<string, unknown> = {\n ...record,\n action: 'host_action',\n };\n if (record.hostAction && typeof record.hostAction === 'object') {\n withAction.hostAction = {\n ...(record.hostAction as Record<string, unknown>),\n action: 'host_action',\n };\n }\n return parseModernHostAction(withAction);\n}\n\n/** True when the action can be emitted and dispatched to handlers / host tools. */\nexport function isDispatchableHostAction(action: AgentChatHostAction): boolean {\n return (\n action.action === 'host_action' &&\n Boolean(action.scope?.trim()) &&\n action.hostTools.length > 0\n );\n}\n\n/**\n * Parse a backend SSE / JSON payload into a host action.\n * Requires `action: host_action`, non-empty `hostTools`, and `scope`.\n */\nexport function parseHostActionPayload(\n raw: unknown,\n): AgentChatHostAction | null {\n if (!isRecord(raw)) return null;\n const modern = parseModernHostAction(raw);\n if (modern) return modern;\n return parseLegacyHostAction(raw);\n}\n\n/** @alias {@link parseHostActionPayload} */\nexport const normalizeHostAction = parseHostActionPayload;\n\n/**\n * Parse a host_action SSE payload (v0 batch or v1 stream frame).\n * Returns null when the envelope is not a host action.\n */\nexport function parseHostActionSsePayload(raw: unknown): HostActionSsePayload | null {\n if (!isRecord(raw)) return null;\n const nested = readHostActionEnvelope(raw);\n const actionField = readString(nested.action) ?? readString(raw.action);\n const hasNestedHostAction =\n raw.hostAction && typeof raw.hostAction === 'object';\n\n if (\n actionField !== 'host_action' &&\n actionField !== 'host-action' &&\n !hasNestedHostAction\n ) {\n return null;\n }\n\n const source = nested;\n const action = readString(source.action) ?? 'host_action';\n const base = {\n action: action === 'host-action' ? 'host_action' : action,\n scope: readString(source.scope),\n entity: readEntity(source.entity),\n metadata: readMetadata(source.metadata),\n planStepId: readString(source.planStepId),\n reason: readString(source.reason),\n runId: typeof source.runId === 'number' ? source.runId : undefined,\n turnId: typeof source.turnId === 'number' ? source.turnId : undefined,\n generation:\n typeof source.generation === 'number' && Number.isFinite(source.generation)\n ? source.generation\n : undefined,\n } as HostActionSsePayload;\n\n if (isHostActionStreamPayload(source as HostActionSsePayload)) {\n const streamRaw = source.stream as Record<string, unknown> | undefined;\n const mode = streamRaw?.mode;\n const seq = streamRaw?.seq;\n const validModes: HostToolStreamMode[] = ['begin', 'delta', 'commit', 'end', 'full'];\n if (\n typeof mode !== 'string' ||\n !validModes.includes(mode as HostToolStreamMode) ||\n typeof seq !== 'number' ||\n !Number.isFinite(seq)\n ) {\n return null;\n }\n const hostTools = readHostTools(source);\n const streamPayload: HostActionSsePayload = {\n ...base,\n action: 'host_action',\n v: source.v === 1 ? 1 : undefined,\n stream: { mode: mode as HostToolStreamMode, seq },\n ...(source.dsl && typeof source.dsl === 'object'\n ? { dsl: source.dsl as HostToolDslOp }\n : {}),\n ...(hostTools.length > 0 ? { hostTools } : {}),\n };\n return streamPayload;\n }\n\n const hostTools = readHostTools(source);\n if (hostTools.length === 0) return null;\n\n return {\n ...base,\n action: 'host_action',\n hostTools,\n };\n}\n\n/** Convert v0 / full SSE payload to {@link AgentChatHostAction}. */\nexport function hostActionSseToAgentAction(\n payload: HostActionSsePayload,\n sessionId?: string,\n): AgentChatHostAction | null {\n if (isHostActionStreamPayload(payload) && payload.stream.mode !== 'full') {\n return null;\n }\n const hostTools = payload.hostTools ?? [];\n if (hostTools.length === 0) return null;\n const scope = payload.scope?.trim();\n if (!scope) return null;\n return {\n action: 'host_action',\n scope,\n entity: payload.entity as AgentChatHostAction['entity'],\n metadata: payload.metadata,\n hostTools,\n planStepId: payload.planStepId,\n reason: payload.reason,\n runId: payload.runId,\n turnId: payload.turnId,\n sessionId,\n streamPhase: 'complete',\n };\n}\n\nexport function isHostActionEnvelope(record: Record<string, unknown>): boolean {\n return (\n isHostActionMarker(readHostActionEnvelope(record)) || isHostActionMarker(record)\n );\n}\n","/**\n * Maps backend SSE events to UI actions.\n *\n * Preferred SSE events: `think` | `message` | `complete` | `error`\n * Backward compatible: `result` | `message.delta` | `message.done`\n */\n\nimport { isHostActionEnvelope, normalizeHostAction, parseHostActionSsePayload } from '../host-tool/host-action';\nimport { parseEditPolicyPublic, type EditPolicyPublic } from '../draft-review/edit-policy';\nimport { parseDraftReviewBundles } from '../draft-review/draft-review-bundle';\nimport { parseWriteDraftPublic, type WriteDraftPublic } from '../draft-review/write-draft';\nimport type { AgentChatHostAction } from '../../types';\nimport type { HostActionSsePayload } from '../host-tool/stream/host-tool-stream.types';\n\nexport interface ServerMessagePayload {\n id?: string | number;\n role?: string;\n content?: string;\n createdAt?: string | number | Date;\n}\n\nexport type SseMessageBlock = Record<string, unknown> & { type: string; id?: string };\nexport interface SseMessageBlockPatch {\n replaceId: string;\n block: SseMessageBlock;\n}\n\nexport type ChatSseUiAction =\n | {\n type: 'think';\n text: string;\n mode: 'replace' | 'append';\n messageId?: string;\n runId?: number;\n generation?: number;\n }\n | {\n type: 'result';\n text: string;\n mode: 'replace' | 'append';\n messageId?: string;\n runId?: number;\n generation?: number;\n }\n | {\n type: 'message-blocks';\n runId?: number;\n turnId?: number;\n generation?: number;\n action: 'stream' | 'patch';\n streamMode?: 'delta' | 'full' | 'patch';\n seq?: number;\n blocks?: SseMessageBlock[];\n patches?: SseMessageBlockPatch[];\n messageId?: string;\n }\n | {\n type: 'write-confirmation-required';\n runId: number;\n turnId?: number;\n message: string;\n code?: string;\n generation?: number;\n draftRetryCount?: number;\n draftRetryMax?: number;\n canRetry?: boolean;\n writeDraft?: WriteDraftPublic;\n writeDrafts?: WriteDraftPublic[];\n editPolicy?: EditPolicyPublic;\n editPolicies?: Array<EditPolicyPublic | null>;\n }\n | {\n type: 'write-confirmation-cancelled';\n runId?: number;\n turnId?: number;\n message: string;\n code?: string;\n generation?: number;\n }\n | {\n type: 'host-action';\n action?: AgentChatHostAction;\n ssePayload?: HostActionSsePayload;\n runId?: number;\n generation?: number;\n }\n | {\n type: 'complete';\n serverMessage?: ServerMessagePayload;\n messageId?: string;\n runId?: number;\n generation?: number;\n status?: string;\n reason?: string;\n }\n | {\n type: 'error';\n message: string;\n code?: string;\n runId?: number;\n generation?: number;\n }\n | { type: 'noop' };\n\nfunction tryParseJson(raw: string): unknown {\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return null;\n }\n}\n\nfunction readGeneration(parsed: Record<string, unknown> | null): number | undefined {\n if (!parsed) return undefined;\n const raw = parsed.generation ?? parsed.runGeneration ?? parsed.run_generation;\n return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;\n}\n\nfunction readRunId(parsed: Record<string, unknown> | null): number | undefined {\n if (!parsed) return undefined;\n const raw = parsed.runId ?? parsed.run_id;\n return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;\n}\n\nfunction readHostActionRunMeta(\n parsed: Record<string, unknown>,\n ssePayload: HostActionSsePayload,\n): { generation?: number; runId?: number } {\n return {\n generation: readGeneration(parsed) ?? ssePayload.generation,\n runId: readRunId(parsed) ?? ssePayload.runId,\n };\n}\n\nfunction readSseRunMeta(data: string): { generation?: number; runId?: number } {\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n return {\n generation: readGeneration(parsed),\n runId: readRunId(parsed),\n };\n}\nfunction readMessageId(data: string): string | undefined {\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n if (!parsed) return undefined;\n const raw =\n parsed.messageId ??\n parsed.message_id ??\n parsed.outputMessageId ??\n parsed.output_message_id ??\n parsed.id;\n if (raw == null) return undefined;\n return String(raw);\n}\n\nfunction readContentField(data: string): string {\n const parsed = tryParseJson(data) as { content?: string } | null;\n if (parsed?.content != null) return String(parsed.content);\n return data.trim();\n}\n\nfunction readErrorFromData(data: string): { message: string; code?: string } {\n const parsed = tryParseJson(data) as { message?: string; code?: string } | null;\n return {\n message: parsed?.message?.trim() || data.trim() || 'Stream failed',\n code: typeof parsed?.code === 'string' ? parsed.code : undefined,\n };\n}\n\nconst STREAM_APPEND_MODES = new Set([\n 'delta',\n 'stream',\n 'chunk',\n 'token',\n 'append',\n 'message.delta',\n]);\n\nfunction resolveStreamTextMode(modeRaw: string | undefined): 'replace' | 'append' {\n if (!modeRaw) return 'append';\n if (modeRaw === 'full' || modeRaw === 'replace') return 'replace';\n if (STREAM_APPEND_MODES.has(modeRaw)) return 'append';\n return 'append';\n}\n\nfunction parseThinkEnvelope(data: string): ChatSseUiAction {\n const messageId = readMessageId(data);\n const runMeta = readSseRunMeta(data);\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n if (parsed && typeof parsed === 'object') {\n const text =\n typeof parsed.content === 'string'\n ? parsed.content\n : typeof parsed.text === 'string'\n ? parsed.text\n : '';\n if (!text) return { type: 'noop' };\n const mode = resolveStreamTextMode(\n typeof parsed.mode === 'string' ? parsed.mode : undefined,\n );\n return { type: 'think', text, mode, messageId, ...runMeta };\n }\n const plain = readContentField(data);\n return plain\n ? { type: 'think', text: plain, mode: 'append', messageId, ...runMeta }\n : { type: 'noop' };\n}\n\nfunction readResultChunkText(record: Record<string, unknown>): string {\n const blocks = record.blocks;\n if (Array.isArray(blocks) && blocks.length > 0) {\n const text = blocks\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const content = (block as { content?: unknown }).content;\n return typeof content === 'string' ? content : '';\n })\n .join('');\n if (text) return text;\n }\n\n for (const key of ['output', 'content', 'text', 'delta', 'token'] as const) {\n const value = record[key];\n if (typeof value === 'string' && value.length > 0) return value;\n }\n return '';\n}\n\nfunction parseResultEnvelope(data: string): ChatSseUiAction {\n const messageId = readMessageId(data);\n const runMeta = readSseRunMeta(data);\n const outer = tryParseJson(data) as { content?: string } | null;\n const innerRaw = outer?.content ?? data;\n const inner = typeof innerRaw === 'string' ? tryParseJson(innerRaw) : innerRaw;\n\n if (inner && typeof inner === 'object') {\n const record = inner as Record<string, unknown>;\n const source = typeof record.source === 'string' ? record.source : undefined;\n const action = typeof record.action === 'string' ? record.action : undefined;\n const streamMode =\n typeof (record.stream as { mode?: unknown } | undefined)?.mode === 'string'\n ? String((record.stream as { mode?: unknown }).mode)\n : undefined;\n const chunkText = readResultChunkText(record);\n const shouldAppend =\n (action ? STREAM_APPEND_MODES.has(action) : false) ||\n (streamMode ? STREAM_APPEND_MODES.has(streamMode) : false);\n\n if (source === 'agent-run') {\n if (action === 'final') {\n if (!chunkText.trim()) return { type: 'noop' };\n return { type: 'result', text: chunkText, mode: 'replace', messageId, ...runMeta };\n }\n if (shouldAppend) {\n if (!chunkText) return { type: 'noop' };\n return { type: 'result', text: chunkText, mode: 'append', messageId, ...runMeta };\n }\n if (chunkText) {\n return { type: 'result', text: chunkText, mode: 'append', messageId, ...runMeta };\n }\n }\n\n if ((source === 'message' || nameLooksLikeMessage(record)) && chunkText) {\n return { type: 'result', text: chunkText, mode: 'append', messageId };\n }\n\n if (chunkText) {\n return {\n type: 'result',\n text: chunkText,\n mode: shouldAppend ? 'append' : 'append',\n messageId,\n };\n }\n }\n\n const plain = readContentField(data);\n if (plain) {\n return { type: 'result', text: plain, mode: 'append', messageId };\n }\n\n return { type: 'noop' };\n}\n\nfunction parseHostActionEnvelope(data: string): ChatSseUiAction {\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n if (!parsed || !isHostActionEnvelope(parsed)) return { type: 'noop' };\n const ssePayload = parseHostActionSsePayload(parsed);\n if (!ssePayload) return { type: 'noop' };\n const action = normalizeHostAction(parsed) ?? undefined;\n const runMeta = readHostActionRunMeta(parsed, ssePayload);\n return {\n type: 'host-action',\n action,\n ssePayload,\n generation: runMeta.generation,\n runId: runMeta.runId,\n };\n}\n\nfunction parseWriteConfirmationEnvelope(\n parsed: Record<string, unknown>,\n): ChatSseUiAction | null {\n const action = typeof parsed.action === 'string' ? parsed.action : undefined;\n const message =\n typeof parsed.message === 'string' ? parsed.message.trim() : '';\n const code = typeof parsed.code === 'string' ? parsed.code : undefined;\n const runId = typeof parsed.runId === 'number' ? parsed.runId : undefined;\n const turnId = typeof parsed.turnId === 'number' ? parsed.turnId : undefined;\n const generation = readGeneration(parsed);\n const draftRetryCount =\n typeof parsed.draftRetryCount === 'number' ? parsed.draftRetryCount : undefined;\n const draftRetryMax =\n typeof parsed.draftRetryMax === 'number' ? parsed.draftRetryMax : undefined;\n const canRetry = typeof parsed.canRetry === 'boolean' ? parsed.canRetry : undefined;\n const writeDraft = parseWriteDraftPublic(parsed.writeDraft) ?? undefined;\n const editPolicy = parseEditPolicyPublic(parsed.editPolicy) ?? undefined;\n const bundles = parseDraftReviewBundles({\n writeDraft,\n writeDrafts: parsed.writeDrafts,\n editPolicy,\n editPolicies: parsed.editPolicies,\n });\n\n if (action === 'confirmation_required' && runId != null && message) {\n const primary = bundles[0]?.writeDraft;\n const provenance = primary?.provenance;\n return {\n type: 'write-confirmation-required',\n runId,\n turnId,\n message,\n code,\n generation,\n draftRetryCount: draftRetryCount ?? provenance?.draftRetryCount,\n draftRetryMax: draftRetryMax ?? provenance?.draftRetryMax,\n canRetry: canRetry ?? provenance?.canRetry,\n writeDraft: primary,\n writeDrafts: bundles.length > 1 ? bundles.map((bundle) => bundle.writeDraft) : undefined,\n editPolicy: bundles[0]?.editPolicy ?? undefined,\n editPolicies:\n bundles.length > 1 ? bundles.map((bundle) => bundle.editPolicy) : undefined,\n };\n }\n if (action === 'write_confirmation_cancelled' && message) {\n return {\n type: 'write-confirmation-cancelled',\n runId,\n turnId,\n message,\n code,\n generation,\n };\n }\n return null;\n}\n\nfunction parseMessageBlocksEnvelope(data: string): ChatSseUiAction {\n const messageId = readMessageId(data);\n const parsed = tryParseJson(data) as Record<string, unknown> | null;\n if (!parsed) return parseResultEnvelope(data);\n if (parsed.source === 'message') return { type: 'noop' };\n\n if (isHostActionEnvelope(parsed)) {\n const ssePayload = parseHostActionSsePayload(parsed);\n if (!ssePayload) return { type: 'noop' };\n const hostAction = normalizeHostAction(parsed) ?? undefined;\n const runMeta = readHostActionRunMeta(parsed, ssePayload);\n return {\n type: 'host-action',\n action: hostAction,\n ssePayload,\n generation: runMeta.generation,\n runId: runMeta.runId,\n };\n }\n\n const writeAction = parseWriteConfirmationEnvelope(parsed);\n if (writeAction) return writeAction;\n\n const actionRaw = parsed.action;\n const action = actionRaw === 'patch' ? 'patch' : actionRaw === 'stream' ? 'stream' : undefined;\n if (!action) return parseResultEnvelope(data);\n\n const runId = typeof parsed.runId === 'number' ? parsed.runId : undefined;\n const turnId = typeof parsed.turnId === 'number' ? parsed.turnId : undefined;\n const generation = readGeneration(parsed);\n const stream = (parsed.stream as Record<string, unknown> | undefined) ?? undefined;\n const modeRaw = stream?.mode;\n const streamMode = modeRaw === 'delta' || modeRaw === 'full' || modeRaw === 'patch' ? modeRaw : undefined;\n const seq = typeof stream?.seq === 'number' ? stream.seq : undefined;\n const blocks = Array.isArray(parsed.blocks)\n ? parsed.blocks.filter(\n (item): item is SseMessageBlock =>\n !!item && typeof item === 'object' && typeof (item as { type?: unknown }).type === 'string',\n )\n : undefined;\n const patches = Array.isArray(parsed.patches)\n ? parsed.patches\n .map((item) => {\n if (!item || typeof item !== 'object') return null;\n const row = item as { replaceId?: unknown; block?: unknown };\n if (typeof row.replaceId !== 'string') return null;\n if (!row.block || typeof row.block !== 'object') return null;\n const block = row.block as { type?: unknown };\n if (typeof block.type !== 'string') return null;\n return { replaceId: row.replaceId, block: row.block as SseMessageBlock };\n })\n .filter((item): item is SseMessageBlockPatch => item != null)\n : undefined;\n\n return {\n type: 'message-blocks',\n action,\n runId,\n turnId,\n generation,\n streamMode,\n seq,\n blocks,\n patches,\n messageId,\n };\n}\n\nfunction nameLooksLikeMessage(record: Record<string, unknown>): boolean {\n const kind = record.type;\n if (typeof kind !== 'string') return false;\n return kind === 'message' || kind === 'result';\n}\n\n/** Map a raw SSE chunk to a UI action. */\nexport function parseChatSseEvent(event: string, data: string): ChatSseUiAction {\n const name = event.trim() || 'message';\n const messageId = readMessageId(data);\n\n switch (name) {\n case 'think':\n return parseThinkEnvelope(data);\n case 'message':\n case 'result': {\n const parsed = name === 'message' ? parseMessageBlocksEnvelope(data) : parseResultEnvelope(data);\n if (parsed.type === 'result' && !parsed.messageId && messageId) {\n return { ...parsed, messageId };\n }\n return parsed;\n }\n case 'message.delta': {\n const text = readContentField(data);\n return text ? { type: 'result', text, mode: 'append', messageId } : { type: 'noop' };\n }\n case 'complete': {\n const envelope = tryParseJson(data) as Record<string, unknown> | null;\n const parsed = envelope as ServerMessagePayload | null;\n const status = typeof envelope?.status === 'string' ? envelope.status : undefined;\n const reason = typeof envelope?.reason === 'string' ? envelope.reason : undefined;\n const generation = readGeneration(envelope);\n const runId = readRunId(envelope);\n if (parsed && (parsed.content != null || parsed.id != null || parsed.role != null)) {\n return {\n type: 'complete',\n serverMessage: parsed,\n messageId: parsed.id != null ? String(parsed.id) : messageId,\n status,\n reason,\n generation,\n runId,\n };\n }\n return { type: 'complete', messageId, status, reason, generation, runId };\n }\n case 'host_action':\n case 'host-action':\n return parseHostActionEnvelope(data);\n case 'error': {\n const err = readErrorFromData(data);\n const runMeta = readSseRunMeta(data);\n return { type: 'error', message: err.message, code: err.code, ...runMeta };\n }\n case 'message.done': {\n const parsed = tryParseJson(data) as ServerMessagePayload | null;\n return {\n type: 'complete',\n serverMessage: parsed ?? undefined,\n messageId: parsed?.id != null ? String(parsed.id) : messageId,\n };\n }\n default:\n return { type: 'noop' };\n }\n}\n","import type { AgentChatHostAction, HostToolHandler } from '../../types';\nimport type { HostToolStreamConfig } from './stream/host-tool-stream.types';\n\ntype ToolEntry = {\n handler: HostToolHandler;\n invokeOnAppend?: boolean;\n onPreview?: HostToolHandler;\n};\n\nconst toolRegistry = new Map<string, Map<string, ToolEntry>>();\nconst declaredTools = new Map<string, Set<string>>();\n\nfunction registryScope(scope: string): string {\n const trimmed = scope.trim();\n return trimmed || '*';\n}\n\nfunction registryName(name: string): string {\n const trimmed = name.trim();\n if (!trimmed) {\n throw new Error('registerHostTool: name is required');\n }\n return trimmed;\n}\n\nfunction resolveEntry(scope: string, name: string): ToolEntry | undefined {\n const toolName = registryName(name);\n const scopeKey = registryScope(scope);\n return (\n toolRegistry.get(scopeKey)?.get(toolName) ??\n toolRegistry.get('*')?.get(toolName)\n );\n}\n\nexport type RegisterHostToolMeta = {\n invokeOnAppend?: boolean;\n onPreview?: HostToolHandler;\n};\n\n/**\n * Register a local host-tool handler for a scope (use `*` for app-wide generic tools).\n */\nexport function registerHostTool(\n scope: string,\n name: string,\n handler: HostToolHandler,\n meta?: RegisterHostToolMeta,\n): void {\n const scopeKey = registryScope(scope);\n const toolName = registryName(name);\n let bucket = toolRegistry.get(scopeKey);\n if (!bucket) {\n bucket = new Map();\n toolRegistry.set(scopeKey, bucket);\n }\n bucket.set(toolName, {\n handler,\n ...(meta?.invokeOnAppend !== undefined ? { invokeOnAppend: meta.invokeOnAppend } : {}),\n ...(meta?.onPreview ? { onPreview: meta.onPreview } : {}),\n });\n}\n\n/** Remove a page-scoped handler (call on component unmount). */\nexport function unregisterHostTool(scope: string, name: string): void {\n const toolName = name.trim();\n if (!toolName) return;\n const bucket = toolRegistry.get(registryScope(scope));\n bucket?.delete(toolName);\n if (bucket && bucket.size === 0) {\n toolRegistry.delete(registryScope(scope));\n }\n}\n\nexport function unregisterHostTools(scope: string, names: string[]): void {\n for (const name of names) {\n unregisterHostTool(scope, name);\n }\n}\n\nexport function getHostToolStreamConfig(\n scope: string,\n name: string,\n): HostToolStreamConfig | undefined {\n const entry = resolveEntry(scope, name);\n if (!entry) return undefined;\n return {\n invokeOnAppend: entry.invokeOnAppend === true,\n };\n}\n\n/**\n * Run a registered host tool. Falls back from page scope to `*`. Returns false when not found.\n */\nexport async function runHostTool(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n): Promise<boolean> {\n const entry = resolveEntry(scope, name);\n if (!entry) return false;\n await entry.handler(args);\n return true;\n}\n\n/** Streaming preview callback (`invokeOnAppend: false`). */\nexport async function runHostToolPreview(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n): Promise<boolean> {\n const entry = resolveEntry(scope, name);\n if (!entry?.onPreview) return false;\n await entry.onPreview(args);\n return true;\n}\n\n/** Execute every `hostTools` entry from a host action. */\nexport async function executeHostToolsFromAction(\n action: AgentChatHostAction,\n): Promise<void> {\n if (action.action !== 'host_action') return;\n const tools = action.hostTools;\n if (!tools.length) return;\n\n const scope = registryScope(action.scope ?? '*');\n for (const tool of tools) {\n const ran = await runHostTool(scope, tool.name, tool.args);\n if (!ran && typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(\n '[agent-chat] hostTool not registered:',\n tool.name,\n '(scope:',\n scope,\n ')',\n );\n }\n }\n}\n\n/**\n * Declare host-tool metadata without a local handler (e.g. app-root sync-only tools).\n * Page scopes may still register handlers via {@link registerHostTool}.\n */\nexport function declareHostTool(scope: string, name: string): void {\n const scopeKey = registryScope(scope);\n const toolName = registryName(name);\n let bucket = declaredTools.get(scopeKey);\n if (!bucket) {\n bucket = new Set();\n declaredTools.set(scopeKey, bucket);\n }\n bucket.add(toolName);\n}\n\n/** Remove a metadata-only declaration (e.g. app-root tool on unmount). */\nexport function undeclareHostTool(scope: string, name: string): void {\n const toolName = name.trim();\n if (!toolName) return;\n const bucket = declaredTools.get(registryScope(scope));\n bucket?.delete(toolName);\n if (bucket && bucket.size === 0) {\n declaredTools.delete(registryScope(scope));\n }\n}\n\nexport function undeclareHostTools(scope: string, names: string[]): void {\n for (const name of names) {\n undeclareHostTool(scope, name);\n }\n}\n\n/** Test helper — clears all registered host tools. */\nexport function clearHostTools(): void {\n toolRegistry.clear();\n declaredTools.clear();\n}\n\n/** Whether `name` is registered under the exact scope bucket (no fallback to `*`). */\nexport function isHostToolRegisteredInScope(scope: string, name: string): boolean {\n const toolName = name.trim();\n if (!toolName) return false;\n return toolRegistry.get(registryScope(scope))?.has(toolName) ?? false;\n}\n\n/** Whether `name` is registered in the app-wide `*` scope. */\nexport function isHostToolRegisteredGlobally(name: string): boolean {\n return isHostToolRegisteredInScope('*', name);\n}\n\n/** Whether `name` was declared (metadata-only) under the exact scope bucket. */\nexport function isHostToolDeclaredInScope(scope: string, name: string): boolean {\n const toolName = name.trim();\n if (!toolName) return false;\n return declaredTools.get(registryScope(scope))?.has(toolName) ?? false;\n}\n\n/** Whether `name` was declared in the app-wide `*` scope. */\nexport function isHostToolDeclaredGlobally(name: string): boolean {\n return isHostToolDeclaredInScope('*', name);\n}\n\n/** Registered or metadata-only declaration in app-wide `*` scope. */\nexport function isHostToolKnownGlobally(name: string): boolean {\n return isHostToolRegisteredGlobally(name) || isHostToolDeclaredGlobally(name);\n}\n","import type { AgentChatHostAction } from '../../types';\nimport {\n isHostToolRegisteredGlobally,\n isHostToolRegisteredInScope,\n} from './host-tool-registry';\n\nexport type HostActionHandler = (action: AgentChatHostAction) => void | Promise<void>;\n\nconst scopedHandlers = new Map<string, Set<HostActionHandler>>();\nconst globalHandlers = new Set<HostActionHandler>();\n\nfunction addHandler(bucket: Set<HostActionHandler>, handler: HostActionHandler): () => void {\n bucket.add(handler);\n return () => {\n bucket.delete(handler);\n };\n}\n\n/**\n * Register a host-page handler for a business scope (usually `pageContext.page`).\n * Returns an unsubscribe function — call on component unmount.\n */\nexport function registerHostAction(scope: string, handler: HostActionHandler): () => void;\n/** Register a global handler (runs for every host action, after scoped handlers). */\nexport function registerHostAction(handler: HostActionHandler): () => void;\nexport function registerHostAction(\n scopeOrHandler: string | HostActionHandler,\n handler?: HostActionHandler,\n): () => void {\n if (typeof scopeOrHandler === 'function') {\n return addHandler(globalHandlers, scopeOrHandler);\n }\n if (!handler) {\n throw new Error('registerHostAction(scope, handler): handler is required');\n }\n const scope = scopeOrHandler.trim();\n if (!scope) {\n throw new Error('registerHostAction(scope, handler): scope is required');\n }\n let bucket = scopedHandlers.get(scope);\n if (!bucket) {\n bucket = new Set();\n scopedHandlers.set(scope, bucket);\n }\n const off = addHandler(bucket, handler);\n return () => {\n off();\n const current = scopedHandlers.get(scope);\n if (current && current.size === 0) {\n scopedHandlers.delete(scope);\n }\n };\n}\n\n/**\n * Dispatch a host action to registered page handlers.\n * Scoped handlers run when `action.scope` matches; global handlers always run.\n */\nexport async function dispatchHostAction(action: AgentChatHostAction): Promise<void> {\n if (action.action !== 'host_action') return;\n if (action.streamPhase === 'streaming') return;\n if (!action.hostTools.length) return;\n\n const scope = action.scope?.trim();\n if (!scope) return;\n\n const tasks: Array<void | Promise<void>> = [];\n\n const bucket = scopedHandlers.get(scope);\n if (bucket?.size) {\n for (const handler of bucket) {\n tasks.push(handler(action));\n }\n } else {\n const hasLocalToolHandlers = action.hostTools.some(\n (tool) =>\n isHostToolRegisteredInScope(scope, tool.name) ||\n isHostToolRegisteredGlobally(tool.name),\n );\n if (\n !hasLocalToolHandlers &&\n typeof console !== 'undefined' &&\n typeof console.warn === 'function'\n ) {\n console.warn('[agent-chat] hostAction: no handler registered for scope:', scope);\n }\n }\n\n for (const handler of globalHandlers) {\n tasks.push(handler(action));\n }\n\n await Promise.all(tasks);\n}\n\n/** Alias of {@link registerHostAction} — listen for host actions by scope. */\nexport const onHostAction = registerHostAction;\n\n/** Test helper — clears all registered handlers. */\nexport function clearHostActionHandlers(): void {\n scopedHandlers.clear();\n globalHandlers.clear();\n}\n","/** 点路径写入,如 `payload.body` → nested object */\nexport function setByDotPath(\n root: Record<string, unknown>,\n path: string,\n value: unknown,\n): Record<string, unknown> {\n const segments = path.split('.').filter(Boolean);\n if (segments.length === 0) return root;\n let cursor: Record<string, unknown> = root;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const key = segments[i]!;\n const next = cursor[key];\n if (next == null || typeof next !== 'object' || Array.isArray(next)) {\n cursor[key] = {};\n }\n cursor = cursor[key] as Record<string, unknown>;\n }\n cursor[segments[segments.length - 1]!] = value;\n return root;\n}\n\n/** 点路径字符串追加;路径不存在视为 \"\" */\nexport function appendByDotPath(\n root: Record<string, unknown>,\n path: string,\n chunk: string,\n): Record<string, unknown> {\n const segments = path.split('.').filter(Boolean);\n if (segments.length === 0) return root;\n let cursor: Record<string, unknown> = root;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const key = segments[i]!;\n const next = cursor[key];\n if (next == null || typeof next !== 'object' || Array.isArray(next)) {\n cursor[key] = {};\n }\n cursor = cursor[key] as Record<string, unknown>;\n }\n const leaf = segments[segments.length - 1]!;\n const prev = cursor[leaf];\n const base = typeof prev === 'string' ? prev : '';\n cursor[leaf] = base + chunk;\n return root;\n}\n\nexport function getByDotPath(root: Record<string, unknown>, path: string): unknown {\n const segments = path.split('.').filter(Boolean);\n let current: unknown = root;\n for (const seg of segments) {\n if (current == null || typeof current !== 'object' || Array.isArray(current)) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[seg];\n }\n return current;\n}\n","import type {\n HostActionHostToolInvocation,\n HostActionSsePayload,\n HostActionStreamPayload,\n HostToolDslOp,\n HostToolStreamConfig,\n} from './host-tool-stream.types';\nimport { isHostActionStreamPayload } from './host-tool-stream.types';\nimport { appendByDotPath, setByDotPath } from '../host-tool-path-args';\nimport type { StreamSessionGate } from './host-tool-stream-gate';\n\nexport type CallAccumulator = {\n name: string;\n index: number;\n args: Record<string, unknown>;\n committed: boolean;\n flushed: boolean;\n};\n\nexport type HostToolStreamSession = {\n streamId: string;\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n reason?: string;\n planStepId?: string;\n runId?: number;\n turnId?: number;\n calls: Map<string, CallAccumulator>;\n ended: boolean;\n lastSeq: number;\n};\n\nexport type HostToolStreamReducerState = {\n session: HostToolStreamSession | null;\n authoritative: HostActionHostToolInvocation[] | null;\n /** Last streamId finalized via `stream.mode: full` — dedupe replay full frames. */\n finalizedStreamId: string | null;\n /** Fingerprint of last `full` when `streamId` is absent (SSE replay). */\n finalizedFullFingerprint: string | null;\n};\n\nexport type HostActionSseMeta = {\n scope?: string;\n entity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n reason?: string;\n planStepId?: string;\n runId?: number;\n turnId?: number;\n};\n\nexport type HostToolStreamEffect =\n | { type: 'round-start'; streamId: string; meta: HostActionSseMeta }\n | {\n type: 'tool-start';\n streamId: string;\n callId: string;\n name: string;\n meta: HostActionSseMeta;\n }\n | {\n type: 'preview';\n callId: string;\n name: string;\n args: Record<string, unknown>;\n invokeHandler: boolean;\n meta: HostActionSseMeta;\n }\n | { type: 'session-ended'; streamId: string; meta: HostActionSseMeta }\n | { type: 'batch'; payload: HostActionHostToolInvocation[]; reason?: string; meta: HostActionSseMeta }\n | {\n type: 'reconcile';\n payload: HostActionHostToolInvocation[];\n meta: HostActionSseMeta;\n sessionCalls?: Map<string, CallAccumulator>;\n }\n | { type: 'warn'; message: string };\n\nexport type HostToolStreamReducerOptions = {\n getStreamConfig?: (toolName: string) => HostToolStreamConfig | undefined;\n onEffect?: (effect: HostToolStreamEffect) => void;\n};\n\nexport function createInitialHostToolStreamState(): HostToolStreamReducerState {\n return {\n session: null,\n authoritative: null,\n finalizedStreamId: null,\n finalizedFullFingerprint: null,\n };\n}\n\nfunction computeFullFingerprint(\n payload: HostActionStreamPayload,\n tools: HostActionHostToolInvocation[],\n): string | null {\n if (!tools.length) return null;\n const toolSig = tools\n .map((tool) => `${tool.name}:${JSON.stringify(tool.args)}`)\n .join(';');\n return [\n payload.runId ?? '',\n payload.turnId ?? '',\n payload.planStepId ?? '',\n payload.reason ?? '',\n toolSig,\n ].join('|');\n}\n\nfunction isDuplicateFullFrame(\n state: HostToolStreamReducerState,\n streamId: string | undefined,\n fingerprint: string | null,\n hasActiveSession: boolean,\n): boolean {\n if (hasActiveSession) return false;\n if (streamId && state.finalizedStreamId === streamId) return true;\n if (fingerprint && state.finalizedFullFingerprint === fingerprint) return true;\n return false;\n}\n\nfunction readSseMeta(payload: HostActionSsePayload): HostActionSseMeta {\n return {\n scope: payload.scope,\n entity: payload.entity,\n metadata: payload.metadata,\n reason: payload.reason,\n planStepId: payload.planStepId,\n runId: payload.runId,\n turnId: payload.turnId,\n };\n}\n\nfunction readSessionMeta(session: HostToolStreamSession): HostActionSseMeta {\n return {\n scope: session.scope,\n entity: session.entity,\n metadata: session.metadata,\n reason: session.reason,\n planStepId: session.planStepId,\n runId: session.runId,\n turnId: session.turnId,\n };\n}\n\nfunction ensureCall(\n session: HostToolStreamSession,\n callId: string,\n seed?: Partial<CallAccumulator>,\n): CallAccumulator {\n let call = session.calls.get(callId);\n if (!call) {\n call = {\n name: seed?.name ?? '',\n index: seed?.index ?? session.calls.size,\n args: {},\n committed: false,\n flushed: false,\n };\n session.calls.set(callId, call);\n }\n if (seed?.name) call.name = seed.name;\n if (seed?.index != null) call.index = seed.index;\n return call;\n}\n\nfunction shouldInvokeOnAppend(\n toolName: string,\n opts: HostToolStreamReducerOptions,\n): boolean {\n return opts.getStreamConfig?.(toolName)?.invokeOnAppend === true;\n}\n\nfunction emitPreview(\n session: HostToolStreamSession,\n callId: string,\n opts: HostToolStreamReducerOptions,\n): void {\n const call = session.calls.get(callId);\n if (!call?.name) return;\n opts.onEffect?.({\n type: 'preview',\n callId,\n name: call.name,\n args: { ...call.args },\n invokeHandler: shouldInvokeOnAppend(call.name, opts),\n meta: readSessionMeta(session),\n });\n}\n\nfunction applyDslOp(\n session: HostToolStreamSession,\n dsl: HostToolDslOp,\n opts: HostToolStreamReducerOptions,\n): void {\n switch (dsl.op) {\n case 'session.begin':\n break;\n case 'session.end':\n if (session.streamId === dsl.streamId) {\n session.ended = true;\n opts.onEffect?.({\n type: 'session-ended',\n streamId: session.streamId,\n meta: readSessionMeta(session),\n });\n }\n break;\n case 'tool.begin': {\n if (dsl.streamId !== session.streamId) return;\n ensureCall(session, dsl.callId, { name: dsl.name, index: dsl.index });\n opts.onEffect?.({\n type: 'tool-start',\n streamId: session.streamId,\n callId: dsl.callId,\n name: dsl.name,\n meta: readSessionMeta(session),\n });\n break;\n }\n case 'arg.set': {\n if (dsl.streamId !== session.streamId) return;\n const call = ensureCall(session, dsl.callId);\n setByDotPath(call.args, dsl.path, dsl.value);\n emitPreview(session, dsl.callId, opts);\n break;\n }\n case 'arg.append': {\n if (dsl.streamId !== session.streamId) return;\n const call = ensureCall(session, dsl.callId);\n appendByDotPath(call.args, dsl.path, dsl.chunk);\n emitPreview(session, dsl.callId, opts);\n break;\n }\n case 'tool.commit': {\n if (dsl.streamId !== session.streamId) return;\n const call = ensureCall(session, dsl.callId);\n call.committed = true;\n break;\n }\n case 'tool.flush': {\n if (dsl.streamId !== session.streamId) return;\n const call = ensureCall(session, dsl.callId, {\n name: dsl.name,\n index: session.calls.size,\n });\n call.args = { ...dsl.args };\n call.flushed = true;\n break;\n }\n default:\n break;\n }\n}\n\nfunction readFrameStreamId(dsl?: HostToolDslOp): string | undefined {\n if (!dsl || !('streamId' in dsl)) return undefined;\n const id = dsl.streamId;\n return typeof id === 'string' && id.trim() ? id.trim() : undefined;\n}\n\nfunction isIdempotentSessionEnd(\n stream: HostActionStreamPayload['stream'],\n dsl: HostToolDslOp | undefined,\n session: HostToolStreamSession,\n): boolean {\n return (\n stream.mode === 'end' &&\n dsl?.op === 'session.end' &&\n dsl.streamId === session.streamId\n );\n}\n\nfunction handleStreamPayload(\n state: HostToolStreamReducerState,\n payload: HostActionStreamPayload,\n opts: HostToolStreamReducerOptions,\n): HostToolStreamReducerState {\n const { stream, dsl } = payload;\n const seq = stream.seq;\n\n if (stream.mode === 'begin' && dsl?.op === 'session.begin') {\n if (state.session && !state.session.ended) {\n opts.onEffect?.({\n type: 'warn',\n message: `host_tool stream: session.begin while stream ${state.session.streamId} is still active`,\n });\n }\n const session: HostToolStreamSession = {\n streamId: dsl.streamId,\n scope: dsl.scope ?? payload.scope,\n entity: dsl.entity ?? payload.entity,\n metadata: dsl.metadata ?? payload.metadata,\n reason: dsl.reason ?? payload.reason,\n planStepId: dsl.planStepId ?? payload.planStepId,\n runId: dsl.runId ?? payload.runId,\n turnId: dsl.turnId ?? payload.turnId,\n calls: new Map(),\n ended: false,\n lastSeq: seq,\n };\n opts.onEffect?.({\n type: 'round-start',\n streamId: session.streamId,\n meta: readSessionMeta(session),\n });\n return {\n session,\n authoritative: null,\n finalizedStreamId: null,\n finalizedFullFingerprint: null,\n };\n }\n\n const next: HostToolStreamReducerState = {\n ...state,\n session: state.session ? { ...state.session, calls: new Map(state.session.calls) } : null,\n };\n\n if (stream.mode === 'full') {\n const streamId = next.session?.streamId ?? readFrameStreamId(dsl);\n const tools = payload.hostTools ?? [];\n const fingerprint = computeFullFingerprint(payload, tools);\n if (isDuplicateFullFrame(state, streamId, fingerprint, Boolean(next.session))) {\n return state;\n }\n if (next.session && seq <= next.session.lastSeq) {\n return state;\n }\n const meta = readSseMeta(payload);\n const sessionCalls = next.session?.calls\n ? new Map(next.session.calls)\n : undefined;\n opts.onEffect?.({ type: 'reconcile', payload: tools, meta, sessionCalls });\n return {\n session: null,\n authoritative: tools,\n finalizedStreamId: streamId ?? state.finalizedStreamId,\n finalizedFullFingerprint: fingerprint ?? state.finalizedFullFingerprint,\n };\n }\n\n if (!next.session) {\n opts.onEffect?.({\n type: 'warn',\n message: `host_tool stream delta before session.begin (seq=${seq})`,\n });\n return state;\n }\n\n const frameStreamId = readFrameStreamId(dsl);\n if (frameStreamId && frameStreamId !== next.session.streamId) {\n opts.onEffect?.({\n type: 'warn',\n message: `host_tool stream streamId mismatch (frame=${frameStreamId}, session=${next.session.streamId}, seq=${seq})`,\n });\n return state;\n }\n\n if (seq <= next.session.lastSeq) {\n return state;\n }\n\n if (next.session.ended && !isIdempotentSessionEnd(stream, dsl, next.session)) {\n opts.onEffect?.({\n type: 'warn',\n message: `host_tool stream frame after session.end (mode=${stream.mode}, seq=${seq})`,\n });\n return state;\n }\n\n next.session = { ...next.session, lastSeq: seq };\n\n if (dsl) {\n applyDslOp(next.session, dsl, opts);\n }\n\n return next;\n}\n\n/** 主入口:处理单帧 host_action SSE payload。 */\nexport function reduceHostToolStream(\n state: HostToolStreamReducerState,\n payload: HostActionSsePayload,\n opts: HostToolStreamReducerOptions = {},\n): HostToolStreamReducerState {\n if (!isHostActionStreamPayload(payload)) {\n const batch = payload.hostTools ?? [];\n const meta = readSseMeta(payload);\n opts.onEffect?.({ type: 'batch', payload: batch, reason: payload.reason, meta });\n return {\n session: null,\n authoritative: batch,\n finalizedStreamId: null,\n finalizedFullFingerprint: null,\n };\n }\n\n return handleStreamPayload(state, payload, opts);\n}\n\nexport function toStreamSessionGate(\n session: HostToolStreamSession | null,\n): StreamSessionGate {\n if (!session) return null;\n return {\n streamId: session.streamId,\n scope: session.scope,\n entity: session.entity,\n ended: session.ended,\n };\n}\n","import type { HostActionSsePayload, HostActionStreamPayload } from './host-tool-stream.types';\nimport { isHostActionStreamPayload } from './host-tool-stream.types';\n\nexport type PageContextGate = {\n page?: string;\n entity?: { type?: string; id?: string | number };\n};\n\n/** Snapshot of the in-flight DSL session used for mid-stream / post-end gating. */\nexport type StreamSessionGate = {\n streamId: string;\n scope?: string;\n entity?: Record<string, unknown>;\n ended: boolean;\n} | null;\n\nexport type StreamIngestContext = {\n page: PageContextGate;\n streamSession: StreamSessionGate;\n};\n\nfunction entityIdsMatch(\n payloadId: unknown,\n ctxId: string | number | undefined,\n): boolean {\n if (payloadId == null || ctxId == null) return true;\n return String(payloadId) === String(ctxId);\n}\n\nfunction scopeMatches(payloadScope: string | undefined, page: string | undefined): boolean {\n const scope = payloadScope?.trim();\n const ctxPage = page?.trim();\n if (!scope || !ctxPage) return true;\n return scope === ctxPage;\n}\n\nfunction gateScopeEntity(\n scope: string | undefined,\n entity: Record<string, unknown> | undefined,\n page: PageContextGate,\n): boolean {\n return (\n scopeMatches(scope, page.page) &&\n entityIdsMatch(entity?.id, page.entity?.id)\n );\n}\n\n/**\n * Gate for v0 batch / full frames — requires non-empty hostTools when not mid-stream.\n */\nexport function passesHostActionGate(\n payload: HostActionSsePayload,\n page: PageContextGate,\n): boolean {\n if (payload.action !== 'host_action') return false;\n\n const scope = payload.scope ?? undefined;\n const entity = payload.entity;\n\n if (!gateScopeEntity(scope, entity, page)) return false;\n\n if (\n (!isHostActionStreamPayload(payload) || payload.stream.mode === 'full') &&\n (!payload.hostTools || payload.hostTools.length === 0)\n ) {\n return false;\n }\n\n return true;\n}\n\nfunction resolveFullFrameGate(\n payload: HostActionStreamPayload,\n streamSession: StreamSessionGate,\n page: PageContextGate,\n): boolean {\n const scope = payload.scope ?? streamSession?.scope;\n const entity = payload.entity ?? streamSession?.entity;\n if (!gateScopeEntity(scope, entity, page)) return false;\n return Boolean(payload.hostTools?.length);\n}\n\n/**\n * Whether to ingest a host_action SSE frame.\n * Mid-stream frames may omit top-level scope when a reducer session is active.\n * After `session.end`, only `full` (and idempotent `session.end`) are accepted.\n */\nexport function shouldIngestHostActionStreamFrame(\n payload: HostActionSsePayload,\n ctx: StreamIngestContext,\n): boolean {\n const { page, streamSession } = ctx;\n\n if (!isHostActionStreamPayload(payload)) {\n return passesHostActionGate(payload, page);\n }\n\n const { stream, dsl } = payload;\n\n if (stream.mode === 'full') {\n return resolveFullFrameGate(payload, streamSession, page);\n }\n\n if (stream.mode === 'begin' && dsl?.op === 'session.begin') {\n return gateScopeEntity(\n dsl.scope ?? payload.scope,\n dsl.entity ?? payload.entity,\n page,\n );\n }\n\n if (streamSession) {\n if (streamSession.ended) {\n return stream.mode === 'end' && dsl?.op === 'session.end';\n }\n return true;\n }\n\n return gateScopeEntity(payload.scope, payload.entity, page);\n}\n","/**\n * Tracks which tool calls were already executed in the current DSL stream round.\n * Lifecycle: {@link begin} → mark on invokeOnAppend preview → {@link finalize} at full/v0.\n */\nexport class HostToolStreamRound {\n private executedCallIds = new Set<string>();\n\n begin(): void {\n this.executedCallIds.clear();\n }\n\n has(callId: string): boolean {\n return this.executedCallIds.has(callId);\n }\n\n mark(callId: string): void {\n this.executedCallIds.add(callId);\n }\n\n /**\n * Snapshot executed callIds for async batch finalize, then start a fresh round tracker.\n */\n finalize(): ReadonlySet<string> {\n const snapshot = new Set(this.executedCallIds);\n this.executedCallIds.clear();\n return snapshot;\n }\n\n reset(): void {\n this.executedCallIds.clear();\n }\n}\n","import type { HostActionHostToolInvocation } from './host-tool-stream.types';\nimport type { CallAccumulator } from './host-tool-stream-reducer';\nimport { runHostTool } from '../host-tool-registry';\n\nexport type HostToolInvocation = HostActionHostToolInvocation;\n\nexport type BatchRunPlan = {\n tool: HostToolInvocation;\n callId?: string;\n skip: boolean;\n};\n\nfunction orderedCallEntries(\n sessionCalls: Map<string, CallAccumulator>,\n): Array<[string, CallAccumulator]> {\n return [...sessionCalls.entries()].sort(([, a], [, b]) => a.index - b.index);\n}\n\n/** Align authoritative `hostTools[]` with DSL call order for deduped finalize. */\nexport function planBatchExecution(\n tools: HostToolInvocation[],\n sessionCalls: Map<string, CallAccumulator> | undefined,\n executedCallIds: ReadonlySet<string>,\n): BatchRunPlan[] {\n if (!sessionCalls || sessionCalls.size === 0) {\n return tools.map((tool) => ({ tool, skip: false }));\n }\n\n const ordered = orderedCallEntries(sessionCalls);\n const plans: BatchRunPlan[] = [];\n\n for (let i = 0; i < tools.length; i += 1) {\n const tool = tools[i]!;\n const entry = ordered[i];\n if (!entry) {\n plans.push({ tool, skip: false });\n continue;\n }\n const [callId] = entry;\n plans.push({\n tool,\n callId,\n skip: executedCallIds.has(callId),\n });\n }\n\n return plans;\n}\n\nfunction shallowEqualArgs(\n a: Record<string, unknown>,\n b: Record<string, unknown>,\n): boolean {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (JSON.stringify(a[key]) !== JSON.stringify(b[key])) return false;\n }\n return true;\n}\n\n/** Debug helper — compare DSL accumulator vs authoritative full snapshot. */\nexport function warnAccumulatorMismatch(\n tools: HostToolInvocation[],\n sessionCalls: Map<string, CallAccumulator> | undefined,\n debug?: boolean,\n): void {\n if (!debug || !sessionCalls?.size || typeof console === 'undefined') return;\n\n const ordered = orderedCallEntries(sessionCalls);\n if (tools.length !== ordered.length) {\n console.warn(\n '[agent-chat] host_tool stream: full hostTools length',\n tools.length,\n '≠ DSL calls',\n ordered.length,\n );\n return;\n }\n\n for (let i = 0; i < tools.length; i += 1) {\n const tool = tools[i]!;\n const [, call] = ordered[i]!;\n if (tool.name !== call.name) {\n console.warn(\n '[agent-chat] host_tool stream: full tool name mismatch at index',\n i,\n `full=${tool.name}`,\n `dsl=${call.name}`,\n );\n continue;\n }\n if (!shallowEqualArgs(tool.args, call.args)) {\n console.warn(\n '[agent-chat] host_tool stream: full args differ from DSL accumulator at index',\n i,\n 'tool=',\n tool.name,\n );\n }\n }\n}\n\nexport async function executeBatchPlan(\n scope: string,\n plans: BatchRunPlan[],\n debug?: boolean,\n): Promise<void> {\n for (const plan of plans) {\n if (plan.skip) continue;\n try {\n const ran = await runHostTool(scope, plan.tool.name, plan.tool.args);\n if (!ran && debug && typeof console !== 'undefined') {\n console.warn(\n '[agent-chat] hostTool not registered:',\n plan.tool.name,\n '(scope:',\n scope,\n ')',\n );\n }\n } catch (err) {\n if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool execution failed:', plan.tool.name, err);\n }\n }\n }\n}\n","import type {\n AgentChatHostAction,\n PageAgentLifecyclePayload,\n PageAgentSource,\n PageAgentCompleteContext,\n PageAgentStartContext,\n PageAgentStreamContext,\n} from '../../../types';\nimport type { HostActionSsePayload } from './host-tool-stream.types';\nimport { isHostActionStreamPayload } from './host-tool-stream.types';\nimport {\n createInitialHostToolStreamState,\n reduceHostToolStream,\n toStreamSessionGate,\n type HostActionSseMeta,\n type HostToolStreamEffect,\n type HostToolStreamReducerState,\n} from './host-tool-stream-reducer';\nimport {\n shouldIngestHostActionStreamFrame,\n type PageContextGate,\n} from './host-tool-stream-gate';\nimport { getHostToolStreamConfig, runHostTool, runHostToolPreview } from '../host-tool-registry';\nimport { HostToolStreamRound } from './host-tool-stream-round';\nimport {\n executeBatchPlan,\n planBatchExecution,\n warnAccumulatorMismatch,\n type HostToolInvocation,\n} from './host-tool-stream-reconcile';\n\nexport type HostToolStreamManagerOptions = {\n pageContext: PageContextGate;\n sessionId?: string;\n debug?: boolean;\n};\n\nexport type HostToolStreamHooks = {\n source: PageAgentSource;\n emitLifecycle: (payload: PageAgentLifecyclePayload) => void;\n emitHostAction: (\n action: AgentChatHostAction,\n phase: 'streaming' | 'complete',\n options?: { skipToolExecution?: boolean },\n ) => void;\n};\n\nasync function runHostToolSafe(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n debug?: boolean,\n): Promise<void> {\n try {\n const ran = await runHostTool(scope, name, args);\n if (!ran && debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool not registered:', name, '(scope:', scope, ')');\n }\n } catch (err) {\n if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool execution failed:', name, err);\n }\n }\n}\n\n/**\n * Per-session Host Tool DSL v1: reducer state + round-scoped execution.\n */\nexport class HostToolStreamManager {\n private state: HostToolStreamReducerState = createInitialHostToolStreamState();\n private readonly round = new HostToolStreamRound();\n private options: HostToolStreamManagerOptions;\n\n constructor(options: HostToolStreamManagerOptions) {\n this.options = options;\n }\n\n updateOptions(patch: Partial<HostToolStreamManagerOptions>): void {\n this.options = { ...this.options, ...patch };\n }\n\n reset(): void {\n this.state = createInitialHostToolStreamState();\n this.round.reset();\n }\n\n getReducerState(): HostToolStreamReducerState {\n return this.state;\n }\n\n ingest(payload: HostActionSsePayload, hooks: HostToolStreamHooks): void {\n const streamSession = toStreamSessionGate(this.state.session);\n if (\n !shouldIngestHostActionStreamFrame(payload, {\n page: this.options.pageContext,\n streamSession,\n })\n ) {\n return;\n }\n\n const scope = this.resolveScope(payload);\n\n this.state = reduceHostToolStream(this.state, payload, {\n getStreamConfig: (name) => getHostToolStreamConfig(scope, name),\n onEffect: (effect) => {\n this.dispatchEffect(effect, scope, hooks);\n },\n });\n }\n\n private resolveScope(payload: HostActionSsePayload): string {\n return (\n payload.scope?.trim() ??\n this.state.session?.scope?.trim() ??\n this.options.pageContext.page?.trim() ??\n '*'\n );\n }\n\n private dispatchEffect(\n effect: HostToolStreamEffect,\n scope: string,\n hooks: HostToolStreamHooks,\n ): void {\n const debug = this.options.debug;\n\n switch (effect.type) {\n case 'round-start':\n this.round.begin();\n this.emitLifecycleStart(hooks, scope, effect.streamId, effect.meta);\n break;\n\n case 'tool-start':\n this.emitLifecycleStart(\n hooks,\n scope,\n effect.streamId,\n effect.meta,\n effect.name,\n effect.callId,\n );\n break;\n\n case 'preview':\n this.emitLifecycleStream(hooks, scope, effect.meta, {\n streamId: this.state.session?.streamId ?? '',\n callId: effect.callId,\n name: effect.name,\n args: effect.args,\n });\n if (effect.invokeHandler) {\n this.round.mark(effect.callId);\n void runHostToolSafe(scope, effect.name, effect.args, debug);\n } else {\n void this.runStreamingPreview(scope, effect, debug);\n }\n break;\n\n case 'session-ended':\n if (debug && typeof console !== 'undefined') {\n console.debug(\n '[agent-chat] host_tool stream: session.end — awaiting stream.full',\n effect.streamId,\n );\n }\n break;\n\n case 'batch':\n this.finalizeBatch(hooks, scope, effect.payload, effect.meta, undefined, debug);\n break;\n\n case 'reconcile':\n warnAccumulatorMismatch(effect.payload, effect.sessionCalls, debug);\n this.finalizeBatch(\n hooks,\n scope,\n effect.payload,\n effect.meta,\n effect.sessionCalls,\n debug,\n );\n break;\n\n case 'warn':\n if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] host_tool stream:', effect.message);\n }\n break;\n\n default:\n break;\n }\n }\n\n private async runStreamingPreview(\n scope: string,\n effect: Extract<HostToolStreamEffect, { type: 'preview' }>,\n debug?: boolean,\n ): Promise<void> {\n try {\n const previewRan = await runHostToolPreview(scope, effect.name, effect.args);\n if (previewRan) return;\n\n const handlerRan = await runHostTool(scope, effect.name, effect.args);\n if (handlerRan) {\n this.round.mark(effect.callId);\n } else if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool not registered:', effect.name, '(scope:', scope, ')');\n }\n } catch (err) {\n if (debug && typeof console !== 'undefined') {\n console.warn('[agent-chat] hostTool streaming preview failed:', effect.name, err);\n }\n }\n }\n\n private finalizeBatch(\n hooks: HostToolStreamHooks,\n scope: string,\n tools: HostToolInvocation[],\n meta: HostActionSseMeta,\n sessionCalls: Map<string, import('./host-tool-stream-reducer').CallAccumulator> | undefined,\n debug?: boolean,\n ): void {\n const action = this.buildCompleteAction(meta, scope, tools);\n if (!action) return;\n\n const executedSnapshot = this.round.finalize();\n const plans = planBatchExecution(tools, sessionCalls, executedSnapshot);\n\n this.emitLifecycleComplete(hooks, scope, meta, tools, action);\n hooks.emitHostAction(action, 'complete', { skipToolExecution: true });\n void executeBatchPlan(scope, plans, debug);\n }\n\n private emitLifecycleStart(\n hooks: HostToolStreamHooks,\n scope: string,\n streamId: string,\n meta: HostActionSseMeta,\n toolName?: string,\n callId?: string,\n ): void {\n const resolvedScope = meta.scope?.trim() ?? scope;\n if (!resolvedScope || !streamId) return;\n hooks.emitLifecycle({\n type: 'start',\n context: {\n streamId,\n scope: resolvedScope,\n source: hooks.source,\n toolName,\n callId,\n entity: meta.entity as PageAgentStartContext['entity'],\n reason: meta.reason,\n runId: meta.runId,\n turnId: meta.turnId,\n },\n });\n }\n\n private emitLifecycleStream(\n hooks: HostToolStreamHooks,\n scope: string,\n meta: HostActionSseMeta,\n preview: { streamId: string; callId: string; name: string; args: Record<string, unknown> },\n ): void {\n const resolvedScope = meta.scope?.trim() ?? scope;\n if (!resolvedScope || !preview.streamId || !preview.callId || !preview.name) return;\n hooks.emitLifecycle({\n type: 'stream',\n context: {\n streamId: preview.streamId,\n scope: resolvedScope,\n source: hooks.source,\n callId: preview.callId,\n toolName: preview.name,\n args: preview.args,\n entity: meta.entity as PageAgentStreamContext['entity'],\n reason: meta.reason,\n },\n });\n }\n\n private emitLifecycleComplete(\n hooks: HostToolStreamHooks,\n scope: string,\n meta: HostActionSseMeta,\n hostTools: HostToolInvocation[],\n action: AgentChatHostAction,\n ): void {\n const resolvedScope = meta.scope?.trim() ?? scope;\n if (!resolvedScope) return;\n hooks.emitLifecycle({\n type: 'complete',\n context: {\n streamId: this.state.finalizedStreamId ?? this.state.session?.streamId,\n scope: resolvedScope,\n source: hooks.source,\n hostTools,\n action,\n entity: meta.entity as PageAgentCompleteContext['entity'],\n reason: meta.reason ?? action.reason,\n },\n });\n }\n\n private buildCompleteAction(\n meta: HostActionSseMeta,\n scope: string,\n hostTools: HostToolInvocation[],\n ): AgentChatHostAction | null {\n const resolvedScope = meta.scope?.trim() ?? scope;\n if (!resolvedScope || hostTools.length === 0) return null;\n return {\n action: 'host_action',\n scope: resolvedScope,\n entity: meta.entity as AgentChatHostAction['entity'],\n metadata: meta.metadata,\n hostTools,\n reason: meta.reason,\n planStepId: meta.planStepId,\n runId: meta.runId,\n turnId: meta.turnId,\n sessionId: this.options.sessionId,\n streamPhase: 'complete',\n };\n }\n}\n\nexport function isHostToolStreamEnabled(\n option: boolean | undefined,\n payload: HostActionSsePayload,\n): boolean {\n if (option === false) {\n return (\n !isHostActionStreamPayload(payload) || payload.stream.mode === 'full'\n );\n }\n return true;\n}\n","import type { AgentChatClient } from '../client/instance';\nimport {\n declareHostTool,\n isHostToolDeclaredInScope,\n isHostToolRegisteredInScope,\n registerHostTool,\n} from './host-tool-registry';\nimport type {\n AppHostToolDefinition,\n HostToolDefinition,\n RegisterHostToolsOptions,\n} from '../../types';\n\nconst serverSyncedKeys = new Set<string>();\nconst pendingSyncByClientId = new Map<string, RegisterHostToolsOptions[]>();\n\nfunction syncKey(appClientId: number, name: string): string {\n return `${appClientId}:${name}`;\n}\n\nfunction resolveToolScope(\n scope: string | undefined,\n generic: boolean | undefined,\n): string {\n if (generic) return '*';\n return scope?.trim() || '*';\n}\n\nfunction toServerToolMeta(\n tool: HostToolDefinition | AppHostToolDefinition,\n appLevel: boolean,\n): Omit<HostToolDefinition, 'handler'> {\n const {\n name,\n description,\n argsSchema,\n argsTemplate,\n definitionKey,\n } = tool;\n const generic =\n appLevel ? true : 'generic' in tool && tool.generic !== undefined ? tool.generic : undefined;\n return {\n name,\n description,\n argsSchema,\n ...(generic !== undefined ? { generic } : {}),\n ...(argsTemplate !== undefined ? { argsTemplate } : {}),\n ...(definitionKey !== undefined ? { definitionKey } : {}),\n };\n}\n\nfunction queuePendingHostToolSync(\n clientId: string,\n options: RegisterHostToolsOptions,\n): void {\n const bucket = pendingSyncByClientId.get(clientId) ?? [];\n bucket.push(options);\n pendingSyncByClientId.set(clientId, bucket);\n}\n\nasync function syncHostToolMetadataToServer(\n chat: AgentChatClient,\n options: RegisterHostToolsOptions,\n): Promise<number> {\n const { scope, tools, appLevel = false } = options;\n const appClientId = chat.getAppClientId();\n if (appClientId == null) return 0;\n\n const toSync = tools.filter(\n (tool) => !serverSyncedKeys.has(syncKey(appClientId, tool.name)),\n );\n if (toSync.length === 0) return 0;\n\n const res = await chat.syncHostToolsToServer({\n scope: appLevel ? '*' : scope,\n pageLabel: options.pageLabel,\n routePattern: options.routePattern,\n tools: toSync.map((tool) => toServerToolMeta(tool, appLevel)),\n });\n\n for (const item of [...res.created, ...res.skipped]) {\n if (item.name) {\n serverSyncedKeys.add(syncKey(appClientId, item.name));\n }\n }\n\n return toSync.length;\n}\n\n/**\n * Retry host-tool metadata sync queued before auth was ready.\n * Called automatically after `init` (when already logged in) and `login`.\n */\nexport async function flushPendingHostToolSyncs(\n chat: AgentChatClient,\n): Promise<void> {\n if (!chat.isHostToolServerSyncReady()) return;\n\n const pending = pendingSyncByClientId.get(chat.id);\n if (!pending?.length) return;\n\n pendingSyncByClientId.delete(chat.id);\n for (const options of pending) {\n await syncHostToolMetadataToServer(chat, options);\n }\n}\n\n/**\n * Register host tools locally and optionally sync metadata to the server (idempotent per tool name).\n * Server sync requires app-client auth + logged-in user (`Authorization: Bearer`); otherwise\n * the sync is queued until {@link flushPendingHostToolSyncs}.\n *\n * @example\n * ```ts\n * await registerHostToolsWithSync(chat, {\n * scope: 'review-detail',\n * tools: [{ name: 'fillReplyDraft', description: '...', argsSchema: {}, handler: () => {} }],\n * });\n * ```\n */\nexport async function registerHostToolsWithSync(\n chat: AgentChatClient,\n options: RegisterHostToolsOptions,\n): Promise<void> {\n const { scope, tools, syncToServer = true, appLevel = false } = options;\n\n let localRegistrationChanged = false;\n\n for (const tool of tools) {\n const toolScope = appLevel ? '*' : resolveToolScope(scope, 'generic' in tool ? tool.generic : undefined);\n const hadLocal =\n tool.handler != null\n ? isHostToolRegisteredInScope(toolScope, tool.name)\n : isHostToolDeclaredInScope(toolScope, tool.name);\n\n if (tool.handler) {\n registerHostTool(toolScope, tool.name, tool.handler, {\n ...(tool.invokeOnAppend !== undefined ? { invokeOnAppend: tool.invokeOnAppend } : {}),\n ...(tool.onPreview ? { onPreview: tool.onPreview } : {}),\n });\n } else {\n declareHostTool(toolScope, tool.name);\n }\n\n if (!hadLocal) {\n localRegistrationChanged = true;\n }\n }\n\n if (!syncToServer) {\n if (localRegistrationChanged) {\n schedulePrepareSession(chat);\n }\n return;\n }\n\n if (!chat.isHostToolServerSyncReady()) {\n queuePendingHostToolSync(chat.id, options);\n if (typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(\n '[agent-chat] registerHostToolsWithSync: waiting for authentication before server sync.',\n );\n }\n if (localRegistrationChanged) {\n schedulePrepareSession(chat);\n }\n return;\n }\n\n const serverSyncedCount = await syncHostToolMetadataToServer(chat, options);\n\n if (localRegistrationChanged || serverSyncedCount > 0) {\n schedulePrepareSession(chat);\n }\n}\n\nfunction schedulePrepareSession(chat: AgentChatClient): void {\n const sessionId = chat.getState().activeSessionId?.trim();\n if (sessionId) {\n void chat.prepareSession(sessionId, { force: true });\n }\n}\n\n/** Test helper — clears the in-process server sync dedupe set and pending queue. */\nexport function clearHostToolServerSyncKeys(): void {\n serverSyncedKeys.clear();\n pendingSyncByClientId.clear();\n}\n","import type { AgentChatPageContext, ContextMentionAttachment } from '../../types';\n\n/** Merge selected @ mentions into pageContext.metadata for a single message send. */\nexport function mergePageContextWithMentions(\n base: AgentChatPageContext | null | undefined,\n mentions: ContextMentionAttachment[],\n): AgentChatPageContext | null {\n if (mentions.length === 0) return base ?? null;\n\n const out: AgentChatPageContext = { ...(base ?? {}) };\n const metadata: Record<string, unknown> = {};\n\n for (const mention of mentions) {\n metadata[mention.kind] = {\n ...mention.payload,\n content:\n typeof mention.payload.content === 'string'\n ? mention.payload.content\n : String(mention.payload.content ?? ''),\n _mentionLabel: mention.label,\n _mentionId: mention.id,\n };\n }\n\n out.metadata = metadata;\n return Object.keys(out).length > 0 ? out : null;\n}\n","import type {\n ContextMentionDefinition,\n ContextMentionRegistration,\n} from '../../types';\n\nconst HOST_ID_PREFIX = 'host:';\n\n/** Stable metadata / registry key from a human label (no manual slug in host code). */\nexport function slugContextMentionKey(label: string): string {\n const slug = label\n .trim()\n .toLowerCase()\n .replace(/[^\\w\\u4e00-\\u9fff]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 48);\n return slug || 'mention';\n}\n\n/** Coerce host `resolve()` output into inline-read payload (server reads `.content`). */\nexport function coerceContextMentionPayload(\n value: string | Record<string, unknown>,\n): Record<string, unknown> {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n return trimmed ? { content: trimmed } : { content: '' };\n }\n if (typeof value.content === 'string' && value.content.trim()) {\n return { ...value, content: value.content.trim() };\n }\n try {\n const serialized = JSON.stringify(value, null, 2);\n return { ...value, content: serialized };\n } catch {\n return { ...value, content: String(value) };\n }\n}\n\nfunction hostMentionId(key: string): string {\n const trimmed = key.trim();\n if (!trimmed) return `${HOST_ID_PREFIX}mention`;\n return trimmed.startsWith(HOST_ID_PREFIX) ? trimmed : `${HOST_ID_PREFIX}${trimmed}`;\n}\n\n/** Normalize a full registration (optional `kind`, optional payload shaping). */\nexport function normalizeContextMentionRegistration(\n item: ContextMentionRegistration,\n): ContextMentionRegistration {\n const id = hostMentionId(item.id || slugContextMentionKey(item.label));\n const key = id.startsWith(HOST_ID_PREFIX) ? id.slice(HOST_ID_PREFIX.length) : id;\n const kind = item.kind?.trim() || key;\n const payload =\n item.payload != null\n ? coerceContextMentionPayload(item.payload as Record<string, unknown>)\n : item.description\n ? coerceContextMentionPayload(item.description)\n : undefined;\n\n return {\n ...item,\n id,\n kind,\n group: item.group ?? 'host',\n payload,\n resolve: item.resolve\n ? async () => coerceContextMentionPayload(await item.resolve!())\n : undefined,\n };\n}\n\n/**\n * Declare one host @ mention — only `label` (+ `resolve` or `value`) required.\n * `id` / `kind` / `content` are derived by the SDK.\n */\nexport function defineContextMention(\n def: ContextMentionDefinition,\n): ContextMentionRegistration {\n const key = def.key?.trim() || slugContextMentionKey(def.label);\n const id = hostMentionId(key);\n const description =\n def.description ??\n (typeof def.value === 'string' ? def.value : undefined);\n\n let payload: Record<string, unknown> | undefined;\n if (def.value != null) {\n payload = coerceContextMentionPayload(def.value);\n }\n\n return normalizeContextMentionRegistration({\n id,\n label: def.label,\n kind: key,\n group: def.group ?? 'host',\n description,\n payload,\n resolve: def.resolve\n ? async () => coerceContextMentionPayload(await def.resolve!())\n : undefined,\n });\n}\n\nexport type PageContextMentionSnippet = {\n label: string;\n body: string;\n};\n\n/**\n * Build `pageContext.metadata` snippets for the @ picker from labels + bodies only.\n * Keys and `content` field are assigned by the SDK.\n */\nexport function definePageContextMentions(\n snippets: PageContextMentionSnippet[],\n): Record<string, unknown> {\n const metadata: Record<string, unknown> = {};\n const used = new Set<string>();\n\n for (const snippet of snippets) {\n let key = slugContextMentionKey(snippet.label);\n if (used.has(key)) {\n let n = 2;\n while (used.has(`${key}-${n}`)) n += 1;\n key = `${key}-${n}`;\n }\n used.add(key);\n metadata[key] = coerceContextMentionPayload({\n title: snippet.label,\n content: snippet.body,\n });\n }\n\n return metadata;\n}\n\nexport function isContextMentionDefinition(\n item: ContextMentionDefinition | ContextMentionRegistration,\n): item is ContextMentionDefinition {\n return !('id' in item && typeof item.id === 'string' && item.id.trim().length > 0);\n}\n\nexport function normalizeContextMentionInput(\n item: ContextMentionDefinition | ContextMentionRegistration,\n): ContextMentionRegistration {\n return isContextMentionDefinition(item)\n ? defineContextMention(item)\n : normalizeContextMentionRegistration(item);\n}\n","import type {\n ContextMentionAttachment,\n ContextMentionRegistration,\n RegisteredContextMention,\n} from '../../types';\nimport { coerceContextMentionPayload } from './context-mention-define';\n\nexport function toRegisteredContextMention(\n item: ContextMentionRegistration,\n): RegisteredContextMention {\n return {\n id: item.id,\n label: item.label,\n kind: item.kind ?? item.id.replace(/^host:/, ''),\n group: item.group,\n description: item.description,\n payload: item.payload,\n lazy: Boolean(item.resolve),\n };\n}\n\nexport function mergeContextMentionRegistrations(\n current: Map<string, ContextMentionRegistration>,\n items: ContextMentionRegistration[],\n replace = false,\n): Map<string, ContextMentionRegistration> {\n const next = replace ? new Map<string, ContextMentionRegistration>() : new Map(current);\n for (const item of items) {\n const id = item.id.trim();\n if (!id) continue;\n next.set(id, { ...item, id });\n }\n return next;\n}\n\nexport async function resolveContextMentionsForSend(\n mentions: ContextMentionAttachment[],\n registry: Map<string, ContextMentionRegistration>,\n): Promise<ContextMentionAttachment[]> {\n if (mentions.length === 0) return mentions;\n\n const resolved: ContextMentionAttachment[] = [];\n for (const mention of mentions) {\n const registration = registry.get(mention.id);\n if (!registration?.resolve) {\n resolved.push(mention);\n continue;\n }\n\n const dynamic = await registration.resolve();\n const coerced = coerceContextMentionPayload(dynamic);\n const content =\n typeof coerced.content === 'string'\n ? coerced.content\n : typeof registration.payload?.content === 'string'\n ? registration.payload.content\n : typeof mention.payload.content === 'string'\n ? mention.payload.content\n : mention.label;\n\n resolved.push({\n ...mention,\n label: registration.label,\n kind: registration.kind ?? registration.id.replace(/^host:/, ''),\n payload: {\n ...registration.payload,\n ...mention.payload,\n ...coerced,\n content,\n },\n });\n }\n return resolved;\n}\n","export class HTTPError extends Error {\n response;\n request;\n options;\n constructor(response, request, options) {\n const code = (response.status || response.status === 0) ? response.status : '';\n const title = response.statusText ?? '';\n const status = `${code} ${title}`.trim();\n const reason = status ? `status code ${status}` : 'an unknown error';\n super(`Request failed with ${reason}: ${request.method} ${request.url}`);\n this.name = 'HTTPError';\n this.response = response;\n this.request = request;\n this.options = options;\n }\n}\n//# sourceMappingURL=HTTPError.js.map","/**\nWrapper for non-Error values that were thrown.\n\nIn JavaScript, any value can be thrown (not just Error instances). This class wraps such values to ensure consistent error handling.\n*/\nexport class NonError extends Error {\n name = 'NonError';\n value;\n constructor(value) {\n let message = 'Non-error value was thrown';\n // Intentionally minimal as this error is just an edge-case.\n try {\n if (typeof value === 'string') {\n message = value;\n }\n else if (value && typeof value === 'object' && 'message' in value && typeof value.message === 'string') {\n message = value.message;\n }\n }\n catch {\n // Use default message if accessing properties throws\n }\n super(message);\n this.value = value;\n }\n}\n//# sourceMappingURL=NonError.js.map","import { NonError } from './NonError.js';\n/**\nInternal error used to signal a forced retry from afterResponse hooks.\nThis is thrown when a user returns ky.retry() from an afterResponse hook.\n*/\nexport class ForceRetryError extends Error {\n name = 'ForceRetryError';\n customDelay;\n code;\n customRequest;\n constructor(options) {\n // Runtime protection: wrap non-Error causes in NonError\n // TypeScript type is Error for guidance, but JS users can pass anything\n const cause = options?.cause\n ? (options.cause instanceof Error ? options.cause : new NonError(options.cause))\n : undefined;\n super(options?.code ? `Forced retry: ${options.code}` : 'Forced retry', cause ? { cause } : undefined);\n this.customDelay = options?.delay;\n this.code = options?.code;\n this.customRequest = options?.request;\n }\n}\n//# sourceMappingURL=ForceRetryError.js.map","export const supportsRequestStreams = (() => {\n let duplexAccessed = false;\n let hasContentType = false;\n const supportsReadableStream = typeof globalThis.ReadableStream === 'function';\n const supportsRequest = typeof globalThis.Request === 'function';\n if (supportsReadableStream && supportsRequest) {\n try {\n hasContentType = new globalThis.Request('https://empty.invalid', {\n body: new globalThis.ReadableStream(),\n method: 'POST',\n // @ts-expect-error - Types are outdated.\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n }\n catch (error) {\n // QQBrowser on iOS throws \"unsupported BodyInit type\" error (see issue #581)\n if (error instanceof Error && error.message === 'unsupported BodyInit type') {\n return false;\n }\n throw error;\n }\n }\n return duplexAccessed && !hasContentType;\n})();\nexport const supportsAbortController = typeof globalThis.AbortController === 'function';\nexport const supportsAbortSignal = typeof globalThis.AbortSignal === 'function' && typeof globalThis.AbortSignal.any === 'function';\nexport const supportsResponseStreams = typeof globalThis.ReadableStream === 'function';\nexport const supportsFormData = typeof globalThis.FormData === 'function';\nexport const requestMethods = ['get', 'post', 'put', 'patch', 'head', 'delete'];\nconst validate = () => undefined;\nvalidate();\nexport const responseTypes = {\n json: 'application/json',\n text: 'text/*',\n formData: 'multipart/form-data',\n arrayBuffer: '*/*',\n blob: '*/*',\n // Supported in modern Fetch implementations (for example, browsers and recent Node.js/undici).\n // We still feature-check at runtime before exposing the shortcut.\n bytes: '*/*',\n};\n// The maximum value of a 32bit int (see issue #117)\nexport const maxSafeTimeout = 2_147_483_647;\n// Size in bytes of a typical form boundary, used to help estimate upload size\nexport const usualFormBoundarySize = new TextEncoder().encode('------WebKitFormBoundaryaxpyiPgbbPti10Rw').length;\nexport const stop = Symbol('stop');\n/**\nMarker returned by ky.retry() to signal a forced retry from afterResponse hooks.\n*/\nexport class RetryMarker {\n options;\n constructor(options) {\n this.options = options;\n }\n}\n/**\nForce a retry from an `afterResponse` hook.\n\nThis allows you to retry a request based on the response content, even if the response has a successful status code. The retry will respect the `retry.limit` option and skip the `shouldRetry` check. The forced retry is observable in `beforeRetry` hooks, where the error will be a `ForceRetryError`.\n\n@param options - Optional configuration for the retry.\n\n@example\n```\nimport ky, {isForceRetryError} from 'ky';\n\nconst api = ky.extend({\n hooks: {\n afterResponse: [\n async (request, options, response) => {\n // Retry based on response body content\n if (response.status === 200) {\n const data = await response.clone().json();\n\n // Simple retry with default delay\n if (data.error?.code === 'TEMPORARY_ERROR') {\n return ky.retry();\n }\n\n // Retry with custom delay from API response\n if (data.error?.code === 'RATE_LIMIT') {\n return ky.retry({\n delay: data.error.retryAfter * 1000,\n code: 'RATE_LIMIT'\n });\n }\n\n // Retry with a modified request (e.g., fallback endpoint)\n if (data.error?.code === 'FALLBACK_TO_BACKUP') {\n return ky.retry({\n request: new Request('https://backup-api.com/endpoint', {\n method: request.method,\n headers: request.headers,\n }),\n code: 'BACKUP_ENDPOINT'\n });\n }\n\n // Retry with refreshed authentication\n if (data.error?.code === 'TOKEN_REFRESH' && data.newToken) {\n return ky.retry({\n request: new Request(request, {\n headers: {\n ...Object.fromEntries(request.headers),\n 'Authorization': `Bearer ${data.newToken}`\n }\n }),\n code: 'TOKEN_REFRESHED'\n });\n }\n\n // Retry with cause to preserve error chain\n try {\n validateResponse(data);\n } catch (error) {\n return ky.retry({\n code: 'VALIDATION_FAILED',\n cause: error\n });\n }\n }\n }\n ],\n beforeRetry: [\n ({error, retryCount}) => {\n // Observable in beforeRetry hooks\n if (isForceRetryError(error)) {\n console.log(`Forced retry #${retryCount}: ${error.message}`);\n // Example output: \"Forced retry #1: Forced retry: RATE_LIMIT\"\n }\n }\n ]\n }\n});\n\nconst response = await api.get('https://example.com/api');\n```\n*/\nexport const retry = (options) => new RetryMarker(options);\nexport const kyOptionKeys = {\n json: true,\n parseJson: true,\n stringifyJson: true,\n searchParams: true,\n prefixUrl: true,\n retry: true,\n timeout: true,\n hooks: true,\n throwHttpErrors: true,\n onDownloadProgress: true,\n onUploadProgress: true,\n fetch: true,\n context: true,\n};\n// Vendor-specific fetch options that should always be passed to fetch()\n// even if they appear on the Request object due to vendor patching.\n// See: https://github.com/sindresorhus/ky/issues/541\nexport const vendorSpecificOptions = {\n next: true, // Next.js cache revalidation (revalidate, tags)\n};\n// Standard RequestInit options that should NOT be passed separately to fetch()\n// because they're already applied to the Request object.\n// Note: `dispatcher` and `priority` are NOT included here - they're fetch-only\n// options that the Request constructor doesn't accept, so they need to be passed\n// separately to fetch().\nexport const requestOptionsRegistry = {\n method: true,\n headers: true,\n body: true,\n mode: true,\n credentials: true,\n cache: true,\n redirect: true,\n referrer: true,\n referrerPolicy: true,\n integrity: true,\n keepalive: true,\n signal: true,\n window: true,\n duplex: true,\n};\n//# sourceMappingURL=constants.js.map","import { usualFormBoundarySize } from '../core/constants.js';\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const getBodySize = (body) => {\n if (!body) {\n return 0;\n }\n if (body instanceof FormData) {\n // This is an approximation, as FormData size calculation is not straightforward\n let size = 0;\n for (const [key, value] of body) {\n size += usualFormBoundarySize;\n size += new TextEncoder().encode(`Content-Disposition: form-data; name=\"${key}\"`).length;\n size += typeof value === 'string'\n ? new TextEncoder().encode(value).length\n : value.size;\n }\n return size;\n }\n if (body instanceof Blob) {\n return body.size;\n }\n if (body instanceof ArrayBuffer) {\n return body.byteLength;\n }\n if (typeof body === 'string') {\n return new TextEncoder().encode(body).length;\n }\n if (body instanceof URLSearchParams) {\n return new TextEncoder().encode(body.toString()).length;\n }\n if ('byteLength' in body) {\n return (body).byteLength;\n }\n if (typeof body === 'object' && body !== null) {\n try {\n const jsonString = JSON.stringify(body);\n return new TextEncoder().encode(jsonString).length;\n }\n catch {\n return 0;\n }\n }\n return 0; // Default case, unable to determine size\n};\nconst withProgress = (stream, totalBytes, onProgress) => {\n let previousChunk;\n let transferredBytes = 0;\n return stream.pipeThrough(new TransformStream({\n transform(currentChunk, controller) {\n controller.enqueue(currentChunk);\n if (previousChunk) {\n transferredBytes += previousChunk.byteLength;\n let percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;\n // Avoid reporting 100% progress before the stream is actually finished (in case totalBytes is inaccurate)\n if (percent >= 1) {\n // Epsilon is used here to get as close as possible to 100% without reaching it.\n // If we were to use 0.99 here, percent could potentially go backwards.\n percent = 1 - Number.EPSILON;\n }\n onProgress?.({ percent, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes }, previousChunk);\n }\n previousChunk = currentChunk;\n },\n flush() {\n if (previousChunk) {\n transferredBytes += previousChunk.byteLength;\n onProgress?.({ percent: 1, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes }, previousChunk);\n }\n },\n }));\n};\nexport const streamResponse = (response, onDownloadProgress) => {\n if (!response.body) {\n return response;\n }\n if (response.status === 204) {\n return new Response(null, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n const totalBytes = Math.max(0, Number(response.headers.get('content-length')) || 0);\n return new Response(withProgress(response.body, totalBytes, onDownloadProgress), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n};\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const streamRequest = (request, onUploadProgress, originalBody) => {\n if (!request.body) {\n return request;\n }\n // Use original body for size calculation since request.body is already a stream\n const totalBytes = getBodySize(originalBody ?? request.body);\n return new Request(request, {\n // @ts-expect-error - Types are outdated.\n duplex: 'half',\n body: withProgress(request.body, totalBytes, onUploadProgress),\n });\n};\n//# sourceMappingURL=body.js.map","// eslint-disable-next-line @typescript-eslint/ban-types\nexport const isObject = (value) => value !== null && typeof value === 'object';\n//# sourceMappingURL=is.js.map","import { supportsAbortSignal } from '../core/constants.js';\nimport { isObject } from './is.js';\nexport const validateAndMerge = (...sources) => {\n for (const source of sources) {\n if ((!isObject(source) || Array.isArray(source)) && source !== undefined) {\n throw new TypeError('The `options` argument must be an object');\n }\n }\n return deepMerge({}, ...sources);\n};\nexport const mergeHeaders = (source1 = {}, source2 = {}) => {\n const result = new globalThis.Headers(source1);\n const isHeadersInstance = source2 instanceof globalThis.Headers;\n const source = new globalThis.Headers(source2);\n for (const [key, value] of source.entries()) {\n if ((isHeadersInstance && value === 'undefined') || value === undefined) {\n result.delete(key);\n }\n else {\n result.set(key, value);\n }\n }\n return result;\n};\nfunction newHookValue(original, incoming, property) {\n return (Object.hasOwn(incoming, property) && incoming[property] === undefined)\n ? []\n : deepMerge(original[property] ?? [], incoming[property] ?? []);\n}\nexport const mergeHooks = (original = {}, incoming = {}) => ({\n beforeRequest: newHookValue(original, incoming, 'beforeRequest'),\n beforeRetry: newHookValue(original, incoming, 'beforeRetry'),\n afterResponse: newHookValue(original, incoming, 'afterResponse'),\n beforeError: newHookValue(original, incoming, 'beforeError'),\n});\nconst appendSearchParameters = (target, source) => {\n const result = new URLSearchParams();\n for (const input of [target, source]) {\n if (input === undefined) {\n continue;\n }\n if (input instanceof URLSearchParams) {\n for (const [key, value] of input.entries()) {\n result.append(key, value);\n }\n }\n else if (Array.isArray(input)) {\n for (const pair of input) {\n if (!Array.isArray(pair) || pair.length !== 2) {\n throw new TypeError('Array search parameters must be provided in [[key, value], ...] format');\n }\n result.append(String(pair[0]), String(pair[1]));\n }\n }\n else if (isObject(input)) {\n for (const [key, value] of Object.entries(input)) {\n if (value !== undefined) {\n result.append(key, String(value));\n }\n }\n }\n else {\n // String\n const parameters = new URLSearchParams(input);\n for (const [key, value] of parameters.entries()) {\n result.append(key, value);\n }\n }\n }\n return result;\n};\n// TODO: Make this strongly-typed (no `any`).\nexport const deepMerge = (...sources) => {\n let returnValue = {};\n let headers = {};\n let hooks = {};\n let searchParameters;\n const signals = [];\n for (const source of sources) {\n if (Array.isArray(source)) {\n if (!Array.isArray(returnValue)) {\n returnValue = [];\n }\n returnValue = [...returnValue, ...source];\n }\n else if (isObject(source)) {\n for (let [key, value] of Object.entries(source)) {\n // Special handling for AbortSignal instances\n if (key === 'signal' && value instanceof globalThis.AbortSignal) {\n signals.push(value);\n continue;\n }\n // Special handling for context - shallow merge only\n if (key === 'context') {\n if (value !== undefined && value !== null && (!isObject(value) || Array.isArray(value))) {\n throw new TypeError('The `context` option must be an object');\n }\n // Shallow merge: always create a new object to prevent mutation bugs\n returnValue = {\n ...returnValue,\n context: (value === undefined || value === null)\n ? {}\n : { ...returnValue.context, ...value },\n };\n continue;\n }\n // Special handling for searchParams\n if (key === 'searchParams') {\n if (value === undefined || value === null) {\n // Explicit undefined or null removes searchParams\n searchParameters = undefined;\n }\n else {\n // First source: keep as-is to preserve type (string/object/URLSearchParams)\n // Subsequent sources: merge and convert to URLSearchParams\n searchParameters = searchParameters === undefined ? value : appendSearchParameters(searchParameters, value);\n }\n continue;\n }\n if (isObject(value) && key in returnValue) {\n value = deepMerge(returnValue[key], value);\n }\n returnValue = { ...returnValue, [key]: value };\n }\n if (isObject(source.hooks)) {\n hooks = mergeHooks(hooks, source.hooks);\n returnValue.hooks = hooks;\n }\n if (isObject(source.headers)) {\n headers = mergeHeaders(headers, source.headers);\n returnValue.headers = headers;\n }\n }\n }\n if (searchParameters !== undefined) {\n returnValue.searchParams = searchParameters;\n }\n if (signals.length > 0) {\n if (signals.length === 1) {\n returnValue.signal = signals[0];\n }\n else if (supportsAbortSignal) {\n returnValue.signal = AbortSignal.any(signals);\n }\n else {\n // When AbortSignal.any is not available, use the last signal\n // This maintains the previous behavior before signal merging was added\n // This can be remove when the `supportsAbortSignal` check is removed.`\n returnValue.signal = signals.at(-1);\n }\n }\n return returnValue;\n};\n//# sourceMappingURL=merge.js.map","import { requestMethods } from '../core/constants.js';\nexport const normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input;\nconst retryMethods = ['get', 'put', 'head', 'delete', 'options', 'trace'];\nconst retryStatusCodes = [408, 413, 429, 500, 502, 503, 504];\nconst retryAfterStatusCodes = [413, 429, 503];\nconst defaultRetryOptions = {\n limit: 2,\n methods: retryMethods,\n statusCodes: retryStatusCodes,\n afterStatusCodes: retryAfterStatusCodes,\n maxRetryAfter: Number.POSITIVE_INFINITY,\n backoffLimit: Number.POSITIVE_INFINITY,\n delay: attemptCount => 0.3 * (2 ** (attemptCount - 1)) * 1000,\n jitter: undefined,\n retryOnTimeout: false,\n};\nexport const normalizeRetryOptions = (retry = {}) => {\n if (typeof retry === 'number') {\n return {\n ...defaultRetryOptions,\n limit: retry,\n };\n }\n if (retry.methods && !Array.isArray(retry.methods)) {\n throw new Error('retry.methods must be an array');\n }\n retry.methods &&= retry.methods.map(method => method.toLowerCase());\n if (retry.statusCodes && !Array.isArray(retry.statusCodes)) {\n throw new Error('retry.statusCodes must be an array');\n }\n const normalizedRetry = Object.fromEntries(Object.entries(retry).filter(([, value]) => value !== undefined));\n return {\n ...defaultRetryOptions,\n ...normalizedRetry,\n };\n};\n//# sourceMappingURL=normalize.js.map","export class TimeoutError extends Error {\n request;\n constructor(request) {\n super(`Request timed out: ${request.method} ${request.url}`);\n this.name = 'TimeoutError';\n this.request = request;\n }\n}\n//# sourceMappingURL=TimeoutError.js.map","import { TimeoutError } from '../errors/TimeoutError.js';\n// `Promise.race()` workaround (#91)\nexport default async function timeout(request, init, abortController, options) {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n if (abortController) {\n abortController.abort();\n }\n reject(new TimeoutError(request));\n }, options.timeout);\n void options\n .fetch(request, init)\n .then(resolve)\n .catch(reject)\n .then(() => {\n clearTimeout(timeoutId);\n });\n });\n}\n//# sourceMappingURL=timeout.js.map","// https://github.com/sindresorhus/delay/tree/ab98ae8dfcb38e1593286c94d934e70d14a4e111\nexport default async function delay(ms, { signal }) {\n return new Promise((resolve, reject) => {\n if (signal) {\n signal.throwIfAborted();\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n function abortHandler() {\n clearTimeout(timeoutId);\n reject(signal.reason);\n }\n const timeoutId = setTimeout(() => {\n signal?.removeEventListener('abort', abortHandler);\n resolve();\n }, ms);\n });\n}\n//# sourceMappingURL=delay.js.map","import { kyOptionKeys, requestOptionsRegistry, vendorSpecificOptions } from '../core/constants.js';\nexport const findUnknownOptions = (request, options) => {\n const unknownOptions = {};\n for (const key in options) {\n // Skip inherited properties\n if (!Object.hasOwn(options, key)) {\n continue;\n }\n // An option is passed to fetch() if:\n // 1. It's not a standard RequestInit option (not in requestOptionsRegistry)\n // 2. It's not a ky-specific option (not in kyOptionKeys)\n // 3. Either:\n // a. It's not on the Request object, OR\n // b. It's a vendor-specific option that should always be passed (in vendorSpecificOptions)\n if (!(key in requestOptionsRegistry) && !(key in kyOptionKeys) && (!(key in request) || key in vendorSpecificOptions)) {\n unknownOptions[key] = options[key];\n }\n }\n return unknownOptions;\n};\nexport const hasSearchParameters = (search) => {\n if (search === undefined) {\n return false;\n }\n // The `typeof array` still gives \"object\", so we need different checking for array.\n if (Array.isArray(search)) {\n return search.length > 0;\n }\n if (search instanceof URLSearchParams) {\n return search.size > 0;\n }\n // Record\n if (typeof search === 'object') {\n return Object.keys(search).length > 0;\n }\n if (typeof search === 'string') {\n return search.trim().length > 0;\n }\n return Boolean(search);\n};\n//# sourceMappingURL=options.js.map","import { HTTPError } from '../errors/HTTPError.js';\nimport { TimeoutError } from '../errors/TimeoutError.js';\nimport { ForceRetryError } from '../errors/ForceRetryError.js';\n/**\nType guard to check if an error is a Ky error.\n\n@param error - The error to check\n@returns `true` if the error is a Ky error, `false` otherwise\n\n@example\n```\nimport ky, {isKyError} from 'ky';\ntry {\n const response = await ky.get('/api/data');\n} catch (error) {\n if (isKyError(error)) {\n // Handle Ky-specific errors\n console.log('Ky error occurred:', error.message);\n } else {\n // Handle other errors\n console.log('Unknown error:', error);\n }\n}\n```\n*/\nexport function isKyError(error) {\n return isHTTPError(error) || isTimeoutError(error) || isForceRetryError(error);\n}\n/**\nType guard to check if an error is an HTTPError.\n\n@param error - The error to check\n@returns `true` if the error is an HTTPError, `false` otherwise\n\n@example\n```\nimport ky, {isHTTPError} from 'ky';\ntry {\n const response = await ky.get('/api/data');\n} catch (error) {\n if (isHTTPError(error)) {\n console.log('HTTP error status:', error.response.status);\n }\n}\n```\n*/\nexport function isHTTPError(error) {\n return error instanceof HTTPError || (error?.name === HTTPError.name);\n}\n/**\nType guard to check if an error is a TimeoutError.\n\n@param error - The error to check\n@returns `true` if the error is a TimeoutError, `false` otherwise\n\n@example\n```\nimport ky, {isTimeoutError} from 'ky';\ntry {\n const response = await ky.get('/api/data', { timeout: 1000 });\n} catch (error) {\n if (isTimeoutError(error)) {\n console.log('Request timed out:', error.request.url);\n }\n}\n```\n*/\nexport function isTimeoutError(error) {\n return error instanceof TimeoutError || (error?.name === TimeoutError.name);\n}\n/**\nType guard to check if an error is a ForceRetryError.\n\n@param error - The error to check\n@returns `true` if the error is a ForceRetryError, `false` otherwise\n\n@example\n```\nimport ky, {isForceRetryError} from 'ky';\n\nconst api = ky.extend({\n hooks: {\n beforeRetry: [\n ({error, retryCount}) => {\n if (isForceRetryError(error)) {\n console.log(`Forced retry #${retryCount}: ${error.code}`);\n }\n }\n ]\n }\n});\n```\n*/\nexport function isForceRetryError(error) {\n return error instanceof ForceRetryError || (error?.name === ForceRetryError.name);\n}\n//# sourceMappingURL=type-guards.js.map","import { HTTPError } from '../errors/HTTPError.js';\nimport { NonError } from '../errors/NonError.js';\nimport { ForceRetryError } from '../errors/ForceRetryError.js';\nimport { streamRequest, streamResponse } from '../utils/body.js';\nimport { mergeHeaders, mergeHooks } from '../utils/merge.js';\nimport { normalizeRequestMethod, normalizeRetryOptions } from '../utils/normalize.js';\nimport timeout from '../utils/timeout.js';\nimport delay from '../utils/delay.js';\nimport { findUnknownOptions, hasSearchParameters } from '../utils/options.js';\nimport { isHTTPError, isTimeoutError } from '../utils/type-guards.js';\nimport { maxSafeTimeout, responseTypes, stop, RetryMarker, supportsAbortController, supportsAbortSignal, supportsFormData, supportsResponseStreams, supportsRequestStreams, } from './constants.js';\nexport class Ky {\n static create(input, options) {\n const ky = new Ky(input, options);\n const function_ = async () => {\n if (typeof ky.#options.timeout === 'number' && ky.#options.timeout > maxSafeTimeout) {\n throw new RangeError(`The \\`timeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n // Delay the fetch so that body method shortcuts can set the Accept header\n await Promise.resolve();\n // Before using ky.request, _fetch clones it and saves the clone for future retries to use.\n // If retry is not needed, close the cloned request's ReadableStream for memory safety.\n let response = await ky.#fetch();\n for (const hook of ky.#options.hooks.afterResponse) {\n // Clone the response before passing to hook so we can cancel it if needed\n const clonedResponse = ky.#decorateResponse(response.clone());\n let modifiedResponse;\n try {\n // eslint-disable-next-line no-await-in-loop\n modifiedResponse = await hook(ky.request, ky.#getNormalizedOptions(), clonedResponse, { retryCount: ky.#retryCount });\n }\n catch (error) {\n // Cancel both responses to prevent memory leaks when hook throws\n ky.#cancelResponseBody(clonedResponse);\n ky.#cancelResponseBody(response);\n throw error;\n }\n if (modifiedResponse instanceof RetryMarker) {\n // Cancel both the cloned response passed to the hook and the current response to prevent resource leaks (especially important in Deno/Bun).\n // Do not await cancellation since hooks can clone the response, leaving extra tee branches that keep cancel promises pending per the Streams spec.\n ky.#cancelResponseBody(clonedResponse);\n ky.#cancelResponseBody(response);\n throw new ForceRetryError(modifiedResponse.options);\n }\n // Determine which response to use going forward\n const nextResponse = modifiedResponse instanceof globalThis.Response ? modifiedResponse : response;\n // Cancel any response bodies we won't use to prevent memory leaks.\n // Uses fire-and-forget since hooks may have cloned the response, creating tee branches that block cancellation.\n if (clonedResponse !== nextResponse) {\n ky.#cancelResponseBody(clonedResponse);\n }\n if (response !== nextResponse) {\n ky.#cancelResponseBody(response);\n }\n response = nextResponse;\n }\n ky.#decorateResponse(response);\n if (!response.ok && (typeof ky.#options.throwHttpErrors === 'function'\n ? ky.#options.throwHttpErrors(response.status)\n : ky.#options.throwHttpErrors)) {\n let error = new HTTPError(response, ky.request, ky.#getNormalizedOptions());\n for (const hook of ky.#options.hooks.beforeError) {\n // eslint-disable-next-line no-await-in-loop\n error = await hook(error, { retryCount: ky.#retryCount });\n }\n throw error;\n }\n // If `onDownloadProgress` is passed, it uses the stream API internally\n if (ky.#options.onDownloadProgress) {\n if (typeof ky.#options.onDownloadProgress !== 'function') {\n throw new TypeError('The `onDownloadProgress` option must be a function');\n }\n if (!supportsResponseStreams) {\n throw new Error('Streams are not supported in your environment. `ReadableStream` is missing.');\n }\n const progressResponse = response.clone();\n ky.#cancelResponseBody(response);\n return streamResponse(progressResponse, ky.#options.onDownloadProgress);\n }\n return response;\n };\n // Always wrap in #retry to catch forced retries from afterResponse hooks\n // Method retriability is checked in #calculateRetryDelay for non-forced retries\n const result = ky.#retry(function_)\n .finally(() => {\n const originalRequest = ky.#originalRequest;\n // Ignore cancellation errors from already-locked or already-consumed streams.\n ky.#cancelBody(originalRequest?.body ?? undefined);\n ky.#cancelBody(ky.request.body ?? undefined);\n });\n for (const [type, mimeType] of Object.entries(responseTypes)) {\n // Only expose `.bytes()` when the environment implements it.\n if (type === 'bytes'\n && typeof globalThis.Response?.prototype?.bytes !== 'function') {\n continue;\n }\n result[type] = async () => {\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n ky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType);\n const response = await result;\n if (type === 'json') {\n if (response.status === 204) {\n return '';\n }\n const text = await response.text();\n if (text === '') {\n return '';\n }\n if (options.parseJson) {\n return options.parseJson(text);\n }\n return JSON.parse(text);\n }\n return response[type]();\n };\n }\n return result;\n }\n // eslint-disable-next-line unicorn/prevent-abbreviations\n static #normalizeSearchParams(searchParams) {\n // Filter out undefined values from plain objects\n if (searchParams && typeof searchParams === 'object' && !Array.isArray(searchParams) && !(searchParams instanceof URLSearchParams)) {\n return Object.fromEntries(Object.entries(searchParams).filter(([, value]) => value !== undefined));\n }\n return searchParams;\n }\n request;\n #abortController;\n #retryCount = 0;\n // eslint-disable-next-line @typescript-eslint/prefer-readonly -- False positive: #input is reassigned on line 202\n #input;\n #options;\n #originalRequest;\n #userProvidedAbortSignal;\n #cachedNormalizedOptions;\n // eslint-disable-next-line complexity\n constructor(input, options = {}) {\n this.#input = input;\n this.#options = {\n ...options,\n headers: mergeHeaders(this.#input.headers, options.headers),\n hooks: mergeHooks({\n beforeRequest: [],\n beforeRetry: [],\n beforeError: [],\n afterResponse: [],\n }, options.hooks),\n method: normalizeRequestMethod(options.method ?? this.#input.method ?? 'GET'),\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n prefixUrl: String(options.prefixUrl || ''),\n retry: normalizeRetryOptions(options.retry),\n throwHttpErrors: options.throwHttpErrors ?? true,\n timeout: options.timeout ?? 10_000,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n context: options.context ?? {},\n };\n if (typeof this.#input !== 'string' && !(this.#input instanceof URL || this.#input instanceof globalThis.Request)) {\n throw new TypeError('`input` must be a string, URL, or Request');\n }\n if (this.#options.prefixUrl && typeof this.#input === 'string') {\n if (this.#input.startsWith('/')) {\n throw new Error('`input` must not begin with a slash when using `prefixUrl`');\n }\n if (!this.#options.prefixUrl.endsWith('/')) {\n this.#options.prefixUrl += '/';\n }\n this.#input = this.#options.prefixUrl + this.#input;\n }\n if (supportsAbortController && supportsAbortSignal) {\n this.#userProvidedAbortSignal = this.#options.signal ?? this.#input.signal;\n this.#abortController = new globalThis.AbortController();\n this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;\n }\n if (supportsRequestStreams) {\n // @ts-expect-error - Types are outdated.\n this.#options.duplex = 'half';\n }\n if (this.#options.json !== undefined) {\n this.#options.body = this.#options.stringifyJson?.(this.#options.json) ?? JSON.stringify(this.#options.json);\n this.#options.headers.set('content-type', this.#options.headers.get('content-type') ?? 'application/json');\n }\n // To provide correct form boundary, Content-Type header should be deleted when creating Request from another Request with FormData/URLSearchParams body\n // Only delete if user didn't explicitly provide a custom content-type\n const userProvidedContentType = options.headers && new globalThis.Headers(options.headers).has('content-type');\n if (this.#input instanceof globalThis.Request\n && ((supportsFormData && this.#options.body instanceof globalThis.FormData) || this.#options.body instanceof URLSearchParams)\n && !userProvidedContentType) {\n this.#options.headers.delete('content-type');\n }\n this.request = new globalThis.Request(this.#input, this.#options);\n if (hasSearchParameters(this.#options.searchParams)) {\n // eslint-disable-next-line unicorn/prevent-abbreviations\n const textSearchParams = typeof this.#options.searchParams === 'string'\n ? this.#options.searchParams.replace(/^\\?/, '')\n : new URLSearchParams(Ky.#normalizeSearchParams(this.#options.searchParams)).toString();\n // eslint-disable-next-line unicorn/prevent-abbreviations\n const searchParams = '?' + textSearchParams;\n const url = this.request.url.replace(/(?:\\?.*?)?(?=#|$)/, searchParams);\n // Recreate request with the updated URL. We already have all options in this.#options, including duplex.\n this.request = new globalThis.Request(url, this.#options);\n }\n // If `onUploadProgress` is passed, it uses the stream API internally\n if (this.#options.onUploadProgress) {\n if (typeof this.#options.onUploadProgress !== 'function') {\n throw new TypeError('The `onUploadProgress` option must be a function');\n }\n if (!supportsRequestStreams) {\n throw new Error('Request streams are not supported in your environment. The `duplex` option for `Request` is not available.');\n }\n this.request = this.#wrapRequestWithUploadProgress(this.request, this.#options.body ?? undefined);\n }\n }\n #calculateDelay() {\n const retryDelay = this.#options.retry.delay(this.#retryCount);\n let jitteredDelay = retryDelay;\n if (this.#options.retry.jitter === true) {\n jitteredDelay = Math.random() * retryDelay;\n }\n else if (typeof this.#options.retry.jitter === 'function') {\n jitteredDelay = this.#options.retry.jitter(retryDelay);\n if (!Number.isFinite(jitteredDelay) || jitteredDelay < 0) {\n jitteredDelay = retryDelay;\n }\n }\n // Handle undefined backoffLimit by treating it as no limit (Infinity)\n const backoffLimit = this.#options.retry.backoffLimit ?? Number.POSITIVE_INFINITY;\n return Math.min(backoffLimit, jitteredDelay);\n }\n async #calculateRetryDelay(error) {\n this.#retryCount++;\n if (this.#retryCount > this.#options.retry.limit) {\n throw error;\n }\n // Wrap non-Error throws to ensure consistent error handling\n const errorObject = error instanceof Error ? error : new NonError(error);\n // Handle forced retry from afterResponse hook - skip method check and shouldRetry\n if (errorObject instanceof ForceRetryError) {\n return errorObject.customDelay ?? this.#calculateDelay();\n }\n // Check if method is retriable for non-forced retries\n if (!this.#options.retry.methods.includes(this.request.method.toLowerCase())) {\n throw error;\n }\n // User-provided shouldRetry function takes precedence over all other checks\n if (this.#options.retry.shouldRetry !== undefined) {\n const result = await this.#options.retry.shouldRetry({ error: errorObject, retryCount: this.#retryCount });\n // Strict boolean checking - only exact true/false are handled specially\n if (result === false) {\n throw error;\n }\n if (result === true) {\n // Force retry - skip all other validation and return delay\n return this.#calculateDelay();\n }\n // If undefined or any other value, fall through to default behavior\n }\n // Default timeout behavior\n if (isTimeoutError(error) && !this.#options.retry.retryOnTimeout) {\n throw error;\n }\n if (isHTTPError(error)) {\n if (!this.#options.retry.statusCodes.includes(error.response.status)) {\n throw error;\n }\n const retryAfter = error.response.headers.get('Retry-After')\n ?? error.response.headers.get('RateLimit-Reset')\n ?? error.response.headers.get('X-RateLimit-Retry-After') // Symfony-based services\n ?? error.response.headers.get('X-RateLimit-Reset') // GitHub\n ?? error.response.headers.get('X-Rate-Limit-Reset'); // Twitter\n if (retryAfter && this.#options.retry.afterStatusCodes.includes(error.response.status)) {\n let after = Number(retryAfter) * 1000;\n if (Number.isNaN(after)) {\n after = Date.parse(retryAfter) - Date.now();\n }\n else if (after >= Date.parse('2024-01-01')) {\n // A large number is treated as a timestamp (fixed threshold protects against clock skew)\n after -= Date.now();\n }\n const max = this.#options.retry.maxRetryAfter ?? after;\n // Don't apply jitter when server provides explicit retry timing\n return after < max ? after : max;\n }\n if (error.response.status === 413) {\n throw error;\n }\n }\n return this.#calculateDelay();\n }\n #decorateResponse(response) {\n if (this.#options.parseJson) {\n response.json = async () => this.#options.parseJson(await response.text());\n }\n return response;\n }\n #cancelBody(body) {\n if (!body) {\n return;\n }\n // Ignore cancellation failures from already-locked or already-consumed streams.\n void body.cancel().catch(() => undefined);\n }\n #cancelResponseBody(response) {\n // Ignore cancellation failures from already-locked or already-consumed streams.\n this.#cancelBody(response.body ?? undefined);\n }\n async #retry(function_) {\n try {\n return await function_();\n }\n catch (error) {\n const ms = Math.min(await this.#calculateRetryDelay(error), maxSafeTimeout);\n if (this.#retryCount < 1) {\n throw error;\n }\n // Only use user-provided signal for delay, not our internal abortController\n await delay(ms, this.#userProvidedAbortSignal ? { signal: this.#userProvidedAbortSignal } : {});\n // Apply custom request from forced retry before beforeRetry hooks\n // Ensure the custom request has the correct managed signal for timeouts and user aborts\n if (error instanceof ForceRetryError && error.customRequest) {\n const managedRequest = this.#options.signal\n ? new globalThis.Request(error.customRequest, { signal: this.#options.signal })\n : new globalThis.Request(error.customRequest);\n this.#assignRequest(managedRequest);\n }\n for (const hook of this.#options.hooks.beforeRetry) {\n // eslint-disable-next-line no-await-in-loop\n const hookResult = await hook({\n request: this.request,\n options: this.#getNormalizedOptions(),\n error: error,\n retryCount: this.#retryCount,\n });\n if (hookResult instanceof globalThis.Request) {\n this.#assignRequest(hookResult);\n break;\n }\n // If a Response is returned, use it and skip the retry\n if (hookResult instanceof globalThis.Response) {\n return hookResult;\n }\n // If `stop` is returned from the hook, the retry process is stopped\n if (hookResult === stop) {\n return;\n }\n }\n return this.#retry(function_);\n }\n }\n async #fetch() {\n // Reset abortController if it was aborted (happens on timeout retry)\n if (this.#abortController?.signal.aborted) {\n this.#abortController = new globalThis.AbortController();\n this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;\n // Recreate request with new signal\n this.request = new globalThis.Request(this.request, { signal: this.#options.signal });\n }\n for (const hook of this.#options.hooks.beforeRequest) {\n // eslint-disable-next-line no-await-in-loop\n const result = await hook(this.request, this.#getNormalizedOptions(), { retryCount: this.#retryCount });\n if (result instanceof Response) {\n return result;\n }\n if (result instanceof globalThis.Request) {\n this.#assignRequest(result);\n break;\n }\n }\n const nonRequestOptions = findUnknownOptions(this.request, this.#options);\n // Cloning is done here to prepare in advance for retries\n this.#originalRequest = this.request;\n this.request = this.#originalRequest.clone();\n if (this.#options.timeout === false) {\n return this.#options.fetch(this.#originalRequest, nonRequestOptions);\n }\n return timeout(this.#originalRequest, nonRequestOptions, this.#abortController, this.#options);\n }\n #getNormalizedOptions() {\n if (!this.#cachedNormalizedOptions) {\n const { hooks, ...normalizedOptions } = this.#options;\n this.#cachedNormalizedOptions = Object.freeze(normalizedOptions);\n }\n return this.#cachedNormalizedOptions;\n }\n #assignRequest(request) {\n this.#cachedNormalizedOptions = undefined;\n this.request = this.#wrapRequestWithUploadProgress(request);\n }\n #wrapRequestWithUploadProgress(request, originalBody) {\n if (!this.#options.onUploadProgress || !request.body) {\n return request;\n }\n return streamRequest(request, this.#options.onUploadProgress, originalBody ?? this.#options.body ?? undefined);\n }\n}\n//# sourceMappingURL=Ky.js.map","/*! MIT License © Sindre Sorhus */\nimport { Ky } from './core/Ky.js';\nimport { requestMethods, stop, retry } from './core/constants.js';\nimport { validateAndMerge } from './utils/merge.js';\nconst createInstance = (defaults) => {\n // eslint-disable-next-line @typescript-eslint/promise-function-async\n const ky = (input, options) => Ky.create(input, validateAndMerge(defaults, options));\n for (const method of requestMethods) {\n // eslint-disable-next-line @typescript-eslint/promise-function-async\n ky[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, { method }));\n }\n ky.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));\n ky.extend = (newDefaults) => {\n if (typeof newDefaults === 'function') {\n newDefaults = newDefaults(defaults ?? {});\n }\n return createInstance(validateAndMerge(defaults, newDefaults));\n };\n ky.stop = stop;\n ky.retry = retry;\n return ky;\n};\nconst ky = createInstance();\nexport default ky;\nexport { HTTPError } from './errors/HTTPError.js';\nexport { TimeoutError } from './errors/TimeoutError.js';\nexport { ForceRetryError } from './errors/ForceRetryError.js';\nexport { isKyError, isHTTPError, isTimeoutError, isForceRetryError, } from './utils/type-guards.js';\n// Intentionally not exporting this for now as it's just an implementation detail and we don't want to commit to a certain API yet at least.\n// export {NonError} from './errors/NonError.js';\n//# sourceMappingURL=index.js.map","import { AgentChatError } from '../lib/errors';\n\ninterface ServerErrorBody {\n error?: { code?: string; message?: string };\n message?: string | string[];\n data?: { message?: string | string[] };\n code?: string;\n}\n\nfunction normalizeServerMessage(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (Array.isArray(value)) {\n const joined = value.filter((item): item is string => typeof item === 'string').join('; ');\n return joined || undefined;\n }\n return undefined;\n}\n\nfunction isJsonContent(headers: Headers): boolean {\n const ct = headers.get('content-type') ?? '';\n return ct.includes('application/json');\n}\n\nexport async function readHttpError(response: Response): Promise<AgentChatError> {\n let serverCode: string | undefined;\n let serverMessage: string | undefined;\n let body: unknown;\n try {\n if (isJsonContent(response.headers)) {\n body = (await response.json()) as ServerErrorBody;\n const parsed = body as ServerErrorBody;\n const nestedData =\n parsed.data != null && typeof parsed.data === 'object' && !Array.isArray(parsed.data)\n ? (parsed.data as { code?: string; message?: string | string[] })\n : undefined;\n serverCode = parsed.error?.code ?? parsed.code ?? nestedData?.code;\n serverMessage =\n normalizeServerMessage(parsed.error?.message) ??\n normalizeServerMessage(parsed.message) ??\n normalizeServerMessage(parsed.data?.message) ??\n normalizeServerMessage(nestedData?.message);\n } else {\n serverMessage = (await response.text()).slice(0, 500);\n }\n } catch {\n // ignore parse errors and fall back to status text\n }\n\n const message = serverMessage\n ? `HTTP ${response.status}: ${serverMessage}`\n : `HTTP ${response.status}: ${response.statusText || 'request failed'}`;\n\n const data =\n body != null && typeof body === 'object' && !Array.isArray(body) && 'data' in body\n ? (body as { data: unknown }).data\n : body;\n\n return new AgentChatError('TRANSPORT_FAILED', message, {\n details: {\n status: response.status,\n serverCode,\n url: response.url,\n /** Full JSON body — needed for 409 `PAGE_ACTION_ALREADY_ACTIVE` soft handling. */\n body,\n data,\n },\n });\n}\n\nexport function toTransportAbortError(err: unknown, label = 'Request aborted'): AgentChatError {\n return new AgentChatError('TRANSPORT_ABORTED', label, { cause: err });\n}\n\nexport function toNetworkError(err: unknown, label = 'Network error'): AgentChatError {\n return new AgentChatError('TRANSPORT_FAILED', label, { cause: err });\n}\n\nexport function isAbortError(err: unknown): boolean {\n if (err instanceof AgentChatError && err.code === 'TRANSPORT_ABORTED') return true;\n const name = (err as { name?: string })?.name;\n return name === 'AbortError';\n}\n","class ParseError extends Error {\n constructor(message, options) {\n super(message), this.name = \"ParseError\", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line;\n }\n}\nconst LF = 10, CR = 13, SPACE = 32;\nfunction noop(_arg) {\n}\nfunction createParser(config) {\n if (typeof config == \"function\")\n throw new TypeError(\n \"`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?\"\n );\n const { onEvent = noop, onError = noop, onRetry = noop, onComment, maxBufferSize } = config, pendingFragments = [];\n let pendingFragmentsLength = 0, isFirstChunk = !0, id, data = \"\", dataLines = 0, eventType, terminated = !1;\n function feed(chunk) {\n if (terminated)\n throw new Error(\n \"Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing.\"\n );\n if (isFirstChunk && (isFirstChunk = !1, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) {\n const trailing2 = processLines(chunk);\n trailing2 !== \"\" && (pendingFragments.push(trailing2), pendingFragmentsLength = trailing2.length), checkBufferSize();\n return;\n }\n if (chunk.indexOf(`\n`) === -1 && chunk.indexOf(\"\\r\") === -1) {\n pendingFragments.push(chunk), pendingFragmentsLength += chunk.length, checkBufferSize();\n return;\n }\n pendingFragments.push(chunk);\n const input = pendingFragments.join(\"\");\n pendingFragments.length = 0, pendingFragmentsLength = 0;\n const trailing = processLines(input);\n trailing !== \"\" && (pendingFragments.push(trailing), pendingFragmentsLength = trailing.length), checkBufferSize();\n }\n function checkBufferSize() {\n maxBufferSize !== void 0 && (pendingFragmentsLength + data.length <= maxBufferSize || (terminated = !0, pendingFragments.length = 0, pendingFragmentsLength = 0, id = void 0, data = \"\", dataLines = 0, eventType = void 0, onError(\n new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {\n type: \"max-buffer-size-exceeded\"\n })\n )));\n }\n function processLines(chunk) {\n let searchIndex = 0;\n if (chunk.indexOf(\"\\r\") === -1) {\n let lfIndex = chunk.indexOf(`\n`, searchIndex);\n for (; lfIndex !== -1; ) {\n if (searchIndex === lfIndex) {\n dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = \"\", dataLines = 0, eventType = void 0, searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`\n`, searchIndex);\n continue;\n }\n const firstCharCode = chunk.charCodeAt(searchIndex);\n if (isDataPrefix(chunk, searchIndex, firstCharCode)) {\n const valueStart = chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5, value = chunk.slice(valueStart, lfIndex);\n if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {\n onEvent({ id, event: eventType, data: value }), id = void 0, data = \"\", eventType = void 0, searchIndex = lfIndex + 2, lfIndex = chunk.indexOf(`\n`, searchIndex);\n continue;\n }\n data = dataLines === 0 ? value : `${data}\n${value}`, dataLines++;\n } else isEventPrefix(chunk, searchIndex, firstCharCode) ? eventType = chunk.slice(\n chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,\n lfIndex\n ) || void 0 : parseLine(chunk, searchIndex, lfIndex);\n searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`\n`, searchIndex);\n }\n return chunk.slice(searchIndex);\n }\n for (; searchIndex < chunk.length; ) {\n const crIndex = chunk.indexOf(\"\\r\", searchIndex), lfIndex = chunk.indexOf(`\n`, searchIndex);\n let lineEnd = -1;\n if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = crIndex < lfIndex ? crIndex : lfIndex : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1)\n break;\n parseLine(chunk, searchIndex, lineEnd), searchIndex = lineEnd + 1, chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF && searchIndex++;\n }\n return chunk.slice(searchIndex);\n }\n function parseLine(chunk, start, end) {\n if (start === end) {\n dispatchEvent();\n return;\n }\n const firstCharCode = chunk.charCodeAt(start);\n if (isDataPrefix(chunk, start, firstCharCode)) {\n const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5, value2 = chunk.slice(valueStart, end);\n data = dataLines === 0 ? value2 : `${data}\n${value2}`, dataLines++;\n return;\n }\n if (isEventPrefix(chunk, start, firstCharCode)) {\n eventType = chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || void 0;\n return;\n }\n if (firstCharCode === 105 && chunk.charCodeAt(start + 1) === 100 && chunk.charCodeAt(start + 2) === 58) {\n const value2 = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end);\n value2.includes(\"\\0\") || (id = value2);\n return;\n }\n if (firstCharCode === 58) {\n if (onComment) {\n const line2 = chunk.slice(start, end);\n onComment(line2.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1));\n }\n return;\n }\n const line = chunk.slice(start, end), fieldSeparatorIndex = line.indexOf(\":\");\n if (fieldSeparatorIndex === -1) {\n processField(line, \"\", line);\n return;\n }\n const field = line.slice(0, fieldSeparatorIndex), offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset);\n processField(field, value, line);\n }\n function processField(field, value, line) {\n switch (field) {\n case \"event\":\n eventType = value || void 0;\n break;\n case \"data\":\n data = dataLines === 0 ? value : `${data}\n${value}`, dataLines++;\n break;\n case \"id\":\n value.includes(\"\\0\") || (id = value);\n break;\n case \"retry\":\n /^\\d+$/.test(value) ? onRetry(parseInt(value, 10)) : onError(\n new ParseError(`Invalid \\`retry\\` value: \"${value}\"`, {\n type: \"invalid-retry\",\n value,\n line\n })\n );\n break;\n default:\n onError(\n new ParseError(\n `Unknown field \"${field.length > 20 ? `${field.slice(0, 20)}\\u2026` : field}\"`,\n { type: \"unknown-field\", field, value, line }\n )\n );\n break;\n }\n }\n function dispatchEvent() {\n dataLines > 0 && onEvent({\n id,\n event: eventType,\n data\n }), id = void 0, data = \"\", dataLines = 0, eventType = void 0;\n }\n function reset(options = {}) {\n if (options.consume && pendingFragments.length > 0) {\n const incompleteLine = pendingFragments.join(\"\");\n parseLine(incompleteLine, 0, incompleteLine.length);\n }\n isFirstChunk = !0, id = void 0, data = \"\", dataLines = 0, eventType = void 0, pendingFragments.length = 0, pendingFragmentsLength = 0, terminated = !1;\n }\n return { feed, reset };\n}\nfunction isDataPrefix(chunk, i, firstCharCode) {\n return firstCharCode === 100 && chunk.charCodeAt(i + 1) === 97 && chunk.charCodeAt(i + 2) === 116 && chunk.charCodeAt(i + 3) === 97 && chunk.charCodeAt(i + 4) === 58;\n}\nfunction isEventPrefix(chunk, i, firstCharCode) {\n return firstCharCode === 101 && chunk.charCodeAt(i + 1) === 118 && chunk.charCodeAt(i + 2) === 101 && chunk.charCodeAt(i + 3) === 110 && chunk.charCodeAt(i + 4) === 116 && chunk.charCodeAt(i + 5) === 58;\n}\nexport {\n ParseError,\n createParser\n};\n//# sourceMappingURL=index.js.map\n","import { createParser, type EventSourceMessage } from 'eventsource-parser';\nimport { AgentChatError } from '../lib/errors';\nimport { readHttpError, toNetworkError } from './errors';\nimport type { HttpStreamOptions, SseEventChunk } from './types';\n\nfunction buildUrl(apiBase: string, path: string): string {\n const base = apiBase.replace(/\\/+$/, '');\n const tail = path.startsWith('/') ? path : `/${path}`;\n return `${base}${tail}`;\n}\n\nexport async function* readSseStream(\n fetchImpl: typeof fetch,\n url: string,\n headers: Record<string, string>,\n init: HttpStreamOptions = {},\n): AsyncIterable<SseEventChunk> {\n const method = init.method ?? (init.body !== undefined ? 'POST' : 'GET');\n\n const requestHeaders = new Headers(headers);\n for (const [key, value] of Object.entries(init.headers ?? {})) {\n requestHeaders.set(key, value);\n }\n requestHeaders.set('accept', 'text/event-stream');\n\n let body: BodyInit | undefined;\n if (init.body !== undefined && method !== 'GET' && method !== 'HEAD') {\n body = typeof init.body === 'string' ? init.body : JSON.stringify(init.body);\n if (!requestHeaders.has('content-type') && typeof init.body !== 'string') {\n requestHeaders.set('content-type', 'application/json');\n }\n }\n\n let response: Response;\n try {\n response = await fetchImpl(url, {\n method,\n headers: requestHeaders,\n body,\n signal: init.signal,\n });\n } catch (err) {\n throw toNetworkError(err);\n }\n\n if (!response.ok) throw await readHttpError(response);\n if (!response.body) {\n throw new AgentChatError('TRANSPORT_FAILED', 'SSE response has no body');\n }\n\n init.onConnected?.();\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8');\n const queue: SseEventChunk[] = [];\n const parser = createParser({\n onEvent(evt: EventSourceMessage) {\n const eventName = evt.event?.trim() ? evt.event.trim() : 'message';\n queue.push({ event: eventName, data: evt.data, id: evt.id });\n },\n });\n\n const drainQueue = (): SseEventChunk[] => queue.splice(0, queue.length);\n\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n const tail = decoder.decode();\n if (tail) parser.feed(tail);\n for (const chunk of drainQueue()) yield chunk;\n break;\n }\n parser.feed(decoder.decode(value, { stream: true }));\n for (const chunk of drainQueue()) yield chunk;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport { buildUrl };\n","import ky, { HTTPError } from 'ky';\nimport { AgentChatError } from '../lib/errors';\nimport {\n isAbortError,\n readHttpError,\n toNetworkError,\n toTransportAbortError,\n} from './errors';\nimport { buildUrl, readSseStream } from './sse';\nimport type {\n HttpClient,\n HttpClientOptions,\n HttpRequestOptions,\n HttpStreamOptions,\n SseEventChunk,\n} from './types';\n\nfunction normalizePath(path: string): string {\n return path.replace(/^\\//, '');\n}\n\nfunction mergeRequestHeaders(\n defaults: Record<string, string>,\n init: HttpRequestOptions,\n): Record<string, string> {\n const omit = new Set(\n (init.omitDefaultHeaders ?? []).map((name) => name.toLowerCase()),\n );\n const merged: Record<string, string> = {};\n for (const [name, value] of Object.entries(defaults)) {\n if (!omit.has(name.toLowerCase())) merged[name] = value;\n }\n return { ...merged, ...(init.headers ?? {}) };\n}\n\nexport function createHttpClient(options: HttpClientOptions): HttpClient {\n const apiBase = options.apiBase.replace(/\\/+$/, '');\n const defaultHeaders: Record<string, string> = { ...(options.defaultHeaders ?? {}) };\n const fetchImpl =\n options.fetch ?? (typeof fetch !== 'undefined' ? fetch.bind(globalThis) : undefined);\n\n if (!fetchImpl) {\n throw new AgentChatError(\n 'TRANSPORT_FAILED',\n 'No fetch implementation available. Provide one via HttpClientOptions.fetch.',\n );\n }\n\n const api = ky.create({\n prefixUrl: `${apiBase}/`,\n retry: { limit: 0 },\n timeout: false,\n fetch: fetchImpl,\n hooks: {\n beforeError: [\n async (error) => {\n if (error instanceof HTTPError) {\n throw await readHttpError(error.response);\n }\n if (isAbortError(error)) {\n throw toTransportAbortError(error);\n }\n throw toNetworkError(error);\n },\n ],\n },\n });\n\n return {\n setDefaultHeader(name, value) {\n if (value === undefined) delete defaultHeaders[name];\n else defaultHeaders[name] = value;\n },\n\n async request<T>(path: string, init: HttpRequestOptions = {}): Promise<T> {\n const method = init.method ?? (init.body !== undefined ? 'POST' : 'GET');\n const headers = {\n accept: 'application/json',\n ...mergeRequestHeaders(defaultHeaders, init),\n };\n\n const searchParams: Record<string, string> | undefined = init.searchParams\n ? Object.fromEntries(\n Object.entries(init.searchParams)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => [key, String(value)]),\n )\n : undefined;\n\n try {\n const response = await api(normalizePath(path), {\n method,\n headers,\n searchParams,\n json: method === 'GET' || method === 'HEAD' ? undefined : init.body,\n signal: init.signal,\n });\n\n if (response.status === 204) return undefined as T;\n\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n return await response.json<T>();\n }\n return (await response.text()) as unknown as T;\n } catch (err) {\n if (err instanceof AgentChatError) throw err;\n if (isAbortError(err)) throw toTransportAbortError(err);\n throw toNetworkError(err);\n }\n },\n\n stream(path: string, init: HttpStreamOptions = {}): AsyncIterable<SseEventChunk> {\n const url = buildUrl(apiBase, path);\n return readSseStream(fetchImpl, url, defaultHeaders, init);\n },\n };\n}\n","import { buildAppClientAuthHeaders } from '../auth/auth-headers';\nimport { parseAuthResponse } from '../auth/auth-response';\nimport type { AppClientAuthData } from '../auth/auth-types';\nimport { AgentChatError } from '../lib/errors';\nimport type { HttpClient } from '../http';\n\nexport class AuthService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /**\n * Exchange `x-app-dsn` (+ optional `x-account-token`) for a user access token\n * via `POST /app-client/auth`.\n */\n async authenticate(dsn: string, accountToken?: string | null): Promise<AppClientAuthData> {\n const body = await this.http.request<unknown>('/app-client/auth', {\n method: 'POST',\n headers: buildAppClientAuthHeaders(dsn, accountToken),\n });\n const authData = parseAuthResponse(body);\n if (!authData?.ok) {\n throw new AgentChatError('AUTH_REQUIRED', 'App client authentication failed');\n }\n return authData;\n }\n\n /** Email/password login via `POST /user/login`. */\n async login(email: string, password: string): Promise<AppClientAuthData> {\n const body = await this.http.request<unknown>('/user/login', {\n method: 'POST',\n body: { email, password },\n });\n const loginAuth = parseAuthResponse(body);\n if (!loginAuth?.accessToken) {\n throw new AgentChatError('LOGIN_FAILED', 'Login succeeded but accessToken is missing');\n }\n return loginAuth;\n }\n}\n","import type { QueryClientAvailableAgents, QueryClientSkillByAgent } from '../../types';\nimport { buildAgentClientHeaders } from '../auth/auth-headers';\nimport type { HttpClient } from '../http';\nimport { DSN_AUTH_HEADER } from '../lib/resolve';\n\nexport type AgentClientAuthContext = () => {\n dsn: string;\n};\n\nfunction compactSearchParams(\n query?: QueryClientAvailableAgents | QueryClientSkillByAgent,\n): Record<string, string | number | boolean | undefined> | undefined {\n if (!query) return undefined;\n const entries = Object.entries(query).filter(\n ([, value]) => value !== undefined && value !== '',\n );\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\nexport class AgentService {\n private http: HttpClient;\n private resolveAuth: AgentClientAuthContext;\n\n constructor(http: HttpClient, resolveAuth: AgentClientAuthContext) {\n this.http = http;\n this.resolveAuth = resolveAuth;\n }\n\n private agentRequestInit(\n dsn: string,\n init: { signal?: AbortSignal; searchParams?: Record<string, string | number | boolean | undefined> },\n ) {\n return {\n method: 'GET' as const,\n signal: init.signal,\n searchParams: init.searchParams,\n omitDefaultHeaders: [DSN_AUTH_HEADER],\n headers: buildAgentClientHeaders(dsn),\n };\n }\n\n /** `GET /agent/client/available` — role-filtered agents for C-end picker. */\n listAvailableAgents(\n query?: QueryClientAvailableAgents,\n signal?: AbortSignal,\n ): Promise<unknown> {\n const { dsn } = this.resolveAuth();\n return this.http.request(\n '/agent/client/available',\n this.agentRequestInit(dsn, { signal, searchParams: compactSearchParams(query) }),\n );\n }\n\n /** `GET /agent/client/list` — all app agents (no role filter); used for empty-state hints. */\n listAllClientAgents(signal?: AbortSignal): Promise<unknown> {\n const { dsn } = this.resolveAuth();\n return this.http.request('/agent/client/list', this.agentRequestInit(dsn, { signal }));\n }\n\n /** `GET /agent/:agentId/skills/client` — role-filtered skills for the selected agent. */\n listClientSkills(\n agentId: string,\n query?: QueryClientSkillByAgent,\n signal?: AbortSignal,\n ): Promise<unknown> {\n const { dsn } = this.resolveAuth();\n const id = agentId.trim();\n return this.http.request(\n `/agent/${id}/skills/client`,\n this.agentRequestInit(dsn, { signal, searchParams: compactSearchParams(query) }),\n );\n }\n}\n","import { AgentChatError } from '../lib/errors';\nimport type { HttpClient, HttpStreamOptions, SseEventChunk } from '../http';\nimport type { AgentChatPageContext, WriteGate } from '../../types';\nimport type { CancelRunResult } from '../chat/session-run';\nimport { parseCancelRunResponse } from '../chat/session-run';\n\nexport const DEFAULT_SESSION_PAGE_SIZE = 20;\nexport const DEFAULT_MESSAGE_PAGE_SIZE = 20;\n\nexport interface MessageSendContext {\n agentId?: string;\n skillId?: string;\n page?: string;\n routePath?: string;\n routeParams?: Record<string, string>;\n flowId?: number;\n programName?: string;\n entity?: AgentChatPageContext['entity'];\n metadata?: Record<string, unknown>;\n /** Brain clarify continuation — structured entity pick. */\n entityCommit?: { entityType: string; selectedId: string };\n}\n\n/** Response from `POST /chat/{sessionId}/prepare` (host-tool warm + runtime cache). */\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\n/** Build nested + flat pageContext fields for prepare / message bodies. */\nexport function buildPageContextRequestBody(\n pageContext: AgentChatPageContext,\n): Record<string, unknown> {\n const body: Record<string, unknown> = { pageContext };\n if (pageContext.page) body.page = pageContext.page;\n if (pageContext.routePath) body.routePath = pageContext.routePath;\n if (pageContext.routeParams) body.routeParams = pageContext.routeParams;\n if (pageContext.flowId != null) body.flowId = pageContext.flowId;\n if (pageContext.programName) body.programName = pageContext.programName;\n if (pageContext.entity) body.entity = pageContext.entity;\n if (pageContext.metadata) body.metadata = pageContext.metadata;\n return body;\n}\n\nfunction isContentFieldRejected(error: unknown): boolean {\n if (!(error instanceof AgentChatError)) return false;\n if (error.code !== 'TRANSPORT_FAILED') return false;\n const msg = error.message.toLowerCase();\n return msg.includes('property content should not exist');\n}\n\nfunction normalizeSessionId(sessionId: string): string {\n return sessionId.trim().toLowerCase();\n}\n\nexport class ChatService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n listSessions(\n page: number,\n size: number,\n signal?: AbortSignal,\n ): Promise<unknown> {\n return this.http.request('/chat', {\n method: 'GET',\n signal,\n searchParams: { page, size },\n });\n }\n\n getSession(\n sessionId: string,\n page: number,\n size: number,\n signal?: AbortSignal,\n ): Promise<unknown> {\n return this.http.request(`/chat/${normalizeSessionId(sessionId)}`, {\n method: 'GET',\n signal,\n searchParams: { page, size },\n });\n }\n\n prepareSession(\n sessionId: string,\n pageContext?: AgentChatPageContext | null,\n signal?: AbortSignal,\n ): Promise<PrepareSessionResult> {\n const body =\n pageContext && Object.keys(pageContext).length > 0\n ? buildPageContextRequestBody(pageContext)\n : undefined;\n return this.http.request(`/chat/${normalizeSessionId(sessionId)}/prepare`, {\n method: 'POST',\n body,\n signal,\n }) as Promise<PrepareSessionResult>;\n }\n\n deleteSession(sessionId: string): Promise<void> {\n return this.http.request(`/chat/${normalizeSessionId(sessionId)}`, {\n method: 'DELETE',\n });\n }\n\n streamSession(\n sessionId: string,\n init?: Omit<HttpStreamOptions, 'method'>,\n ): AsyncIterable<SseEventChunk> {\n return this.http.stream(`/chat/${normalizeSessionId(sessionId)}/stream`, init);\n }\n\n /** `GET /chat/{sessionId}/run-state` — authoritative session generation for SSE filtering. */\n getRunState(sessionId: string, signal?: AbortSignal): Promise<unknown> {\n return this.http.request(`/chat/${normalizeSessionId(sessionId)}/run-state`, {\n method: 'GET',\n signal,\n });\n }\n\n /** `POST /chat` — create session with the first user message. */\n createSession(\n content: string,\n signal: AbortSignal,\n context?: MessageSendContext,\n ): Promise<unknown> {\n return this.postUserPayload('/chat', content, signal, context);\n }\n\n /** `POST /chat/{sessionId}/messages` */\n postMessage(\n sessionId: string,\n content: string,\n signal: AbortSignal,\n context?: MessageSendContext,\n ): Promise<unknown> {\n return this.postUserPayload(`/chat/${sessionId}/messages`, content, signal, context);\n }\n\n postWriteGateDecision(\n sessionId: string,\n writeGate: WriteGate,\n signal: AbortSignal,\n ): Promise<unknown> {\n const path = `/chat/${normalizeSessionId(sessionId)}/messages`;\n const body = { role: 'user', content: '', writeGate };\n return this.postUserPayload(path, '', signal, undefined, body);\n }\n\n /** @deprecated Use `postWriteGateDecision` with `writeGate.action`. */\n postWriteConfirmation(\n sessionId: string,\n flags: { confirmWrite?: true; cancelWrite?: true },\n signal: AbortSignal,\n ): Promise<unknown> {\n const writeGate: WriteGate =\n flags.cancelWrite === true ? { action: 'cancel' } : { action: 'confirm' };\n return this.postWriteGateDecision(sessionId, writeGate, signal);\n }\n\n /** `POST /chat/{sessionId}/cancel-run` — stop the active agent run (SUPERSEDE). */\n async cancelRun(sessionId: string, runId?: number): Promise<CancelRunResult> {\n const body: Record<string, unknown> = {};\n if (runId != null) body.runId = runId;\n const response = await this.http.request(`/chat/${normalizeSessionId(sessionId)}/cancel-run`, {\n method: 'POST',\n body: Object.keys(body).length > 0 ? body : undefined,\n });\n return parseCancelRunResponse(response);\n }\n\n private async postUserPayload(\n path: string,\n text: string,\n signal: AbortSignal,\n context?: MessageSendContext,\n bodyOverride?: Record<string, unknown>,\n ): Promise<unknown> {\n const body = bodyOverride ?? this.buildUserMessageBody(text, context);\n try {\n return await this.http.request(path, {\n method: 'POST',\n body,\n signal,\n });\n } catch (error) {\n if (!isContentFieldRejected(error)) throw error;\n const { content, ...rest } = body;\n return this.http.request(path, {\n method: 'POST',\n body: { ...rest, message: content },\n signal,\n });\n }\n }\n\n private buildUserMessageBody(\n text: string,\n context?: MessageSendContext,\n ): Record<string, unknown> {\n const body: Record<string, unknown> = { role: 'user', content: text };\n const agentId = context?.agentId?.trim();\n const skillId = context?.skillId?.trim();\n if (agentId) {\n body.agentId = /^\\d+$/.test(agentId) ? Number(agentId) : agentId;\n }\n if (skillId) {\n body.skillId = /^\\d+$/.test(skillId) ? Number(skillId) : skillId;\n }\n const pageContext = pickPageContextFields(context);\n if (pageContext) {\n Object.assign(body, buildPageContextRequestBody(pageContext));\n }\n if (\n context?.entityCommit?.entityType?.trim() &&\n context?.entityCommit?.selectedId?.trim()\n ) {\n body.entityCommit = {\n entityType: context.entityCommit.entityType.trim(),\n selectedId: context.entityCommit.selectedId.trim(),\n };\n }\n return body;\n }\n}\n\nfunction pickPageContextFields(\n context?: MessageSendContext,\n): AgentChatPageContext | null {\n if (!context) return null;\n const pageContext: AgentChatPageContext = {};\n if (context.page) pageContext.page = context.page;\n if (context.routePath) pageContext.routePath = context.routePath;\n if (context.routeParams) pageContext.routeParams = context.routeParams;\n if (context.flowId != null) pageContext.flowId = context.flowId;\n if (context.programName) pageContext.programName = context.programName;\n if (context.entity) pageContext.entity = context.entity;\n if (context.metadata) pageContext.metadata = context.metadata;\n return Object.keys(pageContext).length > 0 ? pageContext : null;\n}\n","import { AgentChatError } from './errors';\nimport { unwrapApiData } from '../auth/auth-response';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object';\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\n/**\n * Unwrap `{ status, message, data }` from ReqInterceptor. Throws when\n * `status !== 200` even if HTTP status is 200.\n */\nexport function parseApiEnvelope<T>(body: unknown): T {\n if (!isRecord(body)) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid API response');\n }\n\n const status = readNumber(body.status);\n if (status !== undefined && status !== 200) {\n throw new AgentChatError(\n 'TRANSPORT_FAILED',\n readString(body.message) ?? 'request failed',\n { details: { status, data: body.data } },\n );\n }\n\n if ('data' in body && body.data === null) {\n return null as T;\n }\n\n const data = unwrapApiData(body);\n if (data !== null) return data as T;\n return body as T;\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport {\n parseDownReasonTags,\n parseMessageFeedbackBatch,\n parseMessageFeedbackView,\n} from '../chat/chat-response';\nimport type { HttpClient } from '../http';\nimport type {\n MessageFeedbackBatchData,\n MessageFeedbackDownReasonTag,\n MessageFeedbackView,\n UpsertMessageFeedbackBody,\n} from '../../types';\n\nfunction normalizeSessionId(sessionId: string): string {\n return sessionId.trim().toLowerCase();\n}\n\nexport class FeedbackService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `GET /chat/feedback/down-reason-tags` */\n async getDownReasonTags(signal?: AbortSignal): Promise<MessageFeedbackDownReasonTag[]> {\n const body = await this.http.request<unknown>('/chat/feedback/down-reason-tags', {\n method: 'GET',\n signal,\n });\n return parseDownReasonTags(parseApiEnvelope(body)).items;\n }\n\n /** `GET /chat/:sessionId/messages/feedbacks?messageIds=…` */\n async batchFeedbacks(\n sessionId: string,\n messageIds: number[],\n signal?: AbortSignal,\n ): Promise<MessageFeedbackBatchData> {\n if (messageIds.length === 0) return { items: [] };\n const body = await this.http.request<unknown>(\n `/chat/${normalizeSessionId(sessionId)}/messages/feedbacks`,\n {\n method: 'GET',\n signal,\n searchParams: { messageIds: messageIds.join(',') },\n },\n );\n return parseMessageFeedbackBatch(parseApiEnvelope(body));\n }\n\n /** `PUT /chat/:sessionId/messages/:messageId/feedback` */\n async upsert(\n sessionId: string,\n messageId: number,\n payload: UpsertMessageFeedbackBody,\n signal?: AbortSignal,\n ): Promise<MessageFeedbackView> {\n const body = await this.http.request<unknown>(\n `/chat/${normalizeSessionId(sessionId)}/messages/${messageId}/feedback`,\n {\n method: 'PUT',\n body: payload,\n signal,\n },\n );\n return parseMessageFeedbackView(parseApiEnvelope(body));\n }\n\n /** `DELETE /chat/:sessionId/messages/:messageId/feedback` */\n async remove(\n sessionId: string,\n messageId: number,\n signal?: AbortSignal,\n ): Promise<void> {\n const body = await this.http.request<unknown>(\n `/chat/${normalizeSessionId(sessionId)}/messages/${messageId}/feedback`,\n {\n method: 'DELETE',\n signal,\n },\n );\n parseApiEnvelope<null>(body);\n }\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport type { HttpClient } from '../http';\nimport type { HostToolDefinition } from '../../types';\n\nexport type HostToolRegisterBody = {\n scope?: string;\n pageLabel?: string;\n routePattern?: string;\n tools: Array<Omit<HostToolDefinition, 'handler'>>;\n};\n\nexport type HostToolRegisterItem = {\n name: string;\n id?: number;\n created?: boolean;\n reason?: string;\n};\n\nexport type HostToolRegisterResult = {\n created: HostToolRegisterItem[];\n skipped: HostToolRegisterItem[];\n};\n\nexport type HostToolCatalogQuery = {\n scope?: string;\n agentId?: number;\n};\n\nexport class HostToolService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `POST /host-tool/client/register` — idempotent metadata sync (no handler). */\n async register(body: HostToolRegisterBody): Promise<HostToolRegisterResult> {\n const raw = await this.http.request<unknown>('/host-tool/client/register', {\n method: 'POST',\n body,\n });\n const data = parseApiEnvelope<Partial<HostToolRegisterResult>>(raw);\n return {\n created: Array.isArray(data?.created) ? data.created : [],\n skipped: Array.isArray(data?.skipped) ? data.skipped : [],\n };\n }\n\n /** `GET /host-tool/client/catalog` — optional local vs server catalog check. */\n async getCatalog(query?: HostToolCatalogQuery): Promise<unknown> {\n const raw = await this.http.request<unknown>('/host-tool/client/catalog', {\n method: 'GET',\n searchParams: query,\n });\n return parseApiEnvelope(raw);\n }\n}\n","import type { HttpClient } from '../http';\n\n/** `GET /agent-run/by-app-client/:appClientId/:id` */\nexport class AgentRunService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n getRun(appClientId: number, runId: number, signal?: AbortSignal): Promise<unknown> {\n return this.http.request(`/agent-run/by-app-client/${appClientId}/${runId}`, {\n method: 'GET',\n signal,\n });\n }\n}\n","import type { AgentChatPageContext, AgentChatRouteContext } from '../../types';\n\nfunction isNonEmptyRecord(\n value: Record<string, string> | null | undefined,\n): value is Record<string, string> {\n return Boolean(value && Object.keys(value).length > 0);\n}\n\n/**\n * Build the pageContext snapshot written on PageAction invoke.\n * Prefer host-provided fields; fill missing route from {@link AgentChatRouteContext}.\n */\nexport function buildPageActionInvokePageContextSnapshot(input: {\n pageContext?: AgentChatPageContext | null;\n routeContext?: AgentChatRouteContext | null;\n}): AgentChatPageContext | undefined {\n const page = input.pageContext;\n const route = input.routeContext;\n const out: AgentChatPageContext = {};\n\n if (page?.page?.trim()) out.page = page.page.trim();\n if (page?.flowId != null) out.flowId = page.flowId;\n if (page?.programName?.trim()) out.programName = page.programName.trim();\n if (page?.entity) out.entity = page.entity;\n if (page?.metadata && Object.keys(page.metadata).length > 0) {\n out.metadata = page.metadata;\n }\n\n const routePath = page?.routePath?.trim() || route?.routePath?.trim();\n if (routePath) out.routePath = routePath;\n\n const routeParams =\n (isNonEmptyRecord(page?.routeParams) ? page!.routeParams : undefined) ??\n (isNonEmptyRecord(route?.routeParams) ? route!.routeParams : undefined);\n if (routeParams) out.routeParams = routeParams;\n\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/** Parse API / unknown JSON into {@link AgentChatPageContext} (best-effort). */\nexport function parseAgentChatPageContext(value: unknown): AgentChatPageContext | null {\n if (value == null) return null;\n if (typeof value !== 'object' || Array.isArray(value)) return null;\n const row = value as Record<string, unknown>;\n const out: AgentChatPageContext = {};\n\n if (typeof row.page === 'string' && row.page.trim()) out.page = row.page.trim();\n if (typeof row.routePath === 'string' && row.routePath.trim()) {\n out.routePath = row.routePath.trim();\n }\n if (typeof row.programName === 'string' && row.programName.trim()) {\n out.programName = row.programName.trim();\n }\n if (typeof row.flowId === 'number' && Number.isFinite(row.flowId)) {\n out.flowId = row.flowId;\n }\n\n if (row.routeParams && typeof row.routeParams === 'object' && !Array.isArray(row.routeParams)) {\n const params: Record<string, string> = {};\n for (const [key, raw] of Object.entries(row.routeParams as Record<string, unknown>)) {\n if (typeof raw === 'string') params[key] = raw;\n else if (typeof raw === 'number' || typeof raw === 'boolean') params[key] = String(raw);\n }\n if (Object.keys(params).length > 0) out.routeParams = params;\n }\n\n if (row.entity && typeof row.entity === 'object' && !Array.isArray(row.entity)) {\n out.entity = row.entity as AgentChatPageContext['entity'];\n }\n\n if (row.metadata && typeof row.metadata === 'object' && !Array.isArray(row.metadata)) {\n out.metadata = row.metadata as Record<string, unknown>;\n }\n\n return Object.keys(out).length > 0 ? out : null;\n}\n","import type {\n AutomationTaskDetail,\n AutomationTaskList,\n AutomationTaskListItem,\n AutomationTaskRef,\n AutomationTaskStatus,\n AutomationTaskTimelineEntry,\n AutomationTriggerSource,\n InvokePageActionAccepted,\n PageActionAlreadyActive,\n PageActionInvokeResult,\n PageActionReusableItem,\n PageActionReuseHint,\n} from '../../types';\nimport { parseAgentChatPageContext } from '../page/page-context-snapshot';\nimport { parseBrainClarifyPayload } from '../page/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 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 readTaskStatus(value: unknown): AutomationTaskStatus | undefined {\n const raw = readString(value);\n if (\n raw === 'running' ||\n raw === 'awaiting_approval' ||\n raw === 'completed' ||\n raw === 'failed' ||\n raw === 'cancelled'\n ) {\n return raw;\n }\n return undefined;\n}\n\nfunction readTriggerSource(value: unknown): AutomationTriggerSource | undefined {\n const raw = readString(value);\n if (raw === 'page_action' || raw === 'webhook') return raw;\n return undefined;\n}\n\nfunction parseTaskRef(value: unknown): AutomationTaskRef | null {\n if (!isRecord(value)) return null;\n const kind = readString(value.kind);\n const id = readNumber(value.id);\n if (id == null) return null;\n if (kind === 'page_action_run') return { kind: 'page_action_run', id };\n if (kind === 'webhook_approval') return { kind: 'webhook_approval', id };\n return null;\n}\n\nfunction parseOutputs(value: unknown): AutomationTaskListItem['outputs'] {\n if (!isRecord(value)) {\n return { preview: null, hasFillText: false };\n }\n const preview =\n value.preview === null ? null : (readString(value.preview) ?? null);\n return {\n preview,\n hasFillText: value.hasFillText === true,\n };\n}\n\nfunction parseApproval(value: unknown): AutomationTaskListItem['approval'] {\n if (!isRecord(value)) return null;\n const id = readNumber(value.id);\n const status = readString(value.status);\n if (id == null || !status) return null;\n return { id, status };\n}\n\nfunction parseTimelineEntry(value: unknown): AutomationTaskTimelineEntry | null {\n if (!isRecord(value)) return null;\n const step = readNumber(value.step);\n const type = readString(value.type);\n const name = readString(value.name);\n const at = readString(value.at);\n if (step == null || !type || !name || !at) return null;\n const status = readString(value.status);\n return {\n step,\n type,\n name,\n at,\n ...(status === 'ok' || status === 'failed' || status === 'skipped'\n ? { status }\n : {}),\n };\n}\n\nfunction parseListItem(row: unknown): AutomationTaskListItem | null {\n if (!isRecord(row)) return null;\n const ref = parseTaskRef(row.ref);\n const triggerSource = readTriggerSource(row.triggerSource);\n const taskStatus = readTaskStatus(row.taskStatus);\n const title = readString(row.title);\n const createdAt = readString(row.createdAt);\n if (!ref || !triggerSource || !taskStatus || !title || !createdAt) return null;\n return {\n ref,\n triggerSource,\n taskStatus,\n title,\n subtitle: row.subtitle === null ? null : (readString(row.subtitle) ?? null),\n workflowKey: row.workflowKey === null ? null : (readString(row.workflowKey) ?? null),\n workflowName:\n row.workflowName === null ? null : (readString(row.workflowName) ?? null),\n pageActionKey: row.pageActionKey === null ? null : (readString(row.pageActionKey) ?? null),\n createdAt,\n finishedAt: row.finishedAt === null ? null : (readString(row.finishedAt) ?? null),\n durationMs: row.durationMs === null ? null : (readNumber(row.durationMs) ?? null),\n approval: parseApproval(row.approval),\n outputs: parseOutputs(row.outputs),\n };\n}\n\n/** Parse `GET /automation/tasks` body. */\nexport function parseAutomationTaskList(body: unknown, limit = 20): AutomationTaskList {\n const record = isRecord(body) ? body : null;\n const total = readNumber(record?.total) ?? readNumber(record?.totalCount) ?? 0;\n const itemsRaw = Array.isArray(record?.items) ? record.items : [];\n const items = itemsRaw\n .map((row) => parseListItem(row))\n .filter((row): row is AutomationTaskListItem => row != null);\n return {\n items,\n total,\n hasMore: resolveAutomationTaskListHasMore(items.length, items.length, total, limit),\n };\n}\n\n/** Whether more pages exist after merging the latest page into the loaded list. */\nexport function resolveAutomationTaskListHasMore(\n loadedItemCount: number,\n pageItemCount: number,\n total: number,\n limit: number,\n): boolean {\n if (total > 0) return loadedItemCount < total;\n return pageItemCount >= limit;\n}\n\nfunction parseReplayBlock(\n raw: unknown,\n base: AutomationTaskListItem,\n body: Record<string, unknown>,\n): AutomationTaskDetail['replay'] {\n if (isRecord(raw)) {\n return {\n canReplay: raw.canReplay === true,\n hasHostAction: raw.hasHostAction === true,\n dslOutcome: typeof raw.dslOutcome === 'string' ? raw.dslOutcome : null,\n };\n }\n const hasFillText = Boolean(base.outputs?.hasFillText);\n return {\n canReplay: base.taskStatus === 'completed' && hasFillText,\n hasHostAction: hasFillText,\n dslOutcome: typeof body.dslOutcome === 'string' ? body.dslOutcome : null,\n };\n}\n\n/** Parse `GET /automation/tasks/page_action_run/:id` body. */\nexport function parseAutomationTaskDetail(body: unknown): AutomationTaskDetail | null {\n if (!isRecord(body)) return null;\n const base = parseListItem(body);\n if (!base) return null;\n const actionKey = readString(body.actionKey);\n const streamUrl = readString(body.streamUrl);\n if (!actionKey || !streamUrl) return null;\n const timelineRaw = Array.isArray(body.timeline) ? body.timeline : [];\n const timeline = timelineRaw\n .map((row) => parseTimelineEntry(row))\n .filter((row): row is AutomationTaskTimelineEntry => row != null);\n return {\n ...base,\n actionKey,\n instruction: body.instruction === null ? null : (readString(body.instruction) ?? null),\n errorCode: body.errorCode === null ? null : (readString(body.errorCode) ?? null),\n errorMessage:\n body.errorMessage === null ? null : (readString(body.errorMessage) ?? null),\n streamUrl,\n timeline,\n workflowRun: body.workflowRun ?? null,\n brainClarify: parseBrainClarifyPayload(body.brainClarify),\n pageContext:\n body.pageContext === null || body.pageContext === undefined\n ? null\n : parseAgentChatPageContext(body.pageContext),\n replay: parseReplayBlock(body.replay, base, body),\n };\n}\n\n/** Parse `POST /page-action/brain-invoke` accepted payload. */\nexport function parseInvokePageActionAccepted(body: unknown): InvokePageActionAccepted {\n if (!isRecord(body)) {\n throw new Error('Invalid page-action invoke response');\n }\n const runId = readNumber(body.runId);\n const generation = readNumber(body.generation);\n const streamUrl = readString(body.streamUrl);\n const status = readTaskStatus(body.status);\n if (runId == null || generation == null || !streamUrl || !status) {\n throw new Error('Invalid page-action invoke response');\n }\n return {\n runId,\n generation,\n clientActionId:\n body.clientActionId === null\n ? null\n : (readString(body.clientActionId) ?? null),\n pageActionKey: body.pageActionKey === null ? null : (readString(body.pageActionKey) ?? null),\n streamUrl,\n status,\n };\n}\n\nfunction parseExistingStatus(\n value: unknown,\n): 'running' | 'awaiting_approval' | undefined {\n const raw = readString(value);\n if (raw === 'running' || raw === 'awaiting_approval') return raw;\n return undefined;\n}\n\n/** Parse `POST /page-action/brain-invoke` conflict payload (`PAGE_ACTION_ALREADY_ACTIVE`). */\nexport function parsePageActionAlreadyActive(body: unknown): PageActionAlreadyActive {\n if (!isRecord(body)) {\n throw new Error('Invalid page-action already-active response');\n }\n const code = readString(body.code);\n const pageActionKey = readString(body.pageActionKey);\n const existingRunId = readNumber(body.existingRunId);\n const existingStatus = parseExistingStatus(body.existingStatus);\n const streamUrl = readString(body.streamUrl);\n if (\n code !== 'PAGE_ACTION_ALREADY_ACTIVE' ||\n !pageActionKey ||\n existingRunId == null ||\n !existingStatus ||\n !streamUrl\n ) {\n throw new Error('Invalid page-action already-active response');\n }\n const approvalRequestId = readNumber(body.approvalRequestId);\n return {\n code: 'PAGE_ACTION_ALREADY_ACTIVE',\n message: readString(body.message) ?? 'An active PageAction run already exists',\n pageActionKey,\n existingRunId,\n existingStatus,\n approvalRequestId: approvalRequestId ?? null,\n streamUrl,\n };\n}\n\n/** Parse invoke envelope — accepted (200) or already active (409). */\nexport function parsePageActionInvokeResult(body: unknown): PageActionInvokeResult {\n if (!isRecord(body)) {\n throw new Error('Invalid page-action invoke response');\n }\n const status = readNumber(body.status);\n if (status === 409) {\n return { kind: 'already_active', ...parsePageActionAlreadyActive(body.data) };\n }\n if (status !== undefined && status !== 200) {\n throw new Error(readString(body.message) ?? 'page-action invoke failed');\n }\n const data = isRecord(body.data) ? body.data : body;\n return { kind: 'accepted', ...parseInvokePageActionAccepted(data) };\n}\n\nfunction parseReusableItem(row: unknown): PageActionReusableItem | null {\n if (!isRecord(row)) return null;\n const ref = parseTaskRef(row.ref);\n const triggerSource = readTriggerSource(row.triggerSource);\n const taskStatus = readTaskStatus(row.taskStatus);\n const title = readString(row.title);\n const createdAt = readString(row.createdAt);\n if (!ref || ref.kind !== 'page_action_run' || !triggerSource || !taskStatus || !title || !createdAt) {\n return null;\n }\n const outputsRaw = isRecord(row.outputs) ? row.outputs : null;\n const preview =\n outputsRaw?.preview === null ? null : (readString(outputsRaw?.preview) ?? null);\n const fillText =\n outputsRaw?.fillText === null ? null : (readString(outputsRaw?.fillText) ?? null);\n const runUserId = readNumber(row.runUserId);\n return {\n ref,\n triggerSource,\n taskStatus,\n title,\n subtitle: row.subtitle === null ? null : (readString(row.subtitle) ?? null),\n pageActionKey:\n row.pageActionKey === null ? null : (readString(row.pageActionKey) ?? null),\n createdAt,\n finishedAt: row.finishedAt === null ? null : (readString(row.finishedAt) ?? null),\n outputs: {\n preview,\n fillText: fillText ?? undefined,\n hasFillText: outputsRaw?.hasFillText === true || Boolean(fillText?.trim()),\n },\n ...(row.succeeded === true || row.succeeded === false ? { succeeded: row.succeeded } : {}),\n ...(runUserId != null ? { runUserId } : {}),\n };\n}\n\n/** Parse `POST /page-action/reuse-hint` body. */\nexport function parsePageActionReuseHint(body: unknown): PageActionReuseHint {\n const root = isRecord(body) ? body : null;\n if (!root) {\n throw new Error('Invalid page-action reuse-hint response');\n }\n\n // Envelope `{ status, data }` — non-200 (e.g. route missing) must not look like a hint.\n const envelopeStatus = readNumber(root.status);\n if (envelopeStatus !== undefined && envelopeStatus !== 200) {\n throw new Error(\n readString(root.message) ?? `page-action reuse-hint failed (${envelopeStatus})`,\n );\n }\n\n const data = isRecord(root.data) ? root.data : root;\n const pageActionKey = readString(data.pageActionKey);\n const actionKey = readString(data.actionKey);\n if (!pageActionKey || !actionKey) {\n throw new Error('Invalid page-action reuse-hint response');\n }\n const reusableRaw = isRecord(data.reusable) ? data.reusable : null;\n const itemsRaw = Array.isArray(reusableRaw?.items) ? reusableRaw.items : [];\n const items = itemsRaw\n .map((row) => parseReusableItem(row))\n .filter((row): row is PageActionReusableItem => row != null);\n const total = readNumber(reusableRaw?.total) ?? items.length;\n return {\n pageActionKey,\n actionKey,\n reusable: { total, items },\n };\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport type {\n PageActionCatalogMyFeedback,\n PageActionFeedbackCatalogItem,\n PageActionFeedbackSummary,\n PageActionFeedbackView,\n PageActionRolloutCheckItem,\n PageActionWishList,\n PageActionWishStatus,\n PageActionWishView,\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 | 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\nconst WISH_STATUSES: ReadonlySet<string> = new Set([\n 'submitted',\n 'reviewing',\n 'planned',\n 'in_progress',\n 'done',\n 'rejected',\n 'cancelled',\n]);\n\nfunction readWishStatus(value: unknown): PageActionWishStatus | undefined {\n const raw = readString(value);\n if (raw && WISH_STATUSES.has(raw)) return raw as PageActionWishStatus;\n return undefined;\n}\n\nfunction parseCatalogMyFeedback(raw: unknown): PageActionCatalogMyFeedback | null {\n if (raw == null) return null;\n if (!isRecord(raw)) return null;\n const rating = readNumber(raw.rating);\n const updatedAt = readString(raw.updatedAt);\n if (rating == null || rating < 1 || rating > 5 || !updatedAt) return null;\n return {\n rating,\n comment: raw.comment === null ? null : (readString(raw.comment) ?? null),\n updatedAt,\n };\n}\n\nfunction parseCatalogItem(raw: unknown): PageActionFeedbackCatalogItem | null {\n if (!isRecord(raw)) return null;\n const actionKey = readString(raw.actionKey);\n const name = readString(raw.name);\n const pageActionId = readNumber(raw.pageActionId);\n if (!actionKey || !name || pageActionId == null) return null;\n return {\n pageActionId,\n actionKey,\n name,\n description: raw.description === null ? null : (readString(raw.description) ?? null),\n pageScope: raw.pageScope === null ? null : (readString(raw.pageScope) ?? null),\n sortOrder: readNumber(raw.sortOrder) ?? 0,\n rolloutRestricted: raw.rolloutRestricted === true,\n myFeedback: parseCatalogMyFeedback(raw.myFeedback),\n };\n}\n\nfunction parseRolloutCheckItem(raw: unknown): PageActionRolloutCheckItem | null {\n if (!isRecord(raw)) return null;\n const actionKey = readString(raw.actionKey);\n if (!actionKey || typeof raw.allowed !== 'boolean') return null;\n const reason = readString(raw.reason) ?? (raw.allowed ? 'open' : 'denied');\n return { actionKey, allowed: raw.allowed, reason };\n}\n\n/** Parse `POST /page-action/rollout-check` (`data.items`). */\nexport function parsePageActionRolloutCheck(body: unknown): PageActionRolloutCheckItem[] {\n const data = parseApiEnvelope<unknown>(body);\n const rows = Array.isArray(data)\n ? data\n : isRecord(data) && Array.isArray(data.items)\n ? data.items\n : [];\n const seen = new Set<string>();\n const items: PageActionRolloutCheckItem[] = [];\n for (const row of rows) {\n const item = parseRolloutCheckItem(row);\n if (!item || seen.has(item.actionKey)) continue;\n seen.add(item.actionKey);\n items.push(item);\n }\n return items;\n}\n\nfunction parseFeedbackView(raw: unknown): PageActionFeedbackView | null {\n if (!isRecord(raw)) return null;\n const id = readNumber(raw.id);\n const pageActionId = readNumber(raw.pageActionId);\n const actionKey = readString(raw.actionKey);\n const pageActionName = readString(raw.pageActionName);\n const appClientId = readNumber(raw.appClientId);\n const userId = readNumber(raw.userId);\n const rating = readNumber(raw.rating);\n const createdAt = readString(raw.createdAt);\n const updatedAt = readString(raw.updatedAt);\n if (\n id == null ||\n pageActionId == null ||\n !actionKey ||\n !pageActionName ||\n appClientId == null ||\n userId == null ||\n rating == null ||\n !createdAt ||\n !updatedAt\n ) {\n return null;\n }\n return {\n id,\n pageActionId,\n actionKey,\n pageActionName,\n appClientId,\n userId,\n rating,\n comment: raw.comment === null ? null : (readString(raw.comment) ?? null),\n createdAt,\n updatedAt,\n };\n}\n\nfunction emptyDistribution(): PageActionFeedbackSummary['ratingDistribution'] {\n return { '1': 0, '2': 0, '3': 0, '4': 0, '5': 0 };\n}\n\nfunction parseDistribution(\n raw: unknown,\n): PageActionFeedbackSummary['ratingDistribution'] {\n const base = emptyDistribution();\n if (!isRecord(raw)) return base;\n for (const key of ['1', '2', '3', '4', '5'] as const) {\n const n = readNumber(raw[key]);\n if (n != null) base[key] = n;\n }\n return base;\n}\n\nfunction parseFeedbackSummary(raw: unknown): PageActionFeedbackSummary | null {\n if (!isRecord(raw)) return null;\n const pageActionId = readNumber(raw.pageActionId);\n const actionKey = readString(raw.actionKey);\n const pageActionName = readString(raw.pageActionName);\n const count = readNumber(raw.count);\n if (pageActionId == null || !actionKey || !pageActionName || count == null) {\n return null;\n }\n const avg =\n raw.avgRating === null || raw.avgRating === undefined\n ? null\n : (readNumber(raw.avgRating) ?? null);\n return {\n pageActionId,\n actionKey,\n pageActionName,\n count,\n avgRating: avg,\n ratingDistribution: parseDistribution(raw.ratingDistribution),\n };\n}\n\nfunction parseWishView(raw: unknown): PageActionWishView | null {\n if (!isRecord(raw)) return null;\n const id = readNumber(raw.id);\n const appClientId = readNumber(raw.appClientId);\n const userId = readNumber(raw.userId);\n const title = readString(raw.title);\n const description = readString(raw.description);\n const status = readWishStatus(raw.status);\n const createdAt = readString(raw.createdAt);\n const updatedAt = readString(raw.updatedAt);\n if (\n id == null ||\n appClientId == null ||\n userId == null ||\n !title ||\n !description ||\n !status ||\n !createdAt ||\n !updatedAt\n ) {\n return null;\n }\n return {\n id,\n appClientId,\n userId,\n title,\n description,\n pageScope: raw.pageScope === null ? null : (readString(raw.pageScope) ?? null),\n relatedActionKey:\n raw.relatedActionKey === null\n ? null\n : (readString(raw.relatedActionKey) ?? null),\n status,\n developerNote:\n raw.developerNote === null ? null : (readString(raw.developerNote) ?? null),\n statusUpdatedAt:\n raw.statusUpdatedAt === null\n ? null\n : (readString(raw.statusUpdatedAt) ?? null),\n createdAt,\n updatedAt,\n };\n}\n\n/** Parse `GET /page-action/catalog` (`data.items`; keep server sort order). */\nexport function parsePageActionFeedbackCatalog(body: unknown): PageActionFeedbackCatalogItem[] {\n const data = parseApiEnvelope<unknown>(body);\n const rows = Array.isArray(data)\n ? data\n : isRecord(data) && Array.isArray(data.items)\n ? data.items\n : [];\n const seen = new Set<string>();\n const items: PageActionFeedbackCatalogItem[] = [];\n for (const row of rows) {\n const item = parseCatalogItem(row);\n if (!item || seen.has(item.actionKey)) continue;\n seen.add(item.actionKey);\n items.push(item);\n }\n return items;\n}\n\n/** Parse `GET|PUT /page-action/feedback/:actionKey` (`data` may be null). */\nexport function parsePageActionFeedbackView(body: unknown): PageActionFeedbackView | null {\n const data = parseApiEnvelope<unknown>(body);\n if (data == null) return null;\n return parseFeedbackView(data);\n}\n\n/** Parse `GET /page-action/feedback/:actionKey/summary`. */\nexport function parsePageActionFeedbackSummary(body: unknown): PageActionFeedbackSummary {\n const data = parseApiEnvelope<unknown>(body);\n const parsed = parseFeedbackSummary(data);\n if (!parsed) {\n throw new Error('Invalid page-action feedback summary');\n }\n return parsed;\n}\n\n/** Parse wish create / detail / cancel. */\nexport function parsePageActionWishView(body: unknown): PageActionWishView {\n const data = parseApiEnvelope<unknown>(body);\n const parsed = parseWishView(data);\n if (!parsed) {\n throw new Error('Invalid page-action wish');\n }\n return parsed;\n}\n\n/** Parse `GET /page-action/wishes` paginated list. */\nexport function parsePageActionWishList(body: unknown): PageActionWishList {\n const data = parseApiEnvelope<unknown>(body);\n if (!isRecord(data)) {\n return { items: [], total: 0, page: 1, pageSize: 20, hasMore: false };\n }\n const itemsRaw = Array.isArray(data.items) ? data.items : [];\n const items = itemsRaw\n .map((row) => parseWishView(row))\n .filter((row): row is PageActionWishView => row != null);\n const total = readNumber(data.total) ?? items.length;\n const page = readNumber(data.page) ?? 1;\n const pageSize = readNumber(data.pageSize) ?? 20;\n const hasMore =\n typeof data.hasMore === 'boolean'\n ? data.hasMore\n : page * pageSize < total;\n return { items, total, page, pageSize, hasMore };\n}\n","import { AgentChatError } from '../lib/errors';\nimport {\n parsePageActionAlreadyActive,\n parsePageActionInvokeResult,\n parsePageActionReuseHint,\n} from '../automation/automation-response';\nimport {\n parsePageActionFeedbackCatalog,\n parsePageActionFeedbackSummary,\n parsePageActionFeedbackView,\n parsePageActionRolloutCheck,\n parsePageActionWishList,\n parsePageActionWishView,\n} from '../page/page-action-feedback-wish-response';\nimport type { HttpClient } from '../http';\nimport type {\n CreatePageActionWishInput,\n InvokePageActionRequest,\n PageActionFeedbackCatalogItem,\n PageActionFeedbackCatalogQuery,\n PageActionFeedbackSummary,\n PageActionFeedbackView,\n PageActionInvokeResult,\n PageActionReuseHint,\n PageActionRolloutCheckItem,\n PageActionWishList,\n PageActionWishQuery,\n PageActionWishView,\n UpsertPageActionFeedbackInput,\n} from '../../types';\n\nfunction encodeActionKeyPath(actionKey: string): string {\n return encodeURIComponent(actionKey.trim());\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Map HTTP 409 / TRANSPORT_FAILED carrying `PAGE_ACTION_ALREADY_ACTIVE` to a soft\n * invoke result — never throw that conflict to host PageAction buttons.\n */\nfunction tryParseAlreadyActiveFromTransportError(\n err: unknown,\n): PageActionInvokeResult | null {\n if (!(err instanceof AgentChatError) || err.code !== 'TRANSPORT_FAILED') {\n return null;\n }\n const details = err.details;\n if (!isRecord(details)) return null;\n const envelopeStatus = details.status;\n if (envelopeStatus !== 409) return null;\n\n const candidates: unknown[] = [];\n if (details.data != null) candidates.push(details.data);\n if (isRecord(details.body)) {\n if (details.body.data != null) candidates.push(details.body.data);\n candidates.push(details.body);\n }\n\n for (const candidate of candidates) {\n if (!isRecord(candidate)) continue;\n try {\n if (candidate.code === 'PAGE_ACTION_ALREADY_ACTIVE') {\n return { kind: 'already_active', ...parsePageActionAlreadyActive(candidate) };\n }\n // Envelope-shaped `{ status: 409, data: { code: ... } }`\n if (isRecord(candidate.data) && candidate.data.code === 'PAGE_ACTION_ALREADY_ACTIVE') {\n return {\n kind: 'already_active',\n ...parsePageActionAlreadyActive(candidate.data),\n };\n }\n } catch {\n /* try next candidate */\n }\n }\n\n // Last resort: serverCode alone (body may have been partially parsed).\n if (details.serverCode === 'PAGE_ACTION_ALREADY_ACTIVE' && isRecord(details.data)) {\n try {\n return { kind: 'already_active', ...parsePageActionAlreadyActive(details.data) };\n } catch {\n return null;\n }\n }\n return null;\n}\n\n/** PageAction C-end APIs (`/page-action/*`). */\nexport class PageActionService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `POST /page-action/brain-invoke` — accepted or `PAGE_ACTION_ALREADY_ACTIVE`. */\n async invoke(\n body: InvokePageActionRequest,\n signal?: AbortSignal,\n ): Promise<PageActionInvokeResult> {\n try {\n const response = await this.http.request<unknown>('/page-action/brain-invoke', {\n method: 'POST',\n signal,\n body,\n });\n return parsePageActionInvokeResult(response);\n } catch (err) {\n const soft = tryParseAlreadyActiveFromTransportError(err);\n if (soft) return soft;\n throw err;\n }\n }\n\n /**\n * `POST /page-action/reuse-hint` — same entity key as invoke; no run created.\n * Returns recent successful runs (same App, cross-user when scope=app).\n */\n async reuseHint(\n body: InvokePageActionRequest,\n signal?: AbortSignal,\n ): Promise<PageActionReuseHint> {\n const response = await this.http.request<unknown>('/page-action/reuse-hint', {\n method: 'POST',\n signal,\n body,\n });\n return parsePageActionReuseHint(response);\n }\n\n /** @deprecated Use {@link invoke}. */\n async invokeAccepted(\n body: InvokePageActionRequest,\n signal?: AbortSignal,\n ): Promise<PageActionInvokeResult> {\n return this.invoke(body, signal);\n }\n\n /** `GET /page-action/runs/:runId/stream` — SSE lifecycle + host_action. */\n streamRun(runId: number, signal?: AbortSignal) {\n return this.http.stream(`/page-action/runs/${runId}/stream`, { signal });\n }\n\n /** `GET /page-action/catalog` — enabled PageActions for this App (no run). */\n async listCatalog(\n query: PageActionFeedbackCatalogQuery = {},\n signal?: AbortSignal,\n ): Promise<PageActionFeedbackCatalogItem[]> {\n const pageScope = query.pageScope?.trim();\n const response = await this.http.request<unknown>('/page-action/catalog', {\n method: 'GET',\n signal,\n searchParams: pageScope ? { pageScope } : undefined,\n });\n return parsePageActionFeedbackCatalog(response);\n }\n\n /**\n * `POST /page-action/rollout-check` — for hardcoded actionKey entry points.\n * Catalog UIs do not need this (server already filters).\n */\n async checkRollout(\n actionKeys: string[],\n signal?: AbortSignal,\n ): Promise<PageActionRolloutCheckItem[]> {\n const keys = Array.from(\n new Set(\n actionKeys\n .map((key) => key.trim())\n .filter((key) => key.length > 0),\n ),\n );\n if (keys.length === 0) return [];\n const response = await this.http.request<unknown>('/page-action/rollout-check', {\n method: 'POST',\n signal,\n body: { actionKeys: keys },\n });\n return parsePageActionRolloutCheck(response);\n }\n\n /** `PUT /page-action/feedback/:actionKey` — upsert my rating. */\n async upsertFeedback(\n actionKey: string,\n body: UpsertPageActionFeedbackInput,\n signal?: AbortSignal,\n ): Promise<PageActionFeedbackView> {\n const response = await this.http.request<unknown>(\n `/page-action/feedback/${encodeActionKeyPath(actionKey)}`,\n { method: 'PUT', signal, body },\n );\n const parsed = parsePageActionFeedbackView(response);\n if (!parsed) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid feedback response');\n }\n return parsed;\n }\n\n /** `GET /page-action/feedback/:actionKey` — my rating (`null` if none). */\n async getMyFeedback(\n actionKey: string,\n signal?: AbortSignal,\n ): Promise<PageActionFeedbackView | null> {\n const response = await this.http.request<unknown>(\n `/page-action/feedback/${encodeActionKeyPath(actionKey)}`,\n { method: 'GET', signal },\n );\n return parsePageActionFeedbackView(response);\n }\n\n /** `DELETE /page-action/feedback/:actionKey`. */\n async removeMyFeedback(actionKey: string, signal?: AbortSignal): Promise<void> {\n await this.http.request<unknown>(\n `/page-action/feedback/${encodeActionKeyPath(actionKey)}`,\n { method: 'DELETE', signal },\n );\n }\n\n /** `GET /page-action/feedback/:actionKey/summary`. */\n async getFeedbackSummary(\n actionKey: string,\n signal?: AbortSignal,\n ): Promise<PageActionFeedbackSummary> {\n const response = await this.http.request<unknown>(\n `/page-action/feedback/${encodeActionKeyPath(actionKey)}/summary`,\n { method: 'GET', signal },\n );\n return parsePageActionFeedbackSummary(response);\n }\n\n /** `POST /page-action/wishes`. */\n async createWish(\n body: CreatePageActionWishInput,\n signal?: AbortSignal,\n ): Promise<PageActionWishView> {\n const response = await this.http.request<unknown>('/page-action/wishes', {\n method: 'POST',\n signal,\n body,\n });\n return parsePageActionWishView(response);\n }\n\n /** `GET /page-action/wishes`. */\n async listWishes(\n query: PageActionWishQuery = {},\n signal?: AbortSignal,\n ): Promise<PageActionWishList> {\n const searchParams: Record<string, string | number> = {};\n if (query.page != null) searchParams.page = query.page;\n if (query.pageSize != null) searchParams.pageSize = query.pageSize;\n if (query.status) searchParams.status = query.status;\n if (query.keyword) searchParams.keyword = query.keyword;\n if (query.pageScope) searchParams.pageScope = query.pageScope;\n if (query.relatedActionKey) searchParams.relatedActionKey = query.relatedActionKey;\n const response = await this.http.request<unknown>('/page-action/wishes', {\n method: 'GET',\n signal,\n searchParams,\n });\n return parsePageActionWishList(response);\n }\n\n /** `GET /page-action/wishes/:id`. */\n async getWish(id: number, signal?: AbortSignal): Promise<PageActionWishView> {\n const response = await this.http.request<unknown>(`/page-action/wishes/${id}`, {\n method: 'GET',\n signal,\n });\n return parsePageActionWishView(response);\n }\n\n /** `PATCH /page-action/wishes/:id/cancel`. */\n async cancelWish(id: number, signal?: AbortSignal): Promise<PageActionWishView> {\n const response = await this.http.request<unknown>(\n `/page-action/wishes/${id}/cancel`,\n { method: 'PATCH', signal },\n );\n return parsePageActionWishView(response);\n }\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport {\n parseAutomationTaskDetail,\n parseAutomationTaskList,\n} from '../automation/automation-response';\nimport type { HttpClient } from '../http';\nimport type {\n AutomationTaskDetail,\n AutomationTaskList,\n AutomationTaskStatusFilter,\n AutomationTriggerSourceFilter,\n} from '../../types';\n\nexport interface AutomationTaskQuery {\n status?: AutomationTaskStatusFilter;\n triggerSource?: AutomationTriggerSourceFilter;\n actionKey?: string;\n workflowKey?: string;\n limit?: number;\n offset?: number;\n signal?: AbortSignal;\n}\n\nexport class AutomationService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `GET /automation/tasks` */\n async listTasks(query: AutomationTaskQuery = {}): Promise<AutomationTaskList> {\n const limit = query.limit ?? 20;\n const searchParams: Record<string, string> = {\n limit: String(limit),\n offset: String(query.offset ?? 0),\n };\n if (query.status) searchParams.status = query.status;\n if (query.triggerSource) searchParams.triggerSource = query.triggerSource;\n if (query.actionKey?.trim()) searchParams.actionKey = query.actionKey.trim();\n if (query.workflowKey?.trim()) searchParams.workflowKey = query.workflowKey.trim();\n const body = await this.http.request<unknown>('/automation/tasks', {\n method: 'GET',\n signal: query.signal,\n searchParams,\n });\n return parseAutomationTaskList(parseApiEnvelope(body), limit);\n }\n\n /** `GET /automation/tasks/page_action_run/:id` */\n async getPageActionRunTask(\n id: number,\n signal?: AbortSignal,\n ): Promise<AutomationTaskDetail | null> {\n const body = await this.http.request<unknown>(\n `/automation/tasks/page_action_run/${id}`,\n {\n method: 'GET',\n signal,\n },\n );\n return parseAutomationTaskDetail(parseApiEnvelope(body));\n }\n}\n","import { parseApiEnvelope } from '../lib/api-envelope';\nimport {\n parseApprovalConfirmResult,\n parseApprovalDecideResult,\n parseApprovalDetail,\n parseApprovalInboxList,\n parseApprovalRejectResult,\n} from '../approval/approval-response';\nimport type { HttpClient } from '../http';\nimport type {\n ApprovalConfirmResult,\n ApprovalDecideResult,\n ApprovalDetail,\n ApprovalInboxList,\n ApprovalInboxStatusFilter,\n ApprovalRejectResult,\n DraftReviewDecision,\n} from '../../types';\n\nexport interface ApprovalInboxQuery {\n status?: ApprovalInboxStatusFilter;\n limit?: number;\n offset?: number;\n signal?: AbortSignal;\n}\n\nexport class ApprovalService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `GET /approval/inbox` — page_action / webhook items for current user. */\n async listInbox(query: ApprovalInboxQuery = {}): Promise<ApprovalInboxList> {\n const limit = query.limit ?? 50;\n const searchParams: Record<string, string> = {\n limit: String(limit),\n offset: String(query.offset ?? 0),\n };\n if (query.status) searchParams.status = query.status;\n const body = await this.http.request<unknown>('/approval/inbox', {\n method: 'GET',\n signal: query.signal,\n searchParams,\n });\n return parseApprovalInboxList(parseApiEnvelope(body), limit);\n }\n\n /** `GET /approval/:id` */\n async getById(id: number, signal?: AbortSignal): Promise<ApprovalDetail | null> {\n const body = await this.http.request<unknown>(`/approval/${id}`, {\n method: 'GET',\n signal,\n });\n return parseApprovalDetail(parseApiEnvelope(body));\n }\n\n /** `POST /approval/:id/decide` */\n async decide(\n id: number,\n decision: DraftReviewDecision,\n reason?: string,\n signal?: AbortSignal,\n ): Promise<ApprovalDecideResult> {\n const body: Record<string, unknown> = { decision };\n if (reason?.trim()) body.reason = reason.trim();\n const response = await this.http.request<unknown>(`/approval/${id}/decide`, {\n method: 'POST',\n signal,\n body,\n });\n return parseApprovalDecideResult(parseApiEnvelope(response));\n }\n\n /** `POST /approval/:id/confirm` */\n async confirm(id: number, signal?: AbortSignal): Promise<ApprovalConfirmResult> {\n const body = await this.http.request<unknown>(`/approval/${id}/confirm`, {\n method: 'POST',\n signal,\n });\n return parseApprovalConfirmResult(parseApiEnvelope(body));\n }\n\n /** `POST /approval/:id/reject` */\n async reject(\n id: number,\n reason?: string,\n signal?: AbortSignal,\n ): Promise<ApprovalRejectResult> {\n const body = await this.http.request<unknown>(`/approval/${id}/reject`, {\n method: 'POST',\n signal,\n body: reason?.trim() ? { reason: reason.trim() } : {},\n });\n return parseApprovalRejectResult(parseApiEnvelope(body));\n }\n}\n","import { AgentChatError } from '../lib/errors';\nimport { parseApiEnvelope } from '../lib/api-envelope';\nimport type { HttpClient } from '../http';\n\n/** `GET /app/tools/callable` 单项 — 用 `definitionKey` 调用,勿硬编码 `toolId`。 */\nexport type AppToolCallableItem = {\n definitionKey: string;\n name: string;\n description: string;\n riskLevel: string;\n method: string;\n path: string;\n inputSchema: unknown;\n /** 仅调试用 */\n toolId: number;\n};\n\nexport type AppToolCallableList = {\n items: AppToolCallableItem[];\n};\n\n/** `POST /app/tools/invoke` 结果(含下游非 2xx 的结构化失败)。 */\nexport type AppToolInvokeResult = {\n ok: boolean;\n definitionKey: string;\n toolId: number;\n name: string;\n latencyMs: number;\n output: unknown;\n httpStatus?: number;\n error?: string;\n};\n\nexport type AppToolInvokeInput = {\n definitionKey: string;\n parameters?: Record<string, unknown>;\n signal?: AbortSignal;\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() ? 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 parseCallableItem(raw: unknown): AppToolCallableItem | null {\n if (!isRecord(raw)) return null;\n const definitionKey = readString(raw.definitionKey);\n const name = readString(raw.name);\n const toolId = readNumber(raw.toolId);\n if (!definitionKey || !name || toolId === undefined) return null;\n return {\n definitionKey,\n name,\n description: readString(raw.description) ?? '',\n riskLevel: readString(raw.riskLevel) ?? 'L1',\n method: readString(raw.method) ?? '',\n path: readString(raw.path) ?? '',\n inputSchema: raw.inputSchema ?? null,\n toolId,\n };\n}\n\nfunction parseInvokeResult(raw: unknown): AppToolInvokeResult {\n if (!isRecord(raw)) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid app tool invoke response');\n }\n const definitionKey = readString(raw.definitionKey);\n const name = readString(raw.name);\n const toolId = readNumber(raw.toolId);\n const latencyMs = readNumber(raw.latencyMs) ?? 0;\n if (!definitionKey || !name || toolId === undefined) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid app tool invoke response shape');\n }\n return {\n ok: raw.ok === true,\n definitionKey,\n toolId,\n name,\n latencyMs,\n output: raw.output,\n httpStatus: readNumber(raw.httpStatus),\n error: readString(raw.error),\n };\n}\n\n/**\n * 从 `AgentChatError.details.serverCode` 读取网关门禁码\n *(如 `INTEGRATION_USER_TOKEN_REQUIRED`)。\n */\nexport function getAppToolServerErrorCode(err: unknown): string | null {\n if (!(err instanceof AgentChatError)) return null;\n const code = err.details?.serverCode;\n return typeof code === 'string' && code.trim() ? code.trim() : null;\n}\n\n/** C 端 Tool 代调:`/app/tools/callable`、`/app/tools/invoke`。 */\nexport class AppToolService {\n private http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /** `GET /app/tools/callable` — 当前用户可代调的 L1 Tool 列表。 */\n async listCallable(signal?: AbortSignal): Promise<AppToolCallableList> {\n const raw = await this.http.request<unknown>('/app/tools/callable', {\n method: 'GET',\n signal,\n });\n const data = parseApiEnvelope<{ items?: unknown }>(raw);\n const items = Array.isArray(data?.items)\n ? data.items.map(parseCallableItem).filter((row): row is AppToolCallableItem => row != null)\n : [];\n return { items };\n }\n\n /**\n * `POST /app/tools/invoke` — 按 definitionKey 代调。\n * 下游非 2xx 时 HTTP 仍为 200,`ok: false`;网关门禁失败则抛 `AgentChatError`。\n */\n async invoke(input: AppToolInvokeInput): Promise<AppToolInvokeResult> {\n const definitionKey = input.definitionKey.trim();\n if (!definitionKey) {\n throw new AgentChatError('INVALID_OPTIONS', 'definitionKey is required');\n }\n const raw = await this.http.request<unknown>('/app/tools/invoke', {\n method: 'POST',\n signal: input.signal,\n body: {\n definitionKey,\n ...(input.parameters !== undefined ? { parameters: input.parameters } : {}),\n },\n });\n const data = parseApiEnvelope<unknown>(raw);\n return parseInvokeResult(data);\n }\n}\n","import type { SessionInfo, UserContext, AgentMessage } from '../../types';\n\nexport interface SessionContext {\n sdkVersion: string;\n origin: string;\n locale: string;\n user?: UserContext;\n}\n\nexport interface SessionManagerOptions {\n context: SessionContext;\n}\n\n/**\n * Lightweight in-memory holder for active chat session metadata.\n */\nexport class SessionManager {\n private context: SessionContext;\n\n private sessionId: string | null = null;\n private initialMessages: AgentMessage[] = [];\n\n constructor(options: SessionManagerOptions) {\n this.context = options.context;\n }\n\n updateContext(partial: Partial<SessionContext>): void {\n this.context = { ...this.context, ...partial };\n }\n\n getSession(): SessionInfo | null {\n if (!this.sessionId) return null;\n return { sessionId: this.sessionId, conversationId: this.sessionId };\n }\n\n getInitialMessages(): AgentMessage[] {\n return this.initialMessages;\n }\n\n setSession(sessionId: string, initialMessages: AgentMessage[] = []): void {\n this.sessionId = sessionId.trim().toLowerCase();\n this.initialMessages = initialMessages;\n }\n\n reset(): void {\n this.sessionId = null;\n this.initialMessages = [];\n }\n}\n","import { unwrapApiData } from '../auth/auth-response';\nimport type {\n PageContextPlanKind,\n SkillIntentAlignmentSnapshot,\n SkillIntentMismatchCode,\n SkillTurnContractView,\n TurnScopedToolsSource,\n TurnSkillSelect,\n} from '../../types';\n\nexport type AgentRunStepLike = {\n type: string;\n output?: unknown;\n name?: string;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction normalizeSteps(value: unknown): AgentRunStepLike[] {\n if (typeof value === 'string') {\n try {\n return normalizeSteps(JSON.parse(value));\n } catch {\n return [];\n }\n }\n if (!Array.isArray(value)) return [];\n return value.filter(\n (item): item is AgentRunStepLike =>\n isRecord(item) && typeof item.type === 'string',\n );\n}\n\nexport interface ParsedAgentRunDetail {\n steps: AgentRunStepLike[];\n turnExecutionTimeline: AgentRunStepLike[];\n}\n\nexport function parseAgentRunDetail(body: unknown): ParsedAgentRunDetail | null {\n const raw = unwrapApiData<Record<string, unknown>>(body) ?? (isRecord(body) ? body : null);\n if (!raw) return null;\n return {\n steps: normalizeSteps(raw.steps),\n turnExecutionTimeline: normalizeSteps(raw.turnExecutionTimeline),\n };\n}\n\nexport function resolveAlignmentSteps(run: ParsedAgentRunDetail): AgentRunStepLike[] {\n if (run.turnExecutionTimeline.length > 0) return run.turnExecutionTimeline;\n return run.steps;\n}\n\nfunction parseSkillAlignment(value: unknown): SkillIntentAlignmentSnapshot | null {\n if (!isRecord(value)) return null;\n const status = value.status;\n if (\n status !== 'none' &&\n status !== 'aligned' &&\n status !== 'intent_first' &&\n status !== 'clarified'\n ) {\n return null;\n }\n const snapshot: SkillIntentAlignmentSnapshot = { status };\n if (typeof value.code === 'string') {\n snapshot.code = value.code as SkillIntentMismatchCode;\n }\n const requestedSkillId = value.requestedSkillId;\n if (typeof requestedSkillId === 'number' && Number.isFinite(requestedSkillId)) {\n snapshot.requestedSkillId = requestedSkillId;\n }\n if (value.droppedExplicitSkill === true) {\n snapshot.droppedExplicitSkill = true;\n }\n return snapshot;\n}\n\nfunction parseSkillSelect(value: unknown): TurnSkillSelect {\n if (value === 'explicit' || value === 'page_host' || value === 'llm') {\n return value;\n }\n return 'llm';\n}\n\nfunction parseScopedToolsSource(value: unknown): TurnScopedToolsSource {\n if (value === 'explicit_skill' || value === 'intent') {\n return value;\n }\n return 'intent';\n}\n\nfunction parsePageContextPlan(value: unknown): PageContextPlanKind {\n if (value === 'inline_answer' || value === 'entity_read_detail' || value === 'none') {\n return value;\n }\n return 'none';\n}\n\nexport function readRoutePlanStep(\n steps: AgentRunStepLike[] | null | undefined,\n): Record<string, unknown> | null {\n if (!steps?.length) return null;\n const route = steps.find((step) => step.type === 'route_plan');\n if (!route?.output || !isRecord(route.output)) return null;\n return route.output;\n}\n\nexport function readSkillTurnContract(\n steps: AgentRunStepLike[] | null | undefined,\n): SkillTurnContractView | null {\n const out = readRoutePlanStep(steps);\n if (!out) return null;\n const align = parseSkillAlignment(out.skillAlignment);\n if (!align) return null;\n const requestedSkillId =\n typeof out.requestedSkillId === 'number' && Number.isFinite(out.requestedSkillId)\n ? out.requestedSkillId\n : null;\n return {\n skillAlignment: align,\n skillSelect: parseSkillSelect(out.skillSelect),\n scopedToolsSource: parseScopedToolsSource(out.scopedToolsSource),\n pageContextPlan: parsePageContextPlan(out.pageContextPlan),\n hostMutationIntent: Boolean(out.hostMutationIntent),\n requestedSkillId,\n };\n}\n\n/** @deprecated Use {@link readSkillTurnContract} */\nexport function readSkillAlignment(\n steps: AgentRunStepLike[] | null | undefined,\n): SkillIntentAlignmentSnapshot | null {\n return readSkillTurnContract(steps)?.skillAlignment ?? null;\n}\n\n/** True when the pre-selected skill was actually used this turn (three-field gate). */\nexport function isRequestedSkillActuallyUsed(\n contract: SkillTurnContractView | null | undefined,\n): boolean {\n if (!contract) return false;\n return (\n contract.scopedToolsSource === 'explicit_skill' &&\n contract.skillAlignment.status === 'aligned' &&\n contract.skillSelect === 'explicit'\n );\n}\n\nexport function shouldShowIntentFirstBanner(\n contract: SkillTurnContractView | null | undefined,\n): boolean {\n return contract?.skillAlignment.status === 'intent_first';\n}\n\n/** @deprecated Use {@link shouldShowIntentFirstBanner} */\nexport function shouldShowIntentFirstHint(\n align: SkillIntentAlignmentSnapshot | null | undefined,\n): boolean {\n return align?.status === 'intent_first';\n}\n\nexport function shouldShowSkillClarifyCard(\n contract: SkillTurnContractView | null | undefined,\n): boolean {\n return contract?.skillAlignment.status === 'clarified';\n}\n\n/** @deprecated Use {@link shouldShowSkillClarifyCard} */\nexport function shouldShowClarifyCard(\n align: SkillIntentAlignmentSnapshot | null | undefined,\n): boolean {\n return align?.status === 'clarified';\n}\n\nexport function mismatchI18nKey(code: SkillIntentMismatchCode): string {\n return `skill_intent_mismatch.${code}`;\n}\n\nexport interface SkillIntentMismatchObservation {\n userMessage?: string;\n mismatchCode?: SkillIntentMismatchCode;\n requestedSkillId?: number;\n requestedSkillName?: string;\n routingReason?: string;\n}\n\n/** Read `skill_intent_mismatch` from summarize step observations (debug / fallback). */\nexport function readSkillIntentMismatchObservation(\n steps: AgentRunStepLike[] | null | undefined,\n): SkillIntentMismatchObservation | null {\n if (!steps?.length) return null;\n for (let i = steps.length - 1; i >= 0; i -= 1) {\n const step = steps[i];\n if (step.type !== 'summarize') continue;\n const output = step.output;\n if (!isRecord(output)) continue;\n const observations = output.observations;\n if (!Array.isArray(observations)) continue;\n for (const item of observations) {\n if (!isRecord(item)) continue;\n if (item.name !== 'skill_intent_mismatch') continue;\n const obsOutput = item.output;\n if (!isRecord(obsOutput)) continue;\n return {\n userMessage:\n typeof obsOutput.userMessage === 'string' ? obsOutput.userMessage : undefined,\n mismatchCode:\n typeof obsOutput.mismatchCode === 'string'\n ? (obsOutput.mismatchCode as SkillIntentMismatchCode)\n : undefined,\n requestedSkillId:\n typeof obsOutput.requestedSkillId === 'number'\n ? obsOutput.requestedSkillId\n : undefined,\n requestedSkillName:\n typeof obsOutput.requestedSkillName === 'string'\n ? obsOutput.requestedSkillName\n : undefined,\n routingReason:\n typeof obsOutput.routingReason === 'string' ? obsOutput.routingReason : undefined,\n };\n }\n }\n return null;\n}\n","import { AgentChatError } from '../lib/errors';\nimport { parseHostActionSsePayload } from '../host-tool/host-action';\nimport { isHostActionStreamPayload } from '../host-tool/stream/host-tool-stream.types';\nimport type { HostActionSsePayload } from '../host-tool/stream/host-tool-stream.types';\nimport type { SseEventChunk } from '../http';\nimport type { AgentChatPageContext, PageBotStreamResult } from '../../types';\nimport type { PageActionSseLifecycle } from '../../types';\nimport type { PageContextGate } from '../host-tool/stream/host-tool-stream-gate';\nimport {\n parsePageWorkflowEvent,\n type PageWorkflowEvent,\n} from './page-action-workflow-progress';\nimport {\n isBrainAskUserErrorCode,\n parseBrainClarifyPayload,\n} from './brain-clarify';\n\nexport const PAGE_ACTION_STREAM_KEY_PREFIX = 'page-action:';\n/** @deprecated Use per-invoke keys under {@link PAGE_ACTION_STREAM_KEY_PREFIX}. */\nexport const PAGE_ACTION_STREAM_SESSION_KEY = '__page_action__';\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 tryParseJson(raw: string): unknown {\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return null;\n }\n}\n\nfunction throwPageActionFailed(\n message: string,\n details: Record<string, unknown>,\n): never {\n throw new AgentChatError('PAGE_ACTION_FAILED', message, { details });\n}\n\n/** Map HTTP / transport failures from `/page-action/*` to {@link AgentChatError} `PAGE_ACTION_FAILED`. */\nexport function rethrowPageActionError(err: unknown): never {\n if (err instanceof AgentChatError) {\n if (err.code === 'TRANSPORT_ABORTED' || err.code === 'PAGE_ACTION_FAILED') {\n throw err;\n }\n if (err.code === 'TRANSPORT_FAILED') {\n throw new AgentChatError('PAGE_ACTION_FAILED', err.message, {\n cause: err,\n details: err.details,\n });\n }\n }\n throw err;\n}\n\nexport function pageGateFromPageContext(\n pageContext: AgentChatPageContext | null | undefined,\n): PageContextGate {\n if (!pageContext) return {};\n return {\n ...(pageContext.page ? { page: pageContext.page } : {}),\n ...(pageContext.entity ? { entity: pageContext.entity } : {}),\n };\n}\n\nfunction readArgAppendChunk(payload: HostActionSsePayload): string | undefined {\n if (!isHostActionStreamPayload(payload)) return undefined;\n const dsl = payload.dsl;\n if (!dsl || dsl.op !== 'arg.append') return undefined;\n const chunk = dsl.chunk;\n return typeof chunk === 'string' ? chunk : undefined;\n}\n\nexport type PageActionStreamHooks = {\n onHostAction: (payload: HostActionSsePayload) => void;\n onChunk?: (chunk: string) => void;\n onLifecycle?: (lifecycle: PageActionSseLifecycle) => void;\n /** Process loading narrative (`page_workflow`) — UI only. */\n onWorkflowProgress?: (event: PageWorkflowEvent) => void;\n /** Log malformed `host_action` SSE payloads when true. */\n debug?: boolean;\n};\n\nfunction readLifecycle(body: Record<string, unknown>): PageActionSseLifecycle | null {\n const phase = readString(body.phase);\n const actionRunId = typeof body.actionRunId === 'number' ? body.actionRunId : null;\n const actionKey = readString(body.actionKey);\n const generation = typeof body.generation === 'number' ? body.generation : null;\n if (\n !phase ||\n actionRunId == null ||\n !actionKey ||\n generation == null ||\n (phase !== 'started' &&\n phase !== 'stream' &&\n phase !== 'completed' &&\n phase !== 'failed' &&\n phase !== 'awaiting_approval')\n ) {\n return null;\n }\n return {\n phase,\n actionRunId,\n actionKey,\n generation,\n clientActionId: readString(body.clientActionId) ?? null,\n streamId: readString(body.streamId) ?? null,\n text: typeof body.text === 'string' ? body.text : undefined,\n dslOutcome:\n typeof body.dslOutcome === 'string'\n ? body.dslOutcome\n : body.dslOutcome === null\n ? null\n : undefined,\n errorCode: readString(body.errorCode),\n errorMessage: readString(body.errorMessage),\n brainClarify: parseBrainClarifyPayload(body.brainClarify),\n };\n}\n\n/** Consume PageAction run SSE (`page_action` + `page_workflow` + optional `host_action`). */\nexport async function consumePageActionRunStream(\n chunks: AsyncIterable<SseEventChunk>,\n hooks: PageActionStreamHooks,\n): Promise<PageBotStreamResult> {\n let actionRunId = 0;\n let finalText = '';\n let dslOutcome: string | null = null;\n let completed = false;\n\n for await (const evt of chunks) {\n if (evt.event === 'ping') {\n continue;\n }\n\n if (evt.event === 'page_workflow') {\n const parsed = tryParseJson(evt.data);\n const workflow = parsePageWorkflowEvent(parsed);\n if (workflow) {\n hooks.onWorkflowProgress?.(workflow);\n }\n continue;\n }\n\n if (evt.event === 'host_action') {\n const parsed = tryParseJson(evt.data);\n const payload = parseHostActionSsePayload(parsed);\n if (payload) {\n hooks.onHostAction(payload);\n const chunk = readArgAppendChunk(payload);\n if (chunk) hooks.onChunk?.(chunk);\n } else if (\n hooks.debug &&\n typeof console !== 'undefined' &&\n typeof console.warn === 'function'\n ) {\n console.warn('[agent-chat] page_action: ignored malformed host_action SSE frame');\n }\n continue;\n }\n\n if (evt.event !== 'page_action') continue;\n\n const body = tryParseJson(evt.data);\n if (!isRecord(body)) continue;\n\n const lifecycle = readLifecycle(body);\n if (lifecycle) {\n hooks.onLifecycle?.(lifecycle);\n }\n\n if (typeof body.actionRunId === 'number' && Number.isFinite(body.actionRunId)) {\n actionRunId = body.actionRunId;\n }\n\n if (body.phase === 'stream') {\n const chunk = typeof body.text === 'string' ? body.text : '';\n if (chunk) {\n finalText += chunk;\n hooks.onChunk?.(chunk);\n }\n continue;\n }\n\n if (body.phase === 'completed') {\n completed = true;\n finalText = typeof body.text === 'string' ? body.text : '';\n dslOutcome =\n typeof body.dslOutcome === 'string'\n ? body.dslOutcome\n : body.dslOutcome === null\n ? null\n : dslOutcome;\n }\n\n if (body.phase === 'failed') {\n const errorCode = readString(body.errorCode);\n const errorMessage =\n readString(body.errorMessage) ?? 'Page action invoke failed';\n const brainClarify = parseBrainClarifyPayload(body.brainClarify);\n // Brain ASK_USER is a soft pause for entity pick — not a hard stream failure.\n if (isBrainAskUserErrorCode(errorCode) && brainClarify) {\n return {\n actionRunId,\n text: brainClarify.question,\n dslOutcome: null,\n awaitingClarify: true,\n actionKey: readString(body.actionKey),\n clientActionId: readString(body.clientActionId),\n brainClarify,\n message: brainClarify.question,\n };\n }\n throwPageActionFailed(errorMessage, {\n serverCode: errorCode,\n actionRunId: actionRunId || undefined,\n phase: 'failed',\n brainClarify: brainClarify ?? undefined,\n });\n }\n\n if (body.phase === 'awaiting_approval') {\n return {\n actionRunId,\n text: '',\n dslOutcome: null,\n awaitingApproval: true,\n status: 'awaiting_approval',\n actionKey: readString(body.actionKey),\n clientActionId: readString(body.clientActionId),\n };\n }\n }\n\n if (!completed) {\n throwPageActionFailed('Page action stream ended without completion', {\n actionRunId: actionRunId || undefined,\n phase: 'incomplete',\n });\n }\n\n return { actionRunId, text: finalText, dslOutcome };\n}\n\nexport type { PageWorkflowEvent };\n\n/** @deprecated Use {@link consumePageActionRunStream}. */\nexport const consumePageActionInvokeStream = consumePageActionRunStream;\n","import type { InvokePageActionRequest, PageActionReuseHint } from '../../types';\n\n/** Stable cache key for reuse-hint — same fields the server hashes into pageActionKey. */\nexport function pageActionReuseHintCacheKey(body: InvokePageActionRequest): string {\n return JSON.stringify({\n actionKey: body.actionKey.trim(),\n pageContext: body.pageContext ?? null,\n instruction: body.instruction?.trim() || null,\n context: body.context && Object.keys(body.context).length > 0 ? body.context : null,\n });\n}\n\nexport class PageActionReuseHintCache {\n private readonly byBodyKey = new Map<string, PageActionReuseHint>();\n private readonly bodyKeyByPageActionKey = new Map<string, string>();\n\n get(body: InvokePageActionRequest): PageActionReuseHint | null {\n return this.byBodyKey.get(pageActionReuseHintCacheKey(body)) ?? null;\n }\n\n set(body: InvokePageActionRequest, hint: PageActionReuseHint): void {\n const key = pageActionReuseHintCacheKey(body);\n this.byBodyKey.set(key, hint);\n const pageActionKey = hint.pageActionKey.trim();\n if (pageActionKey) {\n this.bodyKeyByPageActionKey.set(pageActionKey, key);\n }\n }\n\n /** Drop cached hint after a fresh successful run for this key. */\n invalidateByPageActionKey(pageActionKey: string | null | undefined): void {\n const pak = pageActionKey?.trim();\n if (!pak) return;\n const bodyKey = this.bodyKeyByPageActionKey.get(pak);\n if (!bodyKey) return;\n this.byBodyKey.delete(bodyKey);\n this.bodyKeyByPageActionKey.delete(pak);\n }\n\n invalidateByBody(body: InvokePageActionRequest): void {\n const key = pageActionReuseHintCacheKey(body);\n const hint = this.byBodyKey.get(key);\n this.byBodyKey.delete(key);\n if (hint?.pageActionKey) {\n this.bodyKeyByPageActionKey.delete(hint.pageActionKey.trim());\n }\n }\n\n clear(): void {\n this.byBodyKey.clear();\n this.bodyKeyByPageActionKey.clear();\n }\n}\n","import type { AgentChatPageContext } from '../../types';\n\n/**\n * Navigation target from a task `pageContext` snapshot.\n * Only `routePath` is used — host must pass it on invoke.\n */\nexport type PageContextNavigateTarget =\n | { kind: 'routePath'; path: string }\n | { kind: 'none' };\n\nexport function resolvePageContextNavigateTarget(\n pageContext: AgentChatPageContext | null | undefined,\n): PageContextNavigateTarget {\n const routePath = pageContext?.routePath?.trim();\n if (routePath) {\n return { kind: 'routePath', path: routePath };\n }\n return { kind: 'none' };\n}\n\n/** Host-facing payload for「应用到页面」navigation. */\nexport type NavigateForPageActionInput = {\n runId: number;\n actionKey: string;\n pageContext: AgentChatPageContext | null;\n target: PageContextNavigateTarget;\n /**\n * `true` when SDK wrote pendingApply — target `usePageAction({ ready })`\n * will auto `replayPageAction` when ready.\n */\n canReplay: boolean;\n};\n\nexport type ApplyPageActionToPageResult = {\n runId: number;\n actionKey: string;\n pageContext: AgentChatPageContext | null;\n target: PageContextNavigateTarget;\n /** Host `onNavigateForPageAction` was invoked successfully. */\n navigated: boolean;\n /**\n * `true` when pendingApply was written for the target page to consume.\n */\n canReplay: boolean;\n ok: boolean;\n reason?:\n | 'missing_route_path'\n | 'no_replayable_output'\n | 'not_completed'\n | 'navigate_only';\n};\n","import type { AgentChatPageContext } from '../../types';\n\nconst STORAGE_PREFIX = 'omnix-chat:pending-page-action-apply:';\n/** Drop stale pending applies after 30 minutes. */\nconst PENDING_TTL_MS = 30 * 60 * 1000;\n\n/** Intent left by「应用到页面」until the target page is ready to replay. */\nexport type PendingPageActionApply = {\n runId: number;\n actionKey: string;\n pageContext: AgentChatPageContext | null;\n createdAt: string;\n};\n\nfunction storageKey(dsn: string): string {\n return `${STORAGE_PREFIX}${dsn.trim()}`;\n}\n\nfunction isFresh(pending: PendingPageActionApply): boolean {\n const created = Date.parse(pending.createdAt);\n if (!Number.isFinite(created)) return false;\n return Date.now() - created <= PENDING_TTL_MS;\n}\n\nexport function readPendingPageActionApply(dsn: string): PendingPageActionApply | null {\n if (typeof sessionStorage === 'undefined') return null;\n try {\n const raw = sessionStorage.getItem(storageKey(dsn));\n if (!raw) return null;\n const parsed = JSON.parse(raw) as PendingPageActionApply;\n if (\n !parsed ||\n typeof parsed.runId !== 'number' ||\n !Number.isFinite(parsed.runId) ||\n typeof parsed.actionKey !== 'string' ||\n !parsed.actionKey.trim()\n ) {\n return null;\n }\n if (!isFresh(parsed)) {\n sessionStorage.removeItem(storageKey(dsn));\n return null;\n }\n return {\n runId: Math.trunc(parsed.runId),\n actionKey: parsed.actionKey.trim(),\n pageContext: parsed.pageContext ?? null,\n createdAt: typeof parsed.createdAt === 'string' ? parsed.createdAt : new Date().toISOString(),\n };\n } catch {\n return null;\n }\n}\n\nexport function writePendingPageActionApply(\n dsn: string,\n pending: PendingPageActionApply,\n): void {\n if (typeof sessionStorage === 'undefined') return;\n try {\n sessionStorage.setItem(storageKey(dsn), JSON.stringify(pending));\n } catch {\n /* quota / private mode */\n }\n}\n\nexport function clearPendingPageActionApplyStorage(dsn: string): void {\n if (typeof sessionStorage === 'undefined') return;\n try {\n sessionStorage.removeItem(storageKey(dsn));\n } catch {\n /* ignore */\n }\n}\n\nfunction normalizeEntityId(value: unknown): string | null {\n if (value == null) return null;\n const s = String(value).trim();\n return s || null;\n}\n\n/**\n * Whether a pending apply belongs to this page slot.\n * If pending carries `page` / `entity.id`, the hook opts must match (missing = no match).\n */\nexport function matchesPendingPageActionApply(\n pending: PendingPageActionApply | null | undefined,\n opts: {\n actionKey: string;\n pageContext?: AgentChatPageContext | null;\n },\n): boolean {\n if (!pending) return false;\n const actionKey = opts.actionKey.trim();\n if (!actionKey || pending.actionKey !== actionKey) return false;\n\n const page = opts.pageContext?.page?.trim() || null;\n const pendingPage = pending.pageContext?.page?.trim() || null;\n if (pendingPage && page !== pendingPage) return false;\n\n const entityId = normalizeEntityId(opts.pageContext?.entity?.id);\n const pendingEntityId = normalizeEntityId(pending.pageContext?.entity?.id);\n if (pendingEntityId && entityId !== pendingEntityId) return false;\n\n return true;\n}\n","import type {\n AutomationTaskListItem,\n AutomationTaskStatus,\n AutomationTaskStatusFilter,\n InvokePageActionAccepted,\n PageActionLifecyclePhase,\n} from '../../types';\n\nexport type TrackedAutomationRun = {\n runId: number;\n actionKey: string;\n /** Server-issued de-duplication key (`pageActionKey`). */\n pageActionKey: string | null;\n /** Host list-row key (optional; set by {@link AgentChatInstance.invokePageAction}). */\n rowKey: string | null;\n status: AutomationTaskStatus;\n registeredAt: string;\n updatedAt: string;\n clientActionId: string | null;\n};\n\nexport const AUTOMATION_RECONCILE_STALE_MS = 60_000;\nexport const AUTOMATION_TRACKED_RUN_TTL_MS = 30 * 60_000;\n\nexport function isActiveAutomationTaskStatus(status: AutomationTaskStatus): boolean {\n return status === 'running' || status === 'awaiting_approval';\n}\n\nexport function countActiveTrackedRuns(registry: Map<number, TrackedAutomationRun>): number {\n let count = 0;\n for (const run of registry.values()) {\n if (isActiveAutomationTaskStatus(run.status)) count += 1;\n }\n return count;\n}\n\nexport function collectActivePageActionKeys(\n registry: Map<number, TrackedAutomationRun>,\n): Set<string> {\n const keys = new Set<string>();\n for (const run of registry.values()) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n const key = run.pageActionKey?.trim();\n if (key) keys.add(key);\n }\n return keys;\n}\n\nexport function findActivePageActionKeyForActionKey(\n registry: Map<number, TrackedAutomationRun>,\n actionKey: string,\n): string | null {\n const key = actionKey.trim();\n if (!key) return null;\n for (const run of registry.values()) {\n if (run.actionKey !== key) continue;\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n const pageActionKey = run.pageActionKey?.trim();\n if (pageActionKey) return pageActionKey;\n }\n return null;\n}\n\nexport function pruneStaleTrackedRuns(registry: Map<number, TrackedAutomationRun>): void {\n const cutoff = Date.now() - AUTOMATION_TRACKED_RUN_TTL_MS;\n for (const [runId, run] of registry) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n const updatedAt = Date.parse(run.updatedAt);\n if (Number.isFinite(updatedAt) && updatedAt < cutoff) {\n registry.delete(runId);\n }\n }\n}\n\nexport function taskMatchesStatusFilter(\n status: AutomationTaskStatus,\n filter: AutomationTaskStatusFilter,\n): boolean {\n switch (filter) {\n case 'active':\n return isActiveAutomationTaskStatus(status);\n case 'all':\n return true;\n default:\n return status === filter;\n }\n}\n\nexport function lifecyclePhaseToTaskStatus(\n phase: PageActionLifecyclePhase,\n): AutomationTaskStatus | null {\n switch (phase) {\n case 'started':\n case 'stream':\n return 'running';\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'awaiting_approval':\n return 'awaiting_approval';\n default:\n return null;\n }\n}\n\nexport function buildOptimisticAutomationTaskItem(\n accepted: InvokePageActionAccepted,\n actionKey: string,\n opts?: { title?: string | null; subtitle?: string | null },\n): AutomationTaskListItem {\n const now = new Date().toISOString();\n const taskStatus =\n accepted.status === 'awaiting_approval'\n ? 'awaiting_approval'\n : accepted.status === 'running'\n ? 'running'\n : accepted.status;\n const title = opts?.title?.trim() || formatPageActionDisplayTitle(actionKey);\n return {\n ref: { kind: 'page_action_run', id: accepted.runId },\n triggerSource: 'page_action',\n taskStatus,\n title,\n subtitle: opts?.subtitle?.trim() || null,\n workflowKey: null,\n workflowName: null,\n pageActionKey: accepted.pageActionKey,\n createdAt: now,\n finishedAt: null,\n durationMs: null,\n approval: null,\n outputs: {\n preview: null,\n hasFillText: false,\n },\n };\n}\n\n/**\n * Prefer catalog display name; otherwise last segment of `actionKey`\n * (`campaign-detail.analyze` → `analyze`). Never show a bare hash.\n */\nexport function formatPageActionDisplayTitle(\n actionKey: string,\n catalogName?: string | null,\n): string {\n const named = catalogName?.trim();\n const key = actionKey.trim();\n if (named && named !== key && !looksLikeOpaqueKey(named)) return named;\n if (!key) return 'PageAction';\n if (looksLikeOpaqueKey(key)) return 'PageAction';\n const last = key.includes('.') ? key.slice(key.lastIndexOf('.') + 1) : key;\n return last || key;\n}\n\nfunction looksLikeOpaqueKey(value: string): boolean {\n return /^[a-f0-9]{32,}$/i.test(value.trim());\n}\n\n/** Find all active tracked runs for an actionKey (list pages may have several). */\nexport function findActiveTrackedRunsForActionKey(\n registry: Map<number, TrackedAutomationRun>,\n actionKey: string,\n): TrackedAutomationRun[] {\n const key = actionKey.trim();\n if (!key) return [];\n const rows: TrackedAutomationRun[] = [];\n for (const run of registry.values()) {\n if (run.actionKey !== key) continue;\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n rows.push(run);\n }\n return rows;\n}\n\nexport function findPageActionRunIndex(\n items: AutomationTaskListItem[],\n runId: number,\n): number {\n return items.findIndex(\n (item) => item.ref.kind === 'page_action_run' && item.ref.id === runId,\n );\n}\n\nexport function upsertAutomationTaskListItem(\n items: AutomationTaskListItem[],\n item: AutomationTaskListItem,\n): AutomationTaskListItem[] {\n const index = findPageActionRunIndex(items, item.ref.id);\n if (index >= 0) {\n const next = [...items];\n next[index] = { ...next[index], ...item };\n return next;\n }\n return [item, ...items];\n}\n\nexport function patchAutomationTaskListItem(\n items: AutomationTaskListItem[],\n runId: number,\n patch: Partial<AutomationTaskListItem>,\n): AutomationTaskListItem[] {\n const index = findPageActionRunIndex(items, runId);\n if (index < 0) return items;\n const next = [...items];\n const current = next[index]!;\n next[index] = {\n ...current,\n ...patch,\n outputs: patch.outputs ? { ...current.outputs, ...patch.outputs } : current.outputs,\n approval: patch.approval === undefined ? current.approval : patch.approval,\n };\n return next;\n}\n\nexport function removeAutomationTaskListItem(\n items: AutomationTaskListItem[],\n runId: number,\n): AutomationTaskListItem[] {\n return items.filter(\n (item) => !(item.ref.kind === 'page_action_run' && item.ref.id === runId),\n );\n}\n\nexport function mergeOptimisticRunsIntoList(\n serverItems: AutomationTaskListItem[],\n registry: Map<number, TrackedAutomationRun>,\n): AutomationTaskListItem[] {\n const serverRunIds = new Set(\n serverItems\n .filter((item) => item.ref.kind === 'page_action_run')\n .map((item) => item.ref.id),\n );\n const optimistic: AutomationTaskListItem[] = [];\n for (const run of registry.values()) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n if (serverRunIds.has(run.runId)) continue;\n optimistic.push(\n buildOptimisticAutomationTaskItem(\n {\n runId: run.runId,\n generation: 0,\n clientActionId: run.clientActionId,\n pageActionKey: run.pageActionKey,\n streamUrl: '',\n status: run.status,\n },\n run.actionKey,\n ),\n );\n }\n if (optimistic.length === 0) return serverItems;\n const merged = [...optimistic];\n for (const item of serverItems) {\n if (item.ref.kind === 'page_action_run' && optimistic.some((row) => row.ref.id === item.ref.id)) {\n continue;\n }\n merged.push(item);\n }\n return merged;\n}\n\nexport function mergeRegistryFromActiveListItems(\n registry: Map<number, TrackedAutomationRun>,\n items: AutomationTaskListItem[],\n opts: { fallbackActionKey?: string } = {},\n): void {\n const activeRunIds = new Set<number>();\n const now = new Date().toISOString();\n const nowMs = Date.now();\n const fallbackActionKey = opts.fallbackActionKey?.trim() || null;\n for (const item of items) {\n if (item.ref.kind !== 'page_action_run') continue;\n if (!isActiveAutomationTaskStatus(item.taskStatus)) continue;\n activeRunIds.add(item.ref.id);\n const existing = registry.get(item.ref.id);\n // List items only expose `title` (often == actionKey when optimistic). Prefer\n // tracked actionKey, then caller filter (GET ?actionKey=), then title.\n const actionKey =\n fallbackActionKey || existing?.actionKey || item.title;\n registry.set(item.ref.id, {\n runId: item.ref.id,\n actionKey,\n pageActionKey: existing?.pageActionKey ?? item.pageActionKey ?? null,\n rowKey: existing?.rowKey ?? null,\n status: item.taskStatus,\n registeredAt: existing?.registeredAt ?? item.createdAt ?? now,\n updatedAt: now,\n clientActionId: existing?.clientActionId ?? null,\n });\n }\n for (const runId of registry.keys()) {\n if (activeRunIds.has(runId)) continue;\n const tracked = registry.get(runId);\n if (!tracked) continue;\n const registeredAt = Date.parse(tracked.registeredAt);\n if (Number.isFinite(registeredAt) && nowMs - registeredAt < 30_000) {\n continue;\n }\n registry.delete(runId);\n }\n}\n","import type { AutomationTaskListItem, AutomationTaskStatusFilter } from '../../types';\n\nexport const AUTOMATION_TASK_CENTER_TABS = [\n 'active',\n 'awaiting_approval',\n 'completed',\n 'failed',\n] as const satisfies readonly AutomationTaskStatusFilter[];\n\nexport type AutomationTaskTabCache = {\n items: AutomationTaskListItem[];\n hasMore: boolean;\n total: number;\n /** Whether this tab has completed at least one list fetch. */\n hydrated: boolean;\n};\n\nexport function createAutomationTaskTabCaches(): Map<\n AutomationTaskStatusFilter,\n AutomationTaskTabCache\n> {\n const map = new Map<AutomationTaskStatusFilter, AutomationTaskTabCache>();\n for (const tab of AUTOMATION_TASK_CENTER_TABS) {\n map.set(tab, emptyAutomationTaskTabCache());\n }\n return map;\n}\n\nexport function emptyAutomationTaskTabCache(): AutomationTaskTabCache {\n return { items: [], hasMore: false, total: 0, hydrated: false };\n}\n\nexport function getAutomationTaskTabCache(\n caches: Map<AutomationTaskStatusFilter, AutomationTaskTabCache>,\n filter: AutomationTaskStatusFilter,\n): AutomationTaskTabCache {\n return caches.get(filter) ?? emptyAutomationTaskTabCache();\n}\n\nexport function writeAutomationTaskTabCache(\n caches: Map<AutomationTaskStatusFilter, AutomationTaskTabCache>,\n filter: AutomationTaskStatusFilter,\n patch: Partial<AutomationTaskTabCache> & { items?: AutomationTaskListItem[] },\n): void {\n const prev = getAutomationTaskTabCache(caches, filter);\n caches.set(filter, {\n items: patch.items ?? prev.items,\n hasMore: patch.hasMore ?? prev.hasMore,\n total: patch.total ?? prev.total,\n hydrated: patch.hydrated ?? prev.hydrated,\n });\n}\n","import type {\n AutomationTaskStatus,\n PageActionPhase,\n PageActionRowState,\n} from '../../types';\nimport type { TrackedAutomationRun } from '../automation/automation-run-tracker';\nimport { isActiveAutomationTaskStatus } from '../automation/automation-run-tracker';\n\nexport function createIdlePageActionRowState(\n rowKey: string,\n actionKey: string,\n): PageActionRowState {\n return {\n rowKey,\n actionKey,\n runId: null,\n pageActionKey: null,\n phase: 'idle',\n awaitingApproval: false,\n awaitingClarify: false,\n loading: false,\n disabled: false,\n error: null,\n message: null,\n progressLabel: null,\n narrativeItems: [],\n approvalRequestId: null,\n brainClarify: null,\n updatedAt: Date.now(),\n };\n}\n\nexport function derivePageActionRowFlags(\n phase: PageActionPhase,\n): Pick<PageActionRowState, 'awaitingApproval' | 'awaitingClarify' | 'loading' | 'disabled'> {\n const awaitingApproval = phase === 'awaiting_approval';\n const awaitingClarify = phase === 'awaiting_clarify';\n const awaitingReuse = phase === 'awaiting_reuse';\n // Reuse picker must NOT disable the trigger — outside-dismiss + re-click was\n // getting stuck when React row state lagged behind the client unlock.\n const loading =\n !awaitingApproval &&\n !awaitingClarify &&\n !awaitingReuse &&\n (phase === 'submitting' || phase === 'launched' || phase === 'streaming');\n return {\n awaitingApproval,\n awaitingClarify,\n loading,\n // awaiting_reuse stays clickable so dismiss → re-open works even if UI state lags.\n disabled: loading || awaitingApproval || awaitingClarify,\n };\n}\n\nexport function taskStatusToPageActionPhase(\n status: AutomationTaskStatus,\n): PageActionPhase {\n switch (status) {\n case 'awaiting_approval':\n return 'awaiting_approval';\n case 'running':\n return 'streaming';\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'cancelled':\n return 'idle';\n default:\n return 'idle';\n }\n}\n\nexport function resolvePageActionRowKey(input: {\n rowKey?: string | null;\n entityId?: string | number | null;\n}): string | null {\n const explicit = input.rowKey?.trim();\n if (explicit) return explicit;\n if (input.entityId == null) return null;\n const asString = String(input.entityId).trim();\n return asString || null;\n}\n\n/** Synthetic fallback when no host row slot is known before detail is loaded. */\nexport function syntheticPageActionRunRowKey(runId: number): string {\n return `run:${Math.trunc(runId)}`;\n}\n\n/**\n * Resolve list/detail row slot after refresh — prefer host `entity.id` over `run:{id}`.\n */\nexport function resolveRestoredPageActionRowKey(\n runId: number,\n input: {\n rowKey?: string | null;\n entityId?: string | number | null;\n findRowKeyByRunId?: () => string | null | undefined;\n } = {},\n): string {\n const id = Math.trunc(runId);\n const synthetic = syntheticPageActionRunRowKey(id);\n const explicit = input.rowKey?.trim();\n if (explicit && explicit !== synthetic) return explicit;\n const fromRun = input.findRowKeyByRunId?.()?.trim();\n if (fromRun) return fromRun;\n const fromEntity = resolvePageActionRowKey({ entityId: input.entityId ?? null });\n if (fromEntity) return fromEntity;\n return explicit || synthetic;\n}\n\nexport function buildPageActionRowState(\n partial: Omit<\n PageActionRowState,\n | 'awaitingApproval'\n | 'awaitingClarify'\n | 'loading'\n | 'disabled'\n | 'updatedAt'\n | 'message'\n | 'progressLabel'\n | 'narrativeItems'\n | 'brainClarify'\n > & {\n awaitingApproval?: boolean;\n awaitingClarify?: boolean;\n loading?: boolean;\n disabled?: boolean;\n updatedAt?: number;\n message?: string | null;\n progressLabel?: string | null;\n narrativeItems?: PageActionRowState['narrativeItems'];\n brainClarify?: PageActionRowState['brainClarify'];\n },\n): PageActionRowState {\n const flags = derivePageActionRowFlags(partial.phase);\n return {\n ...partial,\n message: partial.message ?? null,\n progressLabel: partial.progressLabel ?? null,\n narrativeItems: partial.narrativeItems ?? [],\n brainClarify: partial.brainClarify ?? null,\n awaitingApproval: partial.awaitingApproval ?? flags.awaitingApproval,\n awaitingClarify: partial.awaitingClarify ?? flags.awaitingClarify,\n loading: partial.loading ?? flags.loading,\n disabled: partial.disabled ?? flags.disabled,\n updatedAt: partial.updatedAt ?? Date.now(),\n };\n}\n\nexport function findTrackedRunsByActionKey(\n registry: Map<number, TrackedAutomationRun>,\n actionKey: string,\n): TrackedAutomationRun[] {\n const key = actionKey.trim();\n if (!key) return [];\n const rows: TrackedAutomationRun[] = [];\n for (const run of registry.values()) {\n if (run.actionKey !== key) continue;\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n rows.push(run);\n }\n return rows;\n}\n\nexport function findTrackedRunByPageActionKey(\n registry: Map<number, TrackedAutomationRun>,\n pageActionKey: string,\n): TrackedAutomationRun | null {\n const key = pageActionKey.trim();\n if (!key) return null;\n for (const run of registry.values()) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n if (run.pageActionKey?.trim() === key) return run;\n }\n return null;\n}\n\nexport function findTrackedRunByRowKey(\n registry: Map<number, TrackedAutomationRun>,\n rowKey: string,\n): TrackedAutomationRun | null {\n const key = rowKey.trim();\n if (!key) return null;\n for (const run of registry.values()) {\n if (!isActiveAutomationTaskStatus(run.status)) continue;\n if (run.rowKey?.trim() === key) return run;\n }\n return null;\n}\n","import { matchesPendingPageActionApply } from './pending-page-action-apply';\nimport type {\n AgentChatPageContext,\n PageActionApplyPhase,\n PendingPageActionApply,\n} from '../../types';\n\n/** List-level bind: reconcile all rows for an actionKey (no per-row apply). */\nexport const PAGE_ACTION_ACTION_SCOPE_ROW_KEY = '*';\n\n/** Host-registered PageAction UI slot (one button / one list row). */\nexport type PageActionSlotBinding = {\n actionKey: string;\n rowKey: string;\n pageContext?: AgentChatPageContext | null;\n ready: boolean;\n autoResume: boolean;\n autoApplyPending: boolean;\n};\n\nexport type PageActionSlotSyncResult = {\n applyPhase: PageActionApplyPhase;\n};\n\nexport type PageActionCoordinatorDeps = {\n ensureLoggedIn: () => Promise<void>;\n reconcileActivePageActions: (opts: { actionKey: string }) => Promise<unknown>;\n resumeActivePageActionStreams: (opts: { actionKey: string }) => Promise<number>;\n replayPageAction: (runId: number) => Promise<void>;\n getPendingPageActionApply: () => PendingPageActionApply | null;\n onApplyPhaseChanged: (slotKey: string, phase: PageActionApplyPhase) => void;\n};\n\nexport function pageActionSlotKey(binding: Pick<PageActionSlotBinding, 'actionKey' | 'rowKey'>): string {\n return `${binding.actionKey.trim()}::${binding.rowKey.trim()}`;\n}\n\nfunction isActionScopeRowKey(rowKey: string): boolean {\n const key = rowKey.trim();\n return !key || key === PAGE_ACTION_ACTION_SCOPE_ROW_KEY;\n}\n\n/**\n * Owns PageAction slot bindings and the **single** restore pipeline:\n * auth ready → reconcile server active runs → attach SSE → consume pending apply.\n *\n * Hooks only register/unregister slots; they do not run parallel reconcile effects.\n */\nexport class PageActionCoordinator {\n private readonly slots = new Map<string, PageActionSlotBinding>();\n private readonly syncInflight = new Map<string, Promise<PageActionSlotSyncResult>>();\n /** Slots that need another sync after the current inflight run (pending apply race). */\n private readonly syncDirty = new Set<string>();\n private readonly liveRestoreInflight = new Map<string, Promise<void>>();\n private readonly applyPhaseBySlot = new Map<string, PageActionApplyPhase>();\n private readonly replayInflight = new Set<number>();\n private readonly deps: PageActionCoordinatorDeps;\n\n constructor(deps: PageActionCoordinatorDeps) {\n this.deps = deps;\n }\n\n getApplyPhase(slotKey: string): PageActionApplyPhase {\n return this.applyPhaseBySlot.get(slotKey) ?? 'idle';\n }\n\n bind(binding: PageActionSlotBinding): () => void {\n const key = pageActionSlotKey(binding);\n this.slots.set(key, binding);\n void this.syncSlot(key);\n return () => {\n this.slots.delete(key);\n this.syncInflight.delete(key);\n this.syncDirty.delete(key);\n this.applyPhaseBySlot.delete(key);\n };\n }\n\n patch(slotKey: string, patch: Partial<PageActionSlotBinding>): void {\n const prev = this.slots.get(slotKey);\n if (!prev) return;\n this.slots.set(slotKey, { ...prev, ...patch });\n void this.syncSlot(slotKey);\n }\n\n /** After init / login — restore every registered slot once. */\n onAuthReady(): void {\n for (const key of this.slots.keys()) {\n void this.syncSlot(key);\n }\n }\n\n onPendingApplyChanged(): void {\n for (const [key, binding] of this.slots) {\n if (!binding.autoApplyPending) continue;\n void this.syncSlot(key);\n }\n }\n\n /** Debug: currently registered slots (demo / integration). */\n listBindings(): PageActionSlotBinding[] {\n return [...this.slots.values()];\n }\n\n private setApplyPhase(slotKey: string, phase: PageActionApplyPhase): PageActionSlotSyncResult {\n this.applyPhaseBySlot.set(slotKey, phase);\n this.deps.onApplyPhaseChanged(slotKey, phase);\n return { applyPhase: phase };\n }\n\n private matchesPending(binding: PageActionSlotBinding): PendingPageActionApply | null {\n if (isActionScopeRowKey(binding.rowKey)) return null;\n const pending = this.deps.getPendingPageActionApply();\n if (!pending) return null;\n const matched = matchesPendingPageActionApply(pending, {\n actionKey: binding.actionKey,\n pageContext: binding.pageContext,\n });\n return matched ? pending : null;\n }\n\n /**\n * Coalesce concurrent syncs, but re-run when a sync was requested while one\n * was already in flight (e.g.「应用到页面」pending arrives mid live-restore).\n */\n private async syncSlot(slotKey: string): Promise<PageActionSlotSyncResult> {\n const existing = this.syncInflight.get(slotKey);\n if (existing) {\n this.syncDirty.add(slotKey);\n return existing;\n }\n\n const runHolder: { current: Promise<PageActionSlotSyncResult> | null } = {\n current: null,\n };\n const run = (async (): Promise<PageActionSlotSyncResult> => {\n let last: PageActionSlotSyncResult = { applyPhase: this.getApplyPhase(slotKey) };\n try {\n do {\n this.syncDirty.delete(slotKey);\n last = await this.runSlotSync(slotKey);\n } while (this.syncDirty.has(slotKey) && this.slots.has(slotKey));\n return last;\n } finally {\n if (this.syncInflight.get(slotKey) === runHolder.current) {\n this.syncInflight.delete(slotKey);\n }\n }\n })();\n runHolder.current = run;\n\n this.syncInflight.set(slotKey, run);\n return run;\n }\n\n /** Path A — dedupe reconcile + SSE attach per actionKey across slots. */\n private async runLiveRestore(actionKey: string): Promise<void> {\n const key = actionKey.trim();\n if (!key) return;\n\n const existing = this.liveRestoreInflight.get(key);\n if (existing) {\n await existing;\n return;\n }\n\n const run = (async () => {\n await this.deps.reconcileActivePageActions({ actionKey: key });\n await this.deps.resumeActivePageActionStreams({ actionKey: key });\n })().finally(() => {\n if (this.liveRestoreInflight.get(key) === run) {\n this.liveRestoreInflight.delete(key);\n }\n });\n this.liveRestoreInflight.set(key, run);\n await run;\n }\n\n private async runSlotSync(slotKey: string): Promise<PageActionSlotSyncResult> {\n const binding = this.slots.get(slotKey);\n if (!binding) return { applyPhase: 'idle' };\n\n try {\n await this.deps.ensureLoggedIn();\n } catch {\n return this.setApplyPhase(slotKey, 'idle');\n }\n\n // Re-read binding after await — patch/unbind may have raced.\n const latest = this.slots.get(slotKey);\n if (!latest) return { applyPhase: 'idle' };\n\n // Path B —「应用到页面」:completed replay(与 live SSE 无关)\n if (latest.autoApplyPending && !isActionScopeRowKey(latest.rowKey)) {\n const pending = this.matchesPending(latest);\n if (pending) {\n if (!latest.ready) {\n return this.setApplyPhase(slotKey, 'waiting_ready');\n }\n if (this.replayInflight.has(pending.runId)) {\n return this.setApplyPhase(slotKey, 'replaying');\n }\n this.replayInflight.add(pending.runId);\n this.setApplyPhase(slotKey, 'replaying');\n try {\n await this.deps.replayPageAction(pending.runId);\n return this.setApplyPhase(slotKey, 'done');\n } catch {\n return this.setApplyPhase(slotKey, 'error');\n } finally {\n this.replayInflight.delete(pending.runId);\n }\n }\n if (this.getApplyPhase(slotKey) !== 'idle') {\n this.setApplyPhase(slotKey, 'idle');\n }\n }\n\n // Path A — live run:refresh / mount reconnect\n if (!latest.autoResume) {\n return { applyPhase: this.getApplyPhase(slotKey) };\n }\n\n await this.runLiveRestore(latest.actionKey);\n return { applyPhase: this.getApplyPhase(slotKey) };\n }\n}\n","/**\n * Source-of-truth SDK version string. Kept here (rather than importing\n * package.json) so the library can be consumed without JSON imports.\n *\n * This must be bumped together with `package.json.version` and the\n * `CHANGELOG.md` entry on every release.\n */\nexport const SDK_VERSION = '3.0.2';\n","/**\n * Generate a short, URL-safe random id. Uses `crypto.randomUUID` when\n * available (modern browsers + Node 19+) and falls back to `Math.random`\n * for very old engines or test environments.\n */\nexport function nanoId(prefix = 'id'): string {\n const cryptoLike = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (cryptoLike?.randomUUID) {\n return `${prefix}_${cryptoLike.randomUUID().replace(/-/g, '').slice(0, 12)}`;\n }\n const rand = Math.random().toString(36).slice(2, 14);\n return `${prefix}_${rand}`;\n}\n","import {\n applyAccessTokenHeader,\n clearAccessTokenHeader,\n} from '../auth/auth-headers';\nimport {\n parseAgentList,\n parseChatSessionDetailPage,\n parseChatSessionListPage,\n parseCreateSessionResponse,\n parsePostedMessage,\n parseSkillList,\n} from '../chat/chat-response';\nimport { useAuthStore } from '../auth/auth-store';\nimport {\n getSdkAccessTokenForDsn,\n isSdkAuthenticatedForDsn,\n waitForAuthStoreRehydration,\n} from '../auth/auth-session';\nimport { LoginGate, type PendingGateJob } from '../auth/login-gate';\nimport type { AppClientAuthData } from '../auth/auth-types';\nimport { ensureExtensionAuthResyncListener } from '../extension/auth-extension-resync';\nimport { AgentChatError } from '../lib/errors';\nimport { EventBus } from '../lib/events';\nimport { normalizeDsn, DSN_AUTH_HEADER, DEFAULT_BASE_URL } from '../lib/resolve';\nimport { parseChatSseEvent, type ChatSseUiAction } from '../chat/chat-sse';\nimport { isStaleAgentRunEvent, parseRunGeneration, parseSessionRunState, type SessionRunStateSnapshot } from '../chat/session-run';\nimport { buildClientSkillListQuery, resolveDefaultSkillId } from '../page/skill-client';\nimport { dispatchHostAction } from '../host-tool/host-action-registry';\nimport { hostActionSseToAgentAction, isDispatchableHostAction } from '../host-tool/host-action';\nimport { executeHostToolsFromAction, registerHostTool, runHostTool, undeclareHostTool, unregisterHostTool } from '../host-tool/host-tool-registry';\nimport {\n HostToolStreamManager,\n isHostToolStreamEnabled,\n} from '../host-tool/stream/host-tool-stream';\nimport type { HostActionSsePayload } from '../host-tool/stream/host-tool-stream.types';\nimport { isHostActionStreamPayload } from '../host-tool/stream/host-tool-stream.types';\nimport type { PageContextGate } from '../host-tool/stream/host-tool-stream-gate';\nimport { registerHostToolsWithSync, flushPendingHostToolSyncs } from '../host-tool/register-host-tools';\nimport {\n mergeRouteContext,\n readWindowRouteContext,\n} from '../page/route-context';\nimport { mergePageContextWithMentions } from '../page/context-mention';\nimport {\n mergeContextMentionRegistrations,\n resolveContextMentionsForSend,\n toRegisteredContextMention,\n} from '../page/context-mention-registry';\nimport { normalizeContextMentionInput } from '../page/context-mention-define';\nimport { createHttpClient } from '../http';\nimport { AuthService, AgentService, ChatService, FeedbackService, HostToolService, AgentRunService, PageActionService, ApprovalService, AutomationService, AppToolService, DEFAULT_MESSAGE_PAGE_SIZE, DEFAULT_SESSION_PAGE_SIZE } from '../services';\nimport type {\n AppToolCallableList,\n AppToolInvokeInput,\n AppToolInvokeResult,\n} from '../services/app-tool.service';\nimport type { MessageSendContext } from '../services/chat.service';\nimport { SessionManager } from '../auth/auth';\nimport {\n isPersistedMessageId,\n parsePersistedMessageId,\n} from '../feedback/feedback-utils';\nimport {\n applyPatches,\n applyStreamDelta,\n applyStreamFull,\n blocksToText,\n parseStoredBlocks,\n unwrapBlocksJsonEnvelope,\n type CoreMessageBlock,\n} from '../chat/message-blocks';\nimport {\n parseAgentRunDetail,\n readSkillIntentMismatchObservation,\n readSkillTurnContract,\n resolveAlignmentSteps,\n isRequestedSkillActuallyUsed,\n shouldShowIntentFirstBanner,\n shouldShowSkillClarifyCard,\n} from '../chat/skill-intent-alignment';\nimport {\n consumePageActionRunStream,\n pageGateFromPageContext,\n rethrowPageActionError,\n PAGE_ACTION_STREAM_KEY_PREFIX,\n} from '../page/page-action-client';\nimport {\n buildEntityCommit,\n extractBrainClarifyFromRunSteps,\n formatBrainClarifyCandidateLabel,\n isBrainAskUserErrorCode,\n} from '../page/brain-clarify';\nimport {\n defaultPageActionProgressLabel,\n pageActionAwaitingClarifyLabel,\n pageActionAlreadyAwaitingApprovalTip,\n pageActionAlreadyRunningTip,\n pageActionReuseCheckingLabel,\n pageActionReusedMessage,\n pageActionReusingLabel,\n pageActionTaskAwaitingApprovalSubtitle,\n pageActionTaskRunningSubtitle,\n appendPageActionNarrativeItems,\n resolvePageWorkflowProgressLabel,\n type PageWorkflowEvent,\n} from '../page/page-action-workflow-progress';\nimport { readLaunchSourceRect } from '../page/page-action-launch';\nimport { PageActionReuseHintCache } from '../page/page-action-reuse-cache';\nimport { buildPageActionInvokePageContextSnapshot } from '../page/page-context-snapshot';\nimport {\n resolvePageContextNavigateTarget,\n type ApplyPageActionToPageResult,\n} from '../page/page-context-navigate';\nimport {\n clearPendingPageActionApplyStorage,\n matchesPendingPageActionApply,\n readPendingPageActionApply,\n writePendingPageActionApply,\n} from '../page/pending-page-action-apply';\nimport {\n AUTOMATION_RECONCILE_STALE_MS,\n buildOptimisticAutomationTaskItem,\n collectActivePageActionKeys,\n findActivePageActionKeyForActionKey,\n formatPageActionDisplayTitle,\n countActiveTrackedRuns,\n isActiveAutomationTaskStatus,\n lifecyclePhaseToTaskStatus,\n mergeOptimisticRunsIntoList,\n mergeRegistryFromActiveListItems,\n patchAutomationTaskListItem,\n pruneStaleTrackedRuns,\n removeAutomationTaskListItem,\n taskMatchesStatusFilter,\n upsertAutomationTaskListItem,\n type TrackedAutomationRun,\n} from '../automation/automation-run-tracker';\nimport { resolveAutomationTaskListHasMore } from '../automation/automation-response';\nimport {\n createAutomationTaskTabCaches,\n getAutomationTaskTabCache,\n writeAutomationTaskTabCache,\n type AutomationTaskTabCache,\n} from '../automation/automation-task-tab-store';\nimport type {\n AgentChatEventMap,\n AgentChatErrorPayload,\n AgentChatInstance,\n AgentChatLoginCredentials,\n AgentChatLifecycle,\n AgentChatOptions,\n AgentChatPageContext,\n AgentChatHostAction,\n AgentChatRouteContext,\n AgentChatState,\n AgentMessage,\n ContextMentionAttachment,\n ContextMentionDefinition,\n ContextMentionRegistration,\n RegisteredContextMention,\n RegisterContextMentionsOptions,\n AgentStreamState,\n AgentsEmptyReason,\n ChatAgentSummary,\n ChatSessionSummary,\n ChatSkillSummary,\n HostToolHandler,\n MessageFeedbackDownReasonTag,\n MessageFeedbackView,\n PrepareSessionOptions,\n PrepareSessionResult,\n RegisterHostToolsOptions,\n SkillIntentBannerState,\n SkillIntentClarifyState,\n BrainClarifyUiState,\n BrainClarifyPayload,\n SkillTurnActiveState,\n SkillTurnContractView,\n UpsertMessageFeedbackBody,\n UserContext,\n WriteConfirmationState,\n WriteGate,\n SessionRunSnapshot,\n PageBotInvokeInput,\n PageBotStreamResult,\n PendingPageActionApply,\n InvokePageActionRequest,\n ApprovalInboxList,\n ApprovalInboxStatusFilter,\n ApprovalDetail,\n ApprovalConfirmResult,\n ApprovalDecideResult,\n ApprovalRejectResult,\n ApprovalExecutionCompletedPayload,\n ApprovalExecutionOutcome,\n DraftReviewDecision,\n PageAgentLifecyclePayload,\n PageAgentSource,\n PageAgentErrorContext,\n PageAgentAwaitingApprovalPayload,\n OpenApprovalInboxPayload,\n OpenAutomationTaskCenterPayload,\n OpenPageActionFeedbackPayload,\n PageActionFeedbackCatalogItem,\n PageActionFeedbackCatalogQuery,\n PageActionFeedbackSummary,\n PageActionFeedbackView,\n PageActionRolloutCheckItem,\n UpsertPageActionFeedbackInput,\n CreatePageActionWishInput,\n PageActionWishList,\n PageActionWishQuery,\n PageActionWishView,\n AutoAgentBinding,\n AutomationTaskList,\n AutomationTaskListItem,\n AutomationTaskDetail,\n AutomationTaskStatus,\n AutomationTaskStatusFilter,\n InvokePageActionAccepted,\n PageActionSubmittedPayload,\n PageActionSseLifecycle,\n PageActionRowState,\n PageActionPhase,\n PageActionReuseHint,\n PageActionReusePromptHandler,\n PageActionReusePromptRequest,\n PageActionReusableItem,\n PageActionBrainClarifyInvokeSnapshot,\n PageActionBrainClarifyPromptRequest,\n EntityCommit,\n} from '../../types';\nimport {\n buildPageActionRowState,\n derivePageActionRowFlags,\n resolvePageActionRowKey,\n resolveRestoredPageActionRowKey,\n taskStatusToPageActionPhase,\n} from '../page/page-action-rows';\nimport {\n PageActionCoordinator,\n type PageActionSlotBinding,\n} from '../page/page-action-coordinator';\nimport { SDK_VERSION } from '../../utils/sdk-version';\nimport { nanoId } from '../../utils/id';\n\nfunction trimRight(s: string): string {\n return s.replace(/\\/+$/, '');\n}\n\nconst APPROVAL_INBOX_PAGE_SIZE = 20;\nconst AUTOMATION_TASK_PAGE_SIZE = 20;\nconst MAX_RECENT_AUTOMATION_RUN_IDS = 20;\n\nfunction normalizeSessionId(sessionId: string): string {\n return sessionId.trim().toLowerCase();\n}\n\nfunction mergeSessionSummaries(\n existing: ChatSessionSummary[],\n incoming: ChatSessionSummary[],\n): ChatSessionSummary[] {\n const seen = new Set(existing.map((row) => normalizeSessionId(row.sessionId)));\n const merged = [...existing];\n for (const row of incoming) {\n const key = normalizeSessionId(row.sessionId);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(row);\n }\n return merged;\n}\n\nfunction mergeOlderMessages(\n existing: AgentMessage[],\n older: AgentMessage[],\n): AgentMessage[] {\n const seen = new Set(existing.map((message) => String(message.id)));\n const prepended: AgentMessage[] = [];\n for (const message of older) {\n const key = String(message.id);\n if (seen.has(key)) continue;\n seen.add(key);\n prepended.push(message);\n }\n return [...prepended, ...existing];\n}\n\ninterface SessionMessagesCacheEntry {\n messages: AgentMessage[];\n page: number;\n hasMore: boolean;\n agentId?: string;\n}\n\nfunction createEmptyAgentStream(): AgentStreamState {\n return { phase: 'thinking', thinkText: '', resultText: '' };\n}\n\n/** Finalize a streamed assistant turn (result only; thinking is not kept). */\nfunction finalizeAgentReply(\n message: AgentMessage,\n stream: AgentStreamState,\n overrides: Partial<AgentMessage> = {},\n): AgentMessage {\n const resultText =\n (overrides.content?.type === 'text' ? overrides.content.text : undefined) ??\n (stream.resultText || message.content.text);\n const rawBlocks = overrides.blocks ?? stream.resultBlocks ?? message.blocks;\n const parsedFromText = parseStoredBlocks(resultText);\n const blocks = parsedFromText ?? unwrapBlocksJsonEnvelope((rawBlocks ?? []) as CoreMessageBlock[]);\n const text = parsedFromText ? blocksToText(blocks) : resultText;\n return {\n ...message,\n ...overrides,\n status: overrides.status ?? 'sent',\n content: { type: 'text', text },\n blocks,\n thinkText: undefined,\n stream: undefined,\n };\n}\n\ninterface ServerMessage {\n id: number | string;\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string | null;\n createdAt: string | number | Date;\n}\n\ninterface SessionStreamHandle {\n abort: AbortController;\n targetMessageId: string | null;\n}\n\ninterface SessionRunState {\n sessionGeneration: number;\n activeRunId: number | null;\n activeTurnId: number | null;\n pendingJobCount: number;\n redisBacked: boolean;\n}\n\ninterface InternalState {\n options: AgentChatOptions;\n /** Opaque DSN string the consumer supplied; forwarded as `x-app-dsn`. */\n dsn: string;\n /**\n * Backend base URL used for **all** API calls (sessions, messages, login,\n * and the init-time `/app-client/auth` ping). Normalized to have no\n * trailing slash. Mirrors the value of {@link InternalState.options.baseUrl}\n * after applying defaults.\n */\n apiBaseUrl: string;\n http: ReturnType<typeof createHttpClient>;\n auth: AuthService;\n chat: ChatService;\n agent: AgentService;\n feedback: FeedbackService;\n hostTool: HostToolService;\n agentRun: AgentRunService;\n pageAction: PageActionService;\n approval: ApprovalService;\n automation: AutomationService;\n appTool: AppToolService;\n session: SessionManager;\n abortControllers: Set<AbortController>;\n isOpen: boolean;\n /** `POST /app-client/auth` succeeded at init; gates the floating launcher. */\n isClientAuthenticated: boolean;\n isLoggedIn: boolean;\n /** Sessions/agents/messages bootstrap completed for the current login. */\n catalogHydrated: boolean;\n sessions: ChatSessionSummary[];\n sessionsPage: number;\n sessionsPageSize: number;\n sessionsHasMore: boolean;\n sessionsLoadingMore: boolean;\n activeSessionId: string | null;\n activeSessionMessagesPage: number;\n activeSessionMessagesHasMore: boolean;\n sessionMessagesLoadingMore: boolean;\n sessionMessagesPageSize: number;\n sessionMessagesCache: Map<string, SessionMessagesCacheEntry>;\n agents: ChatAgentSummary[];\n skills: ChatSkillSummary[];\n selectedAgentId: string | null;\n autoAgent: AutoAgentBinding | null;\n selectedSkillId: string | null;\n agentsLoading: boolean;\n skillsLoading: boolean;\n agentsEmptyReason: AgentsEmptyReason;\n /** User JWT used as `Authorization: Bearer` on C-end APIs. */\n userJwt: string | null;\n /** Open SSE connections keyed by normalized session id. */\n sessionStreams: Map<string, SessionStreamHandle>;\n /** Per-session run coordinator state (`generation` / active `runId`). */\n sessionRuns: Map<string, SessionRunState>;\n messages: AgentMessage[];\n lastError: AgentChatErrorPayload | null;\n writeConfirmation: WriteConfirmationState | null;\n /** Pending write confirmations keyed by normalized session id. */\n writeConfirmationsBySession: Map<string, WriteConfirmationState>;\n approvalInboxLoading: boolean;\n approvalInboxLoadingMore: boolean;\n approvalInboxHasMore: boolean;\n approvalInboxStatusFilter: ApprovalInboxStatusFilter;\n approvalInboxPendingCount: number;\n approvalInboxItems: ApprovalInboxList['items'];\n automationTaskLoading: boolean;\n automationTaskLoadingMore: boolean;\n automationTaskHasMore: boolean;\n automationTaskTotal: number;\n automationTaskStatusFilter: AutomationTaskStatusFilter;\n automationTaskActiveCount: number;\n automationTaskItems: AutomationTaskList['items'];\n /** Per-tab list cache — switching tabs restores without refetching page 1. */\n automationTaskTabCaches: Map<AutomationTaskStatusFilter, AutomationTaskTabCache>;\n automationRecentRunIds: number[];\n automationTaskSelectedDetail: AutomationTaskDetail | null;\n automationTaskDetailLoading: boolean;\n skillIntentBanner: SkillIntentBannerState | null;\n skillIntentClarify: SkillIntentClarifyState | null;\n brainClarify: BrainClarifyUiState | null;\n skillTurnContract: SkillTurnContractView | null;\n skillTurnActive: SkillTurnActiveState | null;\n /** Last user message text for the active turn (skill clarify resend). */\n lastTurnUserMessage: string | null;\n skillPickerOpen: boolean;\n downReasonTagsCache: MessageFeedbackDownReasonTag[] | null;\n /** Latest extended page context (prop or {@link setPageContext}). */\n pageContext: AgentChatPageContext | null;\n /** Host override for route path / params (merged with window on sync). */\n routeContextOverride: AgentChatRouteContext | null;\n /** Resolved route sent with every message. */\n routeContext: AgentChatRouteContext | null;\n attachPageContext: boolean;\n appClientId: number | null;\n contextMentionRegistry: Map<string, ContextMentionRegistration>;\n}\n\nfunction defaultLocale(): string {\n if (typeof navigator !== 'undefined' && navigator.language) return navigator.language;\n return 'en';\n}\n\nfunction browserOrigin(): string {\n if (typeof window !== 'undefined' && window.location?.origin) return window.location.origin;\n return 'unknown://sdk';\n}\n\nexport class AgentChatClient implements AgentChatInstance {\n readonly id: string;\n private bus = new EventBus<AgentChatEventMap>();\n private lifecycle: AgentChatLifecycle = 'uninitialized';\n private state: InternalState | null = null;\n private stateChangeListeners = new Set<() => void>();\n /** Bumped when session/messages are changed locally; stale `selectSession` loads are ignored. */\n private sessionEpoch = 0;\n /**\n * Cached `AgentChatState` snapshot returned by {@link getState}. React's\n * `useSyncExternalStore` requires `getSnapshot` to return the same object\n * reference until the store actually changes — otherwise concurrent\n * rendering treats it as torn state, repeatedly remounts the subtree, and\n * (combined with antd's cssinjs cache) the launcher visibly flashes and\n * disappears. We invalidate this cache from {@link notifyStateChange}.\n */\n private stateSnapshot: AgentChatState | null = null;\n private authStoreUnsub: (() => void) | undefined;\n private prepareAbort: AbortController | null = null;\n private prepareTimer: ReturnType<typeof setTimeout> | null = null;\n private lastPrepareFingerprint: string | null = null;\n /** Ignores stale `refreshSkills` results when page or agent changes quickly. */\n private skillsLoadToken = 0;\n /** Target assistant message id before SSE connect registers a stream handle. */\n private pendingStreamTargets = new Map<string, string>();\n /** In-flight `connectSessionStream` per session (prevents duplicate SSE). */\n private sessionStreamConnects = new Map<string, Promise<void>>();\n /** Skip auto-reconnect after intentional `abortSessionStream` (e.g. session switch). */\n private sessionStreamSuppressReconnect = new Set<string>();\n /** Debounced reconnect timers per session. */\n private sessionStreamReconnectTimers = new Map<string, ReturnType<typeof setTimeout>>();\n /** Exponential backoff attempt counter per session. */\n private sessionStreamReconnectAttempts = new Map<string, number>();\n /** Per-session Host Tool DSL v1 reducer state. */\n private hostToolStreamManagers = new Map<string, HostToolStreamManager>();\n /** In-flight Page Bot invokes keyed by `clientActionId`. */\n private pageActionInFlightKeys = new Set<string>();\n /** Coalesce concurrent `GET /approval/inbox` refreshes (list + badge filter). */\n private approvalInboxRefreshPromise: Promise<ApprovalInboxList> | null = null;\n /** Coalesce concurrent pending-count badge refreshes. */\n private approvalPendingCountRefreshPromise: Promise<void> | null = null;\n /**\n * PageAction runs that already emitted awaiting-approval UI for this session.\n * Prevents duplicate notifications + inbox fetches when both early return and\n * run SSE report the same pause (common on 409 / awaitStream:false).\n */\n private pageActionAwaitingApprovalNotified = new Set<number>();\n /** Coalesce concurrent `GET /automation/tasks` refreshes. */\n private automationTaskRefreshPromise: Promise<AutomationTaskList> | null = null;\n private automationTaskRefreshCacheKey: string | null = null;\n /** Bumps on full refresh to drop stale in-flight append publishes. */\n private automationTaskListPublishSeq = 0;\n /** Background PageAction run stream abort controllers keyed by runId. */\n private pageActionRunAborts = new Map<number, AbortController>();\n /** In-flight consume promises keyed by runId — dedupe concurrent attach/replay. */\n private pageActionRunStreamPromises = new Map<number, Promise<PageBotStreamResult>>();\n /** 「应用到页面」pending intent (also mirrored to sessionStorage). */\n private pendingPageActionApply: PendingPageActionApply | null = null;\n /** Built-in reuse popover (registered by ChatRoot). */\n private pageActionReusePromptHandler: PageActionReusePromptHandler | null = null;\n /**\n * Bumped when the user dismisses a docked reuse apply (`撤销`).\n * `applyPageActionReuse` skips post-await row locks when the epoch changed.\n */\n private pageActionReuseDismissEpochByRowKey = new Map<string, number>();\n /** Per-entity reuse-hint cache — avoid re-query on popover close + re-click. */\n private pageActionReuseHintCache = new PageActionReuseHintCache();\n /** Last invoke snapshots for Brain clarify re-invoke (keyed by rowKey / runId). */\n private pageActionInvokeSnapshotsByRowKey = new Map<\n string,\n PageActionBrainClarifyInvokeSnapshot & { launchAnchor?: HTMLElement | null }\n >();\n private pageActionInvokeSnapshotsByRunId = new Map<\n number,\n PageActionBrainClarifyInvokeSnapshot & { launchAnchor?: HTMLElement | null }\n >();\n /** Last `GET /page-action/catalog` (global feedback list). */\n private pageActionFeedbackCatalogItems: PageActionFeedbackCatalogItem[] = [];\n /** Display names for optimistic task-center titles. */\n private pageActionFeedbackNames = new Map<string, string>();\n /** In-memory active PageAction runs for badge + optimistic task center updates. */\n private automationRunRegistry = new Map<number, TrackedAutomationRun>();\n /** Per-row PageAction UI slots keyed by host rowKey (list pages). */\n private pageActionRows = new Map<string, PageActionRowState>();\n /** Maps runId → rowKey for lifecycle / hydrate updates. */\n private pageActionRunToRowKey = new Map<number, string>();\n /** Last `GET /automation/tasks` reconcile timestamp (visibility fallback). */\n private automationTasksLastSyncedAt = 0;\n /** Host calls before `init()` completes — applied when state is created. */\n private pendingRouteContextOverride: AgentChatRouteContext | null | undefined;\n private pendingPageContext: AgentChatPageContext | null | undefined;\n private pendingAttachPageContext: boolean | undefined;\n private pendingContextMentionRegistry = new Map<string, ContextMentionRegistration>();\n\n private initGate: LoginGate;\n private loginGate: LoginGate;\n private pageActionCoordinator: PageActionCoordinator;\n\n constructor(id: string = nanoId('inst')) {\n this.id = id;\n this.pageActionCoordinator = new PageActionCoordinator({\n ensureLoggedIn: () => this.ensureLoggedIn('pageActionSlotSync'),\n reconcileActivePageActions: (opts) => this.reconcileActivePageActions(opts),\n resumeActivePageActionStreams: (opts) => this.resumeActivePageActionStreams(opts),\n replayPageAction: (runId) => this.replayPageAction(runId),\n getPendingPageActionApply: () => this.getPendingPageActionApply(),\n onApplyPhaseChanged: (slotKey, phase) => {\n this.bus.emit('pageActionSlotApplyPhaseChanged', { slotKey, phase });\n },\n });\n const notifyPending = () => this.notifyStateChange();\n this.initGate = new LoginGate(\n () => this.state != null && this.lifecycle === 'initialized',\n 'init',\n notifyPending,\n );\n this.loginGate = new LoginGate(\n () => Boolean(this.state?.isLoggedIn),\n 'login',\n notifyPending,\n );\n }\n\n // ------------------------------------------------------------------ public\n\n /**\n * Merge React prop / option changes without a full re-init (same DSN).\n * Keeps `pageContext` / `attachPageContext` in sync when StrictMode or\n * `<AgentChat>` re-runs `init()` on an already-initialized client.\n */\n applyRuntimeOptions(\n options: Pick<AgentChatOptions, 'attachPageContext' | 'pageContext'>,\n ): void {\n const state = this.state;\n if (!state) {\n if (options.attachPageContext !== undefined) {\n this.pendingAttachPageContext = options.attachPageContext === true;\n }\n if (options.pageContext !== undefined) {\n this.pendingPageContext = options.pageContext;\n }\n this.notifyStateChange();\n return;\n }\n\n let changed = false;\n if (options.attachPageContext !== undefined) {\n const attach = options.attachPageContext === true;\n if (state.attachPageContext !== attach) {\n state.attachPageContext = attach;\n changed = true;\n }\n }\n if (options.pageContext !== undefined) {\n state.pageContext = options.pageContext;\n state.options = { ...state.options, pageContext: options.pageContext ?? undefined };\n changed = true;\n this.schedulePrepareSession();\n }\n if (changed) {\n this.notifyStateChange();\n }\n }\n\n async init(options: AgentChatOptions): Promise<this> {\n ensureExtensionAuthResyncListener();\n\n if (this.state) {\n if (this.state.options.dsn === options.dsn) {\n if (typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(\n '[agent-chat] init() called twice with the same DSN — keeping existing instance state.',\n );\n }\n this.applyRuntimeOptions({\n attachPageContext: options.attachPageContext,\n pageContext: options.pageContext,\n });\n return this;\n }\n throw new AgentChatError(\n 'ALREADY_INITIALIZED',\n 'AgentChat is already initialized with a different DSN. Call destroy() first.',\n );\n }\n\n if (!options || typeof options !== 'object') {\n throw new AgentChatError('INVALID_OPTIONS', 'init(options): options object is required');\n }\n\n // `baseUrl` is the single root for every SDK request.\n const apiBaseUrl = trimRight(\n (options.baseUrl?.trim() || DEFAULT_BASE_URL).replace(/\\s+/g, ''),\n );\n\n const dsn = normalizeDsn(options.dsn);\n await waitForAuthStoreRehydration();\n const storedAccountToken = useAuthStore.getState().getAccessTokenForDsn(dsn);\n const accountToken =\n (typeof options.accountToken === 'string' && options.accountToken.trim()) ||\n (typeof options.userAccessToken === 'string' && options.userAccessToken.trim()) ||\n storedAccountToken ||\n null;\n\n const http = createHttpClient({\n apiBase: apiBaseUrl,\n defaultHeaders: {\n [DSN_AUTH_HEADER]: dsn,\n 'X-Agent-Sdk-Version': SDK_VERSION,\n ...(options.headers ?? {}),\n },\n });\n const auth = new AuthService(http);\n const chat = new ChatService(http);\n const feedback = new FeedbackService(http);\n const hostTool = new HostToolService(http);\n const agentRun = new AgentRunService(http);\n const pageAction = new PageActionService(http);\n const approval = new ApprovalService(http);\n const automation = new AutomationService(http);\n const appTool = new AppToolService(http);\n\n let authData: AppClientAuthData | null = null;\n let clientAuthenticated = false;\n let resolvedUserJwt: string | null = null;\n let initAuthError: AgentChatErrorPayload | null = null;\n\n try {\n authData = await auth.authenticate(dsn, accountToken);\n clientAuthenticated = true;\n resolvedUserJwt = authData.accessToken?.trim() ?? null;\n useAuthStore.getState().setAuth(dsn, authData);\n if (resolvedUserJwt) {\n applyAccessTokenHeader(http, resolvedUserJwt);\n }\n } catch (err) {\n initAuthError = toAgentChatErrorPayload(err);\n if (options.debug) {\n console.warn('[agent-chat] app-client auth failed during init:', initAuthError);\n }\n }\n\n const agent = new AgentService(http, () => ({\n dsn: this.state?.dsn ?? dsn,\n }));\n\n const sdkVersion = SDK_VERSION;\n\n const session = new SessionManager({\n context: {\n sdkVersion,\n origin: browserOrigin(),\n locale: options.locale ?? defaultLocale(),\n user: options.user ?? authUserToContext(authData?.user),\n },\n });\n\n this.state = {\n options,\n dsn,\n apiBaseUrl,\n http,\n auth,\n chat,\n agent,\n feedback,\n hostTool,\n agentRun,\n pageAction,\n approval,\n automation,\n appTool,\n session,\n abortControllers: new Set(),\n isOpen: false,\n isClientAuthenticated: clientAuthenticated,\n isLoggedIn: Boolean(resolvedUserJwt) || isSdkAuthenticatedForDsn(dsn),\n catalogHydrated: false,\n sessions: [],\n sessionsPage: 0,\n sessionsPageSize: DEFAULT_SESSION_PAGE_SIZE,\n sessionsHasMore: false,\n sessionsLoadingMore: false,\n activeSessionId: null,\n activeSessionMessagesPage: 0,\n activeSessionMessagesHasMore: false,\n sessionMessagesLoadingMore: false,\n sessionMessagesPageSize: DEFAULT_MESSAGE_PAGE_SIZE,\n sessionMessagesCache: new Map(),\n agents: options.agents ? [...options.agents] : [],\n skills: [],\n selectedAgentId: options.defaultAgentId?.trim() ?? null,\n autoAgent: null,\n selectedSkillId: options.defaultSkillId?.trim() ?? null,\n agentsLoading: false,\n skillsLoading: false,\n agentsEmptyReason: null,\n userJwt: resolvedUserJwt ?? getSdkAccessTokenForDsn(dsn),\n sessionStreams: new Map(),\n sessionRuns: new Map(),\n messages: [],\n lastError: initAuthError,\n writeConfirmation: null,\n writeConfirmationsBySession: new Map(),\n approvalInboxLoading: false,\n approvalInboxLoadingMore: false,\n approvalInboxHasMore: false,\n approvalInboxStatusFilter: 'pending',\n approvalInboxPendingCount: 0,\n approvalInboxItems: [],\n automationTaskLoading: false,\n automationTaskLoadingMore: false,\n automationTaskHasMore: false,\n automationTaskTotal: 0,\n automationTaskStatusFilter: 'active',\n automationTaskActiveCount: 0,\n automationTaskItems: [],\n automationTaskTabCaches: createAutomationTaskTabCaches(),\n automationRecentRunIds: [],\n automationTaskSelectedDetail: null,\n automationTaskDetailLoading: false,\n skillIntentBanner: null,\n skillIntentClarify: null,\n brainClarify: null,\n skillTurnContract: null,\n skillTurnActive: null,\n lastTurnUserMessage: null,\n skillPickerOpen: false,\n downReasonTagsCache: null,\n pageContext: options.pageContext ?? null,\n routeContextOverride: null,\n routeContext: null,\n attachPageContext: options.attachPageContext === true,\n appClientId: authData?.appClient?.id ?? null,\n contextMentionRegistry: new Map(),\n };\n this.lifecycle = 'initialized';\n this.stateSnapshot = null;\n this.initGate.reconcile();\n\n this.authStoreUnsub = useAuthStore.subscribe(() => {\n this.syncAuthFromStore();\n });\n this.syncAuthFromStore();\n\n this.applyPendingRuntimeConfig(this.state);\n this.syncRouteContextFromWindow();\n\n this.applyStaticSkills(this.state);\n this.syncDefaultAgentSelection(this.state);\n\n if (options.onReady) {\n this.bus.on('ready', options.onReady);\n }\n\n queueMicrotask(() => this.bus.emit('ready', undefined));\n\n if (this.isHostToolServerSyncReady()) {\n void flushPendingHostToolSyncs(this).catch((err) => {\n if (options.debug) {\n console.warn('[agent-chat] flushPendingHostToolSyncs failed:', err);\n }\n });\n }\n\n if (options.autoOpen) {\n this.open();\n }\n\n this.refreshApprovalBadgeBestEffort();\n this.notifyPageActionAuthReady();\n this.scheduleAutomationTasksBestEffort();\n\n return this;\n }\n\n async login(credentials: AgentChatLoginCredentials): Promise<void> {\n await this.ensureInitialized('login');\n const state = this.requireState('login');\n const email = credentials?.email?.trim();\n const password = credentials?.password?.trim();\n if (!email || !password) {\n throw new AgentChatError('INVALID_OPTIONS', 'login requires email and password');\n }\n\n let loginAuth: AppClientAuthData;\n try {\n loginAuth = await state.auth.login(email, password);\n } catch (err) {\n if (err instanceof AgentChatError && err.code === 'TRANSPORT_FAILED') {\n throw new AgentChatError('LOGIN_FAILED', err.message, { cause: err, details: err.details });\n }\n throw err;\n }\n\n const accountToken = loginAuth.accessToken?.trim();\n if (!accountToken) {\n throw new AgentChatError('LOGIN_FAILED', 'Login succeeded but no access token was returned.');\n }\n\n clearAccessTokenHeader(state.http);\n const authData = await state.auth.authenticate(state.dsn, accountToken);\n this.commitAuthSession(authData);\n\n void flushPendingHostToolSyncs(this).catch((err) => {\n if (state.options.debug) {\n console.warn('[agent-chat] flushPendingHostToolSyncs failed:', err);\n }\n });\n if (state.isOpen) {\n void this.refreshAgentCatalog().catch(() => {\n /* catalog is optional */\n });\n }\n this.refreshApprovalBadgeBestEffort();\n this.scheduleAutomationTasksBestEffort();\n }\n\n logout(): void {\n const state = this.state;\n if (!state) return;\n this.abortAllSessionStreams(state);\n this.cancelAllSessionStreamReconnects();\n state.isLoggedIn = false;\n clearAccessTokenHeader(state.http);\n useAuthStore.getState().clearAuth();\n state.session.reset();\n state.sessions = [];\n state.sessionsPage = 0;\n state.sessionsHasMore = false;\n state.sessionsLoadingMore = false;\n state.activeSessionId = null;\n state.activeSessionMessagesPage = 0;\n state.activeSessionMessagesHasMore = false;\n state.sessionMessagesLoadingMore = false;\n state.sessionMessagesCache.clear();\n state.agents = [];\n state.skills = [];\n state.selectedAgentId = null;\n state.autoAgent = null;\n state.selectedSkillId = null;\n state.agentsLoading = false;\n state.skillsLoading = false;\n state.agentsEmptyReason = null;\n state.userJwt = null;\n state.messages = [];\n state.sessionStreams.clear();\n state.sessionRuns.clear();\n state.writeConfirmationsBySession.clear();\n state.approvalInboxItems = [];\n state.approvalInboxLoading = false;\n state.approvalInboxLoadingMore = false;\n state.approvalInboxHasMore = false;\n state.approvalInboxStatusFilter = 'pending';\n state.approvalInboxPendingCount = 0;\n state.automationTaskItems = [];\n state.automationTaskLoading = false;\n state.automationTaskLoadingMore = false;\n state.automationTaskHasMore = false;\n state.automationTaskTotal = 0;\n state.automationTaskStatusFilter = 'active';\n state.automationTaskTabCaches = createAutomationTaskTabCaches();\n state.automationTaskActiveCount = 0;\n state.automationRecentRunIds = [];\n state.automationTaskSelectedDetail = null;\n state.automationTaskDetailLoading = false;\n this.abortAllPageActionRunStreams();\n this.pageActionInFlightKeys.clear();\n this.pageActionAwaitingApprovalNotified.clear();\n this.clearAutomationRunRegistry();\n state.catalogHydrated = false;\n this.pendingStreamTargets.clear();\n this.sessionStreamConnects.clear();\n this.hostToolStreamManagers.clear();\n this.notifyStateChange();\n }\n\n isLoggedIn(): boolean {\n this.syncAuthFromStore();\n return this.state?.isLoggedIn ?? false;\n }\n\n /** 当前因 init / login 门禁而挂起的任务快照(调试 / UI 用) */\n getPendingGateJobs(): PendingGateJob[] {\n return [...this.initGate.getPendingJobs(), ...this.loginGate.getPendingJobs()];\n }\n\n private snapshotPendingGateJobs(): PendingGateJob[] {\n return this.getPendingGateJobs();\n }\n\n /** 将 persist auth store 与 instance HTTP 头对齐(SSOT:useAuthStore) */\n syncAuthFromStore(): void {\n const state = this.state;\n if (!state) {\n return;\n }\n const token = useAuthStore.getState().getAccessTokenForDsn(state.dsn);\n const shouldBeLoggedIn = Boolean(token?.trim());\n if (shouldBeLoggedIn) {\n if (state.userJwt !== token || !state.isLoggedIn) {\n state.userJwt = token;\n state.isLoggedIn = true;\n applyAccessTokenHeader(state.http, token!);\n this.notifyStateChange();\n this.loginGate.reconcile();\n this.notifyPageActionAuthReady();\n }\n return;\n }\n if (state.isLoggedIn || state.userJwt) {\n state.userJwt = null;\n state.isLoggedIn = false;\n clearAccessTokenHeader(state.http);\n this.notifyStateChange();\n }\n }\n\n /**\n * 登录 / 认证完成后的唯一提交点:写 store、对齐 instance、唤醒 login 门禁。\n * login() 在 authenticate 成功前不写 store,避免中途误触发 reconcile。\n */\n private commitAuthSession(authData: AppClientAuthData): void {\n const state = this.requireState('commitAuthSession');\n const userJwt = authData.accessToken?.trim();\n if (!userJwt) {\n throw new AgentChatError('LOGIN_FAILED', 'App client auth succeeded but accessToken is missing');\n }\n\n useAuthStore.getState().setAuth(state.dsn, authData);\n applyAccessTokenHeader(state.http, userJwt);\n state.userJwt = userJwt;\n state.isLoggedIn = true;\n state.isClientAuthenticated = true;\n state.appClientId = authData.appClient?.id ?? state.appClientId;\n this.notifyStateChange();\n this.loginGate.reconcile();\n this.notifyPageActionAuthReady();\n }\n\n private notifyPageActionAuthReady(): void {\n if (!this.state?.isLoggedIn) return;\n this.pageActionCoordinator.onAuthReady();\n }\n\n bindPageActionSlot(\n binding: {\n actionKey: string;\n rowKey: string;\n pageContext?: AgentChatPageContext | null;\n ready?: boolean;\n autoResume?: boolean;\n autoApplyPending?: boolean;\n },\n ): () => void {\n const normalized: PageActionSlotBinding = {\n actionKey: binding.actionKey.trim(),\n rowKey: binding.rowKey.trim(),\n pageContext: binding.pageContext ?? null,\n ready: binding.ready !== false,\n autoResume: binding.autoResume !== false,\n autoApplyPending: binding.autoApplyPending !== false,\n };\n return this.pageActionCoordinator.bind(normalized);\n }\n\n patchPageActionSlot(\n slotKey: string,\n patch: {\n pageContext?: AgentChatPageContext | null;\n ready?: boolean;\n autoResume?: boolean;\n autoApplyPending?: boolean;\n },\n ): void {\n this.pageActionCoordinator.patch(slotKey, patch);\n }\n\n /** @internal demo / integration — registered PageAction slots */\n listBoundPageActionSlots(): PageActionSlotBinding[] {\n return this.pageActionCoordinator.listBindings();\n }\n\n destroy(): void {\n this.pendingRouteContextOverride = undefined;\n this.pendingPageContext = undefined;\n this.pendingAttachPageContext = undefined;\n this.pendingContextMentionRegistry = new Map();\n this.pageActionReuseHintCache.clear();\n this.initGate.cancelAll();\n this.loginGate.cancelAll();\n if (!this.state) return;\n\n this.authStoreUnsub?.();\n this.authStoreUnsub = undefined;\n\n this.cancelScheduledPrepare();\n this.abortAllSessionStreams(this.state);\n this.cancelAllSessionStreamReconnects();\n this.pendingStreamTargets.clear();\n this.sessionStreamConnects.clear();\n this.hostToolStreamManagers.clear();\n this.pageActionInFlightKeys.clear();\n this.pageActionAwaitingApprovalNotified.clear();\n this.abortAllPageActionRunStreams();\n this.clearAutomationRunRegistry();\n this.pendingPageActionApply = null;\n\n for (const ctrl of this.state.abortControllers) {\n try {\n ctrl.abort();\n } catch {\n /* noop */\n }\n }\n this.state.abortControllers.clear();\n\n this.state.session.reset();\n this.state.isOpen = false;\n this.state = null;\n this.lifecycle = 'destroyed';\n this.stateSnapshot = null;\n\n this.bus.emit('destroyed', undefined);\n this.bus.clear();\n this.stateChangeListeners.clear();\n }\n\n open(): void {\n // Graceful when called against a destroyed/uninitialized client. This\n // happens in dev when a stale launcher (e.g. left behind by an HMR or\n // StrictMode race) is clicked after destroy() has run — we don't want\n // those clicks to crash the host page.\n const state = this.state;\n if (!state) {\n if (typeof console !== 'undefined') {\n console.warn(\n '[agent-chat] open() called before init() (or after destroy()) — ignoring.',\n );\n }\n return;\n }\n if (state.isOpen) return;\n state.isOpen = true;\n this.notifyStateChange();\n this.bus.emit('open', undefined);\n }\n\n close(): void {\n const state = this.state;\n if (!state || !state.isOpen) return;\n state.isOpen = false;\n this.notifyStateChange();\n this.bus.emit('close', undefined);\n }\n\n toggle(): void {\n if (this.isOpen()) this.close();\n else this.open();\n }\n\n openApprovalInbox(opts?: OpenApprovalInboxPayload): void {\n this.bus.emit('openApprovalInbox', opts);\n }\n\n openAutomationTaskCenter(opts?: OpenAutomationTaskCenterPayload): void {\n this.bus.emit('openAutomationTaskCenter', opts);\n }\n\n openPageActionFeedback(opts?: OpenPageActionFeedbackPayload): void {\n this.bus.emit('openPageActionFeedback', opts);\n }\n\n /**\n * @deprecated Rating list is `GET /page-action/catalog`.\n * Optional name overlay for optimistic task-center titles only.\n */\n registerPageActionFeedbackCatalog(\n items: Array<{ actionKey: string; name?: string | null }>,\n ): void {\n for (const item of items) {\n const actionKey = item.actionKey?.trim();\n const name = item.name?.trim();\n if (!actionKey || !name || name === actionKey) continue;\n this.pageActionFeedbackNames.set(actionKey, name);\n }\n }\n\n /**\n * `GET /page-action/catalog`. Global「我的反馈」omits `pageScope`.\n */\n async fetchPageActionFeedbackCatalog(\n query: PageActionFeedbackCatalogQuery = {},\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackCatalogItem[]> {\n await this.ensureInitialized('fetchPageActionFeedbackCatalog', {\n signal: opts?.signal,\n });\n await this.ensureLoggedIn('fetchPageActionFeedbackCatalog', {\n signal: opts?.signal,\n });\n const state = this.requireState('fetchPageActionFeedbackCatalog');\n const items = await state.pageAction.listCatalog(query, opts?.signal);\n this.pageActionFeedbackCatalogItems = items;\n for (const item of items) {\n this.pageActionFeedbackNames.set(item.actionKey, item.name);\n }\n return items;\n }\n\n listPageActionFeedbackCatalog(): PageActionFeedbackCatalogItem[] {\n return this.pageActionFeedbackCatalogItems.slice();\n }\n\n /**\n * `POST /page-action/rollout-check` — hardcoded actionKey buttons before invoke.\n * Scene pickers that render catalog do not need this.\n */\n async checkPageActionRollout(\n actionKeys: string[],\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionRolloutCheckItem[]> {\n await this.ensureInitialized('checkPageActionRollout', { signal: opts?.signal });\n await this.ensureLoggedIn('checkPageActionRollout', { signal: opts?.signal });\n const state = this.requireState('checkPageActionRollout');\n return state.pageAction.checkRollout(actionKeys, opts?.signal);\n }\n\n async getPageActionFeedback(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackView | null> {\n await this.ensureInitialized('getPageActionFeedback', { signal: opts?.signal });\n await this.ensureLoggedIn('getPageActionFeedback', { signal: opts?.signal });\n const state = this.requireState('getPageActionFeedback');\n return state.pageAction.getMyFeedback(actionKey, opts?.signal);\n }\n\n async upsertPageActionFeedback(\n actionKey: string,\n body: UpsertPageActionFeedbackInput,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackView> {\n await this.ensureInitialized('upsertPageActionFeedback', { signal: opts?.signal });\n await this.ensureLoggedIn('upsertPageActionFeedback', { signal: opts?.signal });\n const state = this.requireState('upsertPageActionFeedback');\n const result = await state.pageAction.upsertFeedback(actionKey, body, opts?.signal);\n if (result.pageActionName) {\n this.pageActionFeedbackNames.set(result.actionKey, result.pageActionName);\n }\n return result;\n }\n\n async removePageActionFeedback(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<void> {\n await this.ensureInitialized('removePageActionFeedback', { signal: opts?.signal });\n await this.ensureLoggedIn('removePageActionFeedback', { signal: opts?.signal });\n const state = this.requireState('removePageActionFeedback');\n await state.pageAction.removeMyFeedback(actionKey, opts?.signal);\n }\n\n async getPageActionFeedbackSummary(\n actionKey: string,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionFeedbackSummary> {\n await this.ensureInitialized('getPageActionFeedbackSummary', {\n signal: opts?.signal,\n });\n await this.ensureLoggedIn('getPageActionFeedbackSummary', { signal: opts?.signal });\n const state = this.requireState('getPageActionFeedbackSummary');\n const summary = await state.pageAction.getFeedbackSummary(actionKey, opts?.signal);\n if (summary.pageActionName) {\n this.pageActionFeedbackNames.set(summary.actionKey, summary.pageActionName);\n }\n return summary;\n }\n\n async createPageActionWish(\n body: CreatePageActionWishInput,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView> {\n await this.ensureInitialized('createPageActionWish', { signal: opts?.signal });\n await this.ensureLoggedIn('createPageActionWish', { signal: opts?.signal });\n const state = this.requireState('createPageActionWish');\n return state.pageAction.createWish(body, opts?.signal);\n }\n\n async listPageActionWishes(\n query?: PageActionWishQuery,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishList> {\n await this.ensureInitialized('listPageActionWishes', { signal: opts?.signal });\n await this.ensureLoggedIn('listPageActionWishes', { signal: opts?.signal });\n const state = this.requireState('listPageActionWishes');\n return state.pageAction.listWishes(query ?? {}, opts?.signal);\n }\n\n async getPageActionWish(\n id: number,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView> {\n await this.ensureInitialized('getPageActionWish', { signal: opts?.signal });\n await this.ensureLoggedIn('getPageActionWish', { signal: opts?.signal });\n const state = this.requireState('getPageActionWish');\n return state.pageAction.getWish(id, opts?.signal);\n }\n\n async cancelPageActionWish(\n id: number,\n opts?: { signal?: AbortSignal },\n ): Promise<PageActionWishView> {\n await this.ensureInitialized('cancelPageActionWish', { signal: opts?.signal });\n await this.ensureLoggedIn('cancelPageActionWish', { signal: opts?.signal });\n const state = this.requireState('cancelPageActionWish');\n return state.pageAction.cancelWish(id, opts?.signal);\n }\n\n isOpen(): boolean {\n return this.state?.isOpen ?? false;\n }\n\n identify(user: UserContext): void {\n const state = this.requireState('identify');\n const previous = state.session.getSession();\n state.session.updateContext({ user });\n\n const previousUserId = state.options.user?.id;\n state.options = { ...state.options, user };\n\n if (previous && previousUserId && previousUserId !== user.id) {\n this.abortAllSessionStreams(state);\n this.sessionStreamConnects.clear();\n this.pendingStreamTargets.clear();\n state.session.reset();\n state.sessions = [];\n state.sessionMessagesCache.clear();\n state.sessionRuns.clear();\n state.writeConfirmationsBySession.clear();\n state.writeConfirmation = null;\n state.activeSessionId = null;\n state.messages = [];\n this.notifyStateChange();\n }\n }\n\n setPageContext(pageContext: AgentChatPageContext | null): void {\n if (!this.state) {\n this.pendingPageContext = pageContext;\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n const prevPage = this.getPageScope(state);\n state.pageContext = pageContext;\n state.options = { ...state.options, pageContext: pageContext ?? undefined };\n const nextPage = this.getPageScope(state);\n this.notifyStateChange();\n this.schedulePrepareSession();\n\n if (prevPage !== nextPage && !state.options.skills?.length) {\n state.selectedSkillId = null;\n void this.refreshSkills(state.selectedAgentId ?? undefined);\n }\n }\n\n setRouteContext(routeContext: AgentChatRouteContext | null): void {\n if (!this.state) {\n this.pendingRouteContextOverride = routeContext;\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n state.routeContextOverride = routeContext;\n this.syncRouteContextFromWindow();\n }\n\n registerContextMentions(\n items: Array<ContextMentionRegistration | ContextMentionDefinition>,\n options: RegisterContextMentionsOptions = {},\n ): void {\n const normalized = items.map(normalizeContextMentionInput);\n if (!this.state) {\n this.pendingContextMentionRegistry = mergeContextMentionRegistrations(\n this.pendingContextMentionRegistry,\n normalized,\n options.replace === true,\n );\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n state.contextMentionRegistry = mergeContextMentionRegistrations(\n state.contextMentionRegistry,\n normalized,\n options.replace === true,\n );\n this.notifyStateChange();\n }\n\n unregisterContextMentions(ids: string[]): void {\n if (!this.state) {\n let changed = false;\n for (const raw of ids) {\n const id = raw.trim();\n if (!id) continue;\n if (this.pendingContextMentionRegistry.delete(id)) changed = true;\n }\n if (changed) this.notifyStateChange();\n return;\n }\n const state = this.state;\n let changed = false;\n for (const raw of ids) {\n const id = raw.trim();\n if (!id) continue;\n if (state.contextMentionRegistry.delete(id)) changed = true;\n }\n if (changed) this.notifyStateChange();\n }\n\n clearContextMentions(): void {\n if (!this.state) {\n if (this.pendingContextMentionRegistry.size === 0) return;\n this.pendingContextMentionRegistry = new Map();\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n if (state.contextMentionRegistry.size === 0) return;\n state.contextMentionRegistry = new Map();\n this.notifyStateChange();\n }\n\n syncRouteContextFromWindow(): void {\n if (!this.state) return;\n const state = this.state;\n const merged = mergeRouteContext(\n readWindowRouteContext(),\n state.routeContextOverride,\n );\n const prev = JSON.stringify(state.routeContext ?? null);\n const next = JSON.stringify(\n Object.keys(merged).length > 0 ? merged : null,\n );\n state.routeContext = Object.keys(merged).length > 0 ? merged : null;\n if (prev !== next) {\n this.notifyStateChange();\n this.schedulePrepareSession();\n }\n }\n\n setAttachPageContext(attach: boolean): void {\n if (!this.state) {\n this.pendingAttachPageContext = attach;\n this.notifyStateChange();\n return;\n }\n const state = this.state;\n if (state.attachPageContext === attach) return;\n state.attachPageContext = attach;\n state.options = { ...state.options, attachPageContext: attach };\n this.notifyStateChange();\n }\n\n getPageContext(): AgentChatPageContext | null {\n const state = this.state;\n if (!state) return null;\n return state.pageContext ?? state.options.pageContext ?? null;\n }\n\n getAppClientId(): number | null {\n const fromStore = useAuthStore.getState().appClient?.id;\n if (fromStore != null) return fromStore;\n return this.state?.appClientId ?? null;\n }\n\n /**\n * Whether host-tool metadata can be synced to the server\n * (`POST /host-tool/client/register` requires Bearer + app client).\n */\n isHostToolServerSyncReady(): boolean {\n const state = this.state;\n if (!state?.isClientAuthenticated) return false;\n if (!state.isLoggedIn || !state.userJwt?.trim()) return false;\n return this.getAppClientId() != null;\n }\n\n registerHostTool(scope: string, name: string, handler: HostToolHandler): void {\n registerHostTool(scope, name, handler);\n }\n\n unregisterHostTool(scope: string, name: string): void {\n unregisterHostTool(scope, name);\n }\n\n undeclareHostTool(scope: string, name: string): void {\n undeclareHostTool(scope, name);\n }\n\n runHostTool(\n scope: string,\n name: string,\n args: Record<string, unknown>,\n ): Promise<boolean> {\n return runHostTool(scope, name, args);\n }\n\n registerHostToolsWithSync(options: RegisterHostToolsOptions): Promise<void> {\n return registerHostToolsWithSync(this, options);\n }\n\n async syncHostToolsToServer(\n body: Parameters<HostToolService['register']>[0],\n ): Promise<import('../services/host-tool.service').HostToolRegisterResult> {\n await this.ensureLoggedIn('syncHostToolsToServer');\n const state = this.requireState('syncHostToolsToServer');\n if (!state.isClientAuthenticated || state.appClientId == null) {\n throw new AgentChatError(\n 'AUTH_REQUIRED',\n 'Host tool server sync requires app client authentication.',\n );\n }\n return state.hostTool.register(body);\n }\n\n getHostToolCatalog(query?: { scope?: string; agentId?: number }): Promise<unknown> {\n const state = this.requireState('getHostToolCatalog');\n return state.hostTool.getCatalog(query);\n }\n\n /**\n * `GET /app/tools/callable` — 当前用户可代调的 Integration Tool(须登录)。\n * 用返回的 `definitionKey` 调 {@link invokeAppTool},勿硬编码 `toolId`。\n */\n async listCallableTools(signal?: AbortSignal): Promise<AppToolCallableList> {\n await this.ensureLoggedIn('listCallableTools', { signal });\n const state = this.requireState('listCallableTools');\n return state.appTool.listCallable(signal);\n }\n\n /**\n * `POST /app/tools/invoke` — 按 `definitionKey` 代调 Tool。\n * 未登录时自动挂起,登录后继续执行(默认等待 5 分钟,超时抛 `PENDING_TIMEOUT`)。\n * 下游非 2xx 时返回 `{ ok: false, httpStatus, error }`;网关门禁失败抛 `AgentChatError`\n *(`details.serverCode` 如 `INTEGRATION_USER_TOKEN_REQUIRED`)。\n */\n async invokeAppTool(input: AppToolInvokeInput): Promise<AppToolInvokeResult> {\n await this.ensureLoggedIn('invokeAppTool', { signal: input.signal });\n const state = this.requireState('invokeAppTool');\n return state.appTool.invoke(input);\n }\n\n isPageActionKeyActive(pageActionKey: string | null | undefined): boolean {\n const key = pageActionKey?.trim();\n if (!key) return false;\n return collectActivePageActionKeys(this.automationRunRegistry).has(key);\n }\n\n getActivePageActionKeyForActionKey(actionKey: string): string | null {\n return findActivePageActionKeyForActionKey(this.automationRunRegistry, actionKey);\n }\n\n getPageActionRowState(rowKey: string): PageActionRowState | null {\n const key = rowKey.trim();\n if (!key) return null;\n return this.pageActionRows.get(key) ?? null;\n }\n\n getPageActionRowsForActionKey(actionKey: string): PageActionRowState[] {\n const key = actionKey.trim();\n if (!key) return [];\n return [...this.pageActionRows.values()].filter((row) => row.actionKey === key);\n }\n\n isPageActionRowActive(rowKey: string): boolean {\n const row = this.getPageActionRowState(rowKey);\n if (!row) return false;\n // Reuse picker (`awaiting_reuse`) is interruptible — never soft-lock re-clicks.\n if (row.phase === 'awaiting_reuse') return false;\n // Stale soft-lock: idle/loading with no run (legacy reuse path). Allow re-invoke.\n if (row.loading && row.phase === 'idle' && row.runId == null && !row.awaitingApproval) {\n return false;\n }\n return row.loading || row.awaitingApproval;\n }\n\n /** Clear soft error / tip text on a row slot without changing phase. */\n clearPageActionRowError(rowKey: string): void {\n const key = rowKey.trim();\n const current = this.pageActionRows.get(key);\n if (!current?.error && !current?.message) return;\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...current,\n error: null,\n message: null,\n }),\n );\n }\n\n async hydratePageActionByRunId(\n runId: number,\n opts: { rowKey?: string; actionKey?: string; signal?: AbortSignal } = {},\n ): Promise<PageActionRowState | null> {\n await this.ensureLoggedIn('hydratePageActionByRunId');\n this.requireState('hydratePageActionByRunId');\n if (!Number.isFinite(runId)) return null;\n const id = Math.trunc(runId);\n const detail = await this.getAutomationTaskDetail(id, opts.signal);\n if (!detail) return null;\n\n const mappedRowKey = resolveRestoredPageActionRowKey(id, {\n rowKey: opts.rowKey,\n entityId: detail.pageContext?.entity?.id ?? null,\n findRowKeyByRunId: () =>\n this.findRowKeyByRunId(id) || this.findRowKeyByPageActionKey(detail.pageActionKey),\n });\n const actionKey =\n opts.actionKey?.trim() ||\n detail.actionKey?.trim() ||\n this.automationRunRegistry.get(id)?.actionKey ||\n detail.title;\n\n const isBrainClarify =\n detail.taskStatus === 'failed' &&\n isBrainAskUserErrorCode(detail.errorCode) &&\n detail.brainClarify != null;\n const phase: PageActionPhase = isBrainClarify\n ? 'awaiting_clarify'\n : taskStatusToPageActionPhase(detail.taskStatus);\n const flags = derivePageActionRowFlags(phase);\n const prevRow = this.pageActionRows.get(mappedRowKey);\n const progressLabel = flags.loading\n ? (prevRow?.progressLabel ??\n defaultPageActionProgressLabel(this.state?.options.locale))\n : phase === 'awaiting_clarify'\n ? pageActionAwaitingClarifyLabel(this.state?.options.locale)\n : phase === 'awaiting_approval'\n ? resolvePageWorkflowProgressLabel(\n {\n phase: 'awaiting_approval',\n actionRunId: id,\n actionKey,\n generation: id,\n nodeId: '',\n stageKind: 'other',\n },\n this.state?.options.locale,\n )\n : null;\n const row = buildPageActionRowState({\n rowKey: mappedRowKey,\n actionKey,\n runId: id,\n pageActionKey: detail.pageActionKey,\n phase,\n error: isBrainClarify ? null : detail.errorMessage,\n message: prevRow?.message ?? null,\n progressLabel,\n narrativeItems: prevRow?.narrativeItems ?? [],\n approvalRequestId: detail.approval?.id ?? null,\n brainClarify: isBrainClarify ? detail.brainClarify : null,\n });\n this.upsertPageActionRow(row);\n this.bindPageActionRunToRow(id, mappedRowKey);\n const tracked = this.automationRunRegistry.get(id);\n if (tracked) {\n tracked.rowKey = mappedRowKey;\n tracked.actionKey = actionKey;\n tracked.pageActionKey = detail.pageActionKey;\n tracked.status = detail.taskStatus;\n tracked.updatedAt = new Date().toISOString();\n if (!isActiveAutomationTaskStatus(detail.taskStatus)) {\n this.automationRunRegistry.delete(id);\n }\n } else if (isActiveAutomationTaskStatus(detail.taskStatus)) {\n this.automationRunRegistry.set(id, {\n runId: id,\n actionKey,\n pageActionKey: detail.pageActionKey,\n rowKey: mappedRowKey,\n status: detail.taskStatus,\n registeredAt: detail.createdAt ?? new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n clientActionId: null,\n });\n }\n if (isBrainClarify && detail.brainClarify) {\n const snap = this.pageActionInvokeSnapshotsByRunId.get(id) ?? {\n pageContext: detail.pageContext ?? undefined,\n rowKey: mappedRowKey,\n awaitStream: false,\n };\n if (!this.pageActionInvokeSnapshotsByRunId.has(id)) {\n this.pageActionInvokeSnapshotsByRunId.set(id, {\n ...snap,\n launchAnchor: snap.launchAnchor ?? null,\n });\n this.pageActionInvokeSnapshotsByRowKey.set(mappedRowKey, {\n ...snap,\n launchAnchor: snap.launchAnchor ?? null,\n });\n }\n this.emitPageActionBrainClarifyFromPayload({\n actionKey,\n runId: id,\n brainClarify: detail.brainClarify,\n rowKey: mappedRowKey,\n });\n } else if (phase === 'completed' || phase === 'failed') {\n this.schedulePageActionRowIdleReset(\n mappedRowKey,\n phase === 'failed' ? 1_600 : 900,\n );\n }\n return row;\n }\n\n async reconcileActivePageActions(\n opts: { actionKey?: string; signal?: AbortSignal } = {},\n ): Promise<PageActionRowState[]> {\n await this.ensureLoggedIn('reconcileActivePageActions');\n this.requireState('reconcileActivePageActions');\n const actionKey = opts.actionKey?.trim();\n await this.refreshAutomationTasks({\n status: 'active',\n actionKey: actionKey || undefined,\n offset: 0,\n signal: opts.signal,\n });\n\n const updated: PageActionRowState[] = [];\n for (const [runId, tracked] of this.automationRunRegistry) {\n if (!isActiveAutomationTaskStatus(tracked.status)) continue;\n const row = await this.hydratePageActionByRunId(runId, {\n rowKey: tracked.rowKey ?? undefined,\n actionKey: tracked.actionKey,\n signal: opts.signal,\n });\n if (!row) continue;\n if (actionKey && row.actionKey !== actionKey) continue;\n updated.push(row);\n }\n return updated;\n }\n\n async invokePageAction(input: PageBotInvokeInput): Promise<PageBotStreamResult> {\n await this.ensureInitialized('invokePageAction', { signal: input.signal });\n const state = this.requireState('invokePageAction');\n this.requirePageActionKey(input);\n\n const rowKey = this.resolveInvokeRowKey(input);\n if (rowKey) {\n const existing = this.pageActionRows.get(rowKey);\n // Legacy reuse path left idle+loading after a dismissed picker; unlock before gate.\n if (\n existing &&\n existing.phase === 'idle' &&\n existing.loading &&\n existing.runId == null &&\n !existing.awaitingApproval\n ) {\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: existing.actionKey || input.actionKey.trim(),\n runId: null,\n pageActionKey: existing.pageActionKey,\n phase: 'idle',\n loading: false,\n disabled: false,\n error: null,\n message: null,\n progressLabel: null,\n approvalRequestId: existing.approvalRequestId,\n }),\n );\n }\n }\n if (rowKey && this.isPageActionRowActive(rowKey)) {\n return this.finishAlreadyActiveInvoke(input, rowKey, {\n source: 'local',\n });\n }\n\n const lockKey = this.acquirePageActionLock(input.clientActionId);\n\n try {\n const preferReuse =\n input.preferReuse !== false && this.pageActionReusePromptHandler != null;\n const invokeBody = preferReuse\n ? this.buildPageActionInvokeBody(state, input)\n : null;\n const cachedHint = invokeBody ? this.pageActionReuseHintCache.get(invokeBody) : null;\n /** Skip network + checking label when we already know this entity's hint. */\n const reuseCacheHit = cachedHint != null;\n const reuseHasItems =\n (cachedHint?.reusable.items.length ?? 0) > 0 ||\n (cachedHint?.reusable.total ?? 0) > 0;\n const needsReuseFetch = preferReuse && !reuseCacheHit;\n const showReusePrompt = preferReuse && (needsReuseFetch || reuseHasItems);\n\n if (rowKey) {\n this.clearPageActionNarrativeClearTimer(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: this.pageActionRows.get(rowKey)?.runId ?? null,\n pageActionKey:\n cachedHint?.pageActionKey ??\n this.pageActionRows.get(rowKey)?.pageActionKey ??\n null,\n phase: showReusePrompt ? 'awaiting_reuse' : 'submitting',\n error: null,\n message: null,\n progressLabel: needsReuseFetch\n ? pageActionReuseCheckingLabel(this.state?.options.locale)\n : showReusePrompt\n ? null\n : defaultPageActionProgressLabel(this.state?.options.locale),\n narrativeItems: [],\n approvalRequestId: this.pageActionRows.get(rowKey)?.approvalRequestId ?? null,\n }),\n );\n }\n\n await this.ensureLoggedIn('invokePageAction', { signal: input.signal });\n\n if (showReusePrompt) {\n const reuseResult = await this.tryPageActionReusePrompt(state, input, rowKey, {\n body: invokeBody!,\n cached: cachedHint,\n });\n if (reuseResult) return reuseResult;\n }\n\n if (rowKey) {\n this.clearPageActionNarrativeClearTimer(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: this.pageActionRows.get(rowKey)?.runId ?? null,\n pageActionKey: this.pageActionRows.get(rowKey)?.pageActionKey ?? null,\n phase: 'submitting',\n error: null,\n message: null,\n progressLabel: defaultPageActionProgressLabel(this.state?.options.locale),\n narrativeItems: [],\n approvalRequestId: this.pageActionRows.get(rowKey)?.approvalRequestId ?? null,\n }),\n );\n }\n\n // Do not invalidate reuse-hint here — empty/positive cache survives cancel + re-click.\n // Cache is dropped on「重新执行」and when a run completes (see below).\n\n return await this.invokePageActionStream(state, input, rowKey);\n } catch (err) {\n const mapped = remapPageActionRolloutDenied(err);\n if (rowKey && !(mapped instanceof AgentChatError && mapped.code === 'PAGE_ACTION_ALREADY_ACTIVE')) {\n const message = mapped instanceof Error ? mapped.message : String(mapped);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: this.pageActionRows.get(rowKey)?.runId ?? null,\n pageActionKey: this.pageActionRows.get(rowKey)?.pageActionKey ?? null,\n phase: 'failed',\n error: message,\n message: null,\n progressLabel: null,\n approvalRequestId: this.pageActionRows.get(rowKey)?.approvalRequestId ?? null,\n }),\n );\n this.schedulePageActionRowIdleReset(rowKey, 1_600);\n }\n throw mapped;\n } finally {\n this.releasePageActionLock(lockKey);\n }\n }\n\n /**\n * Register the built-in reuse popover handler (ChatRoot).\n * Without a handler, {@link invokePageAction} skips reuse and invokes directly.\n */\n setPageActionReusePromptHandler(\n handler: PageActionReusePromptHandler | null,\n ): () => void {\n this.pageActionReusePromptHandler = handler;\n return () => {\n if (this.pageActionReusePromptHandler === handler) {\n this.pageActionReusePromptHandler = null;\n }\n };\n }\n\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 const runId =\n typeof input?.runId === 'number' && Number.isFinite(input.runId)\n ? Math.trunc(input.runId)\n : null;\n const rowKey =\n input?.rowKey?.trim() ||\n (runId != null ? this.findRowKeyByRunId(runId) : null);\n if (!rowKey) return;\n const prev = this.pageActionRows.get(rowKey);\n if (!prev || prev.phase !== 'awaiting_clarify') return;\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n phase: 'idle',\n loading: false,\n disabled: false,\n error: null,\n progressLabel: null,\n brainClarify: null,\n }),\n );\n }\n\n /**\n * After a reused result was applied (docked「撤销」/「继续执行」), force the\n * trigger row back to clickable idle and abort any in-flight replay for that run.\n */\n dismissPageActionReuse(input?: {\n rowKey?: string | null;\n runId?: number | null;\n }): void {\n const runId =\n typeof input?.runId === 'number' && Number.isFinite(input.runId)\n ? Math.trunc(input.runId)\n : null;\n const rowKey =\n input?.rowKey?.trim() ||\n (runId != null ? this.findRowKeyByRunId(runId) : null);\n if (!rowKey) return;\n\n const prevEpoch = this.pageActionReuseDismissEpochByRowKey.get(rowKey) ?? 0;\n this.pageActionReuseDismissEpochByRowKey.set(rowKey, prevEpoch + 1);\n\n const idleTimer = this.pageActionRowIdleTimers.get(rowKey);\n if (idleTimer != null) {\n clearTimeout(idleTimer);\n this.pageActionRowIdleTimers.delete(rowKey);\n }\n\n const prev = this.pageActionRows.get(rowKey);\n const abortRunId = runId ?? prev?.runId ?? null;\n if (abortRunId != null) {\n this.pageActionRunAborts.get(abortRunId)?.abort();\n }\n\n if (!prev) return;\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: prev.actionKey,\n runId: prev.runId,\n pageActionKey: prev.pageActionKey,\n phase: 'idle',\n loading: false,\n disabled: false,\n error: null,\n message: null,\n progressLabel: null,\n approvalRequestId: prev.approvalRequestId,\n brainClarify: null,\n }),\n );\n }\n\n /** `POST /page-action/reuse-hint` — soft check for reusable successful runs. */\n async reusePageActionHint(\n input: Pick<\n PageBotInvokeInput,\n 'actionKey' | 'pageContext' | 'instruction' | 'context' | 'signal'\n > & { refresh?: boolean },\n ): Promise<PageActionReuseHint> {\n await this.ensureInitialized('reusePageActionHint', { signal: input.signal });\n const state = this.requireState('reusePageActionHint');\n await this.ensureLoggedIn('reusePageActionHint', { signal: input.signal });\n const body = this.buildPageActionInvokeBody(state, {\n actionKey: input.actionKey,\n pageContext: input.pageContext,\n instruction: input.instruction,\n context: input.context,\n });\n if (!input.refresh) {\n const cached = this.pageActionReuseHintCache.get(body);\n if (cached) return cached;\n }\n const hint = await state.pageAction.reuseHint(body, input.signal);\n this.pageActionReuseHintCache.set(body, hint);\n return hint;\n }\n\n async prefetch(): Promise<void> {\n await this.ensureLoggedIn('prefetch');\n const state = this.requireState('prefetch');\n const ctrl = this.makeAbortController();\n try {\n await Promise.all([\n this.refreshSessions(ctrl.signal),\n this.refreshAgentCatalog(ctrl.signal),\n this.refreshApprovalPendingCount(ctrl.signal).catch(() => {\n /* inbox badge is optional */\n }),\n this.refreshApprovalInbox({ signal: ctrl.signal }).catch(() => {\n /* inbox is optional */\n }),\n ]);\n if (!state.sessions.length) return;\n const targetId =\n state.activeSessionId && state.sessions.some((s) => s.sessionId === state.activeSessionId)\n ? state.activeSessionId\n : state.sessions[0]!.sessionId;\n await this.selectSession(targetId, { signal: ctrl.signal, skipAbortStream: true });\n } finally {\n state.catalogHydrated = true;\n state.abortControllers.delete(ctrl);\n this.notifyStateChange();\n }\n }\n\n async selectSession(\n sessionId: string,\n opts: { signal?: AbortSignal; skipAbortStream?: boolean } = {},\n ): Promise<void> {\n await this.ensureLoggedIn('selectSession');\n const state = this.requireState('selectSession');\n const id = sessionId.trim();\n if (!id) {\n throw new AgentChatError('INVALID_OPTIONS', 'selectSession: sessionId is required');\n }\n\n this.sessionEpoch += 1;\n const loadEpoch = this.sessionEpoch;\n const normalizedTarget = normalizeSessionId(id);\n\n if (state.activeSessionId && state.activeSessionId !== id) {\n this.writeSessionMessagesCache(state, state.activeSessionId);\n if (!opts.skipAbortStream && !this.sessionHasPendingAgent(state.messages)) {\n this.abortSessionStream(state, state.activeSessionId, { suppressReconnect: true });\n }\n }\n\n state.lastError = null;\n const leavingSession =\n state.activeSessionId != null &&\n normalizeSessionId(state.activeSessionId) !== normalizedTarget;\n if (leavingSession) {\n // Chat turn UI is session-scoped — drop clarify/banner from the previous session.\n this.clearSkillIntentUi(state);\n }\n\n const cached =\n state.sessionMessagesCache.get(normalizedTarget) ??\n state.sessionMessagesCache.get(id);\n if (cached) {\n if (loadEpoch === this.sessionEpoch) {\n state.activeSessionId = id;\n state.messages = cached.messages;\n state.activeSessionMessagesPage = cached.page;\n state.activeSessionMessagesHasMore = cached.hasMore;\n if (cached.agentId) {\n this.applyAutoAgentBinding(state, {\n id: cached.agentId,\n source: 'session',\n reason: 'restored from session detail cache',\n });\n }\n state.session.setSession(id, cached.messages);\n this.syncActiveWriteConfirmation(state, id);\n this.notifyStateChange();\n this.bus.emit('session', state.session.getSession()!);\n if (!opts.signal?.aborted) {\n await this.syncSessionRunState(state, id, opts.signal);\n this.reconcilePendingRepliesAfterSessionSwitch(state, id, normalizedTarget);\n void this.ensureSessionStream(id).catch(() => {\n /* stream error already reported */\n });\n void this.syncMessageFeedbacks(state, id).catch(() => {\n /* feedback sync is best-effort */\n });\n this.schedulePrepareSession();\n }\n }\n return;\n }\n\n const ctrl = this.makeAbortController();\n const signal = opts.signal;\n if (signal) {\n signal.addEventListener('abort', () => ctrl.abort(), { once: true });\n }\n try {\n const detailPage = await this.fetchSessionMessagesPage(state, id, 1, ctrl.signal);\n const mapped = detailPage.messages.map((m) => this.toAgentMessage(m as ServerMessage));\n const cacheEntry: SessionMessagesCacheEntry = {\n messages: mapped,\n page: detailPage.page,\n hasMore: detailPage.hasMore,\n agentId: detailPage.agentId,\n };\n state.sessionMessagesCache.set(normalizedTarget, cacheEntry);\n if (loadEpoch !== this.sessionEpoch) return;\n state.activeSessionId = id;\n state.activeSessionMessagesPage = detailPage.page;\n state.activeSessionMessagesHasMore = detailPage.hasMore;\n state.session.setSession(detailPage.sessionId, mapped);\n state.messages = mapped;\n if (detailPage.agentId) {\n this.applyAutoAgentBinding(state, {\n id: detailPage.agentId,\n source: 'session',\n reason: 'restored from session detail',\n });\n }\n this.syncActiveWriteConfirmation(state, id);\n this.notifyStateChange();\n this.bus.emit('session', state.session.getSession()!);\n if (!opts.signal?.aborted) {\n await this.syncSessionRunState(state, id, ctrl.signal);\n this.reconcilePendingRepliesAfterSessionSwitch(state, id, normalizedTarget);\n void this.ensureSessionStream(id).catch(() => {\n /* stream error already reported */\n });\n void this.syncMessageFeedbacks(state, id).catch(() => {\n /* feedback sync is best-effort */\n });\n this.schedulePrepareSession();\n }\n } finally {\n state.abortControllers.delete(ctrl);\n }\n }\n\n /**\n * Send a user turn end-to-end:\n *\n * 1. Optimistic user bubble (`pending`) → `notifyStateChange` → React re-render\n * 2. Ensure `sessionId` (create via `POST /chat` on first send)\n * 3. `POST /chat/{sessionId}/messages` (existing session) or skip (new session: message already in `POST /chat`)\n * 4. Append empty assistant placeholder (`pending`) with a new id\n * 5. `POST` user message (existing session) → `GET /chat/{sessionId}/stream`\n * 6. SSE updates **only** the placeholder message by id (`think` / `result` / `complete`)\n */\n async sendMessage(\n text: string,\n opts: {\n id?: string;\n contextMentions?: ContextMentionAttachment[];\n entityCommit?: EntityCommit;\n } = {},\n ): Promise<AgentMessage> {\n await this.ensureLoggedIn('sendMessage');\n const state = this.requireState('sendMessage');\n const trimmed = text.trim();\n if (trimmed.length === 0) {\n throw new AgentChatError('INVALID_OPTIONS', 'sendMessage: text must not be empty');\n }\n\n this.settlePendingAgentReplies(state, state.activeSessionId ?? undefined);\n if (state.activeSessionId) {\n this.persistWriteConfirmation(state, state.activeSessionId, null);\n }\n state.lastTurnUserMessage = trimmed;\n this.clearSkillIntentUi(state);\n state.brainClarify = null;\n\n const resolvedMentions = opts.contextMentions?.length\n ? await resolveContextMentionsForSend(\n opts.contextMentions,\n state.contextMentionRegistry,\n )\n : undefined;\n\n const sendPageContext = resolvedMentions?.length\n ? mergePageContextWithMentions(\n this.buildOutboundPageContext(state),\n resolvedMentions,\n )\n : undefined;\n\n const userMessage = this.appendOptimisticUserMessage(\n state,\n trimmed,\n opts.id,\n opts.contextMentions,\n );\n const agentPlaceholder = this.appendAgentPlaceholder(state);\n const ctrl = this.makeAbortController();\n\n try {\n let sessionId = state.activeSessionId ?? state.session.getSession()?.sessionId ?? null;\n\n if (!sessionId) {\n sessionId = await this.createChatSession(\n state,\n trimmed,\n ctrl.signal,\n sendPageContext,\n opts.entityCommit,\n );\n void this.refreshSessions(ctrl.signal).catch(() => {\n /* sidebar refresh is best-effort */\n });\n this.setStreamTargetMessageId(state, sessionId, agentPlaceholder.id);\n await this.ensureSessionStream(sessionId);\n return this.applyUserMessageSent(state, userMessage);\n }\n\n this.setStreamTargetMessageId(state, sessionId, agentPlaceholder.id);\n const sentUser = await this.postUserMessageAndApply(\n state,\n sessionId,\n trimmed,\n ctrl.signal,\n userMessage,\n sendPageContext,\n opts.entityCommit,\n );\n await this.ensureSessionStream(sessionId);\n return sentUser;\n } catch (err) {\n const sessionId = state.activeSessionId;\n const updated = state.messages\n .filter((m) => m.id !== agentPlaceholder.id)\n .map((m) => (m.id === userMessage.id ? { ...userMessage, status: 'failed' as const } : m));\n state.messages = updated;\n if (sessionId) {\n this.commitSessionMessages(state, sessionId, updated);\n } else {\n this.notifyStateChange();\n }\n\n const wrapped =\n err instanceof AgentChatError\n ? new AgentChatError('MESSAGE_FAILED', err.message, {\n cause: err,\n details: { ...(err.details ?? {}), messageId: userMessage.id },\n })\n : new AgentChatError('MESSAGE_FAILED', 'Failed to send message', {\n cause: err,\n details: { messageId: userMessage.id },\n });\n this.reportError(wrapped);\n throw wrapped;\n } finally {\n state.abortControllers.delete(ctrl);\n }\n }\n\n async confirmWrite(): Promise<void> {\n await this.submitWriteGate({ action: 'confirm' });\n }\n\n async confirmWriteWithEdits(input: {\n editedPreviewSerialized?: string;\n editedPendingWriteArguments?: Record<string, unknown>;\n }): Promise<void> {\n const { editedPreviewSerialized, editedPendingWriteArguments } = input;\n if (!editedPreviewSerialized?.trim() && !editedPendingWriteArguments) {\n throw new AgentChatError(\n 'INVALID_OPTIONS',\n 'confirmWriteWithEdits: editedPreviewSerialized or editedPendingWriteArguments is required',\n );\n }\n await this.submitWriteGate({\n action: 'confirm_with_edits',\n editedPreviewSerialized: editedPreviewSerialized?.trim() || undefined,\n editedPendingWriteArguments,\n });\n }\n\n async retryWrite(retryInstruction: string): Promise<void> {\n const instruction = retryInstruction.trim();\n if (!instruction) {\n throw new AgentChatError('INVALID_OPTIONS', 'retryWrite: retryInstruction must not be empty');\n }\n await this.submitWriteGate({ action: 'retry', retryInstruction: instruction });\n }\n\n async cancelWrite(): Promise<void> {\n await this.submitWriteGate({ action: 'cancel' });\n }\n\n private async submitWriteGate(writeGate: WriteGate): Promise<void> {\n const label = `submitWriteGate:${writeGate.action}`;\n await this.ensureLoggedIn(label);\n const state = this.requireState(label);\n const pending = state.writeConfirmation;\n if (!pending?.awaiting) {\n throw new AgentChatError('INVALID_OPTIONS', 'No pending write confirmation');\n }\n\n if (writeGate.action === 'retry' && pending.canRetry === false) {\n throw new AgentChatError('INVALID_OPTIONS', 'Draft retry limit exceeded');\n }\n\n const sessionId = state.activeSessionId ?? state.session.getSession()?.sessionId ?? null;\n if (!sessionId) {\n throw new AgentChatError('INVALID_OPTIONS', `${label}: no active session`);\n }\n\n const keepsGateOpen = writeGate.action === 'retry';\n state.writeConfirmation = {\n ...pending,\n awaiting: keepsGateOpen,\n submitting: true,\n gateError: undefined,\n gateErrorCode: undefined,\n };\n this.persistWriteConfirmation(state, sessionId, state.writeConfirmation);\n this.notifyStateChange();\n\n const needsStreamPlaceholder =\n writeGate.action === 'confirm' || writeGate.action === 'confirm_with_edits';\n if (needsStreamPlaceholder) {\n const agentPlaceholder = this.appendAgentPlaceholder(state);\n this.setStreamTargetMessageId(state, sessionId, agentPlaceholder.id);\n }\n\n const ctrl = this.makeAbortController();\n\n try {\n await this.postWriteGateAction(state, sessionId, writeGate, ctrl.signal);\n } catch (err) {\n const serverCode = readWriteGateServerCode(err);\n const gateLevel =\n serverCode === 'DRAFT_RETRY_LIMIT_EXCEEDED' ||\n serverCode === 'INVALID_DRAFT_REVIEW_DECISION' ||\n serverCode === 'EDITED_WRITE_ARGS_INVALID' ||\n serverCode === 'EDITED_LOCKED_FIELD' ||\n serverCode === 'EDITED_FIELD_NOT_ALLOWED' ||\n serverCode === 'MULTI_WRITE_EDIT_NOT_SUPPORTED';\n\n const restored: WriteConfirmationState = {\n ...pending,\n awaiting: true,\n submitting: false,\n gateError: err instanceof AgentChatError ? err.message : undefined,\n gateErrorCode: serverCode,\n canRetry: serverCode === 'DRAFT_RETRY_LIMIT_EXCEEDED' ? false : pending.canRetry,\n };\n state.writeConfirmation = restored;\n this.persistWriteConfirmation(state, sessionId, restored);\n this.notifyStateChange();\n\n if (gateLevel) return;\n\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to submit write gate decision', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n } finally {\n state.abortControllers.delete(ctrl);\n }\n }\n\n async refreshApprovalInbox(\n opts: {\n signal?: AbortSignal;\n status?: ApprovalInboxStatusFilter;\n limit?: number;\n offset?: number;\n append?: boolean;\n } = {},\n ): Promise<ApprovalInboxList> {\n if (this.approvalInboxRefreshPromise && !opts.append) {\n return this.approvalInboxRefreshPromise;\n }\n const run = this.fetchApprovalInbox(opts);\n if (!opts.append) {\n this.approvalInboxRefreshPromise = run;\n }\n try {\n return await run;\n } finally {\n if (!opts.append && this.approvalInboxRefreshPromise === run) {\n this.approvalInboxRefreshPromise = null;\n }\n }\n }\n\n setApprovalInboxStatusFilter(status: ApprovalInboxStatusFilter): void {\n const state = this.state;\n if (!state || state.approvalInboxStatusFilter === status) return;\n state.approvalInboxStatusFilter = status;\n state.approvalInboxItems = [];\n state.approvalInboxHasMore = false;\n this.notifyStateChange();\n }\n\n /** Refresh badge count without replacing the visible inbox list. */\n async refreshApprovalPendingCount(signal?: AbortSignal): Promise<void> {\n if (this.approvalPendingCountRefreshPromise && !signal) {\n return this.approvalPendingCountRefreshPromise;\n }\n const run = this.fetchApprovalPendingCount(signal);\n if (!signal) {\n this.approvalPendingCountRefreshPromise = run;\n }\n try {\n await run;\n } finally {\n if (!signal && this.approvalPendingCountRefreshPromise === run) {\n this.approvalPendingCountRefreshPromise = null;\n }\n }\n }\n\n private async fetchApprovalPendingCount(signal?: AbortSignal): Promise<void> {\n await this.ensureLoggedIn('refreshApprovalPendingCount');\n const state = this.requireState('refreshApprovalPendingCount');\n const list = await state.approval.listInbox({ status: 'pending', limit: 50, signal });\n state.approvalInboxPendingCount = list.hasMore\n ? Math.max(state.approvalInboxPendingCount, list.items.length)\n : list.items.length;\n this.notifyStateChange();\n }\n\n private async fetchApprovalInbox(\n opts: {\n signal?: AbortSignal;\n status?: ApprovalInboxStatusFilter;\n limit?: number;\n offset?: number;\n append?: boolean;\n } = {},\n ): Promise<ApprovalInboxList> {\n await this.ensureLoggedIn('refreshApprovalInbox');\n const state = this.requireState('refreshApprovalInbox');\n const status = opts.status ?? state.approvalInboxStatusFilter;\n const limit = opts.limit ?? APPROVAL_INBOX_PAGE_SIZE;\n const offset = opts.offset ?? (opts.append ? state.approvalInboxItems.length : 0);\n const append = opts.append === true;\n if (append) {\n state.approvalInboxLoadingMore = true;\n } else {\n state.approvalInboxLoading = true;\n }\n this.notifyStateChange();\n try {\n const list = await state.approval.listInbox({\n status,\n limit,\n offset,\n signal: opts.signal,\n });\n state.approvalInboxStatusFilter = status;\n state.approvalInboxHasMore = list.hasMore;\n state.approvalInboxItems = append\n ? [...state.approvalInboxItems, ...list.items]\n : list.items;\n if (status === 'pending' && offset === 0 && !append) {\n state.approvalInboxPendingCount = list.hasMore\n ? Math.max(state.approvalInboxPendingCount, list.items.length)\n : list.items.length;\n }\n return list;\n } finally {\n if (append) {\n state.approvalInboxLoadingMore = false;\n } else {\n state.approvalInboxLoading = false;\n }\n this.notifyStateChange();\n }\n }\n\n async getApproval(id: number, signal?: AbortSignal): Promise<ApprovalDetail | null> {\n await this.ensureLoggedIn('getApproval');\n const state = this.requireState('getApproval');\n return state.approval.getById(id, signal);\n }\n\n /** `GET /approval/:id` — merge fresh `writeDraft` into cached inbox (e.g. after retry). */\n async hydrateApprovalInboxItem(\n id: number,\n signal?: AbortSignal,\n ): Promise<ApprovalDetail | null> {\n await this.ensureLoggedIn('hydrateApprovalInboxItem');\n const state = this.requireState('hydrateApprovalInboxItem');\n const detail = await state.approval.getById(id, signal);\n if (!detail) {\n state.approvalInboxItems = state.approvalInboxItems.filter((item) => item.id !== id);\n this.notifyStateChange();\n return null;\n }\n const index = state.approvalInboxItems.findIndex((item) => item.id === id);\n if (index >= 0) {\n const next = [...state.approvalInboxItems];\n next[index] = detail;\n state.approvalInboxItems = next;\n } else {\n state.approvalInboxItems = [detail, ...state.approvalInboxItems];\n }\n this.notifyStateChange();\n return detail;\n }\n\n async confirmApproval(id: number, signal?: AbortSignal): Promise<ApprovalConfirmResult> {\n await this.ensureLoggedIn('confirmApproval');\n const state = this.requireState('confirmApproval');\n const runId = this.resolveApprovalPageActionRunId(id);\n const identity = this.resolveApprovalIdentity(id);\n const result = await state.approval.confirm(id, signal);\n void this.refreshApprovalPendingCount(signal).catch(() => {\n /* badge refresh is best-effort */\n });\n void this.refreshApprovalInbox().catch(() => {\n /* inbox refresh is best-effort */\n });\n this.bus.emit('approvalInboxChanged', undefined);\n void this.refreshPageActionRowsAfterApprovalDecision(runId, id);\n if (result.resumed) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'resumed');\n void this.emitApprovalExecutionCompleted({\n approvalId: id,\n runId,\n decision: { action: 'confirm' },\n result,\n identity,\n }).catch(() => {\n /* execution notice is best-effort */\n });\n } else if (!result.suspended) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'cancelled');\n }\n return result;\n }\n\n async decideApproval(\n id: number,\n decision: DraftReviewDecision,\n opts?: { reason?: string; signal?: AbortSignal },\n ): Promise<ApprovalDecideResult> {\n await this.ensureLoggedIn('decideApproval');\n const state = this.requireState('decideApproval');\n const runId = this.resolveApprovalPageActionRunId(id);\n const identity = this.resolveApprovalIdentity(id);\n const result = await state.approval.decide(id, decision, opts?.reason, opts?.signal);\n if (result.suspended) {\n await this.hydrateApprovalInboxItem(id, opts?.signal).catch(() => {\n /* detail refresh is best-effort */\n });\n } else {\n void this.refreshApprovalPendingCount(opts?.signal).catch(() => {\n /* badge refresh is best-effort */\n });\n void this.refreshApprovalInbox().catch(() => {\n /* inbox refresh is best-effort */\n });\n }\n this.bus.emit('approvalInboxChanged', undefined);\n void this.refreshPageActionRowsAfterApprovalDecision(runId, id);\n void this.emitApprovalExecutionCompleted({\n approvalId: id,\n runId,\n decision,\n result,\n identity,\n }).catch(() => {\n /* execution notice is best-effort */\n });\n if (result.suspended) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'suspended');\n } else if (decision.action === 'cancel') {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'cancelled');\n } else if (result.resumed) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'resumed');\n }\n return result;\n }\n\n async rejectApproval(\n id: number,\n reason?: string,\n signal?: AbortSignal,\n ): Promise<ApprovalRejectResult> {\n await this.ensureLoggedIn('rejectApproval');\n const state = this.requireState('rejectApproval');\n const runId = this.resolveApprovalPageActionRunId(id);\n const identity = this.resolveApprovalIdentity(id);\n const result = await state.approval.reject(id, reason, signal);\n void this.refreshApprovalPendingCount(signal).catch(() => {\n /* badge refresh is best-effort */\n });\n void this.refreshApprovalInbox().catch(() => {\n /* inbox refresh is best-effort */\n });\n this.bus.emit('approvalInboxChanged', undefined);\n void this.refreshPageActionRowsAfterApprovalDecision(runId, id);\n if (result.ok) {\n this.syncPageActionRowAfterApprovalDecision(runId, id, 'cancelled');\n this.bus.emit('approvalExecutionCompleted', {\n approvalId: id,\n runId,\n outcome: 'cancelled',\n title: identity.approvalTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n });\n }\n return result;\n }\n\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 if (meta?.accepted) {\n this.trackAutomationRun(meta.accepted, {\n actionKey: meta.actionKey?.trim() || meta.accepted.runId.toString(),\n pageActionKey: meta.pageActionKey ?? meta.accepted.pageActionKey ?? null,\n rowKey: meta.rowKey ?? null,\n });\n return;\n }\n if (!Number.isFinite(runId)) return;\n const id = Math.trunc(runId);\n const now = new Date().toISOString();\n const rowKey = meta?.rowKey?.trim() || null;\n this.automationRunRegistry.set(id, {\n runId: id,\n actionKey: meta?.actionKey?.trim() || `Run ${id}`,\n pageActionKey: meta?.pageActionKey ?? null,\n rowKey,\n status: 'running',\n registeredAt: now,\n updatedAt: now,\n clientActionId: null,\n });\n if (rowKey) this.bindPageActionRunToRow(id, rowKey);\n const state = this.state;\n if (state) {\n this.syncAutomationActiveCount(state);\n state.automationRecentRunIds = [\n id,\n ...state.automationRecentRunIds.filter((row) => row !== id),\n ].slice(0, MAX_RECENT_AUTOMATION_RUN_IDS);\n this.notifyStateChange();\n }\n this.bus.emit('automationTaskCenterChanged', undefined);\n }\n\n reconcileAutomationTasksIfNeeded(): void {\n const state = this.state;\n if (!state?.isLoggedIn) return;\n pruneStaleTrackedRuns(this.automationRunRegistry);\n if (this.automationRunRegistry.size === 0) return;\n const stale =\n Date.now() - this.automationTasksLastSyncedAt > AUTOMATION_RECONCILE_STALE_MS;\n if (!stale) return;\n void this.refreshAutomationTasks({ status: 'active', offset: 0 }).catch(() => {\n /* reconcile is best-effort */\n });\n }\n\n async refreshAutomationTasks(\n opts: {\n signal?: AbortSignal;\n status?: AutomationTaskStatusFilter;\n actionKey?: string;\n limit?: number;\n offset?: number;\n append?: boolean;\n } = {},\n ): Promise<AutomationTaskList> {\n const cacheKey = opts.append ? null : this.buildAutomationTaskRefreshCacheKey(opts);\n if (\n this.automationTaskRefreshPromise &&\n cacheKey &&\n this.automationTaskRefreshCacheKey === cacheKey\n ) {\n return this.automationTaskRefreshPromise;\n }\n const run = this.fetchAutomationTasks(opts);\n if (!opts.append) {\n this.automationTaskRefreshCacheKey = cacheKey;\n this.automationTaskRefreshPromise = run;\n }\n try {\n return await run;\n } finally {\n if (!opts.append && this.automationTaskRefreshPromise === run) {\n this.automationTaskRefreshPromise = null;\n this.automationTaskRefreshCacheKey = null;\n }\n }\n }\n\n private buildAutomationTaskRefreshCacheKey(opts: {\n status?: AutomationTaskStatusFilter;\n actionKey?: string;\n offset?: number;\n }): string {\n const status = opts.status ?? 'active';\n const actionKey = opts.actionKey?.trim() ?? '';\n const offset = opts.offset ?? 0;\n return `${status}|${actionKey}|${offset}`;\n }\n\n setAutomationTaskStatusFilter(status: AutomationTaskStatusFilter): void {\n const state = this.state;\n if (!state || state.automationTaskStatusFilter === status) return;\n this.commitAutomationTaskTabCache(state);\n state.automationTaskStatusFilter = status;\n this.restoreAutomationTaskTabView(state);\n state.automationTaskSelectedDetail = null;\n this.notifyStateChange();\n }\n\n /**\n * Show a task-center tab — restore cached list or fetch page 1 when never loaded.\n */\n async ensureAutomationTaskTabLoaded(\n status?: AutomationTaskStatusFilter,\n opts: { refresh?: boolean; signal?: AbortSignal } = {},\n ): Promise<void> {\n await this.ensureLoggedIn('ensureAutomationTaskTabLoaded', { signal: opts.signal });\n const state = this.requireState('ensureAutomationTaskTabLoaded');\n const filter = status ?? state.automationTaskStatusFilter;\n if (filter !== state.automationTaskStatusFilter) {\n this.commitAutomationTaskTabCache(state);\n state.automationTaskStatusFilter = filter;\n this.restoreAutomationTaskTabView(state);\n state.automationTaskSelectedDetail = null;\n }\n const cache = getAutomationTaskTabCache(state.automationTaskTabCaches, filter);\n if (!cache.hydrated || opts.refresh) {\n await this.refreshAutomationTasks({ status: filter, offset: 0, signal: opts.signal });\n return;\n }\n this.notifyStateChange();\n }\n\n /** Append next page for the active task-center tab. */\n async loadAutomationTaskNextPage(opts: { signal?: AbortSignal } = {}): Promise<void> {\n await this.ensureLoggedIn('loadAutomationTaskNextPage', { signal: opts.signal });\n const state = this.requireState('loadAutomationTaskNextPage');\n if (state.automationTaskLoading || state.automationTaskLoadingMore || !state.automationTaskHasMore) {\n return;\n }\n await this.refreshAutomationTasks({\n status: state.automationTaskStatusFilter,\n append: true,\n signal: opts.signal,\n });\n }\n\n private commitAutomationTaskTabCache(state: InternalState): void {\n writeAutomationTaskTabCache(state.automationTaskTabCaches, state.automationTaskStatusFilter, {\n items: state.automationTaskItems,\n hasMore: state.automationTaskHasMore,\n total: state.automationTaskTotal,\n hydrated: getAutomationTaskTabCache(\n state.automationTaskTabCaches,\n state.automationTaskStatusFilter,\n ).hydrated,\n });\n }\n\n private restoreAutomationTaskTabView(state: InternalState): void {\n const cache = getAutomationTaskTabCache(\n state.automationTaskTabCaches,\n state.automationTaskStatusFilter,\n );\n state.automationTaskItems = [...cache.items];\n state.automationTaskHasMore = cache.hasMore;\n state.automationTaskTotal = cache.total;\n state.automationTaskLoading = false;\n state.automationTaskLoadingMore = false;\n }\n\n private publishAutomationTaskTabCache(\n state: InternalState,\n filter: AutomationTaskStatusFilter,\n items: AutomationTaskListItem[],\n hasMore: boolean,\n total?: number,\n ): void {\n const prev = getAutomationTaskTabCache(state.automationTaskTabCaches, filter);\n const resolvedTotal = total ?? prev.total;\n writeAutomationTaskTabCache(state.automationTaskTabCaches, filter, {\n items,\n hasMore,\n total: resolvedTotal,\n hydrated: true,\n });\n if (state.automationTaskStatusFilter === filter) {\n state.automationTaskItems = items;\n state.automationTaskHasMore = hasMore;\n state.automationTaskTotal = resolvedTotal;\n }\n }\n\n async refreshAutomationActiveCount(signal?: AbortSignal): Promise<void> {\n const state = this.state;\n if (!state) return;\n await this.ensureLoggedIn('refreshAutomationActiveCount', { signal });\n this.syncAutomationActiveCount(state);\n this.notifyStateChange();\n }\n\n async getAutomationTaskDetail(\n runId: number,\n signal?: AbortSignal,\n ): Promise<AutomationTaskDetail | null> {\n await this.ensureLoggedIn('getAutomationTaskDetail');\n const state = this.requireState('getAutomationTaskDetail');\n return state.automation.getPageActionRunTask(runId, signal);\n }\n\n async hydrateAutomationTaskDetail(\n runId: number,\n signal?: AbortSignal,\n ): Promise<AutomationTaskDetail | null> {\n await this.ensureLoggedIn('hydrateAutomationTaskDetail');\n const state = this.requireState('hydrateAutomationTaskDetail');\n state.automationTaskDetailLoading = true;\n this.notifyStateChange();\n try {\n const detail = await state.automation.getPageActionRunTask(runId, signal);\n state.automationTaskSelectedDetail = detail;\n if (detail) {\n const index = state.automationTaskItems.findIndex(\n (item) =>\n item.ref.kind === 'page_action_run' && item.ref.id === detail.ref.id,\n );\n if (index >= 0) {\n const next = [...state.automationTaskItems];\n next[index] = detail;\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n next,\n state.automationTaskHasMore,\n );\n }\n }\n return detail;\n } finally {\n state.automationTaskDetailLoading = false;\n this.notifyStateChange();\n }\n }\n\n clearAutomationTaskDetail(): void {\n const state = this.state;\n if (!state || !state.automationTaskSelectedDetail) return;\n state.automationTaskSelectedDetail = null;\n this.notifyStateChange();\n }\n\n /**\n * 任务中心「应用到页面」—— 只导航 + 写入 pendingApply,不直接 replay。\n * 目标页 `usePageAction({ ready })` 就绪后自动调用 `replayPageAction`。\n */\n async applyPageActionToPage(\n runId: number,\n opts: { signal?: AbortSignal } = {},\n ): Promise<ApplyPageActionToPageResult> {\n await this.ensureLoggedIn('applyPageActionToPage', { signal: opts.signal });\n const state = this.requireState('applyPageActionToPage');\n const id = Math.trunc(runId);\n if (!Number.isFinite(id)) {\n throw new AgentChatError('INVALID_OPTIONS', 'applyPageActionToPage requires a valid runId');\n }\n\n const detail =\n (await this.hydrateAutomationTaskDetail(id, opts.signal)) ??\n (await this.getAutomationTaskDetail(id, opts.signal));\n if (!detail || detail.ref.kind !== 'page_action_run') {\n throw new AgentChatError('PAGE_ACTION_FAILED', `PageAction run ${id} not found`);\n }\n\n const pageContext = detail.pageContext;\n const target = resolvePageContextNavigateTarget(pageContext);\n const base = {\n runId: id,\n actionKey: detail.actionKey,\n pageContext,\n target,\n };\n\n if (target.kind !== 'routePath') {\n return { ...base, navigated: false, canReplay: false, ok: false, reason: 'missing_route_path' };\n }\n\n if (detail.taskStatus !== 'completed') {\n const onNavigateEarly = state.options.onNavigateForPageAction;\n let navigated = false;\n if (onNavigateEarly) {\n await onNavigateEarly({ ...base, canReplay: false });\n navigated = true;\n }\n return { ...base, navigated, canReplay: false, ok: false, reason: 'not_completed' };\n }\n\n const canReplay = detail.replay.canReplay;\n if (!canReplay) {\n const onNavigateEmpty = state.options.onNavigateForPageAction;\n let navigated = false;\n if (onNavigateEmpty) {\n await onNavigateEmpty({ ...base, canReplay: false });\n navigated = true;\n }\n return { ...base, navigated, canReplay: false, ok: false, reason: 'no_replayable_output' };\n }\n\n // Write pending before navigate so the target page can see it on mount.\n this.setPendingPageActionApply({\n runId: id,\n actionKey: detail.actionKey,\n pageContext,\n createdAt: new Date().toISOString(),\n });\n\n const onNavigate = state.options.onNavigateForPageAction;\n let navigated = false;\n try {\n if (onNavigate) {\n await onNavigate({ ...base, canReplay: true });\n navigated = true;\n }\n } catch (err) {\n this.clearPendingPageActionApply();\n throw err;\n }\n\n // Same-page apply: navigate is often a no-op and mount sync may have been\n // in-flight when pending was written — kick coordinator again after settle.\n this.pageActionCoordinator.onPendingApplyChanged();\n\n return { ...base, navigated, canReplay: true, ok: true, reason: 'navigate_only' };\n }\n\n /**\n * 重放已完成 PageAction 的 stream 产出。\n * 成功或明确不可重放时清除匹配的 pendingApply;失败时保留 pending 以便重试。\n */\n async replayPageAction(\n runId: number,\n opts: { signal?: AbortSignal } = {},\n ): Promise<void> {\n await this.ensureLoggedIn('replayPageAction', { signal: opts.signal });\n const state = this.requireState('replayPageAction');\n const id = Math.trunc(runId);\n\n const clearIfPending = () => {\n const pending = this.getPendingPageActionApply();\n if (pending?.runId === id) {\n this.clearPendingPageActionApply();\n }\n };\n\n const detail =\n state.automationTaskSelectedDetail?.ref.id === id\n ? state.automationTaskSelectedDetail\n : await this.getAutomationTaskDetail(id, opts.signal);\n if (!detail || detail.ref.kind !== 'page_action_run') {\n clearIfPending();\n throw new AgentChatError('PAGE_ACTION_FAILED', `PageAction run ${id} not found`);\n }\n if (detail.taskStatus !== 'completed' || !detail.replay.canReplay) {\n clearIfPending();\n return;\n }\n\n const accepted: InvokePageActionAccepted = {\n runId: id,\n generation: id,\n clientActionId: null,\n pageActionKey: detail.pageActionKey,\n streamUrl: detail.streamUrl,\n status: 'completed',\n };\n const pageContext = detail.pageContext;\n const pageGate = pageGateFromPageContext(pageContext);\n const rowKey =\n this.pageActionRunToRowKey.get(id) ??\n (pageContext?.entity?.id != null ? String(pageContext.entity.id).trim() : null);\n try {\n await this.consumePageActionRunStream(\n state,\n {\n actionKey: detail.actionKey,\n pageContext: pageContext ?? undefined,\n signal: opts.signal,\n },\n accepted,\n pageGate,\n pageContext,\n );\n clearIfPending();\n this.bus.emit('pageActionApplyCompleted', {\n runId: id,\n actionKey: detail.actionKey,\n rowKey,\n });\n } catch (err) {\n this.bus.emit('pageActionRunFailed', {\n runId: id,\n actionKey: detail.actionKey,\n rowKey,\n errorMessage: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n }\n\n getPendingPageActionApply(): PendingPageActionApply | null {\n if (this.pendingPageActionApply) return this.pendingPageActionApply;\n const state = this.state;\n if (!state?.dsn) return null;\n const fromStorage = readPendingPageActionApply(state.dsn);\n if (fromStorage) {\n this.pendingPageActionApply = fromStorage;\n }\n return this.pendingPageActionApply;\n }\n\n clearPendingPageActionApply(): void {\n const state = this.state;\n this.pendingPageActionApply = null;\n if (state?.dsn) {\n clearPendingPageActionApplyStorage(state.dsn);\n }\n this.bus.emit('pendingPageActionApplyChanged', null);\n this.pageActionCoordinator.onPendingApplyChanged();\n }\n\n /**\n * Attach to a running PageAction SSE (no-op if already attached).\n * @returns true when a new attach was started\n */\n async attachPageActionStream(\n runId: number,\n opts: { signal?: AbortSignal; rowKey?: string } = {},\n ): Promise<boolean> {\n await this.ensureLoggedIn('attachPageActionStream', { signal: opts.signal });\n const state = this.requireState('attachPageActionStream');\n const id = Math.trunc(runId);\n if (!Number.isFinite(id)) return false;\n if (this.pageActionRunAborts.has(id) || this.pageActionRunStreamPromises.has(id)) {\n return false;\n }\n\n const detail = await this.getAutomationTaskDetail(id, opts.signal);\n if (!detail || detail.ref.kind !== 'page_action_run') return false;\n if (detail.taskStatus !== 'running') return false;\n\n const rowKey = resolveRestoredPageActionRowKey(id, {\n rowKey: opts.rowKey,\n entityId: detail.pageContext?.entity?.id ?? null,\n findRowKeyByRunId: () =>\n this.findRowKeyByRunId(id) || this.findRowKeyByPageActionKey(detail.pageActionKey),\n });\n\n await this.hydratePageActionByRunId(id, {\n rowKey,\n actionKey: detail.actionKey,\n signal: opts.signal,\n });\n\n // Re-check after await — another attach/replay may have started.\n if (this.pageActionRunAborts.has(id) || this.pageActionRunStreamPromises.has(id)) {\n return false;\n }\n\n const accepted: InvokePageActionAccepted = {\n runId: id,\n generation: id,\n clientActionId: null,\n pageActionKey: detail.pageActionKey,\n streamUrl: detail.streamUrl,\n status: 'running',\n };\n const pageContext = detail.pageContext;\n const pageGate = pageGateFromPageContext(pageContext);\n\n void this.consumePageActionRunStream(\n state,\n {\n actionKey: detail.actionKey,\n pageContext: pageContext ?? undefined,\n rowKey,\n },\n accepted,\n pageGate,\n pageContext,\n ).catch((err) => {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n detail.actionKey.split('.')[0]?.trim();\n this.markTrackedAutomationRunFailed(id, detail.actionKey);\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n });\n\n this.bus.emit('pageActionStreamResumed', {\n runId: id,\n actionKey: detail.actionKey,\n rowKey,\n });\n\n return true;\n }\n\n async resumeActivePageActionStreams(\n opts: { actionKey?: string; signal?: AbortSignal } = {},\n ): Promise<number> {\n await this.ensureLoggedIn('resumeActivePageActionStreams', { signal: opts.signal });\n this.requireState('resumeActivePageActionStreams');\n const actionKey = opts.actionKey?.trim();\n let attached = 0;\n for (const [runId, tracked] of this.automationRunRegistry) {\n if (tracked.status !== 'running') continue;\n if (actionKey && tracked.actionKey !== actionKey) {\n await this.hydratePageActionByRunId(runId, {\n rowKey: tracked.rowKey ?? undefined,\n actionKey: tracked.actionKey,\n signal: opts.signal,\n });\n const refreshed = this.automationRunRegistry.get(runId);\n if (!refreshed || refreshed.actionKey !== actionKey) continue;\n }\n if (this.pageActionRunAborts.has(runId) || this.pageActionRunStreamPromises.has(runId)) {\n continue;\n }\n const ok = await this.attachPageActionStream(runId, {\n signal: opts.signal,\n rowKey: tracked.rowKey ?? undefined,\n });\n if (ok) attached += 1;\n }\n return attached;\n }\n\n private setPendingPageActionApply(pending: PendingPageActionApply): void {\n const state = this.requireState('setPendingPageActionApply');\n this.pendingPageActionApply = pending;\n writePendingPageActionApply(state.dsn, pending);\n this.bus.emit('pendingPageActionApplyChanged', pending);\n this.pageActionCoordinator.onPendingApplyChanged();\n }\n\n /** @internal exposed for hooks — whether pending matches this page slot */\n matchesPendingPageActionApply(opts: {\n actionKey: string;\n pageContext?: AgentChatPageContext | null;\n }): boolean {\n return matchesPendingPageActionApply(this.getPendingPageActionApply(), opts);\n }\n\n async getDownReasonTags(): Promise<MessageFeedbackDownReasonTag[]> {\n await this.ensureLoggedIn('getDownReasonTags');\n const state = this.requireState('getDownReasonTags');\n if (state.downReasonTagsCache) return state.downReasonTagsCache;\n const items = await state.feedback.getDownReasonTags();\n state.downReasonTagsCache = items;\n return items;\n }\n\n async submitMessageFeedback(\n messageId: string,\n body: UpsertMessageFeedbackBody,\n ): Promise<void> {\n await this.ensureLoggedIn('submitMessageFeedback');\n const state = this.requireState('submitMessageFeedback');\n const sessionId = state.activeSessionId ?? state.session.getSession()?.sessionId ?? null;\n if (!sessionId) {\n throw new AgentChatError('INVALID_OPTIONS', 'submitMessageFeedback: no active session');\n }\n const numericId = parsePersistedMessageId(messageId);\n if (numericId === null) {\n throw new AgentChatError('INVALID_OPTIONS', 'submitMessageFeedback: invalid messageId');\n }\n\n const current = state.messages.find((m) => m.id === messageId);\n if (!current || current.role !== 'agent') {\n throw new AgentChatError('INVALID_OPTIONS', 'submitMessageFeedback: not an assistant message');\n }\n\n const previousFeedback = current.feedback ?? null;\n const optimistic = this.buildOptimisticFeedback(numericId, body);\n this.patchMessageFeedback(state, messageId, optimistic);\n\n try {\n const saved = await state.feedback.upsert(sessionId, numericId, body);\n this.patchMessageFeedback(state, messageId, saved);\n } catch (err) {\n this.patchMessageFeedback(state, messageId, previousFeedback);\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to submit feedback', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n }\n }\n\n async removeMessageFeedback(messageId: string): Promise<void> {\n await this.ensureLoggedIn('removeMessageFeedback');\n const state = this.requireState('removeMessageFeedback');\n const sessionId = state.activeSessionId ?? state.session.getSession()?.sessionId ?? null;\n if (!sessionId) {\n throw new AgentChatError('INVALID_OPTIONS', 'removeMessageFeedback: no active session');\n }\n const numericId = parsePersistedMessageId(messageId);\n if (numericId === null) {\n throw new AgentChatError('INVALID_OPTIONS', 'removeMessageFeedback: invalid messageId');\n }\n\n const current = state.messages.find((m) => m.id === messageId);\n if (!current || current.role !== 'agent') {\n throw new AgentChatError('INVALID_OPTIONS', 'removeMessageFeedback: not an assistant message');\n }\n\n const previousFeedback = current.feedback ?? null;\n this.patchMessageFeedback(state, messageId, null);\n\n try {\n await state.feedback.remove(sessionId, numericId);\n } catch (err) {\n this.patchMessageFeedback(state, messageId, previousFeedback);\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to remove feedback', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n }\n }\n\n /** Internal: read the immutable options snapshot supplied at init time. */\n getOptions(): AgentChatOptions | null {\n return this.state?.options ?? null;\n }\n\n getState(): AgentChatState {\n if (this.stateSnapshot) return this.stateSnapshot;\n if (!this.state) {\n this.stateSnapshot = {\n lifecycle: this.lifecycle,\n dsn: null,\n isOpen: false,\n isClientAuthenticated: false,\n isLoggedIn: false,\n catalogHydrated: false,\n streamingSessionIds: [],\n pendingReplySessionIds: [],\n session: null,\n sessions: [],\n sessionsHasMore: false,\n sessionsLoadingMore: false,\n activeSessionId: null,\n messages: [],\n sessionMessagesHasMore: false,\n sessionMessagesLoadingMore: false,\n agents: [],\n skills: [],\n selectedAgentId: null,\n autoAgent: null,\n selectedSkillId: null,\n agentsLoading: false,\n skillsLoading: false,\n agentsEmptyReason: null,\n lastError: null,\n writeConfirmation: null,\n approvalInbox: {\n items: [],\n loading: false,\n loadingMore: false,\n hasMore: false,\n statusFilter: 'pending',\n pendingCount: 0,\n },\n automationTaskCenter: {\n items: [],\n loading: false,\n loadingMore: false,\n hasMore: false,\n total: 0,\n statusFilter: 'active',\n recentRunIds: [],\n activeCount: 0,\n selectedDetail: null,\n detailLoading: false,\n },\n skillIntentBanner: null,\n skillIntentClarify: null,\n brainClarify: null,\n skillTurnContract: null,\n skillTurnActive: null,\n skillPickerOpen: false,\n pageContext:\n this.pendingPageContext !== undefined ? this.pendingPageContext : null,\n routeContext: this.resolvePendingRouteContext(),\n registeredContextMentions: this.listPendingRegisteredContextMentions(),\n attachPageContext: this.pendingAttachPageContext ?? false,\n activeSessionRun: null,\n pendingGateJobs: this.snapshotPendingGateJobs(),\n };\n } else {\n this.stateSnapshot = {\n lifecycle: this.lifecycle,\n dsn: this.state.dsn,\n isOpen: this.state.isOpen,\n isClientAuthenticated: this.state.isClientAuthenticated,\n isLoggedIn: this.state.isLoggedIn,\n catalogHydrated: this.state.catalogHydrated,\n streamingSessionIds: this.listStreamingSessionIds(this.state),\n pendingReplySessionIds: this.collectSessionsWithPendingReplies(this.state),\n session: this.state.session.getSession(),\n sessions: this.state.sessions,\n sessionsHasMore: this.state.sessionsHasMore,\n sessionsLoadingMore: this.state.sessionsLoadingMore,\n activeSessionId: this.state.activeSessionId,\n messages: [...this.state.messages],\n sessionMessagesHasMore: this.state.activeSessionMessagesHasMore,\n sessionMessagesLoadingMore: this.state.sessionMessagesLoadingMore,\n agents: [...this.state.agents],\n skills: [...this.state.skills],\n selectedAgentId: this.state.selectedAgentId,\n autoAgent: this.state.autoAgent,\n selectedSkillId: this.state.selectedSkillId,\n agentsLoading: this.state.agentsLoading,\n skillsLoading: this.state.skillsLoading,\n agentsEmptyReason: this.state.agentsEmptyReason,\n lastError: this.state.lastError,\n writeConfirmation: this.state.writeConfirmation,\n approvalInbox: {\n items: [...this.state.approvalInboxItems],\n loading: this.state.approvalInboxLoading,\n loadingMore: this.state.approvalInboxLoadingMore,\n hasMore: this.state.approvalInboxHasMore,\n statusFilter: this.state.approvalInboxStatusFilter,\n pendingCount: this.state.approvalInboxPendingCount,\n },\n automationTaskCenter: {\n items: [...this.state.automationTaskItems],\n loading: this.state.automationTaskLoading,\n loadingMore: this.state.automationTaskLoadingMore,\n hasMore: this.state.automationTaskHasMore,\n total: this.state.automationTaskTotal,\n statusFilter: this.state.automationTaskStatusFilter,\n recentRunIds: [...this.state.automationRecentRunIds],\n activeCount: this.state.automationTaskActiveCount,\n selectedDetail: this.state.automationTaskSelectedDetail,\n detailLoading: this.state.automationTaskDetailLoading,\n },\n skillIntentBanner: this.state.skillIntentBanner,\n skillIntentClarify: this.state.skillIntentClarify,\n brainClarify: this.state.brainClarify,\n skillTurnContract: this.state.skillTurnContract,\n skillTurnActive: this.state.skillTurnActive,\n skillPickerOpen: this.state.skillPickerOpen,\n pageContext: this.state.pageContext ?? this.state.options.pageContext ?? null,\n routeContext: this.state.routeContext,\n registeredContextMentions: this.listRegisteredContextMentions(this.state),\n attachPageContext: this.state.attachPageContext,\n activeSessionRun: this.getActiveSessionRunSnapshot(this.state),\n pendingGateJobs: this.snapshotPendingGateJobs(),\n };\n }\n return this.stateSnapshot;\n }\n\n on<K extends keyof AgentChatEventMap>(\n event: K,\n handler: (payload: AgentChatEventMap[K]) => void,\n ): () => void {\n return this.bus.on(event, handler);\n }\n\n off<K extends keyof AgentChatEventMap>(\n event: K,\n handler: (payload: AgentChatEventMap[K]) => void,\n ): void {\n this.bus.off(event, handler);\n }\n\n // ------------------------------------------------------------- internal API\n\n /**\n * Subscribe to internal state changes (open/close, messages, session, error).\n * Used by the UI layer's `useSyncExternalStore` integration.\n */\n subscribeStateChange(listener: () => void): () => void {\n this.stateChangeListeners.add(listener);\n return () => this.stateChangeListeners.delete(listener);\n }\n\n /** Internal: append a message produced outside `sendMessage` (e.g. system). */\n appendMessage(message: AgentMessage): void {\n const state = this.state;\n if (!state) return;\n state.messages = [...state.messages, message];\n this.notifyStateChange();\n this.bus.emit('message', { message, source: message.role });\n }\n\n // ----------------------------------------------------------------- helpers\n\n private applyPendingRuntimeConfig(state: InternalState): void {\n if (this.pendingRouteContextOverride !== undefined) {\n state.routeContextOverride = this.pendingRouteContextOverride;\n this.pendingRouteContextOverride = undefined;\n }\n if (this.pendingPageContext !== undefined) {\n state.pageContext = this.pendingPageContext;\n state.options = { ...state.options, pageContext: this.pendingPageContext ?? undefined };\n this.pendingPageContext = undefined;\n }\n if (this.pendingAttachPageContext !== undefined) {\n state.attachPageContext = this.pendingAttachPageContext;\n state.options = { ...state.options, attachPageContext: this.pendingAttachPageContext };\n this.pendingAttachPageContext = undefined;\n }\n if (this.pendingContextMentionRegistry.size > 0) {\n state.contextMentionRegistry = mergeContextMentionRegistrations(\n state.contextMentionRegistry,\n [...this.pendingContextMentionRegistry.values()],\n false,\n );\n this.pendingContextMentionRegistry = new Map();\n }\n }\n\n private resolvePendingRouteContext(): AgentChatRouteContext | null {\n if (this.pendingRouteContextOverride === undefined) return null;\n const merged = mergeRouteContext(\n readWindowRouteContext(),\n this.pendingRouteContextOverride,\n );\n return Object.keys(merged).length > 0 ? merged : null;\n }\n\n /** Drop write-gate UI superseded by a newer session `generation`. */\n private discardStaleWriteConfirmations(\n state: InternalState,\n sessionId: string,\n generation: number,\n prevGeneration: number,\n ): void {\n const key = normalizeSessionId(sessionId);\n const gate = state.writeConfirmationsBySession.get(key);\n if (!gate) return;\n const stale =\n gate.generation != null\n ? gate.generation < generation\n : generation > prevGeneration;\n if (stale) {\n this.persistWriteConfirmation(state, sessionId, null);\n }\n }\n\n private notifyStateChange(): void {\n this.stateSnapshot = null;\n for (const listener of Array.from(this.stateChangeListeners)) {\n try {\n listener();\n } catch (err) {\n if (this.state?.options.debug) console.error('[agent-chat] state listener threw:', err);\n }\n }\n }\n\n private reportError(err: AgentChatError): void {\n const payload: AgentChatErrorPayload = {\n code: err.code,\n message: err.message,\n cause: (err as { cause?: unknown }).cause,\n };\n if (this.state) {\n this.state.lastError = payload;\n this.notifyStateChange();\n }\n if (this.state?.options.debug && typeof console !== 'undefined') {\n console.error('[agent-chat]', err);\n if (this.bus.listenerCount('error') === 0) {\n console.warn('[agent-chat] Unhandled AgentChat error (no `error` listeners attached)');\n }\n }\n this.bus.emit('error', payload);\n }\n\n /** 等待 init 完成 */\n private ensureInitialized(\n label: string,\n options?: { timeoutMs?: number; signal?: AbortSignal },\n ): Promise<void> {\n return this.initGate.wait({ label, ...options });\n }\n\n /** 等待 init + 登录 — 所有需要 JWT 的 public API 统一入口 */\n private async ensureLoggedIn(\n label: string,\n options?: { timeoutMs?: number; signal?: AbortSignal },\n ): Promise<void> {\n await this.initGate.wait({ label, ...options });\n this.syncAuthFromStore();\n await this.loginGate.wait({ label, ...options });\n }\n\n private requireState(method: string): InternalState {\n if (!this.state) {\n throw new AgentChatError(\n 'NOT_INITIALIZED',\n `AgentChat.${method}() called before init(). Call AgentChat.init({ dsn }) first.`,\n );\n }\n return this.state;\n }\n\n /** Pull pending approval count for launcher badge — best-effort, never throws. */\n private refreshApprovalBadgeBestEffort(): void {\n if (!this.isLoggedIn()) return;\n void this.refreshApprovalPendingCount().catch(() => {\n /* badge sync is best-effort */\n });\n }\n\n /** Pull active automation tasks for badge + pageActionKey reconcile — best-effort. */\n private shouldSkipActiveAutomationReconcile(): boolean {\n if (this.automationTasksLastSyncedAt === 0) return false;\n return Date.now() - this.automationTasksLastSyncedAt < AUTOMATION_RECONCILE_STALE_MS;\n }\n\n private refreshAutomationTasksBestEffort(): void {\n if (!this.isLoggedIn()) return;\n if (this.shouldSkipActiveAutomationReconcile()) return;\n void this.refreshAutomationTasks({ status: 'active', offset: 0 }).catch(() => {\n /* task center sync is best-effort */\n });\n }\n\n /**\n * Defer unscoped active-task fetch so PageAction hook binds can own scoped reconcile first.\n */\n private scheduleAutomationTasksBestEffort(): void {\n const run = () => {\n if (this.pageActionCoordinator.listBindings().length > 0) {\n const state = this.state;\n if (state) this.syncAutomationActiveCount(state);\n return;\n }\n this.refreshAutomationTasksBestEffort();\n };\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(run);\n } else {\n queueMicrotask(run);\n }\n }\n\n private makeAbortController(): AbortController {\n const ctrl = new AbortController();\n this.state?.abortControllers.add(ctrl);\n return ctrl;\n }\n\n /**\n * Warm session runtime + host-tool page cache (`POST /chat/{sessionId}/prepare`).\n * Automatically includes {@link buildPreparePageContext} when the host has set\n * `pageContext.page`. Best-effort: failures are swallowed unless `debug` is on.\n */\n async prepareSession(\n sessionId: string,\n signalOrOptions?: AbortSignal | PrepareSessionOptions,\n ): Promise<PrepareSessionResult | null> {\n await this.ensureLoggedIn('prepareSession');\n const state = this.requireState('prepareSession');\n const id = sessionId.trim();\n if (!id) return null;\n\n const options = normalizePrepareSessionOptions(signalOrOptions);\n const signal = options.signal;\n const pageContext = this.buildPreparePageContext(state);\n const fingerprint = this.buildPrepareFingerprint(id, pageContext);\n\n if (!options.force && fingerprint === this.lastPrepareFingerprint) {\n return null;\n }\n\n try {\n const result = await state.chat.prepareSession(id, pageContext, signal);\n if (signal?.aborted) return null;\n this.lastPrepareFingerprint = fingerprint;\n if (state.options.debug) {\n console.debug(\n '[agent-chat] prepareSession',\n result.pageScope,\n `hostTools=${result.hostToolsCount}`,\n result.fromCache ? 'fromCache' : 'warmed',\n );\n }\n return result;\n } catch (err) {\n if (signal?.aborted) return null;\n if (state.options.debug) {\n console.warn('[agent-chat] prepareSession failed:', err);\n }\n return null;\n }\n }\n\n /** Debounced prepare for the active session after page/route/session changes. */\n private schedulePrepareSession(): void {\n const state = this.state;\n if (!state?.isLoggedIn) return;\n const sessionId = state.activeSessionId?.trim();\n if (!sessionId) return;\n\n this.cancelScheduledPrepare();\n this.prepareAbort = new AbortController();\n const signal = this.prepareAbort.signal;\n\n this.prepareTimer = setTimeout(() => {\n this.prepareTimer = null;\n void this.prepareSession(sessionId, { signal });\n }, 200);\n }\n\n private cancelScheduledPrepare(): void {\n if (this.prepareTimer != null) {\n clearTimeout(this.prepareTimer);\n this.prepareTimer = null;\n }\n if (this.prepareAbort) {\n try {\n this.prepareAbort.abort();\n } catch {\n /* noop */\n }\n this.prepareAbort = null;\n }\n }\n\n /**\n * Page context for prepare — always includes host `page` when set (not gated\n * by {@link attachPageContext}); route fields are always merged.\n */\n private buildPreparePageContext(state: InternalState): AgentChatPageContext | null {\n const out: AgentChatPageContext = {};\n const route = state.routeContext;\n if (route?.routePath) out.routePath = route.routePath;\n if (route?.routeParams && Object.keys(route.routeParams).length > 0) {\n out.routeParams = route.routeParams;\n }\n\n const ext = state.pageContext ?? state.options.pageContext ?? null;\n if (ext?.page) out.page = ext.page;\n if (ext?.flowId != null) out.flowId = ext.flowId;\n if (ext?.programName) out.programName = ext.programName;\n if (ext?.entity) out.entity = ext.entity;\n if (ext?.metadata) out.metadata = ext.metadata;\n\n return Object.keys(out).length > 0 ? out : null;\n }\n\n private buildPrepareFingerprint(\n sessionId: string,\n pageContext: AgentChatPageContext | null,\n ): string {\n return JSON.stringify({\n sessionId: sessionId.trim().toLowerCase(),\n page: pageContext?.page ?? '',\n entityId: pageContext?.entity?.id ?? '',\n entityType: pageContext?.entity?.type ?? '',\n routePath: pageContext?.routePath ?? '',\n routeParams: pageContext?.routeParams ?? null,\n });\n }\n\n /** Delete a chat session (`DELETE /chat/{sessionId}`) and update the sidebar locally. */\n async deleteSession(sessionId: string): Promise<void> {\n await this.ensureLoggedIn('deleteSession');\n const state = this.requireState('deleteSession');\n const id = sessionId.trim();\n if (!id) {\n throw new AgentChatError('INVALID_OPTIONS', 'deleteSession: sessionId is required');\n }\n\n const normalizedId = normalizeSessionId(id);\n const isActive =\n state.activeSessionId != null &&\n normalizeSessionId(state.activeSessionId) === normalizedId;\n\n try {\n await state.chat.deleteSession(id);\n } catch (err) {\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('TRANSPORT_FAILED', 'Failed to delete session', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n }\n\n this.abortSessionStream(state, normalizedId);\n state.writeConfirmationsBySession.delete(normalizedId);\n state.sessionRuns.delete(normalizedId);\n\n for (const key of [...state.sessionMessagesCache.keys()]) {\n if (normalizeSessionId(key) === normalizedId) {\n state.sessionMessagesCache.delete(key);\n }\n }\n\n state.sessions = state.sessions.filter(\n (row) => normalizeSessionId(row.sessionId) !== normalizedId,\n );\n this.notifyStateChange();\n this.bus.emit('sessions', { sessions: state.sessions });\n\n if (isActive) {\n this.sessionEpoch += 1;\n state.activeSessionId = null;\n state.activeSessionMessagesPage = 0;\n state.activeSessionMessagesHasMore = false;\n state.session.reset();\n state.messages = [];\n state.writeConfirmation = null;\n const next = state.sessions[0];\n if (next) {\n await this.selectSession(next.sessionId);\n }\n }\n }\n\n /** Load session list via `GET /chat?page=1&size=` and update sidebar state. */\n async refreshSessions(signal?: AbortSignal): Promise<void> {\n await this.ensureLoggedIn('refreshSessions');\n const state = this.requireState('refreshSessions');\n const page = await this.fetchSessionsPage(state, 1, signal);\n state.sessions = page.sessions;\n state.sessionsPage = page.page;\n state.sessionsHasMore = page.hasMore;\n state.sessionsLoadingMore = false;\n this.notifyStateChange();\n this.bus.emit('sessions', { sessions: state.sessions });\n }\n\n /** Append the next page when the session sidebar is scrolled to the bottom. */\n async loadMoreSessions(signal?: AbortSignal): Promise<void> {\n await this.ensureLoggedIn('loadMoreSessions');\n const state = this.requireState('loadMoreSessions');\n if (!state.sessionsHasMore || state.sessionsLoadingMore) return;\n\n state.sessionsLoadingMore = true;\n this.notifyStateChange();\n try {\n const page = await this.fetchSessionsPage(state, state.sessionsPage + 1, signal);\n state.sessions = mergeSessionSummaries(state.sessions, page.sessions);\n state.sessionsPage = page.page;\n state.sessionsHasMore = page.hasMore;\n this.bus.emit('sessions', { sessions: state.sessions });\n } finally {\n state.sessionsLoadingMore = false;\n this.notifyStateChange();\n }\n }\n\n private async fetchSessionsPage(\n state: InternalState,\n page: number,\n signal?: AbortSignal,\n ) {\n const body = await state.chat.listSessions(page, state.sessionsPageSize, signal);\n return parseChatSessionListPage(body, page, state.sessionsPageSize);\n }\n\n /** Append older messages when the message list is scrolled to the top. */\n async loadMoreSessionMessages(signal?: AbortSignal): Promise<void> {\n await this.ensureLoggedIn('loadMoreSessionMessages');\n const state = this.requireState('loadMoreSessionMessages');\n const sessionId = state.activeSessionId;\n if (!sessionId || !state.activeSessionMessagesHasMore || state.sessionMessagesLoadingMore) {\n return;\n }\n\n state.sessionMessagesLoadingMore = true;\n this.notifyStateChange();\n try {\n const detailPage = await this.fetchSessionMessagesPage(\n state,\n sessionId,\n state.activeSessionMessagesPage + 1,\n signal,\n );\n const older = detailPage.messages.map((m) => this.toAgentMessage(m as ServerMessage));\n const merged = mergeOlderMessages(state.messages, older);\n state.messages = merged;\n state.activeSessionMessagesPage = detailPage.page;\n state.activeSessionMessagesHasMore = detailPage.hasMore;\n state.session.setSession(sessionId, merged);\n this.writeSessionMessagesCache(state, sessionId, merged, detailPage.page, detailPage.hasMore);\n this.notifyStateChange();\n void this.syncMessageFeedbacks(state, sessionId).catch(() => {\n /* feedback sync is best-effort */\n });\n } finally {\n state.sessionMessagesLoadingMore = false;\n this.notifyStateChange();\n }\n }\n\n async selectAgent(agentId: string): Promise<void> {\n await this.ensureLoggedIn('selectAgent');\n const state = this.requireState('selectAgent');\n const id = agentId.trim();\n if (!id) {\n if (!state.selectedAgentId && !state.autoAgent && !state.selectedSkillId) return;\n state.selectedAgentId = null;\n state.autoAgent = null;\n state.selectedSkillId = null;\n state.skills = [];\n state.skillsLoading = false;\n this.notifyStateChange();\n return;\n }\n if (state.selectedAgentId === id && state.autoAgent?.source === 'requested') return;\n\n state.selectedAgentId = id;\n state.autoAgent = { id, source: 'requested', reason: 'selected in UI' };\n state.selectedSkillId = null;\n this.notifyStateChange();\n await this.refreshSkills(id);\n }\n\n selectSkill(skillId: string): void {\n const state = this.requireState('selectSkill');\n const id = skillId.trim();\n if (!id) {\n if (state.selectedSkillId == null) return;\n state.selectedSkillId = null;\n state.skillPickerOpen = false;\n this.notifyStateChange();\n return;\n }\n if (state.selectedSkillId === id) return;\n state.selectedSkillId = id;\n state.skillPickerOpen = false;\n state.skillIntentClarify = null;\n this.notifyStateChange();\n }\n\n dismissSkillIntentBanner(): void {\n const state = this.state;\n if (!state?.skillIntentBanner) return;\n state.skillIntentBanner = null;\n this.notifyStateChange();\n }\n\n clearSkillFromIntentBanner(): void {\n this.selectSkill('');\n const state = this.state;\n if (!state) return;\n state.skillIntentBanner = null;\n this.notifyStateChange();\n }\n\n dismissSkillIntentClarify(): void {\n const state = this.state;\n if (!state?.skillIntentClarify) return;\n state.skillIntentClarify = null;\n this.notifyStateChange();\n }\n\n dismissBrainClarify(): void {\n const state = this.state;\n if (!state?.brainClarify) return;\n state.brainClarify = null;\n this.notifyStateChange();\n }\n\n async commitBrainClarify(selectedId: string): Promise<void> {\n await this.ensureLoggedIn('commitBrainClarify');\n const state = this.requireState('commitBrainClarify');\n const clarify = state.brainClarify;\n if (!clarify) return;\n const id = selectedId.trim();\n if (!id) {\n throw new AgentChatError('INVALID_OPTIONS', 'commitBrainClarify: selectedId required');\n }\n const candidate =\n clarify.brainClarify.candidates.find((row) => row.id === id) ?? null;\n const label = candidate\n ? formatBrainClarifyCandidateLabel(candidate)\n : id;\n const entityCommit = buildEntityCommit(clarify.brainClarify, id);\n state.brainClarify = null;\n this.notifyStateChange();\n try {\n await this.sendMessage(label, { entityCommit });\n } catch (err) {\n // Restore pick UI if send failed (footer was cleared optimistically).\n if (this.state === state && !state.brainClarify) {\n state.brainClarify = clarify;\n this.notifyStateChange();\n }\n throw err;\n }\n }\n\n async followSkillIntentClarify(): Promise<void> {\n await this.ensureLoggedIn('followSkillIntentClarify');\n const state = this.requireState('followSkillIntentClarify');\n const text =\n state.skillIntentClarify?.userMessage?.trim() ?? state.lastTurnUserMessage?.trim() ?? '';\n if (!text) {\n throw new AgentChatError('INVALID_OPTIONS', 'No user message to resend');\n }\n state.skillIntentClarify = null;\n this.selectSkill('');\n await this.sendMessage(text);\n }\n\n openSkillPicker(): void {\n const state = this.state;\n if (!state) return;\n state.skillPickerOpen = true;\n state.skillIntentClarify = null;\n this.notifyStateChange();\n }\n\n closeSkillPicker(): void {\n const state = this.state;\n if (!state?.skillPickerOpen) return;\n state.skillPickerOpen = false;\n this.notifyStateChange();\n }\n\n private resolveSkillName(state: InternalState, skillId: number | undefined): string | undefined {\n if (skillId == null) return undefined;\n const id = String(skillId);\n return state.skills.find((skill) => skill.id === id)?.name;\n }\n\n private clearSkillIntentUi(state: InternalState): void {\n state.skillIntentBanner = null;\n state.skillIntentClarify = null;\n state.brainClarify = null;\n state.skillTurnActive = null;\n }\n\n private applySkillTurnContract(\n state: InternalState,\n contract: SkillTurnContractView,\n input: {\n assistantMessageId: string;\n runId: number;\n steps: ReturnType<typeof resolveAlignmentSteps>;\n },\n ): void {\n const align = contract.skillAlignment;\n const observation = readSkillIntentMismatchObservation(input.steps);\n const skillId =\n contract.requestedSkillId ??\n align.requestedSkillId ??\n observation?.requestedSkillId;\n\n if (shouldShowSkillClarifyCard(contract) && align.code) {\n const userMessage =\n state.lastTurnUserMessage?.trim() ??\n observation?.userMessage?.trim() ??\n '';\n if (!userMessage) return;\n state.skillIntentClarify = {\n code: align.code,\n requestedSkillId: skillId ?? undefined,\n requestedSkillName:\n observation?.requestedSkillName ?? this.resolveSkillName(state, skillId),\n userMessage,\n messageId: input.assistantMessageId,\n runId: input.runId,\n };\n state.skillIntentBanner = null;\n state.skillTurnActive = null;\n return;\n }\n\n if (shouldShowIntentFirstBanner(contract)) {\n state.skillIntentBanner = {\n code: align.code ?? observation?.mismatchCode,\n requestedSkillId: skillId ?? undefined,\n requestedSkillName:\n observation?.requestedSkillName ?? this.resolveSkillName(state, skillId),\n };\n state.skillIntentClarify = null;\n state.skillTurnActive = null;\n return;\n }\n\n if (isRequestedSkillActuallyUsed(contract)) {\n state.skillTurnActive = {\n requestedSkillId: skillId ?? undefined,\n requestedSkillName:\n observation?.requestedSkillName ?? this.resolveSkillName(state, skillId),\n };\n state.skillIntentBanner = null;\n state.skillIntentClarify = null;\n return;\n }\n\n state.skillTurnActive = null;\n }\n\n private applySkillIntentAlignment(\n state: InternalState,\n input: {\n sessionId: string;\n runId: number;\n assistantMessageId: string;\n },\n ): void {\n if (!this.isViewingSession(state, input.sessionId)) return;\n\n void this.loadSkillIntentAlignment(state, input).catch(() => {\n /* best-effort UX hint */\n });\n }\n\n private async loadSkillIntentAlignment(\n state: InternalState,\n input: {\n sessionId: string;\n runId: number;\n assistantMessageId: string;\n },\n ): Promise<void> {\n const appClientId = state.appClientId;\n if (appClientId == null) return;\n\n const body = await state.agentRun.getRun(appClientId, input.runId);\n const detail = parseAgentRunDetail(body);\n if (!detail) return;\n\n const steps = resolveAlignmentSteps(detail);\n const brainClarify = extractBrainClarifyFromRunSteps({ steps });\n if (brainClarify && this.isViewingSession(state, input.sessionId)) {\n state.brainClarify = {\n messageId: input.assistantMessageId,\n runId: input.runId,\n brainClarify,\n };\n } else if (\n state.brainClarify?.runId === input.runId ||\n state.brainClarify?.messageId === input.assistantMessageId\n ) {\n state.brainClarify = null;\n }\n\n const contract = readSkillTurnContract(steps);\n if (!contract) {\n if (brainClarify) this.notifyStateChange();\n return;\n }\n\n state.skillTurnContract = contract;\n this.applySkillTurnContract(state, contract, {\n assistantMessageId: input.assistantMessageId,\n runId: input.runId,\n steps,\n });\n this.notifyStateChange();\n }\n\n async refreshAgentCatalog(signal?: AbortSignal): Promise<void> {\n await this.ensureInitialized('refreshAgentCatalog', { signal });\n const state = this.requireState('refreshAgentCatalog');\n\n if (state.options.agents?.length) {\n state.agents = [...state.options.agents];\n state.agentsEmptyReason = null;\n this.syncDefaultAgentSelection(state);\n if (!state.options.skills?.length) {\n await this.refreshSkills(state.selectedAgentId ?? undefined, signal);\n }\n return;\n }\n\n await this.ensureLoggedIn('refreshAgentCatalog', { signal });\n\n state.agentsLoading = true;\n state.agentsEmptyReason = null;\n this.notifyStateChange();\n try {\n const body = await state.agent.listAvailableAgents(\n state.options.agentListQuery,\n signal,\n );\n const agents = parseAgentList(body);\n state.agents = agents;\n if (agents.length === 0) {\n state.agentsEmptyReason = await this.resolveAgentsEmptyReason(state, signal);\n }\n this.syncDefaultAgentSelection(state);\n await this.refreshSkills(state.selectedAgentId ?? undefined, signal);\n } catch {\n state.agents = [];\n state.agentsEmptyReason = null;\n this.applyStaticSkills(state);\n } finally {\n state.agentsLoading = false;\n this.notifyStateChange();\n }\n }\n\n private async resolveAgentsEmptyReason(\n state: InternalState,\n signal?: AbortSignal,\n ): Promise<AgentsEmptyReason> {\n try {\n const allBody = await state.agent.listAllClientAgents(signal);\n const allAgents = parseAgentList(allBody);\n return allAgents.length > 0 ? 'permission' : 'not_configured';\n } catch {\n return null;\n }\n }\n\n private async refreshSkills(agentId?: string, signal?: AbortSignal): Promise<void> {\n const state = this.requireState('refreshSkills');\n const normalizedAgentId = agentId?.trim() || state.selectedAgentId || undefined;\n const loadToken = ++this.skillsLoadToken;\n\n if (state.options.skills?.length) {\n state.skills = normalizedAgentId\n ? state.options.skills.filter(\n (skill) => !skill.agentId || skill.agentId === normalizedAgentId,\n )\n : [...state.options.skills];\n this.syncDefaultSkillSelection(state);\n this.notifyStateChange();\n return;\n }\n\n if (!normalizedAgentId) {\n state.skills = [];\n state.selectedSkillId = null;\n this.notifyStateChange();\n return;\n }\n\n state.skillsLoading = true;\n this.notifyStateChange();\n const isCurrentSkillsLoad = () => loadToken === this.skillsLoadToken;\n try {\n const pageContext = state.pageContext ?? state.options.pageContext ?? null;\n const query = buildClientSkillListQuery(state.options.skillListQuery, pageContext);\n const body = await state.agent.listClientSkills(normalizedAgentId, query, signal);\n if (!isCurrentSkillsLoad()) return;\n state.skills = parseSkillList(body);\n this.syncDefaultSkillSelection(state);\n } catch {\n if (isCurrentSkillsLoad()) {\n state.skills = [];\n state.selectedSkillId = null;\n }\n } finally {\n if (isCurrentSkillsLoad()) {\n state.skillsLoading = false;\n this.notifyStateChange();\n }\n }\n }\n\n private applyStaticSkills(state: InternalState): void {\n const staticSkills = state.options.skills;\n if (!staticSkills?.length) return;\n const agentId = state.selectedAgentId;\n state.skills = agentId\n ? staticSkills.filter((skill) => !skill.agentId || skill.agentId === agentId)\n : [...staticSkills];\n this.syncDefaultSkillSelection(state);\n }\n\n private syncDefaultAgentSelection(state: InternalState): void {\n const defaultAgentId = state.options.defaultAgentId?.trim();\n if (state.selectedAgentId && state.agents.length > 0) {\n if (!state.agents.some((agent) => agent.id === state.selectedAgentId)) {\n state.selectedAgentId =\n defaultAgentId && state.agents.some((agent) => agent.id === defaultAgentId)\n ? defaultAgentId\n : null;\n if (!state.selectedAgentId) {\n state.selectedSkillId = null;\n }\n }\n } else if (defaultAgentId && state.agents.some((agent) => agent.id === defaultAgentId)) {\n state.selectedAgentId = defaultAgentId;\n }\n this.applyStaticSkills(state);\n }\n\n private applyAutoAgentBinding(\n state: InternalState,\n binding: AutoAgentBinding | null | undefined,\n ): void {\n if (!binding?.id) return;\n const previousAgentId = state.selectedAgentId;\n state.autoAgent = binding;\n state.selectedAgentId = binding.id;\n if (previousAgentId !== binding.id) {\n state.selectedSkillId = null;\n void this.refreshSkills(binding.id).catch(() => {\n /* skill refresh after Auto-Agent binding is best-effort */\n });\n }\n }\n\n private syncDefaultSkillSelection(state: InternalState): void {\n const defaultSkillId = state.options.defaultSkillId?.trim();\n if (\n state.selectedSkillId &&\n state.skills.some((skill) => skill.id === state.selectedSkillId)\n ) {\n return;\n }\n if (defaultSkillId && state.skills.some((skill) => skill.id === defaultSkillId)) {\n state.selectedSkillId = defaultSkillId;\n return;\n }\n\n const pageScope = this.getPageScope(state);\n if (pageScope) {\n const pageDefault = resolveDefaultSkillId(state.skills);\n state.selectedSkillId = pageDefault ?? null;\n return;\n }\n\n state.selectedSkillId = state.skills[0]?.id ?? null;\n }\n\n private getPageScope(state: InternalState): string {\n return (state.pageContext?.page ?? state.options.pageContext?.page ?? '').trim();\n }\n\n private syncActiveWriteConfirmation(state: InternalState, sessionId: string): void {\n const key = normalizeSessionId(sessionId);\n state.writeConfirmation = state.writeConfirmationsBySession.get(key) ?? null;\n }\n\n private persistWriteConfirmation(\n state: InternalState,\n sessionId: string,\n confirmation: WriteConfirmationState | null,\n ): void {\n const key = normalizeSessionId(sessionId);\n if (confirmation) {\n state.writeConfirmationsBySession.set(key, confirmation);\n } else {\n state.writeConfirmationsBySession.delete(key);\n }\n if (this.isViewingSession(state, sessionId)) {\n state.writeConfirmation = confirmation;\n }\n }\n\n private maybeNotifyBackgroundReply(state: InternalState, sessionId: string): void {\n if (state.isOpen && this.isViewingSession(state, sessionId)) return;\n const normalizedId = normalizeSessionId(sessionId);\n const session = state.sessions.find(\n (item) => normalizeSessionId(item.sessionId) === normalizedId,\n );\n this.bus.emit('backgroundReplyReady', {\n sessionId: normalizedId,\n sessionTitle: session?.title ?? null,\n });\n }\n\n private emitHostAction(\n state: InternalState,\n action: AgentChatHostAction,\n phase: 'streaming' | 'complete' = 'complete',\n options?: { skipToolExecution?: boolean },\n ): void {\n const isStreaming = phase === 'streaming';\n if (isStreaming) return;\n if (!isDispatchableHostAction(action)) return;\n\n const enriched: AgentChatHostAction = {\n ...action,\n sessionId: action.sessionId ?? state.activeSessionId ?? undefined,\n streamPhase: action.streamPhase ?? phase,\n };\n this.bus.emit('hostAction', { action: enriched, phase: 'complete' });\n\n void (async () => {\n await dispatchHostAction(enriched);\n if (!options?.skipToolExecution) {\n await executeHostToolsFromAction(enriched);\n }\n })().catch((err) => {\n if (state.options.debug) {\n console.warn('[agent-chat] hostAction dispatch failed:', err);\n }\n });\n }\n\n private emitPageAgentLifecycle(payload: PageAgentLifecyclePayload): void {\n this.bus.emit('pageAgentLifecycle', payload);\n }\n\n private emitPageAgentCompleteFromAction(\n action: AgentChatHostAction,\n source: PageAgentSource,\n ): void {\n const scope = action.scope?.trim();\n if (!scope) return;\n this.emitPageAgentLifecycle({\n type: 'complete',\n context: {\n scope,\n source,\n hostTools: action.hostTools,\n action,\n entity: action.entity,\n reason: action.reason,\n },\n });\n }\n\n private emitPageAgentError(\n scope: string | undefined,\n source: PageAgentSource,\n phase: PageAgentErrorContext['phase'],\n err: unknown,\n ): void {\n const message =\n err instanceof AgentChatError\n ? err.message\n : err instanceof Error\n ? err.message\n : String(err);\n const code = err instanceof AgentChatError ? err.code : undefined;\n this.emitPageAgentLifecycle({\n type: 'error',\n context: {\n scope,\n source,\n phase,\n code,\n message,\n },\n });\n }\n\n private buildHostActionPageGate(state: InternalState): {\n page?: string;\n entity?: { type?: string; id?: string | number };\n } {\n const ext = state.pageContext ?? state.options.pageContext ?? null;\n return {\n ...(ext?.page ? { page: ext.page } : {}),\n ...(ext?.entity ? { entity: ext.entity } : {}),\n };\n }\n\n private getHostToolStreamManager(\n state: InternalState,\n sessionId: string,\n pageGate?: PageContextGate,\n ): HostToolStreamManager {\n const key = normalizeSessionId(sessionId);\n const gate = pageGate ?? this.buildHostActionPageGate(state);\n let manager = this.hostToolStreamManagers.get(key);\n if (!manager) {\n manager = new HostToolStreamManager({\n pageContext: gate,\n sessionId,\n debug: state.options.debug,\n });\n this.hostToolStreamManagers.set(key, manager);\n } else {\n manager.updateOptions({\n pageContext: gate,\n sessionId,\n debug: state.options.debug,\n });\n }\n return manager;\n }\n\n private ingestHostActionSse(\n state: InternalState,\n sessionId: string,\n payload: HostActionSsePayload,\n pageGate?: PageContextGate,\n source: PageAgentSource = 'chat',\n ): void {\n if (!isHostToolStreamEnabled(state.options.hostToolStream, payload)) {\n const action = hostActionSseToAgentAction(payload, sessionId);\n if (action) {\n this.emitHostAction(state, action);\n this.emitPageAgentCompleteFromAction(action, source);\n }\n return;\n }\n\n if (!isHostActionStreamPayload(payload)) {\n const action = hostActionSseToAgentAction(payload, sessionId);\n if (action) {\n this.getHostToolStreamManager(state, sessionId, pageGate).reset();\n this.emitHostAction(state, action);\n this.emitPageAgentCompleteFromAction(action, source);\n }\n return;\n }\n\n const manager = this.getHostToolStreamManager(state, sessionId, pageGate);\n manager.ingest(payload, {\n source,\n emitLifecycle: (lifecycle) => this.emitPageAgentLifecycle(lifecycle),\n emitHostAction: (action, phase, options) => {\n this.emitHostAction(state, action, phase, options);\n },\n });\n }\n\n private acquirePageActionLock(clientActionId: string | undefined): string | null {\n const id = clientActionId?.trim();\n if (!id) return null;\n if (this.pageActionInFlightKeys.has(id)) {\n throw new AgentChatError(\n 'INVALID_OPTIONS',\n `Page action invoke already in flight for clientActionId: ${id}`,\n );\n }\n this.pageActionInFlightKeys.add(id);\n return id;\n }\n\n private releasePageActionLock(lockKey: string | null): void {\n if (lockKey) this.pageActionInFlightKeys.delete(lockKey);\n }\n\n private requirePageActionKey(\n input: Pick<PageBotInvokeInput, 'actionKey'>,\n ): string {\n const actionKey = input.actionKey?.trim();\n if (!actionKey) {\n throw new AgentChatError('INVALID_OPTIONS', 'Page action: actionKey is required');\n }\n return actionKey;\n }\n\n private resolvePageActionStreamSessionKey(\n input: PageBotInvokeInput,\n runId?: number,\n ): string {\n const clientActionId = input.clientActionId?.trim();\n if (clientActionId) {\n return `${PAGE_ACTION_STREAM_KEY_PREFIX}${clientActionId}`;\n }\n if (runId != null) {\n return `${PAGE_ACTION_STREAM_KEY_PREFIX}${runId}`;\n }\n return `${PAGE_ACTION_STREAM_KEY_PREFIX}${nanoId()}`;\n }\n\n private releasePageActionStreamManager(sessionKey: string): void {\n this.hostToolStreamManagers.delete(normalizeSessionId(sessionKey));\n }\n\n private resolvePageActionContext(\n state: InternalState,\n input: PageBotInvokeInput,\n ): AgentChatPageContext | undefined {\n const fromState = state.pageContext ?? state.options.pageContext ?? null;\n const fromInput = input.pageContext;\n if (fromInput && fromState) {\n return { ...fromState, ...fromInput };\n }\n return fromInput ?? fromState ?? undefined;\n }\n\n private buildPageActionInvokeBody(\n state: InternalState,\n input: PageBotInvokeInput,\n ): InvokePageActionRequest {\n const actionKey = this.requirePageActionKey(input);\n const pageContext = buildPageActionInvokePageContextSnapshot({\n pageContext: this.resolvePageActionContext(state, input),\n routeContext: state.routeContext,\n });\n const body: InvokePageActionRequest = { actionKey };\n if (pageContext) body.pageContext = pageContext;\n if (input.instruction?.trim()) body.instruction = input.instruction.trim();\n if (input.context && Object.keys(input.context).length > 0) {\n body.context = input.context;\n }\n if (input.idempotencyKey?.trim()) body.idempotencyKey = input.idempotencyKey.trim();\n if (input.clientActionId?.trim()) body.clientActionId = input.clientActionId.trim();\n if (input.entityCommit?.entityType?.trim() && input.entityCommit?.selectedId?.trim()) {\n body.entityCommit = {\n entityType: input.entityCommit.entityType.trim(),\n selectedId: input.entityCommit.selectedId.trim(),\n };\n }\n return body;\n }\n\n /**\n * Hint + popover gate. Returns a result when reuse/cancel handled the click;\n * `null` means fall through to a fresh invoke (no items, or user chose rerun).\n */\n private async tryPageActionReusePrompt(\n state: InternalState,\n input: PageBotInvokeInput,\n rowKey: string | null,\n opts: {\n body: InvokePageActionRequest;\n cached: PageActionReuseHint | null;\n },\n ): Promise<PageBotStreamResult | null> {\n const handler = this.pageActionReusePromptHandler;\n if (!handler) return null;\n\n let hint = opts.cached;\n if (!hint) {\n try {\n hint = await state.pageAction.reuseHint(opts.body, input.signal);\n this.pageActionReuseHintCache.set(opts.body, hint);\n } catch {\n // Hint is best-effort — never block a real invoke.\n return null;\n }\n }\n\n if (hint.reusable.total <= 0 || hint.reusable.items.length === 0) {\n return null;\n }\n\n if (rowKey) {\n const prev = this.pageActionRows.get(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: prev?.runId ?? null,\n pageActionKey: hint.pageActionKey,\n phase: 'awaiting_reuse',\n error: null,\n message: null,\n progressLabel: null,\n approvalRequestId: prev?.approvalRequestId ?? null,\n }),\n );\n }\n\n const prompt: PageActionReusePromptRequest = {\n actionKey: hint.actionKey,\n pageActionKey: hint.pageActionKey,\n items: hint.reusable.items,\n sourceRect: readLaunchSourceRect(input.launchAnchor),\n launchAnchor: input.launchAnchor ?? null,\n invokeSnapshot: {\n pageContext: input.pageContext,\n instruction: input.instruction,\n context: input.context,\n clientActionId: input.clientActionId,\n idempotencyKey: input.idempotencyKey,\n rowKey: rowKey ?? input.rowKey,\n awaitStream: input.awaitStream,\n },\n };\n\n const decision = await handler(prompt);\n if (decision.type === 'rerun') {\n // Fall through to a fresh POST /page-action/brain-invoke in invokePageAction.\n this.pageActionReuseHintCache.invalidateByBody(opts.body);\n if (rowKey) {\n const prev = this.pageActionRows.get(rowKey);\n this.clearPageActionNarrativeClearTimer(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: prev?.runId ?? null,\n pageActionKey: prev?.pageActionKey ?? hint.pageActionKey,\n phase: 'submitting',\n error: null,\n message: null,\n progressLabel: defaultPageActionProgressLabel(this.state?.options.locale),\n narrativeItems: [],\n approvalRequestId: prev?.approvalRequestId ?? null,\n }),\n );\n }\n return null;\n }\n\n if (decision.type === 'cancel') {\n // Keep cache — closing the popover must not force another reuse-hint.\n if (rowKey) {\n const prev = this.pageActionRows.get(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: input.actionKey.trim(),\n runId: prev?.runId ?? null,\n pageActionKey: prev?.pageActionKey ?? hint.pageActionKey,\n phase: 'idle',\n loading: false,\n disabled: false,\n error: null,\n message: null,\n progressLabel: null,\n approvalRequestId: prev?.approvalRequestId ?? null,\n }),\n );\n }\n return {\n actionRunId: 0,\n text: '',\n dslOutcome: null,\n actionKey: input.actionKey.trim(),\n clientActionId: input.clientActionId,\n cancelled: true,\n };\n }\n\n const item =\n hint.reusable.items.find((row) => row.ref.id === decision.runId) ??\n hint.reusable.items[0];\n if (!item) return null;\n\n return this.applyPageActionReuse(input, rowKey, hint, item);\n }\n\n private async applyPageActionReuse(\n input: PageBotInvokeInput,\n rowKey: string | null,\n hint: PageActionReuseHint,\n item: PageActionReusableItem,\n ): Promise<PageBotStreamResult> {\n const runId = item.ref.id;\n const locale = this.state?.options.locale;\n const tip = pageActionReusedMessage(locale);\n const actionKey = input.actionKey.trim();\n const dismissEpoch = rowKey\n ? (this.pageActionReuseDismissEpochByRowKey.get(rowKey) ?? 0)\n : 0;\n\n const wasDismissed = () =>\n rowKey != null &&\n (this.pageActionReuseDismissEpochByRowKey.get(rowKey) ?? 0) !== dismissEpoch;\n\n const setRow = (patch: {\n phase: PageActionPhase;\n loading?: boolean;\n disabled?: boolean;\n error?: string | null;\n message?: string | null;\n progressLabel?: string | null;\n }) => {\n if (!rowKey || wasDismissed()) return;\n const prev = this.pageActionRows.get(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey,\n runId,\n pageActionKey: hint.pageActionKey,\n phase: patch.phase,\n loading: patch.loading,\n disabled: patch.disabled,\n error: patch.error ?? null,\n message: patch.message ?? null,\n progressLabel: patch.progressLabel ?? null,\n approvalRequestId: prev?.approvalRequestId ?? null,\n }),\n );\n };\n\n // Selecting a historical run must actually apply it (replay), not only show a tip.\n setRow({\n phase: 'streaming',\n loading: true,\n disabled: true,\n progressLabel: pageActionReusingLabel(locale),\n message: null,\n error: null,\n });\n\n this.bus.emit('pageActionApplyStarted', {\n runId,\n actionKey,\n rowKey,\n });\n\n let text =\n item.outputs.fillText?.trim() ||\n item.outputs.preview?.trim() ||\n '';\n\n try {\n const detail = await this.getAutomationTaskDetail(runId, input.signal);\n if (wasDismissed()) {\n return {\n actionRunId: runId,\n text: '',\n dslOutcome: null,\n actionKey,\n clientActionId: input.clientActionId,\n cancelled: true,\n reused: true,\n };\n }\n if (!detail || detail.ref.kind !== 'page_action_run') {\n throw new AgentChatError(\n 'PAGE_ACTION_FAILED',\n `PageAction run ${runId} not found`,\n );\n }\n if (detail.taskStatus !== 'completed') {\n throw new AgentChatError(\n 'PAGE_ACTION_FAILED',\n `PageAction run ${runId} is not completed`,\n );\n }\n\n const detailText =\n detail.outputs.preview?.trim() ||\n text;\n if (detailText) text = detailText;\n\n const canReplay =\n detail.replay.canReplay ||\n detail.outputs.hasFillText === true ||\n Boolean(text);\n\n if (canReplay && (detail.replay.canReplay || detail.outputs.hasFillText)) {\n // 有 fill 产出:走 stream replay(服务端会尽量重放 host_action)\n await this.replayPageAction(runId, { signal: input.signal });\n if (wasDismissed()) {\n return {\n actionRunId: runId,\n text: '',\n dslOutcome: null,\n actionKey,\n clientActionId: input.clientActionId,\n cancelled: true,\n reused: true,\n };\n }\n // 宿主若挂了 onChunk,再补一份全文(分析页 / 无 host tool 时也能看到)\n if (text && input.onChunk) {\n try {\n input.onChunk(text);\n } catch {\n /* host onChunk must not break reuse */\n }\n }\n } else if (text && input.onChunk) {\n input.onChunk(text);\n this.bus.emit('pageActionApplyCompleted', {\n runId,\n actionKey,\n rowKey,\n });\n } else {\n // 无可重放 fill、也无 onChunk:打开任务中心看详情,避免「点了没效果」\n this.openAutomationTaskCenter({ runId });\n this.bus.emit('pageActionApplyCompleted', {\n runId,\n actionKey,\n rowKey,\n });\n }\n\n setRow({\n phase: 'completed',\n loading: false,\n disabled: false,\n message: tip,\n progressLabel: null,\n error: null,\n });\n if (rowKey && !wasDismissed()) this.schedulePageActionRowIdleReset(rowKey, 1_800);\n\n return {\n actionRunId: runId,\n text,\n dslOutcome: detail.replay.dslOutcome,\n actionKey,\n clientActionId: input.clientActionId,\n message: tip,\n reused: true,\n };\n } catch (err) {\n if (wasDismissed()) {\n return {\n actionRunId: runId,\n text: '',\n dslOutcome: null,\n actionKey,\n clientActionId: input.clientActionId,\n cancelled: true,\n reused: true,\n };\n }\n const message = err instanceof Error ? err.message : String(err);\n setRow({\n phase: 'failed',\n loading: false,\n disabled: false,\n error: message,\n message: null,\n progressLabel: null,\n });\n if (rowKey) this.schedulePageActionRowIdleReset(rowKey, 1_600);\n this.bus.emit('pageActionRunFailed', {\n runId,\n actionKey,\n rowKey,\n errorMessage: message,\n });\n throw err instanceof AgentChatError\n ? err\n : new AgentChatError('PAGE_ACTION_FAILED', message);\n }\n }\n\n private async invokePageActionStream(\n state: InternalState,\n input: PageBotInvokeInput,\n rowKey: string | null = null,\n ): Promise<PageBotStreamResult> {\n const pageContext = this.resolvePageActionContext(state, input);\n const pageGate = pageGateFromPageContext(pageContext);\n const requestBody = this.buildPageActionInvokeBody(state, input);\n const resolvedRowKey = rowKey ?? this.resolveInvokeRowKey(input);\n\n let invokeResult;\n try {\n invokeResult = await state.pageAction.invoke(requestBody, input.signal);\n } catch (err) {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim();\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n rethrowPageActionError(err);\n }\n\n if (invokeResult.kind === 'already_active') {\n const active = invokeResult;\n const accepted: InvokePageActionAccepted = {\n runId: active.existingRunId,\n generation: active.existingRunId,\n clientActionId: input.clientActionId?.trim() ?? null,\n pageActionKey: active.pageActionKey,\n streamUrl: active.streamUrl,\n status: active.existingStatus,\n };\n this.registerAutomationRun(accepted.runId, {\n actionKey: input.actionKey,\n accepted,\n pageActionKey: active.pageActionKey,\n rowKey: resolvedRowKey,\n });\n\n const tip =\n active.existingStatus === 'awaiting_approval'\n ? pageActionAlreadyAwaitingApprovalTip(this.state?.options.locale)\n : pageActionAlreadyRunningTip(this.state?.options.locale);\n\n if (resolvedRowKey) {\n this.syncPageActionRowFromAccepted(resolvedRowKey, input.actionKey, accepted, {\n approvalRequestId: active.approvalRequestId,\n message: tip,\n });\n }\n\n this.bus.emit('pageActionSoftNotice', {\n kind:\n active.existingStatus === 'awaiting_approval'\n ? 'already_awaiting_approval'\n : 'already_running',\n message: tip,\n runId: accepted.runId,\n actionKey: input.actionKey,\n approvalRequestId: active.approvalRequestId,\n });\n\n // Already paused for approval — notify once and skip run SSE (no progress until decided).\n if (active.existingStatus === 'awaiting_approval') {\n const result = this.buildEarlyPageActionResult(accepted, {\n actionKey: input.actionKey,\n approvalRequestId: active.approvalRequestId,\n message: tip,\n alreadyActive: true,\n });\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, result);\n return result;\n }\n\n // Duplicate running invoke: attach SSE in background, return tip immediately\n // (even when awaitStream is true — do not block on the existing run).\n const streamPromise = this.consumePageActionRunStream(\n state,\n input,\n accepted,\n pageGate,\n pageContext,\n );\n void streamPromise\n .then((result) => {\n if (result?.awaitingApproval) {\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, {\n ...result,\n approvalRequestId: result.approvalRequestId ?? active.approvalRequestId,\n });\n }\n })\n .catch((err) => {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim();\n this.markTrackedAutomationRunFailed(accepted.runId, input.actionKey);\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n });\n return this.buildEarlyPageActionResult(accepted, {\n actionKey: input.actionKey,\n approvalRequestId: active.approvalRequestId,\n message: tip,\n alreadyActive: true,\n });\n }\n\n const accepted = invokeResult;\n this.registerAutomationRun(accepted.runId, {\n actionKey: input.actionKey,\n accepted,\n pageActionKey: accepted.pageActionKey,\n rowKey: resolvedRowKey,\n });\n if (resolvedRowKey) {\n this.syncPageActionRowFromAccepted(resolvedRowKey, input.actionKey, accepted);\n }\n this.rememberPageActionInvokeSnapshot(input, resolvedRowKey, accepted.runId);\n const payload: PageActionSubmittedPayload = {\n ...accepted,\n sourceRect: readLaunchSourceRect(input.launchAnchor),\n launchAnchor: input.launchAnchor ?? null,\n rowKey: resolvedRowKey,\n actionKey: input.actionKey.trim(),\n };\n this.bus.emit('pageActionSubmitted', payload);\n\n const awaitStream = input.awaitStream !== false;\n const streamPromise = this.consumePageActionRunStream(\n state,\n input,\n accepted,\n pageGate,\n pageContext,\n );\n if (!awaitStream) {\n void streamPromise\n .then((result) => {\n if (result?.awaitingApproval) {\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, result);\n }\n // Brain clarify is emitted from applyPageActionRunLifecycle; no extra work.\n })\n .catch((err) => {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim();\n this.markTrackedAutomationRunFailed(accepted.runId, input.actionKey);\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n });\n const early = this.buildEarlyPageActionResult(accepted, { actionKey: input.actionKey });\n if (early.awaitingApproval) {\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, early);\n }\n return early;\n }\n\n try {\n return await streamPromise;\n } catch (err) {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim();\n this.markTrackedAutomationRunFailed(accepted.runId, input.actionKey);\n this.emitPageAgentError(scope, 'page_action', 'page_action', err);\n rethrowPageActionError(err);\n }\n }\n\n private buildEarlyPageActionResult(\n accepted: InvokePageActionAccepted,\n meta?: {\n actionKey?: string;\n approvalRequestId?: number | null;\n message?: string | null;\n alreadyActive?: boolean;\n },\n ): PageBotStreamResult {\n const awaitingApproval = accepted.status === 'awaiting_approval';\n return {\n actionRunId: accepted.runId,\n text: '',\n dslOutcome: null,\n awaitingApproval: awaitingApproval ? true : undefined,\n status: awaitingApproval ? 'awaiting_approval' : undefined,\n actionKey: meta?.actionKey,\n clientActionId: accepted.clientActionId ?? undefined,\n approvalRequestId: meta?.approvalRequestId ?? null,\n message: meta?.message ?? null,\n alreadyActive: meta?.alreadyActive === true ? true : undefined,\n };\n }\n\n /**\n * Duplicate invoke (local row still active): soft message, no throw.\n * Existing SSE from the first invoke continues to drive row phase.\n */\n private finishAlreadyActiveInvoke(\n input: PageBotInvokeInput,\n rowKey: string,\n _meta: { source: 'local' },\n ): PageBotStreamResult {\n const row = this.pageActionRows.get(rowKey);\n const awaitingApproval = row?.awaitingApproval === true || row?.phase === 'awaiting_approval';\n const tip = awaitingApproval\n ? pageActionAlreadyAwaitingApprovalTip(this.state?.options.locale)\n : pageActionAlreadyRunningTip(this.state?.options.locale);\n\n if (row) {\n const { loading: _loading, disabled: _disabled, ...rest } = row;\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...rest,\n error: null,\n message: tip,\n }),\n );\n }\n\n this.bus.emit('pageActionSoftNotice', {\n kind: awaitingApproval ? 'already_awaiting_approval' : 'already_running',\n message: tip,\n runId: row?.runId ?? null,\n actionKey: input.actionKey.trim(),\n approvalRequestId: row?.approvalRequestId ?? null,\n });\n\n if (awaitingApproval && row?.runId != null) {\n if (!this.pageActionAwaitingApprovalNotified.has(row.runId)) {\n this.pageActionAwaitingApprovalNotified.add(row.runId);\n this.bus.emit('pageActionAwaitingApproval', {\n actionRunId: row.runId,\n actionKey: input.actionKey.trim(),\n approvalRequestId: row.approvalRequestId ?? null,\n });\n }\n }\n\n return {\n actionRunId: row?.runId ?? 0,\n text: '',\n dslOutcome: null,\n awaitingApproval: awaitingApproval ? true : undefined,\n status: awaitingApproval ? 'awaiting_approval' : undefined,\n actionKey: input.actionKey.trim(),\n clientActionId: input.clientActionId?.trim() || undefined,\n approvalRequestId: row?.approvalRequestId ?? null,\n message: tip,\n alreadyActive: true,\n };\n }\n\n private async consumePageActionRunStream(\n state: InternalState,\n input: PageBotInvokeInput,\n accepted: InvokePageActionAccepted,\n pageGate: PageContextGate,\n pageContext: AgentChatPageContext | null | undefined,\n ): Promise<PageBotStreamResult> {\n const existing = this.pageActionRunStreamPromises.get(accepted.runId);\n if (existing) {\n return existing;\n }\n\n const runPromise = this.runPageActionConsumeStream(\n state,\n input,\n accepted,\n pageGate,\n pageContext,\n ).finally(() => {\n if (this.pageActionRunStreamPromises.get(accepted.runId) === runPromise) {\n this.pageActionRunStreamPromises.delete(accepted.runId);\n }\n });\n this.pageActionRunStreamPromises.set(accepted.runId, runPromise);\n return runPromise;\n }\n\n private async runPageActionConsumeStream(\n state: InternalState,\n input: PageBotInvokeInput,\n accepted: InvokePageActionAccepted,\n pageGate: PageContextGate,\n pageContext: AgentChatPageContext | null | undefined,\n ): Promise<PageBotStreamResult> {\n const sessionKey = this.resolvePageActionStreamSessionKey(input, accepted.runId);\n this.getHostToolStreamManager(state, sessionKey, pageGate).reset();\n\n const runAbort = new AbortController();\n this.pageActionRunAborts.set(accepted.runId, runAbort);\n if (input.signal) {\n if (input.signal.aborted) runAbort.abort();\n else {\n input.signal.addEventListener('abort', () => runAbort.abort(), { once: true });\n }\n }\n\n try {\n const stream = state.pageAction.streamRun(accepted.runId, runAbort.signal);\n const result = await consumePageActionRunStream(stream, {\n onHostAction: (payload) => {\n this.ingestHostActionSse(state, sessionKey, payload, pageGate, 'page_action');\n },\n onChunk: input.onChunk,\n onLifecycle: (lifecycle) => {\n this.applyPageActionRunLifecycle(state, lifecycle);\n },\n onWorkflowProgress: (event) => {\n this.syncPageActionRowFromWorkflow(event);\n },\n debug: state.options.debug,\n });\n if (result.awaitingApproval) {\n this.notifyPageActionAwaitingApproval(pageGate, pageContext, input, result);\n }\n this.bus.emit('automationTaskCenterChanged', undefined);\n return result;\n } finally {\n this.pageActionRunAborts.delete(accepted.runId);\n this.releasePageActionStreamManager(sessionKey);\n }\n }\n\n private notifyPageActionAwaitingApproval(\n pageGate: PageContextGate,\n pageContext: AgentChatPageContext | null | undefined,\n input: PageBotInvokeInput,\n result: PageBotStreamResult,\n ): void {\n const runId = result.actionRunId;\n if (typeof runId === 'number' && Number.isFinite(runId)) {\n if (this.pageActionAwaitingApprovalNotified.has(runId)) {\n return;\n }\n this.pageActionAwaitingApprovalNotified.add(runId);\n }\n this.emitPageActionAwaitingApproval(pageGate, pageContext, input, result);\n const rowKey =\n input.rowKey?.trim() ||\n resolvePageActionRowKey({\n rowKey: input.rowKey,\n entityId: pageContext?.entity?.id ?? null,\n }) ||\n (typeof result.actionRunId === 'number'\n ? this.pageActionRunToRowKey.get(result.actionRunId)\n : null);\n if (rowKey) {\n const prev = this.pageActionRows.get(rowKey);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: result.actionKey ?? input.actionKey,\n runId: result.actionRunId ?? prev?.runId ?? null,\n pageActionKey: prev?.pageActionKey ?? null,\n phase: 'awaiting_approval',\n error: null,\n message: prev?.message ?? null,\n progressLabel:\n prev?.progressLabel ??\n resolvePageWorkflowProgressLabel(\n {\n phase: 'awaiting_approval',\n actionRunId: result.actionRunId ?? prev?.runId ?? 0,\n actionKey: (result.actionKey ?? input.actionKey).trim(),\n generation: 0,\n nodeId: '',\n stageKind: 'other',\n },\n this.state?.options.locale,\n ),\n narrativeItems: prev?.narrativeItems ?? [],\n approvalRequestId: result.approvalRequestId ?? null,\n brainClarify: prev?.brainClarify ?? null,\n }),\n );\n }\n this.bus.emit('pageActionAwaitingApproval', {\n actionRunId: result.actionRunId,\n actionKey: result.actionKey ?? input.actionKey,\n approvalRequestId: result.approvalRequestId ?? null,\n });\n }\n\n private rememberPageActionInvokeSnapshot(\n input: PageBotInvokeInput,\n rowKey: string | null,\n runId?: number | null,\n ): void {\n const snapshot: PageActionBrainClarifyInvokeSnapshot & {\n launchAnchor?: HTMLElement | null;\n } = {\n pageContext: input.pageContext,\n instruction: input.instruction,\n context: input.context,\n clientActionId: input.clientActionId,\n idempotencyKey: input.idempotencyKey,\n rowKey: input.rowKey ?? rowKey ?? undefined,\n awaitStream: input.awaitStream,\n launchAnchor: input.launchAnchor ?? null,\n };\n if (rowKey) {\n this.pageActionInvokeSnapshotsByRowKey.set(rowKey, snapshot);\n }\n if (typeof runId === 'number' && Number.isFinite(runId)) {\n this.pageActionInvokeSnapshotsByRunId.set(Math.trunc(runId), snapshot);\n }\n }\n\n private emitPageActionBrainClarify(\n _state: InternalState,\n lifecycle: PageActionSseLifecycle,\n rowKey: string | null,\n ): void {\n if (!lifecycle.brainClarify) return;\n this.emitPageActionBrainClarifyFromPayload({\n actionKey: lifecycle.actionKey,\n runId: lifecycle.actionRunId,\n brainClarify: lifecycle.brainClarify,\n rowKey,\n });\n }\n\n private emitPageActionBrainClarifyFromPayload(input: {\n actionKey: string;\n runId: number;\n brainClarify: BrainClarifyPayload;\n rowKey: string | null;\n }): void {\n const runId = input.runId;\n const rowKey = input.rowKey;\n const snap =\n this.pageActionInvokeSnapshotsByRunId.get(runId) ??\n (rowKey ? this.pageActionInvokeSnapshotsByRowKey.get(rowKey) : undefined) ??\n null;\n const prompt: PageActionBrainClarifyPromptRequest = {\n actionKey: input.actionKey,\n runId,\n brainClarify: input.brainClarify,\n sourceRect: readLaunchSourceRect(snap?.launchAnchor ?? null),\n launchAnchor: snap?.launchAnchor ?? null,\n invokeSnapshot: snap\n ? {\n pageContext: snap.pageContext,\n instruction: snap.instruction,\n context: snap.context,\n clientActionId: snap.clientActionId,\n // Intentionally omit idempotencyKey — clarify continuation must open a new run.\n rowKey: snap.rowKey,\n awaitStream: snap.awaitStream,\n }\n : undefined,\n };\n this.bus.emit('pageActionBrainClarify', prompt);\n }\n\n private syncPageActionRowAfterApprovalDecision(\n runId: number | null | undefined,\n approvalId: number | null | undefined,\n transition: 'resumed' | 'cancelled' | 'suspended',\n ): void {\n const resolvedRunId = this.resolvePageActionRunIdForApproval(runId, approvalId);\n if (resolvedRunId != null) {\n this.pageActionAwaitingApprovalNotified.delete(resolvedRunId);\n }\n\n const rowKey = this.findRowKeyForApproval(resolvedRunId, approvalId);\n if (!rowKey) return;\n\n const prev = this.pageActionRows.get(rowKey);\n const approvalKey =\n approvalId != null && Number.isFinite(approvalId) ? Math.trunc(approvalId) : null;\n const canSync =\n prev?.awaitingApproval ||\n prev?.phase === 'awaiting_approval' ||\n (resolvedRunId != null && prev?.runId === resolvedRunId) ||\n (approvalKey != null && prev?.approvalRequestId === approvalKey);\n if (!prev || !canSync) return;\n\n if (transition === 'resumed') {\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n rowKey,\n runId: resolvedRunId ?? prev.runId,\n phase: 'streaming',\n error: null,\n approvalRequestId: null,\n }),\n );\n return;\n }\n\n if (transition === 'suspended') {\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n rowKey,\n runId: resolvedRunId ?? prev.runId,\n phase: 'awaiting_approval',\n error: null,\n approvalRequestId: approvalId ?? prev.approvalRequestId,\n }),\n );\n return;\n }\n\n // cancelled / rejected — unlock row immediately; hydrate will refine terminal status.\n if (resolvedRunId != null) {\n this.automationRunRegistry.delete(resolvedRunId);\n }\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n rowKey,\n runId: null,\n phase: 'idle',\n error: null,\n approvalRequestId: null,\n }),\n );\n }\n\n private findRowKeyByRunId(runId: number): string | null {\n const id = Math.trunc(runId);\n const mapped =\n this.pageActionRunToRowKey.get(id)?.trim() ||\n this.automationRunRegistry.get(id)?.rowKey?.trim() ||\n null;\n if (mapped) return mapped;\n for (const row of this.pageActionRows.values()) {\n if (row.runId === id) return row.rowKey;\n }\n return null;\n }\n\n private findRowKeyForApproval(\n runId: number | null,\n approvalId: number | null | undefined,\n ): string | null {\n if (runId != null && Number.isFinite(runId)) {\n const mapped = this.findRowKeyByRunId(Math.trunc(runId));\n if (mapped) return mapped;\n }\n if (approvalId != null && Number.isFinite(approvalId)) {\n const approvalKey = Math.trunc(approvalId);\n for (const row of this.pageActionRows.values()) {\n if (row.approvalRequestId === approvalKey) return row.rowKey;\n }\n }\n return null;\n }\n\n private resolvePageActionRunIdForApproval(\n runId: number | null | undefined,\n approvalId: number | null | undefined,\n ): number | null {\n if (typeof runId === 'number' && Number.isFinite(runId)) {\n return Math.trunc(runId);\n }\n if (approvalId != null && Number.isFinite(approvalId)) {\n return this.resolveApprovalPageActionRunId(Math.trunc(approvalId));\n }\n return null;\n }\n\n private refreshPageActionRowsAfterApprovalDecision(\n runId: number | null | undefined,\n approvalId: number | null | undefined,\n ): void {\n void (async () => {\n try {\n if (this.automationRunRegistry.size > 0) {\n await this.refreshAutomationTasks({ status: 'active', offset: 0 });\n }\n const resolvedRunId = this.resolvePageActionRunIdForApproval(runId, approvalId);\n if (resolvedRunId != null) {\n await this.hydratePageActionByRunId(resolvedRunId);\n return;\n }\n const awaitingRows = [...this.pageActionRows.values()].filter(\n (row) => row.awaitingApproval || row.phase === 'awaiting_approval',\n );\n await Promise.all(\n awaitingRows\n .filter((row) => row.runId != null)\n .map((row) => this.hydratePageActionByRunId(row.runId!)),\n );\n } catch {\n /* approval-driven row refresh is best-effort */\n }\n })();\n }\n\n private emitPageActionAwaitingApproval(\n pageGate: PageContextGate,\n pageContext: AgentChatPageContext | null | undefined,\n input: PageBotInvokeInput,\n result: PageBotStreamResult,\n ): void {\n const scope =\n pageGate.page?.trim() ??\n pageContext?.page?.trim() ??\n input.actionKey?.split('.')[0]?.trim() ??\n '';\n if (scope) {\n this.bus.emit('pageAgentAwaitingApproval', {\n scope,\n actionRunId: result.actionRunId,\n actionKey: result.actionKey,\n clientActionId: result.clientActionId,\n approvalRequestId: result.approvalRequestId ?? null,\n } satisfies PageAgentAwaitingApprovalPayload);\n }\n // Badge only — list refresh waits until user opens the inbox drawer.\n void this.refreshApprovalPendingCount().catch(() => {\n /* badge refresh is best-effort */\n });\n this.bus.emit('approvalInboxChanged', undefined);\n }\n\n private clearAutomationRunRegistry(): void {\n this.automationRunRegistry.clear();\n this.automationTasksLastSyncedAt = 0;\n this.pageActionRows.clear();\n this.pageActionRunToRowKey.clear();\n this.pageActionReuseHintCache.clear();\n this.clearPageActionRowIdleTimers();\n }\n\n private syncAutomationActiveCount(state: InternalState): void {\n pruneStaleTrackedRuns(this.automationRunRegistry);\n state.automationTaskActiveCount = countActiveTrackedRuns(this.automationRunRegistry);\n }\n\n private resolveInvokeRowKey(input: PageBotInvokeInput): string | null {\n const state = this.state;\n if (!state) {\n return resolvePageActionRowKey({\n rowKey: input.rowKey,\n entityId: input.pageContext?.entity?.id ?? null,\n });\n }\n const pageContext = this.resolvePageActionContext(state, input);\n return resolvePageActionRowKey({\n rowKey: input.rowKey,\n entityId: pageContext?.entity?.id ?? null,\n });\n }\n\n private bindPageActionRunToRow(runId: number, rowKey: string): void {\n const key = rowKey.trim();\n if (!key || !Number.isFinite(runId)) return;\n this.pageActionRunToRowKey.set(Math.trunc(runId), key);\n }\n\n private findRowKeyByPageActionKey(pageActionKey: string | null | undefined): string | null {\n const key = pageActionKey?.trim();\n if (!key) return null;\n for (const row of this.pageActionRows.values()) {\n if (row.pageActionKey?.trim() === key) return row.rowKey;\n }\n for (const run of this.automationRunRegistry.values()) {\n if (run.pageActionKey?.trim() === key && run.rowKey?.trim()) return run.rowKey.trim();\n }\n return null;\n }\n\n private upsertPageActionRow(row: PageActionRowState): void {\n const existingTimer = this.pageActionRowIdleTimers.get(row.rowKey);\n if (\n existingTimer != null &&\n row.phase !== 'completed' &&\n row.phase !== 'failed'\n ) {\n clearTimeout(existingTimer);\n this.pageActionRowIdleTimers.delete(row.rowKey);\n }\n // Strictly increasing updatedAt so React row sync cannot skip a loading/disabled unlock\n // when Date.now() collides with the previous upsert in the same ms.\n const prev = this.pageActionRows.get(row.rowKey);\n const next: PageActionRowState =\n prev && row.updatedAt <= prev.updatedAt\n ? { ...row, updatedAt: prev.updatedAt + 1 }\n : row;\n this.pageActionRows.set(next.rowKey, next);\n if (next.runId != null) this.bindPageActionRunToRow(next.runId, next.rowKey);\n this.bus.emit('pageActionRowChanged', { rowKey: next.rowKey, state: next });\n }\n\n private syncPageActionRowFromAccepted(\n rowKey: string,\n actionKey: string,\n accepted: InvokePageActionAccepted,\n opts: {\n approvalRequestId?: number | null;\n error?: string | null;\n message?: string | null;\n } = {},\n ): void {\n const phase: PageActionPhase =\n accepted.status === 'awaiting_approval'\n ? 'awaiting_approval'\n : accepted.status === 'running'\n ? 'launched'\n : taskStatusToPageActionPhase(accepted.status);\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: actionKey.trim(),\n runId: accepted.runId,\n pageActionKey: accepted.pageActionKey,\n phase,\n error: opts.error ?? null,\n message: opts.message ?? null,\n progressLabel:\n phase === 'awaiting_approval'\n ? resolvePageWorkflowProgressLabel(\n {\n phase: 'awaiting_approval',\n actionRunId: accepted.runId,\n actionKey: actionKey.trim(),\n generation: accepted.generation,\n nodeId: '',\n stageKind: 'other',\n },\n this.state?.options.locale,\n )\n : phase === 'launched' || phase === 'streaming'\n ? (this.pageActionRows.get(rowKey)?.progressLabel ??\n defaultPageActionProgressLabel(this.state?.options.locale))\n : null,\n narrativeItems: this.pageActionRows.get(rowKey)?.narrativeItems ?? [],\n approvalRequestId: opts.approvalRequestId ?? null,\n }),\n );\n }\n\n private syncPageActionRowFromWorkflow(event: PageWorkflowEvent): void {\n const runId = event.actionRunId;\n const rowKey =\n this.pageActionRunToRowKey.get(runId) ||\n this.automationRunRegistry.get(runId)?.rowKey?.trim() ||\n null;\n if (!rowKey) return;\n const prev = this.pageActionRows.get(rowKey);\n if (!prev) return;\n\n if (event.phase === 'failed') {\n // Terminal failure is owned by page_action.failed; keep current label.\n return;\n }\n\n if (\n prev.phase === 'idle' ||\n prev.phase === 'completed' ||\n prev.phase === 'failed' ||\n prev.phase === 'awaiting_reuse'\n ) {\n return;\n }\n\n const nextItems = appendPageActionNarrativeItems(\n prev.narrativeItems,\n event.narrativeItems,\n );\n const nextLabel = resolvePageWorkflowProgressLabel(event, this.state?.options.locale);\n const labelUnchanged = nextLabel == null || nextLabel === prev.progressLabel;\n const itemsUnchanged = nextItems === prev.narrativeItems;\n if (labelUnchanged && itemsUnchanged) {\n return;\n }\n\n const phase: PageActionPhase =\n event.phase === 'awaiting_approval'\n ? 'awaiting_approval'\n : prev.phase === 'submitting' || prev.phase === 'launched'\n ? 'streaming'\n : prev.loading || prev.phase === 'streaming'\n ? 'streaming'\n : prev.phase;\n\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...prev,\n phase,\n progressLabel: nextLabel ?? prev.progressLabel,\n narrativeItems: nextItems,\n // Duplicate-click tip is ephemeral; clear once real workflow narrative arrives.\n message: null,\n }),\n );\n }\n\n private syncPageActionRowFromLifecycle(lifecycle: PageActionSseLifecycle): void {\n const runId = lifecycle.actionRunId;\n const rowKey =\n this.pageActionRunToRowKey.get(runId) ||\n this.automationRunRegistry.get(runId)?.rowKey?.trim() ||\n null;\n if (!rowKey) return;\n const prev = this.pageActionRows.get(rowKey);\n // Late replay / aborted-reuse frames must not re-lock a settled trigger button.\n if (\n (lifecycle.phase === 'started' || lifecycle.phase === 'stream') &&\n (prev?.phase === 'idle' ||\n prev?.phase === 'completed' ||\n prev?.phase === 'failed' ||\n prev?.phase === 'awaiting_reuse')\n ) {\n return;\n }\n const isBrainClarify =\n lifecycle.phase === 'failed' &&\n isBrainAskUserErrorCode(lifecycle.errorCode) &&\n lifecycle.brainClarify != null;\n const phase: PageActionPhase =\n lifecycle.phase === 'started' || lifecycle.phase === 'stream'\n ? 'streaming'\n : lifecycle.phase === 'awaiting_approval'\n ? 'awaiting_approval'\n : lifecycle.phase === 'completed'\n ? 'completed'\n : isBrainClarify\n ? 'awaiting_clarify'\n : lifecycle.phase === 'failed'\n ? 'failed'\n : 'idle';\n // Skip redundant upsert for high-frequency stream frames when row is already streaming.\n if (\n lifecycle.phase === 'stream' &&\n prev?.phase === 'streaming' &&\n prev.progressLabel\n ) {\n return;\n }\n const progressLabel =\n phase === 'completed' || phase === 'failed'\n ? null\n : phase === 'awaiting_clarify'\n ? pageActionAwaitingClarifyLabel(this.state?.options.locale)\n : phase === 'awaiting_approval'\n ? resolvePageWorkflowProgressLabel(\n {\n phase: 'awaiting_approval',\n actionRunId: runId,\n actionKey: lifecycle.actionKey || prev?.actionKey || '',\n generation: lifecycle.generation,\n nodeId: '',\n stageKind: 'other',\n },\n this.state?.options.locale,\n )\n : (prev?.progressLabel ??\n defaultPageActionProgressLabel(this.state?.options.locale));\n this.upsertPageActionRow(\n buildPageActionRowState({\n rowKey,\n actionKey: lifecycle.actionKey || prev?.actionKey || `Run ${runId}`,\n runId,\n pageActionKey: prev?.pageActionKey ?? this.automationRunRegistry.get(runId)?.pageActionKey ?? null,\n phase,\n error: isBrainClarify\n ? null\n : lifecycle.errorMessage ?? (phase === 'failed' ? 'Page action failed' : null),\n message:\n phase === 'failed' ||\n phase === 'completed' ||\n phase === 'awaiting_clarify' ||\n lifecycle.phase === 'started'\n ? null\n : (prev?.message ?? null),\n progressLabel,\n narrativeItems: prev?.narrativeItems ?? [],\n approvalRequestId: prev?.approvalRequestId ?? null,\n brainClarify: isBrainClarify ? lifecycle.brainClarify ?? null : null,\n }),\n );\n if (phase === 'completed' || phase === 'failed') {\n this.schedulePageActionRowIdleReset(rowKey, phase === 'failed' ? 1_600 : 900);\n }\n }\n\n private pageActionRowIdleTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n private schedulePageActionRowIdleReset(\n rowKey: string,\n delayMs: number,\n fromPhases: PageActionPhase[] = ['completed', 'failed'],\n ): void {\n const key = rowKey.trim();\n if (!key) return;\n const existing = this.pageActionRowIdleTimers.get(key);\n if (existing != null) clearTimeout(existing);\n const allowed = new Set(fromPhases);\n const timer = setTimeout(() => {\n this.pageActionRowIdleTimers.delete(key);\n const current = this.pageActionRows.get(key);\n if (!current) return;\n if (!allowed.has(current.phase)) return;\n if (current.phase === 'launched' && current.runId != null) {\n const tracked = this.automationRunRegistry.get(current.runId);\n if (tracked && isActiveAutomationTaskStatus(tracked.status)) {\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...current,\n phase: 'streaming',\n }),\n );\n return;\n }\n }\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...current,\n phase: 'idle',\n runId: current.runId,\n // Never carry a stale soft-lock from a prior streaming/completed frame.\n loading: false,\n disabled: false,\n // Keep failed message after soft unlock; clear ephemeral launched/completed state.\n error: current.phase === 'failed' ? current.error : null,\n message: current.phase === 'failed' ? current.message : null,\n progressLabel: null,\n // Keep storyline so「查看过程」remains usable after the button unlocks.\n narrativeItems: current.narrativeItems ?? [],\n }),\n );\n if ((current.narrativeItems?.length ?? 0) > 0) {\n this.schedulePageActionNarrativeClear(key, 12_000);\n }\n }, delayMs);\n this.pageActionRowIdleTimers.set(key, timer);\n }\n\n private pageActionNarrativeClearTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n /** Drop retained storyline after the button has been idle for a while. */\n private schedulePageActionNarrativeClear(rowKey: string, delayMs: number): void {\n const key = rowKey.trim();\n if (!key) return;\n const existing = this.pageActionNarrativeClearTimers.get(key);\n if (existing != null) clearTimeout(existing);\n const timer = setTimeout(() => {\n this.pageActionNarrativeClearTimers.delete(key);\n const current = this.pageActionRows.get(key);\n if (!current) return;\n if (current.phase !== 'idle') return;\n if ((current.narrativeItems?.length ?? 0) === 0) return;\n this.upsertPageActionRow(\n buildPageActionRowState({\n ...current,\n narrativeItems: [],\n }),\n );\n }, delayMs);\n this.pageActionNarrativeClearTimers.set(key, timer);\n }\n\n private clearPageActionNarrativeClearTimer(rowKey: string): void {\n const key = rowKey.trim();\n if (!key) return;\n const existing = this.pageActionNarrativeClearTimers.get(key);\n if (existing == null) return;\n clearTimeout(existing);\n this.pageActionNarrativeClearTimers.delete(key);\n }\n\n private clearPageActionRowIdleTimers(): void {\n for (const timer of this.pageActionRowIdleTimers.values()) clearTimeout(timer);\n this.pageActionRowIdleTimers.clear();\n for (const timer of this.pageActionNarrativeClearTimers.values()) clearTimeout(timer);\n this.pageActionNarrativeClearTimers.clear();\n this.pageActionReuseDismissEpochByRowKey.clear();\n }\n\n private trackAutomationRun(\n accepted: InvokePageActionAccepted,\n meta: { actionKey: string; pageActionKey: string | null; rowKey?: string | null },\n ): void {\n const state = this.state;\n if (!state) return;\n const now = new Date().toISOString();\n const catalogName = this.pageActionFeedbackNames.get(meta.actionKey.trim());\n const locale = state.options.locale;\n const subtitle =\n accepted.status === 'awaiting_approval'\n ? pageActionTaskAwaitingApprovalSubtitle(locale)\n : pageActionTaskRunningSubtitle(locale);\n const item = buildOptimisticAutomationTaskItem(accepted, meta.actionKey, {\n title: formatPageActionDisplayTitle(meta.actionKey, catalogName),\n subtitle,\n });\n const rowKey = meta.rowKey?.trim() || null;\n\n if (isActiveAutomationTaskStatus(accepted.status)) {\n this.automationRunRegistry.set(accepted.runId, {\n runId: accepted.runId,\n actionKey: meta.actionKey,\n pageActionKey: meta.pageActionKey,\n rowKey,\n status: accepted.status,\n registeredAt: now,\n updatedAt: now,\n clientActionId: accepted.clientActionId,\n });\n if (rowKey) this.bindPageActionRunToRow(accepted.runId, rowKey);\n }\n\n if (taskMatchesStatusFilter(item.taskStatus, state.automationTaskStatusFilter)) {\n const nextItems = upsertAutomationTaskListItem(state.automationTaskItems, item);\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n nextItems,\n state.automationTaskHasMore,\n );\n }\n\n state.automationRecentRunIds = [\n accepted.runId,\n ...state.automationRecentRunIds.filter((row) => row !== accepted.runId),\n ].slice(0, MAX_RECENT_AUTOMATION_RUN_IDS);\n this.syncAutomationActiveCount(state);\n this.notifyStateChange();\n this.bus.emit('automationTaskCenterChanged', undefined);\n }\n\n private applyPageActionRunLifecycle(\n state: InternalState,\n lifecycle: PageActionSseLifecycle,\n ): void {\n const taskStatus = lifecyclePhaseToTaskStatus(lifecycle.phase);\n if (!taskStatus) return;\n\n const runId = lifecycle.actionRunId;\n const now = new Date().toISOString();\n const tracked = this.automationRunRegistry.get(runId);\n\n // Skip redundant processing for high-frequency `stream` frames when run is already tracked as running.\n if (lifecycle.phase === 'stream' && tracked?.status === 'running') {\n this.syncPageActionRowFromLifecycle(lifecycle);\n return;\n }\n\n if (tracked) {\n tracked.status = taskStatus;\n tracked.updatedAt = now;\n if (lifecycle.actionKey) tracked.actionKey = lifecycle.actionKey;\n if (!isActiveAutomationTaskStatus(taskStatus)) {\n this.automationRunRegistry.delete(runId);\n }\n } else if (isActiveAutomationTaskStatus(taskStatus)) {\n this.automationRunRegistry.set(runId, {\n runId,\n actionKey: lifecycle.actionKey,\n pageActionKey: null,\n rowKey: this.pageActionRunToRowKey.get(runId) ?? null,\n status: taskStatus,\n registeredAt: now,\n updatedAt: now,\n clientActionId: lifecycle.clientActionId ?? null,\n });\n }\n\n this.syncPageActionRowFromLifecycle(lifecycle);\n\n const lifecycleRowKey =\n this.pageActionRunToRowKey.get(runId) ??\n this.automationRunRegistry.get(runId)?.rowKey?.trim() ??\n null;\n if (lifecycle.phase === 'completed') {\n const pageActionKey =\n tracked?.pageActionKey ??\n (lifecycleRowKey\n ? this.pageActionRows.get(lifecycleRowKey)?.pageActionKey\n : null) ??\n null;\n this.pageActionReuseHintCache.invalidateByPageActionKey(pageActionKey);\n this.bus.emit('pageActionRunCompleted', {\n runId,\n actionKey: lifecycle.actionKey,\n rowKey: lifecycleRowKey,\n });\n } else if (lifecycle.phase === 'failed') {\n if (\n isBrainAskUserErrorCode(lifecycle.errorCode) &&\n lifecycle.brainClarify\n ) {\n this.emitPageActionBrainClarify(state, lifecycle, lifecycleRowKey);\n } else {\n this.bus.emit('pageActionRunFailed', {\n runId,\n actionKey: lifecycle.actionKey,\n rowKey: lifecycleRowKey,\n errorMessage: lifecycle.errorMessage ?? null,\n errorCode: lifecycle.errorCode ?? null,\n });\n }\n }\n\n const preview =\n lifecycle.phase === 'completed' && typeof lifecycle.text === 'string'\n ? lifecycle.text.trim().slice(0, 120) || null\n : undefined;\n const patch = {\n taskStatus,\n ...(isActiveAutomationTaskStatus(taskStatus)\n ? { finishedAt: null }\n : { finishedAt: now }),\n ...(preview\n ? {\n outputs: {\n preview,\n hasFillText: preview.length > 0,\n },\n }\n : {}),\n };\n\n if (\n state.automationTaskStatusFilter === 'active' &&\n !isActiveAutomationTaskStatus(taskStatus)\n ) {\n const nextItems = removeAutomationTaskListItem(state.automationTaskItems, runId);\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n nextItems,\n state.automationTaskHasMore,\n );\n } else if (taskMatchesStatusFilter(taskStatus, state.automationTaskStatusFilter)) {\n const existingIndex = state.automationTaskItems.findIndex(\n (item) => item.ref.kind === 'page_action_run' && item.ref.id === runId,\n );\n if (existingIndex >= 0) {\n const nextItems = patchAutomationTaskListItem(state.automationTaskItems, runId, patch);\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n nextItems,\n state.automationTaskHasMore,\n );\n } else {\n const nextItems = upsertAutomationTaskListItem(state.automationTaskItems, {\n ...buildOptimisticAutomationTaskItem(\n {\n runId,\n generation: lifecycle.generation,\n clientActionId: lifecycle.clientActionId ?? null,\n pageActionKey: tracked?.pageActionKey ?? null,\n streamUrl: '',\n status: taskStatus,\n },\n lifecycle.actionKey,\n {\n title: formatPageActionDisplayTitle(\n lifecycle.actionKey,\n this.pageActionFeedbackNames.get(lifecycle.actionKey.trim()),\n ),\n },\n ),\n ...patch,\n });\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n nextItems,\n state.automationTaskHasMore,\n );\n }\n }\n\n if (\n state.automationTaskSelectedDetail?.ref.kind === 'page_action_run' &&\n state.automationTaskSelectedDetail.ref.id === runId\n ) {\n state.automationTaskSelectedDetail = {\n ...state.automationTaskSelectedDetail,\n ...patch,\n outputs: patch.outputs\n ? { ...state.automationTaskSelectedDetail.outputs, ...patch.outputs }\n : state.automationTaskSelectedDetail.outputs,\n };\n }\n\n this.syncAutomationActiveCount(state);\n this.notifyStateChange();\n\n if (\n !isActiveAutomationTaskStatus(taskStatus) &&\n state.automationTaskSelectedDetail?.ref.kind === 'page_action_run' &&\n state.automationTaskSelectedDetail.ref.id === runId\n ) {\n void this.hydrateAutomationTaskDetail(runId).catch(() => {\n /* detail refresh is best-effort */\n });\n }\n }\n\n private markTrackedAutomationRunFailed(runId: number, actionKey?: string): void {\n const state = this.state;\n if (!state) return;\n this.applyPageActionRunLifecycle(state, {\n phase: 'failed',\n actionRunId: runId,\n actionKey: actionKey?.trim() || this.automationRunRegistry.get(runId)?.actionKey || `Run ${runId}`,\n generation: 0,\n clientActionId: this.automationRunRegistry.get(runId)?.clientActionId ?? null,\n });\n }\n\n private resolveApprovalPageActionRunId(approvalId: number): number | null {\n const state = this.state;\n if (!state) return null;\n const item = state.approvalInboxItems.find((row) => row.id === approvalId);\n if (item?.pageActionRunId != null && Number.isFinite(item.pageActionRunId)) {\n return Math.trunc(item.pageActionRunId);\n }\n for (const row of this.pageActionRows.values()) {\n if (row.approvalRequestId === approvalId && row.runId != null) {\n return row.runId;\n }\n }\n return null;\n }\n\n private taskStatusToExecutionOutcome(\n status: AutomationTaskStatus,\n ): ApprovalExecutionOutcome {\n switch (status) {\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'running':\n return 'running';\n case 'awaiting_approval':\n return 'awaiting_approval';\n case 'cancelled':\n return 'cancelled';\n default:\n return 'completed';\n }\n }\n\n private resolveApprovalIdentity(approvalId: number): {\n approvalTitle: string | null;\n approvalSummary: string | null;\n } {\n const item = this.state?.approvalInboxItems.find((row) => row.id === approvalId);\n return {\n approvalTitle: item?.title?.trim() || null,\n approvalSummary: item?.summary?.trim() || null,\n };\n }\n\n private async emitApprovalExecutionCompleted(input: {\n approvalId: number;\n runId: number | null;\n decision: DraftReviewDecision;\n result: ApprovalDecideResult | ApprovalConfirmResult;\n identity?: { approvalTitle: string | null; approvalSummary: string | null };\n }): Promise<void> {\n const { approvalId, runId, decision, result } = input;\n const identity = input.identity ?? this.resolveApprovalIdentity(approvalId);\n\n if (decision.action === 'cancel') {\n this.bus.emit('approvalExecutionCompleted', {\n approvalId,\n runId,\n outcome: 'cancelled',\n title: identity.approvalTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n });\n return;\n }\n\n if (decision.action === 'retry') {\n if (!result.resumed) return;\n if (result.suspended) {\n this.bus.emit('approvalExecutionCompleted', {\n approvalId,\n runId,\n outcome: 'awaiting_approval',\n title: identity.approvalTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n });\n } else {\n await this.emitApprovalRunExecutionOutcome(approvalId, runId, identity);\n }\n return;\n }\n\n if (\n (decision.action === 'confirm' || decision.action === 'confirm_with_edits') &&\n result.resumed\n ) {\n await this.emitApprovalRunExecutionOutcome(approvalId, runId, identity);\n }\n }\n\n private async emitApprovalRunExecutionOutcome(\n approvalId: number,\n runId: number | null,\n identity: { approvalTitle: string | null; approvalSummary: string | null } = {\n approvalTitle: null,\n approvalSummary: null,\n },\n ): Promise<void> {\n const state = this.state;\n if (!runId) {\n this.bus.emit('approvalExecutionCompleted', {\n approvalId,\n runId: null,\n outcome: 'completed',\n title: identity.approvalTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n });\n return;\n }\n\n const detail = await this.getAutomationTaskDetail(runId).catch(() => null);\n if (detail && state) {\n const index = state.automationTaskItems.findIndex(\n (item) => item.ref.kind === 'page_action_run' && item.ref.id === runId,\n );\n if (index >= 0) {\n const next = [...state.automationTaskItems];\n next[index] = detail;\n this.publishAutomationTaskTabCache(\n state,\n state.automationTaskStatusFilter,\n next,\n state.automationTaskHasMore,\n );\n }\n if (!isActiveAutomationTaskStatus(detail.taskStatus)) {\n this.automationRunRegistry.delete(runId);\n }\n this.syncAutomationActiveCount(state);\n this.notifyStateChange();\n await this.hydratePageActionByRunId(runId).catch(() => {\n /* row slot refresh is best-effort */\n });\n }\n\n const taskTitle = detail?.title?.trim() || null;\n const displayTitle = identity.approvalTitle || taskTitle;\n const preview =\n detail?.outputs.preview?.trim() ||\n identity.approvalSummary ||\n null;\n\n const payload: ApprovalExecutionCompletedPayload = {\n approvalId,\n runId,\n outcome: detail\n ? this.taskStatusToExecutionOutcome(detail.taskStatus)\n : 'completed',\n title: displayTitle,\n approvalTitle: identity.approvalTitle,\n approvalSummary: identity.approvalSummary,\n preview,\n ...(detail ? { taskStatus: detail.taskStatus } : {}),\n };\n this.bus.emit('approvalExecutionCompleted', payload);\n }\n\n private abortAllPageActionRunStreams(): void {\n for (const ctrl of this.pageActionRunAborts.values()) {\n try {\n ctrl.abort();\n } catch {\n /* noop */\n }\n }\n this.pageActionRunAborts.clear();\n this.pageActionRunStreamPromises.clear();\n }\n\n private async fetchAutomationTasks(\n opts: {\n signal?: AbortSignal;\n status?: AutomationTaskStatusFilter;\n actionKey?: string;\n limit?: number;\n offset?: number;\n append?: boolean;\n } = {},\n ): Promise<AutomationTaskList> {\n await this.ensureLoggedIn('refreshAutomationTasks');\n const state = this.requireState('refreshAutomationTasks');\n const status = opts.status ?? state.automationTaskStatusFilter;\n const limit = opts.limit ?? AUTOMATION_TASK_PAGE_SIZE;\n const tabCache = getAutomationTaskTabCache(state.automationTaskTabCaches, status);\n const offset = opts.offset ?? (opts.append ? tabCache.items.length : 0);\n const append = opts.append === true;\n if (append && state.automationTaskLoading) {\n return {\n items: tabCache.items,\n total: tabCache.total,\n hasMore: tabCache.hasMore,\n };\n }\n const publishSeq = append ? this.automationTaskListPublishSeq : ++this.automationTaskListPublishSeq;\n if (append) {\n state.automationTaskLoadingMore = true;\n } else {\n state.automationTaskLoading = true;\n }\n this.notifyStateChange();\n try {\n const list = await state.automation.listTasks({\n status,\n triggerSource: 'page_action',\n actionKey: opts.actionKey,\n limit,\n offset,\n signal: opts.signal,\n });\n if (publishSeq !== this.automationTaskListPublishSeq) {\n return list;\n }\n state.automationTaskStatusFilter = status;\n const nextItems = append\n ? [...tabCache.items, ...list.items]\n : status === 'active' && offset === 0\n ? mergeOptimisticRunsIntoList(list.items, this.automationRunRegistry)\n : list.items;\n const hasMore = resolveAutomationTaskListHasMore(\n nextItems.length,\n list.items.length,\n list.total,\n limit,\n );\n this.publishAutomationTaskTabCache(state, status, nextItems, hasMore, list.total);\n if (status === 'active' && offset === 0 && !append) {\n mergeRegistryFromActiveListItems(this.automationRunRegistry, list.items, {\n fallbackActionKey: opts.actionKey,\n });\n this.automationTasksLastSyncedAt = Date.now();\n }\n this.syncAutomationActiveCount(state);\n return list;\n } finally {\n if (append) {\n state.automationTaskLoadingMore = false;\n } else {\n state.automationTaskLoading = false;\n }\n this.notifyStateChange();\n }\n }\n\n private getMessageSendContext(\n state: InternalState,\n pageContextOverride?: AgentChatPageContext | null,\n entityCommit?: EntityCommit | null,\n ): MessageSendContext | undefined {\n const ctx: MessageSendContext = {};\n const agentId = state.selectedAgentId?.trim();\n const skillId = state.selectedSkillId?.trim();\n const agentWasAutoBound =\n agentId &&\n state.autoAgent?.id === agentId &&\n state.autoAgent.source !== 'requested';\n if (agentId && !agentWasAutoBound) ctx.agentId = agentId;\n if (skillId) ctx.skillId = skillId;\n\n const page = pageContextOverride ?? this.buildOutboundPageContext(state);\n if (page?.page) ctx.page = page.page;\n if (page?.routePath) ctx.routePath = page.routePath;\n if (page?.routeParams) ctx.routeParams = page.routeParams;\n if (page?.flowId != null) ctx.flowId = page.flowId;\n if (page?.programName) ctx.programName = page.programName;\n if (page?.entity) ctx.entity = page.entity;\n if (page?.metadata) ctx.metadata = page.metadata;\n if (entityCommit?.entityType?.trim() && entityCommit?.selectedId?.trim()) {\n ctx.entityCommit = {\n entityType: entityCommit.entityType.trim(),\n selectedId: entityCommit.selectedId.trim(),\n };\n }\n\n return Object.keys(ctx).length > 0 ? ctx : undefined;\n }\n\n private buildOutboundPageContext(state: InternalState): AgentChatPageContext | null {\n return this.buildPreparePageContext(state);\n }\n\n private listRegisteredContextMentions(\n state: InternalState,\n ): RegisteredContextMention[] {\n return [...state.contextMentionRegistry.values()].map(toRegisteredContextMention);\n }\n\n private listPendingRegisteredContextMentions(): RegisteredContextMention[] {\n return [...this.pendingContextMentionRegistry.values()].map(toRegisteredContextMention);\n }\n\n private async fetchSessionMessagesPage(\n state: InternalState,\n sessionId: string,\n page: number,\n signal?: AbortSignal,\n ) {\n const body = await state.chat.getSession(\n sessionId,\n page,\n state.sessionMessagesPageSize,\n signal,\n );\n const detailPage = parseChatSessionDetailPage(\n body,\n sessionId,\n page,\n state.sessionMessagesPageSize,\n );\n if (!detailPage) {\n throw new AgentChatError('TRANSPORT_FAILED', 'Invalid session detail response', {\n details: { sessionId, page },\n });\n }\n return detailPage;\n }\n\n /** Clear the active session so the next send creates a new chat. */\n async startNewChat(): Promise<void> {\n await this.ensureLoggedIn('startNewChat');\n const state = this.requireState('startNewChat');\n this.sessionEpoch += 1;\n if (state.activeSessionId) {\n this.abortSessionStream(state, state.activeSessionId);\n this.writeSessionMessagesCache(state, state.activeSessionId);\n }\n state.activeSessionId = null;\n state.activeSessionMessagesPage = 0;\n state.activeSessionMessagesHasMore = false;\n state.session.reset();\n state.messages = [];\n state.writeConfirmation = null;\n state.autoAgent = null;\n state.selectedAgentId = state.options.defaultAgentId?.trim() ?? null;\n state.selectedSkillId = null;\n if (state.options.skills?.length) {\n this.applyStaticSkills(state);\n } else {\n state.skills = [];\n state.skillsLoading = false;\n }\n this.notifyStateChange();\n }\n\n /** Stop the active agent run via `POST .../cancel-run` (does not close the session SSE). */\n async cancelGeneration(): Promise<void> {\n const state = this.state;\n if (!state?.activeSessionId) return;\n await this.ensureLoggedIn('cancelGeneration');\n const sessionId = state.activeSessionId;\n const runId = this.resolveActiveRunIdForCancel(state, sessionId);\n\n try {\n const result = await state.chat.cancelRun(sessionId, runId);\n if (!result.superseded) return;\n this.applySessionRunGeneration(state, sessionId, result.generation);\n this.finalizeStreamingTarget(state, sessionId, {\n cancelled: true,\n systemHint: '已停止生成。',\n });\n } catch (err) {\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to cancel generation', { cause: err });\n this.reportError(wrapped);\n throw wrapped;\n }\n }\n\n private isViewingSession(state: InternalState, sessionId: string): boolean {\n return (\n state.activeSessionId != null &&\n normalizeSessionId(state.activeSessionId) === normalizeSessionId(sessionId)\n );\n }\n\n private getSessionRunState(state: InternalState, sessionId: string): SessionRunState {\n const key = normalizeSessionId(sessionId);\n let runState = state.sessionRuns.get(key);\n if (!runState) {\n runState = { sessionGeneration: 0, activeRunId: null, activeTurnId: null, pendingJobCount: 0, redisBacked: false };\n state.sessionRuns.set(key, runState);\n }\n return runState;\n }\n\n private applySessionRunGeneration(\n state: InternalState,\n sessionId: string,\n generation: number,\n opts: { clearActiveRun?: boolean } = {},\n ): void {\n const runState = this.getSessionRunState(state, sessionId);\n const prevGeneration = runState.sessionGeneration;\n runState.sessionGeneration = generation;\n if (generation > prevGeneration) {\n this.discardStaleWriteConfirmations(state, sessionId, generation, prevGeneration);\n }\n if (opts.clearActiveRun !== false) {\n runState.activeRunId = null;\n runState.activeTurnId = null;\n }\n }\n\n private applySessionRunSnapshot(\n state: InternalState,\n sessionId: string,\n snapshot: SessionRunStateSnapshot,\n ): void {\n const runState = this.getSessionRunState(state, sessionId);\n const prevGeneration = runState.sessionGeneration;\n runState.sessionGeneration = snapshot.generation;\n if (snapshot.generation > prevGeneration) {\n this.discardStaleWriteConfirmations(\n state,\n sessionId,\n snapshot.generation,\n prevGeneration,\n );\n }\n runState.activeRunId = snapshot.activeRunId;\n runState.activeTurnId = snapshot.activeTurnId;\n runState.pendingJobCount = snapshot.pendingJobCount;\n runState.redisBacked = snapshot.redisBacked;\n this.syncWriteGateFromRunState(\n state,\n sessionId,\n snapshot.generation,\n snapshot.pendingWriteGate,\n );\n }\n\n /** Restore Chat write gate from `GET run-state` `pendingWriteGate` (page refresh). */\n private syncWriteGateFromRunState(\n state: InternalState,\n sessionId: string,\n generation: number,\n pendingWriteGate: SessionRunStateSnapshot['pendingWriteGate'],\n ): void {\n const key = normalizeSessionId(sessionId);\n const current = state.writeConfirmationsBySession.get(key);\n if (current?.submitting) return;\n\n if (!pendingWriteGate) {\n if (current?.awaiting) {\n this.persistWriteConfirmation(state, sessionId, null);\n }\n return;\n }\n\n const message =\n pendingWriteGate.writeDraft?.presentation.summaryText?.trim() ||\n '即将执行写操作,请确认。';\n\n this.persistWriteConfirmation(state, sessionId, {\n awaiting: true,\n submitting: false,\n runId: pendingWriteGate.runId,\n turnId: pendingWriteGate.turnId,\n message,\n generation,\n draftRetryCount: pendingWriteGate.draftRetryCount,\n draftRetryMax: pendingWriteGate.draftRetryMax,\n canRetry: pendingWriteGate.canRetry,\n writeDraft: pendingWriteGate.writeDraft,\n writeDrafts: pendingWriteGate.writeDrafts,\n editPolicy: pendingWriteGate.editPolicy,\n editPolicies: pendingWriteGate.editPolicies,\n });\n }\n\n /** Align local `sessionGeneration` with Redis before opening or after switching sessions. */\n private async syncSessionRunState(\n state: InternalState,\n sessionId: string,\n signal?: AbortSignal,\n ): Promise<void> {\n try {\n const body = await state.chat.getRunState(sessionId, signal);\n const snapshot = parseSessionRunState(body);\n if (!snapshot) return;\n this.applySessionRunSnapshot(state, sessionId, snapshot);\n this.notifyStateChange();\n } catch (err) {\n if (signal?.aborted) return;\n if (state.options.debug) {\n console.warn('[agent-chat] syncSessionRunState failed:', err);\n }\n }\n }\n\n private getActiveSessionRunSnapshot(state: InternalState): SessionRunSnapshot | null {\n const sessionId = state.activeSessionId;\n if (!sessionId) return null;\n const runState = state.sessionRuns.get(normalizeSessionId(sessionId));\n if (!runState) return null;\n return {\n generation: runState.sessionGeneration,\n activeRunId: runState.activeRunId,\n pendingJobCount: runState.pendingJobCount,\n redisBacked: runState.redisBacked,\n };\n }\n\n private noteActiveRunId(state: InternalState, sessionId: string, runId: number): void {\n this.getSessionRunState(state, sessionId).activeRunId = runId;\n }\n\n private isStaleSseGeneration(\n state: InternalState,\n sessionId: string,\n generation?: number,\n ): boolean {\n const runState = this.getSessionRunState(state, sessionId);\n return isStaleAgentRunEvent(runState.sessionGeneration, generation);\n }\n\n private resolveActiveRunIdForCancel(\n state: InternalState,\n sessionId: string,\n ): number | undefined {\n const runState = this.getSessionRunState(state, sessionId);\n if (runState.activeRunId != null) return runState.activeRunId;\n\n const key = normalizeSessionId(sessionId);\n const pending = state.writeConfirmationsBySession.get(key);\n if (pending?.runId != null) return pending.runId;\n\n const messages = this.getSessionMessagesList(state, sessionId);\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (message?.role === 'agent' && message.status === 'pending') {\n const runId = message.stream?.runId;\n if (runId != null) return runId;\n }\n }\n return undefined;\n }\n\n private shouldFilterAgentRunSse(action: ChatSseUiAction): boolean {\n switch (action.type) {\n case 'think':\n case 'result':\n case 'message-blocks':\n case 'complete':\n case 'error':\n case 'host-action':\n case 'write-confirmation-required':\n case 'write-confirmation-cancelled':\n return true;\n default:\n return false;\n }\n }\n\n private applySseRunGate(\n state: InternalState,\n sessionId: string,\n action: ChatSseUiAction,\n ): 'skip' | 'proceed' {\n if (!this.shouldFilterAgentRunSse(action)) return 'proceed';\n\n const generation = 'generation' in action ? action.generation : undefined;\n const runId = 'runId' in action ? action.runId : undefined;\n\n if (action.type === 'error' && action.code === 'RUN_CANCELLED') {\n if (!this.isStaleSseGeneration(state, sessionId, generation)) {\n const targetId = this.resolveStreamTargetMessageId(state, sessionId);\n this.finalizeStreamingTarget(state, sessionId, {\n cancelled: true,\n systemHint: targetId ? action.message : undefined,\n });\n this.hostToolStreamManagers.get(normalizeSessionId(sessionId))?.reset();\n }\n return 'skip';\n }\n\n if (this.isStaleSseGeneration(state, sessionId, generation)) {\n return 'skip';\n }\n\n if (runId != null) {\n this.noteActiveRunId(state, sessionId, runId);\n }\n return 'proceed';\n }\n\n private finalizeStreamingTarget(\n state: InternalState,\n sessionId: string,\n opts: { cancelled?: boolean; systemHint?: string } = {},\n ): void {\n const targetId = this.resolveStreamTargetMessageId(state, sessionId);\n if (!targetId) {\n if (opts.systemHint) {\n this.appendSystemMessageInSession(state, sessionId, opts.systemHint);\n }\n this.getSessionRunState(state, sessionId).activeRunId = null;\n return;\n }\n\n const snapshot = this.getSessionMessagesList(state, sessionId).find((m) => m.id === targetId);\n if (!snapshot || snapshot.role !== 'agent') return;\n\n const stream = snapshot.stream;\n const text = (stream?.resultText || snapshot.content.text || '').trim();\n if (!text) {\n this.removeAgentMessageInSession(state, sessionId, targetId);\n } else {\n this.replaceMessageInSession(\n state,\n sessionId,\n finalizeAgentReply(\n snapshot,\n { ...(stream ?? createEmptyAgentStream()), phase: 'complete' },\n { status: 'sent' },\n ),\n targetId,\n );\n }\n\n this.setStreamTargetMessageId(state, sessionId, null);\n this.getSessionRunState(state, sessionId).activeRunId = null;\n\n if (opts.systemHint) {\n this.appendSystemMessageInSession(state, sessionId, opts.systemHint);\n }\n this.notifyStateChange();\n }\n\n private getStreamHandle(\n state: InternalState,\n sessionId: string,\n ): SessionStreamHandle | undefined {\n return state.sessionStreams.get(normalizeSessionId(sessionId));\n }\n\n private setStreamTargetMessageId(\n state: InternalState,\n sessionId: string,\n messageId: string | null,\n ): void {\n const key = normalizeSessionId(sessionId);\n const handle = state.sessionStreams.get(key);\n if (handle) {\n handle.targetMessageId = messageId;\n return;\n }\n if (messageId) {\n this.pendingStreamTargets.set(key, messageId);\n } else {\n this.pendingStreamTargets.delete(key);\n }\n }\n\n private abortSessionStream(\n state: InternalState,\n sessionId: string,\n opts: { suppressReconnect?: boolean } = {},\n ): void {\n const key = normalizeSessionId(sessionId);\n if (opts.suppressReconnect !== false) {\n this.sessionStreamSuppressReconnect.add(key);\n this.cancelSessionStreamReconnect(key);\n }\n const handle = state.sessionStreams.get(key);\n if (!handle) return;\n try {\n handle.abort.abort();\n } catch {\n /* noop */\n }\n state.sessionStreams.delete(key);\n }\n\n private abortAllSessionStreams(state: InternalState): void {\n for (const key of [...state.sessionStreams.keys()]) {\n this.abortSessionStream(state, key, { suppressReconnect: true });\n }\n }\n\n private listStreamingSessionIds(state: InternalState): string[] {\n return [...state.sessionStreams.keys()];\n }\n\n private collectSessionsWithPendingReplies(state: InternalState): string[] {\n const ids = new Set<string>();\n if (state.activeSessionId && this.sessionHasPendingAgent(state.messages)) {\n ids.add(normalizeSessionId(state.activeSessionId));\n }\n for (const [sessionId, entry] of state.sessionMessagesCache) {\n if (this.sessionHasPendingAgent(entry.messages)) {\n ids.add(normalizeSessionId(sessionId));\n }\n }\n return [...ids];\n }\n\n private sessionHasPendingAgent(messages: AgentMessage[]): boolean {\n return messages.some(\n (m) => m.role === 'agent' && m.status === 'pending' && m.stream != null,\n );\n }\n\n /** Whether a session should keep (or restore) its SSE listener. */\n private sessionNeedsLiveStream(state: InternalState, sessionId: string): boolean {\n const key = normalizeSessionId(sessionId);\n if (this.sessionStreamSuppressReconnect.has(key)) return false;\n if (this.isViewingSession(state, sessionId)) return true;\n return this.sessionHasPendingAgent(this.getSessionMessagesList(state, sessionId));\n }\n\n /**\n * After switching sessions, finalize stale pending bubbles when the server\n * reports no active run (stream may have ended while the user was away).\n */\n private reconcilePendingRepliesAfterSessionSwitch(\n state: InternalState,\n sessionId: string,\n normalizedSessionId: string,\n ): void {\n if (!this.sessionHasPendingAgent(state.messages)) return;\n const runState = state.sessionRuns.get(normalizedSessionId);\n if (runState?.activeRunId != null) return;\n this.settlePendingAgentReplies(state, sessionId);\n }\n\n private cancelSessionStreamReconnect(sessionId: string): void {\n const key = normalizeSessionId(sessionId);\n const timer = this.sessionStreamReconnectTimers.get(key);\n if (timer == null) return;\n clearTimeout(timer);\n this.sessionStreamReconnectTimers.delete(key);\n }\n\n private cancelAllSessionStreamReconnects(): void {\n for (const timer of this.sessionStreamReconnectTimers.values()) {\n clearTimeout(timer);\n }\n this.sessionStreamReconnectTimers.clear();\n this.sessionStreamReconnectAttempts.clear();\n this.sessionStreamSuppressReconnect.clear();\n }\n\n private scheduleSessionStreamReconnect(state: InternalState, sessionId: string): void {\n const key = normalizeSessionId(sessionId);\n if (!this.sessionNeedsLiveStream(state, sessionId)) {\n this.sessionStreamReconnectAttempts.delete(key);\n return;\n }\n if (state.sessionStreams.has(key) || this.sessionStreamConnects.has(key)) return;\n if (this.sessionStreamReconnectTimers.has(key)) return;\n\n const attempt = (this.sessionStreamReconnectAttempts.get(key) ?? 0) + 1;\n if (attempt > 5) {\n this.sessionStreamReconnectAttempts.delete(key);\n if (state.options.debug && typeof console !== 'undefined') {\n console.warn(`[agent-chat] Session stream reconnect gave up for ${sessionId}`);\n }\n return;\n }\n this.sessionStreamReconnectAttempts.set(key, attempt);\n const delayMs = Math.min(500 * 2 ** (attempt - 1), 8_000);\n\n const timer = setTimeout(() => {\n this.sessionStreamReconnectTimers.delete(key);\n if (!this.state || this.state !== state) return;\n if (!this.sessionNeedsLiveStream(state, sessionId)) {\n this.sessionStreamReconnectAttempts.delete(key);\n return;\n }\n void this.ensureSessionStream(sessionId, { clearReconnectSuppress: false }).catch(() => {\n /* reported or suppressed in consumeSessionStream */\n });\n }, delayMs);\n this.sessionStreamReconnectTimers.set(key, timer);\n }\n\n private getSessionMessagesList(state: InternalState, sessionId: string): AgentMessage[] {\n if (this.isViewingSession(state, sessionId)) {\n return state.messages;\n }\n const key = normalizeSessionId(sessionId);\n return (\n state.sessionMessagesCache.get(key)?.messages ??\n state.sessionMessagesCache.get(sessionId)?.messages ??\n []\n );\n }\n\n private getSessionCacheMeta(\n state: InternalState,\n sessionId: string,\n ): { page: number; hasMore: boolean } {\n if (this.isViewingSession(state, sessionId)) {\n return {\n page: state.activeSessionMessagesPage,\n hasMore: state.activeSessionMessagesHasMore,\n };\n }\n const key = normalizeSessionId(sessionId);\n const cached =\n state.sessionMessagesCache.get(key) ?? state.sessionMessagesCache.get(sessionId);\n return { page: cached?.page ?? 1, hasMore: cached?.hasMore ?? false };\n }\n\n private commitSessionMessages(\n state: InternalState,\n sessionId: string,\n messages: AgentMessage[],\n meta?: { page?: number; hasMore?: boolean },\n ): void {\n const key = normalizeSessionId(sessionId);\n const fallback = this.getSessionCacheMeta(state, sessionId);\n const page = meta?.page ?? fallback.page;\n const hasMore = meta?.hasMore ?? fallback.hasMore;\n state.sessionMessagesCache.set(key, { messages, page, hasMore });\n if (this.isViewingSession(state, sessionId)) {\n state.messages = messages;\n state.activeSessionMessagesPage = page;\n state.activeSessionMessagesHasMore = hasMore;\n state.session.setSession(sessionId, messages);\n }\n this.notifyStateChange();\n }\n\n private patchMessageInSession(\n state: InternalState,\n sessionId: string,\n messageId: string,\n patch: (current: AgentMessage) => AgentMessage,\n ): AgentMessage | null {\n const messages = this.getSessionMessagesList(state, sessionId);\n const current = messages.find((m) => m.id === messageId);\n if (!current) return null;\n const next = patch(current);\n const updated = messages.map((m) => (m.id === messageId ? next : m));\n this.commitSessionMessages(state, sessionId, updated);\n this.bus.emit('message', { message: next, source: next.role === 'user' ? 'user' : 'agent' });\n return next;\n }\n\n private replaceMessageInSession(\n state: InternalState,\n sessionId: string,\n next: AgentMessage,\n previousId: string,\n ): void {\n const messages = this.getSessionMessagesList(state, sessionId);\n const updated = messages.map((m) => (m.id === previousId ? next : m));\n this.syncWriteConfirmationMessageId(state, previousId, next.id);\n this.commitSessionMessages(state, sessionId, updated);\n this.bus.emit('message', { message: next, source: 'agent' });\n }\n\n private removeAgentMessageInSession(\n state: InternalState,\n sessionId: string,\n messageId: string,\n ): void {\n const messages = this.getSessionMessagesList(state, sessionId);\n const updated = messages.filter((m) => m.id !== messageId);\n if (updated.length === messages.length) return;\n this.commitSessionMessages(state, sessionId, updated);\n }\n\n private appendAgentPlaceholderInSession(\n state: InternalState,\n sessionId: string,\n ): AgentMessage {\n const agentMessage: AgentMessage = {\n id: nanoId('msg'),\n role: 'agent',\n content: { type: 'text', text: '' },\n createdAt: Date.now(),\n status: 'pending',\n };\n const messages = [...this.getSessionMessagesList(state, sessionId), agentMessage];\n this.commitSessionMessages(state, sessionId, messages);\n this.bus.emit('message', { message: agentMessage, source: 'agent' });\n return agentMessage;\n }\n\n private appendSystemMessageInSession(\n state: InternalState,\n sessionId: string,\n text: string,\n ): void {\n const hint: AgentMessage = {\n id: nanoId('msg'),\n role: 'system',\n content: { type: 'text', text },\n createdAt: Date.now(),\n status: 'sent',\n };\n const messages = [...this.getSessionMessagesList(state, sessionId), hint];\n this.commitSessionMessages(state, sessionId, messages);\n this.bus.emit('message', { message: hint, source: 'agent' });\n }\n\n private async ensureSessionStream(\n sessionId: string,\n opts: { clearReconnectSuppress?: boolean } = {},\n ): Promise<void> {\n const state = this.requireState('ensureSessionStream');\n const normalizedId = normalizeSessionId(sessionId);\n if (opts.clearReconnectSuppress !== false) {\n this.sessionStreamSuppressReconnect.delete(normalizedId);\n this.cancelSessionStreamReconnect(normalizedId);\n }\n if (state.sessionStreams.has(normalizedId)) {\n return;\n }\n const inFlight = this.sessionStreamConnects.get(normalizedId);\n if (inFlight) {\n await inFlight;\n return;\n }\n const streamCtrl = new AbortController();\n const connectPromise = (async () => {\n await this.syncSessionRunState(state, sessionId, streamCtrl.signal);\n await this.connectSessionStream(sessionId, streamCtrl);\n })().finally(() => {\n this.sessionStreamConnects.delete(normalizedId);\n });\n this.sessionStreamConnects.set(normalizedId, connectPromise);\n await connectPromise;\n this.sessionStreamReconnectAttempts.delete(normalizedId);\n }\n\n private writeSessionMessagesCache(\n state: InternalState,\n sessionId: string,\n messages = state.messages,\n page = state.activeSessionMessagesPage,\n hasMore = state.activeSessionMessagesHasMore,\n ): void {\n state.sessionMessagesCache.set(normalizeSessionId(sessionId), { messages, page, hasMore });\n }\n\n private cacheActiveSessionMessages(state: InternalState): void {\n if (!state.activeSessionId) return;\n this.writeSessionMessagesCache(state, state.activeSessionId);\n }\n\n /** Finalize in-flight assistant turns; drop only empty placeholders. */\n private settlePendingAgentReplies(state: InternalState, sessionId?: string): void {\n const targetSessionId = sessionId ?? state.activeSessionId;\n if (!targetSessionId) return;\n\n const messages = this.getSessionMessagesList(state, targetSessionId);\n const next: AgentMessage[] = [];\n let changed = false;\n\n for (const message of messages) {\n if (message.role !== 'agent' || message.status !== 'pending') {\n next.push(message);\n continue;\n }\n changed = true;\n const stream = message.stream ?? createEmptyAgentStream();\n const text = (stream.resultText || message.content.text).trim();\n if (!text) continue;\n next.push(finalizeAgentReply(message, stream, { status: 'sent' }));\n }\n\n if (!changed) return;\n this.commitSessionMessages(state, targetSessionId, next);\n }\n\n private isExistingSentAssistantText(\n state: InternalState,\n sessionId: string,\n text: string,\n excludeId: string,\n ): boolean {\n const normalized = text.trim();\n if (!normalized) return false;\n return this.getSessionMessagesList(state, sessionId).some(\n (m) =>\n m.role === 'agent' &&\n m.id !== excludeId &&\n m.status === 'sent' &&\n m.content.text.trim() === normalized,\n );\n }\n\n private resolveStreamTargetMessageId(\n state: InternalState,\n sessionId: string,\n messageId?: string,\n ): string | null {\n if (messageId) return messageId;\n const key = normalizeSessionId(sessionId);\n const explicit =\n state.sessionStreams.get(key)?.targetMessageId ??\n this.pendingStreamTargets.get(key) ??\n null;\n const messages = this.getSessionMessagesList(state, sessionId);\n if (explicit && messages.some((m) => m.id === explicit)) return explicit;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (message?.role === 'agent' && (message.status ?? 'pending') === 'pending') {\n this.setStreamTargetMessageId(state, sessionId, message.id);\n return message.id;\n }\n }\n return null;\n }\n\n /** Empty assistant bubble for the in-flight turn (shown before SSE events arrive). */\n private appendAgentPlaceholder(state: InternalState): AgentMessage {\n const agentMessage: AgentMessage = {\n id: nanoId('msg'),\n role: 'agent',\n content: { type: 'text', text: '' },\n createdAt: Date.now(),\n status: 'pending',\n };\n state.messages = [...state.messages, agentMessage];\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n this.bus.emit('message', { message: agentMessage, source: 'agent' });\n return agentMessage;\n }\n\n private appendOptimisticUserMessage(\n state: InternalState,\n text: string,\n id?: string,\n contextMentions?: ContextMentionAttachment[],\n ): AgentMessage {\n const userMessage: AgentMessage = {\n id: id ?? nanoId('msg'),\n role: 'user',\n content: { type: 'text', text },\n createdAt: Date.now(),\n status: 'pending',\n contextMentions:\n contextMentions && contextMentions.length > 0 ? [...contextMentions] : undefined,\n };\n state.messages = [...state.messages, userMessage];\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n this.bus.emit('message', { message: userMessage, source: 'user' });\n return userMessage;\n }\n\n private async createChatSession(\n state: InternalState,\n content: string,\n signal: AbortSignal,\n pageContextOverride?: AgentChatPageContext | null,\n entityCommit?: EntityCommit | null,\n ): Promise<string> {\n const createBody = await state.chat.createSession(\n content,\n signal,\n this.getMessageSendContext(state, pageContextOverride, entityCommit),\n );\n const created = parseCreateSessionResponse(createBody);\n if (!created?.sessionId) {\n throw new AgentChatError('TRANSPORT_FAILED', 'POST /chat did not return sessionId', {\n details: { body: createBody },\n });\n }\n state.activeSessionId = created.sessionId;\n this.applyAutoAgentBinding(state, created.agent);\n const runGeneration = parseRunGeneration(createBody);\n if (runGeneration != null) {\n this.applySessionRunGeneration(state, created.sessionId, runGeneration);\n }\n state.activeSessionMessagesPage = 1;\n state.activeSessionMessagesHasMore = false;\n state.session.setSession(created.sessionId, state.messages);\n this.writeSessionMessagesCache(state, created.sessionId);\n this.bus.emit('session', state.session.getSession()!);\n this.schedulePrepareSession();\n return created.sessionId;\n }\n\n private applyUserMessageSent(state: InternalState, userMessage: AgentMessage): AgentMessage {\n const sentUser: AgentMessage = { ...userMessage, status: 'sent' };\n state.messages = state.messages.map((m) => (m.id === userMessage.id ? sentUser : m));\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n this.bus.emit('message', { message: sentUser, source: 'user' });\n return sentUser;\n }\n\n private async postUserMessageAndApply(\n state: InternalState,\n sessionId: string,\n content: string,\n signal: AbortSignal,\n userMessage: AgentMessage,\n pageContextOverride?: AgentChatPageContext | null,\n entityCommit?: EntityCommit | null,\n ): Promise<AgentMessage> {\n const postBody = await state.chat.postMessage(\n sessionId,\n content,\n signal,\n this.getMessageSendContext(state, pageContextOverride, entityCommit),\n );\n const posted = parsePostedMessage(postBody);\n const sentUser: AgentMessage = posted\n ? {\n ...this.toAgentMessage(posted as ServerMessage),\n status: 'sent',\n contextMentions: userMessage.contextMentions,\n }\n : { ...userMessage, status: 'sent' };\n if (posted?.runGeneration != null) {\n this.applySessionRunGeneration(state, sessionId, posted.runGeneration);\n }\n state.messages = state.messages.map((m) => (m.id === userMessage.id ? sentUser : m));\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n this.bus.emit('message', { message: sentUser, source: sentUser.role });\n return sentUser;\n }\n\n private syncWriteConfirmationMessageId(\n state: InternalState,\n previousId: string,\n nextId: string,\n ): void {\n if (previousId === nextId) return;\n\n for (const [sessionKey, confirmation] of state.writeConfirmationsBySession) {\n if (confirmation.messageId !== previousId) continue;\n const updated = { ...confirmation, messageId: nextId };\n state.writeConfirmationsBySession.set(sessionKey, updated);\n if (\n state.activeSessionId &&\n normalizeSessionId(state.activeSessionId) === sessionKey\n ) {\n state.writeConfirmation = updated;\n }\n return;\n }\n\n if (state.writeConfirmation?.messageId === previousId) {\n state.writeConfirmation = { ...state.writeConfirmation, messageId: nextId };\n }\n }\n\n private async postWriteGateAction(\n state: InternalState,\n sessionId: string,\n writeGate: WriteGate,\n signal: AbortSignal,\n ): Promise<void> {\n const body = await state.chat.postWriteGateDecision(sessionId, writeGate, signal);\n const posted = parsePostedMessage(body);\n if (posted?.runGeneration != null) {\n this.applySessionRunGeneration(state, sessionId, posted.runGeneration, {\n clearActiveRun: false,\n });\n }\n }\n\n /**\n * Open `GET /chat/{sessionId}/stream` and resolve once the SSE connection is up.\n * Consumption continues in the background until the stream ends or is aborted.\n */\n private connectSessionStream(\n sessionId: string,\n streamCtrl: AbortController,\n ): Promise<void> {\n const state = this.requireState('connectSessionStream');\n const normalizedId = normalizeSessionId(sessionId);\n state.sessionStreams.set(normalizedId, {\n abort: streamCtrl,\n targetMessageId: this.pendingStreamTargets.get(normalizedId) ?? null,\n });\n this.pendingStreamTargets.delete(normalizedId);\n state.abortControllers.add(streamCtrl);\n\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n const settleResolve = () => {\n if (settled) return;\n settled = true;\n resolve();\n };\n const settleReject = (err: unknown) => {\n if (settled) return;\n settled = true;\n reject(err);\n };\n\n void this.consumeSessionStream(sessionId, streamCtrl, settleResolve)\n .catch((err) => {\n if (!settled) settleReject(err);\n })\n .finally(() => {\n state.abortControllers.delete(streamCtrl);\n state.sessionStreams.delete(normalizedId);\n this.scheduleSessionStreamReconnect(state, sessionId);\n });\n });\n }\n\n private async consumeSessionStream(\n sessionId: string,\n ctrl: AbortController,\n onConnected?: () => void,\n ): Promise<void> {\n const state = this.requireState('consumeSessionStream');\n\n const getAgent = (id: string | null): AgentMessage | undefined => {\n if (!id) return undefined;\n return this.getSessionMessagesList(state, sessionId).find((m) => m.id === id);\n };\n\n const replaceAgentMessage = (next: AgentMessage, previousId: string): void => {\n this.replaceMessageInSession(state, sessionId, next, previousId);\n };\n\n try {\n for await (const chunk of state.chat.streamSession(sessionId, {\n signal: ctrl.signal,\n onConnected,\n })) {\n if (state.options.debug) {\n console.debug('[agent-chat] SSE', chunk.event, chunk.data.slice(0, 120));\n }\n\n const action = parseChatSseEvent(chunk.event, chunk.data);\n const gate = this.applySseRunGate(state, sessionId, action);\n if (gate === 'skip') continue;\n\n let currentTargetId =\n action.type === 'think' ||\n action.type === 'result' ||\n action.type === 'message-blocks' ||\n action.type === 'complete'\n ? this.resolveStreamTargetMessageId(state, sessionId, action.messageId)\n : null;\n currentTargetId = this.maybeRebindStreamMessageId(\n state,\n sessionId,\n currentTargetId,\n action.type === 'think' ||\n action.type === 'result' ||\n action.type === 'message-blocks' ||\n action.type === 'complete'\n ? action.messageId\n : undefined,\n );\n\n switch (action.type) {\n case 'think': {\n if (!currentTargetId) break;\n this.patchMessageInSession(state, sessionId, currentTargetId, (current) => {\n const stream = { ...(current.stream ?? createEmptyAgentStream()) };\n const thinkText =\n action.mode === 'append'\n ? `${stream.thinkText}${action.text}`\n : action.text;\n const hasResult =\n Boolean(stream.resultText?.trim()) ||\n Boolean((stream.resultBlocks ?? current.blocks ?? []).length);\n return {\n ...current,\n status: 'pending',\n content: hasResult ? current.content : { type: 'text', text: '' },\n stream: {\n ...stream,\n thinkText,\n runId: action.runId ?? stream.runId,\n phase: hasResult ? 'result' : 'thinking',\n },\n };\n });\n break;\n }\n case 'result': {\n if (!currentTargetId) break;\n if (\n action.mode === 'replace' &&\n this.isExistingSentAssistantText(state, sessionId, action.text, currentTargetId)\n ) {\n break;\n }\n this.patchMessageInSession(state, sessionId, currentTargetId, (current) => {\n const stream = { ...(current.stream ?? createEmptyAgentStream()) };\n const nextResult =\n action.mode === 'append' ? `${stream.resultText}${action.text}` : action.text;\n return {\n ...current,\n status: 'pending',\n content: { type: 'text', text: nextResult },\n stream: {\n ...stream,\n resultText: nextResult,\n runId: action.runId ?? stream.runId,\n phase: 'result',\n },\n };\n });\n break;\n }\n case 'message-blocks': {\n const sessionConfirmation = state.writeConfirmationsBySession.get(\n normalizeSessionId(sessionId),\n );\n if (\n !currentTargetId &&\n action.runId != null &&\n sessionConfirmation?.submitting\n ) {\n const placeholder = this.appendAgentPlaceholderInSession(state, sessionId);\n this.setStreamTargetMessageId(state, sessionId, placeholder.id);\n currentTargetId = placeholder.id;\n }\n if (!currentTargetId) break;\n const streamSeq = action.seq;\n this.patchMessageInSession(state, sessionId, currentTargetId, (current) => {\n const stream = { ...(current.stream ?? createEmptyAgentStream()) };\n const seenSeq = new Set<number>(stream.seenSeq ?? []);\n if (streamSeq != null && seenSeq.has(streamSeq)) return current;\n if (streamSeq != null) seenSeq.add(streamSeq);\n\n const previousBlocks = (stream.resultBlocks ?? current.blocks ?? []) as CoreMessageBlock[];\n let nextBlocks = previousBlocks;\n if (action.action === 'stream') {\n if (action.streamMode === 'full') {\n nextBlocks = applyStreamFull(previousBlocks, (action.blocks ?? []) as CoreMessageBlock[]);\n } else {\n nextBlocks = applyStreamDelta(previousBlocks, (action.blocks ?? []) as CoreMessageBlock[]);\n }\n } else if (action.action === 'patch') {\n nextBlocks = applyPatches(\n previousBlocks,\n (action.patches ?? []).map((patch) => ({\n replaceId: patch.replaceId,\n block: patch.block as CoreMessageBlock,\n })),\n );\n }\n\n nextBlocks = unwrapBlocksJsonEnvelope(nextBlocks);\n const nextResult = blocksToText(nextBlocks);\n return {\n ...current,\n status: 'pending',\n content: { type: 'text', text: nextResult },\n blocks: nextBlocks,\n stream: {\n ...stream,\n runId: action.runId ?? stream.runId,\n resultBlocks: nextBlocks,\n resultText: nextResult,\n phase: 'result',\n seenSeq: [...seenSeq],\n },\n };\n });\n break;\n }\n case 'write-confirmation-required': {\n const messages = this.getSessionMessagesList(state, sessionId);\n const messageId =\n this.getStreamHandle(state, sessionId)?.targetMessageId ??\n [...messages].reverse().find((m) => m.role === 'agent')?.id;\n this.persistWriteConfirmation(state, sessionId, {\n awaiting: true,\n submitting: false,\n runId: action.runId,\n turnId: action.turnId,\n message: action.message,\n messageId,\n generation: action.generation,\n draftRetryCount: action.draftRetryCount,\n draftRetryMax: action.draftRetryMax,\n canRetry: action.canRetry,\n writeDraft: action.writeDraft ?? null,\n writeDrafts: action.writeDrafts ?? null,\n editPolicy: action.editPolicy ?? null,\n editPolicies: action.editPolicies ?? null,\n });\n this.notifyStateChange();\n break;\n }\n case 'write-confirmation-cancelled': {\n this.persistWriteConfirmation(state, sessionId, null);\n this.appendSystemMessageInSession(state, sessionId, action.message);\n break;\n }\n case 'host-action': {\n if (action.ssePayload) {\n this.ingestHostActionSse(state, sessionId, action.ssePayload, undefined, 'chat');\n } else if (action.action) {\n this.emitHostAction(state, action.action);\n this.emitPageAgentCompleteFromAction(action.action, 'chat');\n }\n break;\n }\n case 'complete': {\n if (action.status === 'cancelled') {\n if (currentTargetId) {\n this.finalizeStreamingTarget(state, sessionId);\n } else {\n this.getSessionRunState(state, sessionId).activeRunId = null;\n }\n this.hostToolStreamManagers.get(normalizeSessionId(sessionId))?.reset();\n break;\n }\n if (action.status === 'failed') {\n if (currentTargetId) {\n const current = getAgent(currentTargetId);\n if (current) {\n const stream = current.stream ?? createEmptyAgentStream();\n replaceAgentMessage(\n {\n ...current,\n status: 'failed',\n stream: {\n ...stream,\n phase: 'error',\n errorMessage: action.reason ?? 'Generation failed',\n },\n },\n currentTargetId,\n );\n }\n }\n this.setStreamTargetMessageId(state, sessionId, null);\n this.getSessionRunState(state, sessionId).activeRunId = null;\n this.hostToolStreamManagers.get(normalizeSessionId(sessionId))?.reset();\n break;\n }\n if (!currentTargetId) break;\n const current = getAgent(currentTargetId);\n if (!current) break;\n const sessionKey = normalizeSessionId(sessionId);\n const awaitingConfirm = state.writeConfirmationsBySession.get(sessionKey)?.awaiting;\n const stream = { ...(current.stream ?? createEmptyAgentStream()), phase: 'complete' as const };\n let finalized: AgentMessage;\n if (action.serverMessage) {\n const parsed = this.toAgentMessage(action.serverMessage as ServerMessage);\n finalized = finalizeAgentReply(\n { ...current, content: parsed.content, blocks: parsed.blocks ?? current.blocks },\n { ...stream, resultText: parsed.content.text, resultBlocks: parsed.blocks ?? stream.resultBlocks },\n { status: 'sent' },\n );\n } else {\n finalized = finalizeAgentReply(current, stream, { status: 'sent' });\n }\n const serverId = this.resolveCompleteServerMessageId(action);\n if (\n serverId &&\n serverId !== currentTargetId &&\n !this.getSessionMessagesList(state, sessionId).some((m) => m.id === serverId)\n ) {\n replaceAgentMessage({ ...finalized, id: serverId }, currentTargetId);\n } else {\n replaceAgentMessage(finalized, currentTargetId);\n }\n this.setStreamTargetMessageId(state, sessionId, null);\n this.getSessionRunState(state, sessionId).activeRunId = null;\n this.hostToolStreamManagers.get(normalizeSessionId(sessionId))?.reset();\n if (!awaitingConfirm) {\n this.persistWriteConfirmation(state, sessionId, null);\n }\n void this.alignPersistedMessageIds(state, sessionId, {\n preferLocalId: currentTargetId,\n preferServerId: serverId,\n }).catch(() => {\n /* best-effort id alignment for feedback */\n });\n const finalizedId = serverId && serverId !== currentTargetId ? serverId : currentTargetId;\n if (action.runId != null) {\n this.applySkillIntentAlignment(state, {\n sessionId,\n runId: action.runId,\n assistantMessageId: finalizedId,\n });\n }\n this.maybeNotifyBackgroundReply(state, sessionId);\n break;\n }\n case 'error': {\n if (action.code === 'WRITE_CONFIRMATION_EXPIRED') {\n this.persistWriteConfirmation(state, sessionId, null);\n this.notifyStateChange();\n } else if (\n action.code === 'EDITED_WRITE_ARGS_INVALID' ||\n action.code === 'EDITED_LOCKED_FIELD' ||\n action.code === 'EDITED_FIELD_NOT_ALLOWED' ||\n action.code === 'MULTI_WRITE_EDIT_NOT_SUPPORTED' ||\n action.code === 'DRAFT_RETRY_LIMIT_EXCEEDED'\n ) {\n const key = normalizeSessionId(sessionId);\n const current = state.writeConfirmationsBySession.get(key);\n if (current) {\n const updated: WriteConfirmationState = {\n ...current,\n awaiting: true,\n submitting: false,\n gateError: action.message,\n gateErrorCode: action.code,\n canRetry:\n action.code === 'DRAFT_RETRY_LIMIT_EXCEEDED' ? false : current.canRetry,\n };\n this.persistWriteConfirmation(state, sessionId, updated);\n this.notifyStateChange();\n break;\n }\n }\n throw new AgentChatError('MESSAGE_FAILED', action.message, {\n details: action.code ? { code: action.code } : undefined,\n });\n }\n case 'noop':\n break;\n default:\n break;\n }\n }\n\n const snapshot = getAgent(this.resolveStreamTargetMessageId(state, sessionId));\n if (snapshot && (snapshot.status ?? 'pending') === 'pending') {\n const stream = snapshot.stream;\n const text = (stream?.resultText || snapshot.content.text || '').trim();\n if (!text) {\n this.removeAgentMessageInSession(state, sessionId, snapshot.id);\n } else {\n replaceAgentMessage(\n finalizeAgentReply(\n snapshot,\n { ...(stream ?? createEmptyAgentStream()), phase: 'complete' as const },\n { status: 'sent' },\n ),\n snapshot.id,\n );\n }\n this.maybeNotifyBackgroundReply(state, sessionId);\n }\n void this.alignPersistedMessageIds(state, sessionId).catch(() => {\n /* best-effort id alignment for feedback */\n });\n } catch (err) {\n if ((err as { name?: string })?.name === 'AbortError') {\n const snapshot = getAgent(this.resolveStreamTargetMessageId(state, sessionId));\n if (!snapshot) return;\n const stream = snapshot.stream ?? createEmptyAgentStream();\n const text = (stream.resultText || snapshot.content.text).trim();\n if (!text) {\n this.removeAgentMessageInSession(state, sessionId, snapshot.id);\n } else {\n replaceAgentMessage(\n finalizeAgentReply(snapshot, { ...stream, phase: 'complete' }, { status: 'sent' }),\n snapshot.id,\n );\n }\n return;\n }\n const snapshot = getAgent(this.resolveStreamTargetMessageId(state, sessionId));\n if (snapshot) {\n const stream = snapshot.stream ?? createEmptyAgentStream();\n replaceAgentMessage(\n {\n ...snapshot,\n status: 'failed',\n stream: {\n ...stream,\n phase: 'error',\n errorMessage: err instanceof Error ? err.message : 'Stream failed',\n },\n },\n snapshot.id,\n );\n }\n const wrapped =\n err instanceof AgentChatError\n ? err\n : new AgentChatError('MESSAGE_FAILED', 'Failed to receive assistant reply', {\n cause: err,\n });\n if (this.isViewingSession(state, sessionId)) {\n this.reportError(wrapped);\n } else if (state.options.debug && typeof console !== 'undefined') {\n console.warn(\n `[agent-chat] Background stream error for session ${sessionId} (suppressed from UI):`,\n wrapped,\n );\n }\n }\n }\n\n private toAgentMessage(input: ServerMessage): AgentMessage {\n const role =\n input.role === 'assistant' ? 'agent' : input.role === 'user' ? 'user' : 'system';\n const createdAtRaw = input.createdAt;\n const createdAt =\n typeof createdAtRaw === 'number'\n ? createdAtRaw\n : new Date(createdAtRaw as string | Date).getTime();\n const blocks = parseStoredBlocks(input.content);\n const text = blocks ? blocksToText(blocks) : input.content ?? '';\n return {\n id: String(input.id),\n role,\n content: { type: 'text', text },\n blocks,\n createdAt: Number.isFinite(createdAt) ? createdAt : Date.now(),\n status: 'sent',\n };\n }\n\n private resolveCompleteServerMessageId(action: {\n serverMessage?: { id?: string | number };\n messageId?: string;\n }): string | undefined {\n if (action.serverMessage?.id != null) {\n return String(action.serverMessage.id);\n }\n if (action.messageId && isPersistedMessageId(action.messageId)) {\n return action.messageId;\n }\n return undefined;\n }\n\n /**\n * SSE placeholders use client ids until the assistant message is persisted.\n * Match unresolved local agent bubbles to server ids from the latest session page.\n */\n private async alignPersistedMessageIds(\n state: InternalState,\n sessionId: string,\n opts: { preferLocalId?: string; preferServerId?: string } = {},\n ): Promise<void> {\n const preferLocalId = opts.preferLocalId?.trim();\n const preferServerId =\n opts.preferServerId && isPersistedMessageId(opts.preferServerId)\n ? opts.preferServerId\n : undefined;\n\n if (preferLocalId && preferServerId) {\n const messages = this.getSessionMessagesList(state, sessionId);\n const current = messages.find((message) => message.id === preferLocalId);\n if (current && !isPersistedMessageId(current.id) && !messages.some((m) => m.id === preferServerId)) {\n const updated = messages.map((message) =>\n message.id === preferLocalId ? { ...message, id: preferServerId } : message,\n );\n this.syncWriteConfirmationMessageId(state, preferLocalId, preferServerId);\n const handle = this.getStreamHandle(state, sessionId);\n if (handle?.targetMessageId === preferLocalId) {\n handle.targetMessageId = preferServerId;\n }\n this.commitSessionMessages(state, sessionId, updated);\n void this.syncMessageFeedbacks(state, sessionId).catch(() => {\n /* best-effort */\n });\n return;\n }\n }\n\n const messages = this.getSessionMessagesList(state, sessionId);\n const unresolved = messages.filter(\n (message) =>\n message.role === 'agent' &&\n message.status === 'sent' &&\n !message.stream &&\n !isPersistedMessageId(message.id),\n );\n if (unresolved.length === 0) return;\n\n const detailPage = await this.fetchSessionMessagesPage(state, sessionId, 1);\n const serverAgents = detailPage.messages\n .map((raw) => this.toAgentMessage(raw as ServerMessage))\n .filter((message) => message.role === 'agent');\n\n const claimedServerIds = new Set(\n messages\n .filter((message) => message.role === 'agent' && isPersistedMessageId(message.id))\n .map((message) => message.id),\n );\n\n const available = serverAgents.filter((message) => !claimedServerIds.has(message.id));\n if (available.length === 0) return;\n\n const pairsStart = Math.max(0, available.length - unresolved.length);\n let changed = false;\n\n const updated = messages.map((message) => {\n const unresolvedIndex = unresolved.findIndex((candidate) => candidate.id === message.id);\n if (unresolvedIndex < 0) return message;\n const server = available[pairsStart + unresolvedIndex];\n if (!server || !isPersistedMessageId(server.id)) return message;\n changed = true;\n this.syncWriteConfirmationMessageId(state, message.id, server.id);\n return {\n ...message,\n id: server.id,\n createdAt: server.createdAt,\n };\n });\n\n if (!changed) return;\n this.commitSessionMessages(state, sessionId, updated);\n void this.syncMessageFeedbacks(state, sessionId).catch(() => {\n /* best-effort */\n });\n }\n\n private maybeRebindStreamMessageId(\n state: InternalState,\n sessionId: string,\n currentTargetId: string | null,\n incomingMessageId?: string,\n ): string | null {\n if (!currentTargetId || !incomingMessageId || !isPersistedMessageId(incomingMessageId)) {\n return currentTargetId;\n }\n if (currentTargetId === incomingMessageId) return currentTargetId;\n if (isPersistedMessageId(currentTargetId)) return currentTargetId;\n\n const messages = this.getSessionMessagesList(state, sessionId);\n if (messages.some((message) => message.id === incomingMessageId)) {\n return currentTargetId;\n }\n\n const current = messages.find((message) => message.id === currentTargetId);\n if (!current) return incomingMessageId;\n\n const updated = messages.map((message) =>\n message.id === currentTargetId ? { ...message, id: incomingMessageId } : message,\n );\n const handle = this.getStreamHandle(state, sessionId);\n if (handle?.targetMessageId === currentTargetId) {\n handle.targetMessageId = incomingMessageId;\n }\n this.commitSessionMessages(state, sessionId, updated);\n return incomingMessageId;\n }\n\n private buildOptimisticFeedback(\n messageId: number,\n body: UpsertMessageFeedbackBody,\n ): MessageFeedbackView {\n const now = new Date().toISOString();\n if (body.rating === 'up') {\n return {\n messageId,\n rating: 'up',\n reasonTags: [],\n comment: null,\n createdAt: now,\n updatedAt: now,\n };\n }\n return {\n messageId,\n rating: 'down',\n reasonTags: body.reasonTags ?? [],\n comment: body.comment?.trim() || null,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n private patchMessageFeedback(\n state: InternalState,\n messageId: string,\n feedback: MessageFeedbackView | null,\n ): void {\n const next = state.messages.map((message) =>\n message.id === messageId ? { ...message, feedback } : message,\n );\n if (next.every((message, index) => message === state.messages[index])) return;\n state.messages = next;\n this.cacheActiveSessionMessages(state);\n this.notifyStateChange();\n }\n\n private collectFeedbackMessageIds(messages: AgentMessage[]): number[] {\n const ids: number[] = [];\n for (const message of messages) {\n if (message.role !== 'agent' || message.status !== 'sent' || message.stream) continue;\n const numericId = parsePersistedMessageId(message.id);\n if (numericId !== null) ids.push(numericId);\n }\n return ids;\n }\n\n private async syncMessageFeedbacks(state: InternalState, sessionId: string): Promise<void> {\n const messages = this.getSessionMessagesList(state, sessionId);\n const messageIds = this.collectFeedbackMessageIds(messages);\n if (messageIds.length === 0) return;\n\n const batch = await state.feedback.batchFeedbacks(sessionId, messageIds);\n const map = new Map<string, MessageFeedbackView>(\n batch.items.map((row: MessageFeedbackView) => [String(row.messageId), row]),\n );\n let changed = false;\n\n const updated = messages.map((message) => {\n if (message.role !== 'agent' || !isPersistedMessageId(message.id)) return message;\n const nextFeedback: MessageFeedbackView | null = map.get(message.id) ?? null;\n const prev = message.feedback ?? null;\n if (prev === null && nextFeedback === null) return message;\n if (\n prev &&\n nextFeedback &&\n prev.rating === nextFeedback.rating &&\n prev.updatedAt === nextFeedback.updatedAt\n ) {\n return message;\n }\n changed = true;\n return { ...message, feedback: nextFeedback };\n });\n\n if (!changed) return;\n this.commitSessionMessages(state, sessionId, updated);\n }\n\n}\n\nfunction normalizePrepareSessionOptions(\n signalOrOptions?: AbortSignal | PrepareSessionOptions,\n): PrepareSessionOptions {\n if (signalOrOptions == null) return {};\n if (\n typeof signalOrOptions === 'object' &&\n 'aborted' in signalOrOptions &&\n typeof (signalOrOptions as AbortSignal).addEventListener === 'function'\n ) {\n return { signal: signalOrOptions as AbortSignal };\n }\n return signalOrOptions as PrepareSessionOptions;\n}\n\nfunction authUserToContext(user: AppClientAuthData['user']): UserContext | undefined {\n if (!user) return undefined;\n return {\n id: String(user.id),\n email: user.email,\n name: user.username,\n };\n}\n\nfunction toAgentChatErrorPayload(err: unknown): AgentChatErrorPayload {\n if (err instanceof AgentChatError) {\n return {\n code: err.code,\n message: err.message,\n cause: (err as { cause?: unknown }).cause,\n };\n }\n return {\n code: 'TRANSPORT_FAILED',\n message: err instanceof Error ? err.message : 'Unknown error',\n cause: err,\n };\n}\n\nfunction readWriteGateServerCode(err: unknown): string | undefined {\n if (!(err instanceof AgentChatError)) return undefined;\n const details = err.details;\n if (!details) return undefined;\n if (typeof details.serverCode === 'string') return details.serverCode;\n if (typeof details.code === 'string') return details.code;\n return undefined;\n}\n\n/** Map HTTP 403 `PAGE_ACTION_ROLLOUT_DENIED` onto a typed SDK error. */\nfunction remapPageActionRolloutDenied(err: unknown): unknown {\n if (!(err instanceof AgentChatError) || err.code !== 'TRANSPORT_FAILED') {\n return err;\n }\n if (err.details?.serverCode !== 'PAGE_ACTION_ROLLOUT_DENIED') {\n return err;\n }\n return new AgentChatError(\n 'PAGE_ACTION_ROLLOUT_DENIED',\n err.message || 'PageAction not available for this user',\n { cause: err, details: err.details },\n );\n}\n\nexport function createAgentChat(): AgentChatClient {\n return new AgentChatClient();\n}\n","import { createContext } from 'react';\nimport type { AgentChatClient } from '../core/client/instance';\n\nexport const AgentChatContext = createContext<AgentChatClient | null>(null);\n\nexport const MISSING_PROVIDER_MESSAGE =\n 'useAgentChat must be used within <AgentChatProvider>. ' +\n 'Wrap your app: <AgentChatProvider dsn=\"...\"><App /></AgentChatProvider>, ' +\n 'or use <AgentChat dsn=\"...\" /> for the all-in-one integration.';\n","import {\n Suspense,\n lazy,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { createAgentChat, type AgentChatClient } from '../core/client/instance';\nimport type { AgentChatOptions } from '../types';\nimport { AgentChatContext } from './context';\n\n/** Chat shell (antd) — separate async chunk so sync entry stays light for Umi/webpack. */\nconst AgentChatEmbedded = lazy(() => import('./AgentChatEmbedded'));\n\nexport interface AgentChatProps extends AgentChatOptions {\n children?: ReactNode;\n}\n\nfunction syncRuntimeOptions(\n client: AgentChatClient,\n options: Pick<AgentChatOptions, 'attachPageContext' | 'pageContext'>,\n): void {\n client.applyRuntimeOptions({\n attachPageContext: options.attachPageContext,\n pageContext: options.pageContext,\n });\n}\n\n/**\n * Recommended React integration — import and render directly.\n *\n * Host app content passed as `children` always renders, even when SDK init or\n * app-client auth fails. Only the portaled chat widget is gated on init.\n * The widget UI (antd) loads in an async chunk after init — still out-of-the-box,\n * without pulling the full UI into the host's sync dependency graph.\n *\n * @example\n * ```tsx\n * import { AgentChat } from 'omnix-chat/react';\n *\n * export function App() {\n * return (\n * <AgentChat dsn=\"your-dsn\" baseUrl=\"http://localhost:3030\">\n * <YourHostApp />\n * </AgentChat>\n * );\n * }\n * ```\n */\nexport function AgentChat({ children, dsn, ...options }: AgentChatProps) {\n if (!dsn) {\n throw new Error('<AgentChat> requires a `dsn` prop.');\n }\n\n const [client] = useState<AgentChatClient>(() => createAgentChat());\n const [chatReady, setChatReady] = useState(false);\n const generationRef = useRef(0);\n const initKeyRef = useRef<string | null>(null);\n\n const pageContextKey = useMemo(\n () => JSON.stringify(options.pageContext ?? null),\n [options.pageContext],\n );\n\n useEffect(() => {\n const key = JSON.stringify({\n dsn,\n baseUrl: options.baseUrl,\n token: options.accountToken ?? options.userAccessToken,\n });\n const gen = ++generationRef.current;\n let cancelled = false;\n\n void (async () => {\n if (initKeyRef.current === key) {\n syncRuntimeOptions(client, options);\n setChatReady(true);\n return;\n }\n if (initKeyRef.current !== null) {\n client.destroy();\n initKeyRef.current = null;\n setChatReady(false);\n }\n\n await client.init({\n ...options,\n dsn,\n });\n if (cancelled || gen !== generationRef.current) return;\n\n initKeyRef.current = key;\n syncRuntimeOptions(client, options);\n setChatReady(true);\n if (options.autoOpen) client.open();\n })().catch((err) => {\n if (options.debug) {\n console.error('[agent-chat] AgentChat init failed:', err);\n }\n if (!cancelled && gen === generationRef.current) {\n setChatReady(true);\n }\n });\n\n return () => {\n cancelled = true;\n const effectGen = gen;\n queueMicrotask(() => {\n if (effectGen !== generationRef.current) return;\n if (initKeyRef.current === key) {\n client.destroy();\n initKeyRef.current = null;\n setChatReady(false);\n }\n });\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- re-init when connection identity changes\n }, [dsn, options.baseUrl, options.accountToken, options.userAccessToken]);\n\n useEffect(() => {\n syncRuntimeOptions(client, {\n attachPageContext: options.attachPageContext,\n pageContext: options.pageContext,\n });\n }, [\n client,\n options.attachPageContext,\n pageContextKey,\n options.pageContext,\n ]);\n\n return (\n <AgentChatContext.Provider value={client}>\n {children}\n {chatReady ? (\n <Suspense fallback={null}>\n <AgentChatEmbedded client={client} position={options.position} />\n </Suspense>\n ) : null}\n </AgentChatContext.Provider>\n );\n}\n","import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { createAgentChat, type AgentChatClient } from '../core/client/instance';\nimport type { AgentChatOptions } from '../types';\nimport { AgentChatContext } from './context';\n\nexport interface AgentChatProviderProps extends AgentChatOptions {\n children?: ReactNode;\n}\n\n/**\n * Wraps an `AgentChatClient` lifecycle with React semantics:\n * - Creates one client per mount (or per `dsn` change).\n * - In Strict Mode the effect is intentionally double-invoked; we use a\n * `mountedRef` guard so `init()` runs at most once per logical mount.\n * - Re-runs init() if the `dsn` prop changes between renders, after first\n * destroying the previous instance to avoid `ALREADY_INITIALIZED`.\n */\nexport function AgentChatProvider({ children, ...options }: AgentChatProviderProps) {\n const { dsn } = options;\n // Stash the latest non-dsn options in a ref so we can re-init on dsn changes\n // without triggering effects on every render.\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const [client] = useState<AgentChatClient>(() => createAgentChat());\n const initializedDsnRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (initializedDsnRef.current === dsn) return; // Strict Mode guard\n let cancelled = false;\n let initialized = false;\n\n const run = async () => {\n if (initializedDsnRef.current !== null) {\n client.destroy();\n }\n await client.init({ ...optionsRef.current, dsn });\n if (cancelled) {\n client.destroy();\n return;\n }\n initialized = true;\n initializedDsnRef.current = dsn;\n };\n void run().catch((err) => {\n if (optionsRef.current.debug) {\n console.error('[agent-chat] failed to initialize provider instance:', err);\n }\n });\n\n return () => {\n // Effect cleanup runs on dsn change AND on unmount; in Strict Mode the\n // first cleanup happens after the first synchronous double-invocation.\n // We let dsn-change handle its own destroy() above (before re-init), so\n // here we only destroy on real unmount: detected by the ref still\n // matching the dsn we just initialized with.\n cancelled = true;\n if (initialized || initializedDsnRef.current === dsn) {\n client.destroy();\n initializedDsnRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- intentional: only react to dsn\n }, [dsn]);\n\n const ctxValue = useMemo(() => client, [client]);\n\n return <AgentChatContext.Provider value={ctxValue}>{children}</AgentChatContext.Provider>;\n}\n","import { useContext, useRef, useSyncExternalStore } from 'react';\nimport { AgentChatContext, MISSING_PROVIDER_MESSAGE } from './context';\nimport type { AgentChatClient } from '../core/client/instance';\nimport type { AgentChatState } from '../types';\n\n/** Client instance only — does not subscribe to {@link AgentChatState} updates. */\nexport function useAgentChatClient(): AgentChatClient {\n const instance = useContext(AgentChatContext);\n if (!instance) {\n throw new Error(MISSING_PROVIDER_MESSAGE);\n }\n return instance;\n}\n\n/**\n * Subscribe to a slice of {@link AgentChatState}. Re-renders only when the selected\n * value changes (`isEqual`). Use in hooks that do not need the full chat state.\n */\nexport function useAgentChatStore<T>(\n selector: (state: AgentChatState) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n const instance = useAgentChatClient();\n const selectorRef = useRef(selector);\n selectorRef.current = selector;\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n const sliceRef = useRef<T | undefined>(undefined);\n\n const getSnapshot = (): T => {\n const next = selectorRef.current(instance.getState());\n const prev = sliceRef.current;\n if (prev !== undefined && isEqualRef.current(prev, next)) {\n return prev;\n }\n sliceRef.current = next;\n return next;\n };\n\n const subscribe = (onStoreChange: () => void) =>\n instance.subscribeStateChange(() => {\n const next = selectorRef.current(instance.getState());\n const prev = sliceRef.current;\n if (prev !== undefined && isEqualRef.current(prev, next)) {\n return;\n }\n sliceRef.current = next;\n onStoreChange();\n });\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n","import { useCallback, useSyncExternalStore } from 'react';\nimport { useAgentChatClient } from './useAgentChatClient';\nimport type { AgentChatClient } from '../core/client/instance';\nimport type {\n AgentChatErrorPayload,\n AgentChatState,\n AgentChatRouteContext,\n AgentMessage,\n AgentChatLoginCredentials,\n} from '../types';\n\nexport interface UseAgentChatResult {\n instance: AgentChatClient;\n state: AgentChatState;\n isOpen: boolean;\n open: () => void;\n close: () => void;\n toggle: () => void;\n login: (credentials: AgentChatLoginCredentials) => Promise<void>;\n logout: () => void;\n isLoggedIn: boolean;\n sendMessage: (text: string) => Promise<AgentMessage>;\n selectSession: (sessionId: string) => Promise<void>;\n refreshSessions: () => Promise<void>;\n loadMoreSessions: () => Promise<void>;\n loadMoreSessionMessages: () => Promise<void>;\n selectAgent: (agentId: string) => Promise<void>;\n selectSkill: (skillId: string) => void;\n sessions: AgentChatState['sessions'];\n agents: AgentChatState['agents'];\n skills: AgentChatState['skills'];\n selectedAgentId: AgentChatState['selectedAgentId'];\n selectedSkillId: AgentChatState['selectedSkillId'];\n agentsLoading: AgentChatState['agentsLoading'];\n skillsLoading: AgentChatState['skillsLoading'];\n agentsEmptyReason: AgentChatState['agentsEmptyReason'];\n sessionsHasMore: AgentChatState['sessionsHasMore'];\n sessionsLoadingMore: AgentChatState['sessionsLoadingMore'];\n sessionMessagesHasMore: AgentChatState['sessionMessagesHasMore'];\n sessionMessagesLoadingMore: AgentChatState['sessionMessagesLoadingMore'];\n activeSessionId: AgentChatState['activeSessionId'];\n lastError: AgentChatErrorPayload | null;\n pageContext: AgentChatState['pageContext'];\n routeContext: AgentChatState['routeContext'];\n attachPageContext: AgentChatState['attachPageContext'];\n setAttachPageContext: (attach: boolean) => void;\n setRouteContext: (routeContext: AgentChatRouteContext | null) => void;\n syncRouteContextFromWindow: () => void;\n}\n\nexport function useAgentChat(): UseAgentChatResult {\n const instance = useAgentChatClient();\n\n const state = useSyncExternalStore(\n (listener) => instance.subscribeStateChange(listener),\n () => instance.getState(),\n () => instance.getState(),\n );\n\n const open = useCallback(() => instance.open(), [instance]);\n const close = useCallback(() => instance.close(), [instance]);\n const toggle = useCallback(() => instance.toggle(), [instance]);\n const login = useCallback(\n (credentials: AgentChatLoginCredentials) => instance.login(credentials),\n [instance],\n );\n const logout = useCallback(() => instance.logout(), [instance]);\n const sendMessage = useCallback((text: string) => instance.sendMessage(text), [instance]);\n const selectSession = useCallback(\n (sessionId: string) => instance.selectSession(sessionId),\n [instance],\n );\n const refreshSessions = useCallback(() => instance.refreshSessions(), [instance]);\n const loadMoreSessions = useCallback(() => instance.loadMoreSessions(), [instance]);\n const loadMoreSessionMessages = useCallback(\n () => instance.loadMoreSessionMessages(),\n [instance],\n );\n const selectAgent = useCallback(\n (agentId: string) => instance.selectAgent(agentId),\n [instance],\n );\n const selectSkill = useCallback((skillId: string) => instance.selectSkill(skillId), [instance]);\n const setAttachPageContext = useCallback(\n (attach: boolean) => instance.setAttachPageContext(attach),\n [instance],\n );\n const setRouteContext = useCallback(\n (routeContext: AgentChatRouteContext | null) => instance.setRouteContext(routeContext),\n [instance],\n );\n const syncRouteContextFromWindow = useCallback(\n () => instance.syncRouteContextFromWindow(),\n [instance],\n );\n\n return {\n instance,\n state,\n isOpen: state.isOpen,\n open,\n close,\n toggle,\n login,\n logout,\n isLoggedIn: state.isLoggedIn,\n sendMessage,\n selectSession,\n refreshSessions,\n loadMoreSessions,\n loadMoreSessionMessages,\n selectAgent,\n selectSkill,\n sessions: state.sessions,\n agents: state.agents,\n skills: state.skills,\n selectedAgentId: state.selectedAgentId,\n selectedSkillId: state.selectedSkillId,\n agentsLoading: state.agentsLoading,\n skillsLoading: state.skillsLoading,\n agentsEmptyReason: state.agentsEmptyReason,\n sessionsHasMore: state.sessionsHasMore,\n sessionsLoadingMore: state.sessionsLoadingMore,\n sessionMessagesHasMore: state.sessionMessagesHasMore,\n sessionMessagesLoadingMore: state.sessionMessagesLoadingMore,\n activeSessionId: state.activeSessionId,\n lastError: state.lastError,\n pageContext: state.pageContext,\n routeContext: state.routeContext,\n attachPageContext: state.attachPageContext,\n setAttachPageContext,\n setRouteContext,\n syncRouteContextFromWindow,\n };\n}\n","import { useEffect, useRef } from 'react';\nimport { registerHostAction } from '../core/host-tool/host-action-registry';\nimport type { AgentChatHostAction } from '../types';\n\ntype HostActionHandler = (action: AgentChatHostAction) => void | Promise<void>;\n\n/**\n * Register a page-level host action handler for the lifetime of a component.\n *\n * `hostTools` from the server are executed automatically by the SDK after handlers run.\n * Use this hook for extra logic (entity guard, toast, branching on `reason`).\n *\n * @example\n * ```tsx\n * useHostAction('review-detail', async (action) => {\n * if (action.entity?.id !== reviewId) return;\n * if (action.reason === 'agent_mutation_success') await refetch();\n * });\n * ```\n */\nexport function useHostAction(scope: string, handler: HostActionHandler): void;\n/** Register a global handler that receives every host action. */\nexport function useHostAction(handler: HostActionHandler): void;\nexport function useHostAction(\n scopeOrHandler: string | HostActionHandler,\n handler?: HostActionHandler,\n): void {\n const isGlobal = typeof scopeOrHandler === 'function';\n const scope = isGlobal ? '' : scopeOrHandler.trim();\n const globalRef = useRef<HostActionHandler | null>(isGlobal ? scopeOrHandler : null);\n const handlerRef = useRef(handler);\n if (isGlobal) {\n globalRef.current = scopeOrHandler;\n }\n handlerRef.current = handler;\n\n useEffect(() => {\n const wrapped: HostActionHandler = (action) => {\n const fn = isGlobal ? globalRef.current : handlerRef.current;\n return fn?.(action);\n };\n\n if (isGlobal) {\n return registerHostAction(wrapped);\n }\n if (!scope) return;\n return registerHostAction(scope, wrapped);\n }, [isGlobal, scope]);\n}\n","import type { AgentChatClient } from '../core/client/instance';\nimport {\n isHostToolKnownGlobally,\n isHostToolRegisteredInScope,\n} from '../core/host-tool/host-tool-registry';\nimport type {\n PageAgentAwaitingApprovalPayload,\n PageAgentCompleteContext,\n PageAgentErrorContext,\n PageAgentLifecyclePayload,\n PageAgentStartContext,\n PageAgentStreamContext,\n} from '../types';\n\nconst DEFAULT_STREAM_THROTTLE_MS = 16;\n\nexport type PageAgentLifecycleCallbacks = {\n onStart?: (context: PageAgentStartContext) => void;\n onStream?: (context: PageAgentStreamContext) => void;\n onComplete?: (context: PageAgentCompleteContext) => void;\n onError?: (context: PageAgentErrorContext) => void;\n};\n\nexport function lifecycleTouchesGlobalTool(payload: PageAgentLifecyclePayload): boolean {\n switch (payload.type) {\n case 'start':\n return payload.context.toolName\n ? isHostToolKnownGlobally(payload.context.toolName)\n : false;\n case 'stream':\n return isHostToolKnownGlobally(payload.context.toolName);\n case 'complete':\n return payload.context.hostTools.some((tool) =>\n isHostToolKnownGlobally(tool.name),\n );\n case 'error':\n return false;\n default:\n return false;\n }\n}\n\nexport function lifecycleMatchesPageScope(\n payload: PageAgentLifecyclePayload,\n pageScope: string,\n): boolean {\n const scope =\n payload.type === 'error'\n ? payload.context.scope?.trim()\n : payload.context.scope?.trim();\n return scope === pageScope;\n}\n\nexport function lifecycleTouchesPageTool(\n payload: PageAgentLifecyclePayload,\n pageScope: string,\n): boolean {\n if (!lifecycleMatchesPageScope(payload, pageScope)) return false;\n switch (payload.type) {\n case 'start':\n return payload.context.toolName\n ? isHostToolRegisteredInScope(pageScope, payload.context.toolName)\n : true;\n case 'stream':\n return isHostToolRegisteredInScope(pageScope, payload.context.toolName);\n case 'complete':\n return payload.context.hostTools.some((tool) =>\n isHostToolRegisteredInScope(pageScope, tool.name),\n );\n case 'error':\n return true;\n default:\n return false;\n }\n}\n\n/** Page scope: all lifecycle on this `host_action.scope` (incl. global tools running here). */\nexport function shouldDeliverPageLifecycle(\n payload: PageAgentLifecyclePayload,\n pageScope: string,\n): boolean {\n return lifecycleMatchesPageScope(payload, pageScope);\n}\n\n/** App root: global tool registry (`scope *`) on any page. */\nexport function shouldDeliverAppLifecycle(payload: PageAgentLifecyclePayload): boolean {\n return lifecycleTouchesGlobalTool(payload);\n}\n\nexport function subscribePageAgentLifecycle(\n instance: AgentChatClient,\n options: {\n shouldDeliver: (payload: PageAgentLifecyclePayload) => boolean;\n streamThrottleMs?: number;\n callbacks: PageAgentLifecycleCallbacks;\n onAwaitingApproval?: (payload: PageAgentAwaitingApprovalPayload) => void;\n approvalScope?: string;\n },\n): () => void {\n const streamThrottleMs = options.streamThrottleMs ?? DEFAULT_STREAM_THROTTLE_MS;\n const callbacksRef = { current: options.callbacks };\n callbacksRef.current = options.callbacks;\n\n let pendingStream: PageAgentStreamContext | null = null;\n let streamTimer: ReturnType<typeof setTimeout> | null = null;\n\n const flushStream = () => {\n const pending = pendingStream;\n if (!pending) return;\n pendingStream = null;\n callbacksRef.current.onStream?.(pending);\n };\n\n const scheduleStream = (context: PageAgentStreamContext) => {\n if (streamThrottleMs <= 0) {\n callbacksRef.current.onStream?.(context);\n return;\n }\n pendingStream = context;\n if (streamTimer != null) return;\n streamTimer = setTimeout(() => {\n streamTimer = null;\n flushStream();\n }, streamThrottleMs);\n };\n\n const clearStreamState = () => {\n if (streamTimer != null) {\n clearTimeout(streamTimer);\n streamTimer = null;\n }\n pendingStream = null;\n };\n\n const handleLifecycle = (payload: PageAgentLifecyclePayload) => {\n if (!options.shouldDeliver(payload)) return;\n\n switch (payload.type) {\n case 'start':\n callbacksRef.current.onStart?.(payload.context);\n break;\n case 'stream':\n scheduleStream(payload.context);\n break;\n case 'complete':\n clearStreamState();\n flushStream();\n callbacksRef.current.onComplete?.(payload.context);\n break;\n case 'error':\n clearStreamState();\n callbacksRef.current.onError?.(payload.context);\n break;\n default:\n break;\n }\n };\n\n const offLifecycle = instance.on('pageAgentLifecycle', handleLifecycle);\n const offApproval = options.onAwaitingApproval\n ? instance.on('pageAgentAwaitingApproval', (payload) => {\n const scope = options.approvalScope?.trim();\n if (scope && payload.scope?.trim() !== scope) return;\n options.onAwaitingApproval?.(payload);\n })\n : () => {};\n\n return () => {\n offLifecycle();\n offApproval();\n clearStreamState();\n };\n}\n","/** Stable dependency key from tool names (order-independent). */\nexport function hostToolNamesKey(tools: Array<{ name: string }> | undefined): string {\n if (!tools?.length) return '';\n return [...tools].map((t) => t.name.trim()).sort().join('\\0');\n}\n\nexport function splitHostToolNamesKey(key: string): string[] {\n return key ? key.split('\\0') : [];\n}\n","import { useEffect, useRef } from 'react';\nimport { useAgentChatClient, useAgentChatStore } from './useAgentChatClient';\nimport {\n shouldDeliverPageLifecycle,\n subscribePageAgentLifecycle,\n} from './page-agent-lifecycle';\nimport { hostToolNamesKey, splitHostToolNamesKey } from './host-agent-registration';\nimport type {\n AgentChatPageContext,\n HostToolDefinition,\n HostToolHandler,\n PageAgentAwaitingApprovalPayload,\n PageAgentCompleteContext,\n PageAgentErrorContext,\n PageAgentStartContext,\n PageAgentStreamContext,\n} from '../types';\n\nexport interface UsePageAgentOptions {\n /** Business page scope — matches `pageContext.page` and `host_action.scope`. */\n scope: string;\n /** Synced on init; also pass to `<AgentChat pageContext={...} />` when possible. */\n pageContext?: AgentChatPageContext | null;\n /** Page-scoped host tools (fill form, etc.). Global tools → {@link useAppAgent}. */\n tools?: HostToolDefinition[];\n /**\n * Local handlers for app-declared tools on this page (no server sync).\n * Use when {@link useAppAgent} registered metadata without `handler`.\n */\n handlers?: Record<string, HostToolHandler>;\n /**\n * @deprecated Register global tools with {@link useAppAgent} at the app root.\n */\n genericTools?: HostToolDefinition[];\n pageLabel?: string;\n routePattern?: string;\n /**\n * Throttle `onStream` callbacks (ms). Tool `handler` is never throttled.\n * `0` disables throttling. Default `16` (~one frame).\n */\n streamThrottleMs?: number;\n /** `session.begin` / `tool.begin` on this scope */\n onStart?: (context: PageAgentStartContext) => void;\n /** `arg.append` on this scope (page + global tools running here) */\n onStream?: (context: PageAgentStreamContext) => void;\n /** `stream.full` on this scope */\n onComplete?: (context: PageAgentCompleteContext) => void;\n onError?: (context: PageAgentErrorContext) => void;\n onAwaitingApproval?: (context: PageAgentAwaitingApprovalPayload) => void;\n}\n\nfunction bindPageToolsFromRef(\n toolsRef: { current: HostToolDefinition[] | undefined },\n): HostToolDefinition[] {\n const tools = toolsRef.current;\n if (!tools?.length) return [];\n return tools.map((tool) => ({\n ...tool,\n handler: (args: Record<string, unknown>) =>\n toolsRef.current?.find((t) => t.name === tool.name)?.handler(args),\n ...(tool.onPreview\n ? {\n onPreview: (args: Record<string, unknown>) =>\n toolsRef.current?.find((t) => t.name === tool.name)?.onPreview?.(args),\n }\n : {}),\n }));\n}\n\n/**\n * Business-page hook: page context, page-scoped tools, lifecycle on current `scope`.\n *\n * Receives events for **all** tools executing on this page (including app-wide tools\n * declared via {@link useAppAgent}). Use `handlers` to execute app-level tools here.\n */\nexport function usePageAgent(options: UsePageAgentOptions): void {\n const instance = useAgentChatClient();\n const lifecycle = useAgentChatStore((state) => state.lifecycle);\n const scope = options.scope.trim();\n\n const callbacksRef = useRef(options);\n callbacksRef.current = options;\n\n const toolsRef = useRef(options.tools);\n toolsRef.current = options.tools;\n const toolNamesKey = hostToolNamesKey(options.tools);\n\n const genericToolsRef = useRef(options.genericTools);\n genericToolsRef.current = options.genericTools;\n const genericToolNamesKey = hostToolNamesKey(options.genericTools);\n const genericWarnedRef = useRef(false);\n\n useEffect(() => {\n if (lifecycle !== 'initialized') return;\n if (options.pageContext) {\n instance.setPageContext(options.pageContext);\n }\n }, [instance, options.pageContext, lifecycle]);\n\n useEffect(() => {\n if (!genericToolNamesKey) return;\n if (!genericWarnedRef.current) {\n genericWarnedRef.current = true;\n console.warn(\n '[agent-chat] usePageAgent: genericTools is deprecated — use useAppAgent at the app root.',\n );\n }\n let cancelled = false;\n void (async () => {\n try {\n await instance.registerHostToolsWithSync({\n appLevel: true,\n tools: bindPageToolsFromRef(genericToolsRef),\n });\n } catch (err) {\n if (!cancelled) {\n console.warn('[agent-chat] usePageAgent: genericTools register failed:', err);\n }\n }\n })();\n return () => {\n cancelled = true;\n for (const name of splitHostToolNamesKey(genericToolNamesKey)) {\n instance.unregisterHostTool('*', name);\n }\n };\n }, [instance, genericToolNamesKey]);\n\n useEffect(() => {\n if (!scope || !toolNamesKey) return;\n let cancelled = false;\n const names = splitHostToolNamesKey(toolNamesKey);\n\n void (async () => {\n try {\n await instance.registerHostToolsWithSync({\n scope,\n pageLabel: options.pageLabel,\n routePattern: options.routePattern,\n tools: bindPageToolsFromRef(toolsRef),\n });\n } catch (err) {\n if (!cancelled) {\n console.warn('[agent-chat] usePageAgent: registerHostToolsWithSync failed:', err);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n for (const name of names) {\n instance.unregisterHostTool(scope, name);\n }\n };\n }, [instance, scope, options.pageLabel, options.routePattern, toolNamesKey]);\n\n const handlersRef = useRef(options.handlers);\n handlersRef.current = options.handlers;\n const handlerNamesKey = options.handlers\n ? Object.keys(options.handlers).sort().join('\\0')\n : '';\n\n useEffect(() => {\n if (!scope || !handlerNamesKey) return;\n const names = splitHostToolNamesKey(handlerNamesKey);\n for (const name of names) {\n instance.registerHostTool(scope, name, (args) => handlersRef.current?.[name]?.(args));\n }\n return () => {\n for (const name of names) {\n instance.unregisterHostTool(scope, name);\n }\n };\n }, [instance, scope, handlerNamesKey]);\n\n useEffect(() => {\n if (!scope) return;\n\n return subscribePageAgentLifecycle(instance, {\n shouldDeliver: (payload) => shouldDeliverPageLifecycle(payload, scope),\n streamThrottleMs: options.streamThrottleMs,\n approvalScope: scope,\n onAwaitingApproval: (payload) => callbacksRef.current.onAwaitingApproval?.(payload),\n callbacks: {\n onStart: (ctx) => callbacksRef.current.onStart?.(ctx),\n onStream: (ctx) => callbacksRef.current.onStream?.(ctx),\n onComplete: (ctx) => callbacksRef.current.onComplete?.(ctx),\n onError: (ctx) => callbacksRef.current.onError?.(ctx),\n },\n });\n }, [instance, scope, options.streamThrottleMs]);\n}\n","import type { PageActionRowState } from '../../types';\n\n/** Skip React updates when row slots are unchanged (by `updatedAt` + visible flags). */\nexport function pageActionRowsShallowEqual(\n a: Record<string, PageActionRowState>,\n b: Record<string, PageActionRowState>,\n): boolean {\n const aKeys = Object.keys(a);\n if (aKeys.length !== Object.keys(b).length) {\n return false;\n }\n for (const key of aKeys) {\n const ar = a[key];\n const br = b[key];\n if (!br) return false;\n if (\n ar.updatedAt !== br.updatedAt ||\n ar.phase !== br.phase ||\n ar.error !== br.error ||\n ar.message !== br.message ||\n ar.progressLabel !== br.progressLabel ||\n ar.loading !== br.loading ||\n ar.disabled !== br.disabled ||\n ar.awaitingApproval !== br.awaitingApproval ||\n ar.runId !== br.runId ||\n ar.pageActionKey !== br.pageActionKey\n ) {\n return false;\n }\n }\n return true;\n}\n\nexport function buildPageActionRowsMap(\n rows: PageActionRowState[],\n): Record<string, PageActionRowState> {\n const next: Record<string, PageActionRowState> = {};\n for (const row of rows) {\n next[row.rowKey] = row;\n }\n return next;\n}\n","import { useCallback, useEffect, useRef, useState, type RefObject } from 'react';\nimport {\n buildPageActionRowsMap,\n pageActionRowsShallowEqual,\n} from '../core/page/page-action-row-sync';\nimport { createIdlePageActionRowState } from '../core/page/page-action-rows';\nimport { PAGE_ACTION_ACTION_SCOPE_ROW_KEY } from '../core/page/page-action-coordinator';\nimport { useAgentChatClient, useAgentChatStore } from './useAgentChatClient';\nimport type {\n AgentChatPageContext,\n OpenAutomationTaskCenterPayload,\n PageActionRolloutReason,\n PageActionRowState,\n PageBotInvokeInput,\n PageBotStreamResult,\n} from '../types';\nimport {\n toPageActionProcessView,\n type PageActionProcessView,\n} from '../core/page/page-action-process-view';\n\nexport interface UsePageActionsOptions {\n actionKey: string;\n /** Default page scope; merged into invoke pageContext when page is omitted. */\n page?: string;\n defaultInstruction?: string;\n context?: Record<string, unknown>;\n requireInstruction?: boolean;\n /** Reconcile active rows from server on mount (default true). */\n reconcileOnMount?: boolean;\n /**\n * Register action-level restore with {@link PageActionCoordinator} (list pages).\n * Default `false` — set `true` when the list should reconnect running tasks after refresh.\n */\n autoResume?: boolean;\n /**\n * When `true` (default), call `POST /page-action/rollout-check` for this hardcoded\n * actionKey. Catalog-driven UIs should set `false` (server already filtered).\n */\n checkRollout?: boolean;\n}\n\nexport interface UsePageActionsInvokeOverride {\n /** Required for list rows — typically `String(entity.id)`. */\n rowKey: string;\n instruction?: string;\n context?: Record<string, unknown>;\n clientActionId?: string;\n pageContext?: AgentChatPageContext;\n signal?: AbortSignal;\n onChunk?: (chunk: string) => void;\n launchAnchor?: HTMLElement | RefObject<HTMLElement | null> | null;\n /**\n * When `true` (default), check reuse-hint before invoke when the chat UI is mounted.\n * Set `false` to skip the popover and invoke immediately.\n */\n preferReuse?: boolean;\n}\n\nexport interface UsePageActionsResult {\n instruction: string;\n setInstruction: (value: string) => void;\n /** Reactive map of known row slots for this actionKey. */\n rows: Record<string, PageActionRowState>;\n /** Row state; returns idle defaults when the slot is unknown. */\n getRow: (rowKey: string) => PageActionRowState;\n /** Normalized process view for custom rendering (scheme B). */\n getProcessView: (rowKey: string) => PageActionProcessView;\n invoke: (override: UsePageActionsInvokeOverride) => Promise<PageBotStreamResult | undefined>;\n reconcile: () => Promise<PageActionRowState[]>;\n openTaskCenter: (opts?: OpenAutomationTaskCenterPayload) => void;\n clearRowError: (rowKey: string) => void;\n /**\n * Rollout gate for hardcoded buttons.\n * `null` = still checking / skipped; `false` → host should hide the trigger.\n */\n rolloutAllowed: boolean | null;\n rolloutReason: PageActionRolloutReason | null;\n /** `false` only when rollout-check explicitly denied. */\n visible: boolean;\n refreshRollout: () => Promise<void>;\n}\n\nfunction resolveLaunchAnchor(\n anchor: UsePageActionsInvokeOverride['launchAnchor'],\n): HTMLElement | null {\n if (!anchor) return null;\n if ('current' in anchor) return anchor.current;\n return anchor;\n}\n\n/**\n * List-page PageAction helper — one UI slot per `rowKey` (usually entity id).\n *\n * Prefer this over {@link usePageAction} when multiple rows share an `actionKey`.\n */\nexport function usePageActions(options: UsePageActionsOptions): UsePageActionsResult {\n const instance = useAgentChatClient();\n const isLoggedIn = useAgentChatStore((state) => state.isLoggedIn);\n const requireInstruction = options.requireInstruction !== false;\n const autoResume = options.autoResume === true;\n const checkRollout = options.checkRollout !== false;\n /** Coordinator owns restore when `autoResume`; avoid parallel reconcile on mount. */\n const reconcileOnMount =\n options.reconcileOnMount ?? (autoResume ? false : true);\n\n const [instruction, setInstruction] = useState(options.defaultInstruction ?? '');\n const [rows, setRows] = useState<Record<string, PageActionRowState>>({});\n const [rolloutAllowed, setRolloutAllowed] = useState<boolean | null>(\n checkRollout ? null : true,\n );\n const [rolloutReason, setRolloutReason] = useState<PageActionRolloutReason | null>(\n checkRollout ? null : 'open',\n );\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const seqRef = useRef(0);\n const rolloutAllowedRef = useRef(rolloutAllowed);\n rolloutAllowedRef.current = rolloutAllowed;\n\n const actionKey = options.actionKey.trim();\n\n const refreshRollout = useCallback(async () => {\n if (!checkRollout || !actionKey) {\n setRolloutAllowed(true);\n setRolloutReason('open');\n return;\n }\n if (!isLoggedIn) {\n setRolloutAllowed(null);\n setRolloutReason(null);\n return;\n }\n try {\n const items = await instance.checkPageActionRollout([actionKey]);\n const hit = items.find((item) => item.actionKey === actionKey) ?? items[0];\n if (!hit) {\n // Empty response: keep optimistic allow so a transient parse miss doesn't hide UI.\n setRolloutAllowed(true);\n setRolloutReason('open');\n return;\n }\n setRolloutAllowed(hit.allowed);\n setRolloutReason(hit.reason);\n } catch {\n // Network / auth blip — do not hide; invoke may still 403.\n setRolloutAllowed(true);\n setRolloutReason(null);\n }\n }, [actionKey, checkRollout, instance, isLoggedIn]);\n\n useEffect(() => {\n void refreshRollout();\n }, [refreshRollout]);\n\n const syncRowsFromClient = useCallback(() => {\n const list = instance.getPageActionRowsForActionKey(actionKey);\n const next = buildPageActionRowsMap(list);\n setRows((current) => (pageActionRowsShallowEqual(current, next) ? current : next));\n }, [actionKey, instance]);\n\n useEffect(() => {\n syncRowsFromClient();\n const offRow = instance.on('pageActionRowChanged', (payload) => {\n if (payload.state.actionKey !== actionKey) return;\n setRows((current) => {\n const prev = current[payload.rowKey];\n if (\n prev &&\n prev.updatedAt === payload.state.updatedAt &&\n prev.phase === payload.state.phase &&\n prev.message === payload.state.message &&\n prev.progressLabel === payload.state.progressLabel &&\n prev.error === payload.state.error &&\n prev.loading === payload.state.loading &&\n prev.disabled === payload.state.disabled &&\n prev.narrativeItems === payload.state.narrativeItems\n ) {\n return current;\n }\n return { ...current, [payload.rowKey]: payload.state };\n });\n });\n const offCenter = instance.on('automationTaskCenterChanged', syncRowsFromClient);\n const offApproval = instance.on('approvalExecutionCompleted', syncRowsFromClient);\n const offInbox = instance.on('approvalInboxChanged', syncRowsFromClient);\n return () => {\n offRow();\n offCenter();\n offApproval();\n offInbox();\n };\n }, [actionKey, instance, syncRowsFromClient]);\n\n useEffect(() => {\n if (!isLoggedIn) {\n setRows({});\n }\n }, [isLoggedIn]);\n\n useEffect(() => {\n if (!reconcileOnMount || !isLoggedIn || !actionKey) return;\n void instance.reconcileActivePageActions({ actionKey }).then(syncRowsFromClient).catch(() => {\n /* reconcile is best-effort */\n });\n }, [actionKey, instance, isLoggedIn, reconcileOnMount, syncRowsFromClient]);\n\n useEffect(() => {\n if (!autoResume || !actionKey) return;\n return instance.bindPageActionSlot({\n actionKey,\n rowKey: PAGE_ACTION_ACTION_SCOPE_ROW_KEY,\n pageContext: options.page ? { page: options.page } : null,\n ready: true,\n autoResume: true,\n autoApplyPending: false,\n });\n }, [actionKey, autoResume, instance, options.page]);\n\n const getRow = useCallback(\n (rowKey: string): PageActionRowState => {\n const key = rowKey.trim();\n if (!key) return createIdlePageActionRowState('', actionKey);\n return rows[key] ?? instance.getPageActionRowState(key) ?? createIdlePageActionRowState(key, actionKey);\n },\n [actionKey, instance, rows],\n );\n\n const reconcile = useCallback(async () => {\n const updated = await instance.reconcileActivePageActions({ actionKey });\n syncRowsFromClient();\n return updated;\n }, [actionKey, instance, syncRowsFromClient]);\n\n const openTaskCenter = useCallback(\n (opts?: OpenAutomationTaskCenterPayload) => {\n instance.openAutomationTaskCenter(opts);\n },\n [instance],\n );\n\n const clearRowError = useCallback(\n (rowKey: string) => {\n instance.clearPageActionRowError(rowKey);\n },\n [instance],\n );\n\n const invoke = useCallback(\n async (override: UsePageActionsInvokeOverride): Promise<PageBotStreamResult | undefined> => {\n const rowKey = override.rowKey.trim();\n if (!rowKey) return undefined;\n\n const resolvedInstruction = (override.instruction ?? instruction).trim();\n if (requireInstruction && !resolvedInstruction) return undefined;\n if (!actionKey) return undefined;\n if (rolloutAllowedRef.current === false) return undefined;\n\n seqRef.current += 1;\n const pageFromOpts = optionsRef.current.page?.trim();\n const pageContext: AgentChatPageContext | undefined = override.pageContext\n ? {\n ...override.pageContext,\n ...(pageFromOpts && !override.pageContext.page ? { page: pageFromOpts } : {}),\n }\n : pageFromOpts\n ? { page: pageFromOpts }\n : undefined;\n\n const baseContext = optionsRef.current.context;\n const extraContext = override.context;\n const body: PageBotInvokeInput = {\n actionKey,\n rowKey,\n clientActionId: override.clientActionId?.trim() || `page-action-${rowKey}-${seqRef.current}`,\n awaitStream: false,\n launchAnchor: resolveLaunchAnchor(override.launchAnchor),\n pageContext,\n };\n if (override.preferReuse === false) body.preferReuse = false;\n if (resolvedInstruction) body.instruction = resolvedInstruction;\n if (baseContext || extraContext) {\n body.context = { ...baseContext, ...extraContext };\n }\n if (override.signal) body.signal = override.signal;\n if (override.onChunk) body.onChunk = override.onChunk;\n\n try {\n const result = await instance.invokePageAction(body);\n syncRowsFromClient();\n return result;\n } catch (err) {\n syncRowsFromClient();\n throw err;\n }\n },\n [actionKey, instance, instruction, requireInstruction, syncRowsFromClient],\n );\n\n return {\n instruction,\n setInstruction,\n rows,\n getRow,\n getProcessView: (rowKey: string) => toPageActionProcessView(getRow(rowKey)),\n invoke,\n reconcile,\n openTaskCenter,\n clearRowError,\n rolloutAllowed,\n rolloutReason,\n visible: rolloutAllowed !== false,\n refreshRollout,\n };\n}\n","import { useEffect, useRef, useState, type RefObject } from 'react';\nimport {\n usePageActions,\n type UsePageActionsInvokeOverride,\n} from './usePageActions';\nimport { pageActionSlotKey } from '../core/page/page-action-coordinator';\nimport { matchesPendingPageActionApply } from '../core/page/pending-page-action-apply';\nimport { useAgentChatClient } from './useAgentChatClient';\nimport type {\n AgentChatPageContext,\n PageActionApplyPhase,\n PageActionPhase,\n PageActionRolloutReason,\n PendingPageActionApply,\n PageBotStreamResult,\n} from '../types';\nimport type { NarrativeItem } from '../core/page/page-action-workflow-progress';\nimport { toPageActionProcessView } from '../core/page/page-action-process-view';\nimport type { PageActionProcessView } from '../core/page/page-action-process-view';\n\nexport interface UsePageActionOptions {\n actionKey: string;\n pageContext?: AgentChatPageContext | null;\n /** Initial value for user-editable instruction. */\n defaultInstruction?: string;\n /** Merged into every invoke (overridable per call). */\n context?: Record<string, unknown>;\n /**\n * When `true` (default), `invoke` rejects empty instruction before calling the API.\n * Set `false` to let the server apply its default.\n */\n requireInstruction?: boolean;\n /** How long the `launched` phase lasts before returning to `idle` (ms). Kept for API compat. */\n launchedDurationMs?: number;\n /**\n * Whether this page slot is ready to receive apply / host_action replay.\n * Default `true`. Pass drawer/tab open state for pages that need a prepare step.\n */\n ready?: boolean;\n /**\n * After mount reconcile, attach SSE for active `running` tasks (refresh reconnect).\n * Default `true`.\n */\n autoResume?: boolean;\n /**\n * When pending「应用到页面」matches this slot and {@link ready}, auto `replayPageAction`.\n * Default `true`.\n */\n autoApplyPending?: boolean;\n /**\n * When `true` (default), `POST /page-action/rollout-check` for this hardcoded actionKey.\n * Set `false` when the button comes from catalog (already filtered).\n */\n checkRollout?: boolean;\n}\n\nexport interface UsePageActionInvokeOverride {\n instruction?: string;\n context?: Record<string, unknown>;\n clientActionId?: string;\n pageContext?: AgentChatPageContext;\n signal?: AbortSignal;\n onChunk?: (chunk: string) => void;\n launchAnchor?: HTMLElement | RefObject<HTMLElement | null> | null;\n /**\n * When `true` (default), check reuse-hint before invoke when the chat UI is mounted.\n * Set `false` to skip the popover and invoke immediately.\n */\n preferReuse?: boolean;\n /** Optional; defaults to `entity.id` or `'default'`. */\n rowKey?: string;\n}\n\nexport interface UsePageActionResult {\n instruction: string;\n setInstruction: (value: string) => void;\n phase: PageActionPhase;\n /** Server-issued de-duplication key from the latest invoke (or restored active run). */\n pageActionKey: string | null;\n lastRunId: number | null;\n /** Invoke Page Bot; uses current `instruction` unless overridden. */\n invoke: (override?: UsePageActionInvokeOverride) => Promise<PageBotStreamResult | undefined>;\n openTaskCenter: () => void;\n /** True while submitting, streaming, or an active non-approval run exists. */\n loading: boolean;\n /** True when invoke paused at inbox approval (`phase === 'awaiting_approval'`). */\n awaitingApproval: boolean;\n /** Recommended button `disabled` — {@link loading}, awaiting approval, or rollout denied. */\n disabled: boolean;\n /**\n * Rollout gate for hardcoded buttons (`null` while checking).\n * When `false`, hide the trigger (`visible === false`).\n */\n rolloutAllowed: boolean | null;\n rolloutReason: PageActionRolloutReason | null;\n /** `false` only when rollout-check explicitly denied. */\n visible: boolean;\n refreshRollout: () => Promise<void>;\n error: string | null;\n /** Soft tip (e.g. duplicate invoke); not a failure. */\n message: string | null;\n /**\n * SSE workflow loading copy for the trigger button (`page_workflow` / `stageKind`).\n * Prefer this over raw phase for loading copy.\n */\n progressLabel: string | null;\n /**\n * Accumulated storyline from `page_workflow.narrativeItems`.\n * Optional; do not replace {@link progressLabel}.\n */\n narrativeItems: NarrativeItem[];\n /**\n * Normalized execution-process snapshot for custom UI (scheme B).\n * Built-in process chrome is gated by `pageActionProcessUi` on AgentChat options.\n */\n process: PageActionProcessView;\n clearError: () => void;\n /** Whether a matching「应用到页面」pending intent exists for this slot. */\n pendingApply: boolean;\n /** Pending apply payload when matched; otherwise null. */\n pendingApplyIntent: PendingPageActionApply | null;\n /** Apply/replay lifecycle for this slot. */\n applyPhase: PageActionApplyPhase;\n}\n\nfunction defaultRowKey(pageContext?: AgentChatPageContext | null): string {\n const id = pageContext?.entity?.id;\n if (id != null && String(id).trim()) return String(id).trim();\n return 'default';\n}\n\n/**\n * Page Bot invoke helper for a **single** entity / page slot.\n *\n * Pair with {@link usePageAgent} on the same page for tool execution and lifecycle.\n * For list pages with one button per row, use {@link usePageActions} instead.\n *\n * Restore / apply is owned by {@link PageActionCoordinator} via slot bind — not hook effects.\n */\nexport function usePageAction(options: UsePageActionOptions): UsePageActionResult {\n const instance = useAgentChatClient();\n const ready = options.ready !== false;\n const autoResume = options.autoResume !== false;\n const autoApplyPending = options.autoApplyPending !== false;\n const actionKey = options.actionKey.trim();\n const rowKey = defaultRowKey(options.pageContext);\n const slotKey = pageActionSlotKey({ actionKey, rowKey });\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const multi = usePageActions({\n actionKey: options.actionKey,\n page: options.pageContext?.page,\n defaultInstruction: options.defaultInstruction,\n context: options.context,\n requireInstruction: options.requireInstruction,\n reconcileOnMount: false,\n checkRollout: options.checkRollout,\n });\n\n const row = multi.getRow(rowKey);\n const [pendingApplyIntent, setPendingApplyIntent] = useState<PendingPageActionApply | null>(\n null,\n );\n const [applyPhase, setApplyPhase] = useState<PageActionApplyPhase>('idle');\n\n useEffect(() => {\n const syncPending = () => {\n const pending = instance.getPendingPageActionApply();\n const matched = matchesPendingPageActionApply(pending, {\n actionKey,\n pageContext: optionsRef.current.pageContext,\n });\n setPendingApplyIntent(matched ? pending : null);\n };\n syncPending();\n return instance.on('pendingPageActionApplyChanged', syncPending);\n }, [actionKey, instance]);\n\n useEffect(() => {\n return instance.on('pageActionSlotApplyPhaseChanged', (payload) => {\n if (payload.slotKey !== slotKey) return;\n setApplyPhase(payload.phase);\n });\n }, [instance, slotKey]);\n\n useEffect(() => {\n const o = optionsRef.current;\n return instance.bindPageActionSlot({\n actionKey,\n rowKey,\n pageContext: o.pageContext,\n ready: o.ready !== false,\n autoResume: o.autoResume !== false,\n autoApplyPending: o.autoApplyPending !== false,\n });\n }, [actionKey, instance, rowKey]);\n\n useEffect(() => {\n instance.patchPageActionSlot(slotKey, {\n pageContext: options.pageContext,\n ready,\n autoResume,\n autoApplyPending,\n });\n }, [slotKey, instance, options.pageContext, ready, autoResume, autoApplyPending]);\n\n return {\n instruction: multi.instruction,\n setInstruction: multi.setInstruction,\n phase: row.phase,\n pageActionKey: row.pageActionKey,\n lastRunId: row.runId,\n invoke: (override) => {\n const resolvedRowKey = override?.rowKey?.trim() || rowKey;\n const pageContext = override?.pageContext ?? options.pageContext ?? undefined;\n const body: UsePageActionsInvokeOverride = {\n rowKey: resolvedRowKey,\n instruction: override?.instruction,\n context: override?.context,\n clientActionId: override?.clientActionId,\n pageContext: pageContext ?? undefined,\n signal: override?.signal,\n onChunk: override?.onChunk,\n launchAnchor: override?.launchAnchor,\n preferReuse: override?.preferReuse,\n };\n return multi.invoke(body);\n },\n openTaskCenter: () =>\n multi.openTaskCenter(row.runId != null ? { runId: row.runId } : undefined),\n loading: row.loading,\n awaitingApproval: row.awaitingApproval,\n disabled: row.disabled || multi.rolloutAllowed === false,\n rolloutAllowed: multi.rolloutAllowed,\n rolloutReason: multi.rolloutReason,\n visible: multi.visible,\n refreshRollout: multi.refreshRollout,\n error: row.error,\n message: row.message,\n progressLabel: row.progressLabel,\n narrativeItems: row.narrativeItems,\n process: toPageActionProcessView(row),\n clearError: () => multi.clearRowError(rowKey),\n pendingApply: pendingApplyIntent != null,\n pendingApplyIntent,\n applyPhase,\n };\n}\n","import {\n EXTENSION_BRIDGE_REQUEST_EVENT,\n EXTENSION_READY_EVENT,\n requireOmnixSdkAuthentication,\n} from './extension-contract';\n\nexport {\n EXTENSION_BRIDGE_REQUEST_EVENT,\n EXTENSION_READY_EVENT,\n} from './extension-contract';\nexport { isOmnixSdkAuthenticated, requireOmnixSdkAuthentication } from './extension-contract';\n\nexport type GofoTrackEvent = {\n title?: string;\n date?: string;\n time?: string;\n location?: string;\n};\n\nexport type GofoTrackResult = {\n /** 查询入参 waybillNo */\n waybillNo?: string;\n /** 关联单号(查 G1253-… 得到 GFUS…,或反过来) */\n relatedNo?: string;\n /** @deprecated 请用 relatedNo */\n trackingNumber?: string;\n};\n\nexport type GofoTrackResponse = {\n ok: true;\n waybillNo: string;\n result: GofoTrackResult | null;\n jobId: string;\n /** @deprecated 与 waybillNo 相同;请改用 waybillNo */\n trackNumber?: string;\n};\n\n/** GOFO 查询入参:只需 waybillNo(也可直接传字符串) */\nexport type GofoTrackInput =\n | string\n | {\n waybillNo?: string;\n reuseTab?: boolean;\n activateGofoTab?: boolean;\n pollTimeoutMs?: number;\n /** @deprecated 请用 waybillNo */\n trackNumber?: string;\n /** @deprecated 请用 waybillNo */\n warehouseNo?: string;\n };\n\nexport type OmnixExtensionGofoApi = {\n track(input: GofoTrackInput): Promise<GofoTrackResponse>;\n start(input: GofoTrackInput): Promise<{ jobId: string; pending: boolean }>;\n getJob(jobId: string): Promise<Record<string, unknown> | null>;\n waitForJob(jobId: string, timeoutMs?: number): Promise<Record<string, unknown>>;\n};\n\n/** 插件在页面注入的内部 API — 业务请使用 SDK 封装,勿直接依赖 window.OmnixExtension */\nexport type OmnixExtensionApi = {\n VERSION: string;\n isAvailable(): boolean;\n ping(): Promise<{ ok: boolean; version?: string }>;\n getStatus(): Promise<Record<string, unknown>>;\n syncPmsIntegration(): Promise<Record<string, unknown>>;\n gofo: OmnixExtensionGofoApi;\n};\n\ndeclare global {\n interface Window {\n OmnixExtension?: OmnixExtensionApi;\n }\n}\n\nfunction readExtensionApi(): OmnixExtensionApi | null {\n if (typeof window === 'undefined') {\n return null;\n }\n const ext = window.OmnixExtension;\n return ext && typeof ext.ping === 'function' ? ext : null;\n}\n\n/** 插件 content bridge 是否已注入(不要求已登录) */\nexport function isOmnixExtensionAvailable(): boolean {\n return readExtensionApi() != null;\n}\n\n/** 通知已注入的 content script 重新挂载 page bridge */\nexport function requestOmnixExtensionBridge(): void {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n window.dispatchEvent(new CustomEvent(EXTENSION_BRIDGE_REQUEST_EVENT));\n } catch {\n /* non-browser */\n }\n}\n\n/** 等待插件 bridge 就绪(不要求已登录) */\nexport function waitForOmnixExtensionAvailable(timeoutMs = 8_000): Promise<boolean> {\n if (isOmnixExtensionAvailable()) {\n return Promise.resolve(true);\n }\n if (typeof window === 'undefined') {\n return Promise.resolve(false);\n }\n\n requestOmnixExtensionBridge();\n\n return new Promise((resolve) => {\n let settled = false;\n const finish = (ok: boolean) => {\n if (settled) {\n return;\n }\n settled = true;\n window.removeEventListener(EXTENSION_READY_EVENT, onReady);\n clearInterval(pollTimer);\n clearTimeout(timer);\n resolve(ok);\n };\n\n const onReady = () => finish(isOmnixExtensionAvailable());\n window.addEventListener(EXTENSION_READY_EVENT, onReady);\n\n const pollTimer = window.setInterval(() => {\n requestOmnixExtensionBridge();\n if (isOmnixExtensionAvailable()) {\n finish(true);\n }\n }, 500);\n\n const timer = window.setTimeout(() => finish(isOmnixExtensionAvailable()), timeoutMs);\n });\n}\n\nasync function resolveExtensionApi(waitMs = 3_000): Promise<OmnixExtensionApi> {\n const ext = readExtensionApi() ?? (await waitForOmnixExtensionAvailable(waitMs)\n ? readExtensionApi()\n : null);\n if (!ext) {\n throw new Error(\n '未检测到 Omnix 浏览器插件。请安装 omnix-token-sync 并刷新页面。',\n );\n }\n return ext;\n}\n\nasync function invokeExtension<T>(\n fn: (ext: OmnixExtensionApi) => Promise<T>,\n options?: { waitMs?: number; requireAuth?: boolean },\n): Promise<T> {\n if (options?.requireAuth !== false) {\n requireOmnixSdkAuthentication();\n }\n const ext = await resolveExtensionApi(options?.waitMs);\n return fn(ext);\n}\n\n/** 探测插件是否在线(不要求登录) */\nexport async function pingOmnixExtension(options?: { waitMs?: number }) {\n return invokeExtension((ext) => ext.ping(), { ...options, requireAuth: false });\n}\n\n/** 读取插件状态(含 Omnix 登录镜像;不要求调用方已登录) */\nexport async function getOmnixExtensionStatus(options?: { waitMs?: number }) {\n return invokeExtension((ext) => ext.getStatus(), { ...options, requireAuth: false });\n}\n\n/** PMS · 同步 OMS 等业务 token(须 SDK 已登录) */\nexport async function syncOmnixPmsIntegration(options?: { waitMs?: number }) {\n return invokeExtension((ext) => ext.syncPmsIntegration(), options);\n}\n\n/** GOFO waybillNo 轨迹查询 — 不依赖 SDK 登录,有插件即可 */\nexport async function trackGofoWaybill(\n input: GofoTrackInput,\n options?: { waitMs?: number },\n): Promise<GofoTrackResponse> {\n return invokeExtension((ext) => ext.gofo.track(input), {\n ...options,\n requireAuth: false,\n });\n}\n\nexport async function startGofoTrack(\n input: GofoTrackInput,\n options?: { waitMs?: number },\n) {\n return invokeExtension((ext) => ext.gofo.start(input), {\n ...options,\n requireAuth: false,\n });\n}\n\nexport async function getGofoTrackJob(jobId: string, options?: { waitMs?: number }) {\n return invokeExtension((ext) => ext.gofo.getJob(jobId), {\n ...options,\n requireAuth: false,\n });\n}\n\nexport async function waitForGofoTrackJob(\n jobId: string,\n timeoutMs?: number,\n options?: { waitMs?: number },\n) {\n return invokeExtension((ext) => ext.gofo.waitForJob(jobId, timeoutMs), {\n ...options,\n requireAuth: false,\n });\n}\n\n/**\n * @deprecated 请使用 `isOmnixExtensionAvailable` / SDK 封装方法,勿直接访问插件 API。\n */\nexport function getOmnixExtension(): OmnixExtensionApi | null {\n return readExtensionApi();\n}\n\n/**\n * @deprecated 请使用 `waitForOmnixExtensionAvailable`。\n */\nexport function waitForOmnixExtension(timeoutMs = 8_000): Promise<OmnixExtensionApi | null> {\n return waitForOmnixExtensionAvailable(timeoutMs).then(() => readExtensionApi());\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport {\n EXTENSION_READY_EVENT,\n isOmnixExtensionAvailable,\n requestOmnixExtensionBridge,\n syncOmnixPmsIntegration,\n trackGofoWaybill,\n waitForOmnixExtensionAvailable,\n type GofoTrackInput,\n type GofoTrackResponse,\n} from '../core/extension/omnix-extension-client';\nimport { useAgentChatStore } from './useAgentChatClient';\n\nexport type UseOmnixExtensionOptions = {\n /** 等待插件 bridge 注入的最长时间 */\n waitMs?: number;\n};\n\nexport type UseOmnixExtensionResult = {\n /** 插件 bridge 是否已注入(`window.OmnixExtension`) */\n extensionAvailable: boolean;\n isLoggedIn: boolean;\n canUseGofo: boolean;\n canUsePms: boolean;\n /** @deprecated 请用 `canUseGofo` */\n canUse: boolean;\n trackGofoWaybill: (\n input: GofoTrackInput,\n options?: { waitMs?: number },\n ) => Promise<GofoTrackResponse>;\n syncPmsIntegration: (options?: { waitMs?: number }) => Promise<Record<string, unknown>>;\n};\n\n/**\n * React 侧接入 Omnix 浏览器插件(经 SDK)。\n * - 会检测 `extensionAvailable`(插件是否已注入 bridge)\n * - GOFO 不依赖登录;PMS 须 `isLoggedIn`\n */\nexport function useOmnixExtension(\n options: UseOmnixExtensionOptions = {},\n): UseOmnixExtensionResult {\n const waitMs = options.waitMs ?? 10_000;\n const isLoggedIn = useAgentChatStore((s) => s.isLoggedIn);\n const [extensionAvailable, setExtensionAvailable] = useState(() =>\n isOmnixExtensionAvailable(),\n );\n\n useEffect(() => {\n const sync = () => setExtensionAvailable(isOmnixExtensionAvailable());\n window.addEventListener(EXTENSION_READY_EVENT, sync);\n return () => window.removeEventListener(EXTENSION_READY_EVENT, sync);\n }, []);\n\n useEffect(() => {\n if (isOmnixExtensionAvailable()) {\n setExtensionAvailable(true);\n return;\n }\n let cancelled = false;\n requestOmnixExtensionBridge();\n void waitForOmnixExtensionAvailable(waitMs).then((ok) => {\n if (!cancelled) {\n setExtensionAvailable(ok);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [waitMs]);\n\n const track = useCallback(\n (input: GofoTrackInput, invokeOptions?: { waitMs?: number }) =>\n trackGofoWaybill(input, invokeOptions),\n [],\n );\n\n const syncPms = useCallback(\n (invokeOptions?: { waitMs?: number }) => syncOmnixPmsIntegration(invokeOptions),\n [],\n );\n\n const canUseGofo = extensionAvailable;\n const canUsePms = extensionAvailable && isLoggedIn;\n\n return {\n extensionAvailable,\n isLoggedIn,\n canUseGofo,\n canUsePms,\n canUse: canUseGofo,\n trackGofoWaybill: track,\n syncPmsIntegration: syncPms,\n };\n}\n","import { useCallback, useState } from 'react';\nimport type {\n AppToolCallableItem,\n AppToolInvokeInput,\n AppToolInvokeResult,\n} from '../core/services/app-tool.service';\nimport { getAppToolServerErrorCode } from '../core/services/app-tool.service';\nimport { useAgentChatClient, useAgentChatStore } from './useAgentChatClient';\n\nexport type UseAppToolResult = {\n isLoggedIn: boolean;\n loading: boolean;\n error: string | null;\n /** 最近一次 listCallable 结果 */\n items: AppToolCallableItem[];\n /** 最近一次 invoke 结果 */\n lastResult: AppToolInvokeResult | null;\n /** 网关门禁码,如 INTEGRATION_USER_TOKEN_REQUIRED */\n lastServerCode: string | null;\n listCallable: (signal?: AbortSignal) => Promise<AppToolCallableItem[]>;\n invoke: (input: AppToolInvokeInput) => Promise<AppToolInvokeResult>;\n clearError: () => void;\n};\n\n/**\n * C 端 Tool 代调 — `listCallableTools` / `invokeAppTool`(须 SDK 已登录)。\n *\n * `invoke` 内置登录挂起:未登录时自动等待,登录后继续执行。\n * @see agent-server/v2/docs/c-end-app-tool-invoke.md\n */\nexport function useAppTool(): UseAppToolResult {\n const instance = useAgentChatClient();\n const isLoggedIn = useAgentChatStore((s) => s.isLoggedIn);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [items, setItems] = useState<AppToolCallableItem[]>([]);\n const [lastResult, setLastResult] = useState<AppToolInvokeResult | null>(null);\n const [lastServerCode, setLastServerCode] = useState<string | null>(null);\n\n const listCallable = useCallback(\n async (signal?: AbortSignal) => {\n setLoading(true);\n setError(null);\n setLastServerCode(null);\n try {\n const { items: next } = await instance.listCallableTools(signal);\n setItems(next);\n return next;\n } catch (err) {\n setLastServerCode(getAppToolServerErrorCode(err));\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [instance],\n );\n\n const invoke = useCallback(\n async (input: AppToolInvokeInput) => {\n setError(null);\n setLastServerCode(null);\n try {\n const result = await instance.invokeAppTool(input);\n setLastResult(result);\n if (!result.ok) {\n setError(result.error ?? `下游失败 HTTP ${result.httpStatus ?? '?'}`);\n }\n return result;\n } catch (err) {\n setLastServerCode(getAppToolServerErrorCode(err));\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n throw err;\n }\n },\n [instance],\n );\n\n return {\n isLoggedIn,\n loading,\n error,\n items,\n lastResult,\n lastServerCode,\n listCallable,\n invoke,\n clearError: useCallback(() => {\n setError(null);\n setLastServerCode(null);\n }, []),\n };\n}\n","import { useEffect } from 'react';\nimport type { AgentChatInstance, ContextMentionDefinition } from '../types';\nimport { defineContextMention } from '../core/page/context-mention-define';\n\n/**\n * Register host @ mention catalog entries for the chat composer.\n * Pass a **memoized** `definitions` array (`useMemo`) when `resolve` closes over props/state.\n */\nexport function useContextMentions(\n instance: AgentChatInstance,\n definitions: ContextMentionDefinition[],\n): void {\n useEffect(() => {\n if (definitions.length === 0) {\n instance.clearContextMentions();\n return;\n }\n instance.registerContextMentions(\n definitions.map((def) => defineContextMention(def)),\n { replace: true },\n );\n return () => {\n instance.clearContextMentions();\n };\n }, [definitions, instance]);\n}\n","import { useEffect, useRef } from 'react';\nimport { useAgentChatClient } from './useAgentChatClient';\nimport {\n shouldDeliverAppLifecycle,\n subscribePageAgentLifecycle,\n type PageAgentLifecycleCallbacks,\n} from './page-agent-lifecycle';\nimport { hostToolNamesKey, splitHostToolNamesKey } from './host-agent-registration';\nimport type { AppHostToolDefinition } from '../types';\n\nexport interface UseAppAgentOptions extends PageAgentLifecycleCallbacks {\n /**\n * App-wide host tools. Syncs metadata to the server (scope `*`);\n * `handler` is optional — register execution on the business page via\n * {@link usePageAgent} `handlers`.\n */\n tools?: AppHostToolDefinition[];\n /**\n * Throttle `onStream` (ms). Tool handlers are never throttled.\n * @default 16\n */\n streamThrottleMs?: number;\n}\n\nfunction bindAppToolsFromRef(\n toolsRef: { current: AppHostToolDefinition[] | undefined },\n): AppHostToolDefinition[] {\n const tools = toolsRef.current;\n if (!tools?.length) return [];\n return tools.map((tool) => ({\n ...tool,\n ...(tool.handler\n ? {\n handler: (args: Record<string, unknown>) =>\n toolsRef.current?.find((t) => t.name === tool.name)?.handler?.(args),\n }\n : {}),\n ...(tool.onPreview\n ? {\n onPreview: (args: Record<string, unknown>) =>\n toolsRef.current?.find((t) => t.name === tool.name)?.onPreview?.(args),\n }\n : {}),\n }));\n}\n\n/**\n * App-root hook: register global host tools and listen for their lifecycle on **any** page.\n *\n * Typical App layout:\n *\n * ```tsx\n * useAppAgent({\n * tools: [{ name: 'refreshEntity', description: '...', argsSchema: {} }],\n * onComplete: () => analytics.track('refreshed'),\n * });\n *\n * // CampaignDetail.tsx — page executes app-declared tools\n * usePageAgent({\n * scope: 'campaign-detail',\n * handlers: { refreshEntity: ({ entityId }) => refetch(String(entityId)) },\n * });\n * ```\n *\n * `handler` in app `tools` is optional; page `handlers` run the business logic.\n * Lifecycle callbacks (`onComplete`, …) are listen-only.\n */\nexport function useAppAgent(options: UseAppAgentOptions): void {\n const instance = useAgentChatClient();\n const callbacksRef = useRef(options);\n callbacksRef.current = options;\n\n const toolsRef = useRef(options.tools);\n toolsRef.current = options.tools;\n const toolNamesKey = hostToolNamesKey(options.tools);\n\n useEffect(() => {\n if (!toolNamesKey) return;\n let cancelled = false;\n const names = splitHostToolNamesKey(toolNamesKey);\n\n void (async () => {\n try {\n await instance.registerHostToolsWithSync({\n appLevel: true,\n tools: bindAppToolsFromRef(toolsRef),\n });\n } catch (err) {\n if (!cancelled) {\n console.warn('[agent-chat] useAppAgent: registerHostToolsWithSync failed:', err);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n for (const name of names) {\n const tool = toolsRef.current?.find((t) => t.name === name);\n if (tool?.handler) {\n instance.unregisterHostTool('*', name);\n } else {\n instance.undeclareHostTool('*', name);\n }\n }\n };\n }, [instance, toolNamesKey]);\n\n useEffect(() => {\n return subscribePageAgentLifecycle(instance, {\n shouldDeliver: shouldDeliverAppLifecycle,\n streamThrottleMs: options.streamThrottleMs,\n callbacks: {\n onStart: (ctx) => callbacksRef.current.onStart?.(ctx),\n onStream: (ctx) => callbacksRef.current.onStream?.(ctx),\n onComplete: (ctx) => callbacksRef.current.onComplete?.(ctx),\n onError: (ctx) => callbacksRef.current.onError?.(ctx),\n },\n });\n }, [instance, options.streamThrottleMs]);\n}\n"],"x_google_ignoreList":[6,7,8,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,47],"mappings":"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"}
|