bunnyquery 1.5.7 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/attachment_parsers.ts","../src/engine/config.ts","../src/engine/office.ts","../src/engine/attachments.ts","../src/engine/prompts/chat_system_prompt.ts","../src/engine/prompts/indexing_system_prompt.ts","../src/engine/prompts/indexing_user_message.ts","../src/engine/errors.ts","../src/engine/links.ts","../src/engine/budget.ts","../src/engine/requests.ts","../src/engine/history.ts","../src/engine/session.ts"],"names":["i","resolvedModel"],"mappings":"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","file":"engine.mjs","sourcesContent":["/**\n * Client-side attachment-parser plugins.\n *\n * Some attachment formats can't be read by the model's web_fetch (binary) and\n * have no server-side extractor either — e.g. legacy Hancom .hwp. A parser\n * plugin runs IN THE BROWSER, turns the uploaded File into indexable text (or an\n * HTML string), and the engine sends that content INLINE in the background\n * indexing request — so the model indexes the parsed content directly, with no\n * upload-side server extraction and no web_fetch for that file.\n *\n * Register a parser with `registerAttachmentParser()`, or via\n * `configureChatEngine({ attachmentParsers: [...] })`. The BunnyQuery widget also\n * exposes `BunnyQuery.registerAttachmentParser()` and an `attachmentParsers`\n * init option. First matching parser wins.\n */\n\nexport interface AttachmentParser {\n\t/** Human-readable label — used only in logs. */\n\tname?: string;\n\t/**\n\t * Return true if this parser handles the file. Receives the file name and\n\t * (when known) its MIME type. Keep it cheap — it runs for every upload.\n\t */\n\tmatch: (file: { name: string; mime?: string }) => boolean;\n\t/**\n\t * Parse the File into indexable plain text OR an HTML string (the model reads\n\t * either). Runs in the browser; may be async. Return a falsy/empty value to\n\t * skip (the file then falls back to web_fetch / server extraction).\n\t */\n\tparse: (\n\t\tfile: File,\n\t) => string | null | undefined | Promise<string | null | undefined>;\n}\n\n// Hard ceiling on inlined parsed content (characters), mirroring the worker's\n// server-side MAX_EXTRACTED_CHARS, so a huge document can't blow the model's\n// context window or the request size.\nexport const MAX_PARSED_CONTENT_CHARS = 200_000;\n\nconst _parsers: AttachmentParser[] = [];\n\n/** Register an attachment parser. Ignores duplicates (by reference) and invalid plugins. */\nexport function registerAttachmentParser(parser: AttachmentParser): void {\n\tif (\n\t\tparser &&\n\t\ttypeof parser.match === 'function' &&\n\t\ttypeof parser.parse === 'function' &&\n\t\t_parsers.indexOf(parser) === -1\n\t) {\n\t\t_parsers.push(parser);\n\t}\n}\n\n/** Remove all registered parsers (mainly for tests / re-init). */\nexport function clearAttachmentParsers(): void {\n\t_parsers.length = 0;\n}\n\n/** Snapshot of the registered parsers. */\nexport function getAttachmentParsers(): AttachmentParser[] {\n\treturn _parsers.slice();\n}\n\n/** First parser whose `match` returns true for the given file, if any. */\nexport function findAttachmentParser(\n\tname: string,\n\tmime?: string,\n): AttachmentParser | undefined {\n\tfor (let i = 0; i < _parsers.length; i++) {\n\t\ttry {\n\t\t\tif (_parsers[i].match({ name: name, mime: mime })) return _parsers[i];\n\t\t} catch {\n\t\t\t/* a throwing matcher must not break uploads */\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Run the matching parser (if any) and return capped, trimmed content — or null\n * when there is no parser, the parser throws, or it yields nothing. Never throws:\n * a parser failure degrades to null so the upload still completes (the file then\n * resolves via its normal path).\n */\nexport async function parseAttachmentContent(\n\tfile: File,\n\tname: string,\n\tmime?: string,\n): Promise<string | null> {\n\tconst parser = findAttachmentParser(name, mime);\n\tif (!parser) return null;\n\n\tlet raw: string | null | undefined;\n\ttry {\n\t\traw = await parser.parse(file);\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[chat-engine] attachment parser ${parser.name || '(unnamed)'} failed for ${name}:`,\n\t\t\terr,\n\t\t);\n\t\treturn null;\n\t}\n\n\tlet text = (raw == null ? '' : String(raw)).trim();\n\tif (!text) return null;\n\tif (text.length > MAX_PARSED_CONTENT_CHARS) {\n\t\ttext =\n\t\t\ttext.slice(0, MAX_PARSED_CONTENT_CHARS) +\n\t\t\t`\\n...[truncated for length; original ${text.length} characters]`;\n\t}\n\treturn text;\n}\n","/**\n * Engine configuration / dependency injection.\n *\n * The engine is framework- and transport-agnostic: it never imports a skapi\n * instance or `import.meta.env`. Each consumer calls `configureChatEngine()`\n * once at startup to inject the skapi transport functions, the MCP base URL,\n * and (optionally) the `poll` value to attach to clientSecretRequest.\n *\n * Why `poll` is configurable: agent.vue uses the npm-bundled skapi-js and OMITS\n * `poll` (its clientSecretRequest auto-resolves with the final body), whereas\n * the BunnyQuery widget uses the deployed skapi-js@latest and must pass\n * `poll: 0` to get the early ack + a manual `.poll()` handle (needed for queued-\n * send cancel). So the request builders include `poll` only when it is set.\n */\n\nimport { type AttachmentParser, registerAttachmentParser } from './attachment_parsers';\n\nexport interface ChatEngineConfig {\n /** skapi.clientSecretRequest, bound to the consumer's skapi instance. */\n clientSecretRequest: (opts: any) => Promise<any>;\n /** skapi.clientSecretRequestHistory, bound to the consumer's skapi instance. */\n clientSecretRequestHistory: (params: any, fetchOptions: any) => Promise<any>;\n /** MCP server base URL (prod vs dev resolved by the consumer). */\n mcpBaseUrl: string;\n /**\n * Value to attach as `poll` on every clientSecretRequest. When `undefined`\n * the `poll` key is omitted entirely (agent.vue). BunnyQuery sets `0`.\n */\n poll?: number;\n /**\n * Optional client-side attachment parsers (e.g. an .hwp parser). Each is\n * registered at configure time; more can be added later via\n * `registerAttachmentParser()`. See attachment_parsers.ts.\n */\n attachmentParsers?: AttachmentParser[];\n}\n\nlet _config: ChatEngineConfig | null = null;\n\nexport function configureChatEngine(config: ChatEngineConfig): void {\n _config = config;\n if (config.attachmentParsers) {\n for (const parser of config.attachmentParsers) registerAttachmentParser(parser);\n }\n}\n\nexport function chatEngineConfig(): ChatEngineConfig {\n if (!_config) {\n throw new Error(\n '[chat-engine] configureChatEngine() must be called before using the engine.',\n );\n }\n return _config;\n}\n\n/** Spread helper: `{ ...pollOpt() }` adds `poll` only when configured. */\nexport function pollOpt(): { poll?: number } {\n const p = _config?.poll;\n return p === undefined ? {} : { poll: p };\n}\n","/**\n * Office-file server-side extraction helpers.\n *\n * Office documents (Microsoft .docx/.xlsx/.pptx, Hancom .hwpx, etc.) can't be\n * read by web_fetch (binary/zip). The proxy worker downloads them from db\n * storage, extracts their text server-side, and substitutes that text for a\n * placeholder token in the request body (carried under the reserved\n * `_skapi_extract` key, which the producer strips before the upstream call).\n */\n\n// A directive telling the proxy worker which office file to download + extract\n// and which placeholder token in the request body to substitute.\nexport type ExtractDirective = {\n\t/** db storage path of the file, e.g. \"folder/report.docx\" (also the src:: value). */\n\tpath: string;\n\t/** The exact token in the request body to replace with the extracted text. */\n\tplaceholder: string;\n\t/** Original filename — informational (server logs only). */\n\tname?: string;\n\t/** MIME type — informational (server logs only). */\n\tmime?: string;\n};\n\n// A directive telling the proxy worker to re-mint a fresh, short-lived URL for a\n// file the model fetches by url (PDFs, images — anything NOT server-extractable)\n// right before the upstream call, so a queued request never hands the model a\n// stale link. The worker mints from `path` and swaps `url` (the exact baked url\n// string) everywhere it appears in the request body.\nexport type FileUrlDirective = {\n\t/** db storage path of the file, e.g. \"folder/report.pdf\" (also the src:: value). */\n\tpath: string;\n\t/** The exact baked url string in the request body to replace with a fresh one. */\n\turl: string;\n};\n\n// Files whose text the worker extracts SERVER-SIDE and inlines for indexing,\n// instead of handing the agent a URL to fetch. Two groups:\n// (1) BINARY document formats the model can't read at all (OOXML, Hancom\n// HWP/HWPX, OpenDocument, EPUB) — the worker parses them.\n// (2) TEXT/data/markup/code formats. These ARE readable via web_fetch, BUT\n// some providers (OpenAI's Responses API) have no working file-fetch tool,\n// so the agent can't retrieve the URL at all. Extracting them server-side\n// (the worker just decodes the bytes) makes indexing provider-independent.\nconst OFFICE_FILE_EXTENSIONS = new Set([\n\t'doc', 'docx', 'docm',\n\t'xls', 'xlsx', 'xlsm',\n\t'ppt', 'pptx', 'pptm',\n\t'hwp', 'hwpx',\n\t'ods', 'odt', 'odp',\n\t'epub',\n]);\n\nconst TEXT_FILE_EXTENSIONS = new Set([\n\t'csv', 'tsv', 'tab', 'txt', 'text', 'log', 'md', 'markdown', 'rst',\n\t'json', 'ndjson', 'jsonl', 'geojson', 'xml', 'yaml', 'yml', 'toml',\n\t'ini', 'conf', 'cfg', 'properties', 'env', 'rtf', 'html', 'htm',\n\t'js', 'mjs', 'cjs', 'ts', 'tsx', 'jsx', 'py', 'rb', 'go', 'rs', 'java',\n\t'kt', 'c', 'h', 'cpp', 'cc', 'hpp', 'cs', 'php', 'swift', 'sh', 'bash',\n\t'zsh', 'sql', 'css', 'scss', 'less', 'vue', 'svelte', 'tex', 'srt', 'vtt',\n]);\n\n// MIME types that indicate decodable text even when the extension is unknown\n// (the worker has the same fallback, so any text/* file is extracted server-side).\nfunction isTextMime(m: string): boolean {\n\treturn (\n\t\tm.startsWith('text/') ||\n\t\tm.endsWith('+json') || m.endsWith('+xml') || m.endsWith('+yaml') ||\n\t\tm === 'application/json' || m === 'application/ld+json' ||\n\t\tm === 'application/xml' || m === 'application/yaml' || m === 'application/x-yaml' ||\n\t\tm === 'application/javascript' || m === 'application/x-javascript' ||\n\t\tm === 'application/x-sh' || m === 'application/x-ndjson' ||\n\t\tm === 'application/csv' || m === 'application/rtf' ||\n\t\tm === 'application/sql' || m === 'application/toml'\n\t);\n}\n\n/**\n * True when a file should be EXTRACTED SERVER-SIDE (text inlined for indexing)\n * rather than handed to the agent as a URL to fetch — i.e. binary office\n * documents AND all text/data/code files. Detection is extension-first (so a\n * .csv reported as an Office MIME is still treated as text), with a text-MIME\n * fallback for unlisted extensions.\n */\nexport function isServerExtractable(name?: string, mime?: string): boolean {\n\tconst ext = (name || '').split('.').pop()?.toLowerCase() || '';\n\tif (OFFICE_FILE_EXTENSIONS.has(ext)) return true;\n\tif (TEXT_FILE_EXTENSIONS.has(ext)) return true;\n\tconst m = (mime || '').toLowerCase();\n\tif (isTextMime(m)) return true;\n\treturn (\n\t\tm.includes('officedocument') ||\n\t\tm.includes('opendocument') ||\n\t\tm.includes('hwp') ||\n\t\tm.includes('epub') ||\n\t\tm === 'application/msword' ||\n\t\tm === 'application/vnd.ms-excel' ||\n\t\tm === 'application/vnd.ms-powerpoint'\n\t);\n}\n\n/** @deprecated renamed to {@link isServerExtractable} (now also covers text files). */\nexport const isOfficeFile = isServerExtractable;\n\n// Extensions that are best read WINDOW-BY-WINDOW via the readFileContent tool instead of\n// inlined once: spreadsheets (grid rows + embedded photos, and can be huge) and PDFs\n// (scanned page images). For these the indexing agent is told to page through the whole\n// file with readFileContent rather than reading a capped inline dump or web_fetching a URL.\nconst PAGED_READ_EXTENSIONS = new Set(['xls', 'xlsx', 'xlsm', 'ods', 'pdf']);\n\n/**\n * True when a file should be indexed by PAGING through readFileContent (spreadsheets and\n * PDFs), rather than inline extraction or a web_fetch URL. This is what lets a huge sheet\n * be read row-window by row-window and a scanned PDF be read page-image by page-image,\n * with embedded photos delivered to the vision model.\n */\nexport function isPagedReadFile(name?: string, mime?: string): boolean {\n\tconst ext = (name || '').split('.').pop()?.toLowerCase() || '';\n\tif (PAGED_READ_EXTENSIONS.has(ext)) return true;\n\tconst m = (mime || '').toLowerCase();\n\treturn (\n\t\tm === 'application/pdf' ||\n\t\tm === 'application/vnd.ms-excel' ||\n\t\tm.includes('spreadsheetml') ||\n\t\tm.includes('opendocument.spreadsheet')\n\t);\n}\n\n// Monotonic counter so placeholders are unique even for same-named files in one\n// request. Token shape must match the worker's _EXTRACT_PLACEHOLDER_RE:\n// {{SKAPI_FILE_CONTENT::<id>}}.\nlet _extractPlaceholderSeq = 0;\nexport function makeExtractPlaceholder(seed: string): string {\n\t_extractPlaceholderSeq += 1;\n\tconst slug = (seed || 'file').replace(/[^a-zA-Z0-9]+/g, '_').slice(-48);\n\treturn `{{SKAPI_FILE_CONTENT::${slug}-${_extractPlaceholderSeq}}}`;\n}\n\nexport interface ComposedUserMessage {\n\t/** Clean display/history copy (attachment links, NO extraction placeholders). */\n\tcomposed: string;\n\t/** LLM-bound copy — `composed` plus inline office-extraction placeholders. */\n\tcomposedForLlm: string;\n\t/** Office-extraction directives for the proxy worker (undefined if no office files). */\n\textractContent?: ExtractDirective[];\n\t/** JIT url re-mint directives for the worker (non-extractable files: PDFs, images). */\n\tfileUrls?: FileUrlDirective[];\n}\n\n// Compose the user's chat message from the typed text + uploaded attachment URLs.\n// Identical for every consumer (agent.vue + the BunnyQuery widget): appends a\n// markdown \"Attached files\" link block, and for office files\n// (.docx/.xlsx/.pptx/.hwpx) adds inline extraction placeholders to the LLM copy\n// ONLY (the proxy worker substitutes their text server-side; the display/history\n// copy stays clean so stale tokens never accumulate across replayed turns).\n// The directive `path` is the db storage path (uid-prefixed where applicable),\n// NOT the link label — it falls back to the label when no storagePath is given\n// (agent.vue uploads FLAT, so storagePath === name there).\nexport function composeUserMessage(\n\ttext: string,\n\tattachmentUrls: Array<{ name: string; url: string; storagePath?: string }>,\n): ComposedUserMessage {\n\tlet composed = text;\n\tif (attachmentUrls.length > 0) {\n\t\tconst lines = attachmentUrls.map((u) => `- [${u.name}](${u.url})`);\n\t\tcomposed = `${text}\\n\\nAttached files:\\n${lines.join('\\n')}`;\n\t}\n\tlet composedForLlm = composed;\n\tlet extractContent: ExtractDirective[] | undefined;\n\tlet fileUrls: FileUrlDirective[] | undefined;\n\tif (attachmentUrls.length > 0) {\n\t\tconst extractFiles = attachmentUrls.filter((u) => isServerExtractable(u.name));\n\t\tif (extractFiles.length > 0) {\n\t\t\tconst directives: ExtractDirective[] = [];\n\t\t\tconst sections = extractFiles.map((u) => {\n\t\t\t\tconst storagePath = u.storagePath || u.name;\n\t\t\t\tconst placeholder = makeExtractPlaceholder(storagePath);\n\t\t\t\tdirectives.push({ path: storagePath, placeholder, name: u.name });\n\t\t\t\treturn `===== ${u.name} =====\\n----- BEGIN FILE CONTENT -----\\n${placeholder}\\n----- END FILE CONTENT -----`;\n\t\t\t});\n\t\t\textractContent = directives;\n\t\t\tcomposedForLlm =\n\t\t\t\t`${composed}\\n\\nExtracted content of attached office files ` +\n\t\t\t\t`(read inline below; do NOT fetch their URLs):\\n\\n` +\n\t\t\t\tsections.join('\\n\\n');\n\t\t}\n\t\t// Files the model fetches by url (NOT server-extractable: PDFs, images) get\n\t\t// a re-mint directive so the worker swaps the baked long-lived CDN url for a\n\t\t// fresh short-lived one at send time. Extractable files are inlined as text,\n\t\t// so their url is never fetched — no directive needed. A blank url (nothing\n\t\t// to match/replace) is skipped.\n\t\tconst urlFiles = attachmentUrls.filter((u) => u.url && !isServerExtractable(u.name));\n\t\tif (urlFiles.length > 0) {\n\t\t\tfileUrls = urlFiles.map((u) => ({ path: u.storagePath || u.name, url: u.url }));\n\t\t}\n\t}\n\treturn { composed, composedForLlm, extractContent, fileUrls };\n}\n","/**\n * Attachment helpers shared by every consumer's view layer.\n *\n * The upload ORCHESTRATION is per-consumer (agent.vue does admin storage\n * accounting; the widget uses get-signed-url), but the failure-reporting shape\n * is identical, so it lives here. When an upload or its indexing request fails,\n * the orchestrator records the original `error.code` / `error.message` on the\n * attachment (`att.errorCode` / `att.errorDetail`); this groups those failed\n * attachments by (code, description) so a single report dialog can list each\n * distinct error once with all the files it affected.\n */\n\nexport interface AttachmentFailureGroup {\n\t/** The failing `error.code` (empty string when the error carried none). */\n\tcode: string;\n\t/** The failing `error.message` / human description. */\n\tmessage: string;\n\t/** Display names of the attachments that hit this exact (code, message). */\n\tfiles: string[];\n}\n\n// Group failed attachments by (code, message). A status of 'error' means the\n// upload itself failed; 'indexError' means the file uploaded but its indexing\n// request failed — both are surfaced. Order of first appearance is preserved.\nexport function groupAttachmentFailures(attachments: any[]): AttachmentFailureGroup[] {\n\tconst groups: Record<string, AttachmentFailureGroup> = {};\n\tconst order: string[] = [];\n\t(attachments || []).forEach(function (att: any) {\n\t\tif (!att || (att.status !== 'error' && att.status !== 'indexError')) return;\n\t\tconst code = String(att.errorCode || '');\n\t\tconst message = String(\n\t\t\tatt.errorDetail ||\n\t\t\tatt.errorMessage ||\n\t\t\t(att.status === 'indexError' ? 'File indexing failed' : 'File upload has failed'),\n\t\t);\n\t\tconst key = code + '\u0000' + message;\n\t\tif (!groups[key]) {\n\t\t\tgroups[key] = { code: code, message: message, files: [] };\n\t\t\torder.push(key);\n\t\t}\n\t\tgroups[key].files.push(String(att.name || '(unnamed file)'));\n\t});\n\treturn order.map(function (k) { return groups[k]; });\n}\n","/**\n * BASE PROMPT — Chat assistant\n * ============================================================================\n * System prompt sent on every chat turn. Rebuilt fresh on every send because\n * the project name/description can change at any time.\n *\n * The `${...}` placeholders are filled from the live project (service):\n * formattedServiceId -> the project ID the assistant is scoped to\n * serviceName -> project display name (only added if a description exists)\n * serviceDescription -> project description (only added if present)\n */\n\nexport type ChatSystemPromptParams = {\n\t/** The project/service ID this assistant is scoped to (formatted form). */\n\tformattedServiceId: string;\n\t/** Project display name. Only appended when a description is also present. */\n\tserviceName?: string;\n\t/** Project description. When present, name + description are appended. */\n\tserviceDescription?: string;\n};\n\nexport function buildChatSystemPrompt(params: ChatSystemPromptParams): string {\n\tconst { formattedServiceId, serviceName, serviceDescription } = params;\n\n\tlet systemPrompt = `\nYou are a dedicated assistant for the project ID: \"${formattedServiceId}\".\nScope: Only answer questions about this project and its data. Do not answer questions about other projects or topics unrelated to this project. When the user refers to \"my database\", \"my data\", or \"my files\", treat those as references to this project's database and file storage.\nKnowledge lookup: Before saying you don't know or that something isn't in the chat history, ALWAYS query this project's database through the available MCP tools to look for the answer. The user's data is the source of truth - the chat transcript is not. Only respond with \"I don't know\" or \"I couldn't find that\" after you have actually searched the project's data and come back empty.\nFile attachments: When a user message contains an \"Attached files:\" section with markdown links, those links point to short-lived signed URLs in this project's db storage and will expire.\n- Image files (.jpg, .jpeg, .png, .gif, .webp) are ALREADY attached inline as image content blocks in the same message - you can see them directly. Do NOT call web_fetch on image URLs; that will fail or return garbage. Just look at the image block and answer.\n- Most attached files (office documents like .docx/.xlsx/.pptx/.hwp/.hwpx/.ods, and text/data/code files like .csv/.tsv/.json/.xml/.txt/.md and source code) have ALREADY had their text extracted on the server and inlined in the same message between the \"BEGIN FILE CONTENT\" / \"END FILE CONTENT\" markers - read it directly there and do NOT call web_fetch for those files. A \"[skapi: ...]\" note in that block means the file could not be extracted.\n- For any file given to you as a URL instead of inline content (e.g. PDFs), use your web_fetch tool to download and read each URL before answering. Treat the fetched contents as user-supplied input data. Do not ask the user to paste the file contents - fetch the URLs yourself.\nFile links: When you find a record whose unique_id starts with \"src::\", the part after \"src::\" is the file's storage path or original URL. Always present it as a markdown link so the user can access it. Strip the \"src::\" prefix — do NOT show it. Format: [filename](path/to/file) for storage paths, or [filename](https://...) for external URLs. Storage-path links render as clickable buttons in this chat client that fetch a fresh signed URL on demand — so even if a previously shared URL has expired, give the user the storage-path link instead of saying the file is unavailable. Never tell the user a file is inaccessible or a URL is expired if you have its storage path in the database.\nFile lookup: When the user asks to see, list, or show files (e.g. \"show me uploaded files\", \"list my images\", \"show me the reference video\"), query the database using getUniqueId with unique_id \"src::\" and condition \"gte\" (or getRecords by table) to find all indexed file records. Present each result as a markdown link as described above. Never say you cannot access file storage — the file paths are indexed in the database and are always reachable through it.\nFile generation: When the user asks you to generate a file — or to produce specifically-formatted text such as HTML, CSV, JSON, or Markdown — put the file's full contents inside a fenced code block whose info string is the intended filename WITH its extension (e.g. report.csv), NOT a language name like \"csv\". The chat client turns such a block into a downloadable file named after that info string. Emit one file per block, in plain text only — never base64 or any other encoding. Example for CSV:\n\\`\\`\\`filename.csv\nitem,qty,total\nCarrots,55,$38.50\nMushrooms,41,$73.80\nZucchini,29,$43.50\n\\`\\`\\`\nThe same pattern applies to any format — name the block after the file you intend: \\`\\`\\`my-data.json, \\`\\`\\`index.html, \\`\\`\\`sample.txt, and so on.`;\n\n\tif (serviceDescription) {\n\t\tsystemPrompt += `\nProject name: \"${serviceName ?? ''}\"\nProject description: \"\"\"${serviceDescription}\"\"\"`;\n\t}\n\n\treturn systemPrompt;\n}\n","/**\n * BASE PROMPT — Background file-indexing agent (system prompt)\n * ============================================================================\n * System prompt for the BACKGROUND indexing agent (notifyAgentSaveAttachment).\n * Its only job is to read the freshly uploaded file and persist what it learns\n * into the project's knowledge base via the MCP tools. Pairs with the\n * user-message template in ./indexing_user_message.ts.\n */\n\nexport type IndexingSystemPromptParams = {\n\t/** The project/service ID being indexed into. */\n\tservice: string;\n\t/** Project display name. Only appended when a description is also present. */\n\tserviceName?: string;\n\t/** Project description. When present, name + description are appended. */\n\tserviceDescription?: string;\n};\n\nexport function buildIndexingSystemPrompt(params: IndexingSystemPromptParams): string {\n\tconst { service, serviceName, serviceDescription } = params;\n\n\tlet systemPrompt =\n`You are a background indexing agent for project ${service}.\n- Image files (.jpg, .jpeg, .png, .gif, .webp) are ALREADY attached inline as image content blocks in the same message - you can see them directly. Do NOT call web_fetch on image URLs; that will fail or return garbage. Just look at the image block and answer.\n- Most files (office documents like .docx/.xlsx/.pptx/.hwp/.hwpx/.ods, and text/data/code files like .csv/.tsv/.json/.xml/.txt/.md and source code) have ALREADY been extracted on the server and included inline in the user message between the \"BEGIN FILE CONTENT\" / \"END FILE CONTENT\" markers - read that directly. If the inline content is a \"[skapi: ...]\" note, the file could not be extracted - index it from its metadata only.\n- BIG or SCANNED files: the inline content may be only the FIRST part of a large file (it can end with a truncation or \"more remains\" note), and scanned PDFs / files with embedded photos are not fully captured inline. In those cases READ THE FILE WITH THE readFileContent TOOL: it returns the file ONE WINDOW at a time (spreadsheets as coordinate-tagged grid rows, scanned/large PDFs as rendered PAGE IMAGES, text as a range of characters). Pass the file's storage path. After each window: datafy it into records and SAVE them, THEN if the window says MORE REMAINS call readFileContent again with the cursor it gives you. Repeat until it says END OF FILE, so the WHOLE file is indexed - never stop after the first window.\n- VISION: when a readFileContent window (or an inline attachment) includes IMAGES - scanned PDF pages, or photos embedded in a spreadsheet next to a row/block - LOOK at them and capture what they show as record data (the reading/values in a scanned table, the part/defect/condition visible in a photo). The image IS part of the data; correlate each photo with its labelled block (\"PHOTO A3\" markers tie a photo to that grid row).\n- Whatever the file type, use the file's storage path (the \"storage path\" metadata line) as the \"src::\" unique_id - never the inline content or a temporary URL.\n- TABULAR data (any spreadsheet - .csv/.tsv/.xlsx/.xls/.ods, or sheet-like rows): you MUST save EVERY data row as its own record (ONE record per row) with that row's actual column values in the record's \"data\", keyed by the header names, in a dedicated table (e.g. \"spreadsheet_rows\"). Do NOT summarize, sample only a few rows, or save just file metadata - index the whole sheet, paging through it with readFileContent when it is large. Make MULTIPLE postRecords calls in batches (e.g. 30-50 rows per call) rather than one oversized call. This per-row completeness OVERRIDES brevity. ALSO save one file-level summary record (file name, sheet name(s), column headers, total row count, overall summary) - this is the record that carries the file's \"src::\" unique_id - and link EVERY per-row record to it via reference (set each row record's reference to that src:: file record; the row records themselves do NOT carry a src:: unique_id). The per-row records AND this reference linkage are BOTH mandatory: the linkage is what lets the whole sheet be found and cleaned up together when the file is re-indexed.\n- EPUB / e-books / long-form books (.epub or any book-length prose, provided inline in reading order with chapter headings preserved): you MUST save ONE record per CHAPTER (or, when chapters are unclear, per major section/topic) in a dedicated table (e.g. \"book_chapters\") - never collapse the whole book into a single record. Each chapter record's \"data\" must capture the chapter title plus its order/number AND a substantive summary of that chapter's content (key events, arguments, characters, places, concepts, terms, notable quotes). Apply AS MANY relevant tags as possible to EVERY chapter record (characters, locations, themes, topics, key concepts, key terms, dates, named entities) so the book is easy to SEARCH and cross-reference later - this is the whole point. ALSO save one book-level record (title, author, language, overall summary, chapter list / table of contents, genre/subjects) and link each chapter record to it via reference. This per-chapter completeness OVERRIDES brevity; human-readable summaries only, never raw/binary bytes.\n- This is a background indexing task: do ALL the MCP saving FIRST, never reply mid-task, and never ask the user questions. Always use the MCP tools to save what you learn - be exhaustive about meaning (and, for tabular data, about every row). SAVE AS YOU GO: persist each window's records before reading the next, so progress is never lost. If the file is so large you cannot finish in one turn, still save everything you have read so far and note the last cursor/page you reached; a follow-up will continue from there. Never store raw or binary bytes (base64, blobs); describe them in human-readable text instead.\n- Only AFTER every save is done, send exactly ONE final message summarizing what you indexed - never just \"Indexing complete\", and never a raw/base64/binary value or a large pasted dump. Keep it to a few factual sentences or a short markdown bullet list covering: the file name, its content type, each table you wrote to with its record/row count and the key columns/fields or topics captured, and anything that could not be extracted. Follow this shape - Indexed <file name> (<content type>): saved <N> records to <table(s)> capturing <key columns/fields or topics>; could not extract: <gaps, or none>.`;\n\n\tif (serviceDescription) {\n\t\tsystemPrompt += `\nProject name: \"${serviceName ?? ''}\"\nProject description: \"\"\"${serviceDescription}\"\"\"`;\n\t}\n\n\treturn systemPrompt;\n}\n","/**\n * BASE PROMPT — Background file-indexing agent (user message)\n * ============================================================================\n * USER-role message paired with the indexing system prompt. Sent by\n * notifyAgentSaveAttachment() each time a file is uploaded or re-indexed.\n *\n * NOTE: the leading line \"A new file has just been uploaded. Index it now.\" and\n * the \"- name: ...\" line are also what the chat client parses to build the\n * \"Indexing: <name>\" history bubble — keep those fields on their own lines.\n */\n\nexport type IndexingAttachmentInfo = {\n\t/** Original file name. */\n\tname: string;\n\t/** Storage path within the project's db storage. */\n\tstoragePath: string;\n\t/** MIME type, if detected. Omitted from the message when unknown. */\n\tmime?: string;\n\t/** File size in bytes, if known. Omitted from the message when unknown. */\n\tsize?: number;\n\t/** Temporary signed URL the agent/MCP fetches to read the file contents. */\n\turl: string;\n};\n\nexport type BuildIndexingUserMessageOptions = {\n\t/**\n\t * For office files (.docx/.xlsx/.pptx) the model can't read the binary via\n\t * web_fetch, so the proxy worker extracts the text server-side and replaces\n\t * this exact token with it. When provided, the message embeds the token (and\n\t * drops the temporary-URL line — there is nothing for the model to fetch).\n\t */\n\tinlineContentPlaceholder?: string;\n\t/**\n\t * Actual file content parsed CLIENT-SIDE by an attachment-parser plugin (e.g.\n\t * an .hwp parser). Embedded inline verbatim — no server extraction and no\n\t * web_fetch for this file. Takes precedence over `inlineContentPlaceholder`.\n\t */\n\tinlineContent?: string;\n\t/**\n\t * Spreadsheet or PDF: read by PAGING through the readFileContent tool (grid rows +\n\t * embedded photos / rendered scanned pages), not inline and not by web_fetch. The\n\t * message instructs the agent to page through EVERY window and datafy each.\n\t */\n\tpagedRead?: boolean;\n};\n\nexport function buildIndexingUserMessage(\n\tattachment: IndexingAttachmentInfo,\n\toptions?: BuildIndexingUserMessageOptions,\n): string {\n\tconst head =\n\t\t`A new file has just been uploaded. Index it now.\\n\\n` +\n\t\t`File metadata:\\n` +\n\t\t`- name: ${attachment.name}\\n` +\n\t\t`- storage path: ${attachment.storagePath}\\n` +\n\t\t(attachment.mime ? `- mime type: ${attachment.mime}\\n` : '') +\n\t\t(typeof attachment.size === 'number' ? `- size (bytes): ${attachment.size}\\n` : '');\n\n\tif (options?.inlineContent) {\n\t\t// Parsed client-side (an attachment-parser plugin). The content is already\n\t\t// inlined below — no server extraction, no URL to fetch.\n\t\treturn (\n\t\t\thead +\n\t\t\t`\\nThe file's content was parsed by the client and is provided inline below. ` +\n\t\t\t`Read it directly — do NOT fetch any URL for this file. ` +\n\t\t\t`Use the storage path above (not this content) for the \"src::\" unique_id.\\n\\n` +\n\t\t\t`----- BEGIN FILE CONTENT -----\\n` +\n\t\t\t`${options.inlineContent}\\n` +\n\t\t\t`----- END FILE CONTENT -----`\n\t\t);\n\t}\n\n\tif (options?.inlineContentPlaceholder) {\n\t\t// Office file: text was extracted on the server and is inlined below\n\t\t// between the markers. Do NOT fetch any URL for this file.\n\t\treturn (\n\t\t\thead +\n\t\t\t`\\nThe file's text content was extracted on the server and is provided inline below. ` +\n\t\t\t`Read it directly — do NOT fetch any URL for this file. ` +\n\t\t\t`Use the storage path above (not this content) for the \"src::\" unique_id.\\n\\n` +\n\t\t\t`----- BEGIN FILE CONTENT -----\\n` +\n\t\t\t`${options.inlineContentPlaceholder}\\n` +\n\t\t\t`----- END FILE CONTENT -----`\n\t\t);\n\t}\n\n\tif (options?.pagedRead) {\n\t\t// Spreadsheet / PDF: force the paging path. The agent MUST read this with the\n\t\t// readFileContent tool (which returns the file window by window, with grid rows,\n\t\t// embedded photos, and rendered scanned pages), NOT by fetching the URL.\n\t\treturn (\n\t\t\thead +\n\t\t\t`\\nRead this file with the readFileContent tool, using the storage path above - do NOT fetch a URL and do NOT rely on a single sample. ` +\n\t\t\t`readFileContent returns the file ONE WINDOW at a time: spreadsheets as coordinate-tagged grid rows (e.g. 'R4 A:E&I NUMBER | B:E1007'), scanned/large PDFs as rendered PAGE IMAGES, and windows may include embedded photos - LOOK at any images and datafy what they show. ` +\n\t\t\t`Page through EVERY window: for each window SAVE records for its rows/items/pages (postRecords, one record per row/item), THEN if the window says MORE REMAINS call readFileContent again with the cursor it gives you. Repeat until it says END OF FILE, so the WHOLE file is indexed. ` +\n\t\t\t`Do NOT stop after the first window and do NOT just write a summary. Use the storage path above for the \"src::\" unique_id.` +\n\t\t\t(attachment.url ? `\\n(A temporary URL is provided ONLY as a fallback if readFileContent fails: ${attachment.url})` : '')\n\t\t);\n\t}\n\n\treturn head + `- temporary URL (fetch this to read the file contents): ${attachment.url}`;\n}\n","/**\n * Error detection + message extraction (pure). Moved verbatim from the\n * agent.vue / bunnyquery chatbox so both consumers share one implementation.\n */\n\nexport function getErrorMessage(input: any): string {\n\tif (!input) return 'Something went wrong.';\n\tif (typeof input === 'string') return input;\n\tif (input.error && input.error.message) return input.error.message;\n\tif (input.body && input.body.error && input.body.error.message) return input.body.error.message;\n\tif (input.body && typeof input.body.message === 'string') return input.body.message;\n\tif (input.message) return input.message;\n\treturn 'Something went wrong.';\n}\n\nexport function isErrorResponseBody(response: any): boolean {\n\tif (!response || typeof response !== 'object') return false;\n\tif (typeof response.status_code === 'number' && response.status_code >= 400) return true;\n\tif (response.type === 'error') return true;\n\tif (response.error && (response.error.message || response.error.type)) return true;\n\tvar body = response.body;\n\tif (body && typeof body === 'object') {\n\t\tif (body.type === 'error') return true;\n\t\tif (body.error && (body.error.message || body.error.type)) return true;\n\t}\n\tif (typeof response.message === 'string' && response.message.length) {\n\t\tvar hasClaude = Array.isArray(response.content);\n\t\tvar hasOpenAI =\n\t\t\ttypeof response.output_text === 'string' ||\n\t\t\tArray.isArray(response.output) ||\n\t\t\tArray.isArray(response.choices);\n\t\tif (!hasClaude && !hasOpenAI) return true;\n\t}\n\treturn false;\n}\n\n// A request that failed because the REQUEST ITSELF is malformed — an unknown or\n// rejected parameter on a 400/422 — will deterministically re-fail if resent\n// unchanged; no session refresh or retry can fix it. Detecting it lets the retry\n// gates refuse to auto-resend (otherwise a 400 whose param name merely contains\n// \"token\", e.g. `max_output_tokens`, trips the `invalid_request + token` branch\n// of isAuthExpiredError below and loops refresh->resend forever, burning tokens).\n// This is the `_skapi_extract` 400 class. Distinct from auth-expiry, which IS\n// retryable after a token refresh — so 401 (auth) and 429/5xx (transient) are\n// intentionally NOT treated as non-retryable here.\nexport function isNonRetryableRequestError(input: any): boolean {\n\tif (!input || typeof input !== 'object') return false;\n\n\tvar status = typeof input.status_code === 'number' ? input.status_code\n\t\t: typeof input.status === 'number' ? input.status : undefined;\n\n\t// Collect the error envelope wherever it lives (response, response.body, or a\n\t// thrown error), mirroring isErrorResponseBody / isAuthExpiredError.\n\tvar param: any = undefined;\n\tvar blobs: string[] = [];\n\tvar sources = [input.error, input.body && input.body.error, input.body, input];\n\tfor (var i = 0; i < sources.length; i++) {\n\t\tvar e = sources[i];\n\t\tif (!e) continue;\n\t\tif (typeof e === 'string') { blobs.push(e); continue; }\n\t\tif (typeof e !== 'object') continue;\n\t\tif (param === undefined && e.param != null) param = e.param;\n\t\tif (typeof e.code === 'string') blobs.push(e.code);\n\t\tif (typeof e.type === 'string') blobs.push(e.type);\n\t\tif (typeof e.message === 'string') blobs.push(e.message);\n\t}\n\tvar hay = blobs.join(' | ').toLowerCase();\n\n\t// Explicit \"unknown / unsupported parameter\" is always a malformed request.\n\tif (hay.indexOf('unknown_parameter') !== -1 || hay.indexOf('unknown parameter') !== -1 ||\n\t\thay.indexOf('unsupported_parameter') !== -1 || hay.indexOf('unsupported parameter') !== -1) {\n\t\treturn true;\n\t}\n\n\t// A 400/422 invalid_request that points at a specific rejected field: resending\n\t// the identical body re-fails. (401 -> isAuthExpiredError; 429/5xx -> transient.)\n\tvar isClientReqStatus = status === 400 || status === 422;\n\tif (isClientReqStatus && param != null && param !== '') return true;\n\tif (isClientReqStatus && hay.indexOf('invalid_request') !== -1 &&\n\t\t(hay.indexOf('parameter') !== -1 || hay.indexOf('param') !== -1)) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport function isAuthExpiredError(input: any): boolean {\n\tif (!input) return false;\n\tvar blobs: string[] = [];\n\tvar push = function (v: any) { if (typeof v === 'string' && v) blobs.push(v); };\n\tif (typeof input === 'string') push(input);\n\telse {\n\t\tpush(input.message); push(input.code);\n\t\tif (input.error) { push(input.error.message); push(input.error.code); push(input.error.type); }\n\t\tif (input.body) {\n\t\t\tpush(input.body.message);\n\t\t\tif (input.body.error) { push(input.body.error.message); push(input.body.error.code); push(input.body.error.type); }\n\t\t}\n\t\tif (typeof input.status === 'number' && input.status === 401) return true;\n\t\tif (typeof input.status_code === 'number' && input.status_code === 401) return true;\n\t}\n\tvar hay = blobs.join(' | ').toLowerCase();\n\tif (!hay) return false;\n\treturn hay.indexOf('token has expired') !== -1 || hay.indexOf('token is expired') !== -1 ||\n\t\thay.indexOf('expired_token') !== -1 || hay.indexOf('invalid_token') !== -1 ||\n\t\thay.indexOf('unauthorized') !== -1 || hay.indexOf('not authorized') !== -1 ||\n\t\t(hay.indexOf('invalid_request') !== -1 && hay.indexOf('token') !== -1);\n}\n","/**\n * Pure link/path helpers (no DOM, no marked). Moved verbatim from the chatbox.\n * `serviceId` is passed as a PARAMETER (the original read it from a global) so\n * the engine stays consumer-agnostic. The HTML-emitting helpers\n * (buildLinkPartFromGroups, linkToAnchorHtml, fileToAnchorHtml, parseMsgParts*)\n * stay in each VIEW — only these pure pieces move here.\n */\n\nexport var EXPIRED_ATTACHMENT_URL_HOST = '_expired_.url';\nexport var EXPIRED_ATTACHMENT_URL_ORIGIN = 'https://' + EXPIRED_ATTACHMENT_URL_HOST;\nexport var LINK_LABEL_MAX_DISPLAY_CHARS = 32;\n\nexport function createInlineLinkRegex(): RegExp {\n\treturn /src::(\\S+)|\\[([^\\]\\n]+)\\]\\((https?:\\/\\/(?:[^\\s()]+|\\([^\\s()]*\\))+)\\)|\\[([^\\]\\n]+)\\]\\(((?:[^()\\n]+|\\([^()\\n]*\\))+)\\)|(https?:\\/\\/[^\\s<>\"']+)/g;\n}\n\nexport function safeDecodeURIComponent(v: string): string {\n\ttry { return decodeURIComponent(v); } catch (e) { return v; }\n}\n\nexport function encodePathSegments(path: string): string {\n\treturn path.split('/').filter(Boolean).map(function (s) { return encodeURIComponent(s); }).join('/');\n}\n\nexport function normalizeAttachmentPathCandidate(value: string): string {\n\treturn safeDecodeURIComponent((value || '').trim()).replace(/\\\\/g, '/').replace(/^\\/+/, '').replace(/\\/+/g, '/');\n}\n\nexport function extractRemotePathFromAttachmentHref(href: string, serviceId: string): string | null {\n\ttry {\n\t\tvar parsed = new URL(href);\n\t\tif (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return null;\n\t\tvar path = normalizeAttachmentPathCandidate(parsed.pathname || '');\n\t\tvar segs = path.split('/').filter(Boolean);\n\t\tif (!segs.length) return null;\n\t\tvar HEX = /^[a-f0-9]{32,}$/i;\n\t\tvar sid = serviceId || '';\n\t\tvar start = 0;\n\t\twhile (start < segs.length) {\n\t\t\tvar seg = segs[start];\n\t\t\tif (seg === sid || HEX.test(seg)) { start++; continue; }\n\t\t\tbreak;\n\t\t}\n\t\tvar real = segs.slice(start).join('/');\n\t\treturn real || null;\n\t} catch (e) { return null; }\n}\n\nexport function getExpiredAttachmentVisiblePath(remotePath: string, fallback?: string): string {\n\tvar n = normalizeAttachmentPathCandidate(remotePath);\n\tif (n) return n;\n\treturn normalizeAttachmentPathCandidate(fallback || 'file') || 'file';\n}\n\nexport function buildDisplayExpiredAttachmentHref(remotePath: string, fallback?: string): string {\n\treturn EXPIRED_ATTACHMENT_URL_ORIGIN + '/' + encodePathSegments(getExpiredAttachmentVisiblePath(remotePath, fallback));\n}\n\n// Does `href` point at THIS service's db attachment storage? A db attachment URL's\n// path always begins with the serviceId segment (…/<serviceId>/<hash>/<path>). Used\n// to SAFELY sanitize assistant messages — where an arbitrary external citation URL\n// must never be rewritten, only the service's own volatile db links.\nexport function isServiceDbAttachmentHref(href: string, serviceId: string): boolean {\n\tif (!serviceId) return false;\n\ttry {\n\t\tvar parsed = new URL(href);\n\t\tif (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return false;\n\t\tvar segs = normalizeAttachmentPathCandidate(parsed.pathname || '').split('/').filter(Boolean);\n\t\treturn segs.length > 0 && segs[0] === serviceId;\n\t} catch (e) { return false; }\n}\n\n// Replace volatile attachment URLs with their durable `_expired_.url/<path>`\n// placeholder so a stored/replayed copy re-mints on demand instead of going stale.\n// USER turns: the \"Attached files:\" block gates the (broad) rewrite — every url\n// there is a db link. ASSISTANT turns (forAssistant=true): no marker exists and the\n// text may contain external citation urls, so restrict the rewrite to THIS\n// service's db attachment urls and leave every other link untouched.\nexport function sanitizeAttachmentLinksForHistory(content: string, serviceId: string, forAssistant?: boolean): string {\n\tif (!content) return content;\n\tif (!forAssistant && content.indexOf('Attached files:') === -1) return content;\n\treturn content.replace(/\\[([^\\]\\n]+)\\]\\((https?:\\/\\/[^\\s)]+)\\)/g, function (_m: string, label: string, href: string) {\n\t\tif (forAssistant && !isServiceDbAttachmentHref(href, serviceId)) return _m;\n\t\tvar remotePath = extractRemotePathFromAttachmentHref(href, serviceId);\n\t\tvar labelPath = normalizeAttachmentPathCandidate(label);\n\t\tvar fullPath = remotePath || labelPath;\n\t\tif (!fullPath) return forAssistant ? _m : '[' + label + '](' + EXPIRED_ATTACHMENT_URL_ORIGIN + '/file)';\n\t\treturn '[' + label + '](' + buildDisplayExpiredAttachmentHref(fullPath, label) + ')';\n\t});\n}\n\nexport function truncateLabelForDisplay(label: string): string {\n\tif (!label) return label;\n\tif (label.length <= LINK_LABEL_MAX_DISPLAY_CHARS) return label;\n\treturn '…' + label.slice(label.length - (LINK_LABEL_MAX_DISPLAY_CHARS - 1));\n}\n","/**\n * Token-budgeting (pure). Moved verbatim from the chatbox. Constants are shared\n * module-level values (identical in both consumers); a config knob is premature.\n * buildBoundedChatMessages now takes `serviceId` in its options so it can pass it\n * to sanitizeAttachmentLinksForHistory (which used to read a global).\n */\nimport { sanitizeAttachmentLinksForHistory } from './links';\n\nexport var CONTEXT_WINDOW_DEFAULT: Record<string, number> = { claude: 200000, openai: 128000 };\nexport var CONTEXT_WINDOW_BY_MODEL: Record<string, number> = {\n\t'claude-opus-4-7': 200000, 'claude-sonnet-4': 200000, 'gpt-5.4': 128000,\n};\nexport var OUTPUT_TOKEN_RESERVE = 22000;\nexport var TOOL_AND_RESPONSE_BUFFER = 4000;\nexport var MIN_INPUT_TOKEN_BUDGET = 8000;\nexport var CLAUDE_PER_REQUEST_INPUT_CAP = 28000;\nexport var MAX_HISTORY_MESSAGES = 20;\nexport var HISTORY_TOKEN_BUDGET = 8000;\n\nexport function estimateTextTokens(text: string): number {\n\treturn Math.ceil((text || '').length / 3);\n}\n\nexport function estimateMessageTokens(msg: { role: string; content: string }): number {\n\treturn estimateTextTokens(msg.content) + estimateTextTokens(msg.role) + 6;\n}\n\nexport function getContextWindow(platform: string, model?: string): number {\n\tvar normalized = (model || '').trim().toLowerCase();\n\tif (normalized && CONTEXT_WINDOW_BY_MODEL[normalized]) return CONTEXT_WINDOW_BY_MODEL[normalized];\n\treturn CONTEXT_WINDOW_DEFAULT[platform];\n}\n\nexport function stripFileBlocksFromHistory(content: string): string {\n\tif (!content) return content;\n\treturn content.replace(/```([^\\n`]+?\\.[^\\s.`]+)\\n[\\s\\S]*?```/g, '[file previously attached: $1]');\n}\n\nexport type BoundedChatOptions = {\n\tplatform: string;\n\tmodel?: string;\n\tsystemPrompt: string;\n\thistory: Array<{ role: string; content: string }>;\n\t/** Used to strip/rewrite expired attachment links in older user turns. */\n\tserviceId: string;\n};\n\nexport function buildBoundedChatMessages(options: BoundedChatOptions) {\n\tvar contextWindow = getContextWindow(options.platform, options.model);\n\tvar contextBasedBudget = Math.max(MIN_INPUT_TOKEN_BUDGET,\n\t\tcontextWindow - OUTPUT_TOKEN_RESERVE - TOOL_AND_RESPONSE_BUFFER);\n\tvar availableInputBudget = options.platform === 'claude'\n\t\t? Math.min(contextBasedBudget, CLAUDE_PER_REQUEST_INPUT_CAP) : contextBasedBudget;\n\tvar systemCost = estimateTextTokens(options.systemPrompt) + 12;\n\tvar budgetForHistory = Math.max(1000, Math.min(HISTORY_TOKEN_BUDGET, availableInputBudget - systemCost));\n\tvar windowed = options.history.slice(-MAX_HISTORY_MESSAGES);\n\tvar latestIndex = windowed.length - 1;\n\tvar trimmed = windowed.map(function (m, i) {\n\t\tif (i === latestIndex) return m;\n\t\tvar stripped = stripFileBlocksFromHistory(m.content);\n\t\t// Sanitize BOTH roles: user turns via the \"Attached files:\" block, assistant\n\t\t// turns via the safe db-only path (forAssistant=true) so a volatile db url the\n\t\t// model emitted doesn't get replayed into the LLM context as a dead link.\n\t\tvar sanitized = sanitizeAttachmentLinksForHistory(stripped, options.serviceId, m.role !== 'user');\n\t\treturn Object.assign({}, m, { content: sanitized });\n\t});\n\tvar bounded: Array<{ role: string; content: string }> = [], used = 0;\n\tfor (var i = trimmed.length - 1; i >= 0; i--) {\n\t\tvar cost = estimateMessageTokens(trimmed[i]);\n\t\tif (used + cost > budgetForHistory && bounded.length > 0) break;\n\t\tbounded.unshift(trimmed[i]); used += cost;\n\t}\n\treturn {\n\t\tmessages: bounded.map(function (m) { return { role: m.role, content: m.content }; }),\n\t\tdroppedCount: Math.max(0, options.history.length - bounded.length),\n\t\testimatedInputTokens: used + systemCost,\n\t\testimatedBudget: availableInputBudget,\n\t};\n}\n","/**\n * AI request builders + dispatch transport (framework-agnostic).\n *\n * Ported from www.skapi.com/src/code/ai_agent.ts. The only changes vs the\n * original are dependency-injection seams:\n * - `skapi.clientSecretRequest*` -> chatEngineConfig().clientSecretRequest*\n * - MCP endpoint URL -> chatEngineConfig().mcpBaseUrl\n * - `poll` on each request -> pollOpt() (set per consumer; see config.ts)\n * - Vue `reactive`/`ref` removed (bgTaskQueue/agentViewMounted are app-level\n * state that stays in the consumer, not here;\n * only the BgTaskEntry TYPE lives here)\n */\nimport { buildIndexingSystemPrompt, buildIndexingUserMessage } from './prompts';\nimport { isServerExtractable, isPagedReadFile, makeExtractPlaceholder, type ExtractDirective, type FileUrlDirective } from './office';\nimport { chatEngineConfig, pollOpt } from './config';\n\nexport const ANTHROPIC_MESSAGES_API_URL = 'https://api.anthropic.com/v1/messages';\nconst ANTHROPIC_MODELS_API_URL = 'https://api.anthropic.com/v1/models';\nconst ANTHROPIC_VERSION = '2023-06-01';\nconst ANTHROPIC_MCP_BETA = 'mcp-client-2025-11-20';\nconst ANTHROPIC_WEB_FETCH_BETA = 'web-fetch-2025-09-10';\nconst ANTHROPIC_PROMPT_CACHING_BETA = 'prompt-caching-2024-07-31';\nconst ANTHROPIC_BETA_HEADER = `${ANTHROPIC_MCP_BETA},${ANTHROPIC_WEB_FETCH_BETA},${ANTHROPIC_PROMPT_CACHING_BETA}`;\nconst WEB_FETCH_MAX_USES = 40;\nconst WEB_FETCH_MAX_CONTENT_TOKENS = 200000;\n\nexport const OPENAI_RESPONSES_API_URL = 'https://api.openai.com/v1/responses';\nconst OPENAI_MODELS_API_URL = 'https://api.openai.com/v1/models';\nconst MAX_TOKENS = 25000;\nconst DEFAULT_OPENAI_IMAGE_DETAIL = 'auto';\nconst OPENAI_WEB_SEARCH_ENABLED = true;\nconst OPENAI_WEB_SEARCH_EXTERNAL_WEB_ACCESS = true;\nexport const MCP_NAME = 'BunnyQuery';\n\nexport const DEFAULT_CLAUDE_MODEL = 'claude-sonnet-4-6';\nexport const DEFAULT_OPENAI_MODEL = 'gpt-5.4';\n\nconst mcpUrl = () => chatEngineConfig().mcpBaseUrl;\nconst clientSecretRequest = (opts: any) => chatEngineConfig().clientSecretRequest(opts);\n\nconst getOpenAIImageDetail = (model?: string) => {\n\tconst normalized = (model || DEFAULT_OPENAI_MODEL).trim().toLowerCase();\n\tconst match = normalized.match(/^gpt-(\\d+)(?:\\.(\\d+))?$/);\n\tif (!match) {\n\t\treturn DEFAULT_OPENAI_IMAGE_DETAIL;\n\t}\n\n\tconst major = Number(match[1]);\n\tconst minor = match[2] === undefined ? null : Number(match[2]);\n\n\tif (major > 5) {\n\t\treturn 'original';\n\t}\n\n\tif (major === 5 && minor !== null && minor >= 4) {\n\t\treturn 'original';\n\t}\n\n\treturn DEFAULT_OPENAI_IMAGE_DETAIL;\n};\n\nexport type ClaudeRole = 'user' | 'assistant';\n\nexport type ClaudeMessage = {\n\trole: ClaudeRole;\n\tcontent: string;\n};\n\nexport type OpenAIMessage = {\n\trole: ClaudeRole;\n\tcontent: string;\n};\n\nexport type ClaudeMcpToolConfig = {\n\tenabled?: boolean;\n\tdefer_loading?: boolean;\n};\n\nexport type ClaudeMcpServerRequest = {\n\tname: string;\n\turl: string;\n\tauthorizationToken?: string;\n\tdefaultConfig?: ClaudeMcpToolConfig;\n\tconfigs?: Record<string, ClaudeMcpToolConfig>;\n};\n\nconst IMAGE_URL_REGEX =\n\t/\\bhttps?:\\/\\/[^\\s<>\"'()\\[\\]]+?\\.(?:jpg|jpeg|png|gif|webp)(?:\\?[^\\s<>\"'()\\[\\]]*)?/gi;\n\nexport function transformContentWithImages(\n\tcontent: string,\n): string | Array<Record<string, any>> {\n\tif (typeof content !== 'string' || !content) {\n\t\treturn content;\n\t}\n\n\tconst matches = content.match(IMAGE_URL_REGEX);\n\n\tif (!matches || !matches.length) {\n\t\treturn content;\n\t}\n\n\tconst seen = new Set<string>();\n\tconst imageBlocks: Array<Record<string, any>> = [];\n\n\tfor (const url of matches) {\n\t\tif (seen.has(url)) continue;\n\t\tseen.add(url);\n\t\timageBlocks.push({\n\t\t\ttype: 'image',\n\t\t\tsource: { type: 'url', url },\n\t\t});\n\t}\n\n\treturn [...imageBlocks, { type: 'text', text: content }];\n}\n\nfunction prepareClaudeMessages(messages: ClaudeMessage[]) {\n\tif (!messages.length) return messages;\n\t// Only transform the most recent user message. Historical user messages\n\t// may reference image URLs that are now stale (deleted, moved, expired).\n\tconst lastIndex = messages.length - 1;\n\tconst last = messages[lastIndex];\n\tif (last.role !== 'user') return messages;\n\tconst content = transformContentWithImages(last.content);\n\tif (content === last.content) return messages;\n\tconst next = messages.slice();\n\tnext[lastIndex] = { role: last.role, content } as unknown as ClaudeMessage;\n\treturn next;\n}\n\nexport function transformContentWithOpenAIImages(\n\tcontent: string,\n\tdetail = DEFAULT_OPENAI_IMAGE_DETAIL,\n): string | Array<Record<string, any>> {\n\tif (typeof content !== 'string' || !content) {\n\t\treturn content;\n\t}\n\n\tconst matches = content.match(IMAGE_URL_REGEX);\n\n\tif (!matches || !matches.length) {\n\t\treturn content;\n\t}\n\n\tconst seen = new Set<string>();\n\tconst imageBlocks: Array<Record<string, any>> = [];\n\n\tfor (const url of matches) {\n\t\tif (seen.has(url)) continue;\n\t\tseen.add(url);\n\t\timageBlocks.push({\n\t\t\ttype: 'input_image',\n\t\t\timage_url: url,\n\t\t\tdetail,\n\t\t});\n\t}\n\n\treturn [{ type: 'input_text', text: content }, ...imageBlocks];\n}\n\nfunction prepareOpenAIMessages(\n\tmessages: OpenAIMessage[],\n\tdetail = DEFAULT_OPENAI_IMAGE_DETAIL,\n) {\n\tif (!messages.length) return messages;\n\tconst lastIndex = messages.length - 1;\n\tconst last = messages[lastIndex];\n\tif (last.role !== 'user') return messages;\n\tconst content = transformContentWithOpenAIImages(last.content, detail);\n\tif (content === last.content) return messages;\n\tconst next = messages.slice();\n\tnext[lastIndex] = { role: last.role, content } as unknown as OpenAIMessage;\n\treturn next;\n}\n\n// Attach a cache_control breakpoint to the last message of the stable history\n// prefix (everything except the final user turn) so Anthropic re-uses it at\n// ~10% input-token billing.\nfunction applyHistoryCacheBreakpoint(messages: any[]): any[] {\n\tif (messages.length < 2) return messages;\n\tconst breakpointIndex = messages.length - 2;\n\treturn messages.map((m, i) => {\n\t\tif (i !== breakpointIndex) return m;\n\t\tconst blocks = Array.isArray(m.content)\n\t\t\t? m.content.slice()\n\t\t\t: [{ type: 'text', text: m.content }];\n\t\tif (!blocks.length) return m;\n\t\tconst lastBlockIndex = blocks.length - 1;\n\t\tblocks[lastBlockIndex] = {\n\t\t\t...blocks[lastBlockIndex],\n\t\t\tcache_control: { type: 'ephemeral' },\n\t\t};\n\t\treturn { ...m, content: blocks };\n\t});\n}\n\nexport type CallClaudeWithMcpParams = {\n\tprompt: string;\n\tmessages?: ClaudeMessage[];\n\tservice: string;\n\towner: string;\n\tuserId?: string;\n\tmodel?: string;\n\tmaxTokens?: number;\n\tsystem?: string;\n\tmcpServer: ClaudeMcpServerRequest;\n\textractContent?: ExtractDirective[];\n\tfileUrls?: FileUrlDirective[];\n\tonResponse?: (res: any) => void;\n\tonError?: (err: any) => void;\n};\nexport const POLL_INTERVAL = 1500;\nexport async function callClaudeWithMcp({\n\tprompt,\n\tmessages,\n\tservice,\n\towner,\n\tuserId,\n\tmodel = DEFAULT_CLAUDE_MODEL,\n\tmaxTokens = 1000,\n\tsystem,\n\tmcpServer,\n\textractContent,\n\tfileUrls,\n}: CallClaudeWithMcpParams) {\n\tconst mcpServerDefinition: Record<string, any> = {\n\t\ttype: 'url',\n\t\tname: mcpServer.name,\n\t\turl: mcpServer.url,\n\t};\n\n\tif (mcpServer.authorizationToken) {\n\t\tmcpServerDefinition.authorization_token = mcpServer.authorizationToken;\n\t}\n\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'claude',\n\t\tqueue: userId || service,\n\t\tservice,\n\t\towner,\n\t\t...pollOpt(),\n\t\turl: ANTHROPIC_MESSAGES_API_URL,\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\t'content-type': 'application/json',\n\t\t\t'x-api-key': '$CLIENT_SECRET',\n\t\t\t'anthropic-version': ANTHROPIC_VERSION,\n\t\t\t'anthropic-beta': ANTHROPIC_BETA_HEADER,\n\t\t},\n\t\tdata: {\n\t\t\tmodel,\n\t\t\tmax_tokens: maxTokens,\n\t\t\t...(extractContent && extractContent.length\n\t\t\t\t? { _skapi_extract: extractContent }\n\t\t\t\t: {}),\n\t\t\t...(fileUrls && fileUrls.length\n\t\t\t\t? { _skapi_file_urls: fileUrls }\n\t\t\t\t: {}),\n\t\t\t...(system\n\t\t\t\t? {\n\t\t\t\t\t\tsystem: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\t\ttext: system,\n\t\t\t\t\t\t\t\tcache_control: { type: 'ephemeral' },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\tmessages: (() => {\n\t\t\t\tconst prepared =\n\t\t\t\t\tmessages && messages.length\n\t\t\t\t\t\t? prepareClaudeMessages(messages)\n\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\trole: 'user',\n\t\t\t\t\t\t\t\t\tcontent: transformContentWithImages(prompt),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t];\n\t\t\t\treturn applyHistoryCacheBreakpoint(prepared as any[]);\n\t\t\t})(),\n\t\t\tmcp_servers: [mcpServerDefinition],\n\t\t\ttools: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'mcp_toolset',\n\t\t\t\t\tmcp_server_name: mcpServer.name,\n\t\t\t\t\t...(mcpServer.defaultConfig\n\t\t\t\t\t\t? { default_config: mcpServer.defaultConfig }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t...(mcpServer.configs ? { configs: mcpServer.configs } : {}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'web_fetch_20250910',\n\t\t\t\t\tname: 'web_fetch',\n\t\t\t\t\tmax_uses: WEB_FETCH_MAX_USES,\n\t\t\t\t\tcitations: { enabled: true },\n\t\t\t\t\tmax_content_tokens: WEB_FETCH_MAX_CONTENT_TOKENS,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t});\n}\n\nexport async function callClaudeWithPublicMcp(\n\tprompt: string,\n\tservice: string,\n\towner: string,\n\tmessages?: ClaudeMessage[],\n\tsystem?: string,\n\tmodel?: string,\n\tuserId?: string,\n\textractContent?: ExtractDirective[],\n\tfileUrls?: FileUrlDirective[],\n\tonResponse?: (res: any) => void,\n\tonError?: (err: any) => void,\n) {\n\treturn callClaudeWithMcp({\n\t\tprompt,\n\t\tmessages,\n\t\tservice,\n\t\towner,\n\t\tuserId,\n\t\tmodel: model || DEFAULT_CLAUDE_MODEL,\n\t\tmaxTokens: MAX_TOKENS,\n\t\tsystem,\n\t\textractContent,\n\t\tfileUrls,\n\t\tmcpServer: {\n\t\t\tname: MCP_NAME,\n\t\t\turl: mcpUrl(),\n\t\t\tauthorizationToken: '$ACCESS_TOKEN',\n\t\t},\n\t\tonResponse,\n\t\tonError,\n\t});\n}\n\nexport async function callOpenAIWithPublicMcp(\n\tprompt: string,\n\tservice: string,\n\towner: string,\n\tmessages?: OpenAIMessage[],\n\tsystem?: string,\n\tmodel?: string,\n\tuserId?: string,\n\textractContent?: ExtractDirective[],\n\tfileUrls?: FileUrlDirective[],\n\tonResponse?: (res: any) => void,\n\tonError?: (err: any) => void,\n) {\n\tconst resolvedModel = model || DEFAULT_OPENAI_MODEL;\n\tconst imageDetail = getOpenAIImageDetail(resolvedModel);\n\tconst messageList =\n\t\tmessages && messages.length\n\t\t\t? prepareOpenAIMessages(messages, imageDetail)\n\t\t\t: [\n\t\t\t\t{\n\t\t\t\t\trole: 'user' as const,\n\t\t\t\t\tcontent: transformContentWithOpenAIImages(prompt, imageDetail),\n\t\t\t\t},\n\t\t\t];\n\n\tconst responseInput = [\n\t\t...(system\n\t\t\t? [\n\t\t\t\t{\n\t\t\t\t\trole: 'system',\n\t\t\t\t\tcontent: system,\n\t\t\t\t},\n\t\t\t]\n\t\t\t: []),\n\t\t...messageList.map((m) => ({\n\t\t\trole: m.role,\n\t\t\tcontent: m.content,\n\t\t})),\n\t];\n\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'openai',\n\t\tqueue: userId || service,\n\t\tservice,\n\t\towner,\n\t\t...pollOpt(),\n\t\turl: OPENAI_RESPONSES_API_URL,\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\t'content-type': 'application/json',\n\t\t\tAuthorization: 'Bearer $CLIENT_SECRET',\n\t\t},\n\t\tdata: {\n\t\t\tmodel: resolvedModel,\n\t\t\tmax_output_tokens: MAX_TOKENS,\n\t\t\t...(extractContent && extractContent.length\n\t\t\t\t? { _skapi_extract: extractContent }\n\t\t\t\t: {}),\n\t\t\t...(fileUrls && fileUrls.length\n\t\t\t\t? { _skapi_file_urls: fileUrls }\n\t\t\t\t: {}),\n\t\t\tinput: responseInput,\n\t\t\ttools: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'mcp',\n\t\t\t\t\tserver_label: MCP_NAME,\n\t\t\t\t\tserver_url: mcpUrl(),\n\t\t\t\t\trequire_approval: 'never',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: 'Bearer $ACCESS_TOKEN',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t...(OPENAI_WEB_SEARCH_ENABLED\n\t\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'web_search',\n\t\t\t\t\t\t\texternal_web_access: OPENAI_WEB_SEARCH_EXTERNAL_WEB_ACCESS,\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t],\n\t\t},\n\t});\n}\n\nexport type AttachmentSaveInfo = {\n\tplatform: 'claude' | 'openai';\n\tmodel?: string;\n\tservice: string;\n\towner: string;\n\tuserId?: string;\n\tserviceName?: string;\n\tserviceDescription?: string;\n\tattachment: {\n\t\tname: string;\n\t\tstoragePath: string;\n\t\tmime?: string;\n\t\tsize?: number;\n\t\turl: string;\n\t};\n\t/**\n\t * Content parsed CLIENT-SIDE by an attachment-parser plugin (e.g. an .hwp\n\t * parser). When set, it is inlined into the indexing message verbatim and\n\t * takes precedence over server-side office extraction / web_fetch.\n\t */\n\tparsedContent?: string;\n};\n\n// Background \"save into knowledge\" call (not a chat turn). A client-parsed file\n// (parser plugin) is inlined directly; otherwise office files get the\n// _skapi_extract directive + a placeholder, and everything else gets a URL.\nexport async function notifyAgentSaveAttachment(info: AttachmentSaveInfo) {\n\tconst { platform, service, owner, attachment, parsedContent } = info;\n\n\t// Spreadsheets and PDFs are read by PAGING through readFileContent (grid rows +\n\t// embedded photos / scanned page images), NOT inlined once - so they skip the inline\n\t// server-extract and the agent is told to page the whole file (see pagedRead below).\n\tconst pagedRead = !parsedContent && isPagedReadFile(attachment.name, attachment.mime);\n\n\t// Client-parsed content wins over server-side extraction.\n\tconst serverExtract = !parsedContent && !pagedRead && isServerExtractable(attachment.name, attachment.mime);\n\tconst placeholder = serverExtract ? makeExtractPlaceholder(attachment.storagePath) : undefined;\n\tconst extractContent: ExtractDirective[] | undefined =\n\t\tserverExtract && placeholder\n\t\t\t? [{ path: attachment.storagePath, placeholder, name: attachment.name, mime: attachment.mime }]\n\t\t\t: undefined;\n\tconst skapiExtract =\n\t\textractContent && extractContent.length ? { _skapi_extract: extractContent } : {};\n\n\tconst userMessage = buildIndexingUserMessage(\n\t\tattachment,\n\t\tparsedContent\n\t\t\t? { inlineContent: parsedContent }\n\t\t\t: placeholder\n\t\t\t\t? { inlineContentPlaceholder: placeholder }\n\t\t\t\t: pagedRead\n\t\t\t\t\t? { pagedRead: true }\n\t\t\t\t\t: undefined,\n\t);\n\n\tconst systemPrompt = buildIndexingSystemPrompt({\n\t\tservice,\n\t\tserviceName: info.serviceName,\n\t\tserviceDescription: info.serviceDescription,\n\t});\n\n\tif (platform === 'openai') {\n\t\tconst resolvedModel = info.model || DEFAULT_OPENAI_MODEL;\n\t\tconst imageDetail = getOpenAIImageDetail(resolvedModel);\n\t\treturn clientSecretRequest({\n\t\t\tclientSecretName: 'openai',\n\t\t\tqueue: (info.userId || service) + BG_INDEXING_QUEUE_SUFFIX,\n\t\t\tservice,\n\t\t\towner,\n\t\t\t...pollOpt(),\n\t\t\turl: OPENAI_RESPONSES_API_URL,\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'content-type': 'application/json',\n\t\t\t\tAuthorization: 'Bearer $CLIENT_SECRET',\n\t\t\t},\n\t\t\tdata: {\n\t\t\t\tmodel: resolvedModel,\n\t\t\t\tmax_output_tokens: MAX_TOKENS,\n\t\t\t\t...skapiExtract,\n\t\t\t\tinput: [\n\t\t\t\t\t{ role: 'system', content: systemPrompt },\n\t\t\t\t\t{\n\t\t\t\t\t\trole: 'user',\n\t\t\t\t\t\tcontent: transformContentWithOpenAIImages(userMessage, imageDetail),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\ttools: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'mcp',\n\t\t\t\t\t\tserver_label: MCP_NAME,\n\t\t\t\t\t\tserver_url: mcpUrl(),\n\t\t\t\t\t\trequire_approval: 'never',\n\t\t\t\t\t\theaders: { Authorization: 'Bearer $ACCESS_TOKEN' },\n\t\t\t\t\t},\n\t\t\t\t\t...(OPENAI_WEB_SEARCH_ENABLED\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'web_search',\n\t\t\t\t\t\t\t\t\texternal_web_access: OPENAI_WEB_SEARCH_EXTERNAL_WEB_ACCESS,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: []),\n\t\t\t\t],\n\t\t\t},\n\t\t});\n\t}\n\n\tconst resolvedModel = info.model || DEFAULT_CLAUDE_MODEL;\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'claude',\n\t\tqueue: (info.userId || service) + BG_INDEXING_QUEUE_SUFFIX,\n\t\tservice,\n\t\towner,\n\t\t...pollOpt(),\n\t\turl: ANTHROPIC_MESSAGES_API_URL,\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\t'content-type': 'application/json',\n\t\t\t'x-api-key': '$CLIENT_SECRET',\n\t\t\t'anthropic-version': ANTHROPIC_VERSION,\n\t\t\t'anthropic-beta': ANTHROPIC_BETA_HEADER,\n\t\t},\n\t\tdata: {\n\t\t\tmodel: resolvedModel,\n\t\t\tmax_tokens: MAX_TOKENS,\n\t\t\t...skapiExtract,\n\t\t\tsystem: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\ttext: systemPrompt,\n\t\t\t\t\tcache_control: { type: 'ephemeral' },\n\t\t\t\t},\n\t\t\t],\n\t\t\tmessages: [\n\t\t\t\t{\n\t\t\t\t\trole: 'user',\n\t\t\t\t\tcontent: transformContentWithImages(userMessage),\n\t\t\t\t},\n\t\t\t],\n\t\t\tmcp_servers: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'url',\n\t\t\t\t\tname: MCP_NAME,\n\t\t\t\t\turl: mcpUrl(),\n\t\t\t\t\tauthorization_token: '$ACCESS_TOKEN',\n\t\t\t\t},\n\t\t\t],\n\t\t\ttools: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'mcp_toolset',\n\t\t\t\t\tmcp_server_name: MCP_NAME,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'web_fetch_20250910',\n\t\t\t\t\tname: 'web_fetch',\n\t\t\t\t\tmax_uses: WEB_FETCH_MAX_USES,\n\t\t\t\t\tcitations: { enabled: true },\n\t\t\t\t\tmax_content_tokens: WEB_FETCH_MAX_CONTENT_TOKENS,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t});\n}\n\nexport function extractClaudeText(response: any) {\n\tif (!Array.isArray(response?.content)) {\n\t\treturn '';\n\t}\n\n\treturn response.content\n\t\t.filter((block: any) => block?.type === 'text')\n\t\t.map((block: any) => block.text)\n\t\t.join('\\n');\n}\n\nexport function extractOpenAIText(response: any) {\n\tif (\n\t\ttypeof response?.output_text === 'string' &&\n\t\tresponse.output_text.length\n\t) {\n\t\treturn response.output_text;\n\t}\n\n\tif (Array.isArray(response?.output)) {\n\t\tconst text = response.output\n\t\t\t.flatMap((item: any) => item?.content || [])\n\t\t\t.filter((part: any) => part?.type === 'output_text')\n\t\t\t.map((part: any) => part.text || '')\n\t\t\t.join('\\n')\n\t\t\t.trim();\n\n\t\tif (text) {\n\t\t\treturn text;\n\t\t}\n\t}\n\n\tconst content = response?.choices?.[0]?.message?.content;\n\n\tif (typeof content === 'string') {\n\t\treturn content;\n\t}\n\n\tif (Array.isArray(content)) {\n\t\treturn content\n\t\t\t.map((part: any) => {\n\t\t\t\tif (typeof part === 'string') {\n\t\t\t\t\treturn part;\n\t\t\t\t}\n\t\t\t\tif (part?.type === 'text') {\n\t\t\t\t\treturn part.text || '';\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t})\n\t\t\t.join('\\n');\n\t}\n\n\treturn '';\n}\n\nexport async function listClaudeModels(service: string, owner: string) {\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'claude',\n\t\tservice,\n\t\towner,\n\t\turl: ANTHROPIC_MODELS_API_URL,\n\t\tmethod: 'GET',\n\t\theaders: {\n\t\t\t'x-api-key': '$CLIENT_SECRET',\n\t\t\t'anthropic-version': ANTHROPIC_VERSION,\n\t\t},\n\t});\n}\n\nexport async function listOpenAIModels(service: string, owner: string) {\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'openai',\n\t\tservice,\n\t\towner,\n\t\turl: OPENAI_MODELS_API_URL,\n\t\tmethod: 'GET',\n\t\theaders: {\n\t\t\tAuthorization: 'Bearer $CLIENT_SECRET',\n\t\t},\n\t});\n}\n\n// Suffix for the background-indexing queue. Must sort *before* ':' (ASCII 58)\n// so the chat-history BETWEEN query never includes bg-queue items. '-' (45) works.\nexport const BG_INDEXING_QUEUE_SUFFIX = '-bg';\n\n// Pending background-indexing task descriptor. NOTE: the live mutable queue\n// (a Vue `reactive([])` in agent.vue, a plain array in bunnyquery) is app-level\n// state owned by the consumer — only the TYPE lives in the engine.\nexport type BgTaskEntry = {\n\tserviceId: string;\n\tplatform: 'claude' | 'openai';\n\tid: string;\n\tfilename: string;\n\tstoragePath?: string;\n\tisReindex?: boolean;\n\tmime?: string;\n\tsize?: number;\n\tstatus: 'running' | 'pending';\n\tpoll: ((opts: { latency: number }) => Promise<any>) | undefined;\n};\n\nexport async function getChatHistory(\n\tparams: { service?: string; owner?: string; platform: 'claude' | 'openai'; queue?: string },\n\tfetchOptions: Record<string, any>,\n) {\n\tconst url =\n\t\tparams.platform === 'claude'\n\t\t\t? ANTHROPIC_MESSAGES_API_URL\n\t\t\t: OPENAI_RESPONSES_API_URL;\n\tconst p = Object.assign(\n\t\t{\n\t\t\turl,\n\t\t\tmethod: 'POST',\n\t\t},\n\t\t{ service: params.service, owner: params.owner },\n\t\tparams.queue ? { queue: params.queue } : {},\n\t);\n\n\treturn chatEngineConfig().clientSecretRequestHistory(\n\t\tp as { url: string; method: 'POST'; queue?: string },\n\t\tObject.assign({ ascending: false }, fetchOptions),\n\t);\n}\n","/**\n * History mapping (pure). Moved verbatim from the chatbox. The clear-horizon\n * timestamp and the \"Indexing: …\" display label are INJECTED (clearedAt param,\n * formatIndexingLabel callback) so the engine touches neither localStorage nor\n * view-specific display formatting. serviceId is passed for link sanitization.\n */\nimport { extractClaudeText, extractOpenAIText } from './requests';\nimport { isErrorResponseBody, getErrorMessage } from './errors';\nimport { sanitizeAttachmentLinksForHistory } from './links';\n\nexport function filterListByClearHorizon(list: any[], clearedAt: number): any[] {\n\tif (!clearedAt) return list;\n\treturn list.filter(function (item) {\n\t\tvar updated = Number(item && item.updated);\n\t\treturn isFinite(updated) && updated > clearedAt;\n\t});\n}\n\nexport function normalizeTextContent(content: any): string {\n\tif (typeof content === 'string') return content;\n\tif (Array.isArray(content)) {\n\t\treturn content.map(function (part: any) {\n\t\t\tif (typeof part === 'string') return part;\n\t\t\tif (part && (part.type === 'text' || part.type === 'input_text' || part.type === 'output_text')) return part.text || '';\n\t\t\treturn '';\n\t\t}).join('\\n').trim();\n\t}\n\treturn '';\n}\n\nexport function extractLastUserTextFromRequest(requestBody: any): string {\n\tvar arr = requestBody && Array.isArray(requestBody.messages) ? requestBody.messages\n\t\t: (requestBody && Array.isArray(requestBody.input) ? requestBody.input : []);\n\tfor (var i = arr.length - 1; i >= 0; i--) {\n\t\tif (arr[i] && arr[i].role === 'user') {\n\t\t\tvar t = normalizeTextContent(arr[i].content);\n\t\t\tif (t) return t;\n\t\t}\n\t}\n\treturn '';\n}\n\nexport type MapHistoryOptions = {\n\tclearedAt: number;\n\tserviceId: string;\n\t/** View-side display formatter for \"Indexing:/Reindexing: …\" bubbles. */\n\tformatIndexingLabel: (name: string, mime?: string, size?: number | null, storagePath?: string) => string;\n};\n\nexport function mapHistoryListToMessages(list: any[], platform: 'claude' | 'openai', opts: MapHistoryOptions) {\n\tvar mapped: any[] = [], runningItemIds: string[] = [];\n\tvar extractAssistantText = platform === 'openai' ? extractOpenAIText : extractClaudeText;\n\tvar filtered = filterListByClearHorizon(list, opts.clearedAt);\n\tfiltered.slice().reverse().forEach(function (item) {\n\t\tvar requestBody = item && item.request_body;\n\t\tvar isInProcess = item && item.status === 'running';\n\t\tvar isQueued = item && item.status === 'pending';\n\t\tvar isCancelledItem = item && item.status === 'cancelled';\n\t\tvar isPending = isInProcess || isQueued;\n\t\tvar isFailed = item && item.status === 'failed';\n\t\tvar response = isFailed ? (item.error != null ? item.error : item.response_body)\n\t\t\t: (item && item.response_body != null ? item.response_body : item && item.error);\n\t\tvar userText = extractLastUserTextFromRequest(requestBody);\n\t\tvar assistantText = isPending ? '' : ((extractAssistantText(response) || '').trim() || '');\n\t\tvar isErrorResponse = !isPending && (isFailed || isErrorResponseBody(response));\n\t\tvar serverItemId = item && typeof item.id === 'string' && item.id ? item.id : undefined;\n\n\t\tif (userText) {\n\t\t\tvar displayContent;\n\t\t\tif (item._isBgTask) {\n\t\t\t\tvar nameMatch = userText.match(/^- name: (.+)$/m);\n\t\t\t\tif (nameMatch) {\n\t\t\t\t\tvar mimeMatch = userText.match(/^- mime type: (.+)$/m);\n\t\t\t\t\tvar sizeMatch = userText.match(/^- size \\(bytes\\): (\\d+)$/m);\n\t\t\t\t\tvar pathMatch = userText.match(/^- storage path: (.+)$/m);\n\t\t\t\t\tdisplayContent = opts.formatIndexingLabel(\n\t\t\t\t\t\tnameMatch[1].trim(),\n\t\t\t\t\t\tmimeMatch ? mimeMatch[1].trim() : '',\n\t\t\t\t\t\tsizeMatch ? Number(sizeMatch[1]) : null,\n\t\t\t\t\t\tpathMatch ? pathMatch[1].trim() : undefined\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tdisplayContent = userText;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdisplayContent = sanitizeAttachmentLinksForHistory(userText, opts.serviceId);\n\t\t\t}\n\t\t\tvar userMsg: any = { role: 'user', content: displayContent };\n\t\t\tif (isInProcess) userMsg.isPendingInProcess = true;\n\t\t\tif (isQueued) userMsg.isPendingQueued = true;\n\t\t\tif (isCancelledItem) userMsg.isCancelled = true;\n\t\t\tif (item._isBgTask) userMsg.isBackgroundTask = true;\n\t\t\tif (item._isOnBgQueue) userMsg._useBgQueue = true;\n\t\t\tif (serverItemId !== undefined) userMsg._serverItemId = serverItemId;\n\t\t\tmapped.push(userMsg);\n\t\t}\n\t\tif (isCancelledItem) { /* no assistant bubble */ }\n\t\telse if (isInProcess) {\n\t\t\tvar ph: any = { role: 'assistant', content: '', isPending: true, isPendingInProcess: true };\n\t\t\tif (item._isBgTask) ph.isBackgroundTask = true;\n\t\t\tif (serverItemId !== undefined) { ph._serverItemId = serverItemId; runningItemIds.push(serverItemId); }\n\t\t\tmapped.push(ph);\n\t\t} else if (isQueued) { /* no assistant placeholder */ }\n\t\telse if (isErrorResponse) {\n\t\t\tvar em: any = { role: 'assistant', content: getErrorMessage(response), isError: true };\n\t\t\tif (item._isBgTask) em.isBackgroundTask = true;\n\t\t\tif (serverItemId !== undefined) em._serverItemId = serverItemId;\n\t\t\tmapped.push(em);\n\t\t} else if (assistantText) {\n\t\t\t// Safe db-only sanitize (forAssistant) so a volatile db url the model\n\t\t\t// emitted renders as a re-mintable `_expired_.url` link, not a dead one.\n\t\t\tvar okm: any = { role: 'assistant', content: sanitizeAttachmentLinksForHistory(assistantText, opts.serviceId, true) };\n\t\t\tif (item._isBgTask) okm.isBackgroundTask = true;\n\t\t\tif (serverItemId !== undefined) okm._serverItemId = serverItemId;\n\t\t\tmapped.push(okm);\n\t\t}\n\t});\n\treturn { messages: mapped, runningItemIds: runningItemIds };\n}\n","/**\n * ChatSession — framework-agnostic stateful chat orchestration.\n *\n * Ported verbatim from the bunnyquery widget's in-place state machine (which was\n * itself ported from agent.vue), with three mechanical substitutions:\n * CS.<field> -> this.state.<field>\n * renderMessages() -> this.host.notify()\n * S.<x> / skapi -> this.host.getIdentity().<x> / this.host.cancelRequest / refreshSession\n * scroll/refresh -> this.host.scrollToBottom(IfSticky) / refreshMessageBubble\n * Module-level singletons (bgTaskQueue, aiChatHistoryCache, pendingAgentRequests,\n * cancelledServerIds, historyItemPolls) become instance fields. The provider\n * request builders are reached through the engine (which already has the skapi\n * transport + poll injected via configureChatEngine), so cancel/poll behavior is\n * preserved.\n *\n * The view (per consumer) keeps: rendering, markdown PARSE, DOM refs + scroll\n * measurement, attachment chips, and the auth/account shell. It drives the\n * session via the public methods and re-renders in host.notify().\n */\nimport {\n\tcallClaudeWithPublicMcp,\n\tcallOpenAIWithPublicMcp,\n\tnotifyAgentSaveAttachment,\n\textractClaudeText,\n\textractOpenAIText,\n\tgetChatHistory,\n\tPOLL_INTERVAL,\n\tBG_INDEXING_QUEUE_SUFFIX,\n\tANTHROPIC_MESSAGES_API_URL,\n\tOPENAI_RESPONSES_API_URL,\n\ttype BgTaskEntry,\n} from './requests';\nimport { isErrorResponseBody, isAuthExpiredError, isNonRetryableRequestError, getErrorMessage } from './errors';\nimport { buildBoundedChatMessages } from './budget';\nimport { createInlineLinkRegex } from './links';\nimport { mapHistoryListToMessages, extractLastUserTextFromRequest } from './history';\nimport { parseAttachmentContent } from './attachment_parsers';\nimport type { ChatHost, ChatState, ChatMessage } from './host';\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise(function (r) { setTimeout(r, ms); });\n}\n\n// requestAnimationFrame / high-res clock, reached through globalThis so the\n// engine stays DOM-free at the type level (and degrades gracefully in non-DOM\n// / test environments where these globals are absent).\nvar _g: any = typeof globalThis !== 'undefined' ? globalThis : {};\nfunction nowMs(): number {\n\treturn (_g.performance && typeof _g.performance.now === 'function') ? _g.performance.now() : Date.now();\n}\nfunction nextFrame(cb: (t: number) => void): void {\n\tif (typeof _g.requestAnimationFrame === 'function') { _g.requestAnimationFrame(cb); return; }\n\tsetTimeout(function () { cb(nowMs()); }, 16);\n}\n\nexport class ChatSession {\n\thost: ChatHost;\n\tstate: ChatState;\n\tbgTaskQueue: BgTaskEntry[];\n\tcancelledServerIds: Set<string>;\n\tpendingAgentRequests: Record<string, Promise<any>>;\n\taiChatHistoryCache: Record<string, { messages: ChatMessage[]; endOfList: boolean; startKeyHistory: string[] }>;\n\thistoryItemPolls: Map<string, boolean>;\n\tprivate _lidSeq: number;\n\n\tconstructor(host: ChatHost) {\n\t\tthis.host = host;\n\t\tthis.state = {\n\t\t\tmessages: [],\n\t\t\tattachments: [],\n\t\t\tuploadingAttachments: false,\n\t\t\tsending: false,\n\t\t\ttyping: false,\n\t\t\ttypingAbort: false,\n\t\t\tloadingHistory: false,\n\t\t\tloadingOlderHistory: false,\n\t\t\thistoryEndOfList: false,\n\t\t\thistoryStartKeyHistory: [],\n\t\t\thistoryRequestToken: 0,\n\t\t\tgateRefreshToken: 0,\n\t\t};\n\t\tthis.bgTaskQueue = [];\n\t\tthis.cancelledServerIds = new Set();\n\t\tthis.pendingAgentRequests = {};\n\t\tthis.aiChatHistoryCache = {};\n\t\tthis.historyItemPolls = new Map();\n\t\tthis._lidSeq = 0;\n\t}\n\n\tprivate _newLocalId(): string {\n\t\tthis._lidSeq += 1;\n\t\treturn 'lid_' + this._lidSeq;\n\t}\n\n\tgetHistoryCacheKey(): string {\n\t\tvar id = this.host.getIdentity();\n\t\tif (!id.serviceId || id.platform === 'none') return '';\n\t\treturn id.serviceId + '#' + id.platform;\n\t}\n\n\tupdateHistoryCache(): void {\n\t\tvar key = this.getHistoryCacheKey();\n\t\tif (!key) return;\n\t\tthis.aiChatHistoryCache[key] = {\n\t\t\tmessages: this.state.messages.slice(),\n\t\t\tendOfList: this.state.historyEndOfList,\n\t\t\tstartKeyHistory: this.state.historyStartKeyHistory.slice(),\n\t\t};\n\t}\n\n\tprivate _callProviderFor(platform: string, prompt: string, messages: any, system: string, model: string | undefined, userId: string, extractContent: any, fileUrls?: any) {\n\t\tvar id = this.host.getIdentity();\n\t\treturn platform === 'openai'\n\t\t\t? callOpenAIWithPublicMcp(prompt, id.serviceId, id.owner, messages, system, model, userId, extractContent, fileUrls)\n\t\t\t: callClaudeWithPublicMcp(prompt, id.serviceId, id.owner, messages, system, model, userId, extractContent, fileUrls);\n\t}\n\n\tdispatchAgentRequest(params: any) {\n\t\tvar self = this;\n\t\t// Id of the in-flight item this dispatch polls. Recorded in\n\t\t// historyItemPolls (set below, deleted when the dispatch settles) so a\n\t\t// remount / history refetch dedups against THIS poll instead of stacking\n\t\t// a duplicate history poll on the same item. (The cacheKey guard alone\n\t\t// stops covering an item once pendingAgentRequests clears — e.g. a queued\n\t\t// message still in flight after the immediate one resolved.)\n\t\tvar dispatchItemId: string | undefined;\n\t\tvar sendAndPoll = function () {\n\t\t\treturn Promise.resolve(\n\t\t\t\tself._callProviderFor(params.aiPlatform, params.text, params.boundedMessages, params.systemPrompt, params.aiModel, params.userId, params.extractContent, params.fileUrls)\n\t\t\t).then(function (initial: any) {\n\t\t\t\tif (initial && initial.poll && (initial.status === 'pending' || initial.status === 'running')) {\n\t\t\t\t\tif (initial.id) {\n\t\t\t\t\t\tif (dispatchItemId && dispatchItemId !== initial.id) self.historyItemPolls.delete(dispatchItemId);\n\t\t\t\t\t\tdispatchItemId = initial.id;\n\t\t\t\t\t\tself.historyItemPolls.set(initial.id, true);\n\t\t\t\t\t}\n\t\t\t\t\treturn initial.poll({ latency: POLL_INTERVAL });\n\t\t\t\t}\n\t\t\t\treturn initial;\n\t\t\t});\n\t\t};\n\t\tvar run = sendAndPoll()\n\t\t\t.catch(function (err: any) {\n\t\t\t\t// Only auth-expiry is worth a refresh+resend; a malformed-request 400\n\t\t\t\t// (e.g. the `_skapi_extract`/unknown-parameter class) re-fails identically,\n\t\t\t\t// so never loop on it — guard against isAuthExpiredError's heuristic\n\t\t\t\t// misfiring on a param name that merely contains \"token\".\n\t\t\t\tif (isAuthExpiredError(err) && !isNonRetryableRequestError(err)) return self.host.refreshSession().then(sendAndPoll);\n\t\t\t\tthrow err;\n\t\t\t})\n\t\t\t.then(function (response: any) {\n\t\t\t\tif (isErrorResponseBody(response) && isAuthExpiredError(response) && !isNonRetryableRequestError(response)) {\n\t\t\t\t\treturn self.host.refreshSession().then(sendAndPoll);\n\t\t\t\t}\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.then(function (response: any) {\n\t\t\t\tif (isErrorResponseBody(response)) return { content: getErrorMessage(response), isError: true };\n\t\t\t\tvar answer = (params.aiPlatform === 'openai' ? extractOpenAIText(response) : extractClaudeText(response));\n\t\t\t\tanswer = (answer || '').trim();\n\t\t\t\treturn { content: answer || 'No text response received from AI provider.', isError: false };\n\t\t\t})\n\t\t\t.catch(function (err: any) { return { content: getErrorMessage(err), isError: true }; })\n\t\t\t.then(function (result: any) {\n\t\t\t\t// Land the resolved reply in the shared history cache. This runs\n\t\t\t\t// independently of the view lifecycle, so a reply is captured even\n\t\t\t\t// if the chatbox unmounted mid-request.\n\t\t\t\tdelete self.pendingAgentRequests[params.key];\n\t\t\t\tif (dispatchItemId) self.historyItemPolls.delete(dispatchItemId);\n\t\t\t\tvar existing = self.aiChatHistoryCache[params.key] || { messages: [], endOfList: false, startKeyHistory: [] };\n\t\t\t\tvar reply: ChatMessage = { role: 'assistant', content: result.content, isError: result.isError };\n\n\t\t\t\t// REPLACE the trailing pending \"Thinking...\" bubble in the cache with\n\t\t\t\t// the answer (falling back to append when none is present), regardless\n\t\t\t\t// of whether this chat is the currently-visible view. The cache must\n\t\t\t\t// NEVER retain a pending \"Thinking...\" bubble: even when the chatbox is\n\t\t\t\t// showing this chat, typewriteLatestReply swaps the bubble only in\n\t\t\t\t// state.messages and NEVER re-snapshots the cache — so appending a\n\t\t\t\t// duplicate here would leave the cached copy stuck pending, and a later\n\t\t\t\t// cache-first remount (agent.vue's loadChatHistory) would re-render that\n\t\t\t\t// \"Thinking...\" forever. typewriteLatestReply still finds this reply (it\n\t\t\t\t// reads the latest non-pending assistant from the cache), so replacing is\n\t\t\t\t// correct for the visible case too. The next fresh history fetch\n\t\t\t\t// reconciles it either way.\n\t\t\t\tvar msgs = existing.messages.slice();\n\t\t\t\tvar idx = -1;\n\t\t\t\tfor (var i = msgs.length - 1; i >= 0; i--) {\n\t\t\t\t\tvar m = msgs[i];\n\t\t\t\t\tif (m && m.isPending && m.role === 'assistant' && !m.isBackgroundTask) { idx = i; break; }\n\t\t\t\t}\n\t\t\t\tif (idx !== -1) {\n\t\t\t\t\treply._serverItemId = msgs[idx]._serverItemId;\n\t\t\t\t\tmsgs[idx] = reply;\n\t\t\t\t} else {\n\t\t\t\t\tmsgs.push(reply);\n\t\t\t\t}\n\t\t\t\tself.aiChatHistoryCache[params.key] = {\n\t\t\t\t\tmessages: msgs,\n\t\t\t\t\tendOfList: existing.endOfList,\n\t\t\t\t\tstartKeyHistory: existing.startKeyHistory,\n\t\t\t\t};\n\t\t\t\treturn result;\n\t\t\t});\n\t\tthis.pendingAgentRequests[params.key] = run;\n\t\treturn run;\n\t}\n\n\t// composed = clean display text; composedForLlm carries office-extraction\n\t// placeholders for the provider only. useBgQueue routes a post-attachment turn\n\t// onto the \"-bg\" queue so it runs after indexing.\n\tdispatchComposedMessage(composed: string, useBgQueue?: boolean, composedForLlm?: string, extractContent?: any, fileUrls?: any): void {\n\t\tvar self = this;\n\t\tif (!composed) return;\n\t\tvar id = this.host.getIdentity();\n\t\tif (id.platform === 'none') return;\n\n\t\tvar llmComposed = composedForLlm || composed;\n\n\t\tvar isQueuedSend = useBgQueue || this.state.sending || this.state.messages.some(function (m) {\n\t\t\treturn (m.isPending || m.isPendingQueued) && !m.isBackgroundTask && !m._useBgQueue;\n\t\t});\n\n\t\tvar aiPlatform = id.platform;\n\t\tvar aiModel = id.model || undefined;\n\t\tvar systemPrompt = this.host.buildSystemPrompt();\n\t\tvar userId = id.userId || id.serviceId;\n\t\tvar chatQueue = useBgQueue ? userId + BG_INDEXING_QUEUE_SUFFIX : userId;\n\n\t\tif (isQueuedSend) {\n\t\t\tvar resolvedHistory = this.state.messages.filter(function (m) {\n\t\t\t\treturn !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder &&\n\t\t\t\t\t!m.isCancelled && !m.isBackgroundTask;\n\t\t\t});\n\t\t\tvar boundedQ = buildBoundedChatMessages({\n\t\t\t\tplatform: aiPlatform, model: aiModel, systemPrompt: systemPrompt, serviceId: id.serviceId,\n\t\t\t\thistory: resolvedHistory.concat([{ role: 'user', content: llmComposed }]),\n\t\t\t});\n\t\t\tvar queuedBubble: ChatMessage = { role: 'user', content: composed, isPendingQueued: true, isSendingToServer: true };\n\t\t\tif (useBgQueue) queuedBubble._useBgQueue = true;\n\t\t\tthis.state.messages.push(queuedBubble);\n\t\t\tthis.host.notify(); this.updateHistoryCache(); this.host.scrollToBottom(true);\n\n\t\t\tvar capturedComposed = composed, capturedPlatform = aiPlatform;\n\t\t\tPromise.resolve(this._callProviderFor(aiPlatform, composed, boundedQ.messages, systemPrompt, aiModel, chatQueue, extractContent, fileUrls))\n\t\t\t\t.then(function (result: any) {\n\t\t\t\t\tvar sendingIdx = self.state.messages.findIndex(function (m) {\n\t\t\t\t\t\treturn m.isSendingToServer && (m.isPendingQueued || m.isPendingInProcess) && m.role === 'user';\n\t\t\t\t\t});\n\t\t\t\t\tvar serverId = result && typeof result.id === 'string' ? result.id : undefined;\n\t\t\t\t\tif (sendingIdx >= 0) {\n\t\t\t\t\t\tvar upd = Object.assign({}, self.state.messages[sendingIdx], { isSendingToServer: false });\n\t\t\t\t\t\tif (serverId) upd._serverItemId = serverId;\n\t\t\t\t\t\tself.state.messages[sendingIdx] = upd; self.host.notify();\n\t\t\t\t\t}\n\t\t\t\t\tif (result && result.poll && (result.status === 'pending' || result.status === 'running')) {\n\t\t\t\t\t\t// Track this queued item's poll so a remount/refetch dedups\n\t\t\t\t\t\t// against it instead of attaching a duplicate history poll.\n\t\t\t\t\t\tif (serverId) self.historyItemPolls.set(serverId, true);\n\t\t\t\t\t\treturn result.poll({ latency: POLL_INTERVAL })\n\t\t\t\t\t\t\t.then(function (res: any) { return self.onQueuedSendResponse(capturedComposed, res, capturedPlatform, serverId); })\n\t\t\t\t\t\t\t.catch(function (err: any) { return self.onQueuedSendError(capturedComposed, err, serverId); });\n\t\t\t\t\t}\n\t\t\t\t\treturn self.onQueuedSendResponse(capturedComposed, result, capturedPlatform, serverId);\n\t\t\t\t})\n\t\t\t\t.catch(function (err: any) { return self.onQueuedSendError(capturedComposed, err, undefined); });\n\t\t\treturn;\n\t\t}\n\n\t\t// immediate send — cache+resume model (mirrors agent.vue). The reply is\n\t\t// appended to aiChatHistoryCache by dispatchAgentRequest (so it survives a\n\t\t// view unmount), then rendered from the cache via typewriteLatestReply. A\n\t\t// later resumePendingRequest() re-renders it if the view remounted while the\n\t\t// request was still in flight.\n\t\tthis.state.messages.push({ role: 'user', content: composed });\n\t\tthis.state.messages.push({ role: 'assistant', content: '', isPending: true, isPendingInProcess: true });\n\t\tthis.host.notify(); this.updateHistoryCache(); this.state.sending = true; this.host.scrollToBottom(true);\n\n\t\tvar key = this.getHistoryCacheKey();\n\t\tvar historyForLlm = this.state.messages.filter(function (m) { return !m.isCancelled && !m.isBackgroundTask; });\n\t\tif (llmComposed !== composed) {\n\t\t\tfor (var li = historyForLlm.length - 1; li >= 0; li--) {\n\t\t\t\tif (historyForLlm[li].role === 'user' && historyForLlm[li].content === composed) {\n\t\t\t\t\thistoryForLlm[li] = Object.assign({}, historyForLlm[li], { content: llmComposed });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvar bounded = buildBoundedChatMessages({\n\t\t\tplatform: aiPlatform, model: aiModel, systemPrompt: systemPrompt, serviceId: id.serviceId,\n\t\t\thistory: historyForLlm,\n\t\t});\n\t\tvar run = this.dispatchAgentRequest({\n\t\t\tkey: key, serviceId: id.serviceId, owner: id.owner, aiPlatform: aiPlatform, aiModel: aiModel,\n\t\t\tsystemPrompt: systemPrompt, text: composed, boundedMessages: bounded.messages, userId: chatQueue,\n\t\t\textractContent: extractContent, fileUrls: fileUrls,\n\t\t});\n\t\t// Render the reply into the \"Thinking...\" bubble whenever the chatbox is\n\t\t// CURRENTLY showing this chat — even after an unmount/remount. The old\n\t\t// guard bailed on `requestToken !== gateRefreshToken`, but EVERY remount\n\t\t// bumps gateRefreshToken (refreshGate), so a request that finished after\n\t\t// the user navigated away and back left a stuck \"Thinking...\" (no view\n\t\t// typewriter ever ran, and resumePendingRequest bails when a pending\n\t\t// bubble is already present). Gate on \"is this the visible chat\" instead.\n\t\t// When it ISN'T (unmounted / another project), dispatchAgentRequest has\n\t\t// already replaced the pending bubble with the answer IN THE CACHE, so a\n\t\t// later loadChatHistory renders it.\n\t\tPromise.resolve(run).catch(function () { }).then(function () {\n\t\t\tif (!(self.host.isViewMounted() && self.getHistoryCacheKey() === key)) return;\n\t\t\tself.state.sending = false;\n\t\t\treturn Promise.resolve(self.typewriteLatestReply(key)).then(function () { self.host.scrollToBottom(true); });\n\t\t});\n\t}\n\n\tpromoteNextBgQueuedToRunning(): void {\n\t\tif (this.state.messages.some(function (m) { return m.isPending && m.role === 'assistant' && m.isBackgroundTask; })) return;\n\t\tvar nextIdx = this.state.messages.findIndex(function (m) {\n\t\t\treturn m.isPendingQueued && m.role === 'user' && m.isBackgroundTask;\n\t\t});\n\t\tif (nextIdx === -1) return;\n\t\tvar existing = this.state.messages[nextIdx];\n\t\tvar promoted: ChatMessage = { role: 'user', content: existing.content, isPendingInProcess: true, isBackgroundTask: true };\n\t\tif (existing._serverItemId !== undefined) promoted._serverItemId = existing._serverItemId;\n\t\tthis.state.messages[nextIdx] = promoted;\n\t\tvar placeholder: ChatMessage = { role: 'assistant', content: '', isPending: true, isPendingInProcess: true, isBackgroundTask: true };\n\t\tif (existing._serverItemId !== undefined) placeholder._serverItemId = existing._serverItemId;\n\t\tthis.state.messages.splice(nextIdx + 1, 0, placeholder);\n\t\tthis.host.notify();\n\t}\n\n\tpromoteNextQueuedToRunning(): void {\n\t\tif (this.state.messages.some(function (m) { return m.isPending && m.role === 'assistant' && !m.isBackgroundTask; })) return;\n\t\tvar nextIdx = this.state.messages.findIndex(function (m) {\n\t\t\treturn m.isPendingQueued && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue;\n\t\t});\n\t\tif (nextIdx === -1) return;\n\t\tvar existing = this.state.messages[nextIdx];\n\t\tvar promoted: ChatMessage = { role: 'user', content: existing.content, isPendingInProcess: true };\n\t\tif (existing.isBackgroundTask) promoted.isBackgroundTask = true;\n\t\tif (existing._serverItemId !== undefined) promoted._serverItemId = existing._serverItemId;\n\t\tif (existing.isSendingToServer) promoted.isSendingToServer = true;\n\t\tthis.state.messages[nextIdx] = promoted;\n\t\t// Carry the promoted turn's _serverItemId onto the \"Thinking...\" placeholder\n\t\t// (mirrors promoteNextBgQueuedToRunning). Without it, when this promoted turn\n\t\t// is resolved via the history-poll path — applyHistoryItemResolution, which\n\t\t// matches the pending assistant by _serverItemId — the placeholder is not\n\t\t// found, so the reply is spliced in BESIDE it and the \"Thinking...\" is\n\t\t// stranded forever (e.g. after a reload, or when a cancel advances the queue).\n\t\t// onQueuedSendResponse still finds it by position, so the queued-send path is\n\t\t// unaffected.\n\t\tvar placeholder: ChatMessage = { role: 'assistant', content: '', isPending: true };\n\t\tif (existing._serverItemId !== undefined) placeholder._serverItemId = existing._serverItemId;\n\t\tthis.state.messages.splice(nextIdx + 1, 0, placeholder);\n\t\tthis.host.notify();\n\t}\n\n\tresolveQueuedUserBubble(serverId?: string): number | undefined {\n\t\tvar userIdx = -1;\n\t\tif (serverId) {\n\t\t\tuserIdx = this.state.messages.findIndex(function (m) {\n\t\t\t\treturn m._serverItemId === serverId && (m.isPendingInProcess || m.isPendingQueued) &&\n\t\t\t\t\tm.role === 'user' && !m.isBackgroundTask;\n\t\t\t});\n\t\t}\n\t\tif (userIdx === -1) {\n\t\t\tuserIdx = this.state.messages.findIndex(function (m) {\n\t\t\t\treturn m.isPendingInProcess && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue;\n\t\t\t});\n\t\t}\n\t\tif (userIdx === -1) {\n\t\t\tuserIdx = this.state.messages.findIndex(function (m) {\n\t\t\t\treturn m.isPendingQueued && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue;\n\t\t\t});\n\t\t}\n\t\tif (serverId && this.cancelledServerIds.has(serverId)) {\n\t\t\tthis.cancelledServerIds.delete(serverId);\n\t\t\tif (userIdx >= 0) {\n\t\t\t\tvar ex = this.state.messages[userIdx];\n\t\t\t\tthis.state.messages[userIdx] = { role: 'user', content: ex.content, isCancelled: true, _serverItemId: ex._serverItemId };\n\t\t\t\tvar thIdx = this.state.messages.findIndex(function (m, i) {\n\t\t\t\t\treturn i > userIdx && m.isPending && m.role === 'assistant' && !m.isBackgroundTask;\n\t\t\t\t});\n\t\t\t\tif (thIdx !== -1) this.state.messages.splice(thIdx, 1);\n\t\t\t}\n\t\t\tthis.promoteNextQueuedToRunning();\n\t\t\treturn undefined;\n\t\t}\n\t\tif (userIdx >= 0) {\n\t\t\tvar exist = this.state.messages[userIdx];\n\t\t\tvar repl: ChatMessage = { role: 'user', content: exist.content };\n\t\t\tif (exist._serverItemId !== undefined) repl._serverItemId = exist._serverItemId;\n\t\t\tthis.state.messages[userIdx] = repl;\n\t\t}\n\t\tvar thinkingIdx = userIdx >= 0\n\t\t\t? this.state.messages.findIndex(function (m, i) { return i > userIdx && m.isPending && m.role === 'assistant' && !m.isBackgroundTask; })\n\t\t\t: -1;\n\t\treturn thinkingIdx !== -1 ? thinkingIdx : (userIdx >= 0 ? userIdx + 1 : -1);\n\t}\n\n\tinsertAtTarget(msg: ChatMessage, targetIdx: number): void {\n\t\tif (targetIdx >= 0 && this.state.messages[targetIdx] && this.state.messages[targetIdx].isPending) this.state.messages[targetIdx] = msg;\n\t\telse if (targetIdx >= 0) this.state.messages.splice(targetIdx, 0, msg);\n\t\telse this.state.messages.push(msg);\n\t}\n\n\tonQueuedSendResponse(_composed: string, response: any, platform: string, serverId?: string): void {\n\t\tif (serverId) this.historyItemPolls.delete(serverId);\n\t\tvar targetIdx = this.resolveQueuedUserBubble(serverId);\n\t\tif (targetIdx === undefined) { this.host.notify(); this.updateHistoryCache(); return; }\n\t\tif (isErrorResponseBody(response)) {\n\t\t\tthis.insertAtTarget({ role: 'assistant', content: getErrorMessage(response), isError: true }, targetIdx);\n\t\t} else {\n\t\t\tvar answer = (platform === 'openai' ? extractOpenAIText(response) : extractClaudeText(response));\n\t\t\tanswer = (answer || '').trim() || 'No text response received from AI provider.';\n\t\t\tvar lid = this._newLocalId();\n\t\t\tif (targetIdx >= 0 && this.state.messages[targetIdx] && this.state.messages[targetIdx].isPending) {\n\t\t\t\tthis.state.messages[targetIdx] = { role: 'assistant', content: '', _localId: lid };\n\t\t\t\tthis.host.notify(); this.enqueueTypewrite(targetIdx, answer, lid);\n\t\t\t} else if (targetIdx >= 0) {\n\t\t\t\tthis.state.messages.splice(targetIdx, 0, { role: 'assistant', content: '', _localId: lid });\n\t\t\t\tthis.host.notify(); this.enqueueTypewrite(targetIdx, answer, lid);\n\t\t\t} else {\n\t\t\t\tvar aiIdx = this.state.messages.length;\n\t\t\t\tthis.state.messages.push({ role: 'assistant', content: '', _localId: lid });\n\t\t\t\tthis.host.notify(); this.enqueueTypewrite(aiIdx, answer, lid);\n\t\t\t}\n\t\t}\n\t\tthis._removeStrayPendingAssistants();\n\t\tthis.promoteNextQueuedToRunning();\n\t\tthis.updateHistoryCache();\n\t\tthis.host.notify();\n\t\tthis.host.scrollToBottom(true);\n\t}\n\n\tonQueuedSendError(_composed: string, err: any, serverId?: string): void {\n\t\tvar self = this;\n\t\tif (serverId) this.historyItemPolls.delete(serverId);\n\t\tvar isNotExists = err && (err.code === 'NOT_EXISTS' || (err.body && err.body.code === 'NOT_EXISTS'));\n\t\tif (isNotExists) {\n\t\t\tvar userIdx = serverId\n\t\t\t\t? this.state.messages.findIndex(function (m) { return m._serverItemId === serverId && (m.isPendingInProcess || m.isPendingQueued) && m.role === 'user' && !m.isBackgroundTask; })\n\t\t\t\t: this.state.messages.findIndex(function (m) { return m.isPendingInProcess && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue; });\n\t\t\tif (!serverId && userIdx === -1) {\n\t\t\t\tuserIdx = this.state.messages.findIndex(function (m) { return m.isPendingQueued && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue; });\n\t\t\t}\n\t\t\tif (userIdx >= 0) {\n\t\t\t\tvar ex = this.state.messages[userIdx];\n\t\t\t\tvar repl: ChatMessage = { role: 'user', content: ex.content, isCancelled: true };\n\t\t\t\tif (ex._serverItemId !== undefined) repl._serverItemId = ex._serverItemId;\n\t\t\t\tthis.state.messages[userIdx] = repl;\n\t\t\t}\n\t\t\tif (serverId) {\n\t\t\t\tvar thById = this.state.messages.findIndex(function (m) { return m._serverItemId === serverId && m.isPending && m.role === 'assistant' && !m.isBackgroundTask; });\n\t\t\t\tif (thById !== -1) this.state.messages.splice(thById, 1);\n\t\t\t\telse if (userIdx >= 0) {\n\t\t\t\t\tvar thPos = this.state.messages.findIndex(function (m, i) { return i > userIdx && m.isPending && m.role === 'assistant' && !m.isBackgroundTask; });\n\t\t\t\t\tif (thPos !== -1) this.state.messages.splice(thPos, 1);\n\t\t\t\t}\n\t\t\t} else if (userIdx >= 0) {\n\t\t\t\tvar thPos2 = this.state.messages.findIndex(function (m, i) { return i > userIdx && m.isPending && m.role === 'assistant' && !m.isBackgroundTask; });\n\t\t\t\tif (thPos2 !== -1) this.state.messages.splice(thPos2, 1);\n\t\t\t}\n\t\t\tif (serverId) this.cancelledServerIds.delete(serverId);\n\t\t\tthis._removeStrayPendingAssistants();\n\t\t\tthis.promoteNextQueuedToRunning(); this.updateHistoryCache(); this.host.notify(); this.host.scrollToBottom(true);\n\t\t\treturn;\n\t\t}\n\t\tvar targetIdx = this.resolveQueuedUserBubble(serverId);\n\t\tif (targetIdx === undefined) { this.host.notify(); this.updateHistoryCache(); return; }\n\t\tthis.insertAtTarget({ role: 'assistant', content: getErrorMessage(err), isError: true }, targetIdx);\n\t\tthis._removeStrayPendingAssistants();\n\t\tthis.promoteNextQueuedToRunning(); this.updateHistoryCache(); this.host.notify(); this.host.scrollToBottom(true);\n\t}\n\n\tcancelQueuedMessage(msg: ChatMessage, idx: number): void {\n\t\tvar self = this;\n\t\tvar id = this.host.getIdentity();\n\t\tvar serverId = msg._serverItemId;\n\t\tif (!serverId || msg._cancelling) return;\n\t\tvar platform = id.platform;\n\t\tif (platform !== 'claude' && platform !== 'openai') return;\n\t\tvar url = platform === 'claude' ? ANTHROPIC_MESSAGES_API_URL : OPENAI_RESPONSES_API_URL;\n\t\tvar queueBase = id.userId || id.serviceId;\n\t\tvar queue = (msg.isBackgroundTask || msg._useBgQueue) ? queueBase + BG_INDEXING_QUEUE_SUFFIX : queueBase;\n\t\tthis.state.messages[idx] = Object.assign({}, msg, { _cancelling: true, _cancelError: undefined });\n\t\tthis.host.notify();\n\t\tPromise.resolve(this.host.cancelRequest({\n\t\t\turl: url, method: 'POST', id: serverId, queue: queue, service: id.serviceId, owner: id.owner,\n\t\t})).then(function (result: any) {\n\t\t\tif (result && result.removed) {\n\t\t\t\tself.cancelledServerIds.add(serverId as string);\n\t\t\t\tvar qi = self.bgTaskQueue.findIndex(function (e) { return e.id === serverId; });\n\t\t\t\tif (qi !== -1) self.bgTaskQueue.splice(qi, 1);\n\t\t\t\tvar removeIdx = self.state.messages.findIndex(function (m) {\n\t\t\t\t\treturn m._serverItemId === serverId && (m.isPendingQueued || m.isPendingInProcess) && m.role === 'user';\n\t\t\t\t});\n\t\t\t\tif (removeIdx !== -1) {\n\t\t\t\t\tself.state.messages[removeIdx] = { role: 'user', content: self.state.messages[removeIdx].content, isCancelled: true, _serverItemId: serverId };\n\t\t\t\t\tvar thById = self.state.messages.findIndex(function (m) { return m._serverItemId === serverId && m.isPending && m.role === 'assistant'; });\n\t\t\t\t\tif (thById !== -1) self.state.messages.splice(thById, 1);\n\t\t\t\t\telse {\n\t\t\t\t\t\tvar thPos = self.state.messages.findIndex(function (m, i) {\n\t\t\t\t\t\t\treturn i > removeIdx && m.isPending && m.role === 'assistant' &&\n\t\t\t\t\t\t\t\t(msg.isBackgroundTask ? !!m.isBackgroundTask : !m.isBackgroundTask);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (thPos !== -1) self.state.messages.splice(thPos, 1);\n\t\t\t\t\t}\n\t\t\t\t\tif (msg.isBackgroundTask) self.promoteNextBgQueuedToRunning(); else self.promoteNextQueuedToRunning();\n\t\t\t\t\tself.updateHistoryCache();\n\t\t\t\t}\n\t\t\t\tself.host.notify();\n\t\t\t} else {\n\t\t\t\tvar errMsg = result && typeof result.message === 'string' && result.message ? result.message : 'Could not remove from queue.';\n\t\t\t\tvar ci = self.state.messages.findIndex(function (m) { return m._serverItemId === serverId && m.role === 'user'; });\n\t\t\t\tif (ci !== -1) { self.state.messages[ci] = Object.assign({}, self.state.messages[ci], { _cancelling: false, _cancelError: errMsg }); self.host.notify(); }\n\t\t\t}\n\t\t}).catch(function (err: any) {\n\t\t\tvar errMsg = err && typeof err.message === 'string' && err.message ? err.message : 'Could not remove from queue.';\n\t\t\tvar ci = self.state.messages.findIndex(function (m) { return m._serverItemId === serverId && m.role === 'user'; });\n\t\t\tif (ci !== -1) { self.state.messages[ci] = Object.assign({}, self.state.messages[ci], { _cancelling: false, _cancelError: errMsg }); self.host.notify(); }\n\t\t});\n\t}\n\n\t// --- typewriter -------------------------------------------------------\n\t// Reveal `fullText` into a message bubble at a constant wall-clock RATE\n\t// (chars/second) driven by requestAnimationFrame, rather than a fixed number\n\t// of characters per fixed-delay tick. This is what keeps typing smooth and\n\t// cheap on slow machines:\n\t//\n\t// * Each frame reveals `elapsed_ms * CHARS_PER_SEC` characters, so the\n\t// visual speed is the same regardless of how long a frame actually took.\n\t// * As the bubble's markdown grows, each re-render gets more expensive, so\n\t// frames get longer — which makes each frame reveal MORE characters and\n\t// therefore do FEWER, larger renders. That converts the old O(n^2)\n\t// \"re-render the whole growing string once per 3 characters\" (which got\n\t// slower and slower and pegged the CPU) into roughly O(n): the number of\n\t// renders self-throttles to what the machine can actually paint.\n\t// * rAF paces us to the browser's paint cycle and pauses in background\n\t// tabs, so we never queue work faster than it can be drawn.\n\ttypewriteIntoIndex(idx: number, fullText: string, localId?: string): Promise<void> {\n\t\tvar self = this;\n\t\tif (!fullText) return Promise.resolve();\n\n\t\tvar CHARS_PER_SEC = 300; // reveal rate (was ~188 = 3 chars / 16ms) — a bit faster\n\t\tvar MIN_STEP = 1; // always make progress, even on a sub-ms frame\n\t\tvar MAX_FRAME_MS = 1000; // cap catch-up after a long stall / backgrounded tab\n\n\t\t// Atomic regions that must never be left half-revealed: file fences\n\t\t// (shown as a download chip / hidden as \"[generating …]\" while unclosed —\n\t\t// and potentially huge, so revealed in one jump) and inline links\n\t\t// (a partial link is broken markdown). If a frame's reveal boundary lands\n\t\t// inside one, snap it to the region end so the chip/link appears whole.\n\t\tvar regions: Array<{ start: number; end: number }> = [], m;\n\t\tvar fenceRegex = /```[^\\n`]+?\\.[^\\s.`]+\\n[\\s\\S]*?```/g;\n\t\twhile ((m = fenceRegex.exec(fullText)) !== null) regions.push({ start: m.index, end: m.index + m[0].length });\n\t\tvar linkRegex = createInlineLinkRegex();\n\t\twhile ((m = linkRegex.exec(fullText)) !== null) regions.push({ start: m.index, end: m.index + m[0].length });\n\t\tregions.sort(function (a, b) { return a.start - b.start; });\n\n\t\tthis.state.typing = true; this.state.typingAbort = false;\n\t\tvar i = 0;\n\t\tvar last = nowMs();\n\n\t\treturn new Promise<void>(function (resolve) {\n\t\t\tvar done = false;\n\t\t\tvar doc: any = _g.document;\n\t\t\tfunction isHidden(): boolean { return !!(doc && doc.hidden); }\n\t\t\tfunction cleanup(): void {\n\t\t\t\tif (doc && doc.removeEventListener) doc.removeEventListener('visibilitychange', onVisibility);\n\t\t\t}\n\t\t\tfunction finish(): void {\n\t\t\t\tif (done) return;\n\t\t\t\tdone = true;\n\t\t\t\tcleanup();\n\t\t\t\tif (!self.state.typingAbort) {\n\t\t\t\t\t// Re-find the bubble by localId and, if it's gone, bail WITHOUT\n\t\t\t\t\t// writing — never fall back to the numeric idx, which a concurrent\n\t\t\t\t\t// array mutation may have repurposed for an unrelated message\n\t\t\t\t\t// (mirrors frame()'s currentIdx===-1 bail below).\n\t\t\t\t\tvar fi = localId ? self.state.messages.findIndex(function (mm) { return mm._localId === localId; }) : idx;\n\t\t\t\t\tif (fi !== -1) {\n\t\t\t\t\t\tvar t = self.state.messages[fi];\n\t\t\t\t\t\tif (t) { t.content = fullText; self.host.refreshMessageBubble(fi); }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tself.state.typing = false;\n\t\t\t\tresolve();\n\t\t\t}\n\t\t\t// requestAnimationFrame is PAUSED in a backgrounded tab (setTimeout only\n\t\t\t// throttles), so an rAF-driven reveal would freeze there — leaving a blank\n\t\t\t// bubble and stalling the sequential enqueueTypewrite queue until refocus.\n\t\t\t// When the page is (or becomes) hidden, skip the animation and show the\n\t\t\t// full text immediately so the queue keeps draining.\n\t\t\tfunction onVisibility(): void { if (isHidden()) finish(); }\n\t\t\tif (doc && doc.addEventListener) doc.addEventListener('visibilitychange', onVisibility);\n\t\t\tfunction frame(t: number): void {\n\t\t\t\tif (done) return;\n\t\t\t\tif (self.state.typingAbort || i >= fullText.length || isHidden()) { finish(); return; }\n\n\t\t\t\tvar dt = t - last; last = t;\n\t\t\t\tif (!(dt > 0)) dt = 16; // first frame / clock glitch\n\t\t\t\tif (dt > MAX_FRAME_MS) dt = MAX_FRAME_MS;\n\t\t\t\tvar step = Math.round(dt * CHARS_PER_SEC / 1000);\n\t\t\t\tif (step < MIN_STEP) step = MIN_STEP;\n\t\t\t\tvar next = Math.min(fullText.length, i + step);\n\n\t\t\t\t// Extend past any atomic region the newly-revealed span (i, next]\n\t\t\t\t// cuts into. Iterate to convergence so back-to-back regions (e.g. a\n\t\t\t\t// link right after a fence) are all revealed whole in one frame.\n\t\t\t\tfor (var changed = true; changed;) {\n\t\t\t\t\tchanged = false;\n\t\t\t\t\tfor (var k = 0; k < regions.length; k++) {\n\t\t\t\t\t\tvar r = regions[k];\n\t\t\t\t\t\tif (next > r.start && i < r.end && r.end > next) { next = r.end; changed = true; }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (next > fullText.length) next = fullText.length;\n\t\t\t\ti = next;\n\n\t\t\t\tvar currentIdx = localId ? self.state.messages.findIndex(function (mm) { return mm._localId === localId; }) : idx;\n\t\t\t\tif (currentIdx === -1) { finish(); return; }\n\t\t\t\tvar target = self.state.messages[currentIdx];\n\t\t\t\tif (!target) { finish(); return; }\n\t\t\t\ttarget.content = fullText.slice(0, i);\n\t\t\t\tself.host.refreshMessageBubble(currentIdx);\n\t\t\t\tself.host.scrollToBottomIfSticky();\n\t\t\t\tnextFrame(frame);\n\t\t\t}\n\t\t\tif (isHidden()) { finish(); return; }\n\t\t\tnextFrame(frame);\n\t\t});\n\t}\n\n\tprivate typewriterQueue: Promise<any> = Promise.resolve();\n\tenqueueTypewrite(idx: number, fullText: string, localId?: string): Promise<any> {\n\t\tvar self = this;\n\t\tthis.typewriterQueue = this.typewriterQueue.then(function () { return self.typewriteIntoIndex(idx, fullText, localId); });\n\t\treturn this.typewriterQueue;\n\t}\n\n\t// --- cache+resume immediate-send rendering -----------------------------\n\t// Render the just-resolved reply (read from aiChatHistoryCache) into the\n\t// pending assistant bubble, character-by-character. Runs AFTER the reply is\n\t// already in the cache (dispatchAgentRequest appended it); errors are shown\n\t// instantly (no typing). Promotes the next queued message immediately so its\n\t// \"Thinking…\" bubble appears without waiting for this typewriter to finish.\n\ttypewriteLatestReply(key: string): Promise<any> {\n\t\tvar cached = this.aiChatHistoryCache[key];\n\t\tif (!cached || !cached.messages.length) return Promise.resolve();\n\t\tvar latest: ChatMessage | undefined;\n\t\tfor (var i = cached.messages.length - 1; i >= 0; i--) {\n\t\t\tvar m = cached.messages[i];\n\t\t\tif (m.role === 'assistant' && !m.isPending) { latest = m; break; }\n\t\t}\n\t\tif (!latest) return Promise.resolve();\n\t\tvar pendingIdx = this.state.messages.findIndex(function (mm) {\n\t\t\treturn mm.isPending && mm.role === 'assistant' && !mm.isBackgroundTask;\n\t\t});\n\t\tif (pendingIdx === -1) return Promise.resolve();\n\t\tif (latest.isError || !latest.content) {\n\t\t\tthis.state.messages[pendingIdx] = { role: 'assistant', content: latest.content || '', isError: !!latest.isError };\n\t\t\tthis._removeStrayPendingAssistants();\n\t\t\tthis.host.notify();\n\t\t\tthis.promoteNextQueuedToRunning();\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\tvar lid = this._newLocalId();\n\t\tthis.state.messages[pendingIdx] = { role: 'assistant', content: '', isPending: false, _localId: lid };\n\t\tthis._removeStrayPendingAssistants();\n\t\tthis.host.notify();\n\t\tthis.promoteNextQueuedToRunning();\n\t\treturn this.enqueueTypewrite(pendingIdx, latest.content, lid);\n\t}\n\n\t// Remove any leftover non-background pending (\"Thinking…\") assistant bubbles.\n\t// There is normally at most ONE such bubble at a time (promoteNext* refuses to\n\t// add a second), so any extra is a duplicate — it appears when a concurrent\n\t// history refetch re-maps the still-\"running\" turn into a pending placeholder\n\t// (with a real _serverItemId) while the local pending bubble (no _serverItemId)\n\t// is rescued and re-appended (see loadHistory rescue below). Each resolve path\n\t// only replaces the FIRST pending bubble, so without this a stray \"Thinking…\"\n\t// survives next to the reply/error. MUST run AFTER the resolved bubble has been\n\t// made non-pending and BEFORE promoteNext*() (so a freshly-promoted Thinking,\n\t// which is added only once no pending assistant remains, is preserved).\n\t_removeStrayPendingAssistants(): void {\n\t\tfor (var k = this.state.messages.length - 1; k >= 0; k--) {\n\t\t\tvar m = this.state.messages[k];\n\t\t\tif (m.isPending && m.role === 'assistant' && !m.isBackgroundTask) this.state.messages.splice(k, 1);\n\t\t}\n\t}\n\n\t// Drop the pending flags on the resolved turn's USER bubble (preserving its\n\t// content + background-task marker). Needed because a bg \"Indexing:\" turn's user\n\t// bubble carries isPendingInProcess; leaving it set keeps the bubble visually\n\t// stuck and keeps its bgTaskQueue entry alive forever.\n\t_clearPendingUserBubble(itemId: string): void {\n\t\tvar uIdx = this.state.messages.findIndex(function (m) {\n\t\t\treturn m.role === 'user' && m._serverItemId === itemId &&\n\t\t\t\t(m.isPendingInProcess || m.isPendingQueued || m.isSendingToServer);\n\t\t});\n\t\tif (uIdx === -1) return;\n\t\tvar u = this.state.messages[uIdx];\n\t\tvar cleaned: ChatMessage = { role: 'user', content: u.content, _serverItemId: itemId };\n\t\tif (u.isBackgroundTask) cleaned.isBackgroundTask = true;\n\t\tthis.state.messages[uIdx] = cleaned;\n\t}\n\n\t// If an immediate-send request for the current cache key is still in flight\n\t// (e.g. the view unmounted then remounted mid-request), show the sending\n\t// state, await it, then render the reply from the cache. Skipped when the\n\t// list already has its own pending/queued bubbles (those resolve via their\n\t// own polls). The displayed reply also lands via dispatchComposedMessage's\n\t// own finally if the view never unmounted — this is the remount recovery.\n\tresumePendingRequest(token: number): Promise<void> {\n\t\tvar self = this;\n\t\tvar key = this.getHistoryCacheKey();\n\t\tvar pending = key ? this.pendingAgentRequests[key] : undefined;\n\t\tif (!pending) return Promise.resolve();\n\t\tif (this.state.messages.some(function (m) { return (m.isPending || m.isPendingQueued) && !m.isBackgroundTask && !m._useBgQueue; })) return Promise.resolve();\n\t\tthis.state.sending = true;\n\t\tthis.host.scrollToBottom(true);\n\t\treturn Promise.resolve(pending).catch(function () { }).then(function () {\n\t\t\tif (token !== self.state.gateRefreshToken) return;\n\t\t\tself.state.sending = false;\n\t\t\treturn Promise.resolve(self.typewriteLatestReply(key)).then(function () { self.host.scrollToBottom(true); });\n\t\t});\n\t}\n\n\t// --- background-task resolution + drain -------------------------------\n\thandleHistoryItemResolution(itemId: string, response: any, platform: string): void {\n\t\tthis.applyHistoryItemResolution(itemId, response, platform);\n\t\tthis.promoteNextBgQueuedToRunning();\n\t}\n\n\tapplyHistoryItemResolution(itemId: string, response: any, platform: string): void {\n\t\tthis.historyItemPolls.delete(itemId);\n\t\tvar isErr = isErrorResponseBody(response);\n\t\tvar answer = isErr ? getErrorMessage(response)\n\t\t\t: ((platform === 'openai' ? extractOpenAIText(response) : extractClaudeText(response)) || '').trim();\n\t\tvar idx = this.state.messages.findIndex(function (m) { return m.isPending && m._serverItemId === itemId; });\n\t\tif (idx !== -1) {\n\t\t\t// A bg \"Indexing:\" turn pushes a user bubble (isPendingInProcess) ALONGSIDE\n\t\t\t// the assistant Thinking; replacing only the assistant leaves that user\n\t\t\t// bubble stuck pending — and drainBgTaskQueue then never clears its queue\n\t\t\t// entry (its stillPending check stays true). Un-pend it here too.\n\t\t\tthis._clearPendingUserBubble(itemId);\n\t\t\tif (isErr) {\n\t\t\t\tthis.state.messages[idx] = { role: 'assistant', content: answer, isError: true, _serverItemId: itemId };\n\t\t\t\tthis.host.notify(); this.updateHistoryCache(); return;\n\t\t\t}\n\t\t\tvar lid = this._newLocalId();\n\t\t\tthis.state.messages[idx] = { role: 'assistant', content: '', _localId: lid, _serverItemId: itemId };\n\t\t\tthis.host.notify(); this.enqueueTypewrite(idx, answer || 'No text response received from AI provider.', lid);\n\t\t\tthis.updateHistoryCache(); return;\n\t\t}\n\t\tvar userIdx = this.state.messages.findIndex(function (m) {\n\t\t\treturn m.role === 'user' && m._serverItemId === itemId && (m.isPendingQueued || m.isPendingInProcess);\n\t\t});\n\t\tif (userIdx === -1) return;\n\t\tvar ex = this.state.messages[userIdx];\n\t\tthis.state.messages[userIdx] = { role: 'user', content: ex.content, _serverItemId: itemId };\n\t\tif (isErr) {\n\t\t\tthis.state.messages.splice(userIdx + 1, 0, { role: 'assistant', content: answer, isError: true, _serverItemId: itemId });\n\t\t\tthis.host.notify(); this.updateHistoryCache(); return;\n\t\t}\n\t\tvar lid2 = this._newLocalId();\n\t\tthis.state.messages.splice(userIdx + 1, 0, { role: 'assistant', content: '', _localId: lid2, _serverItemId: itemId });\n\t\tthis.host.notify(); this.enqueueTypewrite(userIdx + 1, answer || 'No text response received from AI provider.', lid2);\n\t\tthis.updateHistoryCache();\n\t}\n\n\t// Inject \"Indexing: <file>\" bubbles for queued bg tasks + attach their polls.\n\tdrainBgTaskQueue(): void {\n\t\tvar self = this;\n\t\tvar id = this.host.getIdentity();\n\t\tvar svcId = id.serviceId, plat = id.platform;\n\t\tif (!svcId || plat === 'none' || !this.host.isViewMounted()) return;\n\t\t// Index messages by _serverItemId ONCE, so the per-entry presence/pending\n\t\t// checks below are O(1) instead of a full messages.some() scan each. With a\n\t\t// large bg queue (bulk uploads) the old nested scan was O(queue x messages)\n\t\t// per drain, and the drain runs once per uploaded file (O(n^3) overall).\n\t\tvar presentIds: { [id: string]: boolean } = {};\n\t\tvar pendingIds: { [id: string]: boolean } = {};\n\t\tthis.state.messages.forEach(function (m) {\n\t\t\tvar sid = m._serverItemId;\n\t\t\tif (sid == null) return;\n\t\t\tpresentIds[sid] = true;\n\t\t\tif (m.isPending || m.isPendingInProcess || m.isPendingQueued) pendingIds[sid] = true;\n\t\t});\n\t\tfor (var i = this.bgTaskQueue.length - 1; i >= 0; i--) {\n\t\t\tvar e = this.bgTaskQueue[i];\n\t\t\tif (e.serviceId !== svcId || e.platform !== plat) continue;\n\t\t\tif (presentIds[e.id] && !pendingIds[e.id]) this.bgTaskQueue.splice(i, 1);\n\t\t}\n\t\tthis.bgTaskQueue.forEach(function (entry) {\n\t\t\tif (entry.serviceId !== svcId || entry.platform !== plat) return;\n\t\t\tif (presentIds[entry.id]) return;\n\t\t\tvar isRunning = entry.status === 'running';\n\t\t\tvar userBubble: ChatMessage = { role: 'user', content: self.host.formatIndexingLabel(entry.filename, entry.mime, entry.size, entry.storagePath, entry.isReindex), isBackgroundTask: true, _serverItemId: entry.id };\n\t\t\tif (isRunning) userBubble.isPendingInProcess = true; else userBubble.isPendingQueued = true;\n\t\t\tself.state.messages.push(userBubble);\n\t\t\tif (isRunning) {\n\t\t\t\tself.state.messages.push({ role: 'assistant', content: '', isPending: true, isPendingInProcess: true, isBackgroundTask: true, _serverItemId: entry.id });\n\t\t\t}\n\t\t\tpresentIds[entry.id] = true; // keep the index consistent with the pushed bubbles\n\t\t\tself.host.notify(); self.updateHistoryCache(); self.host.scrollToBottom(false);\n\t\t\tif (!self.historyItemPolls.has(entry.id) && typeof entry.poll === 'function') {\n\t\t\t\tself.historyItemPolls.set(entry.id, true);\n\t\t\t\tvar capturedId = entry.id, capturedPlat = plat;\n\t\t\t\tentry.poll({ latency: POLL_INTERVAL }).then(function (response: any) {\n\t\t\t\t\tself.handleHistoryItemResolution(capturedId, response, capturedPlat);\n\t\t\t\t}).catch(function (err: any) {\n\t\t\t\t\tself.historyItemPolls.delete(capturedId);\n\t\t\t\t\tvar isNotExists = err && (err.code === 'NOT_EXISTS' || (err.body && err.body.code === 'NOT_EXISTS'));\n\t\t\t\t\tvar bi = self.state.messages.findIndex(function (m) { return m.isPending && m._serverItemId === capturedId; });\n\t\t\t\t\tif (bi !== -1) {\n\t\t\t\t\t\tif (isNotExists) self.state.messages.splice(bi, 1);\n\t\t\t\t\t\telse self.state.messages[bi] = { role: 'assistant', content: getErrorMessage(err), isError: true, isBackgroundTask: true, _serverItemId: capturedId };\n\t\t\t\t\t\tself.host.notify(); self.updateHistoryCache();\n\t\t\t\t\t}\n\t\t\t\t}).then(function () {\n\t\t\t\t\tvar qi = self.bgTaskQueue.findIndex(function (q) { return q.id === capturedId; });\n\t\t\t\t\tif (qi !== -1) self.bgTaskQueue.splice(qi, 1);\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\tthis.promoteNextBgQueuedToRunning();\n\t}\n\n\t// --- history fetch + pagination --------------------------------------\n\t// Initial load (fetchMore=false) replaces the list (with in-flight rescue +\n\t// cancelled-merge) and attaches polls to running/pending items; pagination\n\t// (fetchMore=true) prepends older messages. The DOM scroll-restore for the\n\t// older-prepend is the VIEW's job (it captures the pre-prepend scroll position\n\t// and restores after this resolves) — the engine never measures the DOM.\n\tloadHistory(fetchMore?: boolean, token?: number): Promise<void> {\n\t\tvar self = this;\n\t\tvar id = this.host.getIdentity();\n\t\tif (token === undefined) token = this.state.gateRefreshToken;\n\t\tif ((this.state.loadingHistory && this.state.historyRequestToken === token) || id.platform === 'none' || !id.serviceId) {\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\tthis.state.historyRequestToken = token;\n\t\tthis.state.loadingHistory = true;\n\t\tif (fetchMore) this.state.loadingOlderHistory = true;\n\t\tthis.host.notify(); // surface \"Fetching history...\" while it loads\n\t\tvar platform = id.platform as 'claude' | 'openai';\n\t\tvar serviceId = id.serviceId, owner = id.owner;\n\t\tvar options: any = { fetchMore: fetchMore };\n\t\tif (fetchMore && this.state.historyStartKeyHistory.length) options.startKeyHistory = this.state.historyStartKeyHistory.slice();\n\n\t\tvar fetchHistory = function () { return getChatHistory({ service: serviceId, owner: owner, platform: platform }, options); };\n\n\t\treturn Promise.resolve().then(fetchHistory).catch(function (err: any) {\n\t\t\tif (isAuthExpiredError(err) && !isNonRetryableRequestError(err)) return self.host.refreshSession().then(fetchHistory);\n\t\t\tthrow err;\n\t\t}).then(function (history: any) {\n\t\t\tif (token !== self.state.gateRefreshToken) return;\n\t\t\tvar chatList = history && Array.isArray(history.list) ? history.list : [];\n\t\t\tchatList.forEach(function (item: any) {\n\t\t\t\tif (typeof item.queue_name === 'string' && item.queue_name.slice(-BG_INDEXING_QUEUE_SUFFIX.length) === BG_INDEXING_QUEUE_SUFFIX) {\n\t\t\t\t\tvar userText = extractLastUserTextFromRequest(item.request_body);\n\t\t\t\t\tif (typeof userText === 'string' && userText.indexOf('A new file has just been uploaded') === 0) item._isBgTask = true;\n\t\t\t\t\telse item._isOnBgQueue = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar list = chatList.sort(function (a: any, b: any) {\n\t\t\t\tvar ai = typeof a.id === 'string' ? a.id : '', bi = typeof b.id === 'string' ? b.id : '';\n\t\t\t\treturn ai > bi ? -1 : (ai < bi ? 1 : 0);\n\t\t\t});\n\t\t\tvar mapped = mapHistoryListToMessages(list, platform, {\n\t\t\t\tclearedAt: self.host.getClearedAt(),\n\t\t\t\tserviceId: id.serviceId,\n\t\t\t\tformatIndexingLabel: self.host.formatIndexingLabel,\n\t\t\t}).messages;\n\n\t\t\tif (fetchMore) {\n\t\t\t\tself.state.messages = mapped.concat(self.state.messages);\n\t\t\t} else {\n\t\t\t\tif (self.state.typing) self.state.typingAbort = true;\n\t\t\t\tvar serverIds: any = {};\n\t\t\t\tmapped.forEach(function (m: any) { if (m._serverItemId) serverIds[m._serverItemId] = 1; });\n\t\t\t\tvar locallyCancelled: any = {};\n\t\t\t\tself.state.messages.forEach(function (m) { if (m.isCancelled && m._serverItemId) locallyCancelled[m._serverItemId] = 1; });\n\t\t\t\t// If the freshly-mapped server list ALREADY shows this in-flight turn\n\t\t\t\t// as a pending placeholder (a non-bg pending assistant, which carries\n\t\t\t\t// a real _serverItemId), re-pushing the local no-_serverItemId\n\t\t\t\t// user+Thinking would DUPLICATE it. Each resolve path only clears the\n\t\t\t\t// first pending bubble, so the duplicate strands a \"Thinking…\" beside\n\t\t\t\t// the reply/error. There is at most one in-flight regular turn, so a\n\t\t\t\t// mapped pending assistant IS this turn — skip the redundant local copy.\n\t\t\t\tvar mappedHasPendingAssistant = mapped.some(function (m: any) {\n\t\t\t\t\treturn m.isPending && m.role === 'assistant' && !m.isBackgroundTask;\n\t\t\t\t});\n\t\t\t\tvar rescued: ChatMessage[] = [];\n\t\t\t\tfor (var ri = 0; ri < self.state.messages.length; ri++) {\n\t\t\t\t\tvar mm = self.state.messages[ri];\n\t\t\t\t\tif (mm.isBackgroundTask) continue;\n\t\t\t\t\tif (mm._serverItemId && serverIds[mm._serverItemId]) continue;\n\t\t\t\t\tif (!mm._serverItemId) {\n\t\t\t\t\t\tif (mappedHasPendingAssistant) continue;\n\t\t\t\t\t\tif (mm.isSendingToServer || mm.isPendingQueued || mm.isPendingInProcess || mm.isPending) rescued.push(mm);\n\t\t\t\t\t\telse if (self.state.sending && mm.role === 'user') {\n\t\t\t\t\t\t\tvar next = self.state.messages[ri + 1];\n\t\t\t\t\t\t\tif (next && !next.isBackgroundTask && next.isPending && !next._serverItemId) rescued.push(mm);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tself.state.messages = mapped;\n\t\t\t\trescued.forEach(function (m) { self.state.messages.push(m); });\n\t\t\t\tif (Object.keys(locallyCancelled).length) {\n\t\t\t\t\tfor (var ci = 0; ci < self.state.messages.length; ci++) {\n\t\t\t\t\t\tvar c = self.state.messages[ci];\n\t\t\t\t\t\tif (!c._serverItemId || !locallyCancelled[c._serverItemId] || c.isCancelled) continue;\n\t\t\t\t\t\tself.state.messages[ci] = { role: 'user', content: c.content, isCancelled: true, _serverItemId: c._serverItemId };\n\t\t\t\t\t\tif (ci + 1 < self.state.messages.length && self.state.messages[ci + 1].isPending && self.state.messages[ci + 1]._serverItemId === c._serverItemId) {\n\t\t\t\t\t\t\tself.state.messages.splice(ci + 1, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tself.state.historyEndOfList = !!(history && history.endOfList);\n\t\t\tself.state.historyStartKeyHistory = history && Array.isArray(history.startKeyHistory) ? history.startKeyHistory : [];\n\t\t\tvar clearedAt = self.host.getClearedAt();\n\t\t\tif (clearedAt && chatList.length > 0) {\n\t\t\t\tvar oldestUpdated = Number(chatList[chatList.length - 1] && chatList[chatList.length - 1].updated);\n\t\t\t\tif (isFinite(oldestUpdated) && oldestUpdated <= clearedAt) self.state.historyEndOfList = true;\n\t\t\t}\n\t\t\t// Clear loading flags BEFORE this render so the final paint is\n\t\t\t// indicator-free (and the view's scroll-restore math sees matching heights).\n\t\t\tif (self.state.historyRequestToken === token) { self.state.loadingHistory = false; self.state.loadingOlderHistory = false; }\n\t\t\tself.updateHistoryCache();\n\t\t\tself.host.notify();\n\n\t\t\tif (!fetchMore) {\n\t\t\t\tchatList.forEach(function (item: any) {\n\t\t\t\t\tif (item.status !== 'running' && item.status !== 'pending') return;\n\t\t\t\t\tif (!item.poll || !item.id) return;\n\t\t\t\t\t// Every live poll registers its item id in historyItemPolls — an\n\t\t\t\t\t// immediate dispatch (dispatchAgentRequest ~123), a queued send\n\t\t\t\t\t// (~253), a bg task (drain), or an earlier history poll — so the\n\t\t\t\t\t// has() check below already skips exactly the items a live poll\n\t\t\t\t\t// covers (including the one the current dispatch is polling). Do NOT\n\t\t\t\t\t// additionally skip every OTHER running/pending item just because\n\t\t\t\t\t// some immediate dispatch is in flight: that dispatch polls only ITS\n\t\t\t\t\t// item, so blanket-skipping stranded a concurrent \"-bg\" indexing item\n\t\t\t\t\t// (a separate server queue runs in parallel) — or any item whose own\n\t\t\t\t\t// poll had since died — with no live poller, leaving a \"Thinking...\"\n\t\t\t\t\t// that never clears even after the server settled everything.\n\t\t\t\t\tif (self.historyItemPolls.has(item.id)) return;\n\t\t\t\t\t// An in-flight immediate dispatch polls its own MAIN-QUEUE item but\n\t\t\t\t\t// registers that id in historyItemPolls only AFTER its provider POST\n\t\t\t\t\t// returns; in the sliver before that, a remount can surface the item\n\t\t\t\t\t// here still unregistered. Skip re-polling MAIN-QUEUE items while a\n\t\t\t\t\t// dispatch is in flight so we don't stack a 2nd poll on the item the\n\t\t\t\t\t// dispatch is about to poll. Bg-queue items (_isBgTask indexing tasks\n\t\t\t\t\t// and _isOnBgQueue chats) run on a SEPARATE queue the immediate\n\t\t\t\t\t// dispatch never polls, so they MUST still get their poll — skipping\n\t\t\t\t\t// them was the stranded-\"Thinking\" bug this guard must not revive.\n\t\t\t\t\tif (self.pendingAgentRequests[self.getHistoryCacheKey()] && !item._isBgTask && !item._isOnBgQueue) return;\n\t\t\t\t\tself.historyItemPolls.set(item.id, true);\n\t\t\t\t\tvar capturedId = item.id;\n\t\t\t\t\tvar pp = item.poll({\n\t\t\t\t\t\tlatency: POLL_INTERVAL,\n\t\t\t\t\t\tonResponse: function (response: any) { self.handleHistoryItemResolution(capturedId, response, platform); },\n\t\t\t\t\t\tonError: function (err: any) {\n\t\t\t\t\t\t\tself.historyItemPolls.delete(capturedId);\n\t\t\t\t\t\t\tvar isNotExists = err && (err.code === 'NOT_EXISTS' || (err.body && err.body.code === 'NOT_EXISTS'));\n\t\t\t\t\t\t\tvar aIdx = self.state.messages.findIndex(function (m) { return m.isPending && m._serverItemId === capturedId; });\n\t\t\t\t\t\t\tif (isNotExists) {\n\t\t\t\t\t\t\t\tvar isBg = aIdx !== -1 ? !!self.state.messages[aIdx].isBackgroundTask : false;\n\t\t\t\t\t\t\t\tif (aIdx !== -1) self.state.messages.splice(aIdx, 1);\n\t\t\t\t\t\t\t\tif (!isBg) {\n\t\t\t\t\t\t\t\t\tvar uIdx = self.state.messages.findIndex(function (m) { return m.role === 'user' && m._serverItemId === capturedId && !m.isCancelled; });\n\t\t\t\t\t\t\t\t\tif (uIdx !== -1) { var ex = self.state.messages[uIdx]; self.state.messages[uIdx] = { role: 'user', content: ex.content, isCancelled: true, _serverItemId: ex._serverItemId }; }\n\t\t\t\t\t\t\t\t\tself.cancelledServerIds.delete(capturedId); self.promoteNextQueuedToRunning();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tself.host.notify(); self.updateHistoryCache(); return;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (aIdx !== -1) {\n\t\t\t\t\t\t\t\tvar wasBg = self.state.messages[aIdx].isBackgroundTask;\n\t\t\t\t\t\t\t\tself.state.messages[aIdx] = { role: 'assistant', content: getErrorMessage(err), isError: true };\n\t\t\t\t\t\t\t\tif (wasBg) self.state.messages[aIdx].isBackgroundTask = true;\n\t\t\t\t\t\t\t\tself.host.notify(); self.updateHistoryCache();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tif (pp && pp.catch) pp.catch(function () { });\n\t\t\t\t});\n\t\t\t\tself.drainBgTaskQueue();\n\t\t\t}\n\n\t\t\tif (!fetchMore) return self.host.scrollToBottom();\n\t\t}).catch(function (err: any) {\n\t\t\tconsole.warn('[chat-engine] getChatHistory failed', err);\n\t\t}).then(function () {\n\t\t\tif (self.state.historyRequestToken === token) {\n\t\t\t\tvar wasLoading = self.state.loadingHistory || self.state.loadingOlderHistory;\n\t\t\t\tself.state.loadingHistory = false; self.state.loadingOlderHistory = false;\n\t\t\t\tif (wasLoading) self.host.notify();\n\t\t\t}\n\t\t});\n\t}\n\n\t// --- attachment upload orchestration ---------------------------------\n\t// Upload one attachment (a file = 1 member, a folder = N) to db storage and\n\t// queue indexing per member. The bytes I/O + chip rendering go through host\n\t// hooks; the overwrite/reindex flow, status lifecycle, and indexing live here.\n\tuploadSingleAttachment(att: any): Promise<Array<{ name: string; url: string; storagePath: string }>> {\n\t\tvar self = this;\n\t\tvar id = this.host.getIdentity();\n\t\tatt.status = 'uploading'; att.progress = 0; att.errorMessage = '';\n\t\tatt.errorCode = ''; att.errorDetail = ''; // clear any prior failure (retry)\n\t\tthis.host.renderAttachmentChips();\n\t\tvar members = (att.kind === 'folder')\n\t\t\t? (att.files || []).map(function (f: any) { return { file: f.file, relPath: f.path, storagePath: self.host.storagePathFor(f.path) }; })\n\t\t\t: [{ file: att.file, relPath: att.name, storagePath: this.host.storagePathFor(att.name) }];\n\t\tvar total = members.length;\n\t\tif (!total) return Promise.reject(new Error('Empty attachment'));\n\t\tvar urls: Array<{ name: string; url: string; storagePath: string }> = [];\n\t\tvar anyIndexFailed = false;\n\t\tvar chain: Promise<any> = Promise.resolve();\n\t\tmembers.forEach(function (member: any, idx: number) {\n\t\t\tchain = chain.then(function () {\n\t\t\t\tvar hadExists = false;\n\t\t\t\tvar skipped = false;\n\t\t\t\t// True when the file already existed and we are re-indexing over it\n\t\t\t\t// (user chose Reindex, OR Overwrite replaced the bytes). Drives the\n\t\t\t\t// delete-then-repost of the stale \"src::\" record below. Kept separate\n\t\t\t\t// from hadExists, which must keep driving ONLY the Reindexing/Indexing\n\t\t\t\t// label (isReindex) — overwrite still labels as \"Indexing:\".\n\t\t\t\tvar existedBefore = false;\n\t\t\t\tvar onProg = function (p: any) {\n\t\t\t\t\tif (p && p.total) {\n\t\t\t\t\t\tatt.progress = Math.floor(((idx + p.loaded / p.total) / total) * 100);\n\t\t\t\t\t\tself.host.renderAttachmentChips();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tvar doMemberUpload = function (checkExistence: boolean) {\n\t\t\t\t\treturn self.host.uploadFile({\n\t\t\t\t\t\tfile: member.file, storagePath: member.storagePath, checkExistence: checkExistence,\n\t\t\t\t\t\tonProgress: onProg, setAbort: function (abort) { att._abort = abort; },\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t\treturn doMemberUpload(true).catch(function (err: any) {\n\t\t\t\t\tvar code = err && (err.code || (err.body && err.body.code));\n\t\t\t\t\tvar msg = err && (err.message || (err.body && err.body.message) || (typeof err === 'string' ? err : ''));\n\t\t\t\t\tvar isExists = code === 'EXISTS' || (msg && /exist/i.test(msg));\n\t\t\t\t\tif (!isExists) throw err; // a member upload failed → whole attachment fails (red)\n\t\t\t\t\treturn self.host.promptOverwrite(member.file.name).then(function (choice) {\n\t\t\t\t\t\tif (choice === 'overwrite') { existedBefore = true; return doMemberUpload(false); } // replace the existing file\n\t\t\t\t\t\tif (choice === 'skip') { skipped = true; return; } // leave it untouched; no upload/index\n\t\t\t\t\t\thadExists = true; existedBefore = true; // keep it; Reindex\n\t\t\t\t\t});\n\t\t\t\t}).then(function () {\n\t\t\t\t\tif (skipped) return; // user skipped this member — no url, no index request\n\t\t\t\t\treturn self.host.getTemporaryUrl(member.storagePath);\n\t\t\t\t}).then(function (url: string) {\n\t\t\t\t\tif (skipped) return; // guard the indexing branch for a skipped member\n\t\t\t\t\turls.push({ name: member.relPath, url: url, storagePath: member.storagePath });\n\t\t\t\t\tif (att.kind !== 'folder') { att.uploadedUrl = url; att.storagePath = member.storagePath; }\n\t\t\t\t\tvar mime = member.file.type || self.host.getMimeType(member.file.name);\n\t\t\t\t\t// Delete-then-repost: when the file already existed (Reindex or\n\t\t\t\t\t// Overwrite), delete the stale \"src::<storagePath>\" index record\n\t\t\t\t\t// first — the skapi backend cascades the delete to its\n\t\t\t\t\t// reference-linked children — so re-indexing REPLACES rather than\n\t\t\t\t\t// colliding/duplicating. Awaited before the index request is\n\t\t\t\t\t// enqueued. Best-effort + optional-hook guarded: a missing record,\n\t\t\t\t\t// a permission error, or a host without the hook must not block\n\t\t\t\t\t// indexing.\n\t\t\t\t\tvar preIndex = (existedBefore && typeof self.host.deleteExistingFileRecord === 'function')\n\t\t\t\t\t\t? Promise.resolve(self.host.deleteExistingFileRecord(member.storagePath)).catch(function () { })\n\t\t\t\t\t\t: Promise.resolve();\n\t\t\t\t\t// Run a client-side attachment parser (e.g. .hwp) if one matches; its\n\t\t\t\t\t// output is inlined into the indexing request (falls back to office\n\t\t\t\t\t// extraction / web_fetch when no parser matches or it yields nothing).\n\t\t\t\t\treturn preIndex.then(function () {\n\t\t\t\t\t\treturn parseAttachmentContent(member.file, member.file.name, mime || undefined);\n\t\t\t\t\t}).then(function (parsedContent: string | null) {\n\t\t\t\t\treturn notifyAgentSaveAttachment({\n\t\t\t\t\t\tplatform: id.platform as 'claude' | 'openai',\n\t\t\t\t\t\tmodel: id.model,\n\t\t\t\t\t\tservice: id.serviceId,\n\t\t\t\t\t\towner: id.owner,\n\t\t\t\t\t\tuserId: id.userId || id.serviceId,\n\t\t\t\t\t\tserviceName: id.serviceName,\n\t\t\t\t\t\tserviceDescription: id.serviceDescription,\n\t\t\t\t\t\tattachment: {\n\t\t\t\t\t\t\tname: member.file.name, storagePath: member.storagePath,\n\t\t\t\t\t\t\tmime: mime || undefined, size: member.file.size, url: url,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tparsedContent: parsedContent || undefined,\n\t\t\t\t\t}).then(function (ack: any) {\n\t\t\t\t\t\tif (ack && typeof ack.id === 'string') {\n\t\t\t\t\t\t\tself.bgTaskQueue.push({\n\t\t\t\t\t\t\t\tserviceId: id.serviceId, platform: id.platform as 'claude' | 'openai', id: ack.id,\n\t\t\t\t\t\t\t\tfilename: member.file.name,\n\t\t\t\t\t\t\t\tstoragePath: member.storagePath,\n\t\t\t\t\t\t\t\tisReindex: hadExists,\n\t\t\t\t\t\t\t\tmime: mime || undefined,\n\t\t\t\t\t\t\t\tsize: member.file.size,\n\t\t\t\t\t\t\t\tstatus: ack.status === 'running' ? 'running' : 'pending',\n\t\t\t\t\t\t\t\tpoll: ack.poll,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tself.drainBgTaskQueue(); // surface \"Indexing: <file>\" as soon as THIS file uploads\n\t\t\t\t\t\t}\n\t\t\t\t\t}, function (e: any) {\n\t\t\t\t\t\tconsole.error('[chat-engine] indexing request failed', e);\n\t\t\t\t\t\tanyIndexFailed = true; // uploaded but not indexed → yellow\n\t\t\t\t\t\t// Record the first index error's code/message for the report dialog.\n\t\t\t\t\t\tif (!att.errorCode && !att.errorDetail) {\n\t\t\t\t\t\t\tatt.errorCode = (e && (e.code || (e.body && e.body.code))) || '';\n\t\t\t\t\t\t\tatt.errorDetail = (e && (e.message || (e.body && e.body.message))) || (typeof e === 'string' ? e : '');\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t\treturn chain.then(function () {\n\t\t\tatt._abort = null; att.progress = 100;\n\t\t\tif (att.kind === 'folder') att.uploadedUrls = urls.map(function (u) { return { path: u.name, url: u.url, storagePath: u.storagePath }; });\n\t\t\tatt.status = anyIndexFailed ? 'indexError' : 'done';\n\t\t\tif (att.status === 'indexError') att.errorMessage = 'File indexing failed';\n\t\t\tself.host.renderAttachmentChips();\n\t\t\treturn urls;\n\t\t});\n\t}\n\n\t// Upload all not-yet-done attachments sequentially. Resolves to the full\n\t// list of { name, url, storagePath } for composing the chat message.\n\tuploadPendingAttachments(): Promise<Array<{ name: string; url: string; storagePath?: string }>> {\n\t\tvar self = this;\n\t\tthis.host.resetOverwriteBatch();\n\t\tthis.state.uploadingAttachments = true;\n\t\tthis.host.updateComposerControls();\n\t\tthis.host.renderAttachmentChips();\n\t\tvar collected: Array<{ name: string; url: string; storagePath?: string }> = [];\n\t\tvar snapshot = this.state.attachments.slice();\n\t\tvar chain: Promise<any> = Promise.resolve();\n\t\tsnapshot.forEach(function (att: any) {\n\t\t\tchain = chain.then(function () {\n\t\t\t\tif (!self.state.attachments.some(function (a: any) { return a.id === att.id; })) return; // removed\n\t\t\t\tif (att.status === 'done' || att.status === 'indexError') {\n\t\t\t\t\tif (att.kind === 'folder' && att.uploadedUrls) {\n\t\t\t\t\t\tatt.uploadedUrls.forEach(function (u: any) { collected.push({ name: u.path, url: u.url, storagePath: u.storagePath }); });\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (att.uploadedUrl) { collected.push({ name: att.name, url: att.uploadedUrl, storagePath: att.storagePath }); return; }\n\t\t\t\t}\n\t\t\t\treturn self.uploadSingleAttachment(att).then(function (us) {\n\t\t\t\t\tcollected.push.apply(collected, us);\n\t\t\t\t}).catch(function (err: any) {\n\t\t\t\t\tvar removed = !self.state.attachments.some(function (a: any) { return a.id === att.id; });\n\t\t\t\t\tvar aborted = err && (err.message === 'Aborted' || err === 'Aborted');\n\t\t\t\t\tif (removed || aborted) return;\n\t\t\t\t\tatt.status = 'error';\n\t\t\t\t\tatt.errorMessage = 'File upload has failed';\n\t\t\t\t\t// Preserve the original error code/message for the report dialog.\n\t\t\t\t\tatt.errorCode = (err && (err.code || (err.body && err.body.code))) || '';\n\t\t\t\t\tatt.errorDetail = (err && (err.message || (err.body && err.body.message))) || (typeof err === 'string' ? err : '');\n\t\t\t\t\tself.host.renderAttachmentChips();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t\tvar done = function () {\n\t\t\tself.state.uploadingAttachments = false; self.host.updateComposerControls(); self.host.renderAttachmentChips();\n\t\t\treturn collected;\n\t\t};\n\t\treturn chain.then(done, done);\n\t}\n\n\t// Stop timers / abort the typewriter (view teardown).\n\tstop(): void {\n\t\tthis.state.typingAbort = true;\n\t}\n\n\t// Bump the gate token so any in-flight immediate-send result is dropped\n\t// (called by the view on a service/platform switch or history clear).\n\tbumpGate(): void {\n\t\tthis.state.gateRefreshToken += 1;\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/engine/attachment_parsers.ts","../src/engine/config.ts","../src/engine/office.ts","../src/engine/attachments.ts","../src/engine/prompts/chat_system_prompt.ts","../src/engine/prompts/indexing_system_prompt.ts","../src/engine/prompts/indexing_user_message.ts","../src/engine/errors.ts","../src/engine/links.ts","../src/engine/budget.ts","../src/engine/requests.ts","../src/engine/history.ts","../src/engine/session.ts"],"names":["i","resolvedModel"],"mappings":"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","file":"engine.mjs","sourcesContent":["/**\n * Client-side attachment-parser plugins.\n *\n * Some attachment formats can't be read by the model's web_fetch (binary) and\n * have no server-side extractor either — e.g. legacy Hancom .hwp. A parser\n * plugin runs IN THE BROWSER, turns the uploaded File into indexable text (or an\n * HTML string), and the engine sends that content INLINE in the background\n * indexing request — so the model indexes the parsed content directly, with no\n * upload-side server extraction and no web_fetch for that file.\n *\n * Register a parser with `registerAttachmentParser()`, or via\n * `configureChatEngine({ attachmentParsers: [...] })`. The BunnyQuery widget also\n * exposes `BunnyQuery.registerAttachmentParser()` and an `attachmentParsers`\n * init option. First matching parser wins.\n */\n\nexport interface AttachmentParser {\n\t/** Human-readable label — used only in logs. */\n\tname?: string;\n\t/**\n\t * Return true if this parser handles the file. Receives the file name and\n\t * (when known) its MIME type. Keep it cheap — it runs for every upload.\n\t */\n\tmatch: (file: { name: string; mime?: string }) => boolean;\n\t/**\n\t * Parse the File into indexable plain text OR an HTML string (the model reads\n\t * either). Runs in the browser; may be async. Return a falsy/empty value to\n\t * skip (the file then falls back to web_fetch / server extraction).\n\t */\n\tparse: (\n\t\tfile: File,\n\t) => string | null | undefined | Promise<string | null | undefined>;\n}\n\n// Hard ceiling on inlined parsed content (characters), mirroring the worker's\n// server-side MAX_EXTRACTED_CHARS, so a huge document can't blow the model's\n// context window or the request size.\nexport const MAX_PARSED_CONTENT_CHARS = 200_000;\n\nconst _parsers: AttachmentParser[] = [];\n\n/** Register an attachment parser. Ignores duplicates (by reference) and invalid plugins. */\nexport function registerAttachmentParser(parser: AttachmentParser): void {\n\tif (\n\t\tparser &&\n\t\ttypeof parser.match === 'function' &&\n\t\ttypeof parser.parse === 'function' &&\n\t\t_parsers.indexOf(parser) === -1\n\t) {\n\t\t_parsers.push(parser);\n\t}\n}\n\n/** Remove all registered parsers (mainly for tests / re-init). */\nexport function clearAttachmentParsers(): void {\n\t_parsers.length = 0;\n}\n\n/** Snapshot of the registered parsers. */\nexport function getAttachmentParsers(): AttachmentParser[] {\n\treturn _parsers.slice();\n}\n\n/** First parser whose `match` returns true for the given file, if any. */\nexport function findAttachmentParser(\n\tname: string,\n\tmime?: string,\n): AttachmentParser | undefined {\n\tfor (let i = 0; i < _parsers.length; i++) {\n\t\ttry {\n\t\t\tif (_parsers[i].match({ name: name, mime: mime })) return _parsers[i];\n\t\t} catch {\n\t\t\t/* a throwing matcher must not break uploads */\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Run the matching parser (if any) and return capped, trimmed content — or null\n * when there is no parser, the parser throws, or it yields nothing. Never throws:\n * a parser failure degrades to null so the upload still completes (the file then\n * resolves via its normal path).\n */\nexport async function parseAttachmentContent(\n\tfile: File,\n\tname: string,\n\tmime?: string,\n): Promise<string | null> {\n\tconst parser = findAttachmentParser(name, mime);\n\tif (!parser) return null;\n\n\tlet raw: string | null | undefined;\n\ttry {\n\t\traw = await parser.parse(file);\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[chat-engine] attachment parser ${parser.name || '(unnamed)'} failed for ${name}:`,\n\t\t\terr,\n\t\t);\n\t\treturn null;\n\t}\n\n\tlet text = (raw == null ? '' : String(raw)).trim();\n\tif (!text) return null;\n\tif (text.length > MAX_PARSED_CONTENT_CHARS) {\n\t\ttext =\n\t\t\ttext.slice(0, MAX_PARSED_CONTENT_CHARS) +\n\t\t\t`\\n...[truncated for length; original ${text.length} characters]`;\n\t}\n\treturn text;\n}\n","/**\n * Engine configuration / dependency injection.\n *\n * The engine is framework- and transport-agnostic: it never imports a skapi\n * instance or `import.meta.env`. Each consumer calls `configureChatEngine()`\n * once at startup to inject the skapi transport functions, the MCP base URL,\n * and (optionally) the `poll` value to attach to clientSecretRequest.\n *\n * Why `poll` is configurable: agent.vue uses the npm-bundled skapi-js and OMITS\n * `poll` (its clientSecretRequest auto-resolves with the final body), whereas\n * the BunnyQuery widget uses the deployed skapi-js@latest and must pass\n * `poll: 0` to get the early ack + a manual `.poll()` handle (needed for queued-\n * send cancel). So the request builders include `poll` only when it is set.\n */\n\nimport { type AttachmentParser, registerAttachmentParser } from './attachment_parsers';\n\nexport interface ChatEngineConfig {\n /** skapi.clientSecretRequest, bound to the consumer's skapi instance. */\n clientSecretRequest: (opts: any) => Promise<any>;\n /** skapi.clientSecretRequestHistory, bound to the consumer's skapi instance. */\n clientSecretRequestHistory: (params: any, fetchOptions: any) => Promise<any>;\n /** MCP server base URL (prod vs dev resolved by the consumer). */\n mcpBaseUrl: string;\n /**\n * Value to attach as `poll` on every clientSecretRequest. When `undefined`\n * the `poll` key is omitted entirely (agent.vue). BunnyQuery sets `0`.\n */\n poll?: number;\n /**\n * Optional client-side attachment parsers (e.g. an .hwp parser). Each is\n * registered at configure time; more can be added later via\n * `registerAttachmentParser()`. See attachment_parsers.ts.\n */\n attachmentParsers?: AttachmentParser[];\n /**\n * Opt in to SERVER-DRIVEN windowed indexing for text/grid files.\n *\n * Off by default, and deliberately so. When on, the client emits a\n * `_skapi_window` directive and the WORKER reads the file one window at a time,\n * continuing until the reader says it is exhausted. When off, the agent pages the\n * file itself with readFileContent, exactly as before.\n *\n * The flag exists because the backend must ship FIRST: a client emitting the\n * directive against a worker that does not strip it leaves an unknown field in the\n * request body, and the provider rejects the whole call with no retry. Keep it off\n * until the worker is deployed, then flip it per environment.\n */\n windowedIndexing?: boolean;\n}\n\nlet _config: ChatEngineConfig | null = null;\n\nexport function configureChatEngine(config: ChatEngineConfig): void {\n _config = config;\n if (config.attachmentParsers) {\n for (const parser of config.attachmentParsers) registerAttachmentParser(parser);\n }\n}\n\nexport function chatEngineConfig(): ChatEngineConfig {\n if (!_config) {\n throw new Error(\n '[chat-engine] configureChatEngine() must be called before using the engine.',\n );\n }\n return _config;\n}\n\n/** True when the consumer has opted in to server-driven windowed indexing. */\nexport function windowedIndexingEnabled(): boolean {\n return _config?.windowedIndexing === true;\n}\n\n/** Spread helper: `{ ...pollOpt() }` adds `poll` only when configured. */\nexport function pollOpt(): { poll?: number } {\n const p = _config?.poll;\n return p === undefined ? {} : { poll: p };\n}\n","/**\n * Office-file server-side extraction helpers.\n *\n * Office documents (Microsoft .docx/.xlsx/.pptx, Hancom .hwpx, etc.) can't be\n * read by web_fetch (binary/zip). The proxy worker downloads them from db\n * storage, extracts their text server-side, and substitutes that text for a\n * placeholder token in the request body (carried under the reserved\n * `_skapi_extract` key, which the producer strips before the upstream call).\n */\n\n// A directive telling the proxy worker which office file to download + extract\n// and which placeholder token in the request body to substitute.\nexport type ExtractDirective = {\n\t/** db storage path of the file, e.g. \"folder/report.docx\" (also the src:: value). */\n\tpath: string;\n\t/** The exact token in the request body to replace with the extracted text. */\n\tplaceholder: string;\n\t/** Original filename — informational (server logs only). */\n\tname?: string;\n\t/** MIME type — informational (server logs only). */\n\tmime?: string;\n};\n\n// A directive telling the proxy worker to re-mint a fresh, short-lived URL for a\n// file the model fetches by url (PDFs, images — anything NOT server-extractable)\n// right before the upstream call, so a queued request never hands the model a\n// stale link. The worker mints from `path` and swaps `url` (the exact baked url\n// string) everywhere it appears in the request body.\nexport type FileUrlDirective = {\n\t/** db storage path of the file, e.g. \"folder/report.pdf\" (also the src:: value). */\n\tpath: string;\n\t/** The exact baked url string in the request body to replace with a fresh one. */\n\turl: string;\n};\n\n// Files whose text the worker extracts SERVER-SIDE and inlines for indexing,\n// instead of handing the agent a URL to fetch. Two groups:\n// (1) BINARY document formats the model can't read at all (OOXML, Hancom\n// HWP/HWPX, OpenDocument, EPUB) — the worker parses them.\n// (2) TEXT/data/markup/code formats. These ARE readable via web_fetch, BUT\n// some providers (OpenAI's Responses API) have no working file-fetch tool,\n// so the agent can't retrieve the URL at all. Extracting them server-side\n// (the worker just decodes the bytes) makes indexing provider-independent.\nconst OFFICE_FILE_EXTENSIONS = new Set([\n\t'doc', 'docx', 'docm',\n\t'xls', 'xlsx', 'xlsm',\n\t'ppt', 'pptx', 'pptm',\n\t'hwp', 'hwpx',\n\t'ods', 'odt', 'odp',\n\t'epub',\n]);\n\nconst TEXT_FILE_EXTENSIONS = new Set([\n\t'csv', 'tsv', 'tab', 'txt', 'text', 'log', 'md', 'markdown', 'rst',\n\t'json', 'ndjson', 'jsonl', 'geojson', 'xml', 'yaml', 'yml', 'toml',\n\t'ini', 'conf', 'cfg', 'properties', 'env', 'rtf', 'html', 'htm',\n\t'js', 'mjs', 'cjs', 'ts', 'tsx', 'jsx', 'py', 'rb', 'go', 'rs', 'java',\n\t'kt', 'c', 'h', 'cpp', 'cc', 'hpp', 'cs', 'php', 'swift', 'sh', 'bash',\n\t'zsh', 'sql', 'css', 'scss', 'less', 'vue', 'svelte', 'tex', 'srt', 'vtt',\n]);\n\n// MIME types that indicate decodable text even when the extension is unknown\n// (the worker has the same fallback, so any text/* file is extracted server-side).\nfunction isTextMime(m: string): boolean {\n\treturn (\n\t\tm.startsWith('text/') ||\n\t\tm.endsWith('+json') || m.endsWith('+xml') || m.endsWith('+yaml') ||\n\t\tm === 'application/json' || m === 'application/ld+json' ||\n\t\tm === 'application/xml' || m === 'application/yaml' || m === 'application/x-yaml' ||\n\t\tm === 'application/javascript' || m === 'application/x-javascript' ||\n\t\tm === 'application/x-sh' || m === 'application/x-ndjson' ||\n\t\tm === 'application/csv' || m === 'application/rtf' ||\n\t\tm === 'application/sql' || m === 'application/toml'\n\t);\n}\n\n/**\n * True when a file should be EXTRACTED SERVER-SIDE (text inlined for indexing)\n * rather than handed to the agent as a URL to fetch — i.e. binary office\n * documents AND all text/data/code files. Detection is extension-first (so a\n * .csv reported as an Office MIME is still treated as text), with a text-MIME\n * fallback for unlisted extensions.\n */\nexport function isServerExtractable(name?: string, mime?: string): boolean {\n\tconst ext = (name || '').split('.').pop()?.toLowerCase() || '';\n\tif (OFFICE_FILE_EXTENSIONS.has(ext)) return true;\n\tif (TEXT_FILE_EXTENSIONS.has(ext)) return true;\n\tconst m = (mime || '').toLowerCase();\n\tif (isTextMime(m)) return true;\n\treturn (\n\t\tm.includes('officedocument') ||\n\t\tm.includes('opendocument') ||\n\t\tm.includes('hwp') ||\n\t\tm.includes('epub') ||\n\t\tm === 'application/msword' ||\n\t\tm === 'application/vnd.ms-excel' ||\n\t\tm === 'application/vnd.ms-powerpoint'\n\t);\n}\n\n/** @deprecated renamed to {@link isServerExtractable} (now also covers text files). */\nexport const isOfficeFile = isServerExtractable;\n\n// Extensions read WINDOW-BY-WINDOW via the readFileContent tool instead of inlined once.\n//\n// Anything NOT in this set falls back to one-shot server extraction, which is capped at\n// MAX_EXTRACTED_CHARS (200k). Measured against real files, that cap was discarding the\n// overwhelming majority of every large non-spreadsheet upload:\n// 5MB .txt -> 4.0% indexed (4.8M characters silently dropped)\n// 4.8MB .json-> 4.2%\n// 1.9M-char Korean .txt -> 10.5%\n// .docx -> 70.6%\n// The truncation was invisible: the agent received a plausible-looking document and had\n// no way to know most of it was missing. Windowing these types is what makes \"index the\n// whole file\" true rather than aspirational.\n//\n// CSV/TSV specifically must be here rather than in the inline path: the layer now gives\n// them ROW-bounded windows with absolute row numbers, where the character windower used\n// to split rows across boundaries and emit no row numbers at all.\nconst PAGED_READ_EXTENSIONS = new Set([\n\t// grids\n\t'xls', 'xlsx', 'xlsm', 'ods',\n\t// delimited text (row-windowed by the layer)\n\t'csv', 'tsv', 'tab',\n\t// documents\n\t'pdf', 'docx', 'pptx',\n\t// plain text / data / markup\n\t'txt', 'md', 'markdown', 'log', 'json', 'jsonl', 'ndjson', 'xml', 'yaml', 'yml',\n]);\n\n/**\n * True when a file should be indexed by PAGING through readFileContent (spreadsheets and\n * PDFs), rather than inline extraction or a web_fetch URL. This is what lets a huge sheet\n * be read row-window by row-window and a scanned PDF be read page-image by page-image,\n * with embedded photos delivered to the vision model.\n */\nexport function isPagedReadFile(name?: string, mime?: string): boolean {\n\tconst ext = (name || '').split('.').pop()?.toLowerCase() || '';\n\tif (PAGED_READ_EXTENSIONS.has(ext)) return true;\n\tconst m = (mime || '').toLowerCase();\n\treturn (\n\t\tm === 'application/pdf' ||\n\t\tm === 'application/vnd.ms-excel' ||\n\t\tm.includes('spreadsheetml') ||\n\t\tm.includes('opendocument.spreadsheet')\n\t);\n}\n\n/**\n * True for files whose content is VISUAL and must be delivered to the model as IMAGE\n * BLOCKS in the message (rendered pages), because tool-result images render on neither\n * provider. The worker renders a page window to image URLs and injects them (`_skapi_render`\n * directive). Currently PDFs (scanned or not); indexed page-window by page-window with\n * resume advancing the window.\n */\nexport function isImageVisionFile(name?: string, mime?: string): boolean {\n\tconst ext = (name || '').split('.').pop()?.toLowerCase() || '';\n\treturn ext === 'pdf' || (mime || '').toLowerCase() === 'application/pdf';\n}\n\n// Monotonic counter so placeholders are unique even for same-named files in one\n// request. Token shape must match the worker's _EXTRACT_PLACEHOLDER_RE:\n// {{SKAPI_FILE_CONTENT::<id>}}.\nlet _extractPlaceholderSeq = 0;\nexport function makeExtractPlaceholder(seed: string): string {\n\t_extractPlaceholderSeq += 1;\n\tconst slug = (seed || 'file').replace(/[^a-zA-Z0-9]+/g, '_').slice(-48);\n\treturn `{{SKAPI_FILE_CONTENT::${slug}-${_extractPlaceholderSeq}}}`;\n}\n\n// Placeholder marking WHERE the worker injects a window of rendered page/photo IMAGE blocks\n// (the `_skapi_render` directive). Distinct token from the text-extraction placeholder.\nlet _renderPlaceholderSeq = 0;\nexport function makeRenderPlaceholder(seed: string): string {\n\t_renderPlaceholderSeq += 1;\n\tconst slug = (seed || 'file').replace(/[^a-zA-Z0-9]+/g, '_').slice(-48);\n\treturn `{{SKAPI_RENDER::${slug}-${_renderPlaceholderSeq}}}`;\n}\n\n// Page/photo images per render window. Must match the server default so the client's\n// resume window (from = pass * PAGES) lines up with what the worker renders.\nexport const RENDER_PAGES_PER_WINDOW = 5;\n\n// Token the WORKER substitutes with a human description of the next window's position.\n// Shared with the render loop so one substitution path serves both.\nexport const WINDOW_CURSOR_TOKEN = '{{RENDER_FROM}}';\n\nlet _windowPlaceholderSeq = 0;\n\n/**\n * Placeholder the worker replaces with ONE window of a file's text/grid content.\n * Distinct token from the render (page-image) and extract (whole-file) placeholders so\n * a stale token from either can never be mistaken for this one.\n */\nexport function makeWindowPlaceholder(seed: string): string {\n\t_windowPlaceholderSeq += 1;\n\tconst slug = (seed || 'file').replace(/[^a-zA-Z0-9]+/g, '_').slice(-48);\n\treturn `{{SKAPI_WINDOW::${slug}-${_windowPlaceholderSeq}}}`;\n}\n\n/**\n * True when a file should be read server-side, one window at a time, by the worker.\n * PDFs are excluded: they go through the VISION path, where pages are rendered to\n * images because their text layer is often absent or unreliable.\n */\nexport function isWindowedReadFile(name?: string, mime?: string): boolean {\n\tif (isImageVisionFile(name, mime)) return false;\n\treturn isPagedReadFile(name, mime);\n}\n\nexport interface ComposedUserMessage {\n\t/** Clean display/history copy (attachment links, NO extraction placeholders). */\n\tcomposed: string;\n\t/** LLM-bound copy — `composed` plus inline office-extraction placeholders. */\n\tcomposedForLlm: string;\n\t/** Office-extraction directives for the proxy worker (undefined if no office files). */\n\textractContent?: ExtractDirective[];\n\t/** JIT url re-mint directives for the worker (non-extractable files: PDFs, images). */\n\tfileUrls?: FileUrlDirective[];\n}\n\n// Compose the user's chat message from the typed text + uploaded attachment URLs.\n// Identical for every consumer (agent.vue + the BunnyQuery widget): appends a\n// markdown \"Attached files\" link block, and for office files\n// (.docx/.xlsx/.pptx/.hwpx) adds inline extraction placeholders to the LLM copy\n// ONLY (the proxy worker substitutes their text server-side; the display/history\n// copy stays clean so stale tokens never accumulate across replayed turns).\n// The directive `path` is the db storage path (uid-prefixed where applicable),\n// NOT the link label — it falls back to the label when no storagePath is given\n// (agent.vue uploads FLAT, so storagePath === name there).\nexport function composeUserMessage(\n\ttext: string,\n\tattachmentUrls: Array<{ name: string; url: string; storagePath?: string }>,\n): ComposedUserMessage {\n\tlet composed = text;\n\tif (attachmentUrls.length > 0) {\n\t\tconst lines = attachmentUrls.map((u) => `- [${u.name}](${u.url})`);\n\t\tcomposed = `${text}\\n\\nAttached files:\\n${lines.join('\\n')}`;\n\t}\n\tlet composedForLlm = composed;\n\tlet extractContent: ExtractDirective[] | undefined;\n\tlet fileUrls: FileUrlDirective[] | undefined;\n\tif (attachmentUrls.length > 0) {\n\t\tconst extractFiles = attachmentUrls.filter((u) => isServerExtractable(u.name));\n\t\tif (extractFiles.length > 0) {\n\t\t\tconst directives: ExtractDirective[] = [];\n\t\t\tconst sections = extractFiles.map((u) => {\n\t\t\t\tconst storagePath = u.storagePath || u.name;\n\t\t\t\tconst placeholder = makeExtractPlaceholder(storagePath);\n\t\t\t\tdirectives.push({ path: storagePath, placeholder, name: u.name });\n\t\t\t\treturn `===== ${u.name} =====\\n----- BEGIN FILE CONTENT -----\\n${placeholder}\\n----- END FILE CONTENT -----`;\n\t\t\t});\n\t\t\textractContent = directives;\n\t\t\tcomposedForLlm =\n\t\t\t\t`${composed}\\n\\nExtracted content of attached office files ` +\n\t\t\t\t`(read inline below; do NOT fetch their URLs):\\n\\n` +\n\t\t\t\tsections.join('\\n\\n');\n\t\t}\n\t\t// Files the model fetches by url (NOT server-extractable: PDFs, images) get\n\t\t// a re-mint directive so the worker swaps the baked long-lived CDN url for a\n\t\t// fresh short-lived one at send time. Extractable files are inlined as text,\n\t\t// so their url is never fetched — no directive needed. A blank url (nothing\n\t\t// to match/replace) is skipped.\n\t\tconst urlFiles = attachmentUrls.filter((u) => u.url && !isServerExtractable(u.name));\n\t\tif (urlFiles.length > 0) {\n\t\t\tfileUrls = urlFiles.map((u) => ({ path: u.storagePath || u.name, url: u.url }));\n\t\t}\n\t}\n\treturn { composed, composedForLlm, extractContent, fileUrls };\n}\n","/**\n * Attachment helpers shared by every consumer's view layer.\n *\n * The upload ORCHESTRATION is per-consumer (agent.vue does admin storage\n * accounting; the widget uses get-signed-url), but the failure-reporting shape\n * is identical, so it lives here. When an upload or its indexing request fails,\n * the orchestrator records the original `error.code` / `error.message` on the\n * attachment (`att.errorCode` / `att.errorDetail`); this groups those failed\n * attachments by (code, description) so a single report dialog can list each\n * distinct error once with all the files it affected.\n */\n\nexport interface AttachmentFailureGroup {\n\t/** The failing `error.code` (empty string when the error carried none). */\n\tcode: string;\n\t/** The failing `error.message` / human description. */\n\tmessage: string;\n\t/** Display names of the attachments that hit this exact (code, message). */\n\tfiles: string[];\n}\n\n// Group failed attachments by (code, message). A status of 'error' means the\n// upload itself failed; 'indexError' means the file uploaded but its indexing\n// request failed — both are surfaced. Order of first appearance is preserved.\nexport function groupAttachmentFailures(attachments: any[]): AttachmentFailureGroup[] {\n\tconst groups: Record<string, AttachmentFailureGroup> = {};\n\tconst order: string[] = [];\n\t(attachments || []).forEach(function (att: any) {\n\t\tif (!att || (att.status !== 'error' && att.status !== 'indexError')) return;\n\t\tconst code = String(att.errorCode || '');\n\t\tconst message = String(\n\t\t\tatt.errorDetail ||\n\t\t\tatt.errorMessage ||\n\t\t\t(att.status === 'indexError' ? 'File indexing failed' : 'File upload has failed'),\n\t\t);\n\t\tconst key = code + '\u0000' + message;\n\t\tif (!groups[key]) {\n\t\t\tgroups[key] = { code: code, message: message, files: [] };\n\t\t\torder.push(key);\n\t\t}\n\t\tgroups[key].files.push(String(att.name || '(unnamed file)'));\n\t});\n\treturn order.map(function (k) { return groups[k]; });\n}\n","/**\n * BASE PROMPT — Chat assistant\n * ============================================================================\n * System prompt sent on every chat turn. Rebuilt fresh on every send because\n * the project name/description can change at any time.\n *\n * The `${...}` placeholders are filled from the live project (service):\n * formattedServiceId -> the project ID the assistant is scoped to\n * serviceName -> project display name (only added if a description exists)\n * serviceDescription -> project description (only added if present)\n */\n\nexport type ChatSystemPromptParams = {\n\t/** The project/service ID this assistant is scoped to (formatted form). */\n\tformattedServiceId: string;\n\t/** Project display name. Only appended when a description is also present. */\n\tserviceName?: string;\n\t/** Project description. When present, name + description are appended. */\n\tserviceDescription?: string;\n};\n\nexport function buildChatSystemPrompt(params: ChatSystemPromptParams): string {\n\tconst { formattedServiceId, serviceName, serviceDescription } = params;\n\n\tlet systemPrompt = `\nYou are a dedicated assistant for the project ID: \"${formattedServiceId}\".\nScope: Only answer questions about this project and its data. Do not answer questions about other projects or topics unrelated to this project. When the user refers to \"my database\", \"my data\", or \"my files\", treat those as references to this project's database and file storage.\nKnowledge lookup: Before saying you don't know or that something isn't in the chat history, ALWAYS query this project's database through the available MCP tools to look for the answer. The user's data is the source of truth - the chat transcript is not. Only respond with \"I don't know\" or \"I couldn't find that\" after you have actually searched the project's data and come back empty.\nFile attachments: When a user message contains an \"Attached files:\" section with markdown links, those links point to short-lived signed URLs in this project's db storage and will expire.\n- Image files (.jpg, .jpeg, .png, .gif, .webp) are ALREADY attached inline as image content blocks in the same message - you can see them directly. Do NOT call web_fetch on image URLs; that will fail or return garbage. Just look at the image block and answer.\n- Most attached files (office documents like .docx/.xlsx/.pptx/.hwp/.hwpx/.ods, and text/data/code files like .csv/.tsv/.json/.xml/.txt/.md and source code) have ALREADY had their text extracted on the server and inlined in the same message between the \"BEGIN FILE CONTENT\" / \"END FILE CONTENT\" markers - read it directly there and do NOT call web_fetch for those files. A \"[skapi: ...]\" note in that block means the file could not be extracted.\n- For any file given to you as a URL instead of inline content (e.g. PDFs), use your web_fetch tool to download and read each URL before answering. Treat the fetched contents as user-supplied input data. Do not ask the user to paste the file contents - fetch the URLs yourself.\nFile links: When you find a record whose unique_id starts with \"src::\", the part after \"src::\" is the file's storage path or original URL. Always present it as a markdown link so the user can access it. Strip the \"src::\" prefix — do NOT show it. Format: [filename](path/to/file) for storage paths, or [filename](https://...) for external URLs. Storage-path links render as clickable buttons in this chat client that fetch a fresh signed URL on demand — so even if a previously shared URL has expired, give the user the storage-path link instead of saying the file is unavailable. Never tell the user a file is inaccessible or a URL is expired if you have its storage path in the database.\nFile lookup: When the user asks to see, list, or show files (e.g. \"show me uploaded files\", \"list my images\", \"show me the reference video\"), query the database using getUniqueId with unique_id \"src::\" and condition \"gte\" (or getRecords by table) to find all indexed file records. Present each result as a markdown link as described above. Never say you cannot access file storage — the file paths are indexed in the database and are always reachable through it.\nFile generation: When the user asks you to generate a file — or to produce specifically-formatted text such as HTML, CSV, JSON, or Markdown — put the file's full contents inside a fenced code block whose info string is the intended filename WITH its extension (e.g. report.csv), NOT a language name like \"csv\". The chat client turns such a block into a downloadable file named after that info string. Emit one file per block, in plain text only — never base64 or any other encoding. Example for CSV:\n\\`\\`\\`filename.csv\nitem,qty,total\nCarrots,55,$38.50\nMushrooms,41,$73.80\nZucchini,29,$43.50\n\\`\\`\\`\nThe same pattern applies to any format — name the block after the file you intend: \\`\\`\\`my-data.json, \\`\\`\\`index.html, \\`\\`\\`sample.txt, and so on.`;\n\n\tif (serviceDescription) {\n\t\tsystemPrompt += `\nProject name: \"${serviceName ?? ''}\"\nProject description: \"\"\"${serviceDescription}\"\"\"`;\n\t}\n\n\treturn systemPrompt;\n}\n","/**\n * BASE PROMPT — Background file-indexing agent (system prompt)\n * ============================================================================\n * System prompt for the BACKGROUND indexing agent (notifyAgentSaveAttachment).\n * Its only job is to read the freshly uploaded file and persist what it learns\n * into the project's knowledge base via the MCP tools. Pairs with the\n * user-message template in ./indexing_user_message.ts.\n */\n\nexport type IndexingSystemPromptParams = {\n\t/** The project/service ID being indexed into. */\n\tservice: string;\n\t/** Project display name. Only appended when a description is also present. */\n\tserviceName?: string;\n\t/** Project description. When present, name + description are appended. */\n\tserviceDescription?: string;\n};\n\nexport function buildIndexingSystemPrompt(params: IndexingSystemPromptParams): string {\n\tconst { service, serviceName, serviceDescription } = params;\n\n\tlet systemPrompt =\n`You are a background indexing agent for project ${service}.\n- Image files (.jpg, .jpeg, .png, .gif, .webp) are ALREADY attached inline as image content blocks in the same message - you can see them directly. Do NOT call web_fetch on image URLs; that will fail or return garbage. Just look at the image block and answer.\n- Most files (office documents like .docx/.xlsx/.pptx/.hwp/.hwpx/.ods, and text/data/code files like .csv/.tsv/.json/.xml/.txt/.md and source code) have ALREADY been extracted on the server and included inline in the user message between the \"BEGIN FILE CONTENT\" / \"END FILE CONTENT\" markers - read that directly. If the inline content is a \"[skapi: ...]\" note, the file could not be extracted - index it from its metadata only.\n- BIG SPREADSHEETS / TEXT: the inline content may be only the FIRST part of a large file (it can end with a truncation or \"more remains\" note). For big spreadsheets and big text/data files READ THE FILE WITH THE readFileContent TOOL: it returns the file ONE WINDOW at a time (spreadsheets as coordinate-tagged grid rows, text as a range of characters). Pass the file's storage path. After each window: datafy it into records and SAVE them, THEN if the window says MORE REMAINS call readFileContent again with the cursor it gives you. Repeat until it says END OF FILE, so the WHOLE file is indexed - never stop after the first window. (Do NOT call readFileContent on a PDF - see the next line.)\n- PDFs (scanned or not): you do NOT read a PDF with a tool or a URL. Its pages are RENDERED and embedded directly in the user message as IMAGE blocks, a WINDOW of pages at a time. LOOK at the embedded page images and datafy every one. The note beside them tells you whether MORE pages remain: if so, save this window's records and stop (a follow-up pass shows the next window automatically); only when the note says it was the LAST window is the PDF fully seen. Do NOT call readFileContent or web_fetch for a PDF.\n- VISION: when the message (a readFileContent window, an embedded PDF page, or an inline attachment) includes IMAGES - scanned/rendered PDF pages, or photos embedded in a spreadsheet next to a row/block - LOOK at them and capture what they show as record data (the reading/values in a scanned table, the part/defect/condition visible in a photo). The image IS part of the data; correlate each photo with its labelled block (\"PHOTO A3\" markers tie a photo to that grid row).\n- Whatever the file type, use the file's storage path (the \"storage path\" metadata line) as the \"src::\" unique_id - never the inline content or a temporary URL.\n- TABULAR data (any spreadsheet - .csv/.tsv/.xlsx/.xls/.ods, or sheet-like rows): you MUST save EVERY data row as its own record (ONE record per row) with that row's actual column values in the record's \"data\", keyed by the header names, in a dedicated table (e.g. \"spreadsheet_rows\"). Do NOT summarize, sample only a few rows, or save just file metadata - index the whole sheet, paging through it with readFileContent when it is large. Make MULTIPLE postRecords calls in batches (e.g. 30-50 rows per call) rather than one oversized call. This per-row completeness OVERRIDES brevity. ALSO save one file-level summary record (file name, sheet name(s), column headers, total row count, overall summary) - this is the record that carries the file's \"src::\" unique_id - and link EVERY per-row record to it via reference (set each row record's reference to that src:: file record; the row records themselves do NOT carry a src:: unique_id). The per-row records AND this reference linkage are BOTH mandatory: the linkage is what lets the whole sheet be found and cleaned up together when the file is re-indexed.\n- EPUB / e-books / long-form books (.epub or any book-length prose, provided inline in reading order with chapter headings preserved): you MUST save ONE record per CHAPTER (or, when chapters are unclear, per major section/topic) in a dedicated table (e.g. \"book_chapters\") - never collapse the whole book into a single record. Each chapter record's \"data\" must capture the chapter title plus its order/number AND a substantive summary of that chapter's content (key events, arguments, characters, places, concepts, terms, notable quotes). Apply AS MANY relevant tags as possible to EVERY chapter record (characters, locations, themes, topics, key concepts, key terms, dates, named entities) so the book is easy to SEARCH and cross-reference later - this is the whole point. ALSO save one book-level record (title, author, language, overall summary, chapter list / table of contents, genre/subjects) and link each chapter record to it via reference. This per-chapter completeness OVERRIDES brevity; human-readable summaries only, never raw/binary bytes.\n- This is a background indexing task: do ALL the MCP saving FIRST, never reply mid-task, and never ask the user questions. Always use the MCP tools to save what you learn - be exhaustive about meaning (and, for tabular data, about every row). SAVE AS YOU GO: persist each window's records before reading the next, so progress is never lost. If the file is so large you cannot finish in one turn, still save everything you have read so far; a follow-up pass will automatically continue from where you stopped. Never store raw or binary bytes (base64, blobs); describe them in human-readable text instead.\n- COMPLETION SIGNAL: only when you have fully read and saved the ENTIRE file (for readFileContent files: reached \"END OF FILE\"; for PDFs: the embedded page-image note said it was the LAST window - with all rows/pages/items saved), end your final message with the token INDEXING_COMPLETE on its own line. If you did NOT finish the whole file (more rows/pages remain), do NOT write that token - leaving it out is how the system knows to run another pass to continue.\n- Only AFTER every save is done, send exactly ONE final message summarizing what you indexed - never just \"Indexing complete\", and never a raw/base64/binary value or a large pasted dump. Keep it to a few factual sentences or a short markdown bullet list covering: the file name, its content type, each table you wrote to with its record/row count and the key columns/fields or topics captured, and anything that could not be extracted. Follow this shape - Indexed <file name> (<content type>): saved <N> records to <table(s)> capturing <key columns/fields or topics>; could not extract: <gaps, or none>.`;\n\n\tif (serviceDescription) {\n\t\tsystemPrompt += `\nProject name: \"${serviceName ?? ''}\"\nProject description: \"\"\"${serviceDescription}\"\"\"`;\n\t}\n\n\treturn systemPrompt;\n}\n","/**\n * BASE PROMPT — Background file-indexing agent (user message)\n * ============================================================================\n * USER-role message paired with the indexing system prompt. Sent by\n * notifyAgentSaveAttachment() each time a file is uploaded or re-indexed.\n *\n * NOTE: the leading line \"A new file has just been uploaded. Index it now.\" and\n * the \"- name: ...\" line are also what the chat client parses to build the\n * \"Indexing: <name>\" history bubble — keep those fields on their own lines.\n */\n\nexport type IndexingAttachmentInfo = {\n\t/** Original file name. */\n\tname: string;\n\t/** Storage path within the project's db storage. */\n\tstoragePath: string;\n\t/** MIME type, if detected. Omitted from the message when unknown. */\n\tmime?: string;\n\t/** File size in bytes, if known. Omitted from the message when unknown. */\n\tsize?: number;\n\t/** Temporary signed URL the agent/MCP fetches to read the file contents. */\n\turl: string;\n};\n\nexport type BuildIndexingUserMessageOptions = {\n\t/**\n\t * For office files (.docx/.xlsx/.pptx) the model can't read the binary via\n\t * web_fetch, so the proxy worker extracts the text server-side and replaces\n\t * this exact token with it. When provided, the message embeds the token (and\n\t * drops the temporary-URL line — there is nothing for the model to fetch).\n\t */\n\tinlineContentPlaceholder?: string;\n\t/**\n\t * Actual file content parsed CLIENT-SIDE by an attachment-parser plugin (e.g.\n\t * an .hwp parser). Embedded inline verbatim — no server extraction and no\n\t * web_fetch for this file. Takes precedence over `inlineContentPlaceholder`.\n\t */\n\tinlineContent?: string;\n\t/**\n\t * Spreadsheet or PDF: read by PAGING through the readFileContent tool (grid rows +\n\t * embedded photos / rendered scanned pages), not inline and not by web_fetch. The\n\t * message instructs the agent to page through EVERY window and datafy each.\n\t */\n\tpagedRead?: boolean;\n};\n\nexport function buildIndexingUserMessage(\n\tattachment: IndexingAttachmentInfo,\n\toptions?: BuildIndexingUserMessageOptions,\n): string {\n\tconst head =\n\t\t`A new file has just been uploaded. Index it now.\\n\\n` +\n\t\t`File metadata:\\n` +\n\t\t`- name: ${attachment.name}\\n` +\n\t\t`- storage path: ${attachment.storagePath}\\n` +\n\t\t(attachment.mime ? `- mime type: ${attachment.mime}\\n` : '') +\n\t\t(typeof attachment.size === 'number' ? `- size (bytes): ${attachment.size}\\n` : '');\n\n\tif (options?.inlineContent) {\n\t\t// Parsed client-side (an attachment-parser plugin). The content is already\n\t\t// inlined below — no server extraction, no URL to fetch.\n\t\treturn (\n\t\t\thead +\n\t\t\t`\\nThe file's content was parsed by the client and is provided inline below. ` +\n\t\t\t`Read it directly — do NOT fetch any URL for this file. ` +\n\t\t\t`Use the storage path above (not this content) for the \"src::\" unique_id.\\n\\n` +\n\t\t\t`----- BEGIN FILE CONTENT -----\\n` +\n\t\t\t`${options.inlineContent}\\n` +\n\t\t\t`----- END FILE CONTENT -----`\n\t\t);\n\t}\n\n\tif (options?.inlineContentPlaceholder) {\n\t\t// Office file: text was extracted on the server and is inlined below\n\t\t// between the markers. Do NOT fetch any URL for this file.\n\t\treturn (\n\t\t\thead +\n\t\t\t`\\nThe file's text content was extracted on the server and is provided inline below. ` +\n\t\t\t`Read it directly — do NOT fetch any URL for this file. ` +\n\t\t\t`Use the storage path above (not this content) for the \"src::\" unique_id.\\n\\n` +\n\t\t\t`----- BEGIN FILE CONTENT -----\\n` +\n\t\t\t`${options.inlineContentPlaceholder}\\n` +\n\t\t\t`----- END FILE CONTENT -----`\n\t\t);\n\t}\n\n\tif (options?.pagedRead) {\n\t\t// Spreadsheet / PDF: force the paging path. The agent MUST read this with the\n\t\t// readFileContent tool (which returns the file window by window, with grid rows,\n\t\t// embedded photos, and rendered scanned pages), NOT by fetching the URL.\n\t\treturn (\n\t\t\thead +\n\t\t\t`\\nRead this file with the readFileContent tool, using the storage path above - do NOT fetch a URL and do NOT rely on a single sample. ` +\n\t\t\t`readFileContent returns the file ONE WINDOW at a time: spreadsheets as coordinate-tagged grid rows (e.g. 'R4 A:E&I NUMBER | B:E1007'), scanned/large PDFs as rendered PAGE IMAGES, and windows may include embedded photos - LOOK at any images and datafy what they show. ` +\n\t\t\t`Page through EVERY window: for each window SAVE records for its rows/items/pages (postRecords, one record per row/item), THEN if the window says MORE REMAINS call readFileContent again with the cursor it gives you. Repeat until it says END OF FILE, so the WHOLE file is indexed. ` +\n\t\t\t`Do NOT stop after the first window and do NOT just write a summary. Use the storage path above for the \"src::\" unique_id.` +\n\t\t\t(attachment.url ? `\\n(A temporary URL is provided ONLY as a fallback if readFileContent fails: ${attachment.url})` : '')\n\t\t);\n\t}\n\n\treturn head + `- temporary URL (fetch this to read the file contents): ${attachment.url}`;\n}\n\n/**\n * Token the WORKER substitutes with the 1-based first page of the window it is about to\n * render, when it builds the next pass of a document from `RENDER_CONTINUE_TEMPLATE`.\n * Must match the worker's RENDER_FROM_TOKEN.\n */\nexport const RENDER_FROM_TOKEN = '{{RENDER_FROM}}';\nconst WINDOW_CURSOR_TOKEN = RENDER_FROM_TOKEN;\n\n/**\n * User message for a VISION file (PDF): its pages are delivered as RENDERED PAGE IMAGES that\n * the proxy worker injects into THIS message at the `placeholder` token (tool-result images\n * render on neither provider, so the pages must be image blocks in the message itself). Each\n * pass shows one WINDOW of pages starting at `renderFrom` (0-based).\n *\n * The WORKER advances the window: when its renderer reports pages remaining it enqueues the\n * next pass itself, off the true page count, so a document indexes end-to-end with no browser\n * involved. This message therefore only ever describes ONE window, and the model is never\n * asked to decide whether the document is finished.\n *\n * renderFrom === 0 is the FIRST pass (leads with \"A new file has just been uploaded.\" so the\n * client builds the \"Indexing: <name>\" bubble); a continue pass (built by the worker from\n * buildIndexingRenderContinueTemplate) leads with \"CONTINUE indexing\" so it is not a duplicate\n * primary bubble.\n */\nexport function buildIndexingRenderMessage(\n\tattachment: IndexingAttachmentInfo,\n\tplaceholder: string,\n\trenderFrom: number,\n): string {\n\tconst from = Math.max(0, renderFrom || 0);\n\tif (from > 0) return buildIndexingRenderContinueTemplate(attachment, placeholder, String(from + 1));\n\n\treturn (\n\t\t`A new file has just been uploaded. Index it now.\\n\\n` +\n\t\tbuildRenderMeta(attachment) +\n\t\t`\\nThis is a PDF. Its pages are delivered to you as RENDERED PAGE IMAGES embedded directly in this ` +\n\t\t`message (you do NOT need any tool, URL, or web_fetch to see them). You are shown a WINDOW of pages ` +\n\t\t`at a time, starting at page ${from + 1}.\\n` +\n\t\tbuildRenderDatafy(placeholder)\n\t);\n}\n\n/**\n * The CONTINUE pass, as a template the worker fills in. `pageLabel` defaults to the\n * RENDER_FROM_TOKEN placeholder, which the worker replaces with the real 1-based start page\n * of the window it is rendering; passing an explicit label produces a ready-to-send message.\n */\nexport function buildIndexingRenderContinueTemplate(\n\tattachment: IndexingAttachmentInfo,\n\tplaceholder: string,\n\tpageLabel: string = RENDER_FROM_TOKEN,\n): string {\n\tconst src = `src::${attachment.storagePath}`;\n\treturn (\n\t\t`CONTINUE indexing a PDF whose previous pass did not finish.\\n\\n` +\n\t\tbuildRenderMeta(attachment) +\n\t\t`\\nRecords for the earlier pages are ALREADY saved (they reference \"${src}\"). The NEXT window of ` +\n\t\t`rendered page images (starting at page ${pageLabel}) is embedded in this message. Datafy each page as ` +\n\t\t`before and do NOT re-save pages that are already saved.\\n` +\n\t\tbuildRenderDatafy(placeholder)\n\t);\n}\n\nfunction buildRenderMeta(attachment: IndexingAttachmentInfo): string {\n\treturn (\n\t\t`File metadata:\\n` +\n\t\t`- name: ${attachment.name}\\n` +\n\t\t`- storage path: ${attachment.storagePath}\\n` +\n\t\t(attachment.mime ? `- mime type: ${attachment.mime}\\n` : '')\n\t);\n}\n\n// Shared datafy guidance. The placeholder is where the worker splices the note + rendered\n// page images; instructions reference \"the page images in this message\" so they read\n// correctly whether the images land before or after this text.\n//\n// Deliberately says nothing about INDEXING_COMPLETE or about whether the document is\n// finished: the worker decides that from the renderer's page count. Asking the model was\n// what used to end an 88-page file at page 15.\nfunction buildRenderDatafy(placeholder: string): string {\n\treturn (\n\t\t`\\n${placeholder}\\n\\n` +\n\t\t`LOOK at each rendered page image in this message and DATAFY what it shows: for EVERY page ` +\n\t\t`call postRecords and save records - one record per row / table entry / line item visible on the page ` +\n\t\t`(or one record for the page if it is prose), capturing every value you can read (OCR the text, read tables ` +\n\t\t`cell by cell, describe any photos/diagrams). Use the storage path above for the \"src::\" unique_id.\\n\\n` +\n\t\t`Save records for THIS window of pages only, then stop and report what you saved. Do NOT try to read ` +\n\t\t`the rest of the file and do NOT worry about the pages after this window: if any remain, the next window ` +\n\t\t`is rendered and sent to you automatically. Report only the pages you were actually shown - never imply ` +\n\t\t`you have seen the whole document.`\n\t);\n}\n\n/**\n * User message for a WINDOWED file: the worker splices ONE window of the file's rows or\n * text into this message at `placeholder`, then continues from the reader's own cursor\n * until the file is exhausted.\n *\n * The agent is deliberately NOT asked to page the file itself, and is NOT asked to judge\n * whether it is finished. Both used to be its job, and both failed the same way: the\n * traversal lived inside a single turn's budget, so a large file simply stopped partway\n * with a confident summary of the part it had seen.\n */\nexport function buildIndexingWindowMessage(\n\tattachment: IndexingAttachmentInfo,\n\tplaceholder: string,\n\tisContinuation: boolean,\n\tpositionLabel?: string,\n): string {\n\tconst src = `src::${attachment.storagePath}`;\n\tconst head = isContinuation\n\t\t? `CONTINUE indexing a file whose previous pass did not finish.\\n\\n`\n\t\t: `A new file has just been uploaded. Index it now.\\n\\n`;\n\tconst where = isContinuation\n\t\t? `\\nRecords for the earlier windows are ALREADY saved (they reference \"${src}\"). The NEXT window ` +\n\t\t `(starting at ${positionLabel || WINDOW_CURSOR_TOKEN}) is embedded below. Do NOT re-save windows that are already saved.\\n`\n\t\t: `\\nThis file is delivered to you ONE WINDOW at a time, embedded directly in this message. ` +\n\t\t `You do NOT need any tool, URL, or web_fetch to read it.\\n`;\n\n\treturn (\n\t\thead +\n\t\tbuildRenderMeta(attachment) +\n\t\twhere +\n\t\t`\\n${placeholder}\\n\\n` +\n\t\t`DATAFY this window: call postRecords and save records for everything in it - ONE RECORD PER ROW ` +\n\t\t`for tabular data (keyed by the column headers), or one record per section for prose. Capture every ` +\n\t\t`value you can read. Use the storage path above for the \"src::\" unique_id on the file-level record, ` +\n\t\t`and link every row/section record to it by reference.\\n\\n` +\n\t\t`Save records for THIS window only, then stop and report what you saved. Do NOT try to read the rest ` +\n\t\t`of the file, and do NOT call readFileContent - if more remains, the next window is read and sent to ` +\n\t\t`you automatically. Report only what you were actually shown, and never imply you have seen the whole ` +\n\t\t`file when the note beside the window says more remains.`\n\t);\n}\n\n/**\n * User message for a RESUME pass: a previous indexing pass could not finish this large\n * file, so continue it from where the already-saved records leave off (never restart).\n */\nexport function buildIndexingContinueMessage(attachment: IndexingAttachmentInfo): string {\n\tconst src = `src::${attachment.storagePath}`;\n\treturn (\n\t\t`CONTINUE indexing a file whose previous pass did not finish.\\n\\n` +\n\t\t`File metadata:\\n` +\n\t\t`- name: ${attachment.name}\\n` +\n\t\t`- storage path: ${attachment.storagePath}\\n` +\n\t\t(attachment.mime ? `- mime type: ${attachment.mime}\\n` : '') +\n\t\t`\\nRecords for the earlier windows/pages of this file are ALREADY saved (they reference \"${src}\"). ` +\n\t\t`First call getRecords with reference \"${src}\" to see how far the previous pass got (the furthest page/row/window already saved). ` +\n\t\t`Then call readFileContent with the storage path above and a CURSOR that RESUMES just after that point - do NOT start at the beginning. The cursor is derivable from what you already saved:\\n` +\n\t\t` - PDF: the cursor is the NUMBER OF PAGES already read (0-based next page). If you saved up to page N, call readFileContent with cursor=\"N\" to get page N+1 onward.\\n` +\n\t\t` - Spreadsheet: the cursor is \"<sheetIndex>:<nextRow>\" (0-based sheet index, 1-based row). If you saved up to row R of sheet S, use cursor=\"S:R+1\".\\n` +\n\t\t` - Text: the cursor is the character offset already read.\\n` +\n\t\t`Index the REMAINING windows - one record per row/item, looking at any page images or embedded photos - saving as you go until readFileContent reports END OF FILE. ` +\n\t\t`Do NOT re-save windows that are already saved. ` +\n\t\t`Use the storage path above for the \"src::\" unique_id. When the ENTIRE file is finally indexed, end your message with the token INDEXING_COMPLETE.`\n\t);\n}\n","/**\n * Error detection + message extraction (pure). Moved verbatim from the\n * agent.vue / bunnyquery chatbox so both consumers share one implementation.\n */\n\nexport function getErrorMessage(input: any): string {\n\tif (!input) return 'Something went wrong.';\n\tif (typeof input === 'string') return input;\n\tif (input.error && input.error.message) return input.error.message;\n\tif (input.body && input.body.error && input.body.error.message) return input.body.error.message;\n\tif (input.body && typeof input.body.message === 'string') return input.body.message;\n\tif (input.message) return input.message;\n\treturn 'Something went wrong.';\n}\n\nexport function isErrorResponseBody(response: any): boolean {\n\tif (!response || typeof response !== 'object') return false;\n\tif (typeof response.status_code === 'number' && response.status_code >= 400) return true;\n\tif (response.type === 'error') return true;\n\tif (response.error && (response.error.message || response.error.type)) return true;\n\tvar body = response.body;\n\tif (body && typeof body === 'object') {\n\t\tif (body.type === 'error') return true;\n\t\tif (body.error && (body.error.message || body.error.type)) return true;\n\t}\n\tif (typeof response.message === 'string' && response.message.length) {\n\t\tvar hasClaude = Array.isArray(response.content);\n\t\tvar hasOpenAI =\n\t\t\ttypeof response.output_text === 'string' ||\n\t\t\tArray.isArray(response.output) ||\n\t\t\tArray.isArray(response.choices);\n\t\tif (!hasClaude && !hasOpenAI) return true;\n\t}\n\treturn false;\n}\n\n// A request that failed because the REQUEST ITSELF is malformed — an unknown or\n// rejected parameter on a 400/422 — will deterministically re-fail if resent\n// unchanged; no session refresh or retry can fix it. Detecting it lets the retry\n// gates refuse to auto-resend (otherwise a 400 whose param name merely contains\n// \"token\", e.g. `max_output_tokens`, trips the `invalid_request + token` branch\n// of isAuthExpiredError below and loops refresh->resend forever, burning tokens).\n// This is the `_skapi_extract` 400 class. Distinct from auth-expiry, which IS\n// retryable after a token refresh — so 401 (auth) and 429/5xx (transient) are\n// intentionally NOT treated as non-retryable here.\nexport function isNonRetryableRequestError(input: any): boolean {\n\tif (!input || typeof input !== 'object') return false;\n\n\tvar status = typeof input.status_code === 'number' ? input.status_code\n\t\t: typeof input.status === 'number' ? input.status : undefined;\n\n\t// Collect the error envelope wherever it lives (response, response.body, or a\n\t// thrown error), mirroring isErrorResponseBody / isAuthExpiredError.\n\tvar param: any = undefined;\n\tvar blobs: string[] = [];\n\tvar sources = [input.error, input.body && input.body.error, input.body, input];\n\tfor (var i = 0; i < sources.length; i++) {\n\t\tvar e = sources[i];\n\t\tif (!e) continue;\n\t\tif (typeof e === 'string') { blobs.push(e); continue; }\n\t\tif (typeof e !== 'object') continue;\n\t\tif (param === undefined && e.param != null) param = e.param;\n\t\tif (typeof e.code === 'string') blobs.push(e.code);\n\t\tif (typeof e.type === 'string') blobs.push(e.type);\n\t\tif (typeof e.message === 'string') blobs.push(e.message);\n\t}\n\tvar hay = blobs.join(' | ').toLowerCase();\n\n\t// Explicit \"unknown / unsupported parameter\" is always a malformed request.\n\tif (hay.indexOf('unknown_parameter') !== -1 || hay.indexOf('unknown parameter') !== -1 ||\n\t\thay.indexOf('unsupported_parameter') !== -1 || hay.indexOf('unsupported parameter') !== -1) {\n\t\treturn true;\n\t}\n\n\t// A 400/422 invalid_request that points at a specific rejected field: resending\n\t// the identical body re-fails. (401 -> isAuthExpiredError; 429/5xx -> transient.)\n\tvar isClientReqStatus = status === 400 || status === 422;\n\tif (isClientReqStatus && param != null && param !== '') return true;\n\tif (isClientReqStatus && hay.indexOf('invalid_request') !== -1 &&\n\t\t(hay.indexOf('parameter') !== -1 || hay.indexOf('param') !== -1)) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport function isAuthExpiredError(input: any): boolean {\n\tif (!input) return false;\n\tvar blobs: string[] = [];\n\tvar push = function (v: any) { if (typeof v === 'string' && v) blobs.push(v); };\n\tif (typeof input === 'string') push(input);\n\telse {\n\t\tpush(input.message); push(input.code);\n\t\tif (input.error) { push(input.error.message); push(input.error.code); push(input.error.type); }\n\t\tif (input.body) {\n\t\t\tpush(input.body.message);\n\t\t\tif (input.body.error) { push(input.body.error.message); push(input.body.error.code); push(input.body.error.type); }\n\t\t}\n\t\tif (typeof input.status === 'number' && input.status === 401) return true;\n\t\tif (typeof input.status_code === 'number' && input.status_code === 401) return true;\n\t}\n\tvar hay = blobs.join(' | ').toLowerCase();\n\tif (!hay) return false;\n\treturn hay.indexOf('token has expired') !== -1 || hay.indexOf('token is expired') !== -1 ||\n\t\thay.indexOf('expired_token') !== -1 || hay.indexOf('invalid_token') !== -1 ||\n\t\thay.indexOf('unauthorized') !== -1 || hay.indexOf('not authorized') !== -1 ||\n\t\t(hay.indexOf('invalid_request') !== -1 && hay.indexOf('token') !== -1);\n}\n","/**\n * Pure link/path helpers (no DOM, no marked). Moved verbatim from the chatbox.\n * `serviceId` is passed as a PARAMETER (the original read it from a global) so\n * the engine stays consumer-agnostic. The HTML-emitting helpers\n * (buildLinkPartFromGroups, linkToAnchorHtml, fileToAnchorHtml, parseMsgParts*)\n * stay in each VIEW — only these pure pieces move here.\n */\n\nexport var EXPIRED_ATTACHMENT_URL_HOST = '_expired_.url';\nexport var EXPIRED_ATTACHMENT_URL_ORIGIN = 'https://' + EXPIRED_ATTACHMENT_URL_HOST;\nexport var LINK_LABEL_MAX_DISPLAY_CHARS = 32;\n\nexport function createInlineLinkRegex(): RegExp {\n\treturn /src::(\\S+)|\\[([^\\]\\n]+)\\]\\((https?:\\/\\/(?:[^\\s()]+|\\([^\\s()]*\\))+)\\)|\\[([^\\]\\n]+)\\]\\(((?:[^()\\n]+|\\([^()\\n]*\\))+)\\)|(https?:\\/\\/[^\\s<>\"']+)/g;\n}\n\nexport function safeDecodeURIComponent(v: string): string {\n\ttry { return decodeURIComponent(v); } catch (e) { return v; }\n}\n\nexport function encodePathSegments(path: string): string {\n\treturn path.split('/').filter(Boolean).map(function (s) { return encodeURIComponent(s); }).join('/');\n}\n\nexport function normalizeAttachmentPathCandidate(value: string): string {\n\treturn safeDecodeURIComponent((value || '').trim()).replace(/\\\\/g, '/').replace(/^\\/+/, '').replace(/\\/+/g, '/');\n}\n\nexport function extractRemotePathFromAttachmentHref(href: string, serviceId: string): string | null {\n\ttry {\n\t\tvar parsed = new URL(href);\n\t\tif (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return null;\n\t\tvar path = normalizeAttachmentPathCandidate(parsed.pathname || '');\n\t\tvar segs = path.split('/').filter(Boolean);\n\t\tif (!segs.length) return null;\n\t\tvar HEX = /^[a-f0-9]{32,}$/i;\n\t\tvar sid = serviceId || '';\n\t\tvar start = 0;\n\t\twhile (start < segs.length) {\n\t\t\tvar seg = segs[start];\n\t\t\tif (seg === sid || HEX.test(seg)) { start++; continue; }\n\t\t\tbreak;\n\t\t}\n\t\tvar real = segs.slice(start).join('/');\n\t\treturn real || null;\n\t} catch (e) { return null; }\n}\n\nexport function getExpiredAttachmentVisiblePath(remotePath: string, fallback?: string): string {\n\tvar n = normalizeAttachmentPathCandidate(remotePath);\n\tif (n) return n;\n\treturn normalizeAttachmentPathCandidate(fallback || 'file') || 'file';\n}\n\nexport function buildDisplayExpiredAttachmentHref(remotePath: string, fallback?: string): string {\n\treturn EXPIRED_ATTACHMENT_URL_ORIGIN + '/' + encodePathSegments(getExpiredAttachmentVisiblePath(remotePath, fallback));\n}\n\n// Does `href` point at THIS service's db attachment storage? A db attachment URL's\n// path always begins with the serviceId segment (…/<serviceId>/<hash>/<path>). Used\n// to SAFELY sanitize assistant messages — where an arbitrary external citation URL\n// must never be rewritten, only the service's own volatile db links.\nexport function isServiceDbAttachmentHref(href: string, serviceId: string): boolean {\n\tif (!serviceId) return false;\n\ttry {\n\t\tvar parsed = new URL(href);\n\t\tif (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return false;\n\t\tvar segs = normalizeAttachmentPathCandidate(parsed.pathname || '').split('/').filter(Boolean);\n\t\treturn segs.length > 0 && segs[0] === serviceId;\n\t} catch (e) { return false; }\n}\n\n// Replace volatile attachment URLs with their durable `_expired_.url/<path>`\n// placeholder so a stored/replayed copy re-mints on demand instead of going stale.\n// USER turns: the \"Attached files:\" block gates the (broad) rewrite — every url\n// there is a db link. ASSISTANT turns (forAssistant=true): no marker exists and the\n// text may contain external citation urls, so restrict the rewrite to THIS\n// service's db attachment urls and leave every other link untouched.\nexport function sanitizeAttachmentLinksForHistory(content: string, serviceId: string, forAssistant?: boolean): string {\n\tif (!content) return content;\n\tif (!forAssistant && content.indexOf('Attached files:') === -1) return content;\n\treturn content.replace(/\\[([^\\]\\n]+)\\]\\((https?:\\/\\/[^\\s)]+)\\)/g, function (_m: string, label: string, href: string) {\n\t\tif (forAssistant && !isServiceDbAttachmentHref(href, serviceId)) return _m;\n\t\tvar remotePath = extractRemotePathFromAttachmentHref(href, serviceId);\n\t\tvar labelPath = normalizeAttachmentPathCandidate(label);\n\t\tvar fullPath = remotePath || labelPath;\n\t\tif (!fullPath) return forAssistant ? _m : '[' + label + '](' + EXPIRED_ATTACHMENT_URL_ORIGIN + '/file)';\n\t\treturn '[' + label + '](' + buildDisplayExpiredAttachmentHref(fullPath, label) + ')';\n\t});\n}\n\nexport function truncateLabelForDisplay(label: string): string {\n\tif (!label) return label;\n\tif (label.length <= LINK_LABEL_MAX_DISPLAY_CHARS) return label;\n\treturn '…' + label.slice(label.length - (LINK_LABEL_MAX_DISPLAY_CHARS - 1));\n}\n","/**\n * Token-budgeting (pure). Moved verbatim from the chatbox. Constants are shared\n * module-level values (identical in both consumers); a config knob is premature.\n * buildBoundedChatMessages now takes `serviceId` in its options so it can pass it\n * to sanitizeAttachmentLinksForHistory (which used to read a global).\n */\nimport { sanitizeAttachmentLinksForHistory } from './links';\n\nexport var CONTEXT_WINDOW_DEFAULT: Record<string, number> = { claude: 200000, openai: 128000 };\nexport var CONTEXT_WINDOW_BY_MODEL: Record<string, number> = {\n\t'claude-opus-4-7': 200000, 'claude-sonnet-4': 200000, 'gpt-5.4': 128000,\n};\nexport var OUTPUT_TOKEN_RESERVE = 22000;\nexport var TOOL_AND_RESPONSE_BUFFER = 4000;\nexport var MIN_INPUT_TOKEN_BUDGET = 8000;\nexport var CLAUDE_PER_REQUEST_INPUT_CAP = 28000;\nexport var MAX_HISTORY_MESSAGES = 20;\nexport var HISTORY_TOKEN_BUDGET = 8000;\n\nexport function estimateTextTokens(text: string): number {\n\treturn Math.ceil((text || '').length / 3);\n}\n\nexport function estimateMessageTokens(msg: { role: string; content: string }): number {\n\treturn estimateTextTokens(msg.content) + estimateTextTokens(msg.role) + 6;\n}\n\nexport function getContextWindow(platform: string, model?: string): number {\n\tvar normalized = (model || '').trim().toLowerCase();\n\tif (normalized && CONTEXT_WINDOW_BY_MODEL[normalized]) return CONTEXT_WINDOW_BY_MODEL[normalized];\n\treturn CONTEXT_WINDOW_DEFAULT[platform];\n}\n\nexport function stripFileBlocksFromHistory(content: string): string {\n\tif (!content) return content;\n\treturn content.replace(/```([^\\n`]+?\\.[^\\s.`]+)\\n[\\s\\S]*?```/g, '[file previously attached: $1]');\n}\n\nexport type BoundedChatOptions = {\n\tplatform: string;\n\tmodel?: string;\n\tsystemPrompt: string;\n\thistory: Array<{ role: string; content: string }>;\n\t/** Used to strip/rewrite expired attachment links in older user turns. */\n\tserviceId: string;\n};\n\nexport function buildBoundedChatMessages(options: BoundedChatOptions) {\n\tvar contextWindow = getContextWindow(options.platform, options.model);\n\tvar contextBasedBudget = Math.max(MIN_INPUT_TOKEN_BUDGET,\n\t\tcontextWindow - OUTPUT_TOKEN_RESERVE - TOOL_AND_RESPONSE_BUFFER);\n\tvar availableInputBudget = options.platform === 'claude'\n\t\t? Math.min(contextBasedBudget, CLAUDE_PER_REQUEST_INPUT_CAP) : contextBasedBudget;\n\tvar systemCost = estimateTextTokens(options.systemPrompt) + 12;\n\tvar budgetForHistory = Math.max(1000, Math.min(HISTORY_TOKEN_BUDGET, availableInputBudget - systemCost));\n\tvar windowed = options.history.slice(-MAX_HISTORY_MESSAGES);\n\tvar latestIndex = windowed.length - 1;\n\tvar trimmed = windowed.map(function (m, i) {\n\t\tif (i === latestIndex) return m;\n\t\tvar stripped = stripFileBlocksFromHistory(m.content);\n\t\t// Sanitize BOTH roles: user turns via the \"Attached files:\" block, assistant\n\t\t// turns via the safe db-only path (forAssistant=true) so a volatile db url the\n\t\t// model emitted doesn't get replayed into the LLM context as a dead link.\n\t\tvar sanitized = sanitizeAttachmentLinksForHistory(stripped, options.serviceId, m.role !== 'user');\n\t\treturn Object.assign({}, m, { content: sanitized });\n\t});\n\tvar bounded: Array<{ role: string; content: string }> = [], used = 0;\n\tfor (var i = trimmed.length - 1; i >= 0; i--) {\n\t\tvar cost = estimateMessageTokens(trimmed[i]);\n\t\tif (used + cost > budgetForHistory && bounded.length > 0) break;\n\t\tbounded.unshift(trimmed[i]); used += cost;\n\t}\n\treturn {\n\t\tmessages: bounded.map(function (m) { return { role: m.role, content: m.content }; }),\n\t\tdroppedCount: Math.max(0, options.history.length - bounded.length),\n\t\testimatedInputTokens: used + systemCost,\n\t\testimatedBudget: availableInputBudget,\n\t};\n}\n","/**\n * AI request builders + dispatch transport (framework-agnostic).\n *\n * Ported from www.skapi.com/src/code/ai_agent.ts. The only changes vs the\n * original are dependency-injection seams:\n * - `skapi.clientSecretRequest*` -> chatEngineConfig().clientSecretRequest*\n * - MCP endpoint URL -> chatEngineConfig().mcpBaseUrl\n * - `poll` on each request -> pollOpt() (set per consumer; see config.ts)\n * - Vue `reactive`/`ref` removed (bgTaskQueue/agentViewMounted are app-level\n * state that stays in the consumer, not here;\n * only the BgTaskEntry TYPE lives here)\n */\nimport { buildIndexingSystemPrompt, buildIndexingUserMessage, buildIndexingContinueMessage, buildIndexingRenderMessage, buildIndexingRenderContinueTemplate, buildIndexingWindowMessage } from './prompts';\nimport { isServerExtractable, isPagedReadFile, isImageVisionFile, isWindowedReadFile, makeExtractPlaceholder, makeRenderPlaceholder, makeWindowPlaceholder, RENDER_PAGES_PER_WINDOW, type ExtractDirective, type FileUrlDirective } from './office';\nimport { chatEngineConfig, pollOpt, windowedIndexingEnabled } from './config';\n\nexport const ANTHROPIC_MESSAGES_API_URL = 'https://api.anthropic.com/v1/messages';\nconst ANTHROPIC_MODELS_API_URL = 'https://api.anthropic.com/v1/models';\nconst ANTHROPIC_VERSION = '2023-06-01';\nconst ANTHROPIC_MCP_BETA = 'mcp-client-2025-11-20';\nconst ANTHROPIC_WEB_FETCH_BETA = 'web-fetch-2025-09-10';\nconst ANTHROPIC_PROMPT_CACHING_BETA = 'prompt-caching-2024-07-31';\nconst ANTHROPIC_BETA_HEADER = `${ANTHROPIC_MCP_BETA},${ANTHROPIC_WEB_FETCH_BETA},${ANTHROPIC_PROMPT_CACHING_BETA}`;\nconst WEB_FETCH_MAX_USES = 40;\nconst WEB_FETCH_MAX_CONTENT_TOKENS = 200000;\n\nexport const OPENAI_RESPONSES_API_URL = 'https://api.openai.com/v1/responses';\nconst OPENAI_MODELS_API_URL = 'https://api.openai.com/v1/models';\nconst MAX_TOKENS = 25000;\nconst DEFAULT_OPENAI_IMAGE_DETAIL = 'auto';\nconst OPENAI_WEB_SEARCH_ENABLED = true;\nconst OPENAI_WEB_SEARCH_EXTERNAL_WEB_ACCESS = true;\nexport const MCP_NAME = 'BunnyQuery';\n\nexport const DEFAULT_CLAUDE_MODEL = 'claude-sonnet-4-6';\nexport const DEFAULT_OPENAI_MODEL = 'gpt-5.4';\n\nconst mcpUrl = () => chatEngineConfig().mcpBaseUrl;\nconst clientSecretRequest = (opts: any) => chatEngineConfig().clientSecretRequest(opts);\n\n// Resolve the per-image `detail` for OpenAI. The version match tolerates a\n// trailing variant/date suffix (`gpt-5.4-nano`, `-mini`, `-2026-01-01`, …):\n// previously the pattern was anchored with no suffix allowed, so EVERY suffixed\n// model silently fell through to 'auto' — i.e. the cheap tiers that most need\n// resolution were the ones getting downsampled images.\n//\n// Base models keep their exact previous behavior ('original'). A suffixed\n// variant resolves to 'high' rather than 'original': 'high' is the universally\n// supported value, and we have no way to confirm a given variant accepts\n// 'original' — sending an unsupported value would fail the whole request, which\n// is far worse than a slightly less detailed image.\nconst getOpenAIImageDetail = (model?: string) => {\n\tconst normalized = (model || DEFAULT_OPENAI_MODEL).trim().toLowerCase();\n\tconst match = normalized.match(/^gpt-(\\d+)(?:\\.(\\d+))?(-[a-z0-9.\\-]+)?$/);\n\tif (!match) {\n\t\treturn DEFAULT_OPENAI_IMAGE_DETAIL;\n\t}\n\n\tconst major = Number(match[1]);\n\tconst minor = match[2] === undefined ? null : Number(match[2]);\n\tconst isVariant = !!match[3];\n\n\tconst supportsOriginal = major > 5 || (major === 5 && minor !== null && minor >= 4);\n\tif (!supportsOriginal) {\n\t\treturn DEFAULT_OPENAI_IMAGE_DETAIL;\n\t}\n\n\treturn isVariant ? 'high' : 'original';\n};\n\n// Per-image `detail` for WORKER-RENDERED document pages (the `_skapi_render`\n// path). Same resolution as above with one difference: these are dense scans\n// whose entire purpose is to be read, so 'auto' is never acceptable — it lets\n// the API downsample exactly the pixels the model needs to OCR. Floor it at\n// 'high'; models that support full-resolution 'original' still get it.\n//\n// Without this the worker falls back to its own model-blind default ('high'),\n// which silently denies the strongest models the 'original' detail they support.\nconst getRenderImageDetail = (model?: string) => {\n\tconst detail = getOpenAIImageDetail(model);\n\treturn detail === DEFAULT_OPENAI_IMAGE_DETAIL ? 'high' : detail;\n};\n\nexport type ClaudeRole = 'user' | 'assistant';\n\nexport type ClaudeMessage = {\n\trole: ClaudeRole;\n\tcontent: string;\n};\n\nexport type OpenAIMessage = {\n\trole: ClaudeRole;\n\tcontent: string;\n};\n\nexport type ClaudeMcpToolConfig = {\n\tenabled?: boolean;\n\tdefer_loading?: boolean;\n};\n\nexport type ClaudeMcpServerRequest = {\n\tname: string;\n\turl: string;\n\tauthorizationToken?: string;\n\tdefaultConfig?: ClaudeMcpToolConfig;\n\tconfigs?: Record<string, ClaudeMcpToolConfig>;\n};\n\nconst IMAGE_URL_REGEX =\n\t/\\bhttps?:\\/\\/[^\\s<>\"'()\\[\\]]+?\\.(?:jpg|jpeg|png|gif|webp)(?:\\?[^\\s<>\"'()\\[\\]]*)?/gi;\n\nexport function transformContentWithImages(\n\tcontent: string,\n): string | Array<Record<string, any>> {\n\tif (typeof content !== 'string' || !content) {\n\t\treturn content;\n\t}\n\n\tconst matches = content.match(IMAGE_URL_REGEX);\n\n\tif (!matches || !matches.length) {\n\t\treturn content;\n\t}\n\n\tconst seen = new Set<string>();\n\tconst imageBlocks: Array<Record<string, any>> = [];\n\n\tfor (const url of matches) {\n\t\tif (seen.has(url)) continue;\n\t\tseen.add(url);\n\t\timageBlocks.push({\n\t\t\ttype: 'image',\n\t\t\tsource: { type: 'url', url },\n\t\t});\n\t}\n\n\treturn [...imageBlocks, { type: 'text', text: content }];\n}\n\nfunction prepareClaudeMessages(messages: ClaudeMessage[]) {\n\tif (!messages.length) return messages;\n\t// Only transform the most recent user message. Historical user messages\n\t// may reference image URLs that are now stale (deleted, moved, expired).\n\tconst lastIndex = messages.length - 1;\n\tconst last = messages[lastIndex];\n\tif (last.role !== 'user') return messages;\n\tconst content = transformContentWithImages(last.content);\n\tif (content === last.content) return messages;\n\tconst next = messages.slice();\n\tnext[lastIndex] = { role: last.role, content } as unknown as ClaudeMessage;\n\treturn next;\n}\n\nexport function transformContentWithOpenAIImages(\n\tcontent: string,\n\tdetail = DEFAULT_OPENAI_IMAGE_DETAIL,\n): string | Array<Record<string, any>> {\n\tif (typeof content !== 'string' || !content) {\n\t\treturn content;\n\t}\n\n\tconst matches = content.match(IMAGE_URL_REGEX);\n\n\tif (!matches || !matches.length) {\n\t\treturn content;\n\t}\n\n\tconst seen = new Set<string>();\n\tconst imageBlocks: Array<Record<string, any>> = [];\n\n\tfor (const url of matches) {\n\t\tif (seen.has(url)) continue;\n\t\tseen.add(url);\n\t\timageBlocks.push({\n\t\t\ttype: 'input_image',\n\t\t\timage_url: url,\n\t\t\tdetail,\n\t\t});\n\t}\n\n\treturn [{ type: 'input_text', text: content }, ...imageBlocks];\n}\n\nfunction prepareOpenAIMessages(\n\tmessages: OpenAIMessage[],\n\tdetail = DEFAULT_OPENAI_IMAGE_DETAIL,\n) {\n\tif (!messages.length) return messages;\n\tconst lastIndex = messages.length - 1;\n\tconst last = messages[lastIndex];\n\tif (last.role !== 'user') return messages;\n\tconst content = transformContentWithOpenAIImages(last.content, detail);\n\tif (content === last.content) return messages;\n\tconst next = messages.slice();\n\tnext[lastIndex] = { role: last.role, content } as unknown as OpenAIMessage;\n\treturn next;\n}\n\n// Attach a cache_control breakpoint to the last message of the stable history\n// prefix (everything except the final user turn) so Anthropic re-uses it at\n// ~10% input-token billing.\nfunction applyHistoryCacheBreakpoint(messages: any[]): any[] {\n\tif (messages.length < 2) return messages;\n\tconst breakpointIndex = messages.length - 2;\n\treturn messages.map((m, i) => {\n\t\tif (i !== breakpointIndex) return m;\n\t\tconst blocks = Array.isArray(m.content)\n\t\t\t? m.content.slice()\n\t\t\t: [{ type: 'text', text: m.content }];\n\t\tif (!blocks.length) return m;\n\t\tconst lastBlockIndex = blocks.length - 1;\n\t\tblocks[lastBlockIndex] = {\n\t\t\t...blocks[lastBlockIndex],\n\t\t\tcache_control: { type: 'ephemeral' },\n\t\t};\n\t\treturn { ...m, content: blocks };\n\t});\n}\n\nexport type CallClaudeWithMcpParams = {\n\tprompt: string;\n\tmessages?: ClaudeMessage[];\n\tservice: string;\n\towner: string;\n\tuserId?: string;\n\tmodel?: string;\n\tmaxTokens?: number;\n\tsystem?: string;\n\tmcpServer: ClaudeMcpServerRequest;\n\textractContent?: ExtractDirective[];\n\tfileUrls?: FileUrlDirective[];\n\tonResponse?: (res: any) => void;\n\tonError?: (err: any) => void;\n};\nexport const POLL_INTERVAL = 1500;\nexport async function callClaudeWithMcp({\n\tprompt,\n\tmessages,\n\tservice,\n\towner,\n\tuserId,\n\tmodel = DEFAULT_CLAUDE_MODEL,\n\tmaxTokens = 1000,\n\tsystem,\n\tmcpServer,\n\textractContent,\n\tfileUrls,\n}: CallClaudeWithMcpParams) {\n\tconst mcpServerDefinition: Record<string, any> = {\n\t\ttype: 'url',\n\t\tname: mcpServer.name,\n\t\turl: mcpServer.url,\n\t};\n\n\tif (mcpServer.authorizationToken) {\n\t\tmcpServerDefinition.authorization_token = mcpServer.authorizationToken;\n\t}\n\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'claude',\n\t\tqueue: userId || service,\n\t\tservice,\n\t\towner,\n\t\t...pollOpt(),\n\t\turl: ANTHROPIC_MESSAGES_API_URL,\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\t'content-type': 'application/json',\n\t\t\t'x-api-key': '$CLIENT_SECRET',\n\t\t\t'anthropic-version': ANTHROPIC_VERSION,\n\t\t\t'anthropic-beta': ANTHROPIC_BETA_HEADER,\n\t\t},\n\t\tdata: {\n\t\t\tmodel,\n\t\t\tmax_tokens: maxTokens,\n\t\t\t...(extractContent && extractContent.length\n\t\t\t\t? { _skapi_extract: extractContent }\n\t\t\t\t: {}),\n\t\t\t...(fileUrls && fileUrls.length\n\t\t\t\t? { _skapi_file_urls: fileUrls }\n\t\t\t\t: {}),\n\t\t\t...(system\n\t\t\t\t? {\n\t\t\t\t\t\tsystem: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\t\ttext: system,\n\t\t\t\t\t\t\t\tcache_control: { type: 'ephemeral' },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\tmessages: (() => {\n\t\t\t\tconst prepared =\n\t\t\t\t\tmessages && messages.length\n\t\t\t\t\t\t? prepareClaudeMessages(messages)\n\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\trole: 'user',\n\t\t\t\t\t\t\t\t\tcontent: transformContentWithImages(prompt),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t];\n\t\t\t\treturn applyHistoryCacheBreakpoint(prepared as any[]);\n\t\t\t})(),\n\t\t\tmcp_servers: [mcpServerDefinition],\n\t\t\ttools: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'mcp_toolset',\n\t\t\t\t\tmcp_server_name: mcpServer.name,\n\t\t\t\t\t...(mcpServer.defaultConfig\n\t\t\t\t\t\t? { default_config: mcpServer.defaultConfig }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t...(mcpServer.configs ? { configs: mcpServer.configs } : {}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'web_fetch_20250910',\n\t\t\t\t\tname: 'web_fetch',\n\t\t\t\t\tmax_uses: WEB_FETCH_MAX_USES,\n\t\t\t\t\tcitations: { enabled: true },\n\t\t\t\t\tmax_content_tokens: WEB_FETCH_MAX_CONTENT_TOKENS,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t});\n}\n\nexport async function callClaudeWithPublicMcp(\n\tprompt: string,\n\tservice: string,\n\towner: string,\n\tmessages?: ClaudeMessage[],\n\tsystem?: string,\n\tmodel?: string,\n\tuserId?: string,\n\textractContent?: ExtractDirective[],\n\tfileUrls?: FileUrlDirective[],\n\tonResponse?: (res: any) => void,\n\tonError?: (err: any) => void,\n) {\n\treturn callClaudeWithMcp({\n\t\tprompt,\n\t\tmessages,\n\t\tservice,\n\t\towner,\n\t\tuserId,\n\t\tmodel: model || DEFAULT_CLAUDE_MODEL,\n\t\tmaxTokens: MAX_TOKENS,\n\t\tsystem,\n\t\textractContent,\n\t\tfileUrls,\n\t\tmcpServer: {\n\t\t\tname: MCP_NAME,\n\t\t\turl: mcpUrl(),\n\t\t\tauthorizationToken: '$ACCESS_TOKEN',\n\t\t},\n\t\tonResponse,\n\t\tonError,\n\t});\n}\n\nexport async function callOpenAIWithPublicMcp(\n\tprompt: string,\n\tservice: string,\n\towner: string,\n\tmessages?: OpenAIMessage[],\n\tsystem?: string,\n\tmodel?: string,\n\tuserId?: string,\n\textractContent?: ExtractDirective[],\n\tfileUrls?: FileUrlDirective[],\n\tonResponse?: (res: any) => void,\n\tonError?: (err: any) => void,\n) {\n\tconst resolvedModel = model || DEFAULT_OPENAI_MODEL;\n\tconst imageDetail = getOpenAIImageDetail(resolvedModel);\n\tconst messageList =\n\t\tmessages && messages.length\n\t\t\t? prepareOpenAIMessages(messages, imageDetail)\n\t\t\t: [\n\t\t\t\t{\n\t\t\t\t\trole: 'user' as const,\n\t\t\t\t\tcontent: transformContentWithOpenAIImages(prompt, imageDetail),\n\t\t\t\t},\n\t\t\t];\n\n\tconst responseInput = [\n\t\t...(system\n\t\t\t? [\n\t\t\t\t{\n\t\t\t\t\trole: 'system',\n\t\t\t\t\tcontent: system,\n\t\t\t\t},\n\t\t\t]\n\t\t\t: []),\n\t\t...messageList.map((m) => ({\n\t\t\trole: m.role,\n\t\t\tcontent: m.content,\n\t\t})),\n\t];\n\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'openai',\n\t\tqueue: userId || service,\n\t\tservice,\n\t\towner,\n\t\t...pollOpt(),\n\t\turl: OPENAI_RESPONSES_API_URL,\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\t'content-type': 'application/json',\n\t\t\tAuthorization: 'Bearer $CLIENT_SECRET',\n\t\t},\n\t\tdata: {\n\t\t\tmodel: resolvedModel,\n\t\t\tmax_output_tokens: MAX_TOKENS,\n\t\t\t...(extractContent && extractContent.length\n\t\t\t\t? { _skapi_extract: extractContent }\n\t\t\t\t: {}),\n\t\t\t...(fileUrls && fileUrls.length\n\t\t\t\t? { _skapi_file_urls: fileUrls }\n\t\t\t\t: {}),\n\t\t\tinput: responseInput,\n\t\t\ttools: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'mcp',\n\t\t\t\t\tserver_label: MCP_NAME,\n\t\t\t\t\tserver_url: mcpUrl(),\n\t\t\t\t\trequire_approval: 'never',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: 'Bearer $ACCESS_TOKEN',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t...(OPENAI_WEB_SEARCH_ENABLED\n\t\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'web_search',\n\t\t\t\t\t\t\texternal_web_access: OPENAI_WEB_SEARCH_EXTERNAL_WEB_ACCESS,\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t],\n\t\t},\n\t});\n}\n\nexport type AttachmentSaveInfo = {\n\tplatform: 'claude' | 'openai';\n\tmodel?: string;\n\tservice: string;\n\towner: string;\n\tuserId?: string;\n\tserviceName?: string;\n\tserviceDescription?: string;\n\tattachment: {\n\t\tname: string;\n\t\tstoragePath: string;\n\t\tmime?: string;\n\t\tsize?: number;\n\t\turl: string;\n\t};\n\t/**\n\t * Content parsed CLIENT-SIDE by an attachment-parser plugin (e.g. an .hwp\n\t * parser). When set, it is inlined into the indexing message verbatim and\n\t * takes precedence over server-side office extraction / web_fetch.\n\t */\n\tparsedContent?: string;\n\t/**\n\t * True for a RESUME pass: a previous indexing pass could not finish this (large)\n\t * file, so continue it - always via readFileContent paging, with a \"continue\"\n\t * message telling the agent to resume from where the saved records leave off.\n\t */\n\tcontinueIndexing?: boolean;\n\t/**\n\t * For an image-vision file (PDF), the 0-based PAGE the render window should start at.\n\t * The worker renders [renderFrom, renderFrom+RENDER_PAGES_PER_WINDOW) and injects them\n\t * as image blocks; the resume loop advances this by a window each pass.\n\t */\n\trenderFrom?: number;\n};\n\n// RESUME pass: continue indexing a large file a previous pass could not finish. Same\n// dispatch as notifyAgentSaveAttachment, but forced onto the paging path with a\n// \"continue from where the saved records leave off\" message.\nexport async function notifyAgentContinueIndexing(info: AttachmentSaveInfo) {\n\treturn notifyAgentSaveAttachment({ ...info, continueIndexing: true });\n}\n\n// Background \"save into knowledge\" call (not a chat turn). A client-parsed file\n// (parser plugin) is inlined directly; otherwise office files get the\n// _skapi_extract directive + a placeholder, and everything else gets a URL.\nexport async function notifyAgentSaveAttachment(info: AttachmentSaveInfo) {\n\tconst { platform, service, owner, attachment, parsedContent } = info;\n\n\t// A CONTINUE pass resumes a large file that a previous pass could not finish.\n\tconst continuing = !!info.continueIndexing;\n\n\t// VISION files (PDFs) are delivered as rendered page IMAGES injected into the message by\n\t// the worker (`_skapi_render`), because tool-result images render on neither provider.\n\t// Both the first pass and every resume pass use this; renderFrom advances the page window.\n\tconst visionFile = !parsedContent && isImageVisionFile(attachment.name, attachment.mime);\n\tconst renderFrom = Math.max(0, info.renderFrom || 0);\n\tconst renderPlaceholder = visionFile ? makeRenderPlaceholder(attachment.storagePath) : undefined;\n\t// Tell the worker what image `detail` to stamp on the injected page blocks.\n\t// The worker is model-blind, so without this it applies a one-size default and\n\t// the strongest models never get the 'original' detail they support. Only\n\t// meaningful for OpenAI — Claude has no per-image detail knob and the worker\n\t// ignores the field for it.\n\tconst renderDetail = platform === 'openai'\n\t\t? getRenderImageDetail(info.model || DEFAULT_OPENAI_MODEL)\n\t\t: undefined;\n\t// `auto_continue` + `continue_text` hand the page loop to the WORKER: when its renderer\n\t// reports pages left after this window, it builds the next pass from this template\n\t// (substituting the window's 1-based start page for RENDER_FROM_TOKEN) and enqueues it\n\t// itself. That is what makes a 500-page document index end-to-end — the loop no longer\n\t// depends on the tab staying open, nor on the model correctly declaring itself unfinished.\n\tconst skapiRender = visionFile && renderPlaceholder\n\t\t? {\n\t\t\t_skapi_render: [\n\t\t\t\t{\n\t\t\t\t\tpath: attachment.storagePath, from: renderFrom, count: RENDER_PAGES_PER_WINDOW,\n\t\t\t\t\tplaceholder: renderPlaceholder, name: attachment.name, mime: attachment.mime, detail: renderDetail,\n\t\t\t\t\tauto_continue: true,\n\t\t\t\t\tcontinue_text: buildIndexingRenderContinueTemplate(attachment, renderPlaceholder),\n\t\t\t\t},\n\t\t\t],\n\t\t}\n\t\t: {};\n\n\t// SERVER-DRIVEN windowed read. When enabled, the worker reads one window of the file\n\t// per request and continues from the reader's own cursor until the file is exhausted,\n\t// so the traversal no longer lives inside the model's turn budget.\n\t//\n\t// Flag-gated because the BACKEND MUST SHIP FIRST: against a worker that does not strip\n\t// `_skapi_window`, the directive reaches the provider as an unknown body field and the\n\t// call fails terminally with no retry.\n\tconst windowedRead =\n\t\t!visionFile && !parsedContent && windowedIndexingEnabled() &&\n\t\tisWindowedReadFile(attachment.name, attachment.mime);\n\tconst windowPlaceholder = windowedRead ? makeWindowPlaceholder(attachment.storagePath) : undefined;\n\tconst skapiWindow = windowedRead && windowPlaceholder\n\t\t? {\n\t\t\t_skapi_window: [\n\t\t\t\t{\n\t\t\t\t\tpath: attachment.storagePath,\n\t\t\t\t\tcursor: null,\n\t\t\t\t\tplaceholder: windowPlaceholder,\n\t\t\t\t\tname: attachment.name,\n\t\t\t\t\tmime: attachment.mime,\n\t\t\t\t\tkind: 'window',\n\t\t\t\t\tauto_continue: true,\n\t\t\t\t\tcontinue_text: buildIndexingWindowMessage(attachment, windowPlaceholder, true),\n\t\t\t\t},\n\t\t\t],\n\t\t}\n\t\t: {};\n\n\t// Spreadsheets are read by PAGING through readFileContent (grid rows), NOT inlined - so\n\t// they skip the inline server-extract and the agent is told to page the whole file.\n\tconst pagedRead = !visionFile && !windowedRead && (continuing || (!parsedContent && isPagedReadFile(attachment.name, attachment.mime)));\n\n\t// Client-parsed content wins over server-side extraction.\n\tconst serverExtract = !visionFile && !windowedRead && !continuing && !parsedContent && !pagedRead && isServerExtractable(attachment.name, attachment.mime);\n\tconst placeholder = serverExtract ? makeExtractPlaceholder(attachment.storagePath) : undefined;\n\tconst extractContent: ExtractDirective[] | undefined =\n\t\tserverExtract && placeholder\n\t\t\t? [{ path: attachment.storagePath, placeholder, name: attachment.name, mime: attachment.mime }]\n\t\t\t: undefined;\n\tconst skapiExtract =\n\t\textractContent && extractContent.length ? { _skapi_extract: extractContent } : {};\n\n\tconst userMessage = (visionFile && renderPlaceholder)\n\t\t? buildIndexingRenderMessage(attachment, renderPlaceholder, renderFrom)\n\t\t: (windowedRead && windowPlaceholder)\n\t\t? buildIndexingWindowMessage(attachment, windowPlaceholder, false)\n\t\t: continuing\n\t\t\t? buildIndexingContinueMessage(attachment)\n\t\t\t: buildIndexingUserMessage(\n\t\t\t\tattachment,\n\t\t\t\tparsedContent\n\t\t\t\t\t? { inlineContent: parsedContent }\n\t\t\t\t\t: placeholder\n\t\t\t\t\t\t? { inlineContentPlaceholder: placeholder }\n\t\t\t\t\t\t: pagedRead\n\t\t\t\t\t\t\t? { pagedRead: true }\n\t\t\t\t\t\t\t: undefined,\n\t\t\t);\n\n\tconst systemPrompt = buildIndexingSystemPrompt({\n\t\tservice,\n\t\tserviceName: info.serviceName,\n\t\tserviceDescription: info.serviceDescription,\n\t});\n\n\tif (platform === 'openai') {\n\t\tconst resolvedModel = info.model || DEFAULT_OPENAI_MODEL;\n\t\tconst imageDetail = getOpenAIImageDetail(resolvedModel);\n\t\treturn clientSecretRequest({\n\t\t\tclientSecretName: 'openai',\n\t\t\tqueue: (info.userId || service) + BG_INDEXING_QUEUE_SUFFIX,\n\t\t\tservice,\n\t\t\towner,\n\t\t\t...pollOpt(),\n\t\t\turl: OPENAI_RESPONSES_API_URL,\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'content-type': 'application/json',\n\t\t\t\tAuthorization: 'Bearer $CLIENT_SECRET',\n\t\t\t},\n\t\t\tdata: {\n\t\t\t\tmodel: resolvedModel,\n\t\t\t\tmax_output_tokens: MAX_TOKENS,\n\t\t\t\t...skapiExtract,\n\t\t\t\t...skapiRender,\n\t\t\t\t...skapiWindow,\n\t\t\t\tinput: [\n\t\t\t\t\t{ role: 'system', content: systemPrompt },\n\t\t\t\t\t{\n\t\t\t\t\t\trole: 'user',\n\t\t\t\t\t\tcontent: transformContentWithOpenAIImages(userMessage, imageDetail),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\ttools: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'mcp',\n\t\t\t\t\t\tserver_label: MCP_NAME,\n\t\t\t\t\t\tserver_url: mcpUrl(),\n\t\t\t\t\t\trequire_approval: 'never',\n\t\t\t\t\t\theaders: { Authorization: 'Bearer $ACCESS_TOKEN' },\n\t\t\t\t\t},\n\t\t\t\t\t...(OPENAI_WEB_SEARCH_ENABLED\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'web_search',\n\t\t\t\t\t\t\t\t\texternal_web_access: OPENAI_WEB_SEARCH_EXTERNAL_WEB_ACCESS,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: []),\n\t\t\t\t],\n\t\t\t},\n\t\t});\n\t}\n\n\tconst resolvedModel = info.model || DEFAULT_CLAUDE_MODEL;\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'claude',\n\t\tqueue: (info.userId || service) + BG_INDEXING_QUEUE_SUFFIX,\n\t\tservice,\n\t\towner,\n\t\t...pollOpt(),\n\t\turl: ANTHROPIC_MESSAGES_API_URL,\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\t'content-type': 'application/json',\n\t\t\t'x-api-key': '$CLIENT_SECRET',\n\t\t\t'anthropic-version': ANTHROPIC_VERSION,\n\t\t\t'anthropic-beta': ANTHROPIC_BETA_HEADER,\n\t\t},\n\t\tdata: {\n\t\t\tmodel: resolvedModel,\n\t\t\tmax_tokens: MAX_TOKENS,\n\t\t\t...skapiExtract,\n\t\t\t...skapiRender,\n\t\t\t...skapiWindow,\n\t\t\tsystem: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\ttext: systemPrompt,\n\t\t\t\t\tcache_control: { type: 'ephemeral' },\n\t\t\t\t},\n\t\t\t],\n\t\t\tmessages: [\n\t\t\t\t{\n\t\t\t\t\trole: 'user',\n\t\t\t\t\tcontent: transformContentWithImages(userMessage),\n\t\t\t\t},\n\t\t\t],\n\t\t\tmcp_servers: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'url',\n\t\t\t\t\tname: MCP_NAME,\n\t\t\t\t\turl: mcpUrl(),\n\t\t\t\t\tauthorization_token: '$ACCESS_TOKEN',\n\t\t\t\t},\n\t\t\t],\n\t\t\ttools: [\n\t\t\t\t{\n\t\t\t\t\ttype: 'mcp_toolset',\n\t\t\t\t\tmcp_server_name: MCP_NAME,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'web_fetch_20250910',\n\t\t\t\t\tname: 'web_fetch',\n\t\t\t\t\tmax_uses: WEB_FETCH_MAX_USES,\n\t\t\t\t\tcitations: { enabled: true },\n\t\t\t\t\tmax_content_tokens: WEB_FETCH_MAX_CONTENT_TOKENS,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t});\n}\n\nexport function extractClaudeText(response: any) {\n\tif (!Array.isArray(response?.content)) {\n\t\treturn '';\n\t}\n\n\treturn response.content\n\t\t.filter((block: any) => block?.type === 'text')\n\t\t.map((block: any) => block.text)\n\t\t.join('\\n');\n}\n\nexport function extractOpenAIText(response: any) {\n\tif (\n\t\ttypeof response?.output_text === 'string' &&\n\t\tresponse.output_text.length\n\t) {\n\t\treturn response.output_text;\n\t}\n\n\tif (Array.isArray(response?.output)) {\n\t\tconst text = response.output\n\t\t\t.flatMap((item: any) => item?.content || [])\n\t\t\t.filter((part: any) => part?.type === 'output_text')\n\t\t\t.map((part: any) => part.text || '')\n\t\t\t.join('\\n')\n\t\t\t.trim();\n\n\t\tif (text) {\n\t\t\treturn text;\n\t\t}\n\t}\n\n\tconst content = response?.choices?.[0]?.message?.content;\n\n\tif (typeof content === 'string') {\n\t\treturn content;\n\t}\n\n\tif (Array.isArray(content)) {\n\t\treturn content\n\t\t\t.map((part: any) => {\n\t\t\t\tif (typeof part === 'string') {\n\t\t\t\t\treturn part;\n\t\t\t\t}\n\t\t\t\tif (part?.type === 'text') {\n\t\t\t\t\treturn part.text || '';\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t})\n\t\t\t.join('\\n');\n\t}\n\n\treturn '';\n}\n\nexport async function listClaudeModels(service: string, owner: string) {\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'claude',\n\t\tservice,\n\t\towner,\n\t\turl: ANTHROPIC_MODELS_API_URL,\n\t\tmethod: 'GET',\n\t\theaders: {\n\t\t\t'x-api-key': '$CLIENT_SECRET',\n\t\t\t'anthropic-version': ANTHROPIC_VERSION,\n\t\t},\n\t});\n}\n\nexport async function listOpenAIModels(service: string, owner: string) {\n\treturn clientSecretRequest({\n\t\tclientSecretName: 'openai',\n\t\tservice,\n\t\towner,\n\t\turl: OPENAI_MODELS_API_URL,\n\t\tmethod: 'GET',\n\t\theaders: {\n\t\t\tAuthorization: 'Bearer $CLIENT_SECRET',\n\t\t},\n\t});\n}\n\n// Suffix for the background-indexing queue. Must sort *before* ':' (ASCII 58)\n// so the chat-history BETWEEN query never includes bg-queue items. '-' (45) works.\nexport const BG_INDEXING_QUEUE_SUFFIX = '-bg';\n\n/**\n * True when a request belongs to the background-indexing queue.\n *\n * Accepts BOTH shapes this value arrives in: the bare queue name the client sends\n * (\"<userId>-bg\"), and the server qid that comes back on history/poll responses\n * (\"<service>:<queue>|<seq>\"). Testing the tail of the raw value only works for the\n * first: a qid ends in \"|<seq>\", so `endsWith('-bg')` is always false for it — which\n * silently meant history items were NEVER recognised as background tasks.\n */\nexport function isBgIndexingQueue(queueName?: string): boolean {\n\tif (typeof queueName !== 'string' || !queueName) return false;\n\tconst prefix = queueName.split('|')[0];\n\tconst idx = prefix.lastIndexOf(':');\n\tconst name = idx === -1 ? prefix : prefix.slice(idx + 1);\n\treturn name.slice(-BG_INDEXING_QUEUE_SUFFIX.length) === BG_INDEXING_QUEUE_SUFFIX;\n}\n\n// Pending background-indexing task descriptor. NOTE: the live mutable queue\n// (a Vue `reactive([])` in agent.vue, a plain array in bunnyquery) is app-level\n// state owned by the consumer — only the TYPE lives in the engine.\nexport type BgTaskEntry = {\n\tserviceId: string;\n\tplatform: 'claude' | 'openai';\n\tid: string;\n\tfilename: string;\n\tstoragePath?: string;\n\tisReindex?: boolean;\n\tmime?: string;\n\tsize?: number;\n\tstatus: 'running' | 'pending';\n\tpoll: ((opts: { latency: number }) => Promise<any>) | undefined;\n\t/** How many CONTINUE passes have already run for this file (resume-across-passes). */\n\tresumePass?: number;\n};\n\n// Token the indexing agent appends to its final message ONLY when it has fully read and\n// saved the whole file. Its ABSENCE is what tells the client to run another CONTINUE pass.\n//\n// Applies to the TEXT/GRID paging path only. The vision path (rendered PDF pages) no longer\n// asks the model whether it is finished — the worker advances that loop off the renderer's\n// page count — so this marker has no say in whether a PDF keeps going.\nexport const INDEXING_COMPLETE_MARKER = 'INDEXING_COMPLETE';\n// Cap on CONTINUE passes per file, so a file the agent can never mark complete (or a\n// pathological loop) stops instead of re-dispatching forever. The text/grid paging path\n// reads MANY windows within a single pass (the agent loops readFileContent in one turn), so\n// a small cap suffices.\nexport const MAX_INDEXING_RESUME_PASSES = 6;\n\nexport async function getChatHistory(\n\tparams: { service?: string; owner?: string; platform: 'claude' | 'openai'; queue?: string },\n\tfetchOptions: Record<string, any>,\n) {\n\tconst url =\n\t\tparams.platform === 'claude'\n\t\t\t? ANTHROPIC_MESSAGES_API_URL\n\t\t\t: OPENAI_RESPONSES_API_URL;\n\tconst p = Object.assign(\n\t\t{\n\t\t\turl,\n\t\t\tmethod: 'POST',\n\t\t},\n\t\t{ service: params.service, owner: params.owner },\n\t\tparams.queue ? { queue: params.queue } : {},\n\t);\n\n\treturn chatEngineConfig().clientSecretRequestHistory(\n\t\tp as { url: string; method: 'POST'; queue?: string },\n\t\tObject.assign({ ascending: false }, fetchOptions),\n\t);\n}\n","/**\n * History mapping (pure). Moved verbatim from the chatbox. The clear-horizon\n * timestamp and the \"Indexing: …\" display label are INJECTED (clearedAt param,\n * formatIndexingLabel callback) so the engine touches neither localStorage nor\n * view-specific display formatting. serviceId is passed for link sanitization.\n */\nimport { extractClaudeText, extractOpenAIText } from './requests';\nimport { isErrorResponseBody, getErrorMessage } from './errors';\nimport { sanitizeAttachmentLinksForHistory } from './links';\n\nexport function filterListByClearHorizon(list: any[], clearedAt: number): any[] {\n\tif (!clearedAt) return list;\n\treturn list.filter(function (item) {\n\t\tvar updated = Number(item && item.updated);\n\t\treturn isFinite(updated) && updated > clearedAt;\n\t});\n}\n\nexport function normalizeTextContent(content: any): string {\n\tif (typeof content === 'string') return content;\n\tif (Array.isArray(content)) {\n\t\treturn content.map(function (part: any) {\n\t\t\tif (typeof part === 'string') return part;\n\t\t\tif (part && (part.type === 'text' || part.type === 'input_text' || part.type === 'output_text')) return part.text || '';\n\t\t\treturn '';\n\t\t}).join('\\n').trim();\n\t}\n\treturn '';\n}\n\nexport function extractLastUserTextFromRequest(requestBody: any): string {\n\tvar arr = requestBody && Array.isArray(requestBody.messages) ? requestBody.messages\n\t\t: (requestBody && Array.isArray(requestBody.input) ? requestBody.input : []);\n\tfor (var i = arr.length - 1; i >= 0; i--) {\n\t\tif (arr[i] && arr[i].role === 'user') {\n\t\t\tvar t = normalizeTextContent(arr[i].content);\n\t\t\tif (t) return t;\n\t\t}\n\t}\n\treturn '';\n}\n\nexport type MapHistoryOptions = {\n\tclearedAt: number;\n\tserviceId: string;\n\t/** View-side display formatter for \"Indexing:/Reindexing: …\" bubbles. */\n\tformatIndexingLabel: (name: string, mime?: string, size?: number | null, storagePath?: string) => string;\n};\n\nexport function mapHistoryListToMessages(list: any[], platform: 'claude' | 'openai', opts: MapHistoryOptions) {\n\tvar mapped: any[] = [], runningItemIds: string[] = [];\n\tvar extractAssistantText = platform === 'openai' ? extractOpenAIText : extractClaudeText;\n\tvar filtered = filterListByClearHorizon(list, opts.clearedAt);\n\tfiltered.slice().reverse().forEach(function (item) {\n\t\tvar requestBody = item && item.request_body;\n\t\tvar isInProcess = item && item.status === 'running';\n\t\tvar isQueued = item && item.status === 'pending';\n\t\tvar isCancelledItem = item && item.status === 'cancelled';\n\t\tvar isPending = isInProcess || isQueued;\n\t\tvar isFailed = item && item.status === 'failed';\n\t\tvar response = isFailed ? (item.error != null ? item.error : item.response_body)\n\t\t\t: (item && item.response_body != null ? item.response_body : item && item.error);\n\t\tvar userText = extractLastUserTextFromRequest(requestBody);\n\t\tvar assistantText = isPending ? '' : ((extractAssistantText(response) || '').trim() || '');\n\t\tvar isErrorResponse = !isPending && (isFailed || isErrorResponseBody(response));\n\t\tvar serverItemId = item && typeof item.id === 'string' && item.id ? item.id : undefined;\n\n\t\tif (userText) {\n\t\t\tvar displayContent;\n\t\t\tif (item._isBgTask) {\n\t\t\t\tvar nameMatch = userText.match(/^- name: (.+)$/m);\n\t\t\t\tif (nameMatch) {\n\t\t\t\t\tvar mimeMatch = userText.match(/^- mime type: (.+)$/m);\n\t\t\t\t\tvar sizeMatch = userText.match(/^- size \\(bytes\\): (\\d+)$/m);\n\t\t\t\t\tvar pathMatch = userText.match(/^- storage path: (.+)$/m);\n\t\t\t\t\tdisplayContent = opts.formatIndexingLabel(\n\t\t\t\t\t\tnameMatch[1].trim(),\n\t\t\t\t\t\tmimeMatch ? mimeMatch[1].trim() : '',\n\t\t\t\t\t\tsizeMatch ? Number(sizeMatch[1]) : null,\n\t\t\t\t\t\tpathMatch ? pathMatch[1].trim() : undefined\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tdisplayContent = userText;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdisplayContent = sanitizeAttachmentLinksForHistory(userText, opts.serviceId);\n\t\t\t}\n\t\t\tvar userMsg: any = { role: 'user', content: displayContent };\n\t\t\tif (isInProcess) userMsg.isPendingInProcess = true;\n\t\t\tif (isQueued) userMsg.isPendingQueued = true;\n\t\t\tif (isCancelledItem) userMsg.isCancelled = true;\n\t\t\tif (item._isBgTask) userMsg.isBackgroundTask = true;\n\t\t\tif (item._isOnBgQueue) userMsg._useBgQueue = true;\n\t\t\tif (serverItemId !== undefined) userMsg._serverItemId = serverItemId;\n\t\t\tmapped.push(userMsg);\n\t\t}\n\t\tif (isCancelledItem) { /* no assistant bubble */ }\n\t\telse if (isInProcess) {\n\t\t\tvar ph: any = { role: 'assistant', content: '', isPending: true, isPendingInProcess: true };\n\t\t\tif (item._isBgTask) ph.isBackgroundTask = true;\n\t\t\tif (serverItemId !== undefined) { ph._serverItemId = serverItemId; runningItemIds.push(serverItemId); }\n\t\t\tmapped.push(ph);\n\t\t} else if (isQueued) { /* no assistant placeholder */ }\n\t\telse if (isErrorResponse) {\n\t\t\tvar em: any = { role: 'assistant', content: getErrorMessage(response), isError: true };\n\t\t\tif (item._isBgTask) em.isBackgroundTask = true;\n\t\t\tif (serverItemId !== undefined) em._serverItemId = serverItemId;\n\t\t\tmapped.push(em);\n\t\t} else if (assistantText) {\n\t\t\t// Safe db-only sanitize (forAssistant) so a volatile db url the model\n\t\t\t// emitted renders as a re-mintable `_expired_.url` link, not a dead one.\n\t\t\tvar okm: any = { role: 'assistant', content: sanitizeAttachmentLinksForHistory(assistantText, opts.serviceId, true) };\n\t\t\tif (item._isBgTask) okm.isBackgroundTask = true;\n\t\t\tif (serverItemId !== undefined) okm._serverItemId = serverItemId;\n\t\t\tmapped.push(okm);\n\t\t}\n\t});\n\treturn { messages: mapped, runningItemIds: runningItemIds };\n}\n","/**\n * ChatSession — framework-agnostic stateful chat orchestration.\n *\n * Ported verbatim from the bunnyquery widget's in-place state machine (which was\n * itself ported from agent.vue), with three mechanical substitutions:\n * CS.<field> -> this.state.<field>\n * renderMessages() -> this.host.notify()\n * S.<x> / skapi -> this.host.getIdentity().<x> / this.host.cancelRequest / refreshSession\n * scroll/refresh -> this.host.scrollToBottom(IfSticky) / refreshMessageBubble\n * Module-level singletons (bgTaskQueue, aiChatHistoryCache, pendingAgentRequests,\n * cancelledServerIds, historyItemPolls) become instance fields. The provider\n * request builders are reached through the engine (which already has the skapi\n * transport + poll injected via configureChatEngine), so cancel/poll behavior is\n * preserved.\n *\n * The view (per consumer) keeps: rendering, markdown PARSE, DOM refs + scroll\n * measurement, attachment chips, and the auth/account shell. It drives the\n * session via the public methods and re-renders in host.notify().\n */\nimport {\n\tcallClaudeWithPublicMcp,\n\tcallOpenAIWithPublicMcp,\n\tnotifyAgentSaveAttachment,\n\tnotifyAgentContinueIndexing,\n\tINDEXING_COMPLETE_MARKER,\n\tMAX_INDEXING_RESUME_PASSES,\n\textractClaudeText,\n\textractOpenAIText,\n\tgetChatHistory,\n\tPOLL_INTERVAL,\n\tBG_INDEXING_QUEUE_SUFFIX,\n\tisBgIndexingQueue,\n\tANTHROPIC_MESSAGES_API_URL,\n\tOPENAI_RESPONSES_API_URL,\n\ttype BgTaskEntry,\n} from './requests';\nimport { isPagedReadFile, isImageVisionFile } from './office';\nimport { isErrorResponseBody, isAuthExpiredError, isNonRetryableRequestError, getErrorMessage } from './errors';\nimport { buildBoundedChatMessages } from './budget';\nimport { createInlineLinkRegex } from './links';\nimport { mapHistoryListToMessages, extractLastUserTextFromRequest } from './history';\nimport { parseAttachmentContent } from './attachment_parsers';\nimport type { ChatHost, ChatState, ChatMessage, PinnedDispatchContext } from './host';\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise(function (r) { setTimeout(r, ms); });\n}\n\n// requestAnimationFrame / high-res clock, reached through globalThis so the\n// engine stays DOM-free at the type level (and degrades gracefully in non-DOM\n// / test environments where these globals are absent).\nvar _g: any = typeof globalThis !== 'undefined' ? globalThis : {};\nfunction nowMs(): number {\n\treturn (_g.performance && typeof _g.performance.now === 'function') ? _g.performance.now() : Date.now();\n}\nfunction nextFrame(cb: (t: number) => void): void {\n\tif (typeof _g.requestAnimationFrame === 'function') { _g.requestAnimationFrame(cb); return; }\n\tsetTimeout(function () { cb(nowMs()); }, 16);\n}\n\n/** A live poll registered in ChatSession.historyItemPolls. */\nexport type PollHandle = {\n\t/** 'bg' = background indexing, pausable. 'fg' = a reply the user is waiting on. */\n\tkind: 'fg' | 'bg';\n\t/** Absent on an older skapi-js that cannot stop an attached poll. */\n\tstop?: () => void;\n};\n\n/**\n * True when a poll result came from stopPolling rather than the server. Duck-typed on\n * purpose — see the note above about not importing skapi-js here.\n */\nfunction isPollStopped(res: any): boolean {\n\treturn !!res && typeof res === 'object' && res.status === 'stopped';\n}\n\nexport class ChatSession {\n\thost: ChatHost;\n\tstate: ChatState;\n\tbgTaskQueue: BgTaskEntry[];\n\tcancelledServerIds: Set<string>;\n\tpendingAgentRequests: Record<string, Promise<any>>;\n\taiChatHistoryCache: Record<string, { messages: ChatMessage[]; endOfList: boolean; startKeyHistory: string[] }>;\n\thistoryItemPolls: Map<string, PollHandle>;\n\t/** Non-empty while polling is paused; keyed by reason so overlapping causes\n\t * (view detached AND tab hidden) do not resume each other prematurely. */\n\tprivate _pauseReasons: Set<string>;\n\tprivate _resuming: boolean;\n\tprivate _lidSeq: number;\n\n\tconstructor(host: ChatHost) {\n\t\tthis.host = host;\n\t\tthis.state = {\n\t\t\tmessages: [],\n\t\t\tattachments: [],\n\t\t\tuploadingAttachments: false,\n\t\t\tsending: false,\n\t\t\ttyping: false,\n\t\t\ttypingAbort: false,\n\t\t\tloadingHistory: false,\n\t\t\tloadingOlderHistory: false,\n\t\t\thistoryEndOfList: false,\n\t\t\thistoryStartKeyHistory: [],\n\t\t\thistoryRequestToken: 0,\n\t\t\tgateRefreshToken: 0,\n\t\t};\n\t\tthis.bgTaskQueue = [];\n\t\tthis.cancelledServerIds = new Set();\n\t\tthis.pendingAgentRequests = {};\n\t\tthis.aiChatHistoryCache = {};\n\t\tthis.historyItemPolls = new Map();\n\t\tthis._pauseReasons = new Set();\n\t\tthis._resuming = false;\n\t\tthis._lidSeq = 0;\n\t}\n\n\t/**\n\t * Register a live poll so (a) a remount dedupes against it instead of stacking a\n\t * SECOND poll on the same item, and (b) pausePolling can stop it.\n\t *\n\t * `stop` comes from the SDK and may be absent on an older skapi-js, in which case the\n\t * poll simply cannot be stopped and is left running — see pausePolling.\n\t */\n\tprivate _trackPoll(id: string, kind: 'fg' | 'bg', p: any): any {\n\t\tvar stop = p && typeof p.stop === 'function' ? p.stop.bind(p) : undefined;\n\t\tif (!stop) {\n\t\t\t// The SDK could not give us a handle. Almost always means an older skapi-js\n\t\t\t// is loaded (or a stale bundler dep cache) — the poll will be unstoppable.\n\t\t\tconsole.debug('[chat-engine] poll has no stop handle', { id: id, kind: kind });\n\t\t}\n\t\tthis.historyItemPolls.set(id, { kind: kind, stop: stop });\n\t\treturn p;\n\t}\n\n\t/** True while any pause reason is active. */\n\tisPollingPaused(): boolean {\n\t\treturn this._pauseReasons.size > 0;\n\t}\n\n\t/**\n\t * Stop BACKGROUND polling until resumePolling. Foreground polls (a reply the user is\n\t * waiting on) keep running deliberately: their results must still land in the history\n\t * cache so resumePendingRequest can render them on return, otherwise a user who sends\n\t * a message then navigates away comes back to a permanently stuck \"Thinking...\".\n\t *\n\t * Server-side work is untouched; this only stops asking about it. That is safe for\n\t * document indexing because the worker drives that loop itself.\n\t */\n\tpausePolling(reason: string): void {\n\t\tthis._pauseReasons.add(reason || 'paused');\n\t\tvar self = this;\n\t\tvar stopped: string[] = [];\n\t\tthis.historyItemPolls.forEach(function (handle, id) {\n\t\t\tif (!handle || handle.kind !== 'bg') return;\n\t\t\t// No stop available (older SDK): LEAVE the entry in place. Deleting it would\n\t\t\t// let a later drain attach a second, uncancellable poll on the same item.\n\t\t\tif (typeof handle.stop !== 'function') return;\n\t\t\ttry { handle.stop(); } catch (e) { /* best effort */ }\n\t\t\tstopped.push(id);\n\t\t});\n\t\t// Delete only what we actually stopped, one at a time. NEVER clear() the map:\n\t\t// wholesale clearing is what previously let loadHistory attach a duplicate poll\n\t\t// on a live item, producing duplicate replies and stranded \"Thinking\" bubbles.\n\t\tstopped.forEach(function (id) { self.historyItemPolls.delete(id); });\n\n\t}\n\n\t/**\n\t * Lift a pause reason WITHOUT running the reconcile. For a caller that is about to\n\t * reload history anyway (a view remounting), letting resumePolling also reconcile\n\t * would race that load and can double-attach.\n\t */\n\tclearPauseReason(reason: string): void {\n\t\tthis._pauseReasons.delete(reason || 'paused');\n\t}\n\n\t/**\n\t * Clear a pause reason and, once none remain, re-attach polling and reconcile.\n\t * Deliberately does NOT touch gateRefreshToken: bumping it would silently discard\n\t * the results of anything still in flight across the pause.\n\t */\n\tresumePolling(reason: string): Promise<void> {\n\t\tthis._pauseReasons.delete(reason || 'paused');\n\t\tif (this._pauseReasons.size > 0 || this._resuming) return Promise.resolve();\n\t\tif (!this.host.isViewMounted || !this.host.isViewMounted()) return Promise.resolve();\n\t\tvar self = this;\n\t\tthis._resuming = true;\n\t\treturn Promise.resolve()\n\t\t\t.then(function () {\n\t\t\t\tself.drainBgTaskQueue();\n\t\t\t\treturn self.loadHistory(false, self.state.gateRefreshToken);\n\t\t\t})\n\t\t\t.catch(function (e: any) { console.error('[chat-engine] resume polling failed', e); })\n\t\t\t.then(function () { self._resuming = false; });\n\t}\n\n\tprivate _newLocalId(): string {\n\t\tthis._lidSeq += 1;\n\t\treturn 'lid_' + this._lidSeq;\n\t}\n\n\tgetHistoryCacheKey(): string {\n\t\tvar id = this.host.getIdentity();\n\t\tif (!id.serviceId || id.platform === 'none') return '';\n\t\treturn id.serviceId + '#' + id.platform;\n\t}\n\n\tupdateHistoryCache(): void {\n\t\tvar key = this.getHistoryCacheKey();\n\t\tif (!key) return;\n\t\t// Never persist another chat's in-flight bubbles under THIS key. The\n\t\t// dashboard shares one ChatSession across projects, so a turn dispatched\n\t\t// in project A can still be sitting in state.messages while the identity\n\t\t// (and therefore `key`) already points at project B — without this filter\n\t\t// A's user + \"Thinking...\" bubbles get written into B's cache entry and\n\t\t// replay on every later visit to B. Bubbles with no _ownerKey (server\n\t\t// history, bg tasks) are always kept. Single pass: this runs on the\n\t\t// typewriter hot path.\n\t\tthis.aiChatHistoryCache[key] = {\n\t\t\tmessages: this.state.messages.filter(function (m) {\n\t\t\t\treturn m._ownerKey === undefined || m._ownerKey === key;\n\t\t\t}),\n\t\t\tendOfList: this.state.historyEndOfList,\n\t\t\tstartKeyHistory: this.state.historyStartKeyHistory.slice(),\n\t\t};\n\t}\n\n\t/**\n\t * Land a resolved reply in the history cache of a chat that is NOT currently\n\t * visible, without touching state.messages. Mirrors the cache-only path in\n\t * dispatchAgentRequest: REPLACE the trailing pending \"Thinking...\" bubble\n\t * (append only when there is none), and settle the matching pending user\n\t * bubble, so the cached copy never keeps a stuck \"Thinking...\" that a later\n\t * cache-first load would re-render forever.\n\t */\n\tprivate _applyReplyToCache(key: string, reply: ChatMessage, serverId?: string): void {\n\t\tif (!key) return;\n\t\tvar existing = this.aiChatHistoryCache[key] || { messages: [], endOfList: false, startKeyHistory: [] };\n\t\tvar msgs = existing.messages.slice();\n\n\t\tvar thIdx = -1;\n\t\tfor (var i = msgs.length - 1; i >= 0; i--) {\n\t\t\tvar m = msgs[i];\n\t\t\tif (!m || !m.isPending || m.role !== 'assistant' || m.isBackgroundTask) continue;\n\t\t\tif (serverId && m._serverItemId && m._serverItemId !== serverId) continue;\n\t\t\tthIdx = i; break;\n\t\t}\n\t\tif (thIdx !== -1) {\n\t\t\tif (reply._serverItemId === undefined && msgs[thIdx]._serverItemId !== undefined) reply._serverItemId = msgs[thIdx]._serverItemId;\n\t\t\tmsgs[thIdx] = reply;\n\t\t} else {\n\t\t\tmsgs.push(reply);\n\t\t}\n\n\t\t// Settle the user bubble this turn belongs to (first pending one, or the\n\t\t// one carrying serverId) so it stops rendering as still in flight.\n\t\tfor (var j = 0; j < msgs.length; j++) {\n\t\t\tvar u = msgs[j];\n\t\t\tif (!u || u.role !== 'user' || u.isBackgroundTask) continue;\n\t\t\tif (!(u.isPendingQueued || u.isPendingInProcess || u.isSendingToServer)) continue;\n\t\t\tif (serverId && u._serverItemId && u._serverItemId !== serverId) continue;\n\t\t\tvar settled: ChatMessage = { role: 'user', content: u.content };\n\t\t\tif (u._serverItemId !== undefined) settled._serverItemId = u._serverItemId;\n\t\t\tif (u._ownerKey !== undefined) settled._ownerKey = u._ownerKey;\n\t\t\tmsgs[j] = settled;\n\t\t\tbreak;\n\t\t}\n\n\t\tthis.aiChatHistoryCache[key] = {\n\t\t\tmessages: msgs,\n\t\t\tendOfList: existing.endOfList,\n\t\t\tstartKeyHistory: existing.startKeyHistory,\n\t\t};\n\t}\n\n\t/**\n\t * serviceId/owner are passed explicitly by every caller: a request can be\n\t * dispatched after the user moved to another project, and re-reading the live\n\t * identity here would silently send the turn to THAT project instead of the\n\t * one it was composed for. Falls back to the live read only when a caller\n\t * omits them.\n\t */\n\tprivate _callProviderFor(platform: string, prompt: string, messages: any, system: string, model: string | undefined, userId: string, extractContent: any, fileUrls?: any, serviceId?: string, owner?: string) {\n\t\tif (serviceId === undefined || owner === undefined) {\n\t\t\tvar id = this.host.getIdentity();\n\t\t\tif (serviceId === undefined) serviceId = id.serviceId;\n\t\t\tif (owner === undefined) owner = id.owner;\n\t\t}\n\t\treturn platform === 'openai'\n\t\t\t? callOpenAIWithPublicMcp(prompt, serviceId, owner, messages, system, model, userId, extractContent, fileUrls)\n\t\t\t: callClaudeWithPublicMcp(prompt, serviceId, owner, messages, system, model, userId, extractContent, fileUrls);\n\t}\n\n\tdispatchAgentRequest(params: any) {\n\t\tvar self = this;\n\t\t// Id of the in-flight item this dispatch polls. Recorded in\n\t\t// historyItemPolls (set below, deleted when the dispatch settles) so a\n\t\t// remount / history refetch dedups against THIS poll instead of stacking\n\t\t// a duplicate history poll on the same item. (The cacheKey guard alone\n\t\t// stops covering an item once pendingAgentRequests clears — e.g. a queued\n\t\t// message still in flight after the immediate one resolved.)\n\t\tvar dispatchItemId: string | undefined;\n\t\tvar sendAndPoll = function () {\n\t\t\treturn Promise.resolve(\n\t\t\t\tself._callProviderFor(params.aiPlatform, params.text, params.boundedMessages, params.systemPrompt, params.aiModel, params.userId, params.extractContent, params.fileUrls, params.serviceId, params.owner)\n\t\t\t).then(function (initial: any) {\n\t\t\t\tif (initial && initial.poll && (initial.status === 'pending' || initial.status === 'running')) {\n\t\t\t\t\tif (initial.id) {\n\t\t\t\t\t\tif (dispatchItemId && dispatchItemId !== initial.id) self.historyItemPolls.delete(dispatchItemId);\n\t\t\t\t\t\tdispatchItemId = initial.id;\n\t\t\t\t\t}\n\t\t\t\t\tvar dp = initial.poll({ latency: POLL_INTERVAL });\n\t\t\t\t\tif (initial.id) self._trackPoll(initial.id, 'fg', dp);\n\t\t\t\t\treturn dp;\n\t\t\t\t}\n\t\t\t\treturn initial;\n\t\t\t});\n\t\t};\n\t\tvar run = sendAndPoll()\n\t\t\t.catch(function (err: any) {\n\t\t\t\t// Only auth-expiry is worth a refresh+resend; a malformed-request 400\n\t\t\t\t// (e.g. the `_skapi_extract`/unknown-parameter class) re-fails identically,\n\t\t\t\t// so never loop on it — guard against isAuthExpiredError's heuristic\n\t\t\t\t// misfiring on a param name that merely contains \"token\".\n\t\t\t\tif (isAuthExpiredError(err) && !isNonRetryableRequestError(err)) return self.host.refreshSession().then(sendAndPoll);\n\t\t\t\tthrow err;\n\t\t\t})\n\t\t\t.then(function (response: any) {\n\t\t\t\tif (isErrorResponseBody(response) && isAuthExpiredError(response) && !isNonRetryableRequestError(response)) {\n\t\t\t\t\treturn self.host.refreshSession().then(sendAndPoll);\n\t\t\t\t}\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.then(function (response: any) {\n\t\t\t\tif (isErrorResponseBody(response)) return { content: getErrorMessage(response), isError: true };\n\t\t\t\tvar answer = (params.aiPlatform === 'openai' ? extractOpenAIText(response) : extractClaudeText(response));\n\t\t\t\tanswer = (answer || '').trim();\n\t\t\t\treturn { content: answer || 'No text response received from AI provider.', isError: false };\n\t\t\t})\n\t\t\t.catch(function (err: any) { return { content: getErrorMessage(err), isError: true }; })\n\t\t\t.then(function (result: any) {\n\t\t\t\t// Land the resolved reply in the shared history cache. This runs\n\t\t\t\t// independently of the view lifecycle, so a reply is captured even\n\t\t\t\t// if the chatbox unmounted mid-request.\n\t\t\t\tdelete self.pendingAgentRequests[params.key];\n\t\t\t\tif (dispatchItemId) self.historyItemPolls.delete(dispatchItemId);\n\t\t\t\tvar existing = self.aiChatHistoryCache[params.key] || { messages: [], endOfList: false, startKeyHistory: [] };\n\t\t\t\tvar reply: ChatMessage = { role: 'assistant', content: result.content, isError: result.isError };\n\n\t\t\t\t// REPLACE the trailing pending \"Thinking...\" bubble in the cache with\n\t\t\t\t// the answer (falling back to append when none is present), regardless\n\t\t\t\t// of whether this chat is the currently-visible view. The cache must\n\t\t\t\t// NEVER retain a pending \"Thinking...\" bubble: even when the chatbox is\n\t\t\t\t// showing this chat, typewriteLatestReply swaps the bubble only in\n\t\t\t\t// state.messages and NEVER re-snapshots the cache — so appending a\n\t\t\t\t// duplicate here would leave the cached copy stuck pending, and a later\n\t\t\t\t// cache-first remount (agent.vue's loadChatHistory) would re-render that\n\t\t\t\t// \"Thinking...\" forever. typewriteLatestReply still finds this reply (it\n\t\t\t\t// reads the latest non-pending assistant from the cache), so replacing is\n\t\t\t\t// correct for the visible case too. The next fresh history fetch\n\t\t\t\t// reconciles it either way.\n\t\t\t\tvar msgs = existing.messages.slice();\n\t\t\t\tvar idx = -1;\n\t\t\t\tfor (var i = msgs.length - 1; i >= 0; i--) {\n\t\t\t\t\tvar m = msgs[i];\n\t\t\t\t\tif (m && m.isPending && m.role === 'assistant' && !m.isBackgroundTask) { idx = i; break; }\n\t\t\t\t}\n\t\t\t\tif (idx !== -1) {\n\t\t\t\t\treply._serverItemId = msgs[idx]._serverItemId;\n\t\t\t\t\tmsgs[idx] = reply;\n\t\t\t\t} else {\n\t\t\t\t\tmsgs.push(reply);\n\t\t\t\t}\n\t\t\t\tself.aiChatHistoryCache[params.key] = {\n\t\t\t\t\tmessages: msgs,\n\t\t\t\t\tendOfList: existing.endOfList,\n\t\t\t\t\tstartKeyHistory: existing.startKeyHistory,\n\t\t\t\t};\n\t\t\t\treturn result;\n\t\t\t});\n\t\tthis.pendingAgentRequests[params.key] = run;\n\t\treturn run;\n\t}\n\n\t// composed = clean display text; composedForLlm carries office-extraction\n\t// placeholders for the provider only. useBgQueue routes a post-attachment turn\n\t// onto the \"-bg\" queue so it runs after indexing.\n\tdispatchComposedMessage(composed: string, useBgQueue?: boolean, composedForLlm?: string, extractContent?: any, fileUrls?: any, pinned?: PinnedDispatchContext): void {\n\t\tvar self = this;\n\t\tif (!composed) return;\n\t\t// A send can be dispatched LONG after the user hit Send (attachment\n\t\t// uploads are awaited first), by which time the live identity may have\n\t\t// moved to another project. The caller pins the identity + system prompt\n\t\t// it captured at Send time so the request still goes to the project the\n\t\t// question was actually asked of. Falls back to the live read when the\n\t\t// caller doesn't pin (the widget, which has only one project anyway).\n\t\tvar id = pinned ? pinned.identity : this.host.getIdentity();\n\t\tif (id.platform === 'none') return;\n\n\t\tvar llmComposed = composedForLlm || composed;\n\n\t\t// Cache key of the chat this turn belongs to. Every locally-created\n\t\t// bubble is stamped with it so a project switch (which flips\n\t\t// getIdentity()/getHistoryCacheKey() to the new project) can't\n\t\t// misattribute this turn's bubbles to that project.\n\t\t// (platform === 'none' already returned above, so serviceId is the only gate)\n\t\tvar key = !id.serviceId ? '' : id.serviceId + '#' + id.platform;\n\t\t// True when the pinned chat is NOT the one currently on screen. Then\n\t\t// state.messages belongs to a different project and MUST NOT be touched:\n\t\t// the turn is staged in the pinned chat's cache instead and shows up when\n\t\t// the user navigates back to it.\n\t\tvar offChat = !!key && key !== this.getHistoryCacheKey();\n\n\t\tvar isQueuedSend = !offChat && (useBgQueue || this.state.sending || this.state.messages.some(function (m) {\n\t\t\treturn (m.isPending || m.isPendingQueued) && !m.isBackgroundTask && !m._useBgQueue;\n\t\t}));\n\n\t\tvar aiPlatform = id.platform;\n\t\tvar aiModel = id.model || undefined;\n\t\tvar systemPrompt = pinned ? pinned.systemPrompt : this.host.buildSystemPrompt();\n\t\tvar userId = id.userId || id.serviceId;\n\t\tvar chatQueue = useBgQueue ? userId + BG_INDEXING_QUEUE_SUFFIX : userId;\n\n\t\tif (offChat) {\n\t\t\t// Stage the turn in the pinned chat's cache and dispatch. The\n\t\t\t// client-side queue can't be consulted (its state is the other\n\t\t\t// project's), but the SERVER serializes per queue name, so ordering\n\t\t\t// within the pinned chat still holds. dispatchAgentRequest replaces\n\t\t\t// the pending bubble in this same cache entry when the reply lands.\n\t\t\tvar offHistory = (this.aiChatHistoryCache[key] ? this.aiChatHistoryCache[key].messages : []).filter(function (m) {\n\t\t\t\treturn !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder &&\n\t\t\t\t\t!m.isCancelled && !m.isBackgroundTask;\n\t\t\t});\n\t\t\tvar offBounded = buildBoundedChatMessages({\n\t\t\t\tplatform: aiPlatform, model: aiModel, systemPrompt: systemPrompt, serviceId: id.serviceId,\n\t\t\t\thistory: offHistory.concat([{ role: 'user', content: llmComposed }]),\n\t\t\t});\n\t\t\tvar offExisting = this.aiChatHistoryCache[key] || { messages: [], endOfList: false, startKeyHistory: [] };\n\t\t\tthis.aiChatHistoryCache[key] = {\n\t\t\t\tmessages: offExisting.messages.concat([\n\t\t\t\t\t{ role: 'user', content: composed, _ownerKey: key },\n\t\t\t\t\t{ role: 'assistant', content: '', isPending: true, isPendingInProcess: true, _ownerKey: key },\n\t\t\t\t]),\n\t\t\t\tendOfList: offExisting.endOfList,\n\t\t\t\tstartKeyHistory: offExisting.startKeyHistory,\n\t\t\t};\n\t\t\tthis.dispatchAgentRequest({\n\t\t\t\tkey: key, serviceId: id.serviceId, owner: id.owner, aiPlatform: aiPlatform, aiModel: aiModel,\n\t\t\t\tsystemPrompt: systemPrompt, text: composed, boundedMessages: offBounded.messages, userId: chatQueue,\n\t\t\t\textractContent: extractContent, fileUrls: fileUrls,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (isQueuedSend) {\n\t\t\tvar resolvedHistory = this.state.messages.filter(function (m) {\n\t\t\t\treturn !m.isPending && !m.isPendingQueued && !m.isPendingInProcess && !m.isPendingOlder &&\n\t\t\t\t\t!m.isCancelled && !m.isBackgroundTask;\n\t\t\t});\n\t\t\tvar boundedQ = buildBoundedChatMessages({\n\t\t\t\tplatform: aiPlatform, model: aiModel, systemPrompt: systemPrompt, serviceId: id.serviceId,\n\t\t\t\thistory: resolvedHistory.concat([{ role: 'user', content: llmComposed }]),\n\t\t\t});\n\t\t\tvar queuedBubble: ChatMessage = { role: 'user', content: composed, isPendingQueued: true, isSendingToServer: true };\n\t\t\tif (key) queuedBubble._ownerKey = key;\n\t\t\tif (useBgQueue) queuedBubble._useBgQueue = true;\n\t\t\tthis.state.messages.push(queuedBubble);\n\t\t\tthis.host.notify(); this.updateHistoryCache(); this.host.scrollToBottom(true);\n\n\t\t\tvar capturedComposed = composed, capturedPlatform = aiPlatform, capturedKey = key;\n\t\t\tPromise.resolve(this._callProviderFor(aiPlatform, composed, boundedQ.messages, systemPrompt, aiModel, chatQueue, extractContent, fileUrls, id.serviceId, id.owner))\n\t\t\t\t.then(function (result: any) {\n\t\t\t\t\t// Only ack a bubble that belongs to THIS chat — the search is\n\t\t\t\t\t// positional, so on another project it would stamp this turn's\n\t\t\t\t\t// _serverItemId onto that project's unrelated in-flight bubble.\n\t\t\t\t\tvar sendingIdx = self.getHistoryCacheKey() !== capturedKey ? -1 : self.state.messages.findIndex(function (m) {\n\t\t\t\t\t\treturn m.isSendingToServer && (m.isPendingQueued || m.isPendingInProcess) && m.role === 'user' &&\n\t\t\t\t\t\t\t(m._ownerKey === undefined || m._ownerKey === capturedKey);\n\t\t\t\t\t});\n\t\t\t\t\tvar serverId = result && typeof result.id === 'string' ? result.id : undefined;\n\t\t\t\t\tif (sendingIdx >= 0) {\n\t\t\t\t\t\tvar upd = Object.assign({}, self.state.messages[sendingIdx], { isSendingToServer: false });\n\t\t\t\t\t\tif (serverId) upd._serverItemId = serverId;\n\t\t\t\t\t\tself.state.messages[sendingIdx] = upd; self.host.notify();\n\t\t\t\t\t}\n\t\t\t\t\tif (result && result.poll && (result.status === 'pending' || result.status === 'running')) {\n\t\t\t\t\t\t// Track this queued item's poll so a remount/refetch dedups\n\t\t\t\t\t\t// against it instead of attaching a duplicate history poll.\n\t\t\t\t\t\tvar qp = result.poll({ latency: POLL_INTERVAL });\n\t\t\t\t\t\tif (serverId) self._trackPoll(serverId, 'fg', qp);\n\t\t\t\t\t\treturn qp\n\t\t\t\t\t\t\t.then(function (res: any) { if (isPollStopped(res)) return; return self.onQueuedSendResponse(capturedComposed, res, capturedPlatform, serverId, capturedKey); })\n\t\t\t\t\t\t\t.catch(function (err: any) { return self.onQueuedSendError(capturedComposed, err, serverId, capturedKey); });\n\t\t\t\t\t}\n\t\t\t\t\treturn self.onQueuedSendResponse(capturedComposed, result, capturedPlatform, serverId, capturedKey);\n\t\t\t\t})\n\t\t\t\t.catch(function (err: any) { return self.onQueuedSendError(capturedComposed, err, undefined, capturedKey); });\n\t\t\treturn;\n\t\t}\n\n\t\t// immediate send — cache+resume model (mirrors agent.vue). The reply is\n\t\t// appended to aiChatHistoryCache by dispatchAgentRequest (so it survives a\n\t\t// view unmount), then rendered from the cache via typewriteLatestReply. A\n\t\t// later resumePendingRequest() re-renders it if the view remounted while the\n\t\t// request was still in flight.\n\t\tthis.state.messages.push({ role: 'user', content: composed, ...(key ? { _ownerKey: key } : {}) });\n\t\tthis.state.messages.push({ role: 'assistant', content: '', isPending: true, isPendingInProcess: true, ...(key ? { _ownerKey: key } : {}) });\n\t\tthis.host.notify(); this.updateHistoryCache(); this.state.sending = true; this.host.scrollToBottom(true);\n\n\t\tvar historyForLlm = this.state.messages.filter(function (m) { return !m.isCancelled && !m.isBackgroundTask; });\n\t\tif (llmComposed !== composed) {\n\t\t\tfor (var li = historyForLlm.length - 1; li >= 0; li--) {\n\t\t\t\tif (historyForLlm[li].role === 'user' && historyForLlm[li].content === composed) {\n\t\t\t\t\thistoryForLlm[li] = Object.assign({}, historyForLlm[li], { content: llmComposed });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvar bounded = buildBoundedChatMessages({\n\t\t\tplatform: aiPlatform, model: aiModel, systemPrompt: systemPrompt, serviceId: id.serviceId,\n\t\t\thistory: historyForLlm,\n\t\t});\n\t\tvar run = this.dispatchAgentRequest({\n\t\t\tkey: key, serviceId: id.serviceId, owner: id.owner, aiPlatform: aiPlatform, aiModel: aiModel,\n\t\t\tsystemPrompt: systemPrompt, text: composed, boundedMessages: bounded.messages, userId: chatQueue,\n\t\t\textractContent: extractContent, fileUrls: fileUrls,\n\t\t});\n\t\t// Render the reply into the \"Thinking...\" bubble whenever the chatbox is\n\t\t// CURRENTLY showing this chat — even after an unmount/remount. The old\n\t\t// guard bailed on `requestToken !== gateRefreshToken`, but EVERY remount\n\t\t// bumps gateRefreshToken (refreshGate), so a request that finished after\n\t\t// the user navigated away and back left a stuck \"Thinking...\" (no view\n\t\t// typewriter ever ran, and resumePendingRequest bails when a pending\n\t\t// bubble is already present). Gate on \"is this the visible chat\" instead.\n\t\t// When it ISN'T (unmounted / another project), dispatchAgentRequest has\n\t\t// already replaced the pending bubble with the answer IN THE CACHE, so a\n\t\t// later loadChatHistory renders it.\n\t\tPromise.resolve(run).catch(function () { }).then(function () {\n\t\t\t// Clear `sending` UNCONDITIONALLY. It is session-global (it gates\n\t\t\t// isQueuedSend above, plus the platform/model pickers in the view), so\n\t\t\t// leaving it set when the user navigated to another project wedged\n\t\t\t// every subsequent send in EVERY project onto the queued path and kept\n\t\t\t// the view's user-bubble rescue arm armed forever. Only the RENDER of\n\t\t\t// the reply stays gated on still showing this chat — when it isn't,\n\t\t\t// dispatchAgentRequest has already written the answer into the cache\n\t\t\t// under `key`, so a later loadChatHistory renders it.\n\t\t\tself.state.sending = false;\n\t\t\tif (!(self.host.isViewMounted() && self.getHistoryCacheKey() === key)) return;\n\t\t\treturn Promise.resolve(self.typewriteLatestReply(key)).then(function () { self.host.scrollToBottom(true); });\n\t\t});\n\t}\n\n\tpromoteNextBgQueuedToRunning(): void {\n\t\tif (this.state.messages.some(function (m) { return m.isPending && m.role === 'assistant' && m.isBackgroundTask; })) return;\n\t\tvar nextIdx = this.state.messages.findIndex(function (m) {\n\t\t\treturn m.isPendingQueued && m.role === 'user' && m.isBackgroundTask;\n\t\t});\n\t\tif (nextIdx === -1) return;\n\t\tvar existing = this.state.messages[nextIdx];\n\t\tvar promoted: ChatMessage = { role: 'user', content: existing.content, isPendingInProcess: true, isBackgroundTask: true };\n\t\tif (existing._serverItemId !== undefined) promoted._serverItemId = existing._serverItemId;\n\t\tif (existing._ownerKey !== undefined) promoted._ownerKey = existing._ownerKey;\n\t\tthis.state.messages[nextIdx] = promoted;\n\t\tvar placeholder: ChatMessage = { role: 'assistant', content: '', isPending: true, isPendingInProcess: true, isBackgroundTask: true };\n\t\tif (existing._serverItemId !== undefined) placeholder._serverItemId = existing._serverItemId;\n\t\tif (existing._ownerKey !== undefined) placeholder._ownerKey = existing._ownerKey;\n\t\tthis.state.messages.splice(nextIdx + 1, 0, placeholder);\n\t\tthis.host.notify();\n\t}\n\n\tpromoteNextQueuedToRunning(): void {\n\t\tif (this.state.messages.some(function (m) { return m.isPending && m.role === 'assistant' && !m.isBackgroundTask; })) return;\n\t\tvar nextIdx = this.state.messages.findIndex(function (m) {\n\t\t\treturn m.isPendingQueued && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue;\n\t\t});\n\t\tif (nextIdx === -1) return;\n\t\tvar existing = this.state.messages[nextIdx];\n\t\tvar promoted: ChatMessage = { role: 'user', content: existing.content, isPendingInProcess: true };\n\t\tif (existing.isBackgroundTask) promoted.isBackgroundTask = true;\n\t\tif (existing._serverItemId !== undefined) promoted._serverItemId = existing._serverItemId;\n\t\tif (existing._ownerKey !== undefined) promoted._ownerKey = existing._ownerKey;\n\t\tif (existing.isSendingToServer) promoted.isSendingToServer = true;\n\t\tthis.state.messages[nextIdx] = promoted;\n\t\t// Carry the promoted turn's _serverItemId onto the \"Thinking...\" placeholder\n\t\t// (mirrors promoteNextBgQueuedToRunning). Without it, when this promoted turn\n\t\t// is resolved via the history-poll path — applyHistoryItemResolution, which\n\t\t// matches the pending assistant by _serverItemId — the placeholder is not\n\t\t// found, so the reply is spliced in BESIDE it and the \"Thinking...\" is\n\t\t// stranded forever (e.g. after a reload, or when a cancel advances the queue).\n\t\t// onQueuedSendResponse still finds it by position, so the queued-send path is\n\t\t// unaffected.\n\t\tvar placeholder: ChatMessage = { role: 'assistant', content: '', isPending: true };\n\t\tif (existing._serverItemId !== undefined) placeholder._serverItemId = existing._serverItemId;\n\t\tif (existing._ownerKey !== undefined) placeholder._ownerKey = existing._ownerKey;\n\t\tthis.state.messages.splice(nextIdx + 1, 0, placeholder);\n\t\tthis.host.notify();\n\t}\n\n\tresolveQueuedUserBubble(serverId?: string): number | undefined {\n\t\t// The two fallbacks below match by POSITION, not identity, so they must\n\t\t// never consider a bubble stamped for a different chat.\n\t\tvar liveKey = this.getHistoryCacheKey();\n\t\tvar isLocal = function (m: ChatMessage) { return m._ownerKey === undefined || m._ownerKey === liveKey; };\n\t\tvar userIdx = -1;\n\t\tif (serverId) {\n\t\t\tuserIdx = this.state.messages.findIndex(function (m) {\n\t\t\t\treturn m._serverItemId === serverId && (m.isPendingInProcess || m.isPendingQueued) &&\n\t\t\t\t\tm.role === 'user' && !m.isBackgroundTask;\n\t\t\t});\n\t\t}\n\t\tif (userIdx === -1) {\n\t\t\tuserIdx = this.state.messages.findIndex(function (m) {\n\t\t\t\treturn m.isPendingInProcess && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue && isLocal(m);\n\t\t\t});\n\t\t}\n\t\tif (userIdx === -1) {\n\t\t\tuserIdx = this.state.messages.findIndex(function (m) {\n\t\t\t\treturn m.isPendingQueued && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue && isLocal(m);\n\t\t\t});\n\t\t}\n\t\tif (serverId && this.cancelledServerIds.has(serverId)) {\n\t\t\tthis.cancelledServerIds.delete(serverId);\n\t\t\tif (userIdx >= 0) {\n\t\t\t\tvar ex = this.state.messages[userIdx];\n\t\t\t\tthis.state.messages[userIdx] = { role: 'user', content: ex.content, isCancelled: true, _serverItemId: ex._serverItemId, ...(ex._ownerKey !== undefined ? { _ownerKey: ex._ownerKey } : {}) };\n\t\t\t\tvar thIdx = this.state.messages.findIndex(function (m, i) {\n\t\t\t\t\treturn i > userIdx && m.isPending && m.role === 'assistant' && !m.isBackgroundTask;\n\t\t\t\t});\n\t\t\t\tif (thIdx !== -1) this.state.messages.splice(thIdx, 1);\n\t\t\t}\n\t\t\tthis.promoteNextQueuedToRunning();\n\t\t\treturn undefined;\n\t\t}\n\t\tif (userIdx >= 0) {\n\t\t\tvar exist = this.state.messages[userIdx];\n\t\t\tvar repl: ChatMessage = { role: 'user', content: exist.content };\n\t\t\tif (exist._serverItemId !== undefined) repl._serverItemId = exist._serverItemId;\n\t\t\tif (exist._ownerKey !== undefined) repl._ownerKey = exist._ownerKey;\n\t\t\tthis.state.messages[userIdx] = repl;\n\t\t}\n\t\tvar thinkingIdx = userIdx >= 0\n\t\t\t? this.state.messages.findIndex(function (m, i) { return i > userIdx && m.isPending && m.role === 'assistant' && !m.isBackgroundTask; })\n\t\t\t: -1;\n\t\treturn thinkingIdx !== -1 ? thinkingIdx : (userIdx >= 0 ? userIdx + 1 : -1);\n\t}\n\n\tinsertAtTarget(msg: ChatMessage, targetIdx: number): void {\n\t\tif (targetIdx >= 0 && this.state.messages[targetIdx] && this.state.messages[targetIdx].isPending) this.state.messages[targetIdx] = msg;\n\t\telse if (targetIdx >= 0) this.state.messages.splice(targetIdx, 0, msg);\n\t\telse this.state.messages.push(msg);\n\t}\n\n\tonQueuedSendResponse(_composed: string, response: any, platform: string, serverId?: string, ownerKey?: string): void {\n\t\tif (serverId) this.historyItemPolls.delete(serverId);\n\t\t// This turn resolved while a DIFFERENT chat is on screen (the user moved to\n\t\t// another project mid-flight). state.messages now belongs to that chat, and\n\t\t// resolveQueuedUserBubble's positional fallbacks would happily hijack ITS\n\t\t// pending bubble — or, finding nothing, push this answer onto its list.\n\t\t// Settle in the owning chat's cache instead and leave the view untouched.\n\t\tif (ownerKey && this.getHistoryCacheKey() !== ownerKey) {\n\t\t\tvar offReply: ChatMessage = isErrorResponseBody(response)\n\t\t\t\t? { role: 'assistant', content: getErrorMessage(response), isError: true }\n\t\t\t\t: { role: 'assistant', content: ((platform === 'openai' ? extractOpenAIText(response) : extractClaudeText(response)) || '').trim() || 'No text response received from AI provider.' };\n\t\t\tthis._applyReplyToCache(ownerKey, offReply, serverId);\n\t\t\tif (serverId) this.cancelledServerIds.delete(serverId);\n\t\t\treturn;\n\t\t}\n\t\tvar targetIdx = this.resolveQueuedUserBubble(serverId);\n\t\tif (targetIdx === undefined) { this.host.notify(); this.updateHistoryCache(); return; }\n\t\tif (isErrorResponseBody(response)) {\n\t\t\tthis.insertAtTarget({ role: 'assistant', content: getErrorMessage(response), isError: true }, targetIdx);\n\t\t} else {\n\t\t\tvar answer = (platform === 'openai' ? extractOpenAIText(response) : extractClaudeText(response));\n\t\t\tanswer = (answer || '').trim() || 'No text response received from AI provider.';\n\t\t\tvar lid = this._newLocalId();\n\t\t\tif (targetIdx >= 0 && this.state.messages[targetIdx] && this.state.messages[targetIdx].isPending) {\n\t\t\t\tthis.state.messages[targetIdx] = { role: 'assistant', content: '', _localId: lid };\n\t\t\t\tthis.host.notify(); this.enqueueTypewrite(targetIdx, answer, lid);\n\t\t\t} else if (targetIdx >= 0) {\n\t\t\t\tthis.state.messages.splice(targetIdx, 0, { role: 'assistant', content: '', _localId: lid });\n\t\t\t\tthis.host.notify(); this.enqueueTypewrite(targetIdx, answer, lid);\n\t\t\t} else {\n\t\t\t\tvar aiIdx = this.state.messages.length;\n\t\t\t\tthis.state.messages.push({ role: 'assistant', content: '', _localId: lid });\n\t\t\t\tthis.host.notify(); this.enqueueTypewrite(aiIdx, answer, lid);\n\t\t\t}\n\t\t}\n\t\tthis._removeStrayPendingAssistants();\n\t\tthis.promoteNextQueuedToRunning();\n\t\tthis.updateHistoryCache();\n\t\tthis.host.notify();\n\t\tthis.host.scrollToBottom(true);\n\t}\n\n\tonQueuedSendError(_composed: string, err: any, serverId?: string, ownerKey?: string): void {\n\t\tvar self = this;\n\t\tif (serverId) this.historyItemPolls.delete(serverId);\n\t\t// Off-chat resolution — see onQueuedSendResponse. Settle in the owning\n\t\t// chat's cache rather than mutating whatever chat is on screen now.\n\t\tif (ownerKey && this.getHistoryCacheKey() !== ownerKey) {\n\t\t\tvar isGone = err && (err.code === 'NOT_EXISTS' || (err.body && err.body.code === 'NOT_EXISTS'));\n\t\t\tthis._applyReplyToCache(ownerKey, isGone\n\t\t\t\t? { role: 'assistant', content: 'Request was cancelled.', isError: true }\n\t\t\t\t: { role: 'assistant', content: getErrorMessage(err), isError: true }, serverId);\n\t\t\tif (serverId) this.cancelledServerIds.delete(serverId);\n\t\t\treturn;\n\t\t}\n\t\tvar isNotExists = err && (err.code === 'NOT_EXISTS' || (err.body && err.body.code === 'NOT_EXISTS'));\n\t\tif (isNotExists) {\n\t\t\tvar userIdx = serverId\n\t\t\t\t? this.state.messages.findIndex(function (m) { return m._serverItemId === serverId && (m.isPendingInProcess || m.isPendingQueued) && m.role === 'user' && !m.isBackgroundTask; })\n\t\t\t\t: this.state.messages.findIndex(function (m) { return m.isPendingInProcess && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue; });\n\t\t\tif (!serverId && userIdx === -1) {\n\t\t\t\tuserIdx = this.state.messages.findIndex(function (m) { return m.isPendingQueued && m.role === 'user' && !m.isBackgroundTask && !m._useBgQueue; });\n\t\t\t}\n\t\t\tif (userIdx >= 0) {\n\t\t\t\tvar ex = this.state.messages[userIdx];\n\t\t\t\tvar repl: ChatMessage = { role: 'user', content: ex.content, isCancelled: true };\n\t\t\t\tif (ex._serverItemId !== undefined) repl._serverItemId = ex._serverItemId;\n\t\t\t\tthis.state.messages[userIdx] = repl;\n\t\t\t}\n\t\t\tif (serverId) {\n\t\t\t\tvar thById = this.state.messages.findIndex(function (m) { return m._serverItemId === serverId && m.isPending && m.role === 'assistant' && !m.isBackgroundTask; });\n\t\t\t\tif (thById !== -1) this.state.messages.splice(thById, 1);\n\t\t\t\telse if (userIdx >= 0) {\n\t\t\t\t\tvar thPos = this.state.messages.findIndex(function (m, i) { return i > userIdx && m.isPending && m.role === 'assistant' && !m.isBackgroundTask; });\n\t\t\t\t\tif (thPos !== -1) this.state.messages.splice(thPos, 1);\n\t\t\t\t}\n\t\t\t} else if (userIdx >= 0) {\n\t\t\t\tvar thPos2 = this.state.messages.findIndex(function (m, i) { return i > userIdx && m.isPending && m.role === 'assistant' && !m.isBackgroundTask; });\n\t\t\t\tif (thPos2 !== -1) this.state.messages.splice(thPos2, 1);\n\t\t\t}\n\t\t\tif (serverId) this.cancelledServerIds.delete(serverId);\n\t\t\tthis._removeStrayPendingAssistants();\n\t\t\tthis.promoteNextQueuedToRunning(); this.updateHistoryCache(); this.host.notify(); this.host.scrollToBottom(true);\n\t\t\treturn;\n\t\t}\n\t\tvar targetIdx = this.resolveQueuedUserBubble(serverId);\n\t\tif (targetIdx === undefined) { this.host.notify(); this.updateHistoryCache(); return; }\n\t\tthis.insertAtTarget({ role: 'assistant', content: getErrorMessage(err), isError: true }, targetIdx);\n\t\tthis._removeStrayPendingAssistants();\n\t\tthis.promoteNextQueuedToRunning(); this.updateHistoryCache(); this.host.notify(); this.host.scrollToBottom(true);\n\t}\n\n\tcancelQueuedMessage(msg: ChatMessage, idx: number): void {\n\t\tvar self = this;\n\t\tvar id = this.host.getIdentity();\n\t\tvar serverId = msg._serverItemId;\n\t\tif (!serverId || msg._cancelling) return;\n\t\tvar platform = id.platform;\n\t\tif (platform !== 'claude' && platform !== 'openai') return;\n\t\tvar url = platform === 'claude' ? ANTHROPIC_MESSAGES_API_URL : OPENAI_RESPONSES_API_URL;\n\t\tvar queueBase = id.userId || id.serviceId;\n\t\tvar queue = (msg.isBackgroundTask || msg._useBgQueue) ? queueBase + BG_INDEXING_QUEUE_SUFFIX : queueBase;\n\t\tthis.state.messages[idx] = Object.assign({}, msg, { _cancelling: true, _cancelError: undefined });\n\t\tthis.host.notify();\n\t\tPromise.resolve(this.host.cancelRequest({\n\t\t\turl: url, method: 'POST', id: serverId, queue: queue, service: id.serviceId, owner: id.owner,\n\t\t})).then(function (result: any) {\n\t\t\tif (result && result.removed) {\n\t\t\t\tself.cancelledServerIds.add(serverId as string);\n\t\t\t\tvar qi = self.bgTaskQueue.findIndex(function (e) { return e.id === serverId; });\n\t\t\t\tif (qi !== -1) self.bgTaskQueue.splice(qi, 1);\n\t\t\t\tvar removeIdx = self.state.messages.findIndex(function (m) {\n\t\t\t\t\treturn m._serverItemId === serverId && (m.isPendingQueued || m.isPendingInProcess) && m.role === 'user';\n\t\t\t\t});\n\t\t\t\tif (removeIdx !== -1) {\n\t\t\t\t\tself.state.messages[removeIdx] = { role: 'user', content: self.state.messages[removeIdx].content, isCancelled: true, _serverItemId: serverId };\n\t\t\t\t\tvar thById = self.state.messages.findIndex(function (m) { return m._serverItemId === serverId && m.isPending && m.role === 'assistant'; });\n\t\t\t\t\tif (thById !== -1) self.state.messages.splice(thById, 1);\n\t\t\t\t\telse {\n\t\t\t\t\t\tvar thPos = self.state.messages.findIndex(function (m, i) {\n\t\t\t\t\t\t\treturn i > removeIdx && m.isPending && m.role === 'assistant' &&\n\t\t\t\t\t\t\t\t(msg.isBackgroundTask ? !!m.isBackgroundTask : !m.isBackgroundTask);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (thPos !== -1) self.state.messages.splice(thPos, 1);\n\t\t\t\t\t}\n\t\t\t\t\tif (msg.isBackgroundTask) self.promoteNextBgQueuedToRunning(); else self.promoteNextQueuedToRunning();\n\t\t\t\t\tself.updateHistoryCache();\n\t\t\t\t}\n\t\t\t\tself.host.notify();\n\t\t\t} else {\n\t\t\t\tvar errMsg = result && typeof result.message === 'string' && result.message ? result.message : 'Could not remove from queue.';\n\t\t\t\tvar ci = self.state.messages.findIndex(function (m) { return m._serverItemId === serverId && m.role === 'user'; });\n\t\t\t\tif (ci !== -1) { self.state.messages[ci] = Object.assign({}, self.state.messages[ci], { _cancelling: false, _cancelError: errMsg }); self.host.notify(); }\n\t\t\t}\n\t\t}).catch(function (err: any) {\n\t\t\tvar errMsg = err && typeof err.message === 'string' && err.message ? err.message : 'Could not remove from queue.';\n\t\t\tvar ci = self.state.messages.findIndex(function (m) { return m._serverItemId === serverId && m.role === 'user'; });\n\t\t\tif (ci !== -1) { self.state.messages[ci] = Object.assign({}, self.state.messages[ci], { _cancelling: false, _cancelError: errMsg }); self.host.notify(); }\n\t\t});\n\t}\n\n\t// --- typewriter -------------------------------------------------------\n\t// Reveal `fullText` into a message bubble at a constant wall-clock RATE\n\t// (chars/second) driven by requestAnimationFrame, rather than a fixed number\n\t// of characters per fixed-delay tick. This is what keeps typing smooth and\n\t// cheap on slow machines:\n\t//\n\t// * Each frame reveals `elapsed_ms * CHARS_PER_SEC` characters, so the\n\t// visual speed is the same regardless of how long a frame actually took.\n\t// * As the bubble's markdown grows, each re-render gets more expensive, so\n\t// frames get longer — which makes each frame reveal MORE characters and\n\t// therefore do FEWER, larger renders. That converts the old O(n^2)\n\t// \"re-render the whole growing string once per 3 characters\" (which got\n\t// slower and slower and pegged the CPU) into roughly O(n): the number of\n\t// renders self-throttles to what the machine can actually paint.\n\t// * rAF paces us to the browser's paint cycle and pauses in background\n\t// tabs, so we never queue work faster than it can be drawn.\n\ttypewriteIntoIndex(idx: number, fullText: string, localId?: string): Promise<void> {\n\t\tvar self = this;\n\t\tif (!fullText) return Promise.resolve();\n\n\t\tvar CHARS_PER_SEC = 300; // reveal rate (was ~188 = 3 chars / 16ms) — a bit faster\n\t\tvar MIN_STEP = 1; // always make progress, even on a sub-ms frame\n\t\tvar MAX_FRAME_MS = 1000; // cap catch-up after a long stall / backgrounded tab\n\n\t\t// Atomic regions that must never be left half-revealed: file fences\n\t\t// (shown as a download chip / hidden as \"[generating …]\" while unclosed —\n\t\t// and potentially huge, so revealed in one jump) and inline links\n\t\t// (a partial link is broken markdown). If a frame's reveal boundary lands\n\t\t// inside one, snap it to the region end so the chip/link appears whole.\n\t\tvar regions: Array<{ start: number; end: number }> = [], m;\n\t\tvar fenceRegex = /```[^\\n`]+?\\.[^\\s.`]+\\n[\\s\\S]*?```/g;\n\t\twhile ((m = fenceRegex.exec(fullText)) !== null) regions.push({ start: m.index, end: m.index + m[0].length });\n\t\tvar linkRegex = createInlineLinkRegex();\n\t\twhile ((m = linkRegex.exec(fullText)) !== null) regions.push({ start: m.index, end: m.index + m[0].length });\n\t\tregions.sort(function (a, b) { return a.start - b.start; });\n\n\t\tthis.state.typing = true; this.state.typingAbort = false;\n\t\tvar i = 0;\n\t\tvar last = nowMs();\n\n\t\treturn new Promise<void>(function (resolve) {\n\t\t\tvar done = false;\n\t\t\tvar doc: any = _g.document;\n\t\t\tfunction isHidden(): boolean { return !!(doc && doc.hidden); }\n\t\t\tfunction cleanup(): void {\n\t\t\t\tif (doc && doc.removeEventListener) doc.removeEventListener('visibilitychange', onVisibility);\n\t\t\t}\n\t\t\tfunction finish(): void {\n\t\t\t\tif (done) return;\n\t\t\t\tdone = true;\n\t\t\t\tcleanup();\n\t\t\t\tif (!self.state.typingAbort) {\n\t\t\t\t\t// Re-find the bubble by localId and, if it's gone, bail WITHOUT\n\t\t\t\t\t// writing — never fall back to the numeric idx, which a concurrent\n\t\t\t\t\t// array mutation may have repurposed for an unrelated message\n\t\t\t\t\t// (mirrors frame()'s currentIdx===-1 bail below).\n\t\t\t\t\tvar fi = localId ? self.state.messages.findIndex(function (mm) { return mm._localId === localId; }) : idx;\n\t\t\t\t\tif (fi !== -1) {\n\t\t\t\t\t\tvar t = self.state.messages[fi];\n\t\t\t\t\t\tif (t) { t.content = fullText; self.host.refreshMessageBubble(fi); }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tself.state.typing = false;\n\t\t\t\tresolve();\n\t\t\t}\n\t\t\t// requestAnimationFrame is PAUSED in a backgrounded tab (setTimeout only\n\t\t\t// throttles), so an rAF-driven reveal would freeze there — leaving a blank\n\t\t\t// bubble and stalling the sequential enqueueTypewrite queue until refocus.\n\t\t\t// When the page is (or becomes) hidden, skip the animation and show the\n\t\t\t// full text immediately so the queue keeps draining.\n\t\t\tfunction onVisibility(): void { if (isHidden()) finish(); }\n\t\t\tif (doc && doc.addEventListener) doc.addEventListener('visibilitychange', onVisibility);\n\t\t\tfunction frame(t: number): void {\n\t\t\t\tif (done) return;\n\t\t\t\tif (self.state.typingAbort || i >= fullText.length || isHidden()) { finish(); return; }\n\n\t\t\t\tvar dt = t - last; last = t;\n\t\t\t\tif (!(dt > 0)) dt = 16; // first frame / clock glitch\n\t\t\t\tif (dt > MAX_FRAME_MS) dt = MAX_FRAME_MS;\n\t\t\t\tvar step = Math.round(dt * CHARS_PER_SEC / 1000);\n\t\t\t\tif (step < MIN_STEP) step = MIN_STEP;\n\t\t\t\tvar next = Math.min(fullText.length, i + step);\n\n\t\t\t\t// Extend past any atomic region the newly-revealed span (i, next]\n\t\t\t\t// cuts into. Iterate to convergence so back-to-back regions (e.g. a\n\t\t\t\t// link right after a fence) are all revealed whole in one frame.\n\t\t\t\tfor (var changed = true; changed;) {\n\t\t\t\t\tchanged = false;\n\t\t\t\t\tfor (var k = 0; k < regions.length; k++) {\n\t\t\t\t\t\tvar r = regions[k];\n\t\t\t\t\t\tif (next > r.start && i < r.end && r.end > next) { next = r.end; changed = true; }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (next > fullText.length) next = fullText.length;\n\t\t\t\ti = next;\n\n\t\t\t\tvar currentIdx = localId ? self.state.messages.findIndex(function (mm) { return mm._localId === localId; }) : idx;\n\t\t\t\tif (currentIdx === -1) { finish(); return; }\n\t\t\t\tvar target = self.state.messages[currentIdx];\n\t\t\t\tif (!target) { finish(); return; }\n\t\t\t\ttarget.content = fullText.slice(0, i);\n\t\t\t\tself.host.refreshMessageBubble(currentIdx);\n\t\t\t\tself.host.scrollToBottomIfSticky();\n\t\t\t\tnextFrame(frame);\n\t\t\t}\n\t\t\tif (isHidden()) { finish(); return; }\n\t\t\tnextFrame(frame);\n\t\t});\n\t}\n\n\tprivate typewriterQueue: Promise<any> = Promise.resolve();\n\tenqueueTypewrite(idx: number, fullText: string, localId?: string): Promise<any> {\n\t\tvar self = this;\n\t\tthis.typewriterQueue = this.typewriterQueue.then(function () { return self.typewriteIntoIndex(idx, fullText, localId); });\n\t\treturn this.typewriterQueue;\n\t}\n\n\t// --- cache+resume immediate-send rendering -----------------------------\n\t// Render the just-resolved reply (read from aiChatHistoryCache) into the\n\t// pending assistant bubble, character-by-character. Runs AFTER the reply is\n\t// already in the cache (dispatchAgentRequest appended it); errors are shown\n\t// instantly (no typing). Promotes the next queued message immediately so its\n\t// \"Thinking…\" bubble appears without waiting for this typewriter to finish.\n\ttypewriteLatestReply(key: string): Promise<any> {\n\t\tvar cached = this.aiChatHistoryCache[key];\n\t\tif (!cached || !cached.messages.length) return Promise.resolve();\n\t\tvar latest: ChatMessage | undefined;\n\t\tfor (var i = cached.messages.length - 1; i >= 0; i--) {\n\t\t\tvar m = cached.messages[i];\n\t\t\tif (m.role === 'assistant' && !m.isPending) { latest = m; break; }\n\t\t}\n\t\tif (!latest) return Promise.resolve();\n\t\tvar pendingIdx = this.state.messages.findIndex(function (mm) {\n\t\t\treturn mm.isPending && mm.role === 'assistant' && !mm.isBackgroundTask;\n\t\t});\n\t\tif (pendingIdx === -1) return Promise.resolve();\n\t\tif (latest.isError || !latest.content) {\n\t\t\tthis.state.messages[pendingIdx] = { role: 'assistant', content: latest.content || '', isError: !!latest.isError };\n\t\t\tthis._removeStrayPendingAssistants();\n\t\t\tthis.host.notify();\n\t\t\tthis.promoteNextQueuedToRunning();\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\tvar lid = this._newLocalId();\n\t\tthis.state.messages[pendingIdx] = { role: 'assistant', content: '', isPending: false, _localId: lid };\n\t\tthis._removeStrayPendingAssistants();\n\t\tthis.host.notify();\n\t\tthis.promoteNextQueuedToRunning();\n\t\treturn this.enqueueTypewrite(pendingIdx, latest.content, lid);\n\t}\n\n\t// Remove any leftover non-background pending (\"Thinking…\") assistant bubbles.\n\t// There is normally at most ONE such bubble at a time (promoteNext* refuses to\n\t// add a second), so any extra is a duplicate — it appears when a concurrent\n\t// history refetch re-maps the still-\"running\" turn into a pending placeholder\n\t// (with a real _serverItemId) while the local pending bubble (no _serverItemId)\n\t// is rescued and re-appended (see loadHistory rescue below). Each resolve path\n\t// only replaces the FIRST pending bubble, so without this a stray \"Thinking…\"\n\t// survives next to the reply/error. MUST run AFTER the resolved bubble has been\n\t// made non-pending and BEFORE promoteNext*() (so a freshly-promoted Thinking,\n\t// which is added only once no pending assistant remains, is preserved).\n\t_removeStrayPendingAssistants(): void {\n\t\tfor (var k = this.state.messages.length - 1; k >= 0; k--) {\n\t\t\tvar m = this.state.messages[k];\n\t\t\tif (m.isPending && m.role === 'assistant' && !m.isBackgroundTask) this.state.messages.splice(k, 1);\n\t\t}\n\t}\n\n\t// Drop the pending flags on the resolved turn's USER bubble (preserving its\n\t// content + background-task marker). Needed because a bg \"Indexing:\" turn's user\n\t// bubble carries isPendingInProcess; leaving it set keeps the bubble visually\n\t// stuck and keeps its bgTaskQueue entry alive forever.\n\t_clearPendingUserBubble(itemId: string): void {\n\t\tvar uIdx = this.state.messages.findIndex(function (m) {\n\t\t\treturn m.role === 'user' && m._serverItemId === itemId &&\n\t\t\t\t(m.isPendingInProcess || m.isPendingQueued || m.isSendingToServer);\n\t\t});\n\t\tif (uIdx === -1) return;\n\t\tvar u = this.state.messages[uIdx];\n\t\tvar cleaned: ChatMessage = { role: 'user', content: u.content, _serverItemId: itemId };\n\t\tif (u.isBackgroundTask) cleaned.isBackgroundTask = true;\n\t\tthis.state.messages[uIdx] = cleaned;\n\t}\n\n\t// If an immediate-send request for the current cache key is still in flight\n\t// (e.g. the view unmounted then remounted mid-request), show the sending\n\t// state, await it, then render the reply from the cache. Skipped when the\n\t// list already has its own pending/queued bubbles (those resolve via their\n\t// own polls). The displayed reply also lands via dispatchComposedMessage's\n\t// own finally if the view never unmounted — this is the remount recovery.\n\tresumePendingRequest(token: number): Promise<void> {\n\t\tvar self = this;\n\t\tvar key = this.getHistoryCacheKey();\n\t\tvar pending = key ? this.pendingAgentRequests[key] : undefined;\n\t\tif (!pending) return Promise.resolve();\n\t\tif (this.state.messages.some(function (m) { return (m.isPending || m.isPendingQueued) && !m.isBackgroundTask && !m._useBgQueue; })) return Promise.resolve();\n\t\tthis.state.sending = true;\n\t\tthis.host.scrollToBottom(true);\n\t\treturn Promise.resolve(pending).catch(function () { }).then(function () {\n\t\t\tif (token !== self.state.gateRefreshToken) return;\n\t\t\tself.state.sending = false;\n\t\t\treturn Promise.resolve(self.typewriteLatestReply(key)).then(function () { self.host.scrollToBottom(true); });\n\t\t});\n\t}\n\n\t// --- background-task resolution + drain -------------------------------\n\thandleHistoryItemResolution(itemId: string, response: any, platform: string): void {\n\t\tthis.applyHistoryItemResolution(itemId, response, platform);\n\t\tthis.promoteNextBgQueuedToRunning();\n\t}\n\n\tapplyHistoryItemResolution(itemId: string, response: any, platform: string): void {\n\t\tthis.historyItemPolls.delete(itemId);\n\t\tvar isErr = isErrorResponseBody(response);\n\t\tvar answer = isErr ? getErrorMessage(response)\n\t\t\t: ((platform === 'openai' ? extractOpenAIText(response) : extractClaudeText(response)) || '').trim();\n\t\t// Hide the internal indexing-completion marker from the displayed summary.\n\t\tif (!isErr && answer) answer = answer.split(INDEXING_COMPLETE_MARKER).join('').trim();\n\t\tvar idx = this.state.messages.findIndex(function (m) { return m.isPending && m._serverItemId === itemId; });\n\t\tif (idx !== -1) {\n\t\t\t// A bg \"Indexing:\" turn pushes a user bubble (isPendingInProcess) ALONGSIDE\n\t\t\t// the assistant Thinking; replacing only the assistant leaves that user\n\t\t\t// bubble stuck pending — and drainBgTaskQueue then never clears its queue\n\t\t\t// entry (its stillPending check stays true). Un-pend it here too.\n\t\t\tthis._clearPendingUserBubble(itemId);\n\t\t\tif (isErr) {\n\t\t\t\tthis.state.messages[idx] = { role: 'assistant', content: answer, isError: true, _serverItemId: itemId };\n\t\t\t\tthis.host.notify(); this.updateHistoryCache(); return;\n\t\t\t}\n\t\t\tvar lid = this._newLocalId();\n\t\t\tthis.state.messages[idx] = { role: 'assistant', content: '', _localId: lid, _serverItemId: itemId };\n\t\t\tthis.host.notify(); this.enqueueTypewrite(idx, answer || 'No text response received from AI provider.', lid);\n\t\t\tthis.updateHistoryCache(); return;\n\t\t}\n\t\tvar userIdx = this.state.messages.findIndex(function (m) {\n\t\t\treturn m.role === 'user' && m._serverItemId === itemId && (m.isPendingQueued || m.isPendingInProcess);\n\t\t});\n\t\tif (userIdx === -1) return;\n\t\tvar ex = this.state.messages[userIdx];\n\t\tthis.state.messages[userIdx] = { role: 'user', content: ex.content, _serverItemId: itemId };\n\t\tif (isErr) {\n\t\t\tthis.state.messages.splice(userIdx + 1, 0, { role: 'assistant', content: answer, isError: true, _serverItemId: itemId });\n\t\t\tthis.host.notify(); this.updateHistoryCache(); return;\n\t\t}\n\t\tvar lid2 = this._newLocalId();\n\t\tthis.state.messages.splice(userIdx + 1, 0, { role: 'assistant', content: '', _localId: lid2, _serverItemId: itemId });\n\t\tthis.host.notify(); this.enqueueTypewrite(userIdx + 1, answer || 'No text response received from AI provider.', lid2);\n\t\tthis.updateHistoryCache();\n\t}\n\n\t// Inject \"Indexing: <file>\" bubbles for queued bg tasks + attach their polls.\n\tdrainBgTaskQueue(): void {\n\t\tvar self = this;\n\t\tvar id = this.host.getIdentity();\n\t\tvar svcId = id.serviceId, plat = id.platform;\n\t\tif (!svcId || plat === 'none' || !this.host.isViewMounted()) return;\n\t\t// Index messages by _serverItemId ONCE, so the per-entry presence/pending\n\t\t// checks below are O(1) instead of a full messages.some() scan each. With a\n\t\t// large bg queue (bulk uploads) the old nested scan was O(queue x messages)\n\t\t// per drain, and the drain runs once per uploaded file (O(n^3) overall).\n\t\tvar presentIds: { [id: string]: boolean } = {};\n\t\tvar pendingIds: { [id: string]: boolean } = {};\n\t\tthis.state.messages.forEach(function (m) {\n\t\t\tvar sid = m._serverItemId;\n\t\t\tif (sid == null) return;\n\t\t\tpresentIds[sid] = true;\n\t\t\tif (m.isPending || m.isPendingInProcess || m.isPendingQueued) pendingIds[sid] = true;\n\t\t});\n\t\tfor (var i = this.bgTaskQueue.length - 1; i >= 0; i--) {\n\t\t\tvar e = this.bgTaskQueue[i];\n\t\t\tif (e.serviceId !== svcId || e.platform !== plat) continue;\n\t\t\tif (presentIds[e.id] && !pendingIds[e.id]) this.bgTaskQueue.splice(i, 1);\n\t\t}\n\t\tthis.bgTaskQueue.forEach(function (entry) {\n\t\t\tif (entry.serviceId !== svcId || entry.platform !== plat) return;\n\t\t\t// Bubble injection and poll attachment are INDEPENDENT. An entry whose bubble\n\t\t\t// already exists may still need a poll — that is exactly the state a paused\n\t\t\t// drain leaves behind, and returning early here stranded it as a permanent\n\t\t\t// \"Thinking...\" once polling resumed.\n\t\t\tif (!presentIds[entry.id]) {\n\t\t\tvar isRunning = entry.status === 'running';\n\t\t\tvar userBubble: ChatMessage = { role: 'user', content: self.host.formatIndexingLabel(entry.filename, entry.mime, entry.size, entry.storagePath, entry.isReindex), isBackgroundTask: true, _serverItemId: entry.id };\n\t\t\tif (isRunning) userBubble.isPendingInProcess = true; else userBubble.isPendingQueued = true;\n\t\t\tself.state.messages.push(userBubble);\n\t\t\tif (isRunning) {\n\t\t\t\tself.state.messages.push({ role: 'assistant', content: '', isPending: true, isPendingInProcess: true, isBackgroundTask: true, _serverItemId: entry.id });\n\t\t\t}\n\t\t\tpresentIds[entry.id] = true; // keep the index consistent with the pushed bubbles\n\t\t\tself.host.notify(); self.updateHistoryCache(); self.host.scrollToBottom(false);\n\t\t\t}\n\t\t\tif (!self.isPollingPaused() && !self.historyItemPolls.has(entry.id) && typeof entry.poll === 'function') {\n\t\t\t\tvar capturedId = entry.id, capturedPlat = plat;\n\t\t\t\tvar capturedEntry = entry;\n\t\t\t\tvar wasStopped = false;\n\t\t\t\tvar bp = entry.poll({ latency: POLL_INTERVAL });\n\t\t\t\tself._trackPoll(entry.id, 'bg', bp);\n\t\t\t\tbp.then(function (response: any) {\n\t\t\t\t\t// A stopped poll is not a result: leave the bubble and the queue entry\n\t\t\t\t\t// exactly as they were so resumePolling can re-attach.\n\t\t\t\t\tif (isPollStopped(response)) { wasStopped = true; return; }\n\t\t\t\t\tself.handleHistoryItemResolution(capturedId, response, capturedPlat);\n\t\t\t\t\tself.maybeResumeIndexing(capturedEntry, response, capturedPlat);\n\t\t\t\t}).catch(function (err: any) {\n\t\t\t\t\tself.historyItemPolls.delete(capturedId);\n\t\t\t\t\tvar isNotExists = err && (err.code === 'NOT_EXISTS' || (err.body && err.body.code === 'NOT_EXISTS'));\n\t\t\t\t\tvar bi = self.state.messages.findIndex(function (m) { return m.isPending && m._serverItemId === capturedId; });\n\t\t\t\t\tif (bi !== -1) {\n\t\t\t\t\t\tif (isNotExists) self.state.messages.splice(bi, 1);\n\t\t\t\t\t\telse self.state.messages[bi] = { role: 'assistant', content: getErrorMessage(err), isError: true, isBackgroundTask: true, _serverItemId: capturedId };\n\t\t\t\t\t\tself.host.notify(); self.updateHistoryCache();\n\t\t\t\t\t}\n\t\t\t\t}).then(function () {\n\t\t\t\t\t// Keep the queue entry when the poll was merely stopped, or resuming\n\t\t\t\t\t// would have nothing left to re-attach to.\n\t\t\t\t\tif (wasStopped) return;\n\t\t\t\t\tvar qi = self.bgTaskQueue.findIndex(function (q) { return q.id === capturedId; });\n\t\t\t\t\tif (qi !== -1) self.bgTaskQueue.splice(qi, 1);\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\tthis.promoteNextBgQueuedToRunning();\n\t}\n\n\t// Resume-across-passes: if a background INDEXING task for a paged file (spreadsheet or\n\t// text) finished WITHOUT the completion marker, the agent ran out of room before reading\n\t// the whole file - dispatch a CONTINUE pass (up to a cap) that resumes from where the\n\t// already-saved records leave off. Additive + guarded so it never loops forever and\n\t// never breaks the resolution path.\n\t//\n\t// VISION files (PDFs rendered to page images) are NOT resumed here: the proxy worker\n\t// advances their page window itself, off the renderer's true page count. Driving them\n\t// from the browser is what used to lose pages on long documents - the chain lived in tab\n\t// memory (a reload or a closed tab ended it), and it stopped whenever the model claimed\n\t// completion, which on an 88-page file happened at page 15. Continuing to dispatch here\n\t// as well would now double-index every window.\n\tmaybeResumeIndexing(entry: BgTaskEntry, response: any, platform: string): void {\n\t\tvar self = this;\n\t\ttry {\n\t\t\tif (!entry || !entry.storagePath) return;\n\t\t\tif (!isPagedReadFile(entry.filename, entry.mime)) return;\n\t\t\tif (isImageVisionFile(entry.filename, entry.mime)) return; // worker owns this loop\n\t\t\tif (isErrorResponseBody(response)) return; // a failed pass is not \"incomplete\"\n\t\t\tvar answer = (platform === 'openai' ? extractOpenAIText(response) : extractClaudeText(response)) || '';\n\t\t\tif (answer.indexOf(INDEXING_COMPLETE_MARKER) !== -1) return; // fully indexed\n\t\t\tvar pass = (entry.resumePass || 0) + 1;\n\t\t\tif (pass > MAX_INDEXING_RESUME_PASSES) return; // give up after the cap\n\t\t\tvar id = this.host.getIdentity();\n\t\t\tif (!id || id.platform === 'none' || id.serviceId !== entry.serviceId) return;\n\t\t\tnotifyAgentContinueIndexing({\n\t\t\t\tplatform: id.platform as 'claude' | 'openai',\n\t\t\t\tmodel: id.model,\n\t\t\t\tservice: id.serviceId,\n\t\t\t\towner: id.owner,\n\t\t\t\tuserId: id.userId || id.serviceId,\n\t\t\t\tserviceName: id.serviceName,\n\t\t\t\tserviceDescription: id.serviceDescription,\n\t\t\t\tattachment: {\n\t\t\t\t\tname: entry.filename,\n\t\t\t\t\tstoragePath: entry.storagePath,\n\t\t\t\t\tmime: entry.mime,\n\t\t\t\t\tsize: entry.size,\n\t\t\t\t\turl: '',\n\t\t\t\t},\n\t\t\t}).then(function (ack: any) {\n\t\t\t\tif (ack && typeof ack.id === 'string') {\n\t\t\t\t\tself.bgTaskQueue.push({\n\t\t\t\t\t\tserviceId: id.serviceId, platform: id.platform as 'claude' | 'openai', id: ack.id,\n\t\t\t\t\t\tfilename: entry.filename, storagePath: entry.storagePath,\n\t\t\t\t\t\tisReindex: entry.isReindex, mime: entry.mime, size: entry.size,\n\t\t\t\t\t\tstatus: ack.status === 'running' ? 'running' : 'pending',\n\t\t\t\t\t\tpoll: ack.poll, resumePass: pass,\n\t\t\t\t\t});\n\t\t\t\t\tself.drainBgTaskQueue();\n\t\t\t\t}\n\t\t\t}, function (e: any) { console.error('[chat-engine] resume-indexing dispatch failed', e); });\n\t\t} catch (e) { /* best-effort: resume must never break bg-task resolution */ }\n\t}\n\n\t// --- history fetch + pagination --------------------------------------\n\t// Initial load (fetchMore=false) replaces the list (with in-flight rescue +\n\t// cancelled-merge) and attaches polls to running/pending items; pagination\n\t// (fetchMore=true) prepends older messages. The DOM scroll-restore for the\n\t// older-prepend is the VIEW's job (it captures the pre-prepend scroll position\n\t// and restores after this resolves) — the engine never measures the DOM.\n\tloadHistory(fetchMore?: boolean, token?: number): Promise<void> {\n\t\tvar self = this;\n\t\tvar id = this.host.getIdentity();\n\t\t// Key this fetch is FOR, snapshotted from the same identity read the\n\t\t// request is built from. The rescue below compares against this rather\n\t\t// than a live getHistoryCacheKey(), so a project switch mid-fetch can't\n\t\t// make another chat's in-flight bubbles look local.\n\t\tvar loadKey = (!id.serviceId || id.platform === 'none') ? '' : id.serviceId + '#' + id.platform;\n\t\tif (token === undefined) token = this.state.gateRefreshToken;\n\t\tif ((this.state.loadingHistory && this.state.historyRequestToken === token) || id.platform === 'none' || !id.serviceId) {\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\tthis.state.historyRequestToken = token;\n\t\tthis.state.loadingHistory = true;\n\t\tif (fetchMore) this.state.loadingOlderHistory = true;\n\t\tthis.host.notify(); // surface \"Fetching history...\" while it loads\n\t\tvar platform = id.platform as 'claude' | 'openai';\n\t\tvar serviceId = id.serviceId, owner = id.owner;\n\t\tvar options: any = { fetchMore: fetchMore };\n\t\tif (fetchMore && this.state.historyStartKeyHistory.length) options.startKeyHistory = this.state.historyStartKeyHistory.slice();\n\n\t\tvar fetchHistory = function () { return getChatHistory({ service: serviceId, owner: owner, platform: platform }, options); };\n\n\t\treturn Promise.resolve().then(fetchHistory).catch(function (err: any) {\n\t\t\tif (isAuthExpiredError(err) && !isNonRetryableRequestError(err)) return self.host.refreshSession().then(fetchHistory);\n\t\t\tthrow err;\n\t\t}).then(function (history: any) {\n\t\t\tif (token !== self.state.gateRefreshToken) return;\n\t\t\tvar chatList = history && Array.isArray(history.list) ? history.list : [];\n\t\t\tchatList.forEach(function (item: any) {\n\t\t\t\tif (isBgIndexingQueue(item.queue_name)) {\n\t\t\t\t\tvar userText = extractLastUserTextFromRequest(item.request_body);\n\t\t\t\t\tif (typeof userText === 'string' && (userText.indexOf('A new file has just been uploaded') === 0 || userText.indexOf('CONTINUE indexing') === 0)) item._isBgTask = true;\n\t\t\t\t\telse item._isOnBgQueue = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar list = chatList.sort(function (a: any, b: any) {\n\t\t\t\tvar ai = typeof a.id === 'string' ? a.id : '', bi = typeof b.id === 'string' ? b.id : '';\n\t\t\t\treturn ai > bi ? -1 : (ai < bi ? 1 : 0);\n\t\t\t});\n\t\t\tvar mapped = mapHistoryListToMessages(list, platform, {\n\t\t\t\tclearedAt: self.host.getClearedAt(),\n\t\t\t\tserviceId: id.serviceId,\n\t\t\t\tformatIndexingLabel: self.host.formatIndexingLabel,\n\t\t\t}).messages;\n\n\t\t\tif (fetchMore) {\n\t\t\t\tself.state.messages = mapped.concat(self.state.messages);\n\t\t\t} else {\n\t\t\t\tif (self.state.typing) self.state.typingAbort = true;\n\t\t\t\tvar serverIds: any = {};\n\t\t\t\tmapped.forEach(function (m: any) { if (m._serverItemId) serverIds[m._serverItemId] = 1; });\n\t\t\t\tvar locallyCancelled: any = {};\n\t\t\t\tself.state.messages.forEach(function (m) { if (m.isCancelled && m._serverItemId) locallyCancelled[m._serverItemId] = 1; });\n\t\t\t\t// If the freshly-mapped server list ALREADY shows this in-flight turn\n\t\t\t\t// as a pending placeholder (a non-bg pending assistant, which carries\n\t\t\t\t// a real _serverItemId), re-pushing the local no-_serverItemId\n\t\t\t\t// user+Thinking would DUPLICATE it. Each resolve path only clears the\n\t\t\t\t// first pending bubble, so the duplicate strands a \"Thinking…\" beside\n\t\t\t\t// the reply/error. There is at most one in-flight regular turn, so a\n\t\t\t\t// mapped pending assistant IS this turn — skip the redundant local copy.\n\t\t\t\tvar mappedHasPendingAssistant = mapped.some(function (m: any) {\n\t\t\t\t\treturn m.isPending && m.role === 'assistant' && !m.isBackgroundTask;\n\t\t\t\t});\n\t\t\t\tvar rescued: ChatMessage[] = [];\n\t\t\t\tfor (var ri = 0; ri < self.state.messages.length; ri++) {\n\t\t\t\t\tvar mm = self.state.messages[ri];\n\t\t\t\t\tif (mm.isBackgroundTask) continue;\n\t\t\t\t\t// Belongs to a different chat (another project, or another\n\t\t\t\t\t// platform on this one) — it must not be carried onto THIS\n\t\t\t\t\t// chat's freshly-fetched history.\n\t\t\t\t\tif (mm._ownerKey !== undefined && mm._ownerKey !== loadKey) continue;\n\t\t\t\t\tif (mm._serverItemId && serverIds[mm._serverItemId]) continue;\n\t\t\t\t\tif (!mm._serverItemId) {\n\t\t\t\t\t\tif (mappedHasPendingAssistant) continue;\n\t\t\t\t\t\tif (mm.isSendingToServer || mm.isPendingQueued || mm.isPendingInProcess || mm.isPending) rescued.push(mm);\n\t\t\t\t\t\telse if (self.state.sending && mm.role === 'user') {\n\t\t\t\t\t\t\tvar next = self.state.messages[ri + 1];\n\t\t\t\t\t\t\tif (next && !next.isBackgroundTask && next.isPending && !next._serverItemId) rescued.push(mm);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tself.state.messages = mapped;\n\t\t\t\trescued.forEach(function (m) { self.state.messages.push(m); });\n\t\t\t\tif (Object.keys(locallyCancelled).length) {\n\t\t\t\t\tfor (var ci = 0; ci < self.state.messages.length; ci++) {\n\t\t\t\t\t\tvar c = self.state.messages[ci];\n\t\t\t\t\t\tif (!c._serverItemId || !locallyCancelled[c._serverItemId] || c.isCancelled) continue;\n\t\t\t\t\t\tself.state.messages[ci] = { role: 'user', content: c.content, isCancelled: true, _serverItemId: c._serverItemId };\n\t\t\t\t\t\tif (ci + 1 < self.state.messages.length && self.state.messages[ci + 1].isPending && self.state.messages[ci + 1]._serverItemId === c._serverItemId) {\n\t\t\t\t\t\t\tself.state.messages.splice(ci + 1, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tself.state.historyEndOfList = !!(history && history.endOfList);\n\t\t\tself.state.historyStartKeyHistory = history && Array.isArray(history.startKeyHistory) ? history.startKeyHistory : [];\n\t\t\tvar clearedAt = self.host.getClearedAt();\n\t\t\tif (clearedAt && chatList.length > 0) {\n\t\t\t\tvar oldestUpdated = Number(chatList[chatList.length - 1] && chatList[chatList.length - 1].updated);\n\t\t\t\tif (isFinite(oldestUpdated) && oldestUpdated <= clearedAt) self.state.historyEndOfList = true;\n\t\t\t}\n\t\t\t// Clear loading flags BEFORE this render so the final paint is\n\t\t\t// indicator-free (and the view's scroll-restore math sees matching heights).\n\t\t\tif (self.state.historyRequestToken === token) { self.state.loadingHistory = false; self.state.loadingOlderHistory = false; }\n\t\t\tself.updateHistoryCache();\n\t\t\tself.host.notify();\n\n\t\t\tif (!fetchMore) {\n\t\t\t\tchatList.forEach(function (item: any) {\n\t\t\t\t\tif (item.status !== 'running' && item.status !== 'pending') return;\n\t\t\t\t\tif (!item.poll || !item.id) return;\n\t\t\t\t\t// Every live poll registers its item id in historyItemPolls — an\n\t\t\t\t\t// immediate dispatch (dispatchAgentRequest ~123), a queued send\n\t\t\t\t\t// (~253), a bg task (drain), or an earlier history poll — so the\n\t\t\t\t\t// has() check below already skips exactly the items a live poll\n\t\t\t\t\t// covers (including the one the current dispatch is polling). Do NOT\n\t\t\t\t\t// additionally skip every OTHER running/pending item just because\n\t\t\t\t\t// some immediate dispatch is in flight: that dispatch polls only ITS\n\t\t\t\t\t// item, so blanket-skipping stranded a concurrent \"-bg\" indexing item\n\t\t\t\t\t// (a separate server queue runs in parallel) — or any item whose own\n\t\t\t\t\t// poll had since died — with no live poller, leaving a \"Thinking...\"\n\t\t\t\t\t// that never clears even after the server settled everything.\n\t\t\t\t\tif (self.historyItemPolls.has(item.id)) return;\n\t\t\t\t\t// An in-flight immediate dispatch polls its own MAIN-QUEUE item but\n\t\t\t\t\t// registers that id in historyItemPolls only AFTER its provider POST\n\t\t\t\t\t// returns; in the sliver before that, a remount can surface the item\n\t\t\t\t\t// here still unregistered. Skip re-polling MAIN-QUEUE items while a\n\t\t\t\t\t// dispatch is in flight so we don't stack a 2nd poll on the item the\n\t\t\t\t\t// dispatch is about to poll. Bg-queue items (_isBgTask indexing tasks\n\t\t\t\t\t// and _isOnBgQueue chats) run on a SEPARATE queue the immediate\n\t\t\t\t\t// dispatch never polls, so they MUST still get their poll — skipping\n\t\t\t\t\t// them was the stranded-\"Thinking\" bug this guard must not revive.\n\t\t\t\t\tif (self.pendingAgentRequests[self.getHistoryCacheKey()] && !item._isBgTask && !item._isOnBgQueue) return;\n\t\t\t\t\t// Background indexing polls are suppressed while paused; foreground\n\t\t\t\t\t// replies the user is waiting on are not.\n\t\t\t\t\tif ((item._isBgTask || item._isOnBgQueue) && self.isPollingPaused()) return;\n\t\t\t\t\tvar capturedId = item.id;\n\t\t\t\t\tvar pp = item.poll({\n\t\t\t\t\t\tlatency: POLL_INTERVAL,\n\t\t\t\t\t\tonResponse: function (response: any) { if (isPollStopped(response)) return; self.handleHistoryItemResolution(capturedId, response, platform); },\n\t\t\t\t\t\tonError: function (err: any) {\n\t\t\t\t\t\t\tself.historyItemPolls.delete(capturedId);\n\t\t\t\t\t\t\tvar isNotExists = err && (err.code === 'NOT_EXISTS' || (err.body && err.body.code === 'NOT_EXISTS'));\n\t\t\t\t\t\t\tvar aIdx = self.state.messages.findIndex(function (m) { return m.isPending && m._serverItemId === capturedId; });\n\t\t\t\t\t\t\tif (isNotExists) {\n\t\t\t\t\t\t\t\tvar isBg = aIdx !== -1 ? !!self.state.messages[aIdx].isBackgroundTask : false;\n\t\t\t\t\t\t\t\tif (aIdx !== -1) self.state.messages.splice(aIdx, 1);\n\t\t\t\t\t\t\t\tif (!isBg) {\n\t\t\t\t\t\t\t\t\tvar uIdx = self.state.messages.findIndex(function (m) { return m.role === 'user' && m._serverItemId === capturedId && !m.isCancelled; });\n\t\t\t\t\t\t\t\t\tif (uIdx !== -1) { var ex = self.state.messages[uIdx]; self.state.messages[uIdx] = { role: 'user', content: ex.content, isCancelled: true, _serverItemId: ex._serverItemId }; }\n\t\t\t\t\t\t\t\t\tself.cancelledServerIds.delete(capturedId); self.promoteNextQueuedToRunning();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tself.host.notify(); self.updateHistoryCache(); return;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (aIdx !== -1) {\n\t\t\t\t\t\t\t\tvar wasBg = self.state.messages[aIdx].isBackgroundTask;\n\t\t\t\t\t\t\t\tself.state.messages[aIdx] = { role: 'assistant', content: getErrorMessage(err), isError: true };\n\t\t\t\t\t\t\t\tif (wasBg) self.state.messages[aIdx].isBackgroundTask = true;\n\t\t\t\t\t\t\t\tself.host.notify(); self.updateHistoryCache();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\t// Anything on the BACKGROUND queue is pausable, not just items whose\n\t\t\t\t\t// prompt text we recognise as an indexing task. _isBgTask vs\n\t\t\t\t\t// _isOnBgQueue is a DISPLAY distinction (\"Indexing: file\" vs a normal\n\t\t\t\t\t// chat bubble); keying the pause off _isBgTask alone left every\n\t\t\t\t\t// bg-queue item we could not text-match polling forever.\n\t\t\t\t\tself._trackPoll(capturedId, (item._isBgTask || item._isOnBgQueue) ? 'bg' : 'fg', pp);\n\t\t\t\t\tif (pp && pp.catch) pp.catch(function () { });\n\t\t\t\t});\n\t\t\t\tself.drainBgTaskQueue();\n\t\t\t}\n\n\t\t\tif (!fetchMore) return self.host.scrollToBottom();\n\t\t}).catch(function (err: any) {\n\t\t\tconsole.warn('[chat-engine] getChatHistory failed', err);\n\t\t}).then(function () {\n\t\t\tif (self.state.historyRequestToken === token) {\n\t\t\t\tvar wasLoading = self.state.loadingHistory || self.state.loadingOlderHistory;\n\t\t\t\tself.state.loadingHistory = false; self.state.loadingOlderHistory = false;\n\t\t\t\tif (wasLoading) self.host.notify();\n\t\t\t}\n\t\t});\n\t}\n\n\t// --- attachment upload orchestration ---------------------------------\n\t// Upload one attachment (a file = 1 member, a folder = N) to db storage and\n\t// queue indexing per member. The bytes I/O + chip rendering go through host\n\t// hooks; the overwrite/reindex flow, status lifecycle, and indexing live here.\n\tuploadSingleAttachment(att: any): Promise<Array<{ name: string; url: string; storagePath: string }>> {\n\t\tvar self = this;\n\t\tvar id = this.host.getIdentity();\n\t\tatt.status = 'uploading'; att.progress = 0; att.errorMessage = '';\n\t\tatt.errorCode = ''; att.errorDetail = ''; // clear any prior failure (retry)\n\t\tthis.host.renderAttachmentChips();\n\t\tvar members = (att.kind === 'folder')\n\t\t\t? (att.files || []).map(function (f: any) { return { file: f.file, relPath: f.path, storagePath: self.host.storagePathFor(f.path) }; })\n\t\t\t: [{ file: att.file, relPath: att.name, storagePath: this.host.storagePathFor(att.name) }];\n\t\tvar total = members.length;\n\t\tif (!total) return Promise.reject(new Error('Empty attachment'));\n\t\tvar urls: Array<{ name: string; url: string; storagePath: string }> = [];\n\t\tvar anyIndexFailed = false;\n\t\tvar chain: Promise<any> = Promise.resolve();\n\t\tmembers.forEach(function (member: any, idx: number) {\n\t\t\tchain = chain.then(function () {\n\t\t\t\tvar hadExists = false;\n\t\t\t\tvar skipped = false;\n\t\t\t\t// True when the file already existed and we are re-indexing over it\n\t\t\t\t// (user chose Reindex, OR Overwrite replaced the bytes). Drives the\n\t\t\t\t// delete-then-repost of the stale \"src::\" record below. Kept separate\n\t\t\t\t// from hadExists, which must keep driving ONLY the Reindexing/Indexing\n\t\t\t\t// label (isReindex) — overwrite still labels as \"Indexing:\".\n\t\t\t\tvar existedBefore = false;\n\t\t\t\tvar onProg = function (p: any) {\n\t\t\t\t\tif (p && p.total) {\n\t\t\t\t\t\tatt.progress = Math.floor(((idx + p.loaded / p.total) / total) * 100);\n\t\t\t\t\t\tself.host.renderAttachmentChips();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tvar doMemberUpload = function (checkExistence: boolean) {\n\t\t\t\t\treturn self.host.uploadFile({\n\t\t\t\t\t\tfile: member.file, storagePath: member.storagePath, checkExistence: checkExistence,\n\t\t\t\t\t\tonProgress: onProg, setAbort: function (abort) { att._abort = abort; },\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t\treturn doMemberUpload(true).catch(function (err: any) {\n\t\t\t\t\tvar code = err && (err.code || (err.body && err.body.code));\n\t\t\t\t\tvar msg = err && (err.message || (err.body && err.body.message) || (typeof err === 'string' ? err : ''));\n\t\t\t\t\tvar isExists = code === 'EXISTS' || (msg && /exist/i.test(msg));\n\t\t\t\t\tif (!isExists) throw err; // a member upload failed → whole attachment fails (red)\n\t\t\t\t\treturn self.host.promptOverwrite(member.file.name).then(function (choice) {\n\t\t\t\t\t\tif (choice === 'overwrite') { existedBefore = true; return doMemberUpload(false); } // replace the existing file\n\t\t\t\t\t\tif (choice === 'skip') { skipped = true; return; } // leave it untouched; no upload/index\n\t\t\t\t\t\thadExists = true; existedBefore = true; // keep it; Reindex\n\t\t\t\t\t});\n\t\t\t\t}).then(function () {\n\t\t\t\t\tif (skipped) return; // user skipped this member — no url, no index request\n\t\t\t\t\treturn self.host.getTemporaryUrl(member.storagePath);\n\t\t\t\t}).then(function (url: string) {\n\t\t\t\t\tif (skipped) return; // guard the indexing branch for a skipped member\n\t\t\t\t\turls.push({ name: member.relPath, url: url, storagePath: member.storagePath });\n\t\t\t\t\tif (att.kind !== 'folder') { att.uploadedUrl = url; att.storagePath = member.storagePath; }\n\t\t\t\t\tvar mime = member.file.type || self.host.getMimeType(member.file.name);\n\t\t\t\t\t// Delete-then-repost: when the file already existed (Reindex or\n\t\t\t\t\t// Overwrite), delete the stale \"src::<storagePath>\" index record\n\t\t\t\t\t// first — the skapi backend cascades the delete to its\n\t\t\t\t\t// reference-linked children — so re-indexing REPLACES rather than\n\t\t\t\t\t// colliding/duplicating. Awaited before the index request is\n\t\t\t\t\t// enqueued. Best-effort + optional-hook guarded: a missing record,\n\t\t\t\t\t// a permission error, or a host without the hook must not block\n\t\t\t\t\t// indexing.\n\t\t\t\t\tvar preIndex = (existedBefore && typeof self.host.deleteExistingFileRecord === 'function')\n\t\t\t\t\t\t? Promise.resolve(self.host.deleteExistingFileRecord(member.storagePath)).catch(function () { })\n\t\t\t\t\t\t: Promise.resolve();\n\t\t\t\t\t// Run a client-side attachment parser (e.g. .hwp) if one matches; its\n\t\t\t\t\t// output is inlined into the indexing request (falls back to office\n\t\t\t\t\t// extraction / web_fetch when no parser matches or it yields nothing).\n\t\t\t\t\treturn preIndex.then(function () {\n\t\t\t\t\t\treturn parseAttachmentContent(member.file, member.file.name, mime || undefined);\n\t\t\t\t\t}).then(function (parsedContent: string | null) {\n\t\t\t\t\treturn notifyAgentSaveAttachment({\n\t\t\t\t\t\tplatform: id.platform as 'claude' | 'openai',\n\t\t\t\t\t\tmodel: id.model,\n\t\t\t\t\t\tservice: id.serviceId,\n\t\t\t\t\t\towner: id.owner,\n\t\t\t\t\t\tuserId: id.userId || id.serviceId,\n\t\t\t\t\t\tserviceName: id.serviceName,\n\t\t\t\t\t\tserviceDescription: id.serviceDescription,\n\t\t\t\t\t\tattachment: {\n\t\t\t\t\t\t\tname: member.file.name, storagePath: member.storagePath,\n\t\t\t\t\t\t\tmime: mime || undefined, size: member.file.size, url: url,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tparsedContent: parsedContent || undefined,\n\t\t\t\t\t}).then(function (ack: any) {\n\t\t\t\t\t\tif (ack && typeof ack.id === 'string') {\n\t\t\t\t\t\t\tself.bgTaskQueue.push({\n\t\t\t\t\t\t\t\tserviceId: id.serviceId, platform: id.platform as 'claude' | 'openai', id: ack.id,\n\t\t\t\t\t\t\t\tfilename: member.file.name,\n\t\t\t\t\t\t\t\tstoragePath: member.storagePath,\n\t\t\t\t\t\t\t\tisReindex: hadExists,\n\t\t\t\t\t\t\t\tmime: mime || undefined,\n\t\t\t\t\t\t\t\tsize: member.file.size,\n\t\t\t\t\t\t\t\tstatus: ack.status === 'running' ? 'running' : 'pending',\n\t\t\t\t\t\t\t\tpoll: ack.poll,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tself.drainBgTaskQueue(); // surface \"Indexing: <file>\" as soon as THIS file uploads\n\t\t\t\t\t\t}\n\t\t\t\t\t}, function (e: any) {\n\t\t\t\t\t\tconsole.error('[chat-engine] indexing request failed', e);\n\t\t\t\t\t\tanyIndexFailed = true; // uploaded but not indexed → yellow\n\t\t\t\t\t\t// Record the first index error's code/message for the report dialog.\n\t\t\t\t\t\tif (!att.errorCode && !att.errorDetail) {\n\t\t\t\t\t\t\tatt.errorCode = (e && (e.code || (e.body && e.body.code))) || '';\n\t\t\t\t\t\t\tatt.errorDetail = (e && (e.message || (e.body && e.body.message))) || (typeof e === 'string' ? e : '');\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t\treturn chain.then(function () {\n\t\t\tatt._abort = null; att.progress = 100;\n\t\t\tif (att.kind === 'folder') att.uploadedUrls = urls.map(function (u) { return { path: u.name, url: u.url, storagePath: u.storagePath }; });\n\t\t\tatt.status = anyIndexFailed ? 'indexError' : 'done';\n\t\t\tif (att.status === 'indexError') att.errorMessage = 'File indexing failed';\n\t\t\tself.host.renderAttachmentChips();\n\t\t\treturn urls;\n\t\t});\n\t}\n\n\t// Upload all not-yet-done attachments sequentially. Resolves to the full\n\t// list of { name, url, storagePath } for composing the chat message.\n\tuploadPendingAttachments(): Promise<Array<{ name: string; url: string; storagePath?: string }>> {\n\t\tvar self = this;\n\t\tthis.host.resetOverwriteBatch();\n\t\tthis.state.uploadingAttachments = true;\n\t\tthis.host.updateComposerControls();\n\t\tthis.host.renderAttachmentChips();\n\t\tvar collected: Array<{ name: string; url: string; storagePath?: string }> = [];\n\t\tvar snapshot = this.state.attachments.slice();\n\t\tvar chain: Promise<any> = Promise.resolve();\n\t\tsnapshot.forEach(function (att: any) {\n\t\t\tchain = chain.then(function () {\n\t\t\t\tif (!self.state.attachments.some(function (a: any) { return a.id === att.id; })) return; // removed\n\t\t\t\tif (att.status === 'done' || att.status === 'indexError') {\n\t\t\t\t\tif (att.kind === 'folder' && att.uploadedUrls) {\n\t\t\t\t\t\tatt.uploadedUrls.forEach(function (u: any) { collected.push({ name: u.path, url: u.url, storagePath: u.storagePath }); });\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (att.uploadedUrl) { collected.push({ name: att.name, url: att.uploadedUrl, storagePath: att.storagePath }); return; }\n\t\t\t\t}\n\t\t\t\treturn self.uploadSingleAttachment(att).then(function (us) {\n\t\t\t\t\tcollected.push.apply(collected, us);\n\t\t\t\t}).catch(function (err: any) {\n\t\t\t\t\tvar removed = !self.state.attachments.some(function (a: any) { return a.id === att.id; });\n\t\t\t\t\tvar aborted = err && (err.message === 'Aborted' || err === 'Aborted');\n\t\t\t\t\tif (removed || aborted) return;\n\t\t\t\t\tatt.status = 'error';\n\t\t\t\t\tatt.errorMessage = 'File upload has failed';\n\t\t\t\t\t// Preserve the original error code/message for the report dialog.\n\t\t\t\t\tatt.errorCode = (err && (err.code || (err.body && err.body.code))) || '';\n\t\t\t\t\tatt.errorDetail = (err && (err.message || (err.body && err.body.message))) || (typeof err === 'string' ? err : '');\n\t\t\t\t\tself.host.renderAttachmentChips();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t\tvar done = function () {\n\t\t\tself.state.uploadingAttachments = false; self.host.updateComposerControls(); self.host.renderAttachmentChips();\n\t\t\treturn collected;\n\t\t};\n\t\treturn chain.then(done, done);\n\t}\n\n\t// Stop timers / abort the typewriter (view teardown).\n\tstop(): void {\n\t\tthis.state.typingAbort = true;\n\t}\n\n\t// Bump the gate token so any in-flight immediate-send result is dropped\n\t// (called by the view on a service/platform switch or history clear).\n\tbumpGate(): void {\n\t\tthis.state.gateRefreshToken += 1;\n\t}\n}\n"]}