@guideai/react-native 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"useOnboarding-DhVtf0U2.js","sources":["../../core/dist/index.mjs","../src/transport/rn-transport.ts","../src/platform/rn-platform.ts","../src/auth/host-auth.ts","../src/screen/screen-registry.ts","../src/tools/rn-tool-registry.ts","../src/runtime.ts","../src/api/rn-api-client.ts","../src/react/context.ts","../src/react/navigation.ts","../src/debug/full-trace.ts","../src/setup.ts","../src/react/useGuideAI.ts","../src/react/useOnboarding.ts"],"sourcesContent":["import { gcm } from \"@noble/ciphers/aes.js\";\nimport { hkdf } from \"@noble/hashes/hkdf.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { randomBytes } from \"@noble/ciphers/utils.js\";\nfunction createId() {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `conversation_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;\n}\nfunction createConversationState(sessionId = createId(), interactionMode = \"guidance\") {\n return {\n sessionId,\n revision: 0,\n modeRevision: 0,\n interactionMode,\n inputModality: null,\n turnState: \"idle\",\n activeTurnId: null,\n activeResponseId: null,\n activeTools: {},\n guidance: {\n status: \"idle\",\n guideId: null,\n stepId: null,\n stepIndex: null,\n totalSteps: null\n },\n interruptionEpoch: 0,\n lastInterruptionReason: null,\n lastError: null\n };\n}\nfunction rejected(state, event, rejectionReason) {\n return {\n previous: state,\n state,\n event,\n effects: [],\n accepted: false,\n rejectionReason\n };\n}\nfunction accepted(previous, event, patch, effects = []) {\n return {\n previous,\n state: {\n ...previous,\n ...patch,\n revision: previous.revision + 1\n },\n event,\n effects,\n accepted: true\n };\n}\nfunction stateAfterForegroundWork(state) {\n if (Object.keys(state.activeTools).length > 0) return \"executing\";\n if (state.guidance.status === \"paused\") return \"paused\";\n return \"idle\";\n}\nfunction interruptionEffects(state, reason, interruptionEpoch) {\n const effects = [];\n if (state.activeResponseId) {\n effects.push({\n type: \"response.cancel\",\n responseId: state.activeResponseId,\n reason\n });\n }\n if (state.turnState === \"speaking\" || state.activeResponseId) {\n effects.push({ type: \"audio.stop\", interruptionEpoch });\n }\n return effects;\n}\nfunction reduceConversation(state, event) {\n switch (event.type) {\n case \"mode.changed\": {\n if (event.mode === state.interactionMode) {\n return rejected(state, event, \"mode_already_active\");\n }\n const interrupted = !!state.activeResponseId || state.turnState === \"speaking\";\n const interruptionEpoch = state.interruptionEpoch + (interrupted ? 1 : 0);\n const effects = interruptionEffects(state, \"mode_changed\", interruptionEpoch);\n let guidance = state.guidance;\n if (event.mode === \"assistant\" && guidance.status === \"active\" && guidance.guideId) {\n const guideId = guidance.guideId;\n guidance = { ...guidance, status: \"paused\" };\n effects.push({\n type: \"guide.pause\",\n guideId,\n reason: \"mode_changed\"\n });\n }\n const foregroundState = stateAfterForegroundWork({\n ...state,\n guidance\n });\n return accepted(state, event, {\n interactionMode: event.mode,\n modeRevision: state.modeRevision + 1,\n activeResponseId: null,\n activeTurnId: null,\n guidance,\n turnState: foregroundState,\n interruptionEpoch,\n lastInterruptionReason: interrupted ? \"mode_changed\" : state.lastInterruptionReason\n }, effects);\n }\n case \"input.started\": {\n const interrupted = !!state.activeResponseId || state.turnState === \"speaking\";\n const interruptionEpoch = state.interruptionEpoch + (interrupted ? 1 : 0);\n return accepted(state, event, {\n inputModality: event.modality,\n turnState: \"listening\",\n activeTurnId: event.turnId,\n activeResponseId: null,\n interruptionEpoch,\n lastInterruptionReason: interrupted ? \"barge_in\" : state.lastInterruptionReason,\n lastError: null\n }, interruptionEffects(state, \"barge_in\", interruptionEpoch));\n }\n case \"input.committed\":\n if (event.turnId !== state.activeTurnId) {\n return rejected(state, event, \"stale_turn\");\n }\n return accepted(state, event, { turnState: \"thinking\" });\n case \"response.started\":\n if (event.modeRevision !== state.modeRevision) {\n return rejected(state, event, \"stale_mode_revision\");\n }\n if (event.turnId !== state.activeTurnId) {\n return rejected(state, event, \"stale_turn\");\n }\n return accepted(state, event, {\n activeResponseId: event.responseId,\n turnState: \"thinking\",\n lastError: null\n });\n case \"response.speech.started\":\n if (event.turnId !== state.activeTurnId || event.responseId !== state.activeResponseId) {\n return rejected(state, event, \"stale_response\");\n }\n return accepted(state, event, { turnState: \"speaking\" });\n case \"response.completed\":\n if (event.turnId !== state.activeTurnId || event.responseId !== state.activeResponseId) {\n return rejected(state, event, \"stale_response\");\n }\n return accepted(state, event, {\n activeResponseId: null,\n activeTurnId: null,\n turnState: stateAfterForegroundWork(state)\n });\n case \"response.failed\":\n if (event.turnId !== state.activeTurnId || event.responseId !== state.activeResponseId) {\n return rejected(state, event, \"stale_response\");\n }\n return accepted(state, event, {\n activeResponseId: null,\n activeTurnId: null,\n turnState: stateAfterForegroundWork(state),\n lastError: event.error\n });\n case \"response.interrupted\": {\n if (!state.activeResponseId && state.turnState !== \"speaking\") {\n return rejected(state, event, \"no_active_response\");\n }\n const interruptionEpoch = state.interruptionEpoch + 1;\n return accepted(state, event, {\n activeResponseId: null,\n activeTurnId: null,\n turnState: stateAfterForegroundWork(state),\n interruptionEpoch,\n lastInterruptionReason: event.reason\n }, interruptionEffects(state, event.reason, interruptionEpoch));\n }\n case \"guide.started\":\n return accepted(state, event, {\n guidance: {\n status: event.status ?? \"active\",\n guideId: event.guideId,\n stepId: null,\n stepIndex: null,\n totalSteps: event.totalSteps ?? null\n }\n });\n case \"guide.step.changed\":\n if (event.guideId !== state.guidance.guideId) {\n return rejected(state, event, \"stale_guide\");\n }\n return accepted(state, event, {\n guidance: {\n ...state.guidance,\n status: \"active\",\n stepId: event.stepId ?? null,\n stepIndex: event.stepIndex,\n totalSteps: event.totalSteps ?? state.guidance.totalSteps\n }\n });\n case \"guide.paused\":\n if (event.guideId !== state.guidance.guideId) {\n return rejected(state, event, \"stale_guide\");\n }\n return accepted(state, event, {\n guidance: { ...state.guidance, status: \"paused\" },\n turnState: Object.keys(state.activeTools).length > 0 ? \"executing\" : \"paused\"\n }, [{\n type: \"guide.pause\",\n guideId: event.guideId,\n reason: event.reason ?? \"user\"\n }]);\n case \"guide.resumed\":\n if (event.guideId !== state.guidance.guideId) {\n return rejected(state, event, \"stale_guide\");\n }\n return accepted(state, event, {\n guidance: { ...state.guidance, status: \"active\" },\n turnState: Object.keys(state.activeTools).length > 0 ? \"executing\" : \"idle\"\n }, [{ type: \"guide.resume\", guideId: event.guideId }]);\n case \"guide.completed\":\n if (event.guideId !== state.guidance.guideId) {\n return rejected(state, event, \"stale_guide\");\n }\n return accepted(state, event, {\n guidance: {\n ...state.guidance,\n status: \"completed\"\n },\n turnState: Object.keys(state.activeTools).length > 0 ? \"executing\" : \"idle\"\n });\n case \"guide.cancelled\":\n if (event.guideId !== state.guidance.guideId) {\n return rejected(state, event, \"stale_guide\");\n }\n return accepted(state, event, {\n guidance: { ...state.guidance, status: \"cancelled\" },\n turnState: Object.keys(state.activeTools).length > 0 ? \"executing\" : \"idle\"\n }, [{\n type: \"guide.stop\",\n guideId: event.guideId,\n reason: event.reason ?? \"user\"\n }]);\n case \"tool.started\":\n return accepted(state, event, {\n activeTools: {\n ...state.activeTools,\n [event.runId]: {\n runId: event.runId,\n toolName: event.toolName,\n consequential: event.consequential ?? false\n }\n },\n turnState: \"executing\"\n });\n case \"tool.completed\":\n case \"tool.failed\": {\n if (!state.activeTools[event.runId]) {\n return rejected(state, event, \"stale_tool_run\");\n }\n const activeTools = { ...state.activeTools };\n delete activeTools[event.runId];\n return accepted(state, event, {\n activeTools,\n turnState: Object.keys(activeTools).length > 0 ? \"executing\" : state.activeResponseId ? state.turnState : state.guidance.status === \"paused\" ? \"paused\" : \"idle\",\n lastError: event.type === \"tool.failed\" ? event.error : state.lastError\n });\n }\n case \"session.reset\":\n return accepted(state, event, {\n ...createConversationState(event.sessionId ?? createId(), state.interactionMode),\n revision: state.revision,\n modeRevision: state.modeRevision\n });\n }\n}\nfunction defaultIdFactory() {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `turn_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;\n}\nclass ConversationOrchestrator {\n constructor(options = {}) {\n this.listeners = /* @__PURE__ */ new Set();\n this.effectListeners = /* @__PURE__ */ new Set();\n this.idFactory = options.idFactory ?? defaultIdFactory;\n this.state = createConversationState(\n options.sessionId ?? this.idFactory(),\n options.initialMode ?? \"guidance\"\n );\n if (options.onEffect) this.effectListeners.add(options.onEffect);\n }\n snapshot() {\n return {\n ...this.state,\n activeTools: { ...this.state.activeTools },\n guidance: { ...this.state.guidance }\n };\n }\n subscribe(listener) {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n subscribeEffects(listener) {\n this.effectListeners.add(listener);\n return () => this.effectListeners.delete(listener);\n }\n dispatch(event) {\n const transition = reduceConversation(this.state, event);\n if (!transition.accepted) return transition;\n this.state = transition.state;\n for (const listener of this.listeners) listener(transition);\n for (const effect of transition.effects) {\n for (const listener of this.effectListeners) listener(effect);\n }\n return transition;\n }\n changeMode(mode, source) {\n return this.dispatch({ type: \"mode.changed\", mode, source });\n }\n beginInput(modality, turnId = this.idFactory()) {\n this.dispatch({ type: \"input.started\", turnId, modality });\n return turnId;\n }\n commitInput(turnId, text) {\n return this.dispatch({ type: \"input.committed\", turnId, text });\n }\n startResponse(turnId, responseId = this.idFactory()) {\n this.dispatch({\n type: \"response.started\",\n turnId,\n responseId,\n modeRevision: this.state.modeRevision\n });\n return responseId;\n }\n startSpeech(turnId, responseId) {\n return this.dispatch({ type: \"response.speech.started\", turnId, responseId });\n }\n completeResponse(turnId, responseId) {\n return this.dispatch({ type: \"response.completed\", turnId, responseId });\n }\n failResponse(turnId, responseId, error) {\n return this.dispatch({ type: \"response.failed\", turnId, responseId, error });\n }\n interrupt(reason = \"user_interrupt\") {\n return this.dispatch({ type: \"response.interrupted\", reason });\n }\n}\nconst DRAWING_URL = /^https:\\/\\/res\\.cloudinary\\.com\\/[\\w-]+\\/image\\/upload\\//;\nconst IMAGE_BLOCK = /```image[ \\t]*\\n([\\s\\S]*?)```/g;\nfunction headlessImages(text) {\n const images = [];\n const out = (text || \"\").replace(IMAGE_BLOCK, (_block, raw) => {\n let data;\n try {\n data = JSON.parse(raw.trim());\n } catch {\n return \"\";\n }\n if (typeof data.url !== \"string\" || !DRAWING_URL.test(data.url)) return \"\";\n const image = {\n url: data.url,\n svg: typeof data.svg === \"string\" && DRAWING_URL.test(data.svg) ? data.svg : null,\n alt: typeof data.alt === \"string\" ? data.alt.slice(0, 200) : \"\",\n width: Math.round(Number(data.width)) || 1600,\n height: Math.round(Number(data.height)) || 900\n };\n images.push(image);\n return `![${image.alt.replace(/[[\\]]/g, \"\")}](${image.url})`;\n });\n return { text: out, images };\n}\nfunction toHeadlessReply(msg) {\n const { text, images } = msg.images ? { text: msg.text, images: msg.images } : headlessImages(msg.text);\n return {\n text,\n intent: msg.intent ?? null,\n intentReason: msg.intentReason ?? null,\n steps: msg.guideSteps ?? null,\n title: msg.guideTitle ?? null,\n demo: msg.demo ?? null,\n navigation: msg.navigation ?? null,\n escalation: msg.escalation ?? null,\n toolsUsed: msg.toolCalls ?? [],\n pendingAction: msg.confirmationNeeded ? msg.pendingToolCall ?? null : null,\n images,\n raw: msg\n };\n}\nfunction forHost(msg) {\n if (!msg.text || !msg.text.includes(\"```image\")) return msg;\n const { text, images } = headlessImages(msg.text);\n return { ...msg, text, images };\n}\nclass HeadlessChatView {\n constructor() {\n this.listeners = /* @__PURE__ */ new Map();\n this.messages = [];\n this.open = false;\n this.mode = \"guidance\";\n this.loading = false;\n this.loadingStatus = null;\n this.streaming = false;\n this.streamBuffer = \"\";\n this.callbacks = null;\n }\n // ── Event plumbing ─────────────────────────────────────────\n on(event, listener) {\n let set = this.listeners.get(event);\n if (!set) {\n set = /* @__PURE__ */ new Set();\n this.listeners.set(event, set);\n }\n const erased = listener;\n set.add(erased);\n return () => {\n set == null ? void 0 : set.delete(erased);\n };\n }\n off(event, listener) {\n var _a;\n (_a = this.listeners.get(event)) == null ? void 0 : _a.delete(listener);\n }\n /**\n * Announce something on this feed from outside the chat itself — the\n * conversation opener and live support report here so a host has one feed.\n */\n notify(event, payload) {\n this.emit(event, payload);\n }\n /** Whether anything is listening for *event*. */\n hasListeners(event) {\n var _a;\n return (((_a = this.listeners.get(event)) == null ? void 0 : _a.size) ?? 0) > 0;\n }\n emit(event, payload) {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const listener of Array.from(set)) {\n try {\n listener(payload);\n } catch (err) {\n console.error(`[GuideAI] chat view listener for \"${event}\" threw`, err);\n }\n }\n }\n // ── Host-side accessors ────────────────────────────────────\n /** The transcript so far, for hosts that mount after the conversation started. */\n getMessages() {\n return [...this.messages];\n }\n /** Text accumulated by the in-flight streaming message. */\n getStreamingText() {\n return this.streamBuffer;\n }\n getMode() {\n return this.mode;\n }\n isLoading() {\n return this.loading;\n }\n /**\n * Resolves with the next assistant message the brain produces.\n *\n * Covers both delivery paths: streamed answers finalize into a message,\n * and non-streamed answers are added directly.\n */\n nextAssistantMessage(timeoutMs = 6e4) {\n return new Promise((resolve, reject) => {\n let timer = null;\n const stop = this.on(\"message\", (msg) => {\n if (msg.role !== \"assistant\") return;\n if (timer) clearTimeout(timer);\n stop();\n resolve(msg);\n });\n if (timeoutMs > 0) {\n timer = setTimeout(() => {\n stop();\n reject(new Error(`GuideAI: no reply within ${timeoutMs}ms`));\n }, timeoutMs);\n }\n });\n }\n /**\n * The callbacks the brain registered. A host wires its own send button\n * and walkthrough button to these.\n */\n getCallbacks() {\n return this.callbacks;\n }\n // ── Lifecycle ──────────────────────────────────────────────\n render(callbacks, _options) {\n this.callbacks = callbacks;\n this.open = true;\n }\n remove() {\n this.open = false;\n this.callbacks = null;\n this.emit(\"closed\", void 0);\n }\n isOpen() {\n return this.open;\n }\n // ── Messages ───────────────────────────────────────────────\n addMessage(raw) {\n var _a;\n const msg = forHost(raw);\n this.messages.push(msg);\n this.emit(\"message\", msg);\n if ((_a = msg.escalation) == null ? void 0 : _a.offered) this.emit(\"supportOffered\", void 0);\n if (msg.confirmationNeeded && msg.pendingToolCall) {\n this.emit(\"confirmationNeeded\", msg.pendingToolCall);\n }\n if (msg.demo) this.emit(\"demo\", msg.demo);\n }\n loadHistory(messages) {\n this.messages = [...messages];\n this.emit(\"history\", this.getMessages());\n }\n clearMessages() {\n this.messages = [];\n this.streamBuffer = \"\";\n this.emit(\"cleared\", void 0);\n }\n addWalkthroughCompleteMessage() {\n this.emit(\"walkthroughComplete\", void 0);\n }\n settleConfirmation(answer) {\n this.emit(\"confirmation:settled\", { answer });\n }\n // ── Intro card ─────────────────────────────────────────────\n showIntroCard(request) {\n this.emit(\"intro:requested\", request);\n }\n hideIntroCard() {\n this.emit(\"intro:hidden\", void 0);\n }\n // ── Streaming ──────────────────────────────────────────────\n beginStreamingMessage() {\n this.streamBuffer = \"\";\n this.emit(\"stream:start\", void 0);\n }\n appendStreamDelta(delta) {\n this.streamBuffer += delta;\n this.emit(\"stream:delta\", { delta, text: this.streamBuffer });\n }\n finalizeStreamingMessage(raw) {\n const msg = forHost(raw);\n this.streamBuffer = \"\";\n this.messages.push(msg);\n this.emit(\"stream:end\", msg);\n this.emit(\"message\", msg);\n }\n setStreaming(streaming) {\n this.streaming = streaming;\n this.emit(\"streaming\", { streaming });\n }\n // ── Busy state ─────────────────────────────────────────────\n setLoading(loading) {\n this.loading = loading;\n if (!loading) this.loadingStatus = null;\n this.emit(\"loading\", { loading, status: this.loadingStatus });\n }\n setLoadingStatus(status) {\n this.loadingStatus = status;\n this.emit(\"loading\", { loading: this.loading, status });\n }\n // ── Mode ───────────────────────────────────────────────────\n setMode(mode) {\n this.mode = mode;\n this.emit(\"mode\", { mode });\n }\n showModeBanner() {\n this.emit(\"modeHint\", { kind: \"banner\", mode: this.mode });\n }\n showModeSwitch() {\n this.emit(\"modeHint\", { kind: \"switch\", mode: this.mode });\n }\n showModePill() {\n this.emit(\"modeHint\", { kind: \"pill\", mode: this.mode });\n }\n showModeIntro() {\n this.emit(\"modeHint\", { kind: \"intro\", mode: this.mode });\n }\n // ── Tool calls ─────────────────────────────────────────────\n addToolCallCard(tool, description) {\n this.emit(\"tool:start\", { tool, description });\n }\n updateToolCallCard(tool, success, summary) {\n this.emit(\"tool:end\", { tool, success, summary });\n }\n renderPlan(plan) {\n this.emit(\"plan:start\", { plan });\n }\n markPlanStep(tool, state) {\n this.emit(\"plan:step\", { tool, state });\n }\n // ── Walkthroughs & demos ───────────────────────────────────\n setWalkthroughButtonState(messageId, state, errorMessage) {\n const msg = this.messages.find((m) => m.id === messageId);\n if (msg) {\n msg.walkthroughBuildState = state;\n msg.walkthroughBuildError = errorMessage;\n }\n this.emit(\"walkthroughState\", { messageId, state, error: errorMessage });\n }\n /**\n * Announces the demo and reports it as handled. The host renders the\n * player from the `demo` event; the brain only needs to know the demo\n * was surfaced rather than needing a text fallback.\n */\n playDemo(demo) {\n this.emit(\"demo\", demo);\n return true;\n }\n async controlActiveMedia(command, demo) {\n if (command === \"play\" && demo) return this.playDemo(demo);\n return false;\n }\n // ── Input ──────────────────────────────────────────────────\n setInputValue(value) {\n this.emit(\"inputValue\", { value });\n }\n // ── Voice ──────────────────────────────────────────────────\n showVoiceButton() {\n this.emit(\"voice:available\", { available: true });\n }\n hideVoiceButton() {\n this.emit(\"voice:available\", { available: false });\n }\n setVoiceStatus(status, message) {\n this.emit(\"voice:status\", { status, message });\n }\n setLiveVoiceTranscript(event) {\n this.emit(\"voice:transcript\", event);\n }\n /**\n * Ask the host to pick a voice language. A host that does not listen keeps\n * `current`; one that does answers through `choose`. Unanswered after two\n * minutes, `current` stands, so a voice start is never stuck on a picker.\n */\n async requestVoiceLanguage(options, current = null) {\n if (!this.hasListeners(\"voice:languageRequested\")) return current;\n return new Promise((resolve) => {\n let settled = false;\n const choose = (language) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(language ?? current);\n };\n const timer = setTimeout(() => choose(null), 12e4);\n this.emit(\"voice:languageRequested\", { options, current, choose });\n });\n }\n setVoiceLanguage(language) {\n this.emit(\"voice:languageChanged\", { language });\n }\n showBatchVoiceButton() {\n this.emit(\"batchVoice:available\", { available: true });\n }\n hideBatchVoiceButton() {\n this.emit(\"batchVoice:available\", { available: false });\n }\n setBatchVoiceStatus(status, message) {\n this.emit(\"batchVoice:status\", { status, message });\n }\n setVoiceReplyState(enabled) {\n this.emit(\"voiceReply\", { enabled });\n }\n // ── Support handoff ────────────────────────────────────────\n showSupportButton() {\n this.emit(\"supportOffered\", void 0);\n this.emit(\"support:available\", { available: true });\n }\n hideSupportButton() {\n this.emit(\"support:available\", { available: false });\n }\n // Expand/collapse is a built-in-UI concern; in headless mode the host owns\n // layout, so these are no-ops.\n expand() {\n }\n collapse() {\n }\n toggleExpand() {\n }\n isExpandedSidebar() {\n return false;\n }\n}\nconst NAME_PREFIXES = [\n /^api[\\s_-]*v?\\d*[\\s_-]*/i,\n /^(get|fetch|list|read|retrieve|show|query|search|find|lookup|look up)[\\s_-]+/i,\n /^(create|add|post|new|insert|register)[\\s_-]+/i,\n /^(update|patch|put|edit|modify|set)[\\s_-]+/i,\n /^(delete|remove|destroy|archive)[\\s_-]+/i,\n /^(check|verify|validate|count|send|export|download)[\\s_-]+/i\n];\nconst METHOD_VERBS = {\n GET: \"Retrieving\",\n POST: \"Creating\",\n PUT: \"Updating\",\n PATCH: \"Updating\",\n DELETE: \"Removing\"\n};\nconst NAME_VERBS = [\n { pattern: /^(search|find|lookup|look_up|query)/i, verb: \"Looking up\" },\n { pattern: /^(list|get_all|getall)/i, verb: \"Retrieving\" },\n { pattern: /^(count|stats|statistics|summary|analytics|metrics|usage|report)/i, verb: \"Gathering\" },\n { pattern: /^(check|verify|validate|status)/i, verb: \"Checking\" },\n { pattern: /^(create|add|new|insert|register)/i, verb: \"Creating\" },\n { pattern: /^(update|edit|modify|set|patch)/i, verb: \"Updating\" },\n { pattern: /^(delete|remove|destroy|archive)/i, verb: \"Removing\" },\n { pattern: /^(send|email|notify|invite)/i, verb: \"Sending\" },\n { pattern: /^(export|download)/i, verb: \"Preparing\" }\n];\nconst SELF_DESCRIBING = /\\b(information|details|data|summary|stats|statistics|activity|history|settings|status|usage|overview|report|list|metrics|analytics|breakdown)\\b/i;\nfunction humanizeName(name) {\n let out = name.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\").replace(/[_\\-/]+/g, \" \").replace(/\\bapi\\s*v?\\d+\\b/gi, \" \").replace(/\\s+(get|post|put|patch|delete)$/i, \"\").replace(/\\s+/g, \" \").trim().toLowerCase();\n for (const prefix of NAME_PREFIXES) {\n out = out.replace(prefix, \"\");\n }\n const kept = [];\n for (const word of out.trim().split(\" \").reverse()) {\n const stem = word.replace(/s$/, \"\");\n if (!word || stem === \"id\" || stem === \"uuid\") continue;\n if (kept.some((k) => k.replace(/s$/, \"\") === stem)) continue;\n kept.push(word);\n }\n return kept.reverse().join(\" \");\n}\nfunction pickVerb(toolName, noun, method) {\n const bare = toolName.replace(NAME_PREFIXES[0], \"\");\n for (const { pattern, verb } of NAME_VERBS) {\n if (pattern.test(bare)) return verb;\n }\n for (const { pattern, verb } of NAME_VERBS) {\n if (pattern.test(noun)) return verb;\n }\n return METHOD_VERBS[method.toUpperCase()] || \"Retrieving\";\n}\nfunction describeToolCall(toolCall) {\n const supplied = (toolCall.label || \"\").trim();\n if (supplied) return supplied;\n let noun = humanizeName(toolCall.tool || \"\");\n if (!noun) return \"Retrieving information\";\n const verb = pickVerb(toolCall.tool || \"\", noun, toolCall.method || \"GET\");\n const ownScope = /\\s+(me|self|current|mine)$/.test(noun);\n if (ownScope) noun = `your ${noun.replace(/\\s+(me|self|current|mine)$/, \"\")}`;\n if (SELF_DESCRIBING.test(noun) || ownScope) return `${verb} ${noun}`;\n const singular = noun.replace(new RegExp(\"([a-z])(?<!s|u|i)s$\"), \"$1\");\n return `${verb} ${singular} information`;\n}\nfunction describeToolBatch(toolCalls) {\n if (toolCalls.length === 0) return \"Working on it\";\n if (toolCalls.length === 1) return describeToolCall(toolCalls[0]);\n return `Gathering information from ${toolCalls.length} sources`;\n}\nclass EmptyToolRegistry {\n definitions() {\n return [];\n }\n copilotDefinitions() {\n return [];\n }\n canExecute() {\n return false;\n }\n canExecuteCall() {\n return false;\n }\n execute() {\n return Promise.resolve({\n success: false,\n error: \"No client tool registry is configured for this platform.\",\n error_type: \"tool_unavailable\"\n });\n }\n executeBatch(toolCalls) {\n return Promise.all(toolCalls.map(() => this.execute()));\n }\n}\nclass MemoryKVStore {\n constructor() {\n this.entries = /* @__PURE__ */ new Map();\n }\n getItem(key) {\n const value = this.entries.get(key);\n return value === void 0 ? null : value;\n }\n setItem(key, value) {\n this.entries.set(key, String(value));\n }\n removeItem(key) {\n this.entries.delete(key);\n }\n /** Test convenience — not part of the KVStore contract. */\n clear() {\n this.entries.clear();\n }\n}\nconst ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst URL_SAFE = `${ALPHABET}-_`;\nfunction toBase64Url(bytes) {\n let out = \"\";\n const fullGroups = Math.floor(bytes.length / 3) * 3;\n for (let i = 0; i < fullGroups; i += 3) {\n const chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];\n out += URL_SAFE[chunk >> 18 & 63] + URL_SAFE[chunk >> 12 & 63] + URL_SAFE[chunk >> 6 & 63] + URL_SAFE[chunk & 63];\n }\n const remaining = bytes.length - fullGroups;\n if (remaining === 1) {\n const chunk = bytes[fullGroups] << 16;\n out += URL_SAFE[chunk >> 18 & 63] + URL_SAFE[chunk >> 12 & 63];\n } else if (remaining === 2) {\n const chunk = bytes[fullGroups] << 16 | bytes[fullGroups + 1] << 8;\n out += URL_SAFE[chunk >> 18 & 63] + URL_SAFE[chunk >> 12 & 63] + URL_SAFE[chunk >> 6 & 63];\n }\n return out;\n}\nfunction utf8Encode(input) {\n const bytes = [];\n for (let i = 0; i < input.length; i++) {\n let code = input.charCodeAt(i);\n if (code >= 55296 && code <= 57343) {\n const next = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;\n if (code <= 56319 && next >= 56320 && next <= 57343) {\n code = 65536 + (code - 55296 << 10) + (next - 56320);\n i++;\n } else {\n code = 65533;\n }\n }\n if (code < 128) {\n bytes.push(code);\n } else if (code < 2048) {\n bytes.push(192 | code >> 6, 128 | code & 63);\n } else if (code < 65536) {\n bytes.push(224 | code >> 12, 128 | code >> 6 & 63, 128 | code & 63);\n } else {\n bytes.push(\n 240 | code >> 18,\n 128 | code >> 12 & 63,\n 128 | code >> 6 & 63,\n 128 | code & 63\n );\n }\n }\n return new Uint8Array(bytes);\n}\nconst HKDF_SALT = new Uint8Array([103, 117, 105, 100, 101, 97, 105, 45, 115, 100, 107, 45, 101, 110, 99, 114, 121, 112, 116, 105, 111, 110, 45, 118, 49]);\nconst HKDF_INFO = new Uint8Array([97, 101, 115, 45, 50, 53, 54, 45, 103, 99, 109]);\nclass CryptoManager {\n constructor(siteId, token) {\n this.ready = false;\n this.siteId = siteId;\n try {\n const ikm = utf8Encode(token);\n this.aesKey = hkdf(sha256, ikm, HKDF_SALT, HKDF_INFO, 32);\n this.ready = true;\n } catch (err) {\n if (typeof console !== \"undefined\") {\n console.warn(\"[GuideAI] Encryption key derivation failed:\", err);\n }\n this.aesKey = new Uint8Array(0);\n this.ready = false;\n }\n }\n /** True when encryption is ready. Always true unless key derivation failed. */\n isReady() {\n return this.ready;\n }\n /** No-op — key is derived synchronously in constructor. Kept for API compat. */\n async init() {\n }\n /**\n * Encrypt a JSON-serializable payload.\n * Returns the encrypted envelope, or null on failure\n * (caller falls back to sending plaintext).\n */\n encrypt(payload) {\n if (!this.ready) return null;\n try {\n const iv = randomBytes(12);\n const plaintext = utf8Encode(JSON.stringify(payload));\n const cipher = gcm(this.aesKey, iv);\n const ciphertextWithTag = cipher.encrypt(plaintext);\n return {\n v: 2,\n // v2 = symmetric token-derived key (v1 was RSA)\n kid: this.siteId,\n iv: this.toBase64Url(iv),\n ct: this.toBase64Url(ciphertextWithTag)\n };\n } catch (err) {\n if (typeof console !== \"undefined\") {\n console.warn(\"[GuideAI] Encryption failed:\", err);\n }\n return null;\n }\n }\n // ---- Helpers ----\n toBase64Url(bytes) {\n return toBase64Url(bytes);\n }\n}\nconst MAX_MESSAGE_LENGTH = 2e3;\nconst MAX_TOOL_RESULT_SIZE = 5e4;\nconst VALID_METHODS = /* @__PURE__ */ new Set([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"CLIENT\"]);\nconst INJECTION_PATTERN = /<script|javascript:|on\\w+\\s*=|union\\s+select|drop\\s+table|insert\\s+into|delete\\s+from/i;\nconst CREDENTIAL_PATTERN$1 = /sk[_-]live[_-]\\w{10,}|pk[_-]live[_-]\\w{10,}|Bearer\\s+\\S{20,}/g;\nconst THINKING_BLOCK_PATTERN = /<thinking\\b[^>]*>[\\s\\S]*?<\\/thinking>/gi;\nconst THINKING_LINE_PATTERN = /^\\s*<\\/?thinking\\b[^>]*>\\s*$/gim;\nconst GUIDE_FENCE_PATTERN = /```(?:guide|guideai-guide)\\s*\\n?[\\s\\S]*?(?:```|$)/gi;\nconst GENERIC_SELECTORS = /* @__PURE__ */ new Set([\n \"a\",\n \"button\",\n \"input\",\n \"select\",\n \"textarea\",\n \"div\",\n \"span\",\n \"li\",\n \"p\",\n \"form\",\n \"table\",\n \"img\",\n \"label\"\n]);\nclass HarnessValidator {\n constructor() {\n this.registeredTools = [];\n }\n /** Update the list of registered tools (called after harness init). */\n setRegisteredTools(tools) {\n this.registeredTools = tools;\n }\n // ----------------------------------------------------------------\n // Input validation\n // ----------------------------------------------------------------\n /**\n * Validate and sanitize user input before sending to the backend.\n *\n * Checks:\n * - Not empty\n * - Within max length\n * - No obvious injection patterns\n */\n validateUserInput(question) {\n if (!question || !question.trim()) {\n return { valid: false, error: \"Message cannot be empty.\" };\n }\n const trimmed = question.trim();\n if (trimmed.length > MAX_MESSAGE_LENGTH) {\n return {\n valid: true,\n sanitized: trimmed.slice(0, MAX_MESSAGE_LENGTH)\n };\n }\n if (INJECTION_PATTERN.test(trimmed)) {\n console.warn(\"[GuideAI] Potential injection pattern detected in user input.\");\n }\n return { valid: true, sanitized: trimmed };\n }\n // ----------------------------------------------------------------\n // Tool call validation\n // ----------------------------------------------------------------\n /**\n * Validate a tool call response from the backend before execution.\n *\n * Checks:\n * - Required fields present (tool, method, path)\n * - Method is a valid HTTP method\n * - Tool exists in the registered tools list\n * - Path looks valid (starts with /)\n */\n validateToolCall(toolCall) {\n if (!toolCall) {\n return { valid: false, error: \"Tool call is missing.\" };\n }\n if (!toolCall.tool || typeof toolCall.tool !== \"string\") {\n return { valid: false, error: 'Tool call missing \"tool\" name.' };\n }\n if (!toolCall.method || typeof toolCall.method !== \"string\") {\n return { valid: false, error: 'Tool call missing \"method\".' };\n }\n const method = toolCall.method.toUpperCase();\n if (!VALID_METHODS.has(method)) {\n return {\n valid: false,\n error: `Invalid tool method \"${toolCall.method}\". Expected one of: ${[...VALID_METHODS].join(\", \")}.`\n };\n }\n if (!toolCall.path || typeof toolCall.path !== \"string\") {\n return { valid: false, error: 'Tool call missing \"path\".' };\n }\n if (!toolCall.path.startsWith(\"/\")) {\n return {\n valid: false,\n error: `Tool path must start with \"/\". Got: \"${toolCall.path}\".`\n };\n }\n if (this.registeredTools.length > 0) {\n const found = this.registeredTools.some(\n (t) => t.name === toolCall.tool\n );\n if (!found) {\n return {\n valid: false,\n error: `Tool \"${toolCall.tool}\" is not registered. Available: ${this.registeredTools.map((t) => t.name).slice(0, 5).join(\", \")}...`\n };\n }\n }\n return { valid: true };\n }\n // ----------------------------------------------------------------\n // Response validation\n // ----------------------------------------------------------------\n /**\n * Validate and sanitize the backend response before showing to user.\n *\n * - Strip leaked credentials from answer text\n * - Validate response structure\n */\n validateResponse(response) {\n if (!response || typeof response !== \"object\") {\n return { valid: false, error: \"Invalid response from server.\" };\n }\n const resp = response;\n if (typeof resp.answer !== \"string\") {\n return { valid: false, error: 'Response missing \"answer\" field.' };\n }\n const sanitizedAnswer = this.sanitizeAnswer(resp.answer);\n if (sanitizedAnswer !== resp.answer) {\n console.warn(\"[GuideAI] Sanitized hidden reasoning or leaked credentials from response.\");\n }\n return { valid: true, sanitized: sanitizedAnswer };\n }\n /**\n * Sanitize the answer text — strip leaked credentials, hidden reasoning\n * and machine payload the visitor should never read.\n */\n sanitizeAnswer(answer) {\n return answer.replace(THINKING_BLOCK_PATTERN, \"\").replace(THINKING_LINE_PATTERN, \"\").replace(GUIDE_FENCE_PATTERN, \"\").replace(CREDENTIAL_PATTERN$1, \"[REDACTED]\").trim();\n }\n // ----------------------------------------------------------------\n // Tool result validation\n // ----------------------------------------------------------------\n /**\n * Validate a tool execution result before sending to the format endpoint.\n *\n * - Check structure\n * - Truncate oversized results\n * - Strip credential-looking values\n */\n validateToolResult(result) {\n if (!result) {\n return { valid: false, error: \"Tool result is missing.\" };\n }\n if (typeof result.success !== \"boolean\") {\n return { valid: false, error: 'Tool result missing \"success\" field.' };\n }\n if (result.data) {\n const serialized = JSON.stringify(result.data);\n if (serialized.length > MAX_TOOL_RESULT_SIZE) {\n result.data = this._truncateData(result.data);\n }\n }\n return { valid: true };\n }\n /**\n * Enhanced tool result validation — classifies errors and detects empty-success.\n *\n * Returns errorType for contextual UI messages and warning for\n * success-but-empty scenarios.\n */\n validateToolResultEnhanced(result) {\n if (!result) {\n return { valid: false, error: \"Tool result is missing.\", errorType: \"unknown\" };\n }\n if (typeof result.success !== \"boolean\") {\n return { valid: false, error: 'Tool result missing \"success\" field.', errorType: \"unknown\" };\n }\n if (!result.success) {\n const errorType = this._classifyError(result);\n const friendlyMsg = this._friendlyErrorMessage(errorType);\n const raw = (result.error || \"\").trim();\n return {\n valid: false,\n error: friendlyMsg,\n errorType,\n detail: raw ? `${friendlyMsg} (${raw})` : friendlyMsg\n };\n }\n if (this._isEmptyData(result.data)) {\n return {\n valid: true,\n warning: \"That went through, but there was nothing to show for it yet.\"\n };\n }\n if (result.data) {\n const serialized = JSON.stringify(result.data);\n if (serialized.length > MAX_TOOL_RESULT_SIZE) {\n result.data = this._truncateData(result.data);\n }\n }\n return { valid: true };\n }\n // ----------------------------------------------------------------\n // Formatted response validation\n // ----------------------------------------------------------------\n /**\n * Validate that an LLM-formatted answer is substantial and relevant.\n * Returns the answer as-is if OK, or a fallback if not.\n */\n validateFormattedResponse(answer, toolResult) {\n if (!answer || answer.trim().length < 15) {\n return \"I retrieved the data but couldn't generate a complete summary. Please try again.\";\n }\n const refusalPatterns = /^(i cannot|i'm unable|i don't have|sorry, i can't)/i;\n if (refusalPatterns.test(answer.trim()) && (toolResult == null ? void 0 : toolResult.success) && toolResult.data) {\n return \"The data was fetched successfully. Please rephrase your question for a better summary.\";\n }\n return this.sanitizeAnswer(answer);\n }\n // ----------------------------------------------------------------\n // Guide step validation\n // ----------------------------------------------------------------\n /**\n * Validate guide steps before rendering the walkthrough button.\n * Ensures steps have minimum required fields and catches generic selectors.\n */\n validateGuideSteps(steps) {\n if (!steps || steps.length === 0) {\n return { valid: false, steps: [], warnings: [\"No guide steps returned.\"] };\n }\n const warnings = [];\n const validSteps = [];\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n const title = step.title;\n const body = step.body;\n const selector = step.target_selector;\n const action = step.action;\n if (!title && !body) {\n warnings.push(`Step ${i + 1} has no title or body — skipped.`);\n continue;\n }\n if (selector && GENERIC_SELECTORS.has(selector.trim())) {\n warnings.push(\n `Step ${i + 1} has a generic selector \"${selector}\" — it may not highlight correctly.`\n );\n step.target_selector = void 0;\n if (action && action !== \"none\") {\n step.action = \"none\";\n }\n }\n validSteps.push(step);\n }\n return {\n valid: validSteps.length > 0,\n steps: validSteps,\n warnings\n };\n }\n // ----------------------------------------------------------------\n // Private helpers\n // ----------------------------------------------------------------\n _classifyError(result) {\n const status = result.status;\n const error = (result.error || \"\").toLowerCase();\n if (status === 401 || status === 403) return \"auth\";\n if (status === 404) return \"not_found\";\n if (status === 429) return \"rate_limit\";\n if (status && status >= 500) return \"server\";\n if (status === 400 || status === 422) return \"validation\";\n if (error.includes(\"timed out\") || error.includes(\"timeout\")) return \"timeout\";\n if (error.includes(\"connect\") || error.includes(\"network\")) return \"connection\";\n if (status && status >= 400) return \"client\";\n return result.error_type || \"unknown\";\n }\n /**\n * What a person reads when a request fails.\n *\n * No status codes, no endpoint names, no field paths — those belong to the\n * model (see `detail`), which can act on them. A person can only be told,\n * plainly, that the thing did not work and roughly why.\n */\n _friendlyErrorMessage(errorType) {\n switch (errorType) {\n case \"auth\":\n return \"Your session has expired. Please log in again and retry.\";\n case \"not_found\":\n return \"I couldn't find that record. It may have been removed.\";\n case \"rate_limit\":\n return \"Too many requests right now. Please try again in a moment.\";\n case \"timeout\":\n return \"That took too long to respond. Please try again.\";\n case \"connection\":\n return \"I couldn't reach the service. Please check your connection and try again.\";\n case \"server\":\n return \"The service ran into a problem. Please try again shortly.\";\n case \"validation\":\n return \"Some of the details in that request weren't accepted.\";\n default:\n return \"I wasn't able to complete that request.\";\n }\n }\n _isEmptyData(data) {\n if (data === null || data === void 0) return true;\n if (Array.isArray(data)) return data.length === 0;\n if (typeof data === \"string\") return data.trim().length === 0;\n if (typeof data === \"object\") {\n const obj = data;\n const keys = Object.keys(obj).filter((k) => !k.startsWith(\"_\"));\n if (keys.length === 0) return true;\n return keys.every((k) => {\n const v = obj[k];\n return v === null || v === void 0 || v === \"\" || Array.isArray(v) && v.length === 0 || typeof v === \"object\" && v !== null && Object.keys(v).length === 0;\n });\n }\n return false;\n }\n /**\n * Truncate large data payloads to prevent token waste at the format endpoint.\n */\n _truncateData(data) {\n if (Array.isArray(data)) {\n return data.slice(0, 25);\n }\n if (data && typeof data === \"object\") {\n const obj = data;\n for (const key of [\"data\", \"results\", \"items\", \"records\", \"rows\"]) {\n if (Array.isArray(obj[key])) {\n return {\n ...obj,\n [key]: obj[key].slice(0, 25),\n _truncated: true\n };\n }\n }\n }\n return data;\n }\n}\nconst DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;\nconst DEFAULT_MAX_MESSAGES = 50;\nconst SENSITIVE_KEY_PATTERN = /^(password|passwd|secret|token|api[_-]?key|admin[_-]?key|access[_-]?key|private[_-]?key|authorization|ssn|credit[_-]?card|cvv|cvc|pin)$/i;\nconst CREDENTIAL_PATTERN = /sk[_-]live[_-]\\w{10,}|pk[_-]live[_-]\\w{10,}|Bearer\\s+\\S{20,}/g;\nclass ConversationMemory {\n /**\n * @param store Where history lives. Defaults to memory so core never\n * reaches for a global; the web SDK passes its localStorage adapter.\n */\n constructor(siteId, ttlMs, maxMessages, store = new MemoryKVStore()) {\n this.listener = null;\n this.store = store;\n this.storageKey = `guideai_chat_${siteId}`;\n this.ttlMs = ttlMs ?? DEFAULT_TTL_MS;\n this.maxMessages = maxMessages ?? DEFAULT_MAX_MESSAGES;\n }\n /** Get all messages, checking TTL. Returns empty array if expired. */\n getMessages() {\n try {\n const raw = this.store.getItem(this.storageKey);\n if (!raw) return [];\n const data = JSON.parse(raw);\n if (Date.now() - data.updated_at > this.ttlMs) {\n this.clear();\n return [];\n }\n return data.messages || [];\n } catch {\n return [];\n }\n }\n /** Add a message and persist to the store. Auto-generates an ID if not provided. */\n addMessage(message) {\n var _a;\n if (!message.id) {\n message.id = `msg_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n }\n const messages = this.getMessages();\n messages.push(message);\n const trimmed = messages.slice(-this.maxMessages);\n this._save(trimmed);\n try {\n (_a = this.listener) == null ? void 0 : _a.call(this, message);\n } catch {\n }\n }\n /** Called with every message added from now on; null stops it. */\n onMessage(listener) {\n this.listener = listener;\n }\n /**\n * Get recent messages formatted for LLM context.\n * Includes tool result summaries so the LLM knows what data was\n * previously returned and can make informed follow-up tool calls.\n * Caps total payload to ~4000 chars to stay within token budget.\n */\n getRecentForLLM(count = 10) {\n const messages = this.getMessages();\n const MAX_MSG_CHARS = 500;\n const MAX_TOOL_RESULT_CHARS = 800;\n const MAX_TOTAL_CHARS = 4e3;\n const recent = messages.slice(-count).map((msg) => {\n var _a;\n let content = msg.content;\n if (msg.role === \"assistant\" && content.length > MAX_MSG_CHARS) {\n content = content.slice(0, MAX_MSG_CHARS) + \"...\";\n }\n if (((_a = msg.toolResult) == null ? void 0 : _a.success) && msg.toolResult.data) {\n const summary = this._summarizeToolResult(msg.toolResult.data, MAX_TOOL_RESULT_CHARS);\n if (summary) {\n content += `\n\n[Tool result data: ${summary}]`;\n }\n }\n if (msg.toolCalls && msg.toolCalls.length > 0) {\n const callSummary = msg.toolCalls.map((tc) => {\n const route = tc.method && tc.path ? ` ${tc.method} ${tc.path}` : \"\";\n const detail = tc.summary ? ` - ${tc.summary}` : \"\";\n return `${tc.tool}${route}: ${tc.success ? \"ok\" : \"failed\"}${detail}`;\n }).join(\"; \");\n content += `\n[Tool calls: ${callSummary}]`;\n }\n content = content.replace(CREDENTIAL_PATTERN, \"[REDACTED]\");\n return { role: msg.role, content };\n });\n let total = recent.reduce((sum, m) => sum + m.content.length, 0);\n while (recent.length > 2 && total > MAX_TOTAL_CHARS) {\n const removed = recent.shift();\n total -= removed.content.length;\n }\n return recent;\n }\n /**\n * Create a compact summary of tool result data for LLM context.\n * Extracts key fields, array lengths, and available resource names.\n */\n _summarizeToolResult(data, maxChars) {\n try {\n const cleaned = this._stripSensitiveFields(data);\n const json = JSON.stringify(cleaned);\n if (json.length <= maxChars) {\n return json;\n }\n if (Array.isArray(cleaned)) {\n const total = cleaned.length;\n const pickFields = (item) => {\n if (typeof item === \"object\" && item !== null) {\n const obj = item;\n const picked = {};\n for (const key of [\"name\", \"id\", \"title\", \"path\", \"endpoint\", \"url\", \"type\", \"method\", \"label\", \"slug\", \"status\"]) {\n if (key in obj) picked[key] = obj[key];\n }\n return Object.keys(picked).length > 0 ? picked : Object.keys(obj).slice(0, 4).reduce((acc, k) => ({ ...acc, [k]: obj[k] }), {});\n }\n return item;\n };\n const compactItems = cleaned.map(pickFields);\n let itemsToShow = compactItems;\n let summary = JSON.stringify({ total_count: total, items: itemsToShow });\n if (summary.length > maxChars) {\n let lo = 1, hi = compactItems.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n const test = JSON.stringify({ total_count: total, items_shown: mid, items: compactItems.slice(0, mid) });\n if (test.length <= maxChars) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n itemsToShow = compactItems.slice(0, lo);\n summary = JSON.stringify({ total_count: total, items_shown: lo, items: itemsToShow });\n }\n return summary.length <= maxChars ? summary : summary.slice(0, maxChars) + \"...\";\n }\n if (typeof cleaned === \"object\" && cleaned !== null) {\n const keys = Object.keys(cleaned);\n const summary = JSON.stringify({ keys, preview: json.slice(0, maxChars - 100) });\n return summary.slice(0, maxChars);\n }\n return json.slice(0, maxChars);\n } catch {\n return \"\";\n }\n }\n /** Recursively strip fields with sensitive-looking keys (defense-in-depth). */\n _stripSensitiveFields(data, depth = 0) {\n if (depth > 5) return data;\n if (Array.isArray(data)) {\n return data.slice(0, 50).map((item) => this._stripSensitiveFields(item, depth + 1));\n }\n if (typeof data === \"object\" && data !== null) {\n const result = {};\n for (const [key, value] of Object.entries(data)) {\n result[key] = SENSITIVE_KEY_PATTERN.test(key) ? \"[REDACTED]\" : this._stripSensitiveFields(value, depth + 1);\n }\n return result;\n }\n return data;\n }\n /** Clear all conversation history. */\n clear() {\n try {\n this.store.removeItem(this.storageKey);\n } catch {\n }\n }\n /** Check if there is any conversation history. */\n hasHistory() {\n return this.getMessages().length > 0;\n }\n _save(messages) {\n try {\n const data = {\n messages,\n updated_at: Date.now()\n };\n this.store.setItem(this.storageKey, JSON.stringify(data));\n } catch {\n }\n }\n}\nfunction encodeParam(value) {\n return encodeURIComponent(value).replace(/%20/g, \"+\").replace(/[!'()~]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);\n}\nconst MAX_ERROR_DETAIL_CHARS = 400;\nconst MAX_ERROR_DETAIL_ITEMS = 5;\nclass ToolExecutor {\n /**\n * @param transport How this platform reaches the customer's API.\n * Defaults to the browser's, so existing callers are unaffected.\n */\n constructor(authConfig, baseUrl, credentials, transport) {\n this.credentials = credentials;\n this.transport = transport;\n this.authConfig = authConfig;\n this.baseUrl = baseUrl.replace(/\\/+$/, \"\");\n }\n /** Read the user's auth token from the configured browser storage. */\n getAuthToken() {\n if (this.authConfig.type === \"none\") return null;\n try {\n let raw = null;\n const storageKey = this.authConfig.key;\n if (storageKey && this.authConfig.source) {\n raw = this.credentials.read(this.authConfig.source, storageKey);\n }\n if (raw) {\n const token = this._extractToken(raw);\n if (token) return token;\n }\n return null;\n } catch {\n return null;\n }\n }\n /**\n * Extract the actual JWT from a raw storage value.\n *\n * Handles all common storage formats automatically:\n * - Plain JWT string: \"eyJhbGciOi...\"\n * - JSON with known field: {\"access_token\": \"eyJ...\"} or {\"token\": \"eyJ...\"}\n * - JSON with any string field that looks like a JWT\n *\n * If token_field is configured, it takes priority and extracts that specific field.\n */\n _extractToken(raw) {\n if (raw.startsWith(\"eyJ\")) return raw;\n try {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n if (this.authConfig.token_field) {\n const value = this._readObjectPath(parsed, this.authConfig.token_field);\n return typeof value === \"string\" ? value : null;\n }\n const commonFields = [\"access_token\", \"token\", \"jwt\", \"id_token\", \"auth_token\", \"accessToken\", \"idToken\", \"authToken\"];\n for (const field of commonFields) {\n if (typeof parsed[field] === \"string\" && parsed[field]) {\n return parsed[field];\n }\n }\n for (const value of Object.values(parsed)) {\n if (typeof value === \"string\" && value.startsWith(\"eyJ\")) {\n return value;\n }\n }\n }\n if (typeof parsed === \"string\") return parsed;\n } catch {\n }\n return raw;\n }\n /** Execute an API tool call client-side using the user's auth. */\n async execute(toolCall) {\n try {\n const method = toolCall.method.toUpperCase();\n const unresolved = [\n ...this._unresolvedPathParams(toolCall),\n ...this._unresolvedHeaders(toolCall)\n ];\n if (unresolved.length > 0) {\n return {\n success: false,\n error: `Missing ${unresolved.join(\", \")} — this needs data from another request first.`\n };\n }\n const url = this._buildUrl(toolCall);\n const headers = this._buildHeaders(toolCall);\n let body;\n if (toolCall.body && method !== \"GET\") {\n body = JSON.stringify(toolCall.body);\n } else if (toolCall.params && method !== \"GET\") {\n body = JSON.stringify(toolCall.params);\n }\n const response = await this.transport.request({\n url,\n // The tool's own verb, not a coerced one: rewriting a DELETE as a\n // POST would silently change what the customer's API is asked to do.\n method,\n headers,\n body\n });\n let data;\n const contentType = response.headers.get(\"content-type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n data = await response.json();\n } else {\n data = await response.text();\n }\n const ok = response.status >= 200 && response.status < 300;\n return {\n success: ok,\n data,\n status: response.status,\n error: ok ? void 0 : response.status === 401 || response.status === 403 ? \"Your session has expired. Please refresh the page or log in again.\" : this._describeHttpError(response.status, data)\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : \"Unknown error executing tool call\"\n };\n }\n }\n /**\n * Turn a failed response into an error the model can act on.\n *\n * \"HTTP 422: Unprocessable Entity\" tells nobody which field was wrong, so a\n * rejected write used to end the chain with a status line the user could do\n * nothing with. The body almost always names the problem — FastAPI puts a\n * loc/msg list in `detail`, most other APIs use `message`, `error` or an\n * `errors` array — so surface that alongside the status.\n */\n _describeHttpError(status, data) {\n const base = `HTTP ${status}`;\n const detail = this._extractErrorDetail(data);\n return detail ? `${base} — ${detail}` : base;\n }\n _extractErrorDetail(data) {\n if (typeof data === \"string\") {\n const text = data.trim();\n return text ? text.slice(0, MAX_ERROR_DETAIL_CHARS) : null;\n }\n if (!data || typeof data !== \"object\") return null;\n const body = data;\n const parts = [];\n for (const key of [\"detail\", \"message\", \"error\", \"errors\", \"error_description\"]) {\n const value = body[key];\n if (value === void 0 || value === null) continue;\n if (typeof value === \"string\") {\n if (value.trim()) parts.push(value.trim());\n } else if (Array.isArray(value)) {\n for (const entry of value.slice(0, MAX_ERROR_DETAIL_ITEMS)) {\n const described = this._describeFieldError(entry);\n if (described) parts.push(described);\n }\n } else if (typeof value === \"object\") {\n for (const [field, msg] of Object.entries(value).slice(0, MAX_ERROR_DETAIL_ITEMS)) {\n const text = Array.isArray(msg) ? msg.join(\", \") : String(msg);\n parts.push(`${field}: ${text}`);\n }\n }\n if (parts.length > 0) break;\n }\n if (parts.length === 0) return null;\n return parts.join(\"; \").slice(0, MAX_ERROR_DETAIL_CHARS);\n }\n /** One entry of a validation-error list, e.g. FastAPI's {loc, msg, type}. */\n _describeFieldError(entry) {\n if (typeof entry === \"string\") return entry.trim() || null;\n if (!entry || typeof entry !== \"object\") return null;\n const item = entry;\n const message = item.msg ?? item.message ?? item.error ?? item.detail;\n const location = Array.isArray(item.loc) ? item.loc.filter((part) => part !== \"body\").join(\".\") : item.field ?? item.param ?? item.name;\n if (!message) return location ? `${location}: invalid` : null;\n return location ? `${location}: ${message}` : String(message);\n }\n /**\n * Execute several independent tool calls concurrently.\n *\n * The model batches only calls that do not depend on each other's results,\n * so a batch of four costs roughly one call's wall-clock time instead of\n * four sequential round trips. Results come back in request order.\n *\n * A rejected promise is impossible here — `execute` already converts thrown\n * errors into a failed ToolExecutionResult — but the settled form is used\n * anyway so one exception can never discard the whole batch.\n */\n async executeBatch(toolCalls, onEach) {\n const settled = await Promise.allSettled(\n toolCalls.map(async (toolCall) => {\n const result = await this.execute(toolCall);\n onEach == null ? void 0 : onEach(toolCall, result);\n return result;\n })\n );\n return settled.map((outcome, i) => {\n if (outcome.status === \"fulfilled\") return outcome.value;\n const result = {\n success: false,\n error: outcome.reason instanceof Error ? outcome.reason.message : \"Unknown error executing tool call\"\n };\n onEach == null ? void 0 : onEach(toolCalls[i], result);\n return result;\n });\n }\n _buildHeaders(toolCall) {\n const headers = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\"\n };\n const blocked = /* @__PURE__ */ new Set([\n \"authorization\",\n \"cookie\",\n \"host\",\n \"origin\",\n \"referer\",\n \"x-forwarded-for\",\n \"x-real-ip\",\n \"content-length\",\n \"transfer-encoding\",\n \"connection\"\n ]);\n const canonical = /* @__PURE__ */ new Map();\n const mergeHeader = (name, value) => {\n const lower = name.toLowerCase();\n if (!value || blocked.has(lower)) return;\n const existing = canonical.get(lower);\n if (existing !== void 0 && existing !== name) delete headers[existing];\n canonical.set(lower, name);\n headers[name] = value;\n };\n for (const name of Object.keys(headers)) canonical.set(name.toLowerCase(), name);\n if (this.authConfig.type === \"none\") ;\n else if (this.authConfig.type === \"bearer\") {\n const token = this.getAuthToken();\n if (!token) {\n throw new Error(\"No auth token found in browser storage. The user may not be logged in.\");\n }\n headers.Authorization = `Bearer ${token}`;\n } else if (this.authConfig.type === \"api_key\" && this.authConfig.key && this.authConfig.header) {\n mergeHeader(this.authConfig.header, this.authConfig.key);\n }\n if (this.authConfig.headers && typeof this.authConfig.headers === \"object\") {\n for (const [name, rawValue] of Object.entries(this.authConfig.headers)) {\n mergeHeader(name, this._resolveHeaderValue(rawValue));\n }\n }\n if (toolCall.headers && typeof toolCall.headers === \"object\") {\n for (const [name, value] of Object.entries(toolCall.headers)) {\n mergeHeader(name, value);\n }\n }\n return headers;\n }\n _resolveHeaderValue(value) {\n if (typeof value === \"string\") return value;\n let raw = null;\n try {\n raw = this.credentials.read(value.source, value.key);\n } catch {\n return null;\n }\n if (!raw) return null;\n if (value.token_field) {\n try {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n const selected = this._readObjectPath(parsed, value.token_field);\n return typeof selected === \"string\" ? selected : null;\n }\n } catch {\n return raw;\n }\n }\n return this._extractToken(raw) || raw;\n }\n /**\n * Path template segments that `_buildUrl` would leave unsubstituted.\n *\n * A value that is itself a placeholder (\"{id}\", \"<site_id>\", \"TBD\") counts\n * as unresolved too — substituting it would produce a URL that looks valid\n * but addresses nothing.\n */\n _unresolvedPathParams(toolCall) {\n const segments = (toolCall.path || \"\").match(/\\{(\\w+)\\}/g) || [];\n if (segments.length === 0) return [];\n const params = toolCall.params || {};\n const placeholder = /^\\s*(?:[{<[].*[}>\\]]|[$:].+|tbd|todo|placeholder|unknown|none|null|n\\/a)\\s*$/i;\n return segments.map((segment) => segment.slice(1, -1)).filter((name) => {\n const value = params[name];\n if (value === void 0 || value === null || value === \"\") return true;\n return typeof value === \"string\" && placeholder.test(value);\n });\n }\n /**\n * Headers whose value is still a placeholder the model never filled in.\n *\n * Worse than an unresolved path segment: a scoping header like X-Site-Id\n * sent as \"{site_id}\" does not 404, it answers about whatever the default\n * record is. Failing the call here is what makes the mistake visible.\n */\n _unresolvedHeaders(toolCall) {\n const headers = toolCall.headers;\n if (!headers) return [];\n const placeholder = /^\\s*(?:[{<[].*[}>\\]]|[$:].+|tbd|todo|placeholder|unknown|none|null|n\\/a)\\s*$/i;\n return Object.entries(headers).filter(([, value]) => typeof value === \"string\" && placeholder.test(value)).map(([name]) => name);\n }\n _buildUrl(toolCall) {\n let path = toolCall.path;\n const method = toolCall.method.toUpperCase();\n if (toolCall.params) {\n for (const [key, value] of Object.entries(toolCall.params)) {\n const placeholder = `{${key}}`;\n if (path.includes(placeholder)) {\n path = path.replace(placeholder, encodeURIComponent(String(value)));\n }\n }\n }\n let url;\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(path)) {\n url = path;\n } else {\n const origin = this._origin(this.baseUrl);\n url = path.startsWith(\"/\") ? `${origin}${path}` : `${this.baseUrl}/${path}`;\n }\n if (toolCall.params && method === \"GET\") {\n const pairs = [];\n for (const [key, value] of Object.entries(toolCall.params)) {\n if (!toolCall.path.includes(`{${key}}`)) {\n pairs.push(`${encodeParam(key)}=${encodeParam(String(value))}`);\n }\n }\n if (pairs.length > 0) {\n url += (url.includes(\"?\") ? \"&\" : \"?\") + pairs.join(\"&\");\n }\n }\n return url;\n }\n /** Scheme + authority of a base URL, without its path. */\n _origin(base) {\n const match = /^([a-z][a-z0-9+.-]*:\\/\\/[^/]+)/i.exec(base);\n return match ? match[1] : base;\n }\n _readObjectPath(source, path) {\n const segments = path.split(\".\").map((segment) => segment.trim()).filter(Boolean);\n let current = source;\n for (const segment of segments) {\n if (!current || typeof current !== \"object\" || Array.isArray(current)) {\n return void 0;\n }\n current = current[segment];\n }\n return current;\n }\n}\nclass AuthError extends Error {\n constructor(status) {\n super(\"Your session has expired. Please refresh the page or log in again.\");\n this.name = \"AuthError\";\n this.status = status;\n }\n}\nclass UsageLimitError extends Error {\n constructor(detail) {\n super(detail.message);\n this.name = \"UsageLimitError\";\n this.status = 429;\n this.limitType = detail.limit_type || \"unknown\";\n this.plan = detail.plan || \"unknown\";\n this.current = detail.current || 0;\n this.limit = detail.limit || 0;\n this.upgradeHint = detail.upgrade_hint || \"\";\n }\n}\nclass PlanAccessError extends Error {\n constructor(detail) {\n super(detail.message || \"This feature is not available on the current plan.\");\n this.status = 402;\n this.name = \"PlanAccessError\";\n this.feature = detail.feature || \"unknown\";\n this.plan = detail.plan || \"unknown\";\n this.upgradeHint = detail.upgrade_hint || \"\";\n }\n}\nclass EncryptionError extends Error {\n constructor(path) {\n super(`[3Guide] Refusing to send ${path} unencrypted: encryption failed.`);\n this.name = \"EncryptionError\";\n }\n}\nclass TimeoutError extends Error {\n constructor(path, timeoutMs) {\n super(`[3Guide] ${path} timed out after ${timeoutMs}ms`);\n this.name = \"TimeoutError\";\n this.timeoutMs = timeoutMs;\n }\n}\nconst _j = (parts) => parts.join(\"/\");\nconst _v = [\"\", \"api\", \"v1\"];\nconst EP = {\n feedback: () => _j([..._v, \"ml\", \"feedback\"]),\n weights: () => _j([..._v, \"ml\", \"weights\"]),\n modelInfo: () => _j([..._v, \"ml\", \"model-info\"]),\n guides: () => _j([..._v, \"guides\", \"published\"]),\n guidesRecord: () => _j([..._v, \"guides\", \"record\"]),\n events: () => _j([..._v, \"events\"]),\n chatAsk: () => _j([..._v, \"chat\", \"ask\"]),\n onboardingCurrent: (userId) => `${_j([..._v, \"onboarding\", \"current\"])}?user_id=${encodeURIComponent(userId)}`,\n onboardingObserve: () => _j([..._v, \"onboarding\", \"observe\"]),\n onboardingDismiss: () => _j([..._v, \"onboarding\", \"dismiss\"]),\n onboardingEnroll: () => _j([..._v, \"onboarding\", \"enroll\"]),\n onboardingSkip: () => _j([..._v, \"onboarding\", \"skip\"]),\n onboardingComplete: () => _j([..._v, \"onboarding\", \"complete\"]),\n onboardingWatched: () => _j([..._v, \"onboarding\", \"watched\"]),\n demoSearch: () => _j([..._v, \"demos\", \"search\"]),\n chatRoute: () => _j([..._v, \"chat\", \"route\"]),\n chatOpener: () => _j([..._v, \"chat\", \"opener\"]),\n chatOpenerSpeech: () => _j([..._v, \"chat\", \"opener\", \"speech\"]),\n chatIntro: () => _j([..._v, \"chat\", \"intro\"]),\n chatEscalate: () => _j([..._v, \"chat\", \"escalate\"]),\n chatEscalationConfig: () => _j([..._v, \"chat\", \"escalate\", \"config\"]),\n chatConversationWebhook: () => _j([..._v, \"chat\", \"conversation-webhook\"]),\n chatFeedback: () => _j([..._v, \"chat\", \"feedback\"]),\n coachScreen: () => _j([..._v, \"chat\", \"coach\", \"screen\"]),\n coachAsk: () => _j([..._v, \"chat\", \"coach\", \"ask\"]),\n coachExplain: () => _j([..._v, \"chat\", \"coach\", \"explain\"]),\n coachReplan: () => _j([..._v, \"chat\", \"coach\", \"replan\"]),\n coachConfirm: () => _j([..._v, \"chat\", \"coach\", \"confirm\"]),\n coachSpeech: () => _j([..._v, \"chat\", \"coach\", \"speech\"]),\n paymentCheckout: () => _j([..._v, \"connectors\", \"payments\", \"checkout\"]),\n chatContinue: () => _j([..._v, \"chat\", \"continue-tool-chain\"]),\n /** A Do it run: plan a screen, act, look again (the agent service). */\n doItRuns: () => _j([..._v, \"guide-executions\"]),\n doItRun: (runId, op) => _j([..._v, \"guide-executions\", encodeURIComponent(runId), ...op ? [op] : []]),\n chatFormat: () => _j([..._v, \"chat\", \"format-tool-result\"]),\n copilotTools: () => _j([..._v, \"copilot-tools\", \"active\"]),\n copilotStream: () => _j([..._v, \"copilot\", \"stream\"]),\n resolveScore: () => _j([..._v, \"resolve\", \"score\"]),\n resolveLocate: () => _j([..._v, \"resolve\", \"locate\"]),\n resolveRoute: () => _j([..._v, \"resolve\", \"route\"]),\n resolveGraph: () => _j([..._v, \"resolve\", \"graph\"]),\n visitors: () => _j([..._v, \"visitors\", \"register\"]),\n announcements: () => _j([..._v, \"announcements\"]),\n pageScan: () => _j([..._v, \"page-scan\", \"scan\"]),\n pageScanReveal: () => _j([..._v, \"page-scan\", \"reveal\"]),\n supportStatus: () => _j([..._v, \"support\", \"public\", \"status\"]),\n supportConvs: () => _j([..._v, \"support\", \"public\", \"conversations\"]),\n supportMsgs: (conversationId) => _j([..._v, \"support\", \"public\", \"conversations\", conversationId, \"messages\"]),\n realtimeSession: () => _j([..._v, \"realtime\", \"session\"]),\n realtimeTranscriptionSession: () => _j([..._v, \"realtime\", \"transcription\", \"session\"]),\n realtimeSpeech: () => _j([..._v, \"realtime\", \"speech\"]),\n listenSession: () => _j([..._v, \"realtime\", \"listen\", \"session\"]),\n speakSession: () => _j([..._v, \"realtime\", \"speak\", \"session\"]),\n liveSession: () => _j([..._v, \"realtime\", \"live\", \"session\"]),\n // v=2: neutral voice codes (stream / pipeline / live / live-rtc).\n voiceCapabilities: () => `${_j([..._v, \"realtime\", \"capabilities\"])}?v=2`,\n liveVoiceMinute: () => _j([..._v, \"realtime\", \"live\", \"minute\"]),\n batchVoiceTranscribe: () => _j([..._v, \"realtime\", \"batch\", \"transcribe\"]),\n documentFormSuggestions: () => _j([..._v, \"realtime\", \"document\", \"form-suggestions\"])\n};\nconst MAX_CHAIN_ROUNDS = 5;\nconst MAX_TOTAL_TOOL_CALLS = 10;\nconst MAX_REPAIR_ROUNDS = 1;\nconst REPAIRABLE_ERROR_TYPES = /* @__PURE__ */ new Set([\"validation\", \"client\", \"not_found\"]);\nclass CopilotHarness {\n /**\n * @param tools How this platform actually touches the screen. Defaults to\n * the browser registry so every existing caller is unaffected; a mobile\n * runtime passes one that dispatches native effects instead. The loop\n * below never learns which it is holding.\n */\n constructor(api, config, tools, storage, transport, credentials) {\n this.toolExecutor = null;\n this.activeTools = null;\n this.initialized = false;\n this.lastPlanFingerprint = null;\n this.api = api;\n this.config = config;\n this.tools = tools;\n this.transport = transport;\n this.credentials = credentials;\n this.memory = new ConversationMemory(\n config.siteId,\n config.memoryTtlMs,\n config.maxMemoryMessages,\n storage\n );\n this.validator = new HarnessValidator();\n this.validator.setRegisteredTools(this.tools.copilotDefinitions());\n }\n /** Hear every turn the conversation records (typed, spoken, replies). */\n onMessageRecorded(listener) {\n this.memory.onMessage(listener);\n }\n /** Initialize the harness — fetch active tools for the site. */\n async initialize() {\n if (this.initialized) return this.isEnabled();\n try {\n const response = await this.api.get(\n EP.copilotTools()\n );\n if (response && response.tools && response.tools.length > 0) {\n this.activeTools = response;\n this.validator.setRegisteredTools([\n ...response.tools,\n ...this.tools.copilotDefinitions()\n ]);\n this.toolExecutor = new ToolExecutor(\n response.auth_config,\n response.base_url,\n this.credentials,\n this.transport\n );\n }\n } catch {\n }\n this.initialized = true;\n return this.isEnabled();\n }\n /**\n * Register the listener that renders the assistant's plan.\n *\n * Set on the harness rather than passed per message: `processMessage` is\n * already called positionally from several places, and a plan belongs to\n * the UI for the whole session, not to one call.\n */\n setPlanCallback(callback) {\n this.onPlan = callback;\n }\n /**\n * Values the host page supplies for tool inputs.\n *\n * Sent with every turn, including chain rounds — a later round builds calls\n * too, and dropping it there is how a chain that started on the right\n * record finishes on the default one.\n */\n /** Bind to the SDK's analytics session. Carries no message content. */\n setAnalyticsSessionId(sessionId) {\n this.config.analyticsSessionId = sessionId;\n }\n /** Read the analytics bundle's ids on every question. Ids only. */\n setAnalyticsIds(read) {\n this.config.analyticsIds = read;\n }\n setToolContext(values) {\n this.toolContext = values && Object.keys(values).length > 0 ? values : void 0;\n }\n /** Whether copilot action tools are available for this site. */\n isEnabled() {\n return this.tools.definitions().length > 0 || this.activeTools !== null && this.activeTools.tools.length > 0;\n }\n /**\n * Process a user message through the harness.\n *\n * 1. Sends question + history + page context to backend /ask\n * 2. If backend returns SSE stream (agent loop running), reads events in real-time\n * 3. Calls onStatus callback with progress updates during the loop\n * 4. Returns the final response when the stream completes\n * 5. For non-tool queries, returns JSON response directly\n */\n async processMessage(question, pageUrl, pageSnapshot, chatMode, onStatus, onTextDelta, onToolCallEvent, abortSignal, userContext, onboardingUserId) {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n const inputCheck = this.validator.validateUserInput(question);\n if (!inputCheck.valid) {\n return this._errorResponse(inputCheck.error || \"Invalid input.\");\n }\n const sanitizedQuestion = inputCheck.sanitized || question;\n this.lastPlanFingerprint = null;\n this.currentPlan = void 0;\n this.memory.addMessage({\n role: \"user\",\n content: sanitizedQuestion,\n timestamp: Date.now()\n });\n const conversationHistory = this.memory.getRecentForLLM(10);\n const mayForwardToken = ((_b = (_a = this.activeTools) == null ? void 0 : _a.auth_config) == null ? void 0 : _b.forward_user_token) === true;\n const userToken = mayForwardToken ? ((_c = this.toolExecutor) == null ? void 0 : _c.getAuthToken()) ?? null : null;\n let analytics = {};\n try {\n analytics = ((_e = (_d = this.config).analyticsIds) == null ? void 0 : _e.call(_d)) ?? {};\n } catch {\n }\n const requestBody = {\n question: sanitizedQuestion,\n page_url: pageUrl,\n session_id: analytics.session_id || this.config.analyticsSessionId || void 0,\n distinct_id: analytics.distinct_id || void 0,\n page_snapshot: pageSnapshot,\n chat_mode: chatMode || \"guidance\",\n assistant_label: ((_f = this.config.assistantLabel) == null ? void 0 : _f.trim()) || void 0,\n delegate_instruction: ((_g = this.config.delegationInstruction) == null ? void 0 : _g.trim().slice(0, 1e3)) || void 0,\n conversation_history: conversationHistory,\n stream: this.api.supportsStreaming,\n user_token: userToken || void 0,\n prefer_client_tool_execution: !!this.toolExecutor || this.tools.definitions().length > 0,\n client_tools: chatMode === \"assistant\" ? this.tools.definitions() : void 0,\n user_context: userContext,\n onboarding_user_id: onboardingUserId,\n tool_context: this.toolContext,\n client_capabilities: ((_h = this.config.clientCapabilities) == null ? void 0 : _h.length) ? this.config.clientCapabilities : void 0\n };\n let rawResponse;\n try {\n rawResponse = await this.api.postRaw(EP.chatAsk(), requestBody, abortSignal);\n } catch (err) {\n if (abortSignal == null ? void 0 : abortSignal.aborted) {\n return this._errorResponse(\"Response cancelled.\");\n }\n if (err instanceof AuthError) {\n return this._errorResponse(err.message);\n }\n if (err instanceof UsageLimitError || err instanceof PlanAccessError) {\n throw err;\n }\n return this._errorResponse(\"Failed to get response from server.\");\n }\n const contentType = rawResponse.headers.get(\"content-type\") || \"\";\n if (contentType.includes(\"text/event-stream\")) {\n return this._readSSEStream(\n rawResponse,\n sanitizedQuestion,\n onStatus,\n onTextDelta,\n onToolCallEvent,\n abortSignal\n );\n }\n let response;\n try {\n response = await rawResponse.json();\n } catch {\n return this._errorResponse(\"Failed to parse server response.\");\n }\n if (onTextDelta && response.answer) {\n this._emitAnswerText(response.answer, onTextDelta, abortSignal);\n }\n const harnessResponse = this._handleJsonResponse(response, chatMode);\n if (harnessResponse.autoExecuteToolCall && harnessResponse.pendingToolCall) {\n return this._executePendingToolCall(\n harnessResponse.pendingToolCalls ?? [harnessResponse.pendingToolCall],\n sanitizedQuestion,\n onStatus,\n onTextDelta,\n onToolCallEvent\n );\n }\n return harnessResponse;\n }\n /**\n * Execute a confirmed tool call after user approval.\n * Called when user clicks \"Yes, do it\" for write/destructive actions.\n * Executes in the browser when possible, then formats the result with LLM.\n */\n async executeToolCall(toolCall, originalQuestion, onStatus, onTextDelta) {\n if (!this.canExecuteTool(toolCall)) {\n const errorMsg = \"Tool execution is unavailable in this browser context.\";\n this.memory.addMessage({\n role: \"assistant\",\n content: errorMsg,\n timestamp: Date.now()\n });\n return {\n mode: \"answer\",\n answer: errorMsg,\n toolResult: {\n success: false,\n error: errorMsg\n },\n autoExecute: false\n };\n }\n const result = await this.executeLocalTool(toolCall);\n const resultCheck = this.validator.validateToolResultEnhanced(result);\n if (!resultCheck.valid) {\n if (REPAIRABLE_ERROR_TYPES.has(resultCheck.errorType || \"\")) {\n onStatus == null ? void 0 : onStatus(\"That did not go through — adjusting the request...\");\n const repaired = await this._continueToolChain(\n toolCall.tool,\n { error: resultCheck.detail || result.error || resultCheck.error },\n originalQuestion,\n [{\n tool_name: toolCall.tool,\n tool_result: { error: resultCheck.detail || result.error || resultCheck.error }\n }],\n onStatus,\n onTextDelta\n );\n if (repaired.pendingToolCall || repaired.answer) {\n return repaired;\n }\n }\n const errorMsg = resultCheck.error || \"Tool execution failed.\";\n this.memory.addMessage({\n role: \"assistant\",\n content: errorMsg,\n toolResult: result,\n timestamp: Date.now()\n });\n return {\n mode: \"answer\",\n answer: errorMsg,\n toolResult: result,\n autoExecute: false\n };\n }\n if (resultCheck.warning) {\n this.memory.addMessage({\n role: \"assistant\",\n content: resultCheck.warning,\n toolResult: result,\n timestamp: Date.now()\n });\n return {\n mode: \"answer\",\n answer: resultCheck.warning,\n toolResult: result,\n autoExecute: false\n };\n }\n return this._formatToolResult(\n toolCall.tool,\n result.data,\n originalQuestion,\n onStatus,\n onTextDelta\n );\n }\n /** Alias for executeToolCall. */\n async confirmAndExecute(toolCall, originalQuestion) {\n return this.executeToolCall(toolCall, originalQuestion);\n }\n /** Get conversation history for display in chat. */\n getConversationHistory() {\n return this.memory.getMessages();\n }\n /** Recent redacted context for semantic conversational follow-ups. */\n getRecentConversationContext(count = 8) {\n return this.memory.getRecentForLLM(count);\n }\n /** Persist a completed Realtime turn so voice and text share one history. */\n recordRealtimeTurn(role, content) {\n const normalized = content.trim().slice(0, 4e3);\n if (!normalized) return;\n this.memory.addMessage({ role, content: normalized, timestamp: Date.now() });\n }\n /** Check if there is existing conversation history. */\n hasHistory() {\n return this.memory.hasHistory();\n }\n /** Clear conversation history. */\n clearHistory() {\n this.memory.clear();\n }\n // ----------------------------------------------------------------\n // Private methods\n // ----------------------------------------------------------------\n /**\n * Read SSE events from the backend agent loop stream.\n * Supports incremental text streaming, tool call display events, and cancellation.\n * Updates status via callback and resolves with the final response.\n */\n async _readSSEStream(rawResponse, originalQuestion, onStatus, onTextDelta, onToolCallEvent, abortSignal) {\n if (!rawResponse.stream) {\n return this._handleJsonResponse(\n await rawResponse.json(),\n void 0\n );\n }\n let buffer = \"\";\n let finalResponse = null;\n let accumulatedText = \"\";\n const toolCallRecords = [];\n try {\n for await (const chunk of rawResponse.stream) {\n if (abortSignal == null ? void 0 : abortSignal.aborted) break;\n buffer += chunk;\n const eventBlocks = buffer.split(\"\\n\\n\");\n buffer = eventBlocks.pop() || \"\";\n for (const block of eventBlocks) {\n const trimmedBlock = block.trim();\n if (!trimmedBlock) continue;\n for (const rawLine of trimmedBlock.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line.startsWith(\"data: \")) continue;\n const jsonStr = line.slice(6);\n let event;\n try {\n event = JSON.parse(jsonStr);\n } catch {\n continue;\n }\n switch (event.type) {\n case \"status\":\n onStatus == null ? void 0 : onStatus(event.message || \"Processing...\");\n break;\n case \"text_delta\":\n if (event.delta) {\n accumulatedText += event.delta;\n onTextDelta == null ? void 0 : onTextDelta(event.delta);\n }\n break;\n case \"tool_call_start\":\n if (event.tool) {\n onToolCallEvent == null ? void 0 : onToolCallEvent({\n type: \"start\",\n tool: event.tool,\n description: event.description\n });\n }\n onStatus == null ? void 0 : onStatus(event.description ? `${event.description}...` : \"Looking up data...\");\n break;\n case \"tool_call_done\":\n if (event.tool) {\n toolCallRecords.push({\n tool: event.tool,\n description: event.description || \"\",\n success: event.success ?? true,\n summary: event.summary\n });\n onToolCallEvent == null ? void 0 : onToolCallEvent({\n type: \"done\",\n tool: event.tool,\n success: event.success,\n summary: event.summary\n });\n }\n break;\n case \"tool_result\":\n onStatus == null ? void 0 : onStatus(\n event.success ? `Got data from ${(event.tool || \"\").replace(/_/g, \" \").slice(0, 40)}...` : \"Tool call failed.\"\n );\n break;\n case \"error\":\n finalResponse = {\n mode: \"answer\",\n answer: event.message || \"An error occurred.\",\n autoExecute: false\n };\n break;\n case \"done\":\n if (event.response) {\n finalResponse = this._parseStreamedResponse(event.response);\n if (!finalResponse.answer && accumulatedText) {\n const stripped = this._stripToolCallArtifacts(accumulatedText);\n finalResponse.answer = stripped || \"Here is the result of your request.\";\n }\n }\n break;\n }\n }\n }\n }\n } catch (err) {\n if (abortSignal == null ? void 0 : abortSignal.aborted) {\n if (accumulatedText) {\n const stripped = this._stripToolCallArtifacts(accumulatedText);\n const partialResponse = {\n mode: \"answer\",\n answer: stripped || \"Response cancelled.\",\n autoExecute: false\n };\n this.memory.addMessage({\n role: \"assistant\",\n content: accumulatedText,\n toolCalls: toolCallRecords.length > 0 ? toolCallRecords : void 0,\n timestamp: Date.now()\n });\n return partialResponse;\n }\n return this._errorResponse(\"Response cancelled.\");\n }\n console.error(\"[GuideAI] SSE stream error:\", err);\n }\n if (!finalResponse && accumulatedText) {\n const stripped = this._stripToolCallArtifacts(accumulatedText);\n finalResponse = {\n mode: \"answer\",\n answer: stripped || \"Here is the result of your request.\",\n autoExecute: false\n };\n }\n if (finalResponse) {\n if (finalResponse.autoExecuteToolCall && finalResponse.pendingToolCall) {\n return this._executePendingToolCall(\n finalResponse.pendingToolCalls ?? [finalResponse.pendingToolCall],\n originalQuestion,\n onStatus,\n onTextDelta,\n onToolCallEvent\n );\n }\n this.memory.addMessage({\n role: \"assistant\",\n content: finalResponse.answer,\n toolResult: finalResponse.toolResult,\n toolCalls: toolCallRecords.length > 0 ? toolCallRecords : void 0,\n guideSteps: finalResponse.guideSteps,\n guideTitle: finalResponse.guideTitle,\n navigation: finalResponse.navigation,\n mode: finalResponse.mode,\n confirmationNeeded: finalResponse.confirmationNeeded,\n pendingToolCall: finalResponse.pendingToolCall,\n demo: finalResponse.demo,\n timestamp: Date.now()\n });\n return finalResponse;\n }\n return this._errorResponse(\"Agent loop completed but no response was received.\");\n }\n /**\n * Parse the ChatAskResponse from a streamed \"done\" event into HarnessResponse.\n */\n /**\n * Strip tool_call artifacts from streamed text so raw JSON is never shown.\n *\n * Handles:\n * - Fenced code blocks: ```tool_call\\n{...}```\n * - Bare JSON objects with a \"tool\" key: {\"tool\":\"list_guides\",\"params\":{}}\n * - Standalone mode: lines (mode: execute)\n */\n _stripToolCallArtifacts(text) {\n let stripped = text.replace(/<thinking\\b[^>]*>[\\s\\S]*?<\\/thinking>/gi, \"\").replace(/^\\s*<\\/?thinking\\b[^>]*>\\s*$/gim, \"\");\n stripped = stripped.replace(/```tool_\\w+\\s*\\n[\\s\\S]*?```/g, \"\").replace(/```tool_\\w+[\\s\\S]*?```/g, \"\");\n let result = \"\";\n let i = 0;\n while (i < stripped.length) {\n if (stripped[i] === \"{\") {\n let depth = 0;\n let j = i;\n while (j < stripped.length) {\n if (stripped[j] === \"{\") depth++;\n else if (stripped[j] === \"}\") {\n depth--;\n if (depth === 0) break;\n }\n j++;\n }\n if (depth === 0 && j < stripped.length) {\n const block = stripped.slice(i, j + 1);\n let parsed = null;\n try {\n parsed = JSON.parse(block);\n } catch {\n if (block.includes(\"{{\")) {\n try {\n parsed = JSON.parse(block.replace(/\\{\\{/g, \"{\").replace(/\\}\\}/g, \"}\"));\n } catch {\n }\n }\n }\n if (parsed && typeof parsed === \"object\" && \"tool\" in parsed) {\n i = j + 1;\n continue;\n }\n }\n }\n result += stripped[i];\n i++;\n }\n result = result.replace(/^\\s*mode:\\s*\\w+\\s*$/gm, \"\");\n return result.trim();\n }\n _parseStreamedResponse(response) {\n var _a, _b, _c, _d;\n const respCheck = this.validator.validateResponse(response);\n const answer = respCheck.sanitized || response.answer || \"\";\n if ((_a = response.tool_call) == null ? void 0 : _a.requires_confirm) {\n return {\n mode: \"answer\",\n answer,\n confirmationNeeded: true,\n pendingToolCall: response.tool_call,\n autoExecute: false\n };\n }\n if (response.tool_call) {\n return {\n mode: \"answer\",\n answer,\n pendingToolCall: response.tool_call,\n pendingToolCalls: ((_b = response.tool_calls) == null ? void 0 : _b.length) ? response.tool_calls : [response.tool_call],\n autoExecuteToolCall: true,\n autoExecute: false\n };\n }\n let guideSteps = response.guide_steps || void 0;\n if (guideSteps && guideSteps.length > 0) {\n const stepCheck = this.validator.validateGuideSteps(guideSteps);\n guideSteps = stepCheck.valid ? stepCheck.steps : void 0;\n }\n let toolResult;\n if (response.tool_result) {\n toolResult = {\n success: response.tool_result.success ?? true,\n data: response.tool_result.data,\n error: response.tool_result.error,\n status: response.tool_result.status\n };\n }\n return {\n mode: response.mode || \"answer\",\n answer,\n intent: response.intent,\n intentReason: response.intent_reason || void 0,\n guideSteps,\n guideTitle: response.guide_title || void 0,\n navigation: response.navigation || void 0,\n toolResult,\n autoExecute: false,\n // disabled — never auto-click/scroll/fill on user's page\n escalation: response.escalation || void 0,\n demo: response.demo || void 0,\n point: response.point || void 0,\n actions: ((_c = response.actions) == null ? void 0 : _c.length) ? response.actions : void 0,\n payment: response.payment || void 0,\n coach: response.coach || void 0,\n quickReplies: ((_d = response.quick_replies) == null ? void 0 : _d.length) ? response.quick_replies : void 0\n };\n }\n /**\n * Handle a regular JSON response (non-streaming).\n */\n /**\n * Surface a plan to the UI once per chain.\n *\n * The chain revisits the server on every round, and a mid-chain response\n * may restate the plan. Re-announcing an identical plan would redraw it and\n * make the assistant look like it had started over, so only a changed plan\n * is emitted.\n */\n _announcePlan(plan) {\n var _a;\n if (!plan || !Array.isArray(plan.steps) || plan.steps.length === 0) {\n return void 0;\n }\n const fingerprint = JSON.stringify(plan.steps.map((s) => [s.title, s.tool]));\n if (fingerprint !== this.lastPlanFingerprint) {\n this.lastPlanFingerprint = fingerprint;\n this.currentPlan = plan;\n (_a = this.onPlan) == null ? void 0 : _a.call(this, plan);\n }\n return plan;\n }\n _handleJsonResponse(response, chatMode, toolResult) {\n var _a, _b, _c;\n const respCheck = this.validator.validateResponse(response);\n if (!respCheck.valid) {\n return this._errorResponse(respCheck.error || \"Invalid server response.\");\n }\n const answer = respCheck.sanitized || response.answer;\n const plan = this._announcePlan(response.plan) ?? this.currentPlan;\n if (response.tool_call && response.tool_call.requires_confirm) {\n return {\n mode: \"answer\",\n answer,\n plan,\n confirmationNeeded: true,\n pendingToolCall: response.tool_call,\n autoExecute: false\n };\n }\n if (response.tool_call) {\n return {\n mode: \"answer\",\n answer,\n plan,\n pendingToolCall: response.tool_call,\n pendingToolCalls: ((_a = response.tool_calls) == null ? void 0 : _a.length) ? response.tool_calls : [response.tool_call],\n autoExecuteToolCall: true,\n autoExecute: false\n };\n }\n let guideSteps = response.guide_steps || void 0;\n if (guideSteps && guideSteps.length > 0) {\n const stepCheck = this.validator.validateGuideSteps(guideSteps);\n if (stepCheck.warnings.length > 0) {\n console.warn(\"[GuideAI] Guide step warnings:\", stepCheck.warnings);\n }\n guideSteps = stepCheck.valid ? stepCheck.steps : void 0;\n }\n const harnessResult = {\n mode: response.mode || \"guide\",\n answer,\n plan,\n intent: response.intent,\n intentReason: response.intent_reason || void 0,\n guideSteps,\n guideTitle: response.guide_title || void 0,\n navigation: response.navigation || void 0,\n toolResult,\n autoExecute: false,\n // disabled — never auto-click/scroll/fill on user's page\n escalation: response.escalation || void 0,\n demo: response.demo || void 0,\n point: response.point || void 0,\n actions: ((_b = response.actions) == null ? void 0 : _b.length) ? response.actions : void 0,\n payment: response.payment || void 0,\n coach: response.coach || void 0,\n quickReplies: ((_c = response.quick_replies) == null ? void 0 : _c.length) ? response.quick_replies : void 0\n };\n this.memory.addMessage({\n role: \"assistant\",\n content: answer,\n toolResult,\n guideSteps: harnessResult.guideSteps,\n guideTitle: harnessResult.guideTitle,\n navigation: harnessResult.navigation,\n mode: harnessResult.mode,\n escalation: harnessResult.escalation,\n demo: harnessResult.demo,\n timestamp: Date.now()\n });\n return harnessResult;\n }\n async _continueToolChain(latestToolName, latestToolResult, originalQuestion, toolHistory, onStatus, onTextDelta, latestBatch, budget) {\n const conversationHistory = this.memory.getRecentForLLM(6);\n if (onStatus) {\n onStatus(\n (budget == null ? void 0 : budget.forceAnswer) ? \"Writing up what I found...\" : latestBatch && latestBatch.length > 1 ? \"Compiling the information together...\" : \"Reviewing what came back...\"\n );\n }\n const response = await this.api.post(\n EP.chatContinue(),\n {\n original_question: originalQuestion,\n latest_tool_name: latestToolName,\n latest_tool_result: latestToolResult,\n latest_batch: latestBatch ?? [],\n conversation_history: conversationHistory,\n tool_history: toolHistory,\n tools_remaining: budget == null ? void 0 : budget.toolsRemaining,\n force_answer: (budget == null ? void 0 : budget.forceAnswer) ?? false,\n tool_context: this.toolContext,\n client_tools: this.tools.definitions()\n }\n );\n const harnessResponse = this._handleJsonResponse(\n response,\n \"assistant\",\n { success: true, data: latestToolResult }\n );\n if (!harnessResponse.autoExecuteToolCall && onTextDelta && harnessResponse.answer) {\n this._emitAnswerText(harnessResponse.answer, onTextDelta);\n }\n return harnessResponse;\n }\n /**\n * Remove calls that have already been made in this chain.\n *\n * The model is told not to repeat itself, and mostly does not, but a long\n * chain occasionally re-requests an endpoint it already has — which costs a\n * request and a model round trip to learn nothing new.\n */\n _dropRepeats(toolCalls, executed, callKey) {\n return toolCalls.filter((call) => !executed.has(callKey(call)));\n }\n /**\n * Run a client-executed tool chain.\n *\n * Each round the model may request either one tool or a batch of\n * independent tools. A batch is executed concurrently, so the wall-clock\n * cost of gathering four unrelated resources is one request plus one model\n * round trip, rather than four of each. Dependent calls still arrive one at\n * a time — the model only batches what it can run without waiting.\n */\n async _runClientToolChain(initialToolCalls, originalQuestion, onStatus, onTextDelta, onToolCallEvent) {\n if (!this.hasAnyLocalTools()) {\n return this._errorResponse(\"Tool execution is unavailable in this browser context.\");\n }\n const toolHistory = [];\n const executed = /* @__PURE__ */ new Set();\n const callKey = (call) => `${call.tool}:${JSON.stringify(call.params ?? {})}:${JSON.stringify(call.body ?? {})}`;\n let currentBatch = this._dropRepeats(initialToolCalls, executed, callKey);\n let toolsRun = 0;\n let repairsUsed = 0;\n for (let iteration = 0; currentBatch.length > 0 && iteration < MAX_CHAIN_ROUNDS; iteration += 1) {\n if (toolsRun + currentBatch.length > MAX_TOTAL_TOOL_CALLS) {\n currentBatch = currentBatch.slice(0, Math.max(0, MAX_TOTAL_TOOL_CALLS - toolsRun));\n if (currentBatch.length === 0) break;\n }\n currentBatch.forEach((call) => executed.add(callKey(call)));\n toolsRun += currentBatch.length;\n const results = await this.executeLocalToolBatch(\n currentBatch,\n (toolCall, result) => {\n const check = this.validator.validateToolResultEnhanced(result);\n onToolCallEvent == null ? void 0 : onToolCallEvent({\n type: \"done\",\n tool: toolCall.tool,\n success: check.valid,\n // The card's badge already shows Complete/Error and its title\n // already shows the label, so only send extra detail worth\n // reading — a warning, or why it failed.\n summary: check.valid ? check.warning : check.error || \"Failed\"\n });\n }\n );\n const batchSteps = [];\n const failures = [];\n let anyRepairable = false;\n let lastGoodResult;\n results.forEach((rawResult, i) => {\n const toolCall = currentBatch[i];\n const check = this.validator.validateToolResultEnhanced(rawResult);\n if (!check.valid) {\n failures.push(check.error || \"Tool execution failed.\");\n if (REPAIRABLE_ERROR_TYPES.has(check.errorType || \"\")) anyRepairable = true;\n batchSteps.push({\n tool_name: toolCall.tool,\n tool_result: {\n error: check.detail || rawResult.error || check.error || \"Tool execution failed.\"\n }\n });\n return;\n }\n lastGoodResult = rawResult;\n batchSteps.push({ tool_name: toolCall.tool, tool_result: rawResult.data });\n });\n const allFailed = failures.length === results.length;\n const canRepair = allFailed && anyRepairable && repairsUsed < MAX_REPAIR_ROUNDS;\n if (allFailed && !canRepair) {\n const errorMsg = failures[0] || \"Tool execution failed.\";\n this.memory.addMessage({\n role: \"assistant\",\n content: errorMsg,\n toolResult: results[0],\n timestamp: Date.now()\n });\n if (onTextDelta) {\n onTextDelta(errorMsg);\n }\n return {\n mode: \"answer\",\n answer: errorMsg,\n toolResult: results[0],\n autoExecute: false\n };\n }\n if (canRepair) {\n repairsUsed += 1;\n onStatus == null ? void 0 : onStatus(\"That did not go through — adjusting and trying again...\");\n }\n toolHistory.push(...batchSteps);\n const latestStep = batchSteps[batchSteps.length - 1];\n const toolsRemaining = Math.max(0, MAX_TOTAL_TOOL_CALLS - toolsRun);\n const forceAnswer = toolsRemaining === 0 || iteration === MAX_CHAIN_ROUNDS - 1;\n const continued = await this._continueToolChain(\n latestStep.tool_name,\n latestStep.tool_result,\n originalQuestion,\n toolHistory,\n onStatus,\n onTextDelta,\n batchSteps,\n { toolsRemaining, forceAnswer }\n );\n const nextBatch = this._dropRepeats(\n continued.pendingToolCalls ?? (continued.pendingToolCall ? [continued.pendingToolCall] : []),\n executed,\n callKey\n );\n if (continued.autoExecuteToolCall && nextBatch.length > 0) {\n currentBatch = nextBatch;\n onStatus == null ? void 0 : onStatus(describeToolBatch(currentBatch));\n for (const toolCall of currentBatch) {\n onToolCallEvent == null ? void 0 : onToolCallEvent({\n type: \"start\",\n tool: toolCall.tool,\n description: describeToolCall(toolCall)\n });\n }\n continue;\n }\n if (!continued.toolResult && lastGoodResult) {\n continued.toolResult = lastGoodResult;\n }\n return continued;\n }\n if (toolHistory.length > 0) {\n const last = toolHistory[toolHistory.length - 1];\n return this._continueToolChain(\n last.tool_name,\n last.tool_result,\n originalQuestion,\n toolHistory,\n onStatus,\n onTextDelta,\n void 0,\n { toolsRemaining: 0, forceAnswer: true }\n );\n }\n const fallback = \"I gathered several data points but hit the maximum number of tool steps.\";\n this.memory.addMessage({\n role: \"assistant\",\n content: fallback,\n timestamp: Date.now()\n });\n return {\n mode: \"answer\",\n answer: fallback,\n autoExecute: false\n };\n }\n hasAnyLocalTools() {\n return !!this.toolExecutor || this.tools.definitions().length > 0;\n }\n canExecuteTool(toolCall) {\n if (this.tools.canExecute(toolCall.tool)) {\n return this.tools.canExecuteCall(toolCall);\n }\n return !!this.toolExecutor;\n }\n executeLocalTool(toolCall) {\n if (this.tools.canExecute(toolCall.tool)) {\n return this.tools.execute(toolCall);\n }\n if (this.toolExecutor) return this.toolExecutor.execute(toolCall);\n return Promise.resolve({\n success: false,\n error: \"Tool execution is unavailable in this browser context.\",\n error_type: \"tool_unavailable\"\n });\n }\n executeLocalToolBatch(toolCalls, onComplete) {\n return Promise.all(toolCalls.map(async (toolCall) => {\n const result = await this.executeLocalTool(toolCall);\n onComplete == null ? void 0 : onComplete(toolCall, result);\n return result;\n }));\n }\n async _formatToolResult(toolName, toolResult, originalQuestion, onStatus, onTextDelta) {\n const conversationHistory = this.memory.getRecentForLLM(3);\n try {\n if (onStatus) {\n onStatus(\"Processing results...\");\n }\n const rawResponse = await this.api.postRaw(\n EP.chatFormat(),\n {\n tool_name: toolName,\n tool_result: toolResult,\n original_question: originalQuestion,\n conversation_history: conversationHistory,\n stream: this.api.supportsStreaming\n }\n );\n const contentType = rawResponse.headers.get(\"content-type\") || \"\";\n if (contentType.includes(\"text/event-stream\")) {\n return this._readFormatToolResultStream(\n rawResponse,\n toolResult,\n onStatus,\n onTextDelta\n );\n }\n const formatted = await rawResponse.json();\n const rawAnswer = (formatted == null ? void 0 : formatted.answer) || \"Here is the result of your request.\";\n const answer = this.validator.validateFormattedResponse(\n rawAnswer,\n { success: true, data: toolResult }\n );\n const navigation = (formatted == null ? void 0 : formatted.navigation) || void 0;\n const guideSteps = (formatted == null ? void 0 : formatted.guide_steps) || void 0;\n const guideTitle = (formatted == null ? void 0 : formatted.guide_title) || void 0;\n const mode = (formatted == null ? void 0 : formatted.mode) === \"execute\" ? \"execute\" : \"answer\";\n this.memory.addMessage({\n role: \"assistant\",\n content: answer,\n toolResult: { success: true, data: toolResult },\n guideSteps,\n guideTitle,\n navigation,\n mode,\n timestamp: Date.now()\n });\n return {\n mode,\n answer,\n guideSteps,\n guideTitle,\n navigation,\n toolResult: { success: true, data: toolResult },\n autoExecute: false\n };\n } catch {\n const fallback = \"I fetched the data successfully but had trouble formatting it.\";\n this.memory.addMessage({\n role: \"assistant\",\n content: fallback,\n timestamp: Date.now()\n });\n return {\n mode: \"answer\",\n answer: fallback,\n toolResult: { success: true, data: toolResult },\n autoExecute: false\n };\n }\n }\n async _readFormatToolResultStream(rawResponse, toolResult, onStatus, onTextDelta) {\n let buffer = \"\";\n let accumulatedText = \"\";\n let finalResponse = null;\n let streamError = null;\n if (!rawResponse.stream) {\n try {\n finalResponse = await rawResponse.json();\n } catch {\n streamError = \"I got the data but had trouble formatting it.\";\n }\n }\n try {\n for await (const chunk of rawResponse.stream ?? []) {\n buffer += chunk;\n const eventBlocks = buffer.split(\"\\n\\n\");\n buffer = eventBlocks.pop() || \"\";\n for (const block of eventBlocks) {\n const trimmedBlock = block.trim();\n if (!trimmedBlock) continue;\n for (const rawLine of trimmedBlock.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line.startsWith(\"data: \")) continue;\n let event;\n try {\n event = JSON.parse(line.slice(6));\n } catch {\n continue;\n }\n switch (event.type) {\n case \"status\":\n onStatus == null ? void 0 : onStatus(event.message || \"Processing results...\");\n break;\n case \"text_delta\":\n if (event.delta) {\n accumulatedText += event.delta;\n onTextDelta == null ? void 0 : onTextDelta(event.delta);\n }\n break;\n case \"error\":\n streamError = event.message || \"I got the data but had trouble formatting it.\";\n break;\n case \"done\":\n if (event.format_response) {\n finalResponse = event.format_response;\n }\n break;\n }\n }\n }\n }\n } catch {\n streamError = \"I got the data but had trouble formatting it.\";\n }\n if (streamError) {\n this.memory.addMessage({\n role: \"assistant\",\n content: streamError,\n timestamp: Date.now()\n });\n return {\n mode: \"answer\",\n answer: streamError,\n toolResult: { success: true, data: toolResult },\n autoExecute: false\n };\n }\n const rawAnswer = (finalResponse == null ? void 0 : finalResponse.answer) || accumulatedText || \"Here is the result of your request.\";\n const answer = this.validator.validateFormattedResponse(\n rawAnswer,\n { success: true, data: toolResult }\n );\n const navigation = (finalResponse == null ? void 0 : finalResponse.navigation) || void 0;\n const guideSteps = (finalResponse == null ? void 0 : finalResponse.guide_steps) || void 0;\n const guideTitle = (finalResponse == null ? void 0 : finalResponse.guide_title) || void 0;\n const mode = (finalResponse == null ? void 0 : finalResponse.mode) === \"execute\" ? \"execute\" : \"answer\";\n this.memory.addMessage({\n role: \"assistant\",\n content: answer,\n toolResult: { success: true, data: toolResult },\n guideSteps,\n guideTitle,\n navigation,\n mode,\n timestamp: Date.now()\n });\n return {\n mode,\n answer,\n guideSteps,\n guideTitle,\n navigation,\n toolResult: { success: true, data: toolResult },\n autoExecute: false\n };\n }\n async _executePendingToolCall(toolCalls, originalQuestion, onStatus, onTextDelta, onToolCallEvent) {\n if (toolCalls.length === 0) {\n return this._errorResponse(\"No tool call to execute.\");\n }\n onStatus == null ? void 0 : onStatus(describeToolBatch(toolCalls));\n for (const toolCall of toolCalls) {\n onToolCallEvent == null ? void 0 : onToolCallEvent({\n type: \"start\",\n tool: toolCall.tool,\n description: describeToolCall(toolCall)\n });\n }\n const result = await this._runClientToolChain(\n toolCalls,\n originalQuestion,\n onStatus,\n onTextDelta,\n onToolCallEvent\n );\n if (!result.toolResult) {\n onToolCallEvent == null ? void 0 : onToolCallEvent({\n type: \"done\",\n tool: toolCalls[0].tool,\n success: false,\n summary: result.answer || \"Failed\"\n });\n }\n return result;\n }\n /**\n * Emit a fully-buffered answer to the UI.\n *\n * This used to fake a typing effect by releasing one word every 12ms. The\n * response has already arrived in full by this point, so that delay was pure\n * added latency — a 250-word answer sat behind three seconds of animation\n * after the data was on the client. Real streaming still arrives token by\n * token over SSE; a buffered answer is shown as soon as we have it.\n */\n _emitAnswerText(text, onTextDelta, abortSignal) {\n if (abortSignal == null ? void 0 : abortSignal.aborted) return;\n onTextDelta(text);\n }\n _errorResponse(message) {\n return {\n mode: \"guide\",\n answer: message,\n autoExecute: false\n };\n }\n}\nfunction buildAssistantUserContext(visitor, account) {\n const context = {};\n const safeString = (value) => {\n if (typeof value !== \"string\") return void 0;\n const compact = value.trim().replace(/\\s+/g, \" \").slice(0, 200);\n return compact || void 0;\n };\n if (visitor) {\n const safeVisitor = {};\n for (const key of [\"full_name\", \"role\"]) {\n const value = safeString(visitor[key]);\n if (value) safeVisitor[key] = value;\n }\n if (Object.keys(safeVisitor).length > 0) context.visitor = safeVisitor;\n }\n if (account) {\n const safeAccount = {};\n for (const key of [\"name\", \"planLevel\"]) {\n const value = safeString(account[key]);\n if (value) safeAccount[key] = value;\n }\n if (typeof account.is_paying === \"boolean\") safeAccount.is_paying = account.is_paying;\n if (Object.keys(safeAccount).length > 0) context.account = safeAccount;\n }\n return Object.keys(context).length > 0 ? context : void 0;\n}\nconst CATALOG = {\n en: {\n label: \"English\",\n transcriptionLanguages: [\"en\"],\n transcriptionPrompt: \"The selected language is English. Transcribe English exactly as spoken. Do not switch languages, translate, summarize, or answer.\",\n speechInstructions: \"Speak in English only.\"\n },\n // Nigerian Pidgin has no recognizer or voice of its own at our providers.\n // It is English-lexified, so it is heard as English, primed with its common\n // words; the agent already answers in the visitor's own dialect. Opt-in\n // only (data-voice-language-codes), never a default.\n pcm: {\n label: \"Nigerian Pidgin\",\n transcriptionLanguages: [\"en\"],\n transcriptionPrompt: \"The speaker talks Nigerian Pidgin English (Naija). Common words: wetin, abeg, dey, una, oya, wahala, sabi, abi, sef, don, na, dem, pikin, how far, no wahala, I no fit, make I, wey. Transcribe the Pidgin words exactly as spoken; do not convert them to standard English, translate, summarize, or answer.\",\n speechInstructions: \"Speak in Nigerian Pidgin English with a warm Nigerian accent.\"\n },\n fr: {\n label: \"French\",\n transcriptionLanguages: [\"fr\"],\n transcriptionPrompt: \"Transcribe French exactly as spoken. Do not translate, summarize, or answer.\"\n },\n pt: {\n label: \"Portuguese\",\n transcriptionLanguages: [\"pt\"],\n transcriptionPrompt: \"Transcribe Portuguese exactly as spoken. Do not translate, summarize, or answer.\"\n },\n es: {\n label: \"Spanish\",\n transcriptionLanguages: [\"es\"],\n transcriptionPrompt: \"Transcribe Spanish exactly as spoken. Do not translate, summarize, or answer.\"\n },\n ar: {\n label: \"Arabic\",\n transcriptionLanguages: [\"ar\"],\n transcriptionPrompt: \"Transcribe Arabic exactly as spoken. Do not translate, summarize, or answer.\"\n },\n \"zh-cn\": {\n label: \"Chinese (Mandarin)\",\n transcriptionLanguages: [\"zh-cn\"],\n transcriptionPrompt: \"Transcribe Mandarin Chinese exactly as spoken. Do not translate, summarize, or answer.\"\n }\n};\nconst DEFAULT_VOICE_LANGUAGE_CODES = [\"en\", \"fr\", \"pt\", \"es\", \"ar\", \"zh-CN\"];\nfunction normalizeVoiceLanguageCode(code) {\n return code.trim().replace(/_/g, \"-\").toLowerCase().slice(0, 35);\n}\nfunction resolveVoiceLanguage(code) {\n const normalized = normalizeVoiceLanguageCode(code) || \"en\";\n const exact = CATALOG[normalized];\n if (exact) return { code: canonicalCode(normalized), ...exact };\n const primary = normalized.split(\"-\")[0];\n const primaryEntry = CATALOG[primary];\n if (primaryEntry) return { code: canonicalCode(normalized), ...primaryEntry };\n return {\n code: canonicalCode(normalized),\n label: displayLanguageName(normalized),\n transcriptionLanguages: [primary],\n transcriptionPrompt: `The speaker selected ${displayLanguageName(normalized)}. Transcribe exactly as spoken. Do not translate, summarize, or answer.`\n };\n}\nfunction listVoiceLanguages(codes) {\n const seen = /* @__PURE__ */ new Set();\n const result = [];\n for (const raw of ((codes == null ? void 0 : codes.length) ? codes : DEFAULT_VOICE_LANGUAGE_CODES).slice(0, 8)) {\n const language = resolveVoiceLanguage(raw);\n const key = normalizeVoiceLanguageCode(language.code);\n if (!key || seen.has(key)) continue;\n seen.add(key);\n result.push(language);\n }\n return result.length ? result : [resolveVoiceLanguage(\"en\")];\n}\nfunction isUnexpectedTranscriptScript(text, language) {\n if (!(language == null ? void 0 : language.transcriptionLanguages.includes(\"en\"))) return false;\n const letters = Array.from(text).filter((char) => new RegExp(\"\\\\p{L}\", \"u\").test(char));\n if (letters.length < 3) return false;\n const latin = letters.filter((char) => new RegExp(\"\\\\p{Script=Latin}\", \"u\").test(char)).length;\n const unrelated = letters.filter((char) => new RegExp(\"\\\\p{Script=Han}|\\\\p{Script=Hiragana}|\\\\p{Script=Katakana}|\\\\p{Script=Arabic}|\\\\p{Script=Cyrillic}\", \"u\").test(char)).length;\n return unrelated >= 3 && unrelated / letters.length >= 0.45 && latin / letters.length < 0.35;\n}\nfunction canonicalCode(normalized) {\n return normalized.split(\"-\").map((part, index) => {\n if (index === 0) return part.toLowerCase();\n return part.length === 2 ? part.toUpperCase() : part;\n }).join(\"-\");\n}\nfunction displayLanguageName(code) {\n try {\n const DisplayNames = Intl.DisplayNames;\n const label = DisplayNames ? new DisplayNames([\"en\"], { type: \"language\" }).of(code) : void 0;\n if (label) return label;\n } catch {\n }\n return code.toUpperCase();\n}\nexport {\n AuthError,\n ConversationMemory,\n ConversationOrchestrator,\n CopilotHarness,\n CryptoManager,\n DEFAULT_VOICE_LANGUAGE_CODES,\n EP,\n EmptyToolRegistry,\n EncryptionError,\n HarnessValidator,\n HeadlessChatView,\n MemoryKVStore,\n PlanAccessError,\n TimeoutError,\n ToolExecutor,\n UsageLimitError,\n buildAssistantUserContext,\n createConversationState,\n describeToolBatch,\n describeToolCall,\n headlessImages,\n isUnexpectedTranscriptScript,\n listVoiceLanguages,\n normalizeVoiceLanguageCode,\n reduceConversation,\n resolveVoiceLanguage,\n toBase64Url,\n toHeadlessReply,\n utf8Encode\n};\n//# sourceMappingURL=index.mjs.map\n","// ============================================================\n// @guideai/react-native — HTTP transport\n// ============================================================\n//\n// React Native's `fetch` is implemented over XHR and does NOT support\n// `response.body.getReader()` — reading a body progressively through it\n// is impossible, and the failure is silent: you get the whole body at\n// the end, so streaming \"works\" but never streams.\n//\n// So this goes to XMLHttpRequest directly, which does expose progressive\n// `responseText` at readyState 3.\n// ============================================================\n\nimport type {\n HttpRequest,\n HttpResponse,\n HttpTransport,\n TextStream,\n} from '@guideai/core';\n\n/**\n * The header the backend accepts in place of a browser `Origin`.\n *\n * A native app sends no `Origin` (there is no browser and no CORS), and\n * `get_effective_request_origin()` in the backend's request_origin_guard\n * falls back to this one. It is then matched against the site's own\n * domain + aliases, so it can only ever name a domain the site owner has\n * already registered — it cannot authorize an unlisted one.\n *\n * It is NOT proof of app identity: anyone who extracts the public token\n * from an APK can send the same header. The web SDK has the identical\n * property. Treat it as origin declaration, not authentication.\n */\nexport const REQUEST_ORIGIN_HEADER = 'x-guideai-request-origin';\n\n/**\n * Parse `getAllResponseHeaders()`'s CRLF-delimited block into a lookup.\n *\n * `raw` is nullable: React Native returns null before headers arrive and\n * on some reused connections. The DOM types say `string`, which is why\n * this crashed as \"Cannot read property 'split' of null\" only on the\n * second request of a turn — the tool call.\n */\nfunction parseHeaders(raw: string | null): { get(name: string): string | null } {\n const map = new Map<string, string>();\n for (const line of (raw ?? '').split(/\\r?\\n/)) {\n const colon = line.indexOf(':');\n if (colon <= 0) continue;\n map.set(line.slice(0, colon).trim().toLowerCase(), line.slice(colon + 1).trim());\n }\n return { get: (name: string) => map.get(name.toLowerCase()) ?? null };\n}\n\nexport interface RNTransportOptions {\n /**\n * The registered site domain this app reports as its origin, e.g.\n * `https://app.example.com`. Required by the backend's origin guard;\n * without it every public endpoint answers 403.\n */\n requestOrigin?: string;\n}\n\n/**\n * How long to wait for a server to START responding, in ms.\n *\n * Not a total-duration cap: `xhr.timeout` measures the whole request, and\n * a chat stream legitimately stays open for minutes, so setting that would\n * cut replies off mid-sentence. This fires only while nothing at all has\n * come back — the case where a tool set points at a host that is not\n * there, and the request otherwise hangs for the two minutes the OS takes\n * to give up while the assistant shows a spinner.\n */\nconst RESPONSE_START_TIMEOUT_MS = 20_000;\n\nexport class RNHttpTransport implements HttpTransport {\n /**\n * True when XHR exists at all. React Native always provides it; the\n * check exists so a Node test runner or an unusual runtime degrades to\n * a buffered response rather than throwing at construction.\n */\n readonly supportsStreaming: boolean;\n\n constructor(private readonly options: RNTransportOptions = {}) {\n this.supportsStreaming = typeof XMLHttpRequest !== 'undefined';\n }\n\n request(req: HttpRequest): Promise<HttpResponse> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open(req.method, req.url);\n\n const headers: Record<string, string> = { ...req.headers };\n if (this.options.requestOrigin && !headers[REQUEST_ORIGIN_HEADER]) {\n headers[REQUEST_ORIGIN_HEADER] = this.options.requestOrigin;\n }\n for (const [name, value] of Object.entries(headers)) {\n xhr.setRequestHeader(name, value);\n }\n\n // Streaming consumers park here until each new slice arrives.\n const doneCallbacks: Array<() => void> = [];\n let delivered = 0;\n let pending: string[] = [];\n let finished = false;\n let failure: Error | null = null;\n let wake: (() => void) | null = null;\n\n const push = (chunk: string) => {\n if (chunk) pending.push(chunk);\n wake?.();\n wake = null;\n };\n\n const drainResponseText = () => {\n // responseText is cumulative, so yield only what is new. Getting\n // this offset wrong duplicates or drops text with no error.\n const text = xhr.responseText;\n if (text.length > delivered) {\n const slice = text.slice(delivered);\n delivered = text.length;\n push(slice);\n }\n };\n\n let startTimer: ReturnType<typeof setTimeout> | null = null;\n const clearStartTimer = () => {\n if (startTimer === null) return;\n clearTimeout(startTimer);\n startTimer = null;\n };\n\n const fail = (error: Error) => {\n clearStartTimer();\n // A timeout has already rejected; a later onabort/onerror from the\n // same abort() must not reject a second time.\n if (finished) return;\n failure = error;\n finished = true;\n push('');\n reject(error);\n };\n\n // Resolve once headers are known, so the caller can inspect the\n // content type and start reading before the body completes.\n let resolved = false;\n const resolveOnce = () => {\n if (resolved) return;\n resolved = true;\n // Headers are in — the server is alive, so the rest of the\n // response may take as long as it needs.\n clearStartTimer();\n\n const stream: TextStream = {\n async *[Symbol.asyncIterator]() {\n while (true) {\n if (pending.length) {\n const batch = pending;\n pending = [];\n for (const chunk of batch) yield chunk;\n continue;\n }\n if (failure) throw failure;\n if (finished) return;\n await new Promise<void>((wakeUp) => { wake = wakeUp; });\n }\n },\n };\n\n // Body text for the non-streaming path. Read lazily: touching\n // responseText early is fine, but the value is only complete once\n // the request finishes, so json()/text() await that.\n const whenDone = new Promise<string>((done, error) => {\n const settle = () => {\n if (failure) error(failure);\n else done(xhr.responseText);\n };\n if (finished) settle();\n else doneCallbacks.push(settle);\n });\n\n resolve({\n status: xhr.status,\n headers: parseHeaders(xhr.getAllResponseHeaders()),\n json: async <T,>() => JSON.parse(await whenDone) as T,\n text: () => whenDone,\n stream,\n });\n };\n\n xhr.onreadystatechange = () => {\n if (xhr.readyState === 2) {\n resolveOnce();\n } else if (xhr.readyState === 3) {\n resolveOnce();\n drainResponseText();\n } else if (xhr.readyState === 4) {\n resolveOnce();\n drainResponseText();\n finished = true;\n push('');\n for (const callback of doneCallbacks) callback();\n }\n };\n\n xhr.onerror = () => fail(new Error(`Network request failed: ${req.method} ${req.url}`));\n xhr.ontimeout = () => fail(new Error(`Request timed out: ${req.url}`));\n xhr.onabort = () => fail(new Error(`Request aborted: ${req.url}`));\n\n if (req.signal) {\n // Core's AbortSignal is declared with only `aborted` — it never\n // originates cancellation, so there is no addEventListener here.\n // Checking once before send covers an already-aborted signal.\n if (req.signal.aborted) {\n fail(new Error(`Request aborted: ${req.url}`));\n return;\n }\n }\n\n // Armed only now, so the callback closes over a fully initialised\n // `fail`. A tool set pointing at an unreachable host otherwise\n // leaves the assistant spinning for however long the OS takes to\n // give up — about two minutes — with no way to tell it failed.\n startTimer = setTimeout(() => {\n startTimer = null;\n fail(new Error(\n `No response after ${RESPONSE_START_TIMEOUT_MS}ms: ${req.method} ${req.url}`,\n ));\n // Abort last: onabort calls fail(), which is now a no-op because\n // the timeout above already settled the promise.\n try { xhr.abort(); } catch { /* already gone */ }\n }, RESPONSE_START_TIMEOUT_MS);\n\n xhr.send(req.body ?? null);\n });\n }\n}\n","// ============================================================\n// @guideai/react-native — platform adapter\n// ============================================================\n//\n// Core's KVStore is SYNCHRONOUS (see platform-adapter.ts): conversation\n// memory reads storage inside getMessages(), which the agent loop calls\n// from ~20 sync places. That rules out AsyncStorage entirely.\n//\n// MMKV and expo-sqlite/kv-store are both sync and both work. This module\n// does not import either one — it takes whichever the host already has,\n// so this package adds no native dependency of its own.\n// ============================================================\n\nimport type { CredentialSource, KVStore, PlatformAdapter } from '@guideai/core';\n\n/**\n * The slice of MMKV this needs. Declared structurally so `new MMKV()`\n * satisfies it without this package depending on react-native-mmkv.\n */\nexport interface SyncNativeStore {\n getString(key: string): string | undefined;\n set(key: string, value: string): void;\n delete(key: string): void;\n}\n\n/** Adapts MMKV's getString/set/delete to core's getItem/setItem/removeItem. */\nexport class NativeKVStore implements KVStore {\n constructor(private readonly store: SyncNativeStore) {}\n\n getItem(key: string): string | null {\n // MMKV returns undefined for a missing key; core's contract says null.\n return this.store.getString(key) ?? null;\n }\n\n setItem(key: string, value: string): void {\n this.store.set(key, value);\n }\n\n removeItem(key: string): void {\n this.store.delete(key);\n }\n}\n\n/** In-memory KVStore. Session storage, and the fallback when no native store is supplied. */\nexport class MemoryStore implements KVStore {\n private readonly map = new Map<string, string>();\n getItem(key: string): string | null { return this.map.get(key) ?? null; }\n setItem(key: string, value: string): void { this.map.set(key, value); }\n removeItem(key: string): void { this.map.delete(key); }\n}\n\n/**\n * Credentials on React Native.\n *\n * A native app has no cookie jar, so `cookie` returns null — the contract\n * explicitly prefers that over an empty string that would read as\n * \"present but blank\". `localStorage`/`sessionStorage` map onto the\n * stores the host provided, which is where an RN app actually keeps a\n * token.\n */\nexport class RNCredentialSource implements CredentialSource {\n /** The signed-in user's token, as the host last handed it over. */\n private hostToken: string | null = null;\n\n constructor(\n private readonly storage: KVStore,\n private readonly session: KVStore,\n ) {}\n\n /**\n * Set by the runtime from `getAuthToken()` before every turn, so the\n * synchronous read inside a tool call sees the host's current login.\n */\n setAuthToken(token: string | null): void {\n this.hostToken = token?.trim() || null;\n }\n\n authToken(): string | null {\n return this.hostToken;\n }\n\n read(source: string, key: string): string | null {\n switch (source) {\n case 'localStorage': return this.storage.getItem(key);\n case 'sessionStorage': return this.session.getItem(key);\n // No cookie jar on a device. Saying so is the honest answer.\n case 'cookie': return null;\n default: return null;\n }\n }\n}\n\nexport interface RNPlatformOptions {\n /** An MMKV instance (or anything sync-shaped). Omitted → memory only, lost on relaunch. */\n store?: SyncNativeStore;\n}\n\nexport function rnPlatform(\n options: RNPlatformOptions = {},\n): Required<PlatformAdapter> & { credentials: RNCredentialSource } {\n const storage: KVStore = options.store ? new NativeKVStore(options.store) : new MemoryStore();\n const session: KVStore = new MemoryStore();\n return { storage, session, credentials: new RNCredentialSource(storage, session) };\n}\n","// ============================================================\n// @guideai/react-native — the host's own login, for its own API\n// ============================================================\n//\n// In assistant mode the model calls the site's API as the signed-in user,\n// from the device, with that user's token. The web SDK finds the token in\n// browser storage under a key the dashboard names. A native app keeps it\n// wherever it likes — SecureStore, AsyncStorage — often behind an async\n// read, and refreshes it when it expires. So the host hands it over:\n//\n// GuideAI.configure({\n// apiKey, origin,\n// getAuthToken: () => AsyncStorage.getItem('accessToken'),\n// onAuthExpired: () => refreshSession(), // returns the new token\n// });\n//\n// The token is read before each turn and cached for the synchronous read\n// inside a tool call. A 401 from the site's API asks for a new one once\n// and repeats that request; a second 401 is the API's real answer.\n//\n// The token goes only to the site's own API (the toolset's base URL). It\n// reaches GuideAI's backend only if the site opted in with\n// `forward_user_token`, exactly as on the web.\n// ============================================================\n\nimport type { HttpRequest, HttpResponse, HttpTransport } from '@guideai/core';\nimport type { RNCredentialSource } from '../platform/rn-platform';\n\n/** Returns the signed-in user's token, or null when signed out. May be async. */\nexport type AuthTokenGetter = () => string | null | undefined | Promise<string | null | undefined>;\n\nexport interface HostAuthOptions {\n getAuthToken?: AuthTokenGetter;\n /** Called once after a 401 from the site's API; returns the refreshed token. */\n onAuthExpired?: AuthTokenGetter;\n}\n\nexport class HostAuth {\n private pendingRenewal: Promise<string | null> | null = null;\n\n constructor(\n private readonly credentials: RNCredentialSource,\n private readonly options: HostAuthOptions = {},\n ) {}\n\n get enabled(): boolean {\n return Boolean(this.options.getAuthToken);\n }\n\n current(): string | null {\n return this.credentials.authToken();\n }\n\n /** Read the host's token now. Never throws: a failed read is \"signed out\". */\n async refresh(): Promise<string | null> {\n if (!this.options.getAuthToken) return null;\n let token: string | null = null;\n try {\n token = (await this.options.getAuthToken())?.trim() || null;\n } catch (error) {\n console.warn('[GuideAI] getAuthToken failed; continuing signed out:', error);\n }\n this.credentials.setAuthToken(token);\n return token;\n }\n\n /**\n * A new token after a 401, or null when there is none to be had.\n *\n * Shared while in flight: a batch of parallel tool calls that all hit an\n * expired token triggers one refresh, not one per call.\n */\n renew(): Promise<string | null> {\n if (!this.pendingRenewal) {\n const ask = this.options.onAuthExpired ?? this.options.getAuthToken;\n this.pendingRenewal = (async () => {\n let token: string | null = null;\n try {\n token = ask ? (await ask())?.trim() || null : null;\n } catch (error) {\n console.warn('[GuideAI] onAuthExpired failed:', error);\n }\n this.credentials.setAuthToken(token);\n return token;\n })().finally(() => { this.pendingRenewal = null; });\n }\n return this.pendingRenewal;\n }\n}\n\nfunction bearerOf(headers: Record<string, string>): string | null {\n const name = Object.keys(headers).find((key) => key.toLowerCase() === 'authorization');\n const value = name ? headers[name] : '';\n return value?.startsWith('Bearer ') ? value.slice(7) : null;\n}\n\n/**\n * The transport tool calls use, with one retry on an expired host token.\n *\n * Only a request carrying the host's own token is retried — a 401 for any\n * other credential (a static API key, a different login) is not ours to\n * refresh, and is passed straight back.\n */\nexport class HostAuthTransport implements HttpTransport {\n constructor(\n private readonly inner: HttpTransport,\n private readonly auth: HostAuth,\n ) {}\n\n get supportsStreaming(): boolean {\n return this.inner.supportsStreaming;\n }\n\n async request(req: HttpRequest): Promise<HttpResponse> {\n const response = await this.inner.request(req);\n if (response.status !== 401 || !this.auth.enabled) return response;\n\n const sent = bearerOf(req.headers);\n if (!sent || sent !== this.auth.current()) return response;\n\n const renewed = await this.auth.renew();\n if (!renewed || renewed === sent) return response;\n\n const headers = { ...req.headers };\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === 'authorization') delete headers[key];\n }\n headers.Authorization = `Bearer ${renewed}`;\n return this.inner.request({ ...req, headers });\n }\n}\n","// ============================================================\n// @guideai/react-native — screen registry\n// ============================================================\n//\n// THE constraint of the whole mobile runtime: there is no auto-capture.\n//\n// The web SDK builds its snapshot with `document.querySelectorAll`.\n// React Native has no queryable view tree at runtime — neither do Flutter\n// or Compose — so nothing here can walk the screen and discover what is\n// on it. The host declares its elements, or the snapshot is empty.\n//\n// No partial heuristic is offered on purpose. A snapshot that silently\n// found half a screen would produce an assistant that confidently points\n// at controls that are not there, which is worse than one that admits it\n// cannot see. An undeclared screen reports zero elements and the model\n// falls back to route-level guidance, which the mobile scanner already\n// grounds — so adoption is incremental rather than all-or-nothing.\n// ============================================================\n\nimport type { PageElement, PageSnapshot } from '@guideai/core';\n\n/** What a host says about one control on screen. */\nexport interface DeclaredElement {\n /**\n * Stable id, unique within the screen. Becomes the snapshot's\n * `selector` — legitimate because the backend treats `selector` as an\n * opaque round-trip token: it renders elements to the model as numbered\n * [ID]s and only checks the string is specific (not the word \"button\").\n */\n id: string;\n /** Visible text. What the model matches the user's words against. */\n label: string;\n /** Coarse kind, mapped to the `tag` the backend's prompt expects. */\n kind?: 'button' | 'link' | 'input' | 'text' | 'toggle' | 'image';\n /** Current value, for inputs. */\n value?: string;\n /** Accessibility label when it says more than the visible text. */\n accessibilityLabel?: string;\n /** Placeholder text for an empty input. */\n placeholder?: string;\n /** True when mounted but off-screen or collapsed. */\n hidden?: boolean;\n /** Heading of the group this sits in, e.g. \"Sharing options\". */\n sectionTitle?: string;\n}\n\n/** Actions a declared element can perform, supplied by the host at registration. */\nexport interface ElementHandlers {\n /** Invoked by guideai_click_element. */\n press?: () => void | Promise<void>;\n /** Invoked by guideai_fill_field / guideai_fill_form. */\n setValue?: (value: string) => void | Promise<void>;\n /** Invoked by guideai_scroll_to_element. */\n scrollTo?: () => void | Promise<void>;\n}\n\nexport interface RegisteredElement extends DeclaredElement {\n handlers: ElementHandlers;\n}\n\n/**\n * The `tag` the backend's snapshot prompt expects. It reuses web\n * vocabulary because the backend and the model already speak it — this\n * is presentation for the planner, not a claim that RN renders HTML.\n */\nconst KIND_TO_TAG: Record<NonNullable<DeclaredElement['kind']>, string> = {\n button: 'button',\n link: 'a',\n input: 'input',\n text: 'p',\n toggle: 'input',\n image: 'img',\n};\n\n/**\n * One screen's declared elements.\n *\n * Registration is keyed by id, so a remount replaces rather than\n * duplicates — React can mount a component twice (StrictMode, fast\n * refresh) and a duplicate would show the model two copies of one button.\n */\nexport class ScreenRegistry {\n private readonly elements = new Map<string, RegisteredElement>();\n\n register(element: DeclaredElement, handlers: ElementHandlers = {}): () => void {\n this.elements.set(element.id, { ...element, handlers });\n return () => {\n // Only unregister if this exact registration still owns the id — a\n // remount that re-registered first must not be clobbered by the old\n // instance's cleanup running afterwards.\n if (this.elements.get(element.id)?.handlers === handlers) {\n this.elements.delete(element.id);\n }\n };\n }\n\n get(id: string): RegisteredElement | undefined {\n return this.elements.get(id);\n }\n\n /** Resolve by id first, then by visible label — the model may send either. */\n find(request: { selector?: string; name?: string }): RegisteredElement | undefined {\n if (request.selector) {\n const byId = this.elements.get(request.selector);\n if (byId) return byId;\n }\n const name = (request.name ?? request.selector ?? '').trim().toLowerCase();\n if (!name) return undefined;\n for (const element of this.elements.values()) {\n if (element.label.trim().toLowerCase() === name) return element;\n if (element.accessibilityLabel?.trim().toLowerCase() === name) return element;\n }\n return undefined;\n }\n\n all(): RegisteredElement[] {\n return Array.from(this.elements.values());\n }\n\n clear(): void {\n this.elements.clear();\n }\n}\n\nexport interface SnapshotInput {\n /**\n * The route path, matching what the mobile scanner emitted (`/share`).\n * Grounding is exact string equality on the backend, so this must be\n * the scanner's `path` — not the native screen name.\n */\n path: string;\n /** Human title of the screen. */\n title: string;\n registry: ScreenRegistry;\n}\n\nfunction toPageElement(element: RegisteredElement): PageElement {\n const tag = KIND_TO_TAG[element.kind ?? 'button'];\n return {\n tag,\n text: element.label,\n selector: element.id,\n ...(element.accessibilityLabel ? { aria_label: element.accessibilityLabel } : {}),\n ...(element.value !== undefined ? { value: element.value } : {}),\n ...(element.placeholder ? { placeholder: element.placeholder } : {}),\n ...(element.hidden ? { hidden: true } : {}),\n ...(element.sectionTitle ? { section_title: element.sectionTitle } : {}),\n };\n}\n\n/**\n * Build the snapshot the backend already consumes.\n *\n * Same `PageSnapshot` type the web SDK produces — no mobile-specific\n * shape — which is what lets one backend serve both without a branch.\n */\nexport function buildSnapshot(input: SnapshotInput): PageSnapshot {\n const elements = input.registry.all().map(toPageElement);\n return {\n url: input.path,\n title: input.title,\n elements,\n };\n}\n","// ============================================================\n// @guideai/react-native — native client tool registry\n// ============================================================\n//\n// The mobile counterpart to BrowserAgentToolRegistry. The agent loop\n// never learns which one it is holding — that is what keeps a single\n// loop serving both platforms.\n//\n// TOOL NAMES ARE NOT FREE. The backend's _CLIENT_BROWSER_TOOL_DESCRIPTIONS\n// (docker/core/app/api/v1/chat.py) is a hardcoded allowlist of nine names\n// and it SILENTLY DROPS anything else — a `guideai_tap` would vanish with\n// no error and the model would simply never call it. So this reuses the\n// nine, and omits the ones a phone cannot honour.\n//\n// Omission IS the capability negotiation: `definitions()` is the\n// declaration the backend turns into the planner's prompt, so a tool left\n// out is a tool the model is never offered. There is deliberately no\n// second capability flag, because two lists could disagree.\n//\n// implemented omitted\n// guideai_click_element → press guideai_hover_element (no hover on touch)\n// guideai_fill_field → setValue guideai_refresh (no page to reload)\n// guideai_fill_form → setValue guideai_highlight_element (needs measure(); v2)\n// guideai_scroll_to_element → scrollTo\n// guideai_navigate → navigation ref\n// guideai_go_back → navigation ref\n// ============================================================\n\nimport type {\n ClientToolDefinition,\n ClientToolRegistry,\n CopilotToolDef,\n ToolCallResponse,\n ToolExecutionResult,\n} from '@guideai/core';\nimport type { ScreenRegistry } from '../screen/screen-registry';\n\n/** Matches the browser registry so the backend sees one round-trip convention. */\nconst CLIENT_PATH_PREFIX = '/__guideai/client/';\n\nconst elementProperties = {\n selector: {\n type: 'string',\n description: 'An element id from the current screen snapshot.',\n },\n name: {\n type: 'string',\n description: 'Visible text or accessible name when a reliable id is unavailable.',\n },\n};\n\nexport const RN_AGENT_TOOL_DEFINITIONS: ClientToolDefinition[] = [\n {\n name: 'guideai_fill_field',\n description: 'Fill one non-sensitive field on the current screen using its id, label, or accessible name.',\n consequential: true,\n parameters: {\n type: 'object',\n properties: {\n fieldName: { type: 'string', description: 'Label, accessible name, or placeholder of the field.' },\n selector: elementProperties.selector,\n value: { type: 'string', description: 'The value the user explicitly asked to enter.' },\n },\n required: ['value'],\n additionalProperties: false,\n },\n },\n {\n name: 'guideai_fill_form',\n description: 'Fill several non-sensitive fields on the current screen in order and report each outcome.',\n consequential: true,\n parameters: {\n type: 'object',\n properties: {\n fields: {\n type: 'array',\n maxItems: 25,\n items: {\n type: 'object',\n properties: {\n fieldName: { type: 'string' }, selector: { type: 'string' }, value: { type: 'string' },\n },\n required: ['value'],\n },\n },\n },\n required: ['fields'],\n additionalProperties: false,\n },\n },\n {\n name: 'guideai_scroll_to_element',\n description: 'Scroll an element on the current screen into view.',\n parameters: { type: 'object', properties: elementProperties, additionalProperties: false },\n },\n {\n name: 'guideai_click_element',\n description: 'Tap one enabled control on the current screen after user confirmation.',\n consequential: true,\n parameters: { type: 'object', properties: elementProperties, additionalProperties: false },\n },\n {\n name: 'guideai_navigate',\n description: 'Navigate to another screen in the app.',\n consequential: true,\n parameters: {\n type: 'object',\n properties: { url: { type: 'string', description: 'The destination screen name.' } },\n required: ['url'], additionalProperties: false,\n },\n },\n {\n name: 'guideai_go_back',\n description: 'Go back one screen in the app navigation stack.',\n consequential: true,\n parameters: { type: 'object', properties: {}, additionalProperties: false },\n },\n];\n\n/**\n * How the registry reaches React Navigation.\n *\n * A ref the provider owns, so core never learns React Navigation exists\n * and this package does not depend on it either — the host wires it.\n */\nexport interface NavigationBridge {\n /** `url` is the scanner's native screen name (`ShareForm`), not the path. */\n navigate(screen: string): void | Promise<void>;\n goBack(): void | Promise<void>;\n canGoBack?(): boolean;\n}\n\nexport interface RNToolRegistryOptions {\n getRegistry: () => ScreenRegistry | undefined;\n navigation?: NavigationBridge;\n}\n\nfunction failure(error: string, errorType = 'action_failed'): ToolExecutionResult {\n return { success: false, error, error_type: errorType };\n}\n\nfunction stringArg(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nexport class RNAgentToolRegistry implements ClientToolRegistry {\n /**\n * Serializes execution, matching the browser registry. On a phone this\n * matters as much as on the web: two taps dispatched concurrently can\n * interleave a navigation with a field fill and land the text on the\n * wrong screen.\n */\n private queue: Promise<unknown> = Promise.resolve();\n\n constructor(private readonly options: RNToolRegistryOptions) {}\n\n definitions(): ClientToolDefinition[] {\n const available = RN_AGENT_TOOL_DEFINITIONS.filter((tool) => {\n // Without a navigation bridge the app genuinely cannot navigate, so\n // the tools are withheld rather than advertised and then failed.\n if (tool.name === 'guideai_navigate' || tool.name === 'guideai_go_back') {\n return Boolean(this.options.navigation);\n }\n return true;\n });\n return available.map((tool) => ({ ...tool, parameters: { ...tool.parameters } }));\n }\n\n copilotDefinitions(): CopilotToolDef[] {\n return this.definitions().map((tool) => ({\n name: tool.name,\n description: tool.description,\n method: 'CLIENT',\n path: `${CLIENT_PATH_PREFIX}${tool.name}`,\n body_schema: tool.parameters,\n risk_level: tool.consequential ? 'write' : 'read',\n }));\n }\n\n canExecute(name: string): boolean {\n return this.definitions().some((tool) => tool.name === name);\n }\n\n canExecuteCall(toolCall: ToolCallResponse): boolean {\n return toolCall.method.toUpperCase() === 'CLIENT'\n && toolCall.path === `${CLIENT_PATH_PREFIX}${toolCall.tool}`\n && this.canExecute(toolCall.tool);\n }\n\n execute(toolCall: ToolCallResponse): Promise<ToolExecutionResult> {\n if (!this.canExecuteCall(toolCall)) {\n return Promise.resolve(failure('Native tool is not registered.', 'tool_not_found'));\n }\n const args = { ...(toolCall.params ?? {}), ...(toolCall.body ?? {}) };\n const run = async () => this.executeNow(toolCall.tool, args);\n const result = this.queue.then(run, run);\n this.queue = result.then(() => undefined, () => undefined);\n return result;\n }\n\n executeBatch(\n toolCalls: ToolCallResponse[],\n onComplete?: (toolCall: ToolCallResponse, result: ToolExecutionResult) => void,\n ): Promise<ToolExecutionResult[]> {\n return Promise.all(toolCalls.map(async (toolCall) => {\n const result = await this.execute(toolCall);\n onComplete?.(toolCall, result);\n return result;\n }));\n }\n\n private async fillOne(\n field: { fieldName?: string; selector?: string; value: string },\n ): Promise<{ field: string; filled: boolean; error?: string }> {\n const label = field.fieldName ?? field.selector ?? 'field';\n const registry = this.options.getRegistry();\n if (!registry) return { field: label, filled: false, error: 'no_active_screen' };\n\n const element = registry.find({ selector: field.selector, name: field.fieldName });\n if (!element) return { field: label, filled: false, error: 'element_not_found' };\n if (!element.handlers.setValue) {\n return { field: label, filled: false, error: 'element_not_fillable' };\n }\n await element.handlers.setValue(field.value);\n return { field: element.label, filled: true };\n }\n\n private async executeNow(name: string, args: Record<string, unknown>): Promise<ToolExecutionResult> {\n try {\n const registry = this.options.getRegistry();\n\n switch (name) {\n case 'guideai_fill_field': {\n const outcome = await this.fillOne({\n fieldName: stringArg(args.fieldName),\n selector: stringArg(args.selector),\n value: String(args.value ?? ''),\n });\n return { success: outcome.filled, data: outcome, error: outcome.error };\n }\n\n case 'guideai_fill_form': {\n const requested = Array.isArray(args.fields) ? args.fields.slice(0, 25) : [];\n const outcomes: Array<{ index: number; field: string; filled: boolean; error?: string }> = [];\n for (let index = 0; index < requested.length; index += 1) {\n const entry = requested[index] as Record<string, unknown> | undefined;\n if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {\n outcomes.push({ index, field: `field ${index + 1}`, filled: false, error: 'invalid_field' });\n continue;\n }\n if (entry.value == null) {\n outcomes.push({ index, field: `field ${index + 1}`, filled: false, error: 'value_required' });\n continue;\n }\n outcomes.push({ index, ...await this.fillOne({\n fieldName: stringArg(entry.fieldName),\n selector: stringArg(entry.selector),\n value: String(entry.value),\n }) });\n }\n const filledCount = outcomes.filter((outcome) => outcome.filled).length;\n return {\n // Matches the browser registry: the tool completed even when a\n // field was refused. The model needs per-field outcomes to\n // explain a partial result rather than a transport error.\n success: outcomes.length > 0,\n data: { success: outcomes.length > 0 && filledCount === outcomes.length, filledCount, outcomes },\n error: outcomes.length === 0 ? 'fields_required' : undefined,\n };\n }\n\n case 'guideai_click_element': {\n if (!registry) return failure('no_active_screen', 'element_not_found');\n const element = registry.find({ selector: stringArg(args.selector), name: stringArg(args.name) });\n if (!element) return failure('element_not_found', 'element_not_found');\n if (!element.handlers.press) return failure('element_not_pressable');\n await element.handlers.press();\n return { success: true, data: { pressed: element.label } };\n }\n\n case 'guideai_scroll_to_element': {\n if (!registry) return failure('no_active_screen', 'element_not_found');\n const element = registry.find({ selector: stringArg(args.selector), name: stringArg(args.name) });\n if (!element) return failure('element_not_found', 'element_not_found');\n if (!element.handlers.scrollTo) return failure('element_not_scrollable');\n await element.handlers.scrollTo();\n return { success: true, data: { scrolledTo: element.label } };\n }\n\n case 'guideai_navigate': {\n const destination = stringArg(args.url);\n if (!destination) return failure('url_required');\n if (!this.options.navigation) return failure('navigation_unavailable');\n await this.options.navigation.navigate(destination);\n return { success: true, data: { navigatedTo: destination } };\n }\n\n case 'guideai_go_back': {\n const navigation = this.options.navigation;\n if (!navigation) return failure('navigation_unavailable');\n if (navigation.canGoBack && !navigation.canGoBack()) {\n return failure('no_history');\n }\n await navigation.goBack();\n return { success: true, data: { wentBack: true } };\n }\n\n default:\n return failure(`Unknown native tool: ${name}`, 'tool_not_found');\n }\n } catch (error) {\n // Contract: execute() never throws — failures come back as results.\n return failure(error instanceof Error ? error.message : String(error));\n }\n }\n}\n","// ============================================================\n// @guideai/react-native — runtime assembly\n// ============================================================\n//\n// Wires the four platform pieces into the shape @guideai/core's agent\n// loop expects. This is the whole \"binding\" — there is no second agent\n// loop, no mobile-specific brain, and no protocol layer: core's harness\n// takes six injected dependencies and this supplies the ones that differ\n// on a device.\n//\n// Kept free of React so it can be tested in plain Node and reused by a\n// host that does not use hooks. The React layer sits on top of this.\n// ============================================================\n\nimport type {\n ClientToolRegistry,\n HttpTransport,\n KVStore,\n PageSnapshot,\n} from '@guideai/core';\nimport { RNHttpTransport } from './transport/rn-transport';\nimport { rnPlatform, type RNCredentialSource, type SyncNativeStore } from './platform/rn-platform';\nimport { HostAuth, HostAuthTransport, type HostAuthOptions } from './auth/host-auth';\nimport { ScreenRegistry, buildSnapshot } from './screen/screen-registry';\nimport { RNAgentToolRegistry, type NavigationBridge } from './tools/rn-tool-registry';\n\nexport interface ActiveScreen {\n /**\n * The route path as the mobile scanner emitted it (`/share`).\n * Grounding on the backend is exact string equality against this, so it\n * must be the scanner's `path` — never the native screen name.\n */\n path: string;\n title: string;\n registry: ScreenRegistry;\n}\n\nexport interface GuideAIRuntimeOptions {\n /** The registered site domain this app reports as its origin. */\n requestOrigin?: string;\n /** MMKV (or any sync store). Omitted → memory only, lost on relaunch. */\n store?: SyncNativeStore;\n /** How the tool registry reaches React Navigation. */\n navigation?: NavigationBridge;\n /** The host's own login, for tool calls to its API. */\n auth?: HostAuthOptions;\n}\n\n/**\n * Holds the mutable \"what screen am I on\" state and hands core the four\n * seams it needs. One instance per app.\n */\nexport class GuideAIRuntime {\n readonly transport: HttpTransport;\n readonly storage: KVStore;\n readonly credentials: RNCredentialSource;\n readonly tools: ClientToolRegistry;\n readonly auth: HostAuth;\n\n private active: ActiveScreen | undefined;\n\n constructor(options: GuideAIRuntimeOptions = {}) {\n const platform = rnPlatform({ store: options.store });\n this.storage = platform.storage;\n this.credentials = platform.credentials;\n this.auth = new HostAuth(this.credentials, options.auth);\n // Tool calls reach the site's API through this; an expired host token\n // is refreshed once and the call repeated.\n this.transport = new HostAuthTransport(\n new RNHttpTransport({ requestOrigin: options.requestOrigin }),\n this.auth,\n );\n this.tools = new RNAgentToolRegistry({\n getRegistry: () => this.active?.registry,\n navigation: options.navigation,\n });\n }\n\n /**\n * Called on every navigation. Replacing the whole screen (rather than\n * merging) is deliberate: elements from the previous screen are gone,\n * and leaving them visible to the model would have it offer controls\n * that are no longer mounted.\n */\n setActiveScreen(screen: ActiveScreen | undefined): void {\n this.active = screen;\n }\n\n getActiveScreen(): ActiveScreen | undefined {\n return this.active;\n }\n\n /**\n * What the host passes as the page snapshot on each turn.\n *\n * Returns undefined when no screen is registered — not an empty\n * snapshot. The difference matters: an empty snapshot asserts \"this\n * screen has no controls\", while undefined says \"nothing was declared\",\n * and only the second lets the backend fall back to route-level\n * guidance rather than concluding the screen is bare.\n */\n captureSnapshot(): PageSnapshot | undefined {\n if (!this.active) return undefined;\n return buildSnapshot({\n path: this.active.path,\n title: this.active.title,\n registry: this.active.registry,\n });\n }\n}\n","// ============================================================\n// @guideai/react-native — API client\n// ============================================================\n//\n// Implements core's CopilotApi over RNHttpTransport. The harness takes a\n// CopilotApi, and the web SDK's ApiClient is browser-bound (FormData,\n// keepalive, document.cookie), so mobile needs its own.\n//\n// Deliberately NOT a port of the SDK's client. It implements the four\n// members the harness actually calls and nothing else — no telemetry\n// beacons, no multipart upload, no unload handling, none of which exist\n// on a device.\n// ============================================================\n\nimport type { CopilotApi, HttpResponse } from '@guideai/core';\nimport { AuthError, PlanAccessError, UsageLimitError } from '@guideai/core';\nimport { REQUEST_ORIGIN_HEADER, RNHttpTransport } from '../transport/rn-transport';\n\nexport interface RNApiClientOptions {\n /** Backend origin, e.g. `https://api.guideai.dev` (no trailing slash). */\n baseUrl: string;\n /** The site's public token. */\n publicKey: string;\n siteId?: string;\n /**\n * The registered site domain this app reports as its origin. Required\n * in practice: the backend's origin guard rejects a request it cannot\n * attribute to an allowed domain, and a native app sends no Origin.\n */\n requestOrigin?: string;\n /**\n * Which of the site's agents (Agent Blueprints) answers, by its key.\n * Omitted: the site's main one.\n */\n agent?: string;\n /** Default time budget for JSON calls. Streaming calls are not budgeted. */\n timeoutMs?: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Map a failing status onto the structured errors the chat layer checks\n * with `instanceof`. Without this, a plan limit renders as a generic\n * \"request failed\" and the visitor is told nothing actionable.\n */\nasync function raiseForStatus(response: HttpResponse, path: string): Promise<void> {\n if (response.status >= 200 && response.status < 300) return;\n\n if (response.status === 401 || response.status === 403) {\n throw new AuthError(response.status);\n }\n\n // The 402/429 bodies carry the detail the UI needs; a body that is not\n // JSON must not mask the status, so parsing failure falls through.\n let detail: Record<string, unknown> = {};\n try {\n detail = (await response.json<Record<string, unknown>>()) ?? {};\n } catch {\n detail = {};\n }\n\n if (response.status === 402) {\n throw new PlanAccessError({\n feature: String(detail.feature ?? 'assistant'),\n plan: String(detail.plan ?? 'unknown'),\n message: typeof detail.message === 'string' ? detail.message : undefined,\n });\n }\n\n if (response.status === 429) {\n throw new UsageLimitError({\n message: typeof detail.message === 'string' ? detail.message : 'Usage limit reached',\n limit_type: String(detail.limit_type ?? 'requests'),\n plan: String(detail.plan ?? 'unknown'),\n });\n }\n\n throw new Error(`HTTP ${response.status} for ${path}`);\n}\n\n/** A refused upload, with the server's own words when it gave any. */\nexport class UploadError extends Error {\n constructor(readonly status: number, message: string) {\n super(message);\n this.name = 'UploadError';\n }\n}\n\nexport class RNApiClient implements CopilotApi {\n private readonly transport: RNHttpTransport;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n\n constructor(private readonly options: RNApiClientOptions) {\n this.transport = new RNHttpTransport({ requestOrigin: options.requestOrigin });\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n }\n\n get supportsStreaming(): boolean {\n return this.transport.supportsStreaming;\n }\n\n private headers(): Record<string, string> {\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n 'x-api-key': this.options.publicKey,\n };\n if (this.options.siteId) headers['x-site-id'] = this.options.siteId;\n if (this.options.agent) headers['x-guideai-agent'] = this.options.agent;\n return headers;\n }\n\n private url(path: string): string {\n return path.startsWith('http')\n ? path\n : `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n }\n\n /**\n * Time budget for JSON calls.\n *\n * Core's AbortSignal is declared with only `aborted` — it never\n * originates cancellation — so the deadline is enforced here by racing\n * rather than by constructing a controller inside the loop.\n */\n private async withTimeout<T>(work: Promise<T>, timeoutMs: number, path: string): Promise<T> {\n // ReturnType<typeof setTimeout>, not number: under Node's types this\n // is a Timeout object, and hardcoding number breaks any consumer\n // whose tsconfig pulls in @types/node (Expo's does).\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n work,\n new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Request timed out after ${timeoutMs}ms: ${path}`)),\n timeoutMs,\n );\n }),\n ]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n async get<T>(path: string, timeoutMs?: number): Promise<T> {\n const request = async (): Promise<T> => {\n const response = await this.transport.request({\n url: this.url(path), method: 'GET', headers: this.headers(),\n });\n await raiseForStatus(response, path);\n return response.json<T>();\n };\n return this.withTimeout(request(), timeoutMs ?? this.timeoutMs, path);\n }\n\n async post<T>(path: string, body?: unknown, timeoutMs?: number): Promise<T> {\n const request = async (): Promise<T> => {\n const response = await this.transport.request({\n url: this.url(path), method: 'POST', headers: this.headers(),\n body: JSON.stringify(body ?? {}),\n });\n await raiseForStatus(response, path);\n return response.json<T>();\n };\n return this.withTimeout(request(), timeoutMs ?? this.timeoutMs, path);\n }\n\n /**\n * Upload a file the device already wrote (a voice recording) as\n * multipart. XHR rather than fetch: it is the transport this package\n * already trusts on RN, and it takes RN's `{ uri, name, type }` parts.\n */\n async postFile<T>(\n path: string,\n field: string,\n file: { uri: string; name: string; type: string },\n fields: Record<string, string> = {},\n timeoutMs?: number,\n ): Promise<T> {\n const form = new FormData();\n form.append(field, file);\n for (const [name, value] of Object.entries(fields)) form.append(name, value);\n const headers = this.headers();\n delete headers['content-type']; // XHR writes the multipart boundary\n if (this.options.requestOrigin) headers[REQUEST_ORIGIN_HEADER] = this.options.requestOrigin;\n\n const request = new Promise<{ status: number; body: string }>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('POST', this.url(path));\n for (const [name, value] of Object.entries(headers)) xhr.setRequestHeader(name, value);\n xhr.onreadystatechange = () => {\n if (xhr.readyState === 4) resolve({ status: xhr.status, body: xhr.responseText });\n };\n xhr.onerror = () => reject(new Error(`Network error for ${path}`));\n xhr.send(form);\n });\n const { status, body } = await this.withTimeout(request, timeoutMs ?? this.timeoutMs, path);\n let parsed: unknown = null;\n try { parsed = body ? JSON.parse(body) : null; } catch { parsed = null; }\n if (status < 200 || status >= 300) {\n const detail = (parsed as { detail?: unknown } | null)?.detail;\n throw new UploadError(status, typeof detail === 'string' ? detail : `HTTP ${status} for ${path}`);\n }\n return parsed as T;\n }\n\n async postRaw(path: string, body?: unknown, signal?: AbortSignal): Promise<HttpResponse> {\n // Not time-budgeted: a stream is long-lived by design, and the caller\n // owns cancellation through `signal`.\n const response = await this.transport.request({\n url: this.url(path), method: 'POST', headers: this.headers(),\n body: JSON.stringify(body ?? {}), signal,\n });\n await raiseForStatus(response, path);\n return response;\n }\n}\n","// ============================================================\n// @guideai/react-native — React context\n// ============================================================\n//\n// Two separate contexts, deliberately.\n//\n// The RUNTIME is app-wide and never changes identity, so it can also be\n// set once as a module singleton — a host that does not want to wrap its\n// app in a provider calls configureGuideAI() instead.\n//\n// The REGISTRY is per-screen. That is the one thing a singleton cannot\n// express: a button three components deep needs to reach *its* screen's\n// registry, and which screen that is depends on position in the tree.\n// This is what context is genuinely for.\n// ============================================================\n\nimport { createContext, useContext } from 'react';\nimport type { GuideAIRuntime } from '../runtime';\nimport type { ScreenRegistry } from '../screen/screen-registry';\n\nexport const RuntimeContext = createContext<GuideAIRuntime | undefined>(undefined);\nexport const RegistryContext = createContext<ScreenRegistry | undefined>(undefined);\n\n/**\n * The module-level runtime, for hosts that skip the provider.\n *\n * A plain class with no React state, so nothing re-renders when it is\n * set — which is why a singleton is safe here and would not be for\n * anything the UI reads reactively.\n */\nlet moduleRuntime: GuideAIRuntime | undefined;\n\n/**\n * Install the app-wide runtime without a provider.\n *\n * Call once at startup. Deliberately a function rather than a\n * module-construction side effect: `requestOrigin` often comes from an\n * env fetch, and a constructor at import time cannot wait for it.\n */\nexport function configureGuideAI(runtime: GuideAIRuntime): void {\n moduleRuntime = runtime;\n}\n\n/** Test seam. Clears the singleton so suites do not leak state between cases. */\nexport function resetGuideAIRuntime(): void {\n moduleRuntime = undefined;\n}\n\nexport function getConfiguredRuntime(): GuideAIRuntime | undefined {\n return moduleRuntime;\n}\n\n/**\n * The active runtime: provider first, module singleton second.\n *\n * Throws rather than returning undefined. A missing runtime means the\n * host forgot to configure the SDK, and every downstream symptom of that\n * (no snapshot, no tools, silent no-ops) is far harder to diagnose than\n * one explicit error at the point of use.\n */\nexport function useGuideAIRuntime(): GuideAIRuntime {\n const fromContext = useContext(RuntimeContext);\n const runtime = fromContext ?? moduleRuntime;\n if (!runtime) {\n throw new Error(\n 'GuideAI is not configured. Call configureGuideAI(new GuideAIRuntime({...})) '\n + 'at app startup, or wrap your app in <GuideAIProvider>.',\n );\n }\n return runtime;\n}\n\n/** The enclosing screen's registry, or undefined outside a <GuideAIScreen>. */\nexport function useScreenRegistry(): ScreenRegistry | undefined {\n return useContext(RegistryContext);\n}\n","// ============================================================\n// @guideai/react-native — navigation bridge\n// ============================================================\n//\n// Adapts a React Navigation ref to the NavigationBridge the tool\n// registry expects.\n//\n// This package does NOT depend on @react-navigation/native. The ref is\n// accepted structurally, so a host on any navigator — or none — can\n// supply an equivalent, and core never learns which router is in use.\n// ============================================================\n\nimport type { NavigationBridge } from '../tools/rn-tool-registry';\n\n/** The slice of React Navigation's ref this needs. */\nexport interface NavigationRefLike {\n isReady?(): boolean;\n navigate(screen: string, params?: object): void;\n goBack(): void;\n canGoBack?(): boolean;\n}\n\n/**\n * Wrap a navigation ref (or a getter for one) as a NavigationBridge.\n *\n * Accepts a getter as well as the ref itself because\n * `createNavigationContainerRef()` is populated asynchronously — reading\n * `.current` at module scope captures null and every navigation silently\n * no-ops.\n */\nexport function navigationBridge(\n source: NavigationRefLike | (() => NavigationRefLike | null | undefined),\n): NavigationBridge {\n const resolve = (): NavigationRefLike | null | undefined =>\n (typeof source === 'function' ? source() : source);\n\n return {\n navigate(screen: string) {\n const ref = resolve();\n // isReady() is false until the container mounts. Navigating then\n // is dropped by React Navigation without an error, so surface it\n // as a failed tool result instead.\n if (!ref || (ref.isReady && !ref.isReady())) {\n throw new Error('navigation_not_ready');\n }\n ref.navigate(screen);\n },\n\n goBack() {\n const ref = resolve();\n if (!ref || (ref.isReady && !ref.isReady())) {\n throw new Error('navigation_not_ready');\n }\n ref.goBack();\n },\n\n canGoBack() {\n const ref = resolve();\n if (!ref || (ref.isReady && !ref.isReady())) return false;\n // A ref without canGoBack cannot prove there is history; assume\n // there is and let goBack() be a no-op rather than blocking it.\n return ref.canGoBack ? ref.canGoBack() : true;\n },\n };\n}\n","// ============================================================\n// @guideai/react-native — full conversation trace\n// ============================================================\n//\n// Logs EVERYTHING, unabridged: every message you type, every request\n// body sent, every streamed frame received, every tool call planned and\n// executed, and every answer.\n//\n// Separate from debug-logger.ts, which is a deliberately terse summary.\n// This one hides nothing, because a truncated log is exactly how a real\n// failure stays invisible — the previous \"HTTP 0\" and \"split of null\"\n// bugs were both diagnosed only after the missing detail was added.\n//\n// Output goes to console.log, which Expo prints in the terminal running\n// `expo start`. Redirect that terminal to a file to keep a transcript.\n// ============================================================\n\nimport type {\n ClientToolRegistry,\n CopilotApi,\n HttpRequest,\n HttpResponse,\n HttpTransport,\n TextStream,\n ToolCallResponse,\n ToolExecutionResult,\n} from '@guideai/core';\n\n/** Wall-clock stamp so entries can be correlated with the server's logs. */\nconst stamp = () => new Date().toISOString().slice(11, 23);\n\nlet seq = 0;\nconst next = () => (seq += 1);\n\nfunction dump(label: string, value: unknown): void {\n let text: string;\n try {\n text = typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n } catch {\n text = String(value);\n }\n // No truncation. The point of this module is that nothing is hidden.\n console.log(`${label}\\n${text}`);\n}\n\nfunction line(icon: string, text: string): void {\n console.log(`[${stamp()}] ${icon} ${text}`);\n}\n\n/**\n * Wrap CopilotApi to trace GuideAI's own endpoints in full.\n *\n * Logs the complete request body — including `page_snapshot`, the full\n * `client_tools` list and `conversation_history` — and every streamed\n * SSE frame as it arrives.\n */\nexport function traceApi(api: CopilotApi): CopilotApi {\n return {\n supportsStreaming: api.supportsStreaming,\n\n async get<T>(path: string, timeoutMs?: number): Promise<T> {\n const id = next();\n line('→', `#${id} GET ${path}`);\n try {\n const result = await api.get<T>(path, timeoutMs);\n dump(`[${stamp()}] ← #${id} GET ${path} responded:`, result);\n return result;\n } catch (error) {\n line('✗', `#${id} GET ${path} FAILED: ${describeError(error)}`);\n throw error;\n }\n },\n\n async post<T>(path: string, body?: unknown, timeoutMs?: number): Promise<T> {\n const id = next();\n dump(`[${stamp()}] → #${id} POST ${path} body:`, body);\n try {\n const result = await api.post<T>(path, body, timeoutMs);\n dump(`[${stamp()}] ← #${id} POST ${path} responded:`, result);\n return result;\n } catch (error) {\n line('✗', `#${id} POST ${path} FAILED: ${describeError(error)}`);\n throw error;\n }\n },\n\n async postRaw(path: string, body?: unknown, signal?: AbortSignal): Promise<HttpResponse> {\n const id = next();\n dump(`[${stamp()}] → #${id} POST ${path} body:`, body);\n\n try {\n const response = await api.postRaw(path, body, signal);\n line('←', `#${id} ${response.status} ${path}`\n + ` (${response.headers.get('content-type') ?? 'no content-type'})`);\n\n // Tee the stream so every SSE frame is logged without consuming\n // it — the harness still receives every chunk in order.\n if (response.stream) {\n return { ...response, stream: teeStream(response.stream, id) };\n }\n return response;\n } catch (error) {\n line('✗', `#${id} POST ${path} FAILED: ${describeError(error)}`);\n throw error;\n }\n },\n };\n}\n\n/**\n * Log each SSE frame while passing it through untouched.\n *\n * Buffers on the frame delimiter rather than logging raw chunks: a chunk\n * boundary falls mid-frame, and half a frame in a log is unreadable.\n */\nfunction teeStream(stream: TextStream, id: number): TextStream {\n return {\n async *[Symbol.asyncIterator]() {\n let buffer = '';\n for await (const chunk of stream) {\n buffer += chunk;\n const parts = buffer.split('\\n\\n');\n buffer = parts.pop() ?? '';\n for (const frame of parts) {\n const trimmed = frame.trim();\n if (trimmed) console.log(`[${stamp()}] ⋯ #${id} frame: ${trimmed}`);\n }\n yield chunk;\n }\n if (buffer.trim()) console.log(`[${stamp()}] ⋯ #${id} frame: ${buffer.trim()}`);\n line('⋯', `#${id} stream ended`);\n },\n };\n}\n\n/**\n * Wrap the transport to trace CUSTOMER API calls — the ones a tool call\n * actually makes. These do not go through CopilotApi, so without this\n * they are invisible.\n */\nexport function traceTransport(transport: HttpTransport): HttpTransport {\n return {\n supportsStreaming: transport.supportsStreaming,\n async request(req: HttpRequest): Promise<HttpResponse> {\n const id = next();\n console.log(\n `[${stamp()}] ⇢ #${id} ${req.method} ${req.url}\\n`\n + ` headers: ${JSON.stringify(req.headers)}\\n`\n + ` body: ${req.body ?? '(none)'}`,\n );\n try {\n const response = await transport.request(req);\n line('⇠', `#${id} ${response.status} ${req.url}`);\n return response;\n } catch (error) {\n // Name the URL: \"cannot resolve host\" is unactionable without it,\n // and a device reports exactly that as a bare HTTP 0.\n line('✗', `#${id} ${req.method} ${req.url} FAILED: ${describeError(error)}`);\n throw error;\n }\n },\n };\n}\n\n/** Wrap the tool registry to trace every planned and executed call. */\nexport function traceTools(tools: ClientToolRegistry): ClientToolRegistry {\n const report = (call: ToolCallResponse, result: ToolExecutionResult) => {\n if (result.success) {\n dump(`[${stamp()}] ✓ executed ${call.tool} →`, result.data);\n } else {\n line('✗', `${call.tool} FAILED: ${result.error ?? 'unknown'}`\n + `${result.error_type ? ` (${result.error_type})` : ''}`);\n }\n };\n\n return {\n definitions: () => tools.definitions(),\n copilotDefinitions: () => tools.copilotDefinitions(),\n canExecute: (name: string) => tools.canExecute(name),\n canExecuteCall: (call: ToolCallResponse) => tools.canExecuteCall(call),\n\n execute: async (call: ToolCallResponse) => {\n dump(`[${stamp()}] ⚙ TOOL CALL ${call.tool} (${call.method} ${call.path}):`, {\n params: call.params, body: call.body, requires_confirm: call.requires_confirm,\n });\n const result = await tools.execute(call);\n report(call, result);\n return result;\n },\n\n executeBatch: async (calls: ToolCallResponse[], onComplete?) => {\n line('⚙', `BATCH of ${calls.length}: ${calls.map((c) => c.tool).join(', ')}`);\n return tools.executeBatch(calls, (call, result) => {\n report(call, result);\n onComplete?.(call, result);\n });\n },\n\n destroy: tools.destroy ? () => tools.destroy?.() : undefined,\n };\n}\n\nfunction describeError(error: unknown): string {\n if (error instanceof Error) {\n return `${error.name}: ${error.message}`;\n }\n return String(error);\n}\n\n/** Log a message you typed, so the transcript reads as a conversation. */\nexport function traceUserMessage(text: string): void {\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`[${stamp()}] 👤 YOU: ${text}`);\n console.log('═'.repeat(60));\n}\n\n/** Log the assistant's final answer, in full. */\nexport function traceAssistantAnswer(text: string, mode?: string): void {\n console.log(`[${stamp()}] 🤖 ASSISTANT${mode ? ` (${mode})` : ''}:\\n${text}`);\n console.log(`${'═'.repeat(60)}\\n`);\n}\n","// ============================================================\n// @guideai/react-native — the whole public setup surface\n// ============================================================\n//\n// A host app should own exactly two things: its UI, and the message the\n// user typed. Everything else — the agent loop, the transport, the tool\n// registry, the snapshot format, the wire protocol — is ours, so that\n// upgrading the agent is a package bump and never a migration.\n//\n// That is why this file exists. Before it, wiring the SDK meant\n// constructing RNApiClient, GuideAIRuntime and CopilotHarness by hand\n// and passing six positional arguments in the right order. Every one of\n// those is an internal class, so any change to them was a breaking\n// change for every customer.\n//\n// Now:\n//\n// GuideAI.configure({ apiKey: 'pk_live_…', origin: 'https://app.acme.com' });\n// <GuideAIChat />\n//\n// Nothing else is required, and nothing internal is named.\n// ============================================================\n\nimport { CopilotHarness } from '@guideai/core';\nimport { GuideAIRuntime } from './runtime';\nimport { RNApiClient } from './api/rn-api-client';\nimport { configureGuideAI } from './react/context';\nimport { navigationBridge, type NavigationRefLike } from './react/navigation';\nimport { traceApi, traceTools, traceTransport } from './debug/full-trace';\nimport type { SyncNativeStore } from './platform/rn-platform';\nimport type { AuthTokenGetter } from './auth/host-auth';\n\nexport interface GuideAIConfig {\n /**\n * The site's public token, from the dashboard. The only required\n * field: it identifies the site, and everything else about that site\n * — its tools, knowledge base, model and prompts — is resolved\n * server-side from it.\n */\n apiKey: string;\n /** The application's stable user ID after login, if already known. */\n visitorId?: string;\n\n /**\n * A domain registered on this site (its own domain, or one of its\n * `domain_aliases`).\n *\n * Required in practice, and it cannot be fetched from the dashboard:\n * the backend uses it to AUTHORIZE the request, so it must accompany\n * the very first call. A native app sends no `Origin` header, so this\n * travels as `x-guideai-request-origin`. Set it once; a mismatch is\n * answered with 403.\n */\n origin?: string;\n\n /**\n * Where the GuideAI backend lives. Defaults to the hosted service, so\n * only self-hosted deployments set it.\n */\n baseUrl?: string;\n\n /**\n * How the assistant navigates between screens — a React Navigation\n * ref, or a getter for one. Omitted, the assistant simply does not\n * offer navigation rather than offering it and failing.\n */\n navigation?: NavigationRefLike | (() => NavigationRefLike | null | undefined);\n\n /**\n * A synchronous key/value store (MMKV, or `expo-sqlite/kv-store`) for\n * conversation history across launches. Omitted, history is kept in\n * memory and resets on relaunch.\n */\n store?: SyncNativeStore;\n\n /** The assistant's visible name in its own replies. */\n assistantName?: string;\n\n /**\n * Which of the site's agents (Agent Blueprints) answers, by its key —\n * e.g. 'tutor'. Omitted: the site's main agent.\n */\n agent?: string;\n\n /**\n * The signed-in user's token for the site's own API. Read before every\n * turn; may be async (AsyncStorage, SecureStore). Return null when\n * signed out. The assistant then calls your endpoints as that user,\n * from the device.\n */\n getAuthToken?: AuthTokenGetter;\n\n /**\n * Called once when your API answers 401 to a tool call. Refresh the\n * session and return the new token; the call is repeated with it.\n * Omitted: getAuthToken() is asked again.\n */\n onAuthExpired?: AuthTokenGetter;\n\n /**\n * Facts about the signed-in user for the agent to pitch answers to —\n * `{ age: 12, class: 'JSS1', country: 'Nigeria', language: 'en' }`.\n * Sent with every turn; change it with GuideAI.setUserProfile().\n */\n userProfile?: GuideAIUserProfile;\n\n /**\n * Log the full conversation and every request. Development only —\n * it prints message content to the console.\n */\n debug?: boolean;\n}\n\n/** Short facts about the user: strings, numbers, booleans or short lists of them. */\nexport type GuideAIUserProfile = Record<string, string | number | boolean | Array<string | number>>;\n\nconst DEFAULT_BASE_URL = 'https://api.guideai.dev';\n\ninterface Configured {\n runtime: GuideAIRuntime;\n harness: CopilotHarness;\n /**\n * The plain API client, for UI that needs to ask the backend something\n * outside a conversation — whether a human is reachable, for one.\n * Untraced: these are status probes, not agent traffic.\n */\n api: RNApiClient;\n debug: boolean;\n visitorId: string | null;\n profile: GuideAIUserProfile | null;\n}\n\nlet configured: Configured | null = null;\n\n/**\n * Configure the assistant. Call once, at app startup.\n *\n * Deliberately a function rather than a provider or a module constant:\n * `apiKey` often arrives from a remote config or an env fetch, and a\n * constructor running at import time cannot wait for it.\n */\nfunction configure(config: GuideAIConfig): void {\n const debug = config.debug ?? false;\n\n const baseApi = new RNApiClient({\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n publicKey: config.apiKey,\n requestOrigin: config.origin,\n agent: config.agent?.trim() || undefined,\n });\n\n const runtime = new GuideAIRuntime({\n requestOrigin: config.origin,\n store: config.store,\n auth: { getAuthToken: config.getAuthToken, onAuthExpired: config.onAuthExpired },\n navigation: config.navigation\n ? navigationBridge(\n typeof config.navigation === 'function'\n ? config.navigation\n : () => config.navigation as NavigationRefLike,\n )\n : undefined,\n });\n\n // Registers the runtime app-wide, so <GuideAIScreen> and the hooks\n // resolve it without the host wrapping their app in a provider.\n configureGuideAI(runtime);\n\n const harness = new CopilotHarness(\n debug ? traceApi(baseApi) : baseApi,\n {\n // The site id is resolved server-side from the API key; the\n // harness only needs a stable string to key its local memory.\n // Per agent too: a tutor and a course builder in one app must not\n // read each other's conversation.\n siteId: config.agent?.trim() ? `${config.apiKey}:${config.agent.trim()}` : config.apiKey,\n assistantLabel: config.assistantName,\n },\n debug ? traceTools(runtime.tools) : runtime.tools,\n runtime.storage,\n debug ? traceTransport(runtime.transport) : runtime.transport,\n runtime.credentials,\n );\n\n configured = {\n runtime, harness, api: baseApi, debug,\n visitorId: config.visitorId ?? null,\n profile: config.userProfile ?? null,\n };\n}\n\n/** Call after login so chat and the checklist use the same person. */\nfunction identify(userId: string | null): void {\n if (!configured) throw new Error('Call GuideAI.configure() before identify().');\n configured.visitorId = userId?.trim() || null;\n}\n\n/** Replace what the agent knows about the user (after login, or a profile edit). */\nfunction setUserProfile(profile: GuideAIUserProfile | null): void {\n if (!configured) throw new Error('Call GuideAI.configure() before setUserProfile().');\n configured.profile = profile;\n}\n\n/**\n * The configured instance, for the UI components.\n *\n * Throws rather than returning null: a missing configuration otherwise\n * surfaces as an assistant that silently answers nothing, which is far\n * harder to diagnose than one explicit error at startup.\n */\nexport function requireConfigured(): Configured {\n if (!configured) {\n throw new Error(\n 'GuideAI is not configured. Call GuideAI.configure({ apiKey, origin }) '\n + 'at app startup, before rendering <GuideAIChat />.',\n );\n }\n return configured;\n}\n\n/** Whether configure() has run. Lets a host render its own fallback. */\nfunction isConfigured(): boolean {\n return configured !== null;\n}\n\n/** Test seam, and for hosts that switch sites at runtime. */\nfunction reset(): void {\n configured = null;\n}\n\nexport const GuideAI = { configure, identify, setUserProfile, isConfigured, reset };\n","// ============================================================\n// @guideai/react-native — chat hook\n// ============================================================\n//\n// One hook serving both UI requirements: it returns the conversation and\n// a send function, so the default <GuideAIChat> is built on exactly this\n// and a host's own UI gets the same thing. There is no privileged path\n// for the built-in UI — if this hook cannot express a UI, the default\n// one could not have been built either.\n// ============================================================\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { describeToolCall, EP, headlessImages } from '@guideai/core';\nimport type { CopilotHarness, HarnessResponse, HeadlessImage, ToolCallResponse } from '@guideai/core';\nimport { useGuideAIRuntime } from './context';\nimport { traceAssistantAnswer, traceUserMessage } from '../debug/full-trace';\nimport { requireConfigured } from '../setup';\nimport { UploadError } from '../api/rn-api-client';\n\nexport interface GuideAIMessage {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n /** True while tokens are still arriving for this message. */\n streaming?: boolean;\n error?: boolean;\n /**\n * Follow-up suggestions to draw as chips. A tap is just\n * `send(suggestion)`.\n */\n suggestions?: string[];\n /**\n * Pictures the agent drew. They are also in `content` as Markdown\n * images where they belong; use this list to place them yourself.\n */\n images?: HeadlessImage[];\n /**\n * A change to the user's data waiting for their yes (\"Create the\n * course\"). Draw Approve / Cancel and call `confirm(id)` or `cancel(id)`.\n */\n pendingAction?: { label: string; tool: string };\n}\n\n/** A recording the host made (expo-audio or any recorder) and saved to a file. */\nexport interface GuideAIVoiceRecording {\n /** `file://…` URI of the finished recording. */\n uri: string;\n /** e.g. 'audio/m4a'. Omitted: guessed from the file extension. */\n mimeType?: string;\n /** BCP-47 language the user spoke, e.g. 'en-NG'. Defaults to 'en-US'. */\n languageCode?: string;\n}\n\nexport interface GuideAIVoiceResult {\n /** What was heard, already sent as the next message; null when nothing was. */\n text: string | null;\n /** Why nothing was sent, in words to show the user. */\n error?: string;\n}\n\n/**\n * Mobile runs in assistant mode only.\n *\n * Guidance mode drives on-screen walkthroughs — highlight this, scroll to\n * that — which the browser SDK performs against live DOM nodes. On a\n * device there is no DOM to drive, no hover, and no highlight overlay\n * (`guideai_highlight_element` is not among the tools this package\n * advertises), so a guidance turn would come back with steps nothing can\n * execute.\n *\n * The backend picks a different prompt template per mode\n * (COPILOT_ACTION_PROMPT_GUIDANCE vs _ASSISTANT), so this is not a\n * cosmetic label — sending 'guidance' asks the model to plan the wrong\n * kind of answer. Narrowed to one value rather than defaulted, so a\n * guidance turn cannot be requested by mistake.\n */\nexport type GuideAIChatMode = 'assistant';\n\n/**\n * Everything a custom chat UI needs, and nothing about how to draw it.\n *\n * A host owns two things — their design, and the text the user typed.\n * This hook owns the rest: the conversation, the streaming, the tool\n * calls, the transport. That split is what lets the agent be upgraded\n * underneath a host's UI without them changing a line.\n */\nexport interface UseGuideAIResult {\n /** The conversation so far, oldest first. */\n messages: GuideAIMessage[];\n\n /**\n * The current input text, and its setter.\n *\n * Managed here so a host binds it straight to their TextInput rather\n * than reimplementing \"clear on send, block while busy\" — the two\n * rules every chat UI needs and each one gets subtly wrong.\n */\n input: string;\n setInput(text: string): void;\n\n /**\n * Send `input`, or an explicit string.\n *\n * Ignores empty text and calls made while a turn is in flight, so a\n * host does not have to guard their send button.\n */\n send(question?: string): Promise<void>;\n\n /** True from send() until the turn settles. Drives a disabled state. */\n busy: boolean;\n\n /** Whether `send()` would do anything right now. */\n canSend: boolean;\n\n /** Status text from the agent loop (\"Thinking\", \"Reading cart\"). */\n status: string | null;\n\n /** Re-send the last user message. Useful after a failed turn. */\n retry(): Promise<void>;\n\n /** Drop the conversation and start over. */\n clear(): void;\n\n /** Approve the message's `pendingAction`; the agent carries it out. */\n confirm(messageId: string): Promise<void>;\n\n /** Decline the message's `pendingAction`. Nothing is changed. */\n cancel(messageId: string): void;\n\n /**\n * Push-to-talk: transcribe a recording and send it as the next message.\n * Recording is the host's (no native module here); this uploads it.\n */\n sendVoice(recording: GuideAIVoiceRecording): Promise<GuideAIVoiceResult>;\n\n /** True while a recording is being transcribed. */\n transcribing: boolean;\n}\n\nexport interface UseGuideAIOptions {\n /**\n * Log the full conversation and every request. Defaults to whatever\n * GuideAI.configure({ debug }) was given, so a host sets it once.\n */\n trace?: boolean;\n\n /**\n * The harness, for tests and for a host running two assistants at\n * once. Omitted — the normal case — it comes from GuideAI.configure(),\n * so a host never holds a reference to it.\n */\n harness?: CopilotHarness;\n}\n\nconst AUDIO_TYPES: Record<string, string> = {\n m4a: 'audio/m4a', mp4: 'audio/mp4', aac: 'audio/aac', caf: 'audio/x-caf',\n wav: 'audio/wav', mp3: 'audio/mpeg', webm: 'audio/webm', ogg: 'audio/ogg', '3gp': 'audio/3gpp',\n};\n\nfunction audioType(uri: string): { type: string; name: string } {\n const extension = (uri.split('?')[0].split('.').pop() ?? '').toLowerCase();\n const type = AUDIO_TYPES[extension] ?? 'audio/m4a';\n return { type, name: `voice.${AUDIO_TYPES[extension] ? extension : 'm4a'}` };\n}\n\n/** The fields a finished turn sets on its reply. */\nfunction replyFields(\n result: HarnessResponse,\n streamed: string,\n): Pick<GuideAIMessage, 'content' | 'images' | 'suggestions' | 'pendingAction'> {\n const { text, images } = headlessImages(answerText(result, streamed));\n const call = result.confirmationNeeded ? result.pendingToolCall : undefined;\n return {\n content: text,\n images: images.length ? images : undefined,\n suggestions: result.quickReplies?.length ? result.quickReplies.slice(0, 4) : undefined,\n pendingAction: call ? { label: call.label?.trim() || describeToolCall(call), tool: call.tool } : undefined,\n };\n}\n\nlet nextId = 0;\nconst nextMessageId = () => `m${(nextId += 1)}`;\n\n/**\n * What to show for a reply, once the machine payload is stripped out.\n *\n * A guide answer is a ```guide fenced block of step JSON and often nothing\n * else, so sanitizing it can legitimately leave an empty string — and an\n * empty assistant bubble reads as a bug. The steps themselves are already\n * parsed into `guideSteps`/`navigation`, so say what is happening in the\n * words the model put in the steps rather than showing the JSON that\n * produced them.\n */\nfunction answerText(\n result: { answer?: string; guideSteps?: unknown[]; guideTitle?: string },\n fallback: string,\n): string {\n const answer = (result.answer ?? '').trim();\n if (answer) return answer;\n\n const first = result.guideSteps?.[0] as Record<string, unknown> | undefined;\n const body = typeof first?.body === 'string' ? first.body.trim() : '';\n if (body) return body;\n\n const title = typeof first?.title === 'string' ? first.title.trim() : '';\n if (title) return title;\n\n return fallback || 'Done.';\n}\n\n/**\n * What the visitor is told when a turn fails.\n *\n * Deliberately ONE message, with no detail about the cause.\n *\n * An earlier version classified the failure — timeout, network, 401, 5xx —\n * and said something different for each. That is still leaking the\n * diagnosis: a visitor cannot act on \"the request timed out\", and being\n * told which of our services broke is not their problem. Worse, the class\n * names read as blame (\"check your connection\") for what is usually our\n * own misconfiguration.\n *\n * The real diagnosis is logged in full, immediately before this is called,\n * so nothing is lost for whoever is debugging.\n */\nconst FAILURE_MESSAGE =\n \"I'm sorry, I can't complete your request right now. \"\n + 'Would you like to talk to a human?';\n\nexport function useGuideAI(options: UseGuideAIOptions = {}): UseGuideAIResult {\n const runtime = useGuideAIRuntime();\n const configured = requireConfigured();\n const harness = options.harness ?? configured.harness;\n const trace = options.trace ?? configured.debug;\n // Mobile is assistant-mode only; see GuideAIChatMode.\n const mode: GuideAIChatMode = 'assistant';\n\n const [messages, setMessages] = useState<GuideAIMessage[]>([]);\n const [input, setInput] = useState('');\n const [busy, setBusy] = useState(false);\n const [status, setStatus] = useState<string | null>(null);\n const [transcribing, setTranscribing] = useState(false);\n // Kept for retry(), which must survive the message list being cleared.\n const lastQuestion = useRef<string | null>(null);\n // The tool call behind each message's pendingAction, with the question\n // that led to it — the harness needs both to carry it out.\n const pending = useRef(new Map<string, { call: ToolCallResponse; question: string }>());\n\n // Guards against setting state after unmount — a streamed turn can\n // outlive the screen that started it.\n const mounted = useRef(true);\n useEffect(() => () => { mounted.current = false; }, []);\n\n /**\n * Rehydrate the conversation the harness already persisted.\n *\n * The harness has written every turn to its store all along — that is\n * what `store` in GuideAI.configure() is for, and what lets the model\n * answer follow-ups. Nothing ever read it back into the view, so closing\n * the sheet unmounted this hook and the transcript appeared to be gone\n * while the model still remembered it: the visitor sees an empty panel\n * and the assistant answers as though mid-conversation.\n *\n * Runs once on mount, and only when the view has nothing of its own, so\n * a remount mid-conversation cannot duplicate what is already on screen.\n */\n useEffect(() => {\n // Guarded rather than called directly: `harness` is a documented\n // option, so a host (and every test fake) may pass an object that\n // implements only the turn-taking surface. A missing history API means\n // \"nothing to restore\", never a crash on mount.\n if (typeof harness.hasHistory !== 'function'\n || typeof harness.getConversationHistory !== 'function') return;\n if (!harness.hasHistory()) return;\n\n setMessages((previous) => {\n if (previous.length > 0) return previous;\n return harness.getConversationHistory()\n .filter((entry) => typeof entry.content === 'string' && entry.content.trim())\n .map((entry, index) => ({\n id: entry.id ?? `h${index}`,\n role: entry.role,\n content: entry.content,\n }));\n });\n }, [harness]);\n\n /**\n * Fetch the site's active tool set once, before the first turn.\n *\n * REQUIRED, not an optimisation. The harness builds its ToolExecutor\n * inside initialize() — it cannot be injected, because the base URL and\n * auth config only exist once the server says which tool set is active.\n * Without this, `toolExecutor` stays null, `canExecuteTool()` returns\n * false for every customer API tool, and the turn dies with\n * \"Tool execution is unavailable in this browser context.\"\n *\n * The web SDK does this in chat-manager.ts; mobile needs its own call.\n */\n const initialized = useRef<Promise<boolean> | null>(null);\n const ensureInitialized = useCallback(() => {\n // Cached as a promise so concurrent sends share one request, and a\n // failure does not permanently disable tools — initialize() swallows\n // its own errors and simply leaves customer tools unavailable.\n if (!initialized.current) initialized.current = harness.initialize();\n return initialized.current;\n }, [harness]);\n\n /**\n * Run one agent turn into the assistant message `replyId`: stream its\n * text, then settle it with the answer, pictures, suggestions and any\n * action awaiting approval. Shared by a typed message and an approval.\n */\n const runTurn = useCallback(async (\n replyId: string,\n question: string,\n work: (\n onStatus: (status: string) => void,\n onDelta: (delta: string) => void,\n ) => Promise<HarnessResponse>,\n ) => {\n setBusy(true);\n setStatus(null);\n let streamed = '';\n const appendDelta = (delta: string) => {\n streamed += delta;\n if (!mounted.current) return;\n setMessages((prev) => prev.map((message) => (\n message.id === replyId\n ? { ...message, content: message.content + delta }\n : message\n )));\n };\n\n try {\n // The user's own token for the site's API, read fresh each turn: it\n // may have been refreshed or signed out since the last one.\n await runtime.auth?.refresh();\n const result = await work((next) => { if (mounted.current) setStatus(next); }, appendDelta);\n\n if (trace) traceAssistantAnswer(result.answer ?? '(empty)', result.mode);\n if (result.confirmationNeeded && result.pendingToolCall) {\n pending.current.set(replyId, { call: result.pendingToolCall, question });\n }\n\n if (!mounted.current) return;\n setMessages((prev) => prev.map((message) => (\n message.id === replyId\n // Streamed deltas and the final answer are the same text; trust\n // the final one, which is also what a non-streaming transport\n // returns. Keeping the streamed text when it is longer would\n // duplicate on a transport that replays.\n ? { ...message, ...replyFields(result, streamed), streaming: false }\n : message\n )));\n } catch (error) {\n // Always log the real cause. A non-Error throw would otherwise be\n // rendered as a bare \"Something went wrong\" with the actual\n // diagnosis discarded — which is exactly the case that is hardest\n // to debug from a phone.\n console.log('[GuideAI] ✗ turn failed:', error);\n if (error instanceof Error && error.stack) {\n console.log('[GuideAI] stack:', error.stack);\n }\n\n if (!mounted.current) return;\n setMessages((prev) => prev.map((message) => (\n message.id === replyId\n ? {\n ...message,\n content: FAILURE_MESSAGE,\n streaming: false,\n error: true,\n }\n : message\n )));\n } finally {\n if (mounted.current) {\n setBusy(false);\n setStatus(null);\n }\n }\n }, [runtime, trace]);\n\n const send = useCallback(async (question?: string) => {\n const text = (question ?? input).trim();\n if (!text || busy) return;\n\n lastQuestion.current = text;\n // Clear the box immediately: leaving the text in place while a turn\n // runs invites a double-send.\n if (question === undefined) setInput('');\n\n if (trace) traceUserMessage(text);\n\n const replyId = nextMessageId();\n setMessages((prev) => [\n ...prev,\n { id: nextMessageId(), role: 'user', content: text },\n { id: replyId, role: 'assistant', content: '', streaming: true },\n ]);\n\n await runTurn(replyId, text, async (onStatus, onDelta) => {\n // Must complete before the first turn, or customer API tools are\n // unavailable for it.\n await ensureInitialized();\n const screen = runtime.getActiveScreen();\n const { profile, visitorId } = requireConfigured();\n return harness.processMessage(\n text,\n screen?.path,\n runtime.captureSnapshot(),\n mode,\n onStatus,\n onDelta,\n undefined,\n undefined,\n // Who is asking, as the app knows them; the agent pitches to it.\n profile ? { profile } : undefined,\n visitorId ?? undefined,\n );\n });\n }, [busy, input, harness, mode, runtime, ensureInitialized, trace, runTurn]);\n\n const retry = useCallback(async () => {\n if (!lastQuestion.current || busy) return;\n // Drop the failed exchange so the retry does not stack a second\n // copy of the question under the first.\n setMessages((prev) => prev.slice(0, -2));\n await send(lastQuestion.current);\n }, [busy, send]);\n\n const clear = useCallback(() => {\n setMessages([]);\n lastQuestion.current = null;\n pending.current.clear();\n }, []);\n\n const settleAction = useCallback((messageId: string) => {\n const action = pending.current.get(messageId);\n pending.current.delete(messageId);\n setMessages((prev) => prev.map((message) => (\n message.id === messageId ? { ...message, pendingAction: undefined } : message\n )));\n return action;\n }, []);\n\n const confirm = useCallback(async (messageId: string) => {\n if (busy) return;\n const action = settleAction(messageId);\n if (!action) return;\n const replyId = nextMessageId();\n setMessages((prev) => [...prev, { id: replyId, role: 'assistant', content: '', streaming: true }]);\n await runTurn(replyId, action.question, async (onStatus, onDelta) => {\n await ensureInitialized();\n return harness.executeToolCall(action.call, action.question, onStatus, onDelta);\n });\n }, [busy, settleAction, runTurn, ensureInitialized, harness]);\n\n const cancel = useCallback((messageId: string) => {\n if (!settleAction(messageId)) return;\n setMessages((prev) => [...prev, { id: nextMessageId(), role: 'assistant', content: \"Okay, I haven't changed anything.\" }]);\n }, [settleAction]);\n\n const sendVoice = useCallback(async (recording: GuideAIVoiceRecording): Promise<GuideAIVoiceResult> => {\n if (busy || transcribing) return { text: null, error: 'Wait for the current reply to finish.' };\n const guessed = audioType(recording.uri);\n setTranscribing(true);\n try {\n const result = await requireConfigured().api.postFile<{ text?: string }>(\n EP.batchVoiceTranscribe(),\n 'audio',\n { uri: recording.uri, name: guessed.name, type: recording.mimeType || guessed.type },\n { language_code: recording.languageCode || 'en-US' },\n 45_000,\n );\n const heard = result?.text?.trim() || '';\n if (!heard) return { text: null, error: \"I didn't catch that. Please try again.\" };\n if (mounted.current) setTranscribing(false);\n await send(heard);\n return { text: heard };\n } catch (error) {\n console.log('[GuideAI] ✗ voice transcription failed:', error);\n // 422 is the recording itself (too short, silent): the server's words\n // say what to do. Anything else is ours, and the user is told plainly.\n const message = error instanceof UploadError && error.status === 422\n ? error.message\n : \"I couldn't process that recording. Please try again or type your message.\";\n return { text: null, error: message };\n } finally {\n if (mounted.current) setTranscribing(false);\n }\n }, [busy, transcribing, send]);\n\n return {\n messages,\n input,\n setInput,\n send,\n busy,\n canSend: Boolean(input.trim()) && !busy,\n status,\n retry,\n clear,\n confirm,\n cancel,\n sendVoice,\n transcribing,\n };\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { EP, type OnboardingState } from '@guideai/core';\nimport { requireConfigured } from '../setup';\nimport { useGuideAIRuntime } from './context';\n\n/** Reads the same durable checklist as the browser adapter. */\nexport function useOnboarding(): {\n checklist: OnboardingState | null;\n loading: boolean;\n refresh: () => Promise<void>;\n dismiss: () => Promise<void>;\n} {\n const runtime = useGuideAIRuntime();\n const [checklist, setChecklist] = useState<OnboardingState | null>(null);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n const { api, visitorId } = requireConfigured();\n if (!visitorId) { setChecklist(null); setLoading(false); return; }\n try {\n const current = await api.get<OnboardingState | null>(EP.onboardingCurrent(visitorId));\n const screen = runtime.getActiveScreen()?.path;\n const updated = current && !current.completed && !current.dismissed && screen\n ? await api.post<OnboardingState | null>(EP.onboardingObserve(), { user_id: visitorId, screen })\n : current;\n setChecklist(updated);\n } catch {\n // The host application keeps working if the checklist service is unavailable.\n } finally { setLoading(false); }\n }, [runtime]);\n\n const dismiss = useCallback(async () => {\n const { api, visitorId } = requireConfigured();\n if (!visitorId) return;\n const updated = await api.post<OnboardingState | null>(EP.onboardingDismiss(), { user_id: visitorId });\n setChecklist(updated);\n }, []);\n\n useEffect(() => {\n void refresh();\n const timer = setInterval(() => void refresh(), 5000);\n return () => clearInterval(timer);\n }, [refresh]);\n\n return { checklist, loading, refresh, dismiss };\n}\n"],"names":["_a","_b","_c","line","failure","configured","next"],"mappings":"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"}