@cubos/agent-sdk 0.0.1136563

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.
@@ -0,0 +1,30 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/errors.ts", "../src/sse.ts", "../src/http.ts", "../src/admin/paths.ts", "../src/admin/agents.ts", "../src/admin/ai-providers.ts", "../src/admin/channels.ts", "../src/client-tools.ts", "../src/admin/client-tools.ts", "../src/admin/component-libraries.ts", "../src/admin/conversations.ts", "../src/admin/global.ts", "../src/admin/knowledge-bases.ts", "../src/admin/mcps.ts", "../src/admin/skills.ts", "../src/admin/task-templates.ts", "../src/admin/users.ts", "../src/admin/index.ts", "../src/cache.ts", "../src/mapping.ts", "../src/client.ts"],
4
+ "sourcesContent": [
5
+ "/** Base for everything this SDK throws, so `catch (e) { if (e instanceof\n * AgentError) }` covers both an HTTP failure and a connection that never got\n * there. */\nexport class AgentError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AgentError\";\n }\n}\n\n/** The server answered, and said no. */\nexport class AgentApiError extends AgentError {\n readonly status: number;\n /** Server's `x-request-id`, when present. Worth quoting in a bug report. */\n readonly requestId: string | null;\n /** The response body, verbatim and untruncated. Some routes explain the\n * failure in there (an MCP probe's reason, a rejected cron) in a form worth\n * showing the user; `message` only carries a truncated preview. */\n readonly body: string;\n\n constructor(message: string, status: number, requestId: string | null = null, body = \"\") {\n super(message);\n this.name = \"AgentApiError\";\n this.status = status;\n this.requestId = requestId;\n this.body = body;\n }\n\n /** The body parsed as JSON, or `undefined` when it isn't. */\n json<T = unknown>(): T | undefined {\n try {\n return JSON.parse(this.body) as T;\n } catch {\n return undefined;\n }\n }\n\n /** The token was rejected. The client already retried once with a fresh one,\n * so seeing this means `getToken` is handing back something unusable. */\n get isAuthError(): boolean {\n return this.status === 401 || this.status === 403;\n }\n\n get isNotFound(): boolean {\n return this.status === 404;\n }\n\n /** The request clashed with current state — a slug already taken, a\n * conversation that belongs to a channel, a user already blocked. */\n get isConflict(): boolean {\n return this.status === 409;\n }\n\n /** Worth retrying after a pause: the server is overloaded or briefly down. */\n get isRetryable(): boolean {\n return this.status === 429 || this.status >= 500;\n }\n}\n\n/**\n * The client was constructed wrong — a `baseUrl` with no scheme, most often.\n * Thrown at construction, not on the first call, so the stack points at the\n * mistake.\n */\nexport class AgentConfigError extends AgentError {\n constructor(message: string) {\n super(message);\n this.name = \"AgentConfigError\";\n }\n}\n\n/**\n * The request never produced a response: DNS, TLS, a refused connection, CORS,\n * or the timeout below.\n *\n * Without this, `fetch` rejects with a bare `TypeError: fetch failed` and the\n * caller cannot tell a wrong `baseUrl` from a server that said 500 — the two\n * need completely different fixes.\n */\nexport class AgentNetworkError extends AgentError {\n /** Whatever `fetch` (or the abort) threw. */\n readonly cause: unknown;\n /** True when the SDK's own timeout fired rather than the network failing. */\n readonly timedOut: boolean;\n\n constructor(message: string, cause: unknown, timedOut = false) {\n super(message);\n this.name = \"AgentNetworkError\";\n this.cause = cause;\n this.timedOut = timedOut;\n }\n}\n\nconst DEFAULT_MESSAGES: Record<number, string> = {\n 400: \"Invalid request.\",\n 401: \"Not authenticated.\",\n 403: \"Not allowed.\",\n 404: \"Not found.\",\n 409: \"Conflicts with the current state.\",\n 413: \"Payload too large.\",\n 429: \"Rate limited.\",\n};\n\nexport async function raiseForStatus(res: Response, fallback: string): Promise<void> {\n if (res.ok) return;\n let detail = \"\";\n try {\n detail = await res.text();\n } catch {\n detail = \"\";\n }\n const base = DEFAULT_MESSAGES[res.status] ?? fallback;\n throw new AgentApiError(\n detail ? `${base} (${detail.slice(0, 500)})` : base,\n res.status,\n res.headers.get(\"x-request-id\"),\n detail,\n );\n}\n",
6
+ "// A `fetch`-based Server-Sent Events reader. Not `EventSource`: that can't\n// attach an Authorization header, which every stream here requires.\n//\n// Runtime-agnostic on purpose — `fetch`, `ReadableStream` and `AbortController`\n// only, no DOM. Exported as its own entry point (`@cubos/agent-sdk/sse`) so the\n// operator dashboard can reuse it without adopting the rest of the client.\n\nimport { raiseForStatus } from \"./errors.js\";\n\n/** Just the call signature, not `typeof fetch` — that also demands runtime\n * extras (Bun's `preconnect`, undici's statics) a caller's wrapper won't have. */\nexport type FetchLike = (\n input: string,\n init?: {\n method?: string;\n headers?: Record<string, string>;\n body?: string | FormData;\n signal?: AbortSignal;\n },\n) => Promise<Response>;\n\nexport interface SseOptions<T> {\n url: string;\n /**\n * Only frames with one of these `event:` names are delivered; the rest are\n * dropped. Several names on one connection is how a stream keeps two kinds of\n * frame in a single order — split across two connections there is none, and a\n * client cannot tell which came first.\n */\n event: string | string[];\n onEvent: (data: T, event: string) => void;\n signal: AbortSignal;\n /** Called before each (re)connect, so the caller can mint a fresh token. */\n headers?: () => Promise<Record<string, string>> | Record<string, string>;\n /** Called once per successful connect, before any frame is delivered. The\n * hook a caller needs to catch up on state the stream won't replay: it fires\n * on every reconnect too, so a gap the backoff swallowed is covered as\n * well. Not awaited — a slow catch-up must not stall frame delivery. */\n onOpen?: () => void;\n /** Resume cursor for the first connect. Later reconnects use the last `id:`\n * the server actually sent. */\n lastEventId?: string;\n fetchImpl?: FetchLike;\n onError?: (err: unknown) => void;\n}\n\nconst MAX_BACKOFF_MS = 30_000;\n\n/** Marks an error the reconnect loop must not swallow. */\nclass Fatal extends Error {\n override readonly cause: unknown;\n constructor(cause: unknown) {\n super(\"fatal stream error\");\n this.cause = cause;\n }\n}\n\n/**\n * Reads `url` until `signal` aborts, reconnecting through any drop — clean\n * close from the server included, since intermediaries (Cloudflare et al.)\n * close idle SSE connections without warning and the caller would otherwise\n * silently stop receiving.\n *\n * `Last-Event-ID` is replayed from the last frame the server sent, so the\n * backend's catch-up query fills whatever the gap swallowed. 4xx ends the loop\n * — a bad token or a deleted conversation won't fix itself by retrying.\n */\nexport async function readSse<T>(opts: SseOptions<T>): Promise<void> {\n const doFetch = opts.fetchImpl ?? globalThis.fetch;\n let lastEventId = opts.lastEventId;\n let attempt = 0;\n\n while (!opts.signal.aborted) {\n let madeProgress = false;\n try {\n const headers: Record<string, string> = {\n ...(await opts.headers?.()),\n Accept: \"text/event-stream\",\n };\n if (lastEventId !== undefined) headers[\"Last-Event-ID\"] = lastEventId;\n\n const res = await doFetch(opts.url, { headers, signal: opts.signal });\n if (opts.signal.aborted) return;\n if (res.ok && res.body) opts.onOpen?.();\n\n if (!res.ok || !res.body) {\n if (res.status >= 400 && res.status < 500) {\n // Wrapped so the catch below can tell it apart from a transient\n // failure and rethrow instead of reconnecting forever.\n await raiseForStatus(res, `Could not open ${opts.url}.`).catch((err) => {\n throw new Fatal(err);\n });\n return;\n }\n throw new Error(`stream open failed with HTTP ${res.status}`);\n }\n\n for await (const frame of frames(res.body, opts.signal)) {\n const parsed = parseFrame<T>(frame, opts.event);\n if (parsed === null) continue;\n if (parsed.id !== null) lastEventId = parsed.id;\n opts.onEvent(parsed.data, parsed.event);\n madeProgress = true;\n }\n } catch (err) {\n if (opts.signal.aborted) return;\n // A bad token or a deleted conversation won't fix itself by retrying.\n if (err instanceof Fatal) throw err.cause;\n // Everything else is transient (network, 5xx, proxy hangup) — report and\n // back off rather than end the subscription.\n opts.onError?.(err);\n }\n\n if (opts.signal.aborted) return;\n\n // Any delivered frame resets the backoff: a long-lived stream that did real\n // work and then dropped should come back fast, not wait out the ceiling.\n if (madeProgress) attempt = 0;\n const delayMs = Math.min(MAX_BACKOFF_MS, 1_000 * 2 ** attempt);\n attempt += 1;\n await sleep(delayMs, opts.signal);\n }\n}\n\nasync function* frames(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n): AsyncGenerator<string> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n try {\n while (!signal.aborted) {\n const { value, done } = await reader.read();\n if (done) return;\n buffer += decoder.decode(value, { stream: true });\n for (;;) {\n const sep = buffer.indexOf(\"\\n\\n\");\n if (sep === -1) break;\n yield buffer.slice(0, sep);\n buffer = buffer.slice(sep + 2);\n }\n }\n } finally {\n reader.cancel().catch(() => {});\n }\n}\n\nexport function parseFrame<T>(\n frame: string,\n expectedEvent: string | string[],\n): { data: T; id: string | null; event: string } | null {\n let dataLine: string | null = null;\n let id: string | null = null;\n let eventName = \"message\";\n for (const line of frame.split(\"\\n\")) {\n if (line.startsWith(\":\")) continue;\n if (line.startsWith(\"data:\")) dataLine = line.slice(5).trimStart();\n else if (line.startsWith(\"event:\")) eventName = line.slice(6).trim();\n else if (line.startsWith(\"id:\")) id = line.slice(3).trim();\n }\n const wanted =\n typeof expectedEvent === \"string\"\n ? eventName === expectedEvent\n : expectedEvent.includes(eventName);\n if (!wanted || dataLine === null) return null;\n try {\n return { data: JSON.parse(dataLine) as T, id, event: eventName };\n } catch {\n return null;\n }\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const onAbort = () => {\n clearTimeout(timer);\n resolve();\n };\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n",
7
+ "import { AgentConfigError, AgentNetworkError, raiseForStatus } from \"./errors.js\";\nimport type { FetchLike } from \"./sse.js\";\n\n/** Called before every request. Cache inside your own implementation if the\n * token is expensive to mint; the SDK calls this freely. `forceRefresh` is set\n * on the retry after a 401 — return a newly minted token, not the cached one. */\nexport type TokenSource = (opts: { forceRefresh: boolean }) => Promise<string> | string;\n\n/**\n * A long-lived api_key, or a short-lived end-user token fetched on demand.\n *\n * The distinction is not cosmetic: an api_key is tenant-wide and must never\n * reach a browser, while a user token is scoped to one user and expires. The\n * two client constructors keep them apart at the type level.\n */\nexport type Auth =\n | { apiKey: string | (() => string | Promise<string>) }\n | { getToken: TokenSource };\n\ninterface RequestOptions {\n body?: unknown;\n query?: Record<string, string | number | boolean | undefined>;\n signal?: AbortSignal;\n /** Skip JSON parsing; used by endpoints that answer 204 or raw bytes. */\n raw?: boolean;\n}\n\nexport interface Transport {\n request<T>(method: string, path: string, opts?: RequestOptions): Promise<T>;\n fetchRaw(method: string, path: string, opts?: RequestOptions): Promise<Response>;\n /** Headers for a stream connect, refreshed per (re)connect attempt. */\n streamHeaders(): Promise<Record<string, string>>;\n url(path: string, query?: RequestOptions[\"query\"]): string;\n fetchImpl: FetchLike;\n}\n\n/** Long enough for a slow upload on a bad connection, short enough that a hung\n * server surfaces as an error instead of a spinner that never resolves. */\nexport const DEFAULT_TIMEOUT_MS = 30_000;\n\n/** How many times a 429 is retried before giving up. Two covers a burst that\n * briefly outran the budget; more would just delay an error the caller needs. */\nexport const DEFAULT_MAX_RETRIES = 2;\n\n/** A `Retry-After` longer than this is honoured as an error rather than a wait:\n * blocking a caller for minutes is worse than telling them now. */\nconst MAX_RETRY_WAIT_MS = 20_000;\n\n/**\n * Seconds from a `Retry-After`, which is either a delta or an HTTP date.\n * Returns null when absent or unusable, so the caller can decide not to retry\n * rather than guess an interval.\n */\nfunction parseRetryAfter(header: string | null): number | null {\n if (!header) return null;\n const seconds = Number(header.trim());\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(header);\n if (Number.isNaN(date)) return null;\n return Math.max(0, date - Date.now());\n}\n\n/** Sleeps, but gives up early if the caller aborts — a retry wait must not keep\n * a cancelled request alive. */\nfunction sleep(ms: number, signal: AbortSignal | undefined): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error(\"Aborted\"));\n return;\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n function onAbort() {\n clearTimeout(timer);\n reject(signal?.reason ?? new Error(\"Aborted\"));\n }\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nfunction buildQuery(query: RequestOptions[\"query\"]): string {\n if (!query) return \"\";\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) search.set(key, String(value));\n }\n const qs = search.toString();\n return qs ? `?${qs}` : \"\";\n}\n\n/**\n * Rejects a `baseUrl` that cannot work, at construction rather than on the\n * first call.\n *\n * `\"localhost:3000\"` is the common slip: `fetch` reads `localhost:` as a scheme\n * and fails with something that mentions neither the URL nor the mistake.\n */\nfunction normalizeBaseUrl(baseUrl: string): string {\n if (typeof baseUrl !== \"string\") {\n throw new AgentConfigError(\"baseUrl is required, e.g. https://agent.acme.com\");\n }\n const trimmed = baseUrl.trim().replace(/\\/+$/, \"\");\n // Empty is legitimate and load-bearing: the dashboard is served by the core\n // itself and passes \"\" to build same-origin paths.\n if (trimmed === \"\") return \"\";\n if (!/^https?:\\/\\//i.test(trimmed)) {\n throw new AgentConfigError(\n `baseUrl must start with http:// or https:// (got ${JSON.stringify(baseUrl)}).`,\n );\n }\n try {\n new URL(trimmed);\n } catch {\n throw new AgentConfigError(`baseUrl is not a valid URL (got ${JSON.stringify(baseUrl)}).`);\n }\n return trimmed;\n}\n\n/** Merges the caller's signal with the timeout, preferring the platform's own\n * combinator and falling back for runtimes that predate it. */\nfunction combineSignals(caller: AbortSignal | undefined, timeout: AbortSignal): AbortSignal {\n if (!caller) return timeout;\n const anyOf = (AbortSignal as { any?: (signals: AbortSignal[]) => AbortSignal }).any;\n if (typeof anyOf === \"function\") return anyOf([caller, timeout]);\n\n const controller = new AbortController();\n const abort = () => controller.abort();\n if (caller.aborted || timeout.aborted) controller.abort();\n caller.addEventListener(\"abort\", abort, { once: true });\n timeout.addEventListener(\"abort\", abort, { once: true });\n return controller.signal;\n}\n\nexport function createTransport(\n baseUrl: string,\n auth: Auth,\n fetchImpl: FetchLike = globalThis.fetch,\n timeoutMs: number = DEFAULT_TIMEOUT_MS,\n maxRetries: number = DEFAULT_MAX_RETRIES,\n): Transport {\n const root = normalizeBaseUrl(baseUrl);\n\n async function authHeader(forceRefresh: boolean): Promise<string> {\n if (!(\"apiKey\" in auth)) return `Bearer ${await auth.getToken({ forceRefresh })}`;\n // A callable api_key is for a host that holds the key somewhere mutable\n // (the dashboard reads localStorage). It is still not refreshable, so a 401\n // stays a 401 — only `getToken` gets the retry.\n const key = typeof auth.apiKey === \"function\" ? await auth.apiKey() : auth.apiKey;\n return `Bearer ${key}`;\n }\n\n async function send(\n method: string,\n path: string,\n opts: RequestOptions,\n retry: boolean,\n ): Promise<Response> {\n const headers: Record<string, string> = { Authorization: await authHeader(retry) };\n // FormData passes through untouched: setting Content-Type here would strip\n // the multipart boundary the runtime generates, and the upload would fail.\n const isForm = typeof FormData !== \"undefined\" && opts.body instanceof FormData;\n let body: string | FormData | undefined;\n if (isForm) {\n body = opts.body as FormData;\n } else if (opts.body !== undefined) {\n body = JSON.stringify(opts.body);\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n // `AbortSignal.timeout` is recent enough that a stray old runtime would\n // otherwise take the whole SDK down at the first request.\n const timer =\n timeoutMs > 0 && typeof AbortSignal.timeout === \"function\"\n ? AbortSignal.timeout(timeoutMs)\n : undefined;\n const signal = timer ? combineSignals(opts.signal, timer) : opts.signal;\n const url = `${root}${path}${buildQuery(opts.query)}`;\n\n try {\n return await fetchImpl(url, { method, headers, body, signal });\n } catch (err) {\n // A caller-initiated abort is not a failure — rethrow it so `if\n // (err.name === \"AbortError\")` keeps working the way it does with fetch.\n if (opts.signal?.aborted) throw err;\n if (timer?.aborted) {\n throw new AgentNetworkError(`Request to ${url} timed out after ${timeoutMs}ms.`, err, true);\n }\n throw new AgentNetworkError(\n `Could not reach ${url}. Check the base URL, that the server is running, and CORS.`,\n err,\n );\n }\n }\n\n // Defaulted here, not only in `request`: `fetchRaw` is exposed directly and\n // callers with nothing to configure call it with two arguments.\n async function once(method: string, path: string, opts: RequestOptions = {}): Promise<Response> {\n let attempt = 0;\n for (;;) {\n let res = await send(method, path, opts, false);\n // One retry with a forced refresh: a short-TTL token that expired between\n // `getToken` and the server reading it is the expected case, not something\n // the host app should have to handle. A static api_key can't be refreshed,\n // so retrying it would just repeat the same rejection.\n if (res.status === 401 && \"getToken\" in auth) {\n res = await send(method, path, opts, true);\n }\n\n // A 429 means the request was refused, not half-applied, so replaying it\n // is safe even for a POST. The server says how long to wait; without a\n // usable header there is nothing to base a wait on, so surface the error.\n if (res.status !== 429 || attempt >= maxRetries) return res;\n const waitMs = parseRetryAfter(res.headers.get(\"retry-after\"));\n if (waitMs === null || waitMs > MAX_RETRY_WAIT_MS) return res;\n\n attempt += 1;\n await sleep(waitMs, opts.signal);\n }\n }\n\n return {\n fetchImpl,\n url: (path, query) => `${root}${path}${buildQuery(query)}`,\n async streamHeaders() {\n return { Authorization: await authHeader(false) };\n },\n fetchRaw: once,\n async request<T>(method: string, path: string, opts: RequestOptions = {}): Promise<T> {\n const res = await once(method, path, opts);\n await raiseForStatus(res, `${method} ${path} failed.`);\n if (opts.raw || res.status === 204) return undefined as T;\n return (await res.json()) as T;\n },\n };\n}\n",
8
+ "/** Percent-encodes one path segment. Slugs are `[a-z0-9-]` and ids are UUIDs,\n * but tenant slugs and model ids come from user input and reach these URLs. */\nexport const enc = encodeURIComponent;\n\nexport const tenantPath = (tenantSlug: string) => `/api/v1/tenants/${enc(tenantSlug)}`;\n\n/** Drops a slug rename that isn't one, so the server's uniqueness pre-check\n * doesn't reject an entity for colliding with itself. */\nexport function withoutNoopRename<T extends { slug?: string | null }>(\n input: T,\n currentSlug: string,\n): T {\n if (input.slug && input.slug === currentSlug) return { ...input, slug: undefined };\n return input;\n}\n",
9
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath, withoutNoopRename } from \"./paths.js\";\n\nexport function agentsApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/agents`;\n const agent = (slug: string) => `${base}/${enc(slug)}`;\n\n return {\n list: (signal?: AbortSignal) => t.request<Schemas[\"AgentListItem\"][]>(\"GET\", base, { signal }),\n\n get: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"Agent\"]>(\"GET\", agent(slug), { signal }),\n\n create: (input: Schemas[\"CreateAgentInput\"]) =>\n t.request<Schemas[\"Agent\"]>(\"POST\", base, { body: input }),\n\n update: (currentSlug: string, input: Schemas[\"UpdateAgentInput\"]) =>\n t.request<Schemas[\"Agent\"]>(\"PATCH\", agent(currentSlug), {\n body: withoutNoopRename(input, currentSlug),\n }),\n\n delete: (slug: string) => t.request<void>(\"DELETE\", agent(slug), { raw: true }),\n\n countTokens: (slug: string, input: Schemas[\"DraftAgentConfig\"], signal?: AbortSignal) =>\n t.request<Schemas[\"CountTokensResponse\"]>(\"POST\", `${agent(slug)}/count-tokens`, {\n body: input,\n signal,\n }),\n\n // MCPs, skills and task templates are attached per agent; availability is\n // the OR of global, agent and conversation config (see CLAUDE.md), so these\n // grant at the agent level only.\n listMcps: (agentSlug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"AgentMcpItem\"][]>(\"GET\", `${agent(agentSlug)}/mcps`, { signal }),\n\n addMcp: (agentSlug: string, mcpSlug: string) =>\n t.request<void>(\"PUT\", `${agent(agentSlug)}/mcps/${enc(mcpSlug)}`, { raw: true }),\n\n removeMcp: (agentSlug: string, mcpSlug: string) =>\n t.request<void>(\"DELETE\", `${agent(agentSlug)}/mcps/${enc(mcpSlug)}`, { raw: true }),\n\n /** `null` restores \"all of the MCP's tools\"; a list narrows to those. */\n updateMcpTools: (agentSlug: string, mcpSlug: string, enabledTools: string[] | null) =>\n t.request<void>(\"PATCH\", `${agent(agentSlug)}/mcps/${enc(mcpSlug)}`, {\n body: { enabled_tools: enabledTools },\n raw: true,\n }),\n\n replaceMcpRoles: (agentSlug: string, mcpSlug: string, roleSlugs: string[]) =>\n t.request<void>(\"PUT\", `${agent(agentSlug)}/mcps/${enc(mcpSlug)}/roles`, {\n body: { role_slugs: roleSlugs } satisfies Schemas[\"ReplaceAgentMcpRolesInput\"],\n raw: true,\n }),\n\n updateMcpRoleTools: (\n agentSlug: string,\n mcpSlug: string,\n roleSlug: string,\n enabledTools: string[] | null,\n ) =>\n t.request<void>(\"PATCH\", `${agent(agentSlug)}/mcps/${enc(mcpSlug)}/roles/${enc(roleSlug)}`, {\n body: { enabled_tools: enabledTools },\n raw: true,\n }),\n\n listSkills: (agentSlug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"AgentSkillItem\"][]>(\"GET\", `${agent(agentSlug)}/skills`, { signal }),\n\n addSkill: (agentSlug: string, skillSlug: string) =>\n t.request<void>(\"PUT\", `${agent(agentSlug)}/skills/${enc(skillSlug)}`, { raw: true }),\n\n removeSkill: (agentSlug: string, skillSlug: string) =>\n t.request<void>(\"DELETE\", `${agent(agentSlug)}/skills/${enc(skillSlug)}`, { raw: true }),\n\n replaceSkillRoles: (agentSlug: string, skillSlug: string, roleSlugs: string[]) =>\n t.request<void>(\"PUT\", `${agent(agentSlug)}/skills/${enc(skillSlug)}/roles`, {\n body: { role_slugs: roleSlugs } satisfies Schemas[\"ReplaceAgentSkillRolesInput\"],\n raw: true,\n }),\n\n listTaskTemplates: (agentSlug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"AgentTaskTemplateItem\"][]>(\"GET\", `${agent(agentSlug)}/task-templates`, {\n signal,\n }),\n\n addTaskTemplate: (agentSlug: string, templateSlug: string) =>\n t.request<void>(\"PUT\", `${agent(agentSlug)}/task-templates/${enc(templateSlug)}`, {\n raw: true,\n }),\n\n removeTaskTemplate: (agentSlug: string, templateSlug: string) =>\n t.request<void>(\"DELETE\", `${agent(agentSlug)}/task-templates/${enc(templateSlug)}`, {\n raw: true,\n }),\n\n replaceTaskTemplateRoles: (agentSlug: string, templateSlug: string, roleSlugs: string[]) =>\n t.request<void>(\"PUT\", `${agent(agentSlug)}/task-templates/${enc(templateSlug)}/roles`, {\n body: { role_slugs: roleSlugs } satisfies Schemas[\"ReplaceAgentTaskTemplateRolesInput\"],\n raw: true,\n }),\n\n listAutoCallTools: (agentSlug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"AutoCallToolsConfig\"]>(\"GET\", `${agent(agentSlug)}/auto-call-tools`, {\n signal,\n }),\n\n putAutoCallTools: (agentSlug: string, tools: Schemas[\"AutoCallToolRef\"][]) =>\n t.request<void>(\"PUT\", `${agent(agentSlug)}/auto-call-tools`, {\n body: { tools } satisfies Schemas[\"PutAutoCallToolsInput\"],\n raw: true,\n }),\n };\n}\n",
10
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath, withoutNoopRename } from \"./paths.js\";\n\nexport function aiProvidersApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/ai-providers`;\n const provider = (slug: string) => `${base}/${enc(slug)}`;\n\n return {\n /** Includes providers shared by the `_root` tenant, flagged `shared: true`. */\n list: (signal?: AbortSignal) => t.request<Schemas[\"AiProvider\"][]>(\"GET\", base, { signal }),\n\n get: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"AiProvider\"]>(\"GET\", provider(slug), { signal }),\n\n create: (input: Schemas[\"CreateAiProviderInput\"]) =>\n t.request<Schemas[\"AiProvider\"]>(\"POST\", base, { body: input }),\n\n update: (currentSlug: string, input: Schemas[\"UpdateAiProviderInput\"]) =>\n t.request<Schemas[\"AiProvider\"]>(\"PATCH\", provider(currentSlug), {\n body: withoutNoopRename(input, currentSlug),\n }),\n\n delete: (slug: string) => t.request<void>(\"DELETE\", provider(slug), { raw: true }),\n\n listModels: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"AiProviderModel\"][]>(\"GET\", `${provider(slug)}/models`, { signal }),\n\n /** Re-probes the upstream catalog. 409 while another reconcile is running. */\n refreshModels: (slug: string) =>\n t.request<Schemas[\"AiProviderModel\"][]>(\"POST\", `${provider(slug)}/models/refresh`),\n\n updateModel: (slug: string, modelId: string, input: Schemas[\"UpdateProviderModelInput\"]) =>\n t.request<void>(\"PATCH\", `${provider(slug)}/models/${enc(modelId)}`, {\n body: input,\n raw: true,\n }),\n };\n}\n",
11
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath } from \"./paths.js\";\n\n/** `Channel` and its Create/Update inputs are discriminated unions over `type`\n * (telegram, whapi, whatsapp, external), so no per-type methods are needed. */\nexport function channelsApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/channels`;\n const channel = (slug: string) => `${base}/${enc(slug)}`;\n\n return {\n list: (signal?: AbortSignal) => t.request<Schemas[\"Channel\"][]>(\"GET\", base, { signal }),\n\n get: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"Channel\"]>(\"GET\", channel(slug), { signal }),\n\n create: (input: Schemas[\"CreateChannelInput\"]) =>\n t.request<Schemas[\"CreatedChannel\"]>(\"POST\", base, { body: input }),\n\n update: (slug: string, input: Schemas[\"UpdateChannelInput\"]) =>\n t.request<Schemas[\"Channel\"]>(\"PATCH\", channel(slug), { body: input }),\n\n delete: (slug: string) => t.request<void>(\"DELETE\", channel(slug), { raw: true }),\n\n /** Invalidates the current connection secret and returns a new one. */\n rotateSecret: (slug: string) =>\n t.request<Schemas[\"RotatedSecret\"]>(\"POST\", `${channel(slug)}/rotate-secret`),\n\n /** The response components registered on the channel (external channels\n * only carry them) — the catalog every conversation on the channel\n * resolves at turn load. */\n listComponentLibraries: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"EnabledLibraries\"]>(\"GET\", `${channel(slug)}/component-libraries`, {\n signal,\n }),\n\n /** Replaces the channel's enabled libraries (send the complete list every\n * time; empty clears it). External channels only — 409 on any other type.\n * Running conversations pick the new catalog up on their next turn.\n *\n * Returns the slugs together with every tag they resolve to, so a runner can\n * check the catalog against what its frontend actually renders. */\n setComponentLibraries: (slug: string, libraries: string[]) =>\n t.request<Schemas[\"EnabledLibraries\"]>(\"PUT\", `${channel(slug)}/component-libraries`, {\n body: { libraries } satisfies Schemas[\"SetLibrariesInput\"],\n }),\n\n listDeadLetters: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"DeadLetter\"][]>(\"GET\", `${channel(slug)}/dead-letters`, { signal }),\n\n pairWhatsapp: (slug: string, input: Schemas[\"WhatsappPairInput\"]) =>\n t.request<Schemas[\"WhatsappPairStatus\"]>(\"POST\", `${channel(slug)}/whatsapp/pair`, {\n body: input,\n }),\n };\n}\n",
12
+ "// The client-tool runner: give it your functions, it keeps a conversation's\n// client tools declared, executed and answered until you stop it.\n//\n// Written against `Transport` rather than the admin client so the same runner\n// serves the browser-safe conversation client when that lands — nothing here\n// knows which credential opened the connection.\n\nimport { AgentApiError } from \"./errors.js\";\nimport type { Transport } from \"./http.js\";\nimport type { Schemas } from \"./schemas.js\";\nimport { readSse } from \"./sse.js\";\n\n/** One tool: its declaration and the function that implements it. */\nexport interface ClientTool<Args = Record<string, unknown>, Result = unknown> {\n description?: string;\n /** JSON Schema for the arguments. Defaults to an open object, which leaves\n * the model to guess — worth writing. */\n inputSchema?: Record<string, unknown>;\n /** JSON Schema for what you return. The server validates against it before\n * the model sees anything, so a bug in your handler surfaces as a rejected\n * submit rather than as nonsense in the transcript. */\n outputSchema?: Record<string, unknown>;\n /** `true` promises the call mutates nothing, which exempts it from the\n * agent's guardrail. Don't claim it lightly. */\n readOnlyHint?: boolean;\n destructiveHint?: boolean;\n /** `true` promises the call is safe to run twice. Without it the server\n * assumes it isn't, and pins the lease to the call's deadline so no second\n * client can pick the call up mid-execution — safer, but a client that dies\n * holds the call until it times out instead of failing over. */\n idempotentHint?: boolean;\n /** Seconds the server waits before failing the call on your behalf.\n * Defaults to 90. Keep it tight: a pending call also holds back any user\n * message that arrives meanwhile. */\n timeoutSeconds?: number;\n handler: (args: Args, ctx: ClientToolContext) => Promise<Result> | Result;\n}\n\nexport interface ClientToolContext {\n /** The call's id, echoed on the result. Handy for logs. */\n toolCallId: string;\n conversationId: string;\n /** Aborts when the session stops, so a long handler can bail out. */\n signal: AbortSignal;\n}\n\nexport interface ServeClientToolsOptions {\n tools: Record<string, ClientTool<never, unknown>>;\n /** Stops the session. Same effect as calling `stop()`. */\n signal?: AbortSignal;\n /** Identifies this runner when leasing calls. Defaults to a random id, which\n * is what you want unless you're deliberately resuming another runner's\n * leases. */\n claimant?: string;\n /** Lease length in seconds; the runner renews at half of it. Defaults to 70.\n * Ignored for a tool that writes and isn't declared `idempotentHint: true` —\n * the server pins that lease to the call's deadline, because handing such a\n * call to a second client is worse than making the first one wait. */\n claimTtlSeconds?: number;\n /** Skip the declaration sync — for when the tools are already declared and\n * you only want to execute. */\n declare?: boolean;\n /**\n * Open the conversation's event stream to watch for calls. On by default.\n *\n * Turn it off when you already hold that stream — a chat UI does — and drive\n * the session with `poke()` instead: once for every `client_tool_call` frame,\n * and once each time the stream (re)connects. One connection instead of two,\n * and the server caps how many a user may hold open at once.\n */\n watch?: boolean;\n /** Reported failures that the runner recovered from: a stream drop, a\n * handler that threw. Losing a claim race is not one of them — that is\n * ordinary coordination, and the runner keeps watching the call instead. */\n onError?: (err: unknown) => void;\n}\n\nexport interface ClientToolsSession {\n stop(): void;\n /**\n * Look for calls to run, now. Cheap and safe to call spuriously: it reads the\n * pending list, and a call already being handled is skipped.\n *\n * Only needed with `watch: false`, where something else owns the stream.\n */\n poke(): void;\n /** Resolves when the session has stopped and no handler is still running. */\n done: Promise<void>;\n}\n\n/** Matches the server's own default. Sized against the browser: a background\n * tab's timers get throttled to about a minute, and renewing at half of 70s\n * still lands inside the window. */\nconst DEFAULT_CLAIM_TTL_SECONDS = 70;\n\n/** How many times the result POST is retried before giving up. The work is\n * already done at that point, so the answer is worth more than one attempt. */\nconst SUBMIT_ATTEMPTS = 5;\n\n/**\n * Declares `tools` on the conversation, then executes every call the agent\n * makes against them until stopped.\n *\n * `conversationPath` is a thunk rather than a string because the two clients\n * learn the tenant differently: the operator client is constructed with the\n * slug, while an end-user client discovers it from the token via `me()` and so\n * can only answer asynchronously.\n *\n * The cycle per call is claim → handler → submit. The claim is what keeps two\n * runners on the same conversation from both executing it; it is renewed while\n * the handler runs, so a slow handler doesn't lose the call, and it lapses if\n * this process dies, so the call isn't stranded either.\n *\n * A handler that throws submits the failure rather than swallowing it: the\n * agent needs to hear that the tool failed, otherwise it waits out the\n * server-side deadline for no reason.\n */\nexport function serveClientTools(\n t: Transport,\n conversationPath: () => Promise<string>,\n conversationId: string,\n options: ServeClientToolsOptions,\n): ClientToolsSession {\n const controller = new AbortController();\n const stop = () => controller.abort();\n if (options.signal) {\n if (options.signal.aborted) stop();\n else options.signal.addEventListener(\"abort\", stop, { once: true });\n }\n\n const claimant = options.claimant ?? `sdk-${randomId()}`;\n const ttl = options.claimTtlSeconds ?? DEFAULT_CLAIM_TTL_SECONDS;\n // Resolved once, on the first use, and reused: the end-user client's thunk\n // costs a `me()` round trip the first time it is called.\n let basePath: string | undefined;\n const resolveBase = async (): Promise<string> => {\n basePath ??= await conversationPath();\n return basePath;\n };\n const inFlight = new Set<string>();\n // A set that drops entries as they settle, not an array that grows: a\n // long-lived session handles thousands of calls and frames, and keeping a\n // resolved promise per event would leak for as long as the session lives.\n const running = new Set<Promise<void>>();\n const track = (p: Promise<void>) => {\n running.add(p);\n void p.finally(() => running.delete(p)).catch(() => {});\n };\n\n const done = (async () => {\n try {\n await run();\n } catch (err) {\n // Declaring failed, or the stream returned a 4xx that won't fix itself.\n // Abort so in-flight handlers unwind (and release their leases) instead\n // of running on behind a promise the caller may never await.\n stop();\n while (running.size > 0) await Promise.allSettled([...running]);\n throw err;\n }\n })();\n\n async function run(): Promise<void> {\n const base = await resolveBase();\n if (options.declare !== false) {\n await t.request<Schemas[\"ClientTool\"][]>(\"PUT\", `${base}/client-tools`, {\n body: { tools: declarations(options.tools) },\n signal: controller.signal,\n });\n }\n\n if (options.watch === false) {\n // The caller's stream is already open — it was open before the tools were\n // declared, which is the ordering the drain below relies on. From here\n // `poke()` plays the part `onOpen`/`onEvent` play in the watched case.\n track(guard(drain));\n await stopped();\n while (running.size > 0) await Promise.allSettled([...running]);\n return;\n }\n\n await readSse<{ event_type?: string }>({\n url: t.url(`${base}/events/stream`),\n event: \"conversation_event\",\n headers: () => t.streamHeaders(),\n fetchImpl: t.fetchImpl,\n signal: controller.signal,\n onError: options.onError,\n // The catch-up runs *after* the stream is open, never before. Declaring\n // the tools makes them callable immediately, so a drain that ran first\n // would leave a window — one round trip wide — in which the agent can\n // issue a call that the drain already missed and the stream isn't there\n // to see. Draining on open cannot miss it: the call either predates the\n // connection, and the drain finds it, or it doesn't, and a frame arrives.\n // Firing on every reconnect covers a gap the backoff swallowed too.\n onOpen: () => {\n track(guard(drain));\n },\n // A client tool event re-drains rather than acting on the frame's own\n // payload: one code path covers the frame, the catch-up and a reconnect,\n // and `inFlight` keeps the overlap from running anything twice.\n onEvent: (ev) => {\n if (ev.event_type !== \"client_tool_call\") return;\n track(guard(drain));\n },\n });\n\n // Loop: a handler still running can be waiting on a claim it will get,\n // and settling it may queue nothing new only once the abort has landed.\n while (running.size > 0) await Promise.allSettled([...running]);\n }\n\n async function drain(): Promise<void> {\n if (controller.signal.aborted) return;\n const base = await resolveBase();\n const calls = await t.request<Schemas[\"ClientToolCall\"][]>(\"GET\", `${base}/client-tool-calls`, {\n signal: controller.signal,\n });\n for (const call of calls) {\n if (inFlight.has(call.tool_call_id)) continue;\n const tool = options.tools[call.tool_name];\n if (!tool) continue;\n inFlight.add(call.tool_call_id);\n track(guard(() => execute(call, tool)));\n }\n }\n\n async function execute(\n call: Schemas[\"ClientToolCall\"],\n tool: ClientTool<never, unknown>,\n ): Promise<void> {\n const id = call.tool_call_id;\n const base = await resolveBase();\n try {\n if (!(await acquireClaim(call))) return;\n\n const keepAlive = setInterval(\n () => {\n void t\n .request(\"POST\", `${base}/client-tool-calls/${id}/claim`, {\n body: { claimant, ttl_seconds: ttl },\n })\n .catch(() => {});\n },\n Math.max(1_000, (ttl * 1000) / 2),\n );\n\n let body: Schemas[\"SubmitResultInput\"];\n try {\n const result = await tool.handler(call.arguments as never, {\n toolCallId: id,\n conversationId,\n signal: controller.signal,\n });\n // `null`, not omitted: a handler with only side effects returns\n // nothing, and that still has to read as an answer.\n body = { result: result === undefined ? null : result, claimant };\n } catch (err) {\n // A handler that threw because *we* stopped the session hasn't failed —\n // the work was cancelled. Submitting an error would answer the call on\n // behalf of every other client too, so hand the lease back instead and\n // let someone still running take it.\n if (controller.signal.aborted) {\n clearInterval(keepAlive);\n await t\n .request<void>(\"DELETE\", `${base}/client-tool-calls/${id}/claim`, {\n query: { claimant },\n raw: true,\n })\n .catch(() => {});\n return;\n }\n options.onError?.(err);\n body = { error: errorText(err), claimant };\n } finally {\n clearInterval(keepAlive);\n }\n\n await submitWithRetry(id, body);\n } finally {\n inFlight.delete(id);\n }\n }\n\n /**\n * Wait for the lease, rather than give up on it. Losing the race is not a\n * failure — the other holder may be a tab the user closed a second later, or\n * a phone that went offline mid-call. So this watches instead: the 409 says\n * when the current lease expires, we sleep exactly that long and ask again.\n *\n * Returns false only when there is genuinely nothing left: the call was\n * answered (410) or vanished (404). A lease that outlives the call's own\n * deadline — what a pinned lease looks like from here — is waited on rather\n * than abandoned: the holder may release it, and a release produces no event\n * for anyone to react to, so a runner that walked away would never come back\n * and the call would sit until the reaper failed it.\n */\n async function acquireClaim(call: Schemas[\"ClientToolCall\"]): Promise<boolean> {\n const base = await resolveBase();\n const deadline = Date.parse(call.deadline_at);\n while (!controller.signal.aborted) {\n try {\n await t.request<Schemas[\"ClientToolCall\"]>(\n \"POST\",\n `${base}/client-tool-calls/${call.tool_call_id}/claim`,\n { body: { claimant, ttl_seconds: ttl }, signal: controller.signal },\n );\n return true;\n } catch (err) {\n if (!(err instanceof AgentApiError)) throw err;\n if (err.status === 410 || err.status === 404) return false;\n if (err.status !== 409) throw err;\n\n const held = err.json<{ claim_expires_at?: string }>()?.claim_expires_at;\n const until = held ? Date.parse(held) : Date.now() + ttl * 1000;\n // Never wait past the deadline: at that point the reaper resolves the\n // call and the next attempt gets a 410, which is what ends the loop.\n const wakeAt = Number.isFinite(deadline) ? Math.min(until, deadline) : until;\n await sleep(Math.max(250, wakeAt - Date.now()), controller.signal);\n }\n }\n return false;\n }\n\n /**\n * The handler has already run by the time this is called — for a write, the\n * side effect has happened. Losing the answer to a dropped connection would\n * leave the agent waiting out the deadline and then told, wrongly, that\n * nothing ran. So retry the POST; the server answers a second delivery of an\n * already-recorded result with 410, which is a success from here.\n */\n async function submitWithRetry(id: string, body: Schemas[\"SubmitResultInput\"]): Promise<void> {\n const base = await resolveBase();\n for (let attempt = 0; ; attempt++) {\n try {\n await t.request<void>(\"POST\", `${base}/client-tool-calls/${id}/result`, {\n body,\n raw: true,\n });\n return;\n } catch (err) {\n const status = err instanceof AgentApiError ? err.status : 0;\n // 410 means it is already recorded; 4xx means this body will never be\n // accepted, so repeating it only delays the failure.\n if (status === 410) return;\n if (status >= 400 && status < 500) throw err;\n if (attempt >= SUBMIT_ATTEMPTS - 1 || controller.signal.aborted) throw err;\n options.onError?.(err);\n await sleep(Math.min(8_000, 250 * 2 ** attempt), controller.signal);\n }\n }\n }\n\n async function guard(fn: () => Promise<void>): Promise<void> {\n try {\n await fn();\n } catch (err) {\n if (!controller.signal.aborted) options.onError?.(err);\n }\n }\n\n function stopped(): Promise<void> {\n if (controller.signal.aborted) return Promise.resolve();\n return new Promise((resolve) => {\n controller.signal.addEventListener(\"abort\", () => resolve(), { once: true });\n });\n }\n\n return {\n stop,\n poke: () => {\n if (!controller.signal.aborted) track(guard(drain));\n },\n done,\n };\n}\n\nexport function declarations(\n tools: Record<string, ClientTool<never, unknown>>,\n): Schemas[\"NamedClientToolInput\"][] {\n return Object.entries(tools).map(([name, tool]) => ({\n name,\n description: tool.description ?? \"\",\n input_schema: tool.inputSchema ?? { type: \"object\" },\n output_schema: tool.outputSchema,\n read_only_hint: tool.readOnlyHint,\n destructive_hint: tool.destructiveHint,\n idempotent_hint: tool.idempotentHint,\n timeout_seconds: tool.timeoutSeconds,\n })) as Schemas[\"NamedClientToolInput\"][];\n}\n\nfunction errorText(err: unknown): string {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const onAbort = () => {\n clearTimeout(timer);\n resolve();\n };\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\n/** `crypto.randomUUID` isn't guaranteed outside secure contexts, and this only\n * needs to be unique among the runners on one conversation. */\nfunction randomId(): string {\n return Math.random().toString(36).slice(2, 10);\n}\n",
13
+ "import {\n type ClientToolsSession,\n type ServeClientToolsOptions,\n serveClientTools,\n} from \"../client-tools.js\";\nimport type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath } from \"./paths.js\";\n\n/**\n * Client tools: tools defined on a conversation with no server-side\n * implementation. The agent calls one, its turn suspends, and whoever drives\n * the API answers.\n *\n * This is the wire layer. For the usual case — \"here are my functions, run\n * them\" — use `serveClientTools`, which drives this on your behalf.\n */\nexport function clientToolsApi(t: Transport, tenantSlug: string) {\n const base = (convId: string) => `${tenantPath(tenantSlug)}/conversations/${enc(convId)}`;\n const tools = (convId: string) => `${base(convId)}/client-tools`;\n const calls = (convId: string) => `${base(convId)}/client-tool-calls`;\n\n return {\n /** Declares your functions on the conversation and runs them as the agent\n * calls them, until you stop the session. This is the whole feature in one\n * call; everything below is the wire it drives. */\n serve: (convId: string, options: ServeClientToolsOptions): ClientToolsSession =>\n serveClientTools(t, async () => base(convId), convId, options),\n\n list: (convId: string, signal?: AbortSignal) =>\n t.request<Schemas[\"ClientTool\"][]>(\"GET\", tools(convId), { signal }),\n\n /** Declares the whole set: entries are upserted, anything not listed is\n * removed. The shape a reconnecting client wants — it converges instead of\n * accumulating definitions from a previous session. */\n replace: (convId: string, input: Schemas[\"ReplaceClientToolsInput\"]) =>\n t.request<Schemas[\"ClientTool\"][]>(\"PUT\", tools(convId), { body: input }),\n\n /** Calls the agent is blocked on. Normally you learn about a call from the\n * `client_tool_call` event on the conversation's SSE stream; this is the\n * catch-up read for calls issued before you connected. */\n listCalls: (convId: string, signal?: AbortSignal) =>\n t.request<Schemas[\"ClientToolCall\"][]>(\"GET\", calls(convId), { signal }),\n\n /** Takes the exclusive lease, or renews it when `claimant` matches the\n * holder. Rejects with 409 while someone else holds a live one. */\n claim: (convId: string, toolCallId: string, input: Schemas[\"ClaimInput\"]) =>\n t.request<Schemas[\"ClientToolCall\"]>(\"POST\", `${calls(convId)}/${enc(toolCallId)}/claim`, {\n body: input,\n }),\n\n releaseClaim: (convId: string, toolCallId: string, claimant: string) =>\n t.request<void>(\"DELETE\", `${calls(convId)}/${enc(toolCallId)}/claim`, {\n query: { claimant },\n raw: true,\n }),\n\n /** Answers a call. Supply exactly one of `result`, `content` or `error`. */\n submitResult: (convId: string, toolCallId: string, input: Schemas[\"SubmitResultInput\"]) =>\n t.request<void>(\"POST\", `${calls(convId)}/${enc(toolCallId)}/result`, {\n body: input,\n raw: true,\n }),\n };\n}\n",
14
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath, withoutNoopRename } from \"./paths.js\";\n\n/** Component libraries: the catalogs of interactive blocks an agent may put in a\n * reply, authored here and enabled by slug on a conversation or an external\n * channel.\n *\n * Authoring is deliberately an operator capability. A component's `summary`,\n * `description` and `exampleMdx` are shown to the model verbatim, so writing one\n * is writing prompt content — hence `component_libraries:write` on an api_key,\n * never a browser. A client app holding an end-user token can only *enable* a\n * library, which is the half that depends on which of its screens is open.\n *\n * Edits replace in place — no version snapshots, and every conversation with the\n * library enabled sees the latest on its next turn, the same rule skills follow. */\nexport function componentLibrariesApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/component-libraries`;\n const library = (slug: string) => `${base}/${enc(slug)}`;\n\n return {\n /** Every library in the tenant with its tag names — enough to wire one up\n * without fetching the full entries. */\n list: (signal?: AbortSignal) =>\n t.request<Schemas[\"ComponentLibraryListItem\"][]>(\"GET\", base, { signal }),\n\n /** One library with every component's full entry — the same text the agent\n * receives from `component_read`. */\n get: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"ComponentLibrary\"]>(\"GET\", library(slug), { signal }),\n\n create: (input: Schemas[\"CreateComponentLibraryInput\"]) =>\n t.request<Schemas[\"ComponentLibrary\"]>(\"POST\", base, { body: input }),\n\n /** Patches in place; omitted fields stay. Supplying `components` replaces\n * the whole set, so send it complete — half a library must never reach a\n * prompt because two calls were in flight. */\n update: (currentSlug: string, input: Schemas[\"UpdateComponentLibraryInput\"]) =>\n t.request<Schemas[\"ComponentLibrary\"]>(\"PATCH\", library(currentSlug), {\n body: withoutNoopRename(input, currentSlug),\n }),\n\n /** Deletes the library and every enablement of it. Messages already written\n * keep their text: blocks are re-derived from content on read, and the read\n * path consults no catalog. */\n delete: (slug: string) => t.request<void>(\"DELETE\", library(slug), { raw: true }),\n };\n}\n",
15
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath } from \"./paths.js\";\n\n/**\n * The operator's view of conversations: the raw event log, sub-agent trees,\n * workspace files and cost — everything an admin console renders.\n *\n * This is deliberately *not* the curated `Conversation`/`Message` surface an\n * end-user app will get from the browser-safe client. These shapes come\n * straight from the generated schema and move with the server.\n */\nexport function conversationsAdminApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/conversations`;\n const conv = (id: string) => `${base}/${enc(id)}`;\n\n /** Multipart body for the image route: repeated `file` parts, positional\n * `label` parts (the i-th label names the i-th file, so an empty string\n * keeps positions aligned when only some images are labeled), and one\n * `caption` shared by the set. */\n const sendImages = (\n id: string,\n images: Array<{ image: Blob; filename?: string; label?: string }>,\n caption?: string,\n ) => {\n const form = new FormData();\n for (const [i, entry] of images.entries()) {\n form.append(\"file\", entry.image, entry.filename ?? `image-${i + 1}.png`);\n form.append(\"label\", entry.label ?? \"\");\n }\n if (caption) form.append(\"caption\", caption);\n return t.request<Schemas[\"ConversationEvent\"]>(\"POST\", `${conv(id)}/user_message/image`, {\n body: form,\n });\n };\n\n return {\n list: (\n query: { before?: string; limit?: number; origin?: string; user_id?: string } = {},\n signal?: AbortSignal,\n ) => t.request<Schemas[\"Conversation\"][]>(\"GET\", base, { query, signal }),\n\n get: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"Conversation\"]>(\"GET\", conv(id), { signal }),\n\n create: (input: Schemas[\"CreateConversationInput\"]) =>\n t.request<Schemas[\"Conversation\"]>(\"POST\", base, { body: input }),\n\n update: (id: string, input: Schemas[\"UpdateConversationInput\"]) =>\n t.request<Schemas[\"Conversation\"]>(\"PATCH\", conv(id), { body: input }),\n\n archive: (id: string) => t.request<Schemas[\"Conversation\"]>(\"POST\", `${conv(id)}/archive`),\n\n /** Clears the backoff and re-dispatches a conversation stuck after failures. */\n retryNow: (id: string) => t.request<Schemas[\"Conversation\"]>(\"POST\", `${conv(id)}/retry-now`),\n\n listEvents: (\n id: string,\n query: { before?: number; limit?: number } = {},\n signal?: AbortSignal,\n ) => t.request<Schemas[\"ConversationEvent\"][]>(\"GET\", `${conv(id)}/events`, { query, signal }),\n\n /** Only for channel-less conversations: a channel-backed one receives the\n * user's words through the channel, so injecting here would forge a message\n * they never sent (409). */\n sendUserMessage: (id: string, content: string) =>\n t.request<Schemas[\"ConversationEvent\"]>(\"POST\", `${conv(id)}/user_message`, {\n body: { content } satisfies Schemas[\"SendMessageInput\"],\n }),\n\n /** Voice message. Stored content-addressed and transcribed by the agent's\n * STT model before the turn runs; the event itself carries empty content. */\n sendUserAudio: (id: string, audio: Blob, filename = \"recording.webm\") => {\n const form = new FormData();\n form.append(\"audio\", audio, filename);\n return t.request<Schemas[\"ConversationEvent\"]>(\"POST\", `${conv(id)}/user_message/audio`, {\n body: form,\n });\n },\n\n /** Image message (png/jpeg/webp/gif). Shown to the model natively when the\n * agent's chat model has vision, otherwise described by the agent's\n * fallback vision model. The optional caption becomes the event content. */\n sendUserImage: (\n id: string,\n image: Blob,\n opts: { filename?: string; caption?: string; label?: string } = {},\n ) => sendImages(id, [{ image, filename: opts.filename, label: opts.label }], opts.caption),\n\n /** Up to 10 images in ONE `user_message`, each with an optional label the\n * model sees next to it (so it can refer to them by name), plus one\n * caption shared by the whole set. */\n sendUserImages: (\n id: string,\n images: Array<{ image: Blob; filename?: string; label?: string }>,\n opts: { caption?: string } = {},\n ) => sendImages(id, images, opts.caption),\n\n /** Works on any conversation, channel-backed included. */\n steer: (id: string, content: string) =>\n t.request<Schemas[\"ConversationEvent\"]>(\"POST\", `${conv(id)}/steer`, {\n body: { content } satisfies Schemas[\"SteerInput\"],\n }),\n\n listSubConversations: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"SubConversationSummary\"][]>(\"GET\", `${conv(id)}/sub-conversations`, {\n signal,\n }),\n\n getSummary: (id: string, summaryId: string, signal?: AbortSignal) =>\n t.request<Schemas[\"ConversationSummaryDto\"]>(\n \"GET\",\n `${conv(id)}/summaries/${enc(summaryId)}`,\n { signal },\n ),\n\n listKnowledgeBases: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"KnowledgeBaseListItem\"][]>(\"GET\", `${conv(id)}/knowledge-bases`, {\n signal,\n }),\n\n attachKnowledgeBase: (id: string, kbSlug: string) =>\n t.request<void>(\"PUT\", `${conv(id)}/knowledge-bases/${enc(kbSlug)}`, { raw: true }),\n\n detachKnowledgeBase: (id: string, kbSlug: string) =>\n t.request<void>(\"DELETE\", `${conv(id)}/knowledge-bases/${enc(kbSlug)}`, { raw: true }),\n\n listSkills: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"ConversationSkillItem\"][]>(\"GET\", `${conv(id)}/skills`, { signal }),\n\n addSkill: (id: string, skillSlug: string) =>\n t.request<void>(\"PUT\", `${conv(id)}/skills/${enc(skillSlug)}`, { raw: true }),\n\n removeSkill: (id: string, skillSlug: string) =>\n t.request<void>(\"DELETE\", `${conv(id)}/skills/${enc(skillSlug)}`, { raw: true }),\n\n /** One directory, never recursive. `atSeq` browses the workspace as it\n * stood at a given event, reaching history the agent no longer sees;\n * without it you get the live tree, which is what the agent would be shown\n * next turn — empty once the workspace has expired. */\n workspaceDir: (id: string, atSeq?: number, path?: string, signal?: AbortSignal) =>\n t.request<Schemas[\"WorkspaceDirResponse\"]>(\"GET\", `${conv(id)}/workspace/dir`, {\n query: { at_seq: atSeq, path },\n signal,\n }),\n\n /** Raw `Response`: the file's bytes, with the server's own filename in\n * `Content-Disposition`. */\n workspaceFile: (id: string, query: { path: string; at_seq?: number }) =>\n t.fetchRaw(\"GET\", `${conv(id)}/workspace/file`, { query }),\n\n /** Create or replace one file. Starts no turn — the agent is told about it\n * as part of its next request, so send a message if you want an answer. */\n workspaceWrite: (id: string, path: string, file: Blob, filename?: string) => {\n const form = new FormData();\n form.append(\"file\", file, filename ?? path.split(\"/\").pop() ?? \"upload\");\n return t.request<Schemas[\"WorkspaceMutationResponse\"]>(\"PUT\", `${conv(id)}/workspace/file`, {\n query: { path },\n body: form,\n });\n },\n\n /** Write several files as **one** snapshot: the agent sees the upload as a\n * single change rather than as N, and no reader ever observes half of it.\n * Positional `path` parts pair with the files by index. */\n workspaceWriteMany: (\n id: string,\n files: Array<{ path: string; file: Blob; filename?: string }>,\n ) => {\n const form = new FormData();\n for (const [i, entry] of files.entries()) {\n form.append(\"file\", entry.file, entry.filename ?? `file-${i + 1}`);\n form.append(\"path\", entry.path);\n }\n return t.request<Schemas[\"WorkspaceMutationResponse\"]>(\n \"POST\",\n `${conv(id)}/workspace/files`,\n { body: form },\n );\n },\n\n /** Remove a file, or a directory with everything under it. History keeps\n * resolving through `atSeq`. */\n workspaceDelete: (id: string, path: string) =>\n t.request<Schemas[\"WorkspaceMutationResponse\"]>(\"DELETE\", `${conv(id)}/workspace/file`, {\n query: { path },\n }),\n\n workspaceMove: (id: string, from: string, to: string) =>\n t.request<Schemas[\"WorkspaceMutationResponse\"]>(\"POST\", `${conv(id)}/workspace/move`, {\n body: { from, to },\n }),\n\n /** Raw `Response`: the bytes of an event's media attachment (voice note or\n * image), `Content-Type` from the stored mime. */\n eventAttachment: (id: string, eventId: string, attachmentId?: string) =>\n t.fetchRaw(\"GET\", `${conv(id)}/events/${eventId}/attachment`, {\n query: { attachment_id: attachmentId },\n }),\n };\n}\n",
16
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, withoutNoopRename } from \"./paths.js\";\n\nexport function tenantsApi(t: Transport) {\n return {\n list: (signal?: AbortSignal) =>\n t.request<Schemas[\"Tenant\"][]>(\"GET\", \"/api/v1/tenants\", { signal }),\n\n create: (input: Schemas[\"CreateTenantInput\"]) =>\n t.request<Schemas[\"Tenant\"]>(\"POST\", \"/api/v1/tenants\", { body: input }),\n\n update: (currentSlug: string, input: Schemas[\"UpdateTenantInput\"]) =>\n t.request<Schemas[\"Tenant\"]>(\"PATCH\", `/api/v1/tenants/${enc(currentSlug)}`, {\n body: withoutNoopRename(input, currentSlug),\n }),\n\n delete: (slug: string) =>\n t.request<void>(\"DELETE\", `/api/v1/tenants/${enc(slug)}`, { raw: true }),\n };\n}\n\nexport function apiKeysApi(t: Transport) {\n const base = \"/api/v1/api_keys\";\n return {\n list: (signal?: AbortSignal) => t.request<Schemas[\"ApiKeyListItem\"][]>(\"GET\", base, { signal }),\n\n get: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"ApiKeyDetail\"]>(\"GET\", `${base}/${enc(id)}`, { signal }),\n\n create: (input: Schemas[\"CreateApiKeyInput\"]) =>\n t.request<Schemas[\"CreatedApiKey\"]>(\"POST\", base, { body: input }),\n\n update: (id: string, input: Schemas[\"UpdateApiKeyInput\"]) =>\n t.request<Schemas[\"ApiKey\"]>(\"PATCH\", `${base}/${enc(id)}`, { body: input }),\n\n delete: (id: string) => t.request<void>(\"DELETE\", `${base}/${enc(id)}`, { raw: true }),\n\n /** Returns a new plaintext secret; the previous one stops working at once. */\n rotate: (id: string) =>\n t.request<Schemas[\"CreatedApiKey\"]>(\"POST\", `${base}/${enc(id)}/rotate`),\n\n addGrant: (id: string, input: Schemas[\"AddGrantInput\"]) =>\n t.request<Schemas[\"GrantOut\"]>(\"POST\", `${base}/${enc(id)}/grants`, { body: input }),\n\n removeGrant: (id: string, grantId: string) =>\n t.request<void>(\"DELETE\", `${base}/${enc(id)}/grants/${enc(grantId)}`, { raw: true }),\n };\n}\n\n/**\n * Providers owned by the reserved `_root` system tenant and shared with every\n * tenant's listing. Root-only, and a separate route family from a tenant's own\n * providers — never reachable through a real tenant's URL.\n */\nexport function sharedProvidersApi(t: Transport) {\n const base = \"/api/v1/ai-providers/shared\";\n return {\n create: (input: Schemas[\"CreateAiProviderInput\"]) =>\n t.request<Schemas[\"AiProvider\"]>(\"POST\", base, { body: input }),\n\n update: (currentSlug: string, input: Schemas[\"UpdateAiProviderInput\"]) =>\n t.request<Schemas[\"AiProvider\"]>(\"PATCH\", `${base}/${enc(currentSlug)}`, {\n body: withoutNoopRename(input, currentSlug),\n }),\n\n delete: (slug: string) => t.request<void>(\"DELETE\", `${base}/${enc(slug)}`, { raw: true }),\n\n refreshModels: (slug: string) =>\n t.request<Schemas[\"AiProviderModel\"][]>(\"POST\", `${base}/${enc(slug)}/models/refresh`),\n\n updateModel: (slug: string, modelId: string, input: Schemas[\"UpdateProviderModelInput\"]) =>\n t.request<void>(\"PATCH\", `${base}/${enc(slug)}/models/${enc(modelId)}`, {\n body: input,\n raw: true,\n }),\n };\n}\n",
17
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath, withoutNoopRename } from \"./paths.js\";\n\n/**\n * A knowledge base is uploaded documents plus a cited wiki curated from them.\n * It attaches to a conversation or to a user (the OR of both links) — unlike\n * MCPs and skills, there is no agent-level link.\n */\nexport function knowledgeBasesApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/knowledge-bases`;\n const kb = (slug: string) => `${base}/${enc(slug)}`;\n\n return {\n list: (signal?: AbortSignal) =>\n t.request<Schemas[\"KnowledgeBaseListItem\"][]>(\"GET\", base, { signal }),\n\n get: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"KnowledgeBase\"]>(\"GET\", kb(slug), { signal }),\n\n create: (input: Schemas[\"CreateKnowledgeBaseInput\"]) =>\n t.request<Schemas[\"KnowledgeBase\"]>(\"POST\", base, { body: input }),\n\n update: (currentSlug: string, input: Schemas[\"UpdateKnowledgeBaseInput\"]) =>\n t.request<Schemas[\"KnowledgeBase\"]>(\"PATCH\", kb(currentSlug), {\n body: withoutNoopRename(input, currentSlug),\n }),\n\n delete: (slug: string) => t.request<void>(\"DELETE\", kb(slug), { raw: true }),\n\n /** Wakes the \"nap\" agent that turns sources into wiki pages. */\n requestCuration: (slug: string) => t.request<void>(\"POST\", `${kb(slug)}/curate`, { raw: true }),\n\n listSources: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"KnowledgeBaseSource\"][]>(\"GET\", `${kb(slug)}/sources`, { signal }),\n\n createTextSource: (slug: string, input: Schemas[\"CreateTextSourceInput\"]) =>\n t.request<Schemas[\"KnowledgeBaseSource\"]>(\"POST\", `${kb(slug)}/sources/text`, {\n body: input,\n }),\n\n /** Multipart upload of a file's original bytes — the only copy kept. */\n uploadSource: (slug: string, file: File | Blob, title?: string) => {\n const form = new FormData();\n form.append(\"file\", file);\n if (title?.trim()) form.append(\"title\", title.trim());\n return t.request<Schemas[\"KnowledgeBaseSource\"]>(\"POST\", `${kb(slug)}/sources`, {\n body: form,\n });\n },\n\n retractSource: (slug: string, sourceId: string) =>\n t.request<void>(\"DELETE\", `${kb(slug)}/sources/${enc(sourceId)}`, { raw: true }),\n\n /** The raw `Response`, so callers decide how to save the bytes — the\n * browser's download dance needs the DOM and doesn't belong here. */\n downloadSource: (slug: string, sourceId: string) =>\n t.fetchRaw(\"GET\", `${kb(slug)}/sources/${enc(sourceId)}/content`),\n\n listPages: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"KnowledgeBasePageListItem\"][]>(\"GET\", `${kb(slug)}/pages`, { signal }),\n\n getPage: (slug: string, pageSlug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"KnowledgeBasePage\"]>(\"GET\", `${kb(slug)}/pages/${enc(pageSlug)}`, {\n signal,\n }),\n\n updatePage: (slug: string, pageSlug: string, input: Schemas[\"UpdatePageInput\"]) =>\n t.request<Schemas[\"KnowledgeBasePage\"]>(\"PUT\", `${kb(slug)}/pages/${enc(pageSlug)}`, {\n body: input,\n }),\n };\n}\n",
18
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath, withoutNoopRename } from \"./paths.js\";\n\n/**\n * MCP servers: the executable-tool half of the tool surface. Skills (markdown\n * for prompt-shaping) are the other half and live in their own module — the two\n * are complementary, not alternatives, and pairing both for one capability is\n * normal.\n */\nexport function mcpsApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/mcps`;\n const mcp = (slug: string) => `${base}/${enc(slug)}`;\n\n return {\n list: (signal?: AbortSignal) => t.request<Schemas[\"McpListItem\"][]>(\"GET\", base, { signal }),\n\n get: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"Mcp\"]>(\"GET\", mcp(slug), { signal }),\n\n create: (input: Schemas[\"CreateMcpInput\"]) =>\n t.request<Schemas[\"Mcp\"]>(\"POST\", base, { body: input }),\n\n update: (currentSlug: string, input: Schemas[\"UpdateMcpInput\"]) =>\n t.request<Schemas[\"Mcp\"]>(\"PATCH\", mcp(currentSlug), {\n body: withoutNoopRename(input, currentSlug),\n }),\n\n delete: (slug: string) => t.request<void>(\"DELETE\", mcp(slug), { raw: true }),\n\n /** Re-handshakes the server and re-reads its tool list. */\n refresh: (slug: string) => t.request<Schemas[\"Mcp\"]>(\"POST\", `${mcp(slug)}/refresh`),\n\n updateTool: (slug: string, toolName: string, enabled: boolean) =>\n t.request<Schemas[\"McpTool\"]>(\"PATCH\", `${mcp(slug)}/tools/${enc(toolName)}`, {\n body: { enabled } satisfies Schemas[\"UpdateMcpToolInput\"],\n }),\n\n getSkill: (slug: string, skillSlug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"McpSkill\"]>(\"GET\", `${mcp(slug)}/skills/${enc(skillSlug)}`, { signal }),\n\n createSkill: (slug: string, input: Schemas[\"CreateMcpSkillInput\"]) =>\n t.request<Schemas[\"McpSkill\"]>(\"POST\", `${mcp(slug)}/skills`, { body: input }),\n\n updateSkill: (slug: string, currentSkillSlug: string, input: Schemas[\"UpdateMcpSkillInput\"]) =>\n t.request<Schemas[\"McpSkill\"]>(\"PATCH\", `${mcp(slug)}/skills/${enc(currentSkillSlug)}`, {\n body: withoutNoopRename(input, currentSkillSlug),\n }),\n\n deleteSkill: (slug: string, skillSlug: string) =>\n t.request<void>(\"DELETE\", `${mcp(slug)}/skills/${enc(skillSlug)}`, { raw: true }),\n };\n}\n",
19
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath, withoutNoopRename } from \"./paths.js\";\n\n/** Skills are markdown plus supporting files, for prompt-shaping and knowledge.\n * Edits replace in place — there are no version snapshots, and live\n * conversations always see the latest. */\nexport function skillsApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/skills`;\n const skill = (slug: string) => `${base}/${enc(slug)}`;\n\n return {\n list: (signal?: AbortSignal) => t.request<Schemas[\"SkillListItem\"][]>(\"GET\", base, { signal }),\n\n get: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"Skill\"]>(\"GET\", skill(slug), { signal }),\n\n create: (input: Schemas[\"CreateSkillInput\"]) =>\n t.request<Schemas[\"Skill\"]>(\"POST\", base, { body: input }),\n\n update: (currentSlug: string, input: Schemas[\"UpdateSkillInput\"]) =>\n t.request<Schemas[\"Skill\"]>(\"PATCH\", skill(currentSlug), {\n body: withoutNoopRename(input, currentSlug),\n }),\n\n delete: (slug: string) => t.request<void>(\"DELETE\", skill(slug), { raw: true }),\n };\n}\n",
20
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath, withoutNoopRename } from \"./paths.js\";\n\n/** Task templates are the user-installable triggers that spawn background runs.\n * `agent_slug` on a template is only the executor — calling one as a tool still\n * needs an `agent_triggers` grant. */\nexport function taskTemplatesApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/task-templates`;\n const template = (slug: string) => `${base}/${enc(slug)}`;\n\n return {\n list: (signal?: AbortSignal) =>\n t.request<Schemas[\"TaskTemplateListItem\"][]>(\"GET\", base, { signal }),\n\n get: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"TaskTemplate\"]>(\"GET\", template(slug), { signal }),\n\n create: (input: Schemas[\"CreateTaskTemplateInput\"]) =>\n t.request<Schemas[\"TaskTemplate\"]>(\"POST\", base, { body: input }),\n\n update: (currentSlug: string, input: Schemas[\"UpdateTaskTemplateInput\"]) =>\n t.request<Schemas[\"TaskTemplate\"]>(\"PATCH\", template(currentSlug), {\n body: withoutNoopRename(input, currentSlug),\n }),\n\n delete: (slug: string) => t.request<void>(\"DELETE\", template(slug), { raw: true }),\n\n /** Mints the shared secret that lets an outside caller schedule this\n * template without an api_key. Shown once. */\n createSecret: (slug: string) =>\n t.request<Schemas[\"GeneratedSecret\"]>(\"POST\", `${template(slug)}/secret`),\n\n revokeSecret: (slug: string) =>\n t.request<void>(\"DELETE\", `${template(slug)}/secret`, { raw: true }),\n\n /** The raw `Response`: this route answers with a plain-text reason for a\n * refusal (missing param, bad cron, cadence too fast, per-user cap) that is\n * worth surfacing verbatim rather than mapping to a generic message. */\n trigger: (slug: string, input: Schemas[\"ScheduleTaskTemplateInput\"]) =>\n t.fetchRaw(\"POST\", `${template(slug)}/trigger`, { body: input }),\n };\n}\n\nexport function scheduledRunsApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/scheduled-runs`;\n\n return {\n list: (\n query: { task_template?: string; user_id?: string; enabled?: boolean } = {},\n signal?: AbortSignal,\n ) => t.request<Schemas[\"ScheduledRun\"][]>(\"GET\", base, { query, signal }),\n\n get: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"ScheduledRunDetail\"]>(\"GET\", `${base}/${enc(id)}`, { signal }),\n\n update: (id: string, input: Schemas[\"UpdateScheduledRunInput\"]) =>\n t.request<Schemas[\"ScheduledRunDetail\"]>(\"PATCH\", `${base}/${enc(id)}`, { body: input }),\n\n cancel: (id: string) => t.request<void>(\"DELETE\", `${base}/${enc(id)}`, { raw: true }),\n };\n}\n\nexport function backgroundTasksApi(t: Transport, tenantSlug: string) {\n return {\n spawn: (input: Schemas[\"SpawnBackgroundTaskInput\"]) =>\n t.request<Schemas[\"SpawnedBackgroundTask\"]>(\n \"POST\",\n `${tenantPath(tenantSlug)}/background-tasks`,\n { body: input },\n ),\n };\n}\n",
21
+ "import type { Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport { enc, tenantPath } from \"./paths.js\";\n\nexport function usersApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/users`;\n const user = (id: string) => `${base}/${enc(id)}`;\n\n return {\n list: (query: { status?: string; role?: string } = {}, signal?: AbortSignal) =>\n t.request<Schemas[\"UserListItem\"][]>(\"GET\", base, { query, signal }),\n\n get: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"User\"]>(\"GET\", user(id), { signal }),\n\n create: (input: Schemas[\"CreateUserInput\"]) =>\n t.request<Schemas[\"User\"]>(\"POST\", base, { body: input }),\n\n update: (id: string, input: Schemas[\"UpdateUserInput\"]) =>\n t.request<Schemas[\"User\"]>(\"PATCH\", user(id), { body: input }),\n\n delete: (id: string) => t.request<void>(\"DELETE\", user(id), { raw: true }),\n\n // Moderation gates on `users:write`; the legacy `users:approve` value is\n // kept in the enum only so old grant rows still parse.\n approve: (id: string, input: Schemas[\"ApproveUserInput\"]) =>\n t.request<Schemas[\"User\"]>(\"POST\", `${user(id)}/approve`, { body: input }),\n\n block: (id: string) => t.request<Schemas[\"User\"]>(\"POST\", `${user(id)}/block`),\n\n unblock: (id: string) => t.request<Schemas[\"User\"]>(\"POST\", `${user(id)}/unblock`),\n\n merge: (id: string, input: Schemas[\"MergeUserInput\"]) =>\n t.request<Schemas[\"User\"]>(\"POST\", `${user(id)}/merge`, { body: input }),\n\n attachRole: (id: string, roleSlug: string) =>\n t.request<void>(\"PUT\", `${user(id)}/roles/${enc(roleSlug)}`, { raw: true }),\n\n detachRole: (id: string, roleSlug: string) =>\n t.request<void>(\"DELETE\", `${user(id)}/roles/${enc(roleSlug)}`, { raw: true }),\n\n addIdentity: (id: string, input: Schemas[\"CreateIdentityInput\"]) =>\n t.request<Schemas[\"UserIdentity\"]>(\"POST\", `${user(id)}/identities`, { body: input }),\n\n deleteIdentity: (id: string, identityId: string) =>\n t.request<void>(\"DELETE\", `${user(id)}/identities/${enc(identityId)}`, { raw: true }),\n\n listKnowledgeBases: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"KnowledgeBaseListItem\"][]>(\"GET\", `${user(id)}/knowledge-bases`, {\n signal,\n }),\n\n attachKnowledgeBase: (id: string, kbSlug: string) =>\n t.request<void>(\"PUT\", `${user(id)}/knowledge-bases/${enc(kbSlug)}`, { raw: true }),\n\n detachKnowledgeBase: (id: string, kbSlug: string) =>\n t.request<void>(\"DELETE\", `${user(id)}/knowledge-bases/${enc(kbSlug)}`, { raw: true }),\n\n getMemory: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"UserMemory\"]>(\"GET\", `${user(id)}/memory`, { signal }),\n\n listMemoryObservations: (id: string, signal?: AbortSignal) =>\n t.request<Schemas[\"MemoryObservation\"][]>(\"GET\", `${user(id)}/memory/observations`, {\n signal,\n }),\n\n createMemoryObservation: (id: string, input: Schemas[\"CreateMemoryObservationInput\"]) =>\n t.request<Schemas[\"MemoryObservation\"]>(\"POST\", `${user(id)}/memory/observations`, {\n body: input,\n }),\n\n deleteMemoryObservation: (id: string, observationId: string) =>\n t.request<void>(\"DELETE\", `${user(id)}/memory/observations/${enc(observationId)}`, {\n raw: true,\n }),\n\n updateMemoryProfile: (id: string, input: Schemas[\"UpdateMemoryProfileInput\"]) =>\n t.request<Schemas[\"UserMemoryProfile\"]>(\"PATCH\", `${user(id)}/memory/profile`, {\n body: input,\n }),\n };\n}\n\nexport function userRolesApi(t: Transport, tenantSlug: string) {\n const base = `${tenantPath(tenantSlug)}/user-roles`;\n const role = (slug: string) => `${base}/${enc(slug)}`;\n\n return {\n list: (signal?: AbortSignal) => t.request<Schemas[\"UserRole\"][]>(\"GET\", base, { signal }),\n\n get: (slug: string, signal?: AbortSignal) =>\n t.request<Schemas[\"UserRole\"]>(\"GET\", role(slug), { signal }),\n\n create: (input: Schemas[\"CreateUserRoleInput\"]) =>\n t.request<Schemas[\"UserRole\"]>(\"POST\", base, { body: input }),\n\n // No slug rename here: `UpdateUserRoleInput` carries only display_name and\n // description, because pre-defined roles are immutable and their slugs are\n // referenced by grants.\n update: (slug: string, input: Schemas[\"UpdateUserRoleInput\"]) =>\n t.request<Schemas[\"UserRole\"]>(\"PATCH\", role(slug), { body: input }),\n\n delete: (slug: string) => t.request<void>(\"DELETE\", role(slug), { raw: true }),\n };\n}\n\n/**\n * Mints the short-lived tokens a browser SDK runs on (see `createUserClient`).\n * Call this from your own backend only — it needs an api_key, which must never\n * reach a browser.\n */\nexport function userTokensApi(t: Transport, tenantSlug: string) {\n return {\n create: (input: Schemas[\"CreateUserTokenInput\"]) =>\n t.request<Schemas[\"UserToken\"]>(\"POST\", `${tenantPath(tenantSlug)}/user-tokens`, {\n body: input,\n }),\n };\n}\n",
22
+ "import { createTransport, type Transport } from \"../http.js\";\nimport type { Schemas } from \"../schemas.js\";\nimport type { FetchLike } from \"../sse.js\";\nimport { agentsApi } from \"./agents.js\";\nimport { aiProvidersApi } from \"./ai-providers.js\";\nimport { channelsApi } from \"./channels.js\";\nimport { clientToolsApi } from \"./client-tools.js\";\nimport { componentLibrariesApi } from \"./component-libraries.js\";\nimport { conversationsAdminApi } from \"./conversations.js\";\nimport { apiKeysApi, sharedProvidersApi, tenantsApi } from \"./global.js\";\nimport { knowledgeBasesApi } from \"./knowledge-bases.js\";\nimport { mcpsApi } from \"./mcps.js\";\nimport { skillsApi } from \"./skills.js\";\nimport { backgroundTasksApi, scheduledRunsApi, taskTemplatesApi } from \"./task-templates.js\";\nimport { userRolesApi, usersApi, userTokensApi } from \"./users.js\";\n\nexport interface AdminClientOptions {\n /** Where the Cubos Agent core is reachable, e.g. `https://agent.acme.com`. */\n baseUrl: string;\n /** A tenant-wide api_key, or the root key. Pass a function when the key lives\n * somewhere mutable and is read per request. Never ship one to a browser. */\n apiKey: string | (() => string | Promise<string>);\n fetch?: FetchLike;\n /** Per-request ceiling in ms; `0` disables it. Defaults to 30s. */\n timeoutMs?: number;\n /** How many times a 429 is retried, honouring the server's `Retry-After`.\n * Defaults to 2. */\n maxRetries?: number;\n}\n\n/** Everything scoped to one tenant. Held rather than passed per call, so the\n * slug appears once instead of in all ~120 signatures. */\nexport interface TenantScope {\n readonly slug: string;\n agents: ReturnType<typeof agentsApi>;\n aiProviders: ReturnType<typeof aiProvidersApi>;\n mcps: ReturnType<typeof mcpsApi>;\n skills: ReturnType<typeof skillsApi>;\n componentLibraries: ReturnType<typeof componentLibrariesApi>;\n channels: ReturnType<typeof channelsApi>;\n users: ReturnType<typeof usersApi>;\n userRoles: ReturnType<typeof userRolesApi>;\n userTokens: ReturnType<typeof userTokensApi>;\n knowledgeBases: ReturnType<typeof knowledgeBasesApi>;\n taskTemplates: ReturnType<typeof taskTemplatesApi>;\n scheduledRuns: ReturnType<typeof scheduledRunsApi>;\n backgroundTasks: ReturnType<typeof backgroundTasksApi>;\n conversations: ReturnType<typeof conversationsAdminApi>;\n clientTools: ReturnType<typeof clientToolsApi>;\n}\n\nexport interface AdminClient {\n health(signal?: AbortSignal): Promise<Schemas[\"Health\"]>;\n me(signal?: AbortSignal): Promise<Schemas[\"WhoAmI\"]>;\n tenants: ReturnType<typeof tenantsApi>;\n apiKeys: ReturnType<typeof apiKeysApi>;\n sharedProviders: ReturnType<typeof sharedProvidersApi>;\n tenant(slug: string): TenantScope;\n /** Escape hatch for a route the SDK hasn't wrapped yet. Paths are absolute\n * (`/api/v1/…`) and auth is applied for you. */\n raw: Transport;\n}\n\nfunction tenantScope(t: Transport, slug: string): TenantScope {\n return {\n slug,\n agents: agentsApi(t, slug),\n aiProviders: aiProvidersApi(t, slug),\n mcps: mcpsApi(t, slug),\n skills: skillsApi(t, slug),\n componentLibraries: componentLibrariesApi(t, slug),\n channels: channelsApi(t, slug),\n users: usersApi(t, slug),\n userRoles: userRolesApi(t, slug),\n userTokens: userTokensApi(t, slug),\n knowledgeBases: knowledgeBasesApi(t, slug),\n taskTemplates: taskTemplatesApi(t, slug),\n scheduledRuns: scheduledRunsApi(t, slug),\n backgroundTasks: backgroundTasksApi(t, slug),\n conversations: conversationsAdminApi(t, slug),\n clientTools: clientToolsApi(t, slug),\n };\n}\n\n/**\n * Full-surface client authenticated with an api_key: every route the key's\n * grants allow, across every tenant it can reach.\n *\n * Server-side only: an api_key is tenant-wide, so it must never reach a\n * browser.\n */\nexport function createAdminClient(options: AdminClientOptions): AdminClient {\n const t = createTransport(\n options.baseUrl,\n { apiKey: options.apiKey },\n options.fetch,\n options.timeoutMs,\n options.maxRetries,\n );\n const scopes = new Map<string, TenantScope>();\n\n return {\n raw: t,\n health: (signal) => t.request<Schemas[\"Health\"]>(\"GET\", \"/api/v1/health\", { signal }),\n me: (signal) => t.request<Schemas[\"WhoAmI\"]>(\"GET\", \"/api/v1/me\", { signal }),\n tenants: tenantsApi(t),\n apiKeys: apiKeysApi(t),\n sharedProviders: sharedProvidersApi(t),\n tenant(slug: string) {\n let scope = scopes.get(slug);\n if (!scope) {\n scope = tenantScope(t, slug);\n scopes.set(slug, scope);\n }\n return scope;\n },\n };\n}\n",
23
+ "// Opening a conversation the user has opened before should not cost a round\n// trip. It doesn't have to, because of two properties of the server's event log\n// (`crates/cubos_agent/migrations/0010_conversation_harness.sql`):\n//\n// - A row's `id`, `seq`, `type`, `content` and `created_at` are never\n// rewritten. What does change — `tentative`, `discarded_at`, the channel\n// delivery columns — never alters a message that was already visible.\n// - Every UPDATE goes through `bump_conversation_event_change_seq`, so a\n// mutation gets a fresh `change_seq` and reaches clients through the same\n// stream as an insert.\n//\n// So `change_seq` is a validity stamp: hold the messages plus the highest one\n// seen, reconnect with `subscribe({ since })`, and the server replays exactly\n// what changed. Nothing else needs invalidating.\n\nimport type { Message, PlanSnapshot, ToolActivity } from \"./types.js\";\n\n/** Bumped when the cached shape changes; entries written by an older SDK are\n * dropped rather than misread. */\nexport const CACHE_VERSION = 3;\n\nexport interface CachedConversation {\n version: number;\n /** Oldest first, as `listMessagesPage` returns them. */\n messages: Message[];\n /** The tools behind those messages, folded. Absent on entries written before\n * the trail existed, which the version bump already invalidates — typed\n * optional only so a hand-written cache doesn't have to supply it. */\n toolActivity?: ToolActivity[];\n /** Plan revisions, same optionality and the same reason. */\n plans?: PlanSnapshot[];\n /** Newest finished turn, so a reload does not show a turn as running. */\n lastTurnDoneSeq?: number | null;\n /** Highest `change_seq` folded in. Pass to `subscribe` as `since`. */\n latestChangeSeq: number;\n /** Cursor for the page before the oldest message held. */\n oldestSeq: number | null;\n hasOlder: boolean;\n}\n\n/**\n * Where a client keeps conversations it has already loaded.\n *\n * Async on purpose: the in-memory default doesn't need it, but IndexedDB,\n * AsyncStorage and SQLite all do, and a synchronous interface would shut them\n * out. Keys are opaque strings already scoped to tenant and user by the client —\n * an implementation must not reinterpret them.\n *\n * Failures should reject rather than throw synchronously; the client treats any\n * rejection as a cache miss, so a broken store degrades to the network path\n * instead of breaking the app.\n */\nexport interface ConversationCache {\n read(key: string): Promise<CachedConversation | null>;\n write(key: string, entry: CachedConversation): Promise<void>;\n /** Drops one key, or everything when called with no argument. */\n clear(key?: string): Promise<void>;\n}\n\nexport interface MemoryConversationCacheOptions {\n /** How many conversations to retain, least-recently-used evicted first. */\n maxConversations?: number;\n}\n\n/**\n * The default: a bounded LRU in a `Map`, lost on reload.\n *\n * Bounded because the natural failure mode of a chat cache is a user who opens\n * fifty conversations in one session and never reloads.\n */\nexport class MemoryConversationCache implements ConversationCache {\n readonly #entries = new Map<string, CachedConversation>();\n readonly #max: number;\n\n constructor(options: MemoryConversationCacheOptions = {}) {\n this.#max = Math.max(1, options.maxConversations ?? 20);\n }\n\n read(key: string): Promise<CachedConversation | null> {\n const entry = this.#entries.get(key);\n if (entry === undefined) return Promise.resolve(null);\n // Re-insert to mark it most-recently-used: `Map` iterates in insertion\n // order, which is what makes the eviction below an LRU rather than a FIFO.\n this.#entries.delete(key);\n this.#entries.set(key, entry);\n return Promise.resolve(entry);\n }\n\n write(key: string, entry: CachedConversation): Promise<void> {\n this.#entries.delete(key);\n this.#entries.set(key, entry);\n while (this.#entries.size > this.#max) {\n const oldest = this.#entries.keys().next();\n if (oldest.done) break;\n this.#entries.delete(oldest.value);\n }\n return Promise.resolve();\n }\n\n clear(key?: string): Promise<void> {\n if (key === undefined) this.#entries.clear();\n else this.#entries.delete(key);\n return Promise.resolve();\n }\n\n /** Retained conversations. For tests and diagnostics. */\n get size(): number {\n return this.#entries.size;\n }\n}\n\n/**\n * Trims an entry to the newest `limit` messages before it is stored.\n *\n * Dropping the front changes what the caller may still page back to, so the\n * cursors move with it: `oldestSeq` becomes the retained head's `seq` (the\n * server's `before` is exclusive, so that page picks up right behind it) and\n * `hasOlder` becomes true, because there now demonstrably is.\n */\nexport function trimCached(entry: CachedConversation, limit: number): CachedConversation {\n if (entry.messages.length <= limit) return entry;\n const messages = entry.messages.slice(entry.messages.length - limit);\n const head = messages[0];\n const oldestSeq = head ? head.seq : entry.oldestSeq;\n return {\n ...entry,\n messages,\n // Cut at the same seq as the messages, which costs the oldest surviving\n // message its own trail — its steps ran before it and fall below the cut.\n // That is the lesser wrong: a trail is grouped by \"what happened since the\n // previous message\", so keeping the older entries would make that one\n // message claim every step of the conversation that was dropped.\n ...(entry.toolActivity === undefined\n ? {}\n : {\n toolActivity: entry.toolActivity.filter((a) => oldestSeq === null || a.seq >= oldestSeq),\n }),\n ...(entry.plans === undefined\n ? {}\n : { plans: entry.plans.filter((p) => oldestSeq === null || p.seq >= oldestSeq) }),\n oldestSeq,\n hasOlder: true,\n };\n}\n",
24
+ "// Wire shapes → the public vocabulary. Only what this file names is a public\n// contract; everything else the server sends is dropped on purpose, so the\n// event log can grow new types without breaking a published SDK.\n\nimport type {\n Activity,\n Attachment,\n Block,\n ClientToolCall,\n Conversation,\n Message,\n PlanSnapshot,\n Todo,\n ToolActivity,\n} from \"./types.js\";\n\n/** Marks a message that came from a `media_transcription`, for\n * `mergeVoiceMessages` alone. Not exported past this module. */\nconst TRANSCRIPTION = Symbol(\"cubos.transcription\");\n\n/** The `user_message` a transcription belongs to, when the server named it.\n * Null on rows written before it did, which pair by position instead. */\nconst SOURCE_EVENT = Symbol(\"cubos.sourceEvent\");\n\n/** Partial view of the server's `Conversation` DTO. */\nexport interface WireConversation {\n id: string;\n title: string | null;\n generated_title: string | null;\n agent: { slug: string } | null;\n last_activity_at: string;\n archived_at: string | null;\n is_processing: boolean;\n has_pending_turn: boolean;\n created_at: string;\n updated_at: string;\n}\n\n/** Partial view of the server's `ConversationEventAttachment` DTO. Unexported:\n * it is reached only through `WireEvent`, and the public shape is `Attachment`. */\ninterface WireAttachment {\n id: string;\n kind: string;\n mime_type: string;\n bytes: number;\n label: string | null;\n}\n\n/** The server's `TurnStatus`, carried as `conversation_status` frames on the\n * event stream. */\nexport interface WireTurnStatus {\n is_processing: boolean;\n has_pending_turn: boolean;\n}\n\n/** Partial view of the server's `ConversationEvent` DTO. */\nexport interface WireEvent {\n id: string;\n tool_call_id?: string | null;\n tool_name?: string | null;\n seq: number;\n change_seq: number;\n type: string;\n content: string | null;\n tentative: boolean;\n discarded_at: string | null;\n created_at: string;\n /** Absent on older servers and on the many event types that never carry\n * media, so it is read defensively rather than required. */\n attachments?: WireAttachment[];\n /** Absent on every event that isn't an agent message, and on servers older\n * than the feature — hence optional rather than required. */\n blocks?: Block[];\n /** Free-form per event type. Read here for `media_transcription`'s\n * `source_event_id` and as a tool's return value. */\n result?: unknown;\n /** Set on a `tool_result` the tool failed. */\n error?: string | null;\n /** Server-measured wall clock, on the event types that time something. */\n duration_ms?: number | null;\n /** The provider exchange behind an `llm_call`. Read here for one thing only:\n * the arguments of the tool calls it issued. */\n llm_call_data?: WireLlmCallData | null;\n}\n\n/** The sliver of the server's `LlmCallData` this file reads. Deliberately not\n * the whole snapshot: the rest is the prompt, and nothing on this surface\n * should start depending on its shape. */\ninterface WireLlmCallData {\n response?: {\n messages?: Array<{\n type?: string;\n tool_call_id?: string;\n name?: string;\n arguments?: unknown;\n }> | null;\n } | null;\n}\n\nexport function toConversation(w: WireConversation): Conversation {\n return {\n id: w.id,\n // The server keeps the two apart and states the rule: render\n // `title ?? generated_title`. Collapsing them here is what this surface is\n // for — a list has one name to draw — and `titleIsGenerated` keeps the\n // distinction for the one screen that needs it, a rename field that must\n // start empty rather than pre-filled with the engine's guess.\n title: w.title ?? w.generated_title ?? null,\n titleIsGenerated: w.title === null && w.generated_title !== null,\n agentSlug: w.agent?.slug ?? null,\n lastActivityAt: w.last_activity_at,\n archived: w.archived_at !== null,\n isProcessing: w.is_processing,\n hasPendingTurn: w.has_pending_turn,\n createdAt: w.created_at,\n updatedAt: w.updated_at,\n };\n}\n\n/** The turn status, as the event stream reports it — ordered against the log\n * rather than racing it on a second connection, which is why the conversation\n * row's copy of the same pair is not what a client should watch. */\nexport function toTurnStatus(w: WireTurnStatus): Activity {\n return { isProcessing: w.is_processing, hasPendingTurn: w.has_pending_turn };\n}\n\n/**\n * A message, or null for the many event types that aren't one (tool calls, LLM\n * bookkeeping, compaction markers…).\n *\n * `tentative` rows are written by the harness mid-turn and may be rolled back;\n * `discarded_at` marks one that was. Neither belongs in a transcript, and the\n * server re-emits both over SSE precisely so clients can drop them.\n */\nexport function toMessage(w: WireEvent): Message | null {\n if (w.tentative || w.discarded_at !== null) return null;\n\n // A voice message is two events: the `user_message` carrying the clip, and the\n // `media_transcription` the harness writes once STT has run. Both become\n // messages here and `mergeVoiceMessages` folds them into one — doing it in two\n // steps keeps this function per-event, which is what the SSE stream delivers.\n if (w.type === \"media_transcription\" && w.content !== null) {\n const message: Message = {\n id: w.id,\n role: \"user\",\n content: w.content,\n attachments: [],\n seq: w.seq,\n at: w.created_at,\n };\n // Symbols, so the flags survive object spreads but show up in neither the\n // public type nor JSON.stringify. Without them `mergeVoiceMessages` cannot\n // tell a transcription from a message the user typed right after recording,\n // and would swallow the typed one.\n const hidden = message as unknown as Record<symbol, unknown>;\n hidden[TRANSCRIPTION] = true;\n hidden[SOURCE_EVENT] = sourceEventId(w.result);\n return message;\n }\n\n const role = w.type === \"user_message\" ? \"user\" : w.type === \"agent_message\" ? \"agent\" : null;\n if (role === null || w.content === null) return null;\n const attachments = toAttachments(w);\n // An empty `user_message` with no media is a voice note whose clip the server\n // didn't report: nothing to draw, and its words arrive as the transcription\n // above. With media it is either the carrier of a clip or an uncaptioned\n // image, and both are the message.\n if (role === \"user\" && w.content === \"\" && attachments.length === 0) return null;\n return {\n id: w.id,\n role,\n content: w.content,\n attachments,\n seq: w.seq,\n at: w.created_at,\n ...(w.blocks === undefined ? {} : { blocks: w.blocks }),\n };\n}\n\n/** Only the two kinds this surface names: an unknown kind from a newer server\n * is dropped rather than widened into the public union. */\nfunction toAttachments(w: WireEvent): Attachment[] {\n const out: Attachment[] = [];\n for (const a of w.attachments ?? []) {\n if (a.kind !== \"image\" && a.kind !== \"audio\") continue;\n out.push({\n id: a.id,\n kind: a.kind,\n mimeType: a.mime_type,\n bytes: a.bytes,\n label: a.label,\n });\n }\n return out;\n}\n\n/** True for the carrier event of a voice note: the clip is there, the words are\n * not yet. */\nfunction hasAudio(message: Message): boolean {\n return message.attachments.some((a) => a.kind === \"audio\");\n}\n\n/** The `user_message` the server says this transcription describes, or null on\n * a row from before it recorded one. */\nfunction sourceEventId(result: unknown): string | null {\n const id = (result as { source_event_id?: unknown } | null | undefined)?.source_event_id;\n return typeof id === \"string\" ? id : null;\n}\n\n/**\n * Folds each transcription into the media it belongs to, so a voice message is\n * one bubble with a player and its text rather than two.\n *\n * The harness names the source event, and that is what pairs them. A\n * transcription of an *image* is the fallback vision model's description, not\n * the user's words — the picture is already on screen, so it is dropped rather\n * than shown as something the user said.\n *\n * Rows written before the server recorded a source pair oldest-first instead,\n * the same FIFO rule the harness used then: a user routinely types something\n * between the recording and its transcription, so \"the message directly before\"\n * is not a safe match.\n *\n * Expects `messages` ordered by `seq`.\n */\nexport function mergeVoiceMessages(messages: Message[]): Message[] {\n const out: Message[] = [];\n const awaitingText: Message[] = [];\n const byId = new Map<string, Message>();\n\n for (const message of messages) {\n const hidden = message as unknown as Record<symbol, unknown>;\n if (hidden[TRANSCRIPTION] !== true) {\n const copy = { ...message };\n byId.set(copy.id, copy);\n // Only a clip still waiting: `mergeMessages` in `@cubos/agent-sdk-react`\n // re-runs this over the whole list on every arrival, and by then the\n // transcription has already been folded in and dropped. Resetting the\n // flag there would un-answer every clip on the next re-render.\n if (hasAudio(copy) && copy.transcribed !== true) {\n copy.transcribed = false;\n awaitingText.push(copy);\n }\n out.push(copy);\n continue;\n }\n\n const sourceId = hidden[SOURCE_EVENT];\n const source = typeof sourceId === \"string\" ? byId.get(sourceId) : undefined;\n if (source) {\n // Only a clip takes the text: an image already shows itself, and its\n // description is the model talking to itself.\n if (hasAudio(source)) {\n source.content = message.content;\n source.transcribed = true;\n }\n continue;\n }\n // The source is either unnamed (a legacy row) or has not arrived yet — the\n // stream can deliver a transcription before the page holding its carrier.\n const clip = awaitingText.shift();\n if (clip) {\n clip.content = message.content;\n clip.transcribed = true;\n continue;\n }\n out.push(message);\n }\n\n return out;\n}\n\n// The server's four states collapse to three: `cancelled` and `done` both mean\n// \"the agent is finished with this item\", and a chat UI has nowhere useful to\n// draw the distinction.\nconst TODO_STATUS: Record<string, Todo[\"status\"]> = {\n pending: \"pending\",\n in_progress: \"in_progress\",\n done: \"completed\",\n cancelled: \"completed\",\n};\n\n/**\n * The agent's whole current plan, or null when this event isn't one.\n *\n * `todo_update` carries a JSON-encoded `TodoUpdatePayload` in `content` (not in\n * `result` — it's a pseudo-tool, so it writes its own side-effect event), and\n * each call overwrites the entire list rather than patching it.\n */\nexport function toTodos(w: WireEvent): Todo[] | null {\n if (w.type !== \"todo_update\" || w.tentative || w.discarded_at !== null) return null;\n if (w.content === null) return null;\n let payload: unknown;\n try {\n payload = JSON.parse(w.content);\n } catch {\n return null;\n }\n const raw = (payload as { items?: unknown } | null)?.items;\n if (!Array.isArray(raw)) return null;\n const todos: Todo[] = [];\n for (const item of raw) {\n if (typeof item !== \"object\" || item === null) continue;\n const { text, status } = item as { text?: unknown; status?: unknown };\n if (typeof text !== \"string\") continue;\n todos.push({\n title: text,\n status: (typeof status === \"string\" ? TODO_STATUS[status] : undefined) ?? \"pending\",\n });\n }\n return todos;\n}\n\n/**\n * The plan revision this event carries, tagged with where it sits in the log.\n *\n * Same content as `toTodos`, plus the `seq` a reader needs to say *which*\n * answer a plan belongs to — without it, a client holding several turns of\n * history can only ever show the newest plan against all of them.\n */\nexport function toPlanSnapshot(w: WireEvent): PlanSnapshot | null {\n const todos = toTodos(w);\n return todos === null ? null : { todos, seq: w.seq };\n}\n\n/**\n * The `seq` of a turn that has finished, or null for every other event.\n *\n * The honest end of a turn, and not the same thing as `isProcessing` going\n * false: a client tool *suspends* the turn while the app answers, and the\n * conversation stops being \"processing\" for as long as that takes. A UI keyed\n * on activity alone therefore stops its own spinner in the middle of the work\n * and starts it again a second later — which is the flicker this exists to\n * prevent.\n */\nexport function toTurnDone(w: WireEvent): number | null {\n if (w.type !== \"turn_done\" || w.tentative || w.discarded_at !== null) return null;\n return w.seq;\n}\n\n/** The agent called a client tool, which suspends its turn until someone\n * answers. Null for every other event. */\nexport function toClientToolCall(w: WireEvent): ClientToolCall | null {\n if (w.type !== \"client_tool_call\" || w.tentative || w.discarded_at !== null) return null;\n if (!w.tool_call_id || !w.tool_name) return null;\n return { toolCallId: w.tool_call_id, toolName: w.tool_name };\n}\n\n/**\n * The agent reaching for a tool, or the outcome of one. Null for every other\n * event.\n *\n * Unlike a message, a `tentative` row is exactly what this wants. A\n * `tool_result` is written tentative and only promoted when the turn\n * consolidates, so dropping those would hide the trail until the turn was over\n * — the opposite of showing what the agent is doing right now. `discarded_at`\n * still disqualifies: that turn was rolled back, so its steps never happened.\n */\nexport function toToolActivity(w: WireEvent): ToolActivity | null {\n if (w.discarded_at !== null) return null;\n if (!w.tool_call_id || !w.tool_name) return null;\n\n if (w.type === \"client_tool_call\") {\n const args = toArguments(w.content);\n return {\n toolCallId: w.tool_call_id,\n toolName: w.tool_name,\n ...(args === undefined ? {} : { arguments: args }),\n status: \"running\",\n seq: w.seq,\n at: w.created_at,\n };\n }\n\n if (w.type === \"tool_result\") {\n const failed = typeof w.error === \"string\" && w.error !== \"\";\n return {\n toolCallId: w.tool_call_id,\n toolName: w.tool_name,\n status: failed ? \"error\" : \"ok\",\n ...(w.result === undefined || w.result === null ? {} : { result: w.result }),\n ...(failed ? { error: w.error as string } : {}),\n ...(typeof w.duration_ms === \"number\" ? { durationMs: w.duration_ms } : {}),\n seq: w.seq,\n at: w.created_at,\n };\n }\n\n return null;\n}\n\n/** The call event serialises its arguments into `content`. Anything that isn't\n * a JSON object is treated as absent rather than widened into the public type —\n * a tool called with a bare string has nothing a trail could label. */\nfunction toArguments(content: string | null): Record<string, unknown> | undefined {\n if (content === null || content === \"\") return undefined;\n try {\n const parsed: unknown = JSON.parse(content);\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return undefined;\n return parsed as Record<string, unknown>;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The arguments the model passed, read off the `llm_call` that issued the\n * calls — the only event that carries them for a server-side tool, since a\n * `tool_result` records the outcome and never the input.\n *\n * Deliberately **not** an activity. A pseudo-tool (`send_message`,\n * `yield_turn`, `update_todo`) writes its own side-effect event instead of a\n * `tool_result`, so minting an entry from every call here would leave three\n * steps per turn stuck at `running` forever. These only ever fill in the\n * arguments of an entry that already exists.\n */\nexport function toToolCallArguments(w: WireEvent): ToolCallArguments[] {\n if (w.type !== \"llm_call\" || w.discarded_at !== null) return [];\n const messages = w.llm_call_data?.response?.messages;\n if (!Array.isArray(messages)) return [];\n const out: ToolCallArguments[] = [];\n for (const m of messages) {\n if (m.type !== \"tool_call\" || typeof m.tool_call_id !== \"string\") continue;\n const args = m.arguments;\n if (typeof args !== \"object\" || args === null || Array.isArray(args)) continue;\n out.push({ toolCallId: m.tool_call_id, arguments: args as Record<string, unknown> });\n }\n return out;\n}\n\nexport interface ToolCallArguments {\n toolCallId: string;\n arguments: Record<string, unknown>;\n}\n\n/** Fills in what an activity could not know about itself. Never overwrites: a\n * client tool reports its own arguments, and those are what it was actually\n * dispatched with. */\nexport function withToolArguments(\n activity: ToolActivity,\n known: Map<string, Record<string, unknown>>,\n): ToolActivity {\n if (activity.arguments !== undefined) return activity;\n const args = known.get(activity.toolCallId);\n return args === undefined ? activity : { ...activity, arguments: args };\n}\n\n/** Folds each call together with its result, so one tool is one entry.\n *\n * Expects activities in any order and returns them by `seq`. */\nexport function mergeToolActivities(activities: ToolActivity[]): ToolActivity[] {\n const byId = new Map<string, ToolActivity>();\n for (const incoming of activities) {\n const held = byId.get(incoming.toolCallId);\n byId.set(incoming.toolCallId, held === undefined ? incoming : fold(held, incoming));\n }\n return [...byId.values()].sort((a, b) => a.seq - b.seq);\n}\n\n/** The call carries the arguments and the earlier `seq`; the result carries the\n * outcome. Either can arrive first — a reconnect replays the log in order, but\n * a live stream can deliver the result of a call whose own frame was missed —\n * so neither is allowed to erase what the other knew. */\nfunction fold(a: ToolActivity, b: ToolActivity): ToolActivity {\n const withArgs = a.arguments !== undefined ? a : b;\n const outcome = a.status !== \"running\" ? a : b.status !== \"running\" ? b : null;\n const earliest = a.seq <= b.seq ? a : b;\n return {\n toolCallId: a.toolCallId,\n toolName: a.toolName,\n ...(withArgs.arguments === undefined ? {} : { arguments: withArgs.arguments }),\n status: outcome?.status ?? \"running\",\n ...(outcome?.result === undefined ? {} : { result: outcome.result }),\n ...(outcome?.error === undefined ? {} : { error: outcome.error }),\n ...(outcome?.durationMs === undefined ? {} : { durationMs: outcome.durationMs }),\n seq: earliest.seq,\n at: earliest.at,\n };\n}\n",
25
+ "import {\n CACHE_VERSION,\n type ConversationCache,\n MemoryConversationCache,\n trimCached,\n} from \"./cache.js\";\nimport {\n type ClientTool,\n type ClientToolsSession,\n declarations,\n type ServeClientToolsOptions,\n serveClientTools,\n} from \"./client-tools.js\";\nimport { AgentApiError, raiseForStatus } from \"./errors.js\";\nimport { createTransport, type TokenSource, type Transport } from \"./http.js\";\nimport {\n mergeToolActivities,\n mergeVoiceMessages,\n toClientToolCall,\n toConversation,\n toMessage,\n toPlanSnapshot,\n toTodos,\n toToolActivity,\n toToolCallArguments,\n toTurnDone,\n toTurnStatus,\n type WireConversation,\n type WireEvent,\n type WireTurnStatus,\n withToolArguments,\n} from \"./mapping.js\";\nimport { type FetchLike, readSse } from \"./sse.js\";\nimport type {\n Activity,\n ClientToolCall,\n Conversation,\n ConversationEvent,\n CreateConversationOptions,\n EnabledComponents,\n EventPage,\n Identity,\n ListConversationsOptions,\n Message,\n MessagePage,\n Page,\n PlanSnapshot,\n Todo,\n ToolActivity,\n WorkspaceDir,\n WorkspaceEntry,\n} from \"./types.js\";\n\ninterface CommonClientOptions {\n /** Where the Cubos Agent core is reachable, e.g. `https://agent.acme.com`.\n * Pass `\"\"` for a same-origin deployment. */\n baseUrl: string;\n /** Tenant slug. Resolved from the token via `/me` when omitted, at the cost\n * of one request the first time it's needed. */\n tenant?: string;\n /** Override for runtimes whose global `fetch` needs wrapping (proxies,\n * instrumentation, Node < 18 polyfills). */\n fetch?: FetchLike;\n /** Per-request ceiling in ms; `0` disables it. Streams are exempt — they are\n * meant to stay open. Defaults to 30s. */\n timeoutMs?: number;\n /** How many times a 429 is retried, honouring the server's `Retry-After`.\n * `0` surfaces the rate limit to you instead. Defaults to 2. */\n maxRetries?: number;\n /**\n * Where already-loaded conversations are kept so reopening one is instant.\n * Defaults to a bounded in-memory LRU; pass `null` to switch it off, or your\n * own `ConversationCache` to survive a reload.\n */\n cache?: ConversationCache | null;\n /** Messages retained per conversation. Older ones are dropped from the cache\n * (not from the server) and come back through `loadOlder`. Defaults to 300. */\n cacheMessageLimit?: number;\n}\n\n/**\n * A short-lived token, either handed over once or fetched on demand.\n *\n * `getToken` is what a real app wants: tokens expire, and the SDK calls it\n * again with `forceRefresh` after a 401. `token` exists because a script or a\n * test that already holds one shouldn't have to write a closure for it — but a\n * static token cannot be renewed, so it eventually 401s for good.\n */\nexport type UserCredential = { getToken: TokenSource } | { token: string };\n\n/** Mirrors the server's `MAX_IMAGES_PER_MESSAGE`, which bounds both the\n * multipart body and what one turn injects into the context window. */\nconst MAX_IMAGES_PER_MESSAGE = 10;\n\nexport type ClientOptions = CommonClientOptions & UserCredential;\n\nexport interface ConversationSubscription {\n /** Stops the streams and releases the connections. Idempotent. */\n close(): void;\n}\n\nexport interface ConversationHandlers {\n /** Fires for the backlog on connect and for each new message after. */\n onMessage?: (message: Message) => void;\n /**\n * Every event, exactly as the server sent it, in stream order — before the\n * handlers above see what it projected into.\n *\n * The curated handlers are a projection over this same frame, not a wall in\n * front of it: taking `onEvent` costs no second connection, no second cursor\n * and no second catch-up, and an app may take both. Reach for it when your UI\n * shows the log itself rather than a conversation.\n */\n onEvent?: (event: ConversationEvent) => void;\n /** The event stream is live — on first connect and after every reconnect.\n * Whatever catches up on gaps belongs here, not before `subscribe`. */\n onOpen?: () => void;\n /** The agent called a client tool. Its turn is suspended until someone\n * answers the call; see `serveClientTools`. */\n onClientToolCall?: (call: ClientToolCall) => void;\n /** The agent reached for a tool, or that call finished. Fires twice per client\n * tool — once running, once resolved — and once for a server-side tool, which\n * only reports its result. Fold them with `mergeToolActivities`. */\n onToolActivity?: (activity: ToolActivity) => void;\n onActivity?: (activity: Activity) => void;\n /** A turn finished. The one signal that means the agent is done — unlike\n * `onActivity`, which goes quiet mid-turn while a client tool is answered. */\n onTurnDone?: (seq: number) => void;\n /** The plan, with the `seq` that says which answer it belongs to. */\n onTodos?: (todos: Todo[], seq: number) => void;\n onConversation?: (conversation: Conversation) => void;\n /** Every frame's `change_seq`, in the order delivered. Feed the last one back\n * as `since` on the next connect — that is what lets a cache pick up where it\n * left off instead of replaying. */\n onCursor?: (changeSeq: number) => void;\n /** Transient stream failures. The SDK is already reconnecting; this is for\n * logging or a \"reconnecting…\" hint, not for recovery. */\n onError?: (err: unknown) => void;\n}\n\n/** What `loadHistory` resolves to: a `MessagePage` plus where it came from. */\nexport interface HistoryStart {\n messages: Message[];\n /** The tools behind those messages, folded and ordered by `seq`. */\n toolActivity: ToolActivity[];\n /** Every plan revision behind them, ordered by `seq`. */\n plans: PlanSnapshot[];\n /** Newest finished turn, or null. */\n lastTurnDoneSeq: number | null;\n oldestSeq: number | null;\n /** Pass to `subscribe` as `since`. Null only for a conversation with no\n * events at all. */\n latestChangeSeq: number | null;\n hasOlder: boolean;\n /** True when nothing was fetched. The stream still reconciles it. */\n fromCache: boolean;\n}\n\nexport interface ListHandlers {\n onConversation: (conversation: Conversation) => void;\n onError?: (err: unknown) => void;\n}\n\nexport class AgentClient {\n readonly #transport: Transport;\n readonly #cache: ConversationCache | null;\n readonly #cacheLimit: number;\n #tenant: string | undefined;\n #identity: Promise<Identity> | null = null;\n\n constructor(options: ClientOptions) {\n const getToken: TokenSource = \"getToken\" in options ? options.getToken : () => options.token;\n this.#transport = createTransport(\n options.baseUrl,\n { getToken },\n options.fetch,\n options.timeoutMs,\n options.maxRetries,\n );\n this.#tenant = options.tenant;\n this.#cache = options.cache === undefined ? new MemoryConversationCache() : options.cache;\n this.#cacheLimit = Math.max(1, options.cacheMessageLimit ?? 300);\n }\n\n /** Who the current token acts as. Cached — call `refreshIdentity` after\n * swapping to a token for a different user. */\n me(): Promise<Identity> {\n this.#identity ??= this.#fetchIdentity();\n return this.#identity;\n }\n\n refreshIdentity(): Promise<Identity> {\n this.#identity = this.#fetchIdentity();\n return this.#identity;\n }\n\n async #fetchIdentity(): Promise<Identity> {\n const raw = await this.#transport.request<{\n display_name: string;\n user_id: string | null;\n agent_slugs: string[];\n tenants: { slug: string }[];\n }>(\"GET\", \"/api/v1/me\");\n\n if (raw.user_id === null) {\n throw new AgentApiError(\n \"This token is an api_key, not an end-user token. Mint one with POST /api/v1/tenants/{slug}/user-tokens and keep the api_key on your server.\",\n 403,\n );\n }\n const tenantSlug = this.#tenant ?? raw.tenants[0]?.slug;\n if (!tenantSlug) {\n throw new AgentApiError(\"Token resolves to no tenant.\", 403);\n }\n this.#tenant = tenantSlug;\n return {\n userId: raw.user_id,\n displayName: raw.display_name,\n tenantSlug,\n agentSlugs: raw.agent_slugs,\n };\n }\n\n async #base(): Promise<string> {\n if (this.#tenant === undefined) await this.me();\n return `/api/v1/tenants/${encodeURIComponent(this.#tenant as string)}/conversations`;\n }\n\n async listConversations(opts: ListConversationsOptions = {}): Promise<Page<Conversation>> {\n const query = { origin: \"interactive\", limit: opts.limit, before: opts.before };\n\n const rows = await this.#transport.request<WireConversation[]>(\"GET\", `${await this.#base()}`, {\n query,\n signal: opts.signal,\n });\n const items = rows.map(toConversation);\n // The list is ordered newest-first, so the cursor for the next (older) page\n // is built from the last row. A short page means there is nothing older.\n const last = rows.at(-1);\n const exhausted = opts.limit !== undefined && rows.length < opts.limit;\n return {\n items,\n nextCursor: last && !exhausted ? `${last.last_activity_at}|${last.id}` : null,\n };\n }\n\n /**\n * Every conversation, newest activity first, fetching pages as you go.\n *\n * `listConversations` hands back a cursor to thread through yourself; this is\n * the same thing when you just want them all:\n *\n * ```ts\n * for await (const conversation of client.iterateConversations()) { … }\n * ```\n *\n * Stops on `break` without fetching the next page.\n */\n async *iterateConversations(\n opts: { pageSize?: number; signal?: AbortSignal } = {},\n ): AsyncGenerator<Conversation> {\n const limit = opts.pageSize ?? 50;\n let before: string | undefined;\n for (;;) {\n const page = await this.listConversations({ limit, before, signal: opts.signal });\n for (const conversation of page.items) yield conversation;\n if (page.nextCursor === null) return;\n before = page.nextCursor;\n }\n }\n\n /**\n * The conversation's history, newest first, paging backwards as you go — so\n * taking the first N gives you the N most recent messages.\n *\n * A voice message's clip and its transcription are paired within a page; if\n * the two land on either side of a page edge, the clip surfaces with empty\n * text. Raise `pageSize` if that matters for your history depth.\n */\n async *iterateMessages(\n id: string,\n opts: { pageSize?: number; signal?: AbortSignal } = {},\n ): AsyncGenerator<Message> {\n const limit = opts.pageSize ?? 50;\n let before: number | undefined;\n for (;;) {\n const page = await this.#messagePage(id, { limit, before, signal: opts.signal });\n for (let i = page.messages.length - 1; i >= 0; i--) yield page.messages[i] as Message;\n // Keyed on events, not messages: a page of nothing but tool calls still\n // has older history behind it, and stopping there would swallow it.\n if (page.eventCount < limit || page.oldestSeq === null) return;\n before = page.oldestSeq;\n }\n }\n\n async createConversation(opts: CreateConversationOptions = {}): Promise<Conversation> {\n // The server refuses an agent-less conversation from a user token, so fall\n // back to the token's single agent rather than sending a request we know\n // will 400.\n let agentSlug = opts.agentSlug;\n if (agentSlug === undefined) {\n const { agentSlugs } = await this.me();\n if (agentSlugs.length !== 1) {\n throw new AgentApiError(\n agentSlugs.length === 0\n ? \"This token was minted without any agent, so it can't start a conversation.\"\n : `This token covers ${agentSlugs.length} agents — pass agentSlug to pick one.`,\n 400,\n );\n }\n agentSlug = agentSlugs[0];\n }\n\n const row = await this.#transport.request<WireConversation>(\"POST\", await this.#base(), {\n body: {\n agent_slug: agentSlug,\n title: opts.title,\n metadata: opts.metadata,\n ...(opts.componentLibraries === undefined\n ? {}\n : { component_libraries: opts.componentLibraries }),\n },\n signal: opts.signal,\n });\n return toConversation(row);\n }\n\n /**\n * Enable component libraries on `id` — the catalogs of interactive blocks the\n * agent may put in a reply. Replaces the whole list, so send it complete; an\n * empty list takes the agent back to plain markdown.\n *\n * The libraries themselves are authored by the operator, not here: their\n * entries are shown to the model verbatim, and writing prompt content needs an\n * api_key this client will never hold. What you choose is which of them apply\n * to the screen you have open.\n *\n * Returns the slugs together with **every tag they resolve to**. Check that\n * against the components you can actually draw — the agent placing a tag your\n * app has no renderer for is a silent hole in a reply, and this is the only\n * moment both halves are in one place.\n *\n * Takes effect on the agent's next turn — a turn already running keeps the\n * catalog it started with, so what the agent was told it could use and what it\n * is held to are always the same list.\n */\n async setComponentLibraries(\n id: string,\n libraries: string[],\n signal?: AbortSignal,\n ): Promise<EnabledComponents> {\n return await this.#transport.request<EnabledComponents>(\n \"PUT\",\n `${await this.#base()}/${id}/component-libraries`,\n { body: { libraries }, signal },\n );\n }\n\n /**\n * Tell the agent what your app currently has on screen — the open page, the\n * selected record, the filters in force. Free-form: prose or JSON, whatever\n * the agent reads best.\n *\n * Cheap and safe to call as often as the screen moves, **including while a\n * turn is running**: it writes no event and starts no turn. The server copies\n * it into the conversation the next time a turn reads it, and only when it\n * differs from what the model was last shown — so repeating an unchanged\n * context costs nothing at all.\n *\n * That is the difference from putting the context in the message text, which\n * is what apps do without this: there it is spent on every message, it shows\n * up in the transcript unless every render path strips it, and only the app\n * that owns the composer can send it.\n *\n * `null` stops reporting. What the model was already shown stays in the log —\n * it is the record of the screen an earlier question was asked against.\n */\n async setContext(id: string, context: string | null, signal?: AbortSignal): Promise<void> {\n await this.#transport.request<unknown>(\"PUT\", `${await this.#base()}/${id}/context`, {\n body: { context },\n signal,\n });\n }\n\n async listComponentLibraries(id: string, signal?: AbortSignal): Promise<EnabledComponents> {\n return await this.#transport.request<EnabledComponents>(\n \"GET\",\n `${await this.#base()}/${id}/component-libraries`,\n { signal },\n );\n }\n\n async getConversation(id: string, signal?: AbortSignal): Promise<Conversation> {\n const row = await this.#transport.request<WireConversation>(\n \"GET\",\n `${await this.#base()}/${id}`,\n { signal },\n );\n return toConversation(row);\n }\n\n async renameConversation(id: string, title: string, signal?: AbortSignal): Promise<Conversation> {\n const row = await this.#transport.request<WireConversation>(\n \"PATCH\",\n `${await this.#base()}/${id}`,\n { body: { title }, signal },\n );\n return toConversation(row);\n }\n\n async archiveConversation(id: string, signal?: AbortSignal): Promise<Conversation> {\n const row = await this.#transport.request<WireConversation>(\n \"POST\",\n `${await this.#base()}/${id}/archive`,\n { signal },\n );\n return toConversation(row);\n }\n\n /**\n * One page of history, oldest-first within the page. Omit `before` for the\n * newest page, then pass `oldestSeq` to walk backwards.\n *\n * `limit` counts **events**, not messages: the log also holds the agent's tool\n * calls and bookkeeping, so a page can legitimately contain no messages at\n * all. That is why the cursor is `oldestSeq` rather than the first message's\n * `seq` — paging by the latter would skip everything in between.\n */\n async #messagePage(\n id: string,\n opts: { before?: number; limit?: number; signal?: AbortSignal },\n ): Promise<{\n messages: Message[];\n toolActivity: ToolActivity[];\n plans: PlanSnapshot[];\n lastTurnDoneSeq: number | null;\n oldestSeq: number | null;\n latestChangeSeq: number | null;\n eventCount: number;\n events: ConversationEvent[];\n }> {\n const rows = await this.#transport.request<WireEvent[]>(\n \"GET\",\n `${await this.#base()}/${id}/events`,\n { query: { before: opts.before, limit: opts.limit }, signal: opts.signal },\n );\n const messages = mergeVoiceMessages(\n rows.map(toMessage).filter((m): m is Message => m !== null),\n );\n // The arguments of a server-side tool live on the `llm_call` that issued\n // it, so they are collected across the whole page before the activities are\n // folded — the call and its result are different rows.\n const argsByCall = new Map<string, Record<string, unknown>>();\n for (const row of rows) {\n for (const call of toToolCallArguments(row)) argsByCall.set(call.toolCallId, call.arguments);\n }\n const toolActivity = mergeToolActivities(\n rows.map(toToolActivity).filter((a): a is ToolActivity => a !== null),\n ).map((a) => withToolArguments(a, argsByCall));\n const plans = rows.map(toPlanSnapshot).filter((p): p is PlanSnapshot => p !== null);\n const turnDones = rows.map(toTurnDone).filter((n): n is number => n !== null);\n const lastTurnDoneSeq = turnDones.length === 0 ? null : Math.max(...turnDones);\n let oldestSeq: number | null = null;\n let latestChangeSeq: number | null = null;\n for (const row of rows) {\n if (oldestSeq === null || row.seq < oldestSeq) oldestSeq = row.seq;\n if (latestChangeSeq === null || row.change_seq > latestChangeSeq) {\n latestChangeSeq = row.change_seq;\n }\n }\n return {\n messages,\n toolActivity,\n plans,\n lastTurnDoneSeq,\n oldestSeq,\n latestChangeSeq,\n eventCount: rows.length,\n // The rows themselves, not only what they projected into. The curated\n // view is a projection over this list, never a wall in front of it — see\n // `listEventsPage`.\n events: rows as ConversationEvent[],\n };\n }\n\n /** One page of history, oldest-first. `limit` counts events, so a page may\n * hold fewer messages than you asked for — `iterateMessages` handles that. */\n async listMessages(\n id: string,\n opts: { before?: number; limit?: number; signal?: AbortSignal } = {},\n ): Promise<Message[]> {\n return (await this.#messagePage(id, opts)).messages;\n }\n\n /**\n * The state to open a conversation with: cached if it has been opened before,\n * fetched otherwise.\n *\n * A hit costs no request. It is not stale either — the caller is expected to\n * `subscribe` with the returned `latestChangeSeq`, and the server replays\n * every insert and every mutation past it, so anything that happened while\n * the app was closed arrives as a delta.\n *\n * A cache that throws is treated as a miss: a corrupt store degrades to the\n * network instead of breaking the conversation.\n */\n async loadHistory(\n id: string,\n opts: { pageSize?: number; signal?: AbortSignal } = {},\n ): Promise<HistoryStart> {\n const key = await this.#cacheKey(id);\n if (key !== null && this.#cache) {\n try {\n const entry = await this.#cache.read(key);\n if (entry && entry.version === CACHE_VERSION && entry.messages.length > 0) {\n return {\n messages: entry.messages,\n toolActivity: entry.toolActivity ?? [],\n plans: entry.plans ?? [],\n lastTurnDoneSeq: entry.lastTurnDoneSeq ?? null,\n oldestSeq: entry.oldestSeq,\n latestChangeSeq: entry.latestChangeSeq,\n hasOlder: entry.hasOlder,\n fromCache: true,\n };\n }\n } catch {\n // Miss.\n }\n }\n\n const page = await this.listMessagesPage(id, {\n limit: opts.pageSize,\n signal: opts.signal,\n });\n await this.saveHistory(id, page);\n return { ...page, fromCache: false };\n }\n\n /**\n * Records the conversation's current state for the next `loadHistory`.\n *\n * `latestChangeSeq` must be the highest cursor folded into `messages` — the\n * page's, or the last one `subscribe`'s `onCursor` reported. Passing a higher\n * one would make the next connect skip the events in between; passing a lower\n * one only costs a replay.\n *\n * Silently does nothing without a cache, so callers need no branch.\n */\n async saveHistory(\n id: string,\n state: {\n messages: Message[];\n toolActivity?: ToolActivity[];\n plans?: PlanSnapshot[];\n lastTurnDoneSeq?: number | null;\n oldestSeq: number | null;\n latestChangeSeq: number | null;\n hasOlder: boolean;\n },\n ): Promise<void> {\n if (!this.#cache || state.latestChangeSeq === null || state.messages.length === 0) return;\n const key = await this.#cacheKey(id);\n if (key === null) return;\n const entry = trimCached(\n {\n version: CACHE_VERSION,\n messages: state.messages,\n ...(state.toolActivity === undefined ? {} : { toolActivity: state.toolActivity }),\n ...(state.plans === undefined ? {} : { plans: state.plans }),\n ...(state.lastTurnDoneSeq === undefined ? {} : { lastTurnDoneSeq: state.lastTurnDoneSeq }),\n latestChangeSeq: state.latestChangeSeq,\n oldestSeq: state.oldestSeq,\n hasOlder: state.hasOlder,\n },\n this.#cacheLimit,\n );\n try {\n await this.#cache.write(key, entry);\n } catch {\n // A cache that cannot be written to is not an error the caller can act on.\n }\n }\n\n /** Forgets one conversation, or every one of this user's. */\n async forgetHistory(id?: string): Promise<void> {\n if (!this.#cache) return;\n if (id === undefined) {\n await this.#cache.clear();\n return;\n }\n const key = await this.#cacheKey(id);\n if (key !== null) await this.#cache.clear(key);\n }\n\n /**\n * Scoped to tenant and user, never the conversation id alone: a persistent\n * store is shared by every session in the browser, and two users on one device\n * must not read each other's messages out of it.\n *\n * Null when identity can't be resolved — no key, no caching, rather than a\n * key that could collide.\n */\n async #cacheKey(id: string): Promise<string | null> {\n if (!this.#cache) return null;\n try {\n const identity = await this.me();\n return `${identity.tenantSlug}\\u0000${identity.userId}\\u0000${id}`;\n } catch {\n return null;\n }\n }\n\n /**\n * `listMessages` plus the cursors a paging UI needs: `oldestSeq` to ask for\n * the page before this one, and `latestChangeSeq` to start a subscription\n * from here instead of replaying everything.\n *\n * `hasOlder` is false only when the server returned fewer events than asked\n * for — the one honest signal that the log is exhausted, since a page can\n * hold events that are not messages.\n */\n /**\n * One page of the conversation's **event log**, oldest-first — the same rows\n * `listMessagesPage` projects into messages, handed over as they came.\n *\n * Reach for this when the curated view is too small a window: an operator\n * console showing tool calls, an audit trail, anything that has to see the\n * event types the chat surface deliberately drops. `ConversationEvent` tracks\n * the server rather than promising stability across refactors — that is the\n * trade, and it is the same one the REST API already offers.\n */\n async listEventsPage(\n id: string,\n opts: { before?: number; limit?: number; signal?: AbortSignal } = {},\n ): Promise<EventPage> {\n const limit = opts.limit ?? 50;\n const page = await this.#messagePage(id, { ...opts, limit });\n return {\n events: page.events,\n oldestSeq: page.oldestSeq,\n latestChangeSeq: page.latestChangeSeq,\n hasOlder: page.eventCount === limit,\n };\n }\n\n async listMessagesPage(\n id: string,\n opts: { before?: number; limit?: number; signal?: AbortSignal } = {},\n ): Promise<MessagePage> {\n const limit = opts.limit ?? 50;\n const page = await this.#messagePage(id, { ...opts, limit });\n return {\n messages: page.messages,\n toolActivity: page.toolActivity,\n plans: page.plans,\n lastTurnDoneSeq: page.lastTurnDoneSeq,\n oldestSeq: page.oldestSeq,\n latestChangeSeq: page.latestChangeSeq,\n hasOlder: page.eventCount >= limit,\n };\n }\n\n async sendMessage(id: string, content: string, signal?: AbortSignal): Promise<void> {\n await this.#transport.request<WireEvent>(\"POST\", `${await this.#base()}/${id}/user_message`, {\n body: { content },\n signal,\n });\n }\n\n /**\n * One image, with an optional caption that becomes the message's text.\n *\n * png, jpeg, webp and gif, up to 10 MB. The agent sees the picture natively\n * when its chat model has vision, and otherwise a description from the\n * agent's fallback vision model — either way this costs a turn, and is\n * budgeted as one.\n */\n async sendImage(\n id: string,\n image: Blob,\n opts: { filename?: string; caption?: string; label?: string; signal?: AbortSignal } = {},\n ): Promise<void> {\n await this.sendImages(id, [{ image, filename: opts.filename, label: opts.label }], {\n caption: opts.caption,\n signal: opts.signal,\n });\n }\n\n /**\n * Up to 10 images in ONE message, so the agent reasons over the set instead of\n * one turn per picture. `label` names an image for the model, which lets it\n * answer about \"the receipt\" rather than \"the second image\"; `caption` is the\n * message's own text, shared by the set.\n */\n async sendImages(\n id: string,\n images: Array<{ image: Blob; filename?: string; label?: string }>,\n opts: { caption?: string; signal?: AbortSignal } = {},\n ): Promise<void> {\n if (images.length === 0) {\n throw new AgentApiError(\"sendImages needs at least one image.\", 400);\n }\n // Refused locally rather than as an opaque 400 from the server, which is\n // also how `createConversation` handles a request it knows will fail.\n if (images.length > MAX_IMAGES_PER_MESSAGE) {\n throw new AgentApiError(\n `A message carries at most ${MAX_IMAGES_PER_MESSAGE} images (got ${images.length}).`,\n 400,\n );\n }\n const form = new FormData();\n for (const [i, entry] of images.entries()) {\n form.append(\"file\", entry.image, entry.filename ?? `image-${i + 1}.png`);\n // Positional: the i-th label names the i-th file, so an unlabelled image\n // still needs its slot or every later label shifts onto the wrong picture.\n form.append(\"label\", entry.label ?? \"\");\n }\n if (opts.caption) form.append(\"caption\", opts.caption);\n await this.#transport.request<WireEvent>(\n \"POST\",\n `${await this.#base()}/${id}/user_message/image`,\n { body: form, signal: opts.signal },\n );\n }\n\n /**\n * Sends a voice message. The agent's STT model transcribes it before the turn\n * runs, so the reply answers what was said — the transcription then arrives as\n * a normal `user` message on the stream, which is why nothing is returned\n * here.\n *\n * `audio` is any `Blob`; a `MediaRecorder` chunk works as-is. Its `type`\n * (codec included) is forwarded, so the provider gets what it needs to decode.\n */\n async sendAudio(\n id: string,\n audio: Blob,\n opts: { filename?: string; signal?: AbortSignal } = {},\n ): Promise<void> {\n const form = new FormData();\n form.append(\"audio\", audio, opts.filename ?? \"recording.webm\");\n await this.#transport.request<WireEvent>(\n \"POST\",\n `${await this.#base()}/${id}/user_message/audio`,\n { body: form, signal: opts.signal },\n );\n }\n\n /**\n * The bytes of one of a message's attachments, as a `Blob`.\n *\n * Bytes rather than a URL because the token travels in a header: an `<img\n * src>` pointing at this route would arrive unauthenticated. Wrap it for the\n * DOM, and revoke when the element goes away:\n *\n * ```ts\n * const url = URL.createObjectURL(await client.fetchAttachment(convId, msg.id, att.id));\n * ```\n *\n * `attachmentId` is optional only for a single-attachment message; omitted on\n * a multi-image one, the server serves the first.\n */\n async fetchAttachment(\n conversationId: string,\n messageId: string,\n attachmentId?: string,\n signal?: AbortSignal,\n ): Promise<Blob> {\n const res = await this.#transport.fetchRaw(\n \"GET\",\n `${await this.#base()}/${conversationId}/events/${messageId}/attachment`,\n { query: { attachment_id: attachmentId }, signal },\n );\n // `fetchRaw` hands back the response untouched, so a 404 would otherwise\n // become a Blob containing the error body.\n await raiseForStatus(res, \"Could not fetch the attachment.\");\n return await res.blob();\n }\n\n /**\n * Lists **one** directory of the conversation's files — never recursive, so a\n * workspace with thousands of files is still one small response. `path`\n * defaults to the root.\n *\n * With no `atSeq` you see exactly what the agent would be shown on its next\n * turn, which is also the tree a write starts from — including empty, once a\n * workspace has gone untouched for long enough to expire. `atSeq` is how you\n * reach a past snapshot, expiry and all.\n *\n * None of the write methods below starts a turn. A file arriving is not a\n * question: upload what the user dropped, then send a message if you want the\n * agent to do something about it. It finds out either way — the harness tells\n * it what changed at the start of its next request.\n */\n async listFiles(\n id: string,\n opts: { path?: string; atSeq?: number; signal?: AbortSignal } = {},\n ): Promise<WorkspaceDir> {\n const raw = await this.#transport.request<{\n root_event_id: string | null;\n root_seq: number | null;\n path: string;\n entries: Array<{\n name: string;\n kind: string;\n size: number;\n exec: boolean;\n mime: string;\n sha256: string | null;\n symlink_target: string | null;\n }>;\n }>(\"GET\", `${await this.#base()}/${id}/workspace/dir`, {\n query: { path: opts.path, at_seq: opts.atSeq },\n signal: opts.signal,\n });\n return {\n path: raw.path,\n rootEventId: raw.root_event_id,\n rootSeq: raw.root_seq,\n entries: raw.entries.map((e) => ({\n name: e.name,\n kind: e.kind as WorkspaceEntry[\"kind\"],\n size: e.size,\n mime: e.mime,\n sha256: e.sha256,\n exec: e.exec,\n symlinkTarget: e.symlink_target,\n })),\n };\n }\n\n /**\n * One file's bytes, as a `Blob`. Bytes rather than a URL for the same reason\n * as `fetchAttachment`: the token travels in a header, so an `<a href>` at\n * this route would arrive unauthenticated.\n */\n async readFile(\n id: string,\n path: string,\n opts: { atSeq?: number; signal?: AbortSignal } = {},\n ): Promise<Blob> {\n const res = await this.#transport.fetchRaw(\n \"GET\",\n `${await this.#base()}/${id}/workspace/file`,\n { query: { path, at_seq: opts.atSeq }, signal: opts.signal },\n );\n await raiseForStatus(res, \"Could not read the file.\");\n return await res.blob();\n }\n\n /** Creates or replaces one file, creating parent directories. */\n async writeFile(\n id: string,\n path: string,\n file: Blob,\n opts: { filename?: string; signal?: AbortSignal } = {},\n ): Promise<void> {\n const form = new FormData();\n form.append(\"file\", file, opts.filename ?? path.split(\"/\").pop() ?? \"upload\");\n await this.#transport.request<unknown>(\"PUT\", `${await this.#base()}/${id}/workspace/file`, {\n query: { path },\n body: form,\n signal: opts.signal,\n });\n }\n\n /**\n * Writes several files as **one** snapshot. Worth preferring over a loop of\n * `writeFile`: the agent is told about the upload as a single change rather\n * than as N, and nothing ever observes half a set.\n */\n async writeFiles(\n id: string,\n files: Array<{ path: string; file: Blob; filename?: string }>,\n opts: { signal?: AbortSignal } = {},\n ): Promise<void> {\n if (files.length === 0) {\n throw new AgentApiError(\"writeFiles needs at least one file.\", 400);\n }\n const form = new FormData();\n for (const [i, entry] of files.entries()) {\n form.append(\"file\", entry.file, entry.filename ?? `file-${i + 1}`);\n // Positional, like the image route's labels: the i-th path names the i-th\n // file, so a missing one would shift every later path onto the wrong blob.\n form.append(\"path\", entry.path);\n }\n await this.#transport.request<unknown>(\"POST\", `${await this.#base()}/${id}/workspace/files`, {\n body: form,\n signal: opts.signal,\n });\n }\n\n /** Removes a file, or a directory with everything under it. Earlier\n * snapshots keep resolving through `atSeq`. */\n async deleteFile(id: string, path: string, signal?: AbortSignal): Promise<void> {\n await this.#transport.request<unknown>(\"DELETE\", `${await this.#base()}/${id}/workspace/file`, {\n query: { path },\n signal,\n });\n }\n\n async moveFile(id: string, from: string, to: string, signal?: AbortSignal): Promise<void> {\n await this.#transport.request<unknown>(\"POST\", `${await this.#base()}/${id}/workspace/move`, {\n body: { from, to },\n signal,\n });\n }\n\n /**\n * Declares the tool set on `id` without running anything — the half of\n * `serveClientTools` that has to happen *before* the first message, since a\n * tool the agent was never told about can't be called.\n *\n * Replaces the whole set, like `setComponents`.\n */\n async setClientTools(\n id: string,\n tools: Record<string, ClientTool<never, unknown>>,\n signal?: AbortSignal,\n ): Promise<void> {\n await this.#transport.request(\"PUT\", `${await this.#base()}/${id}/client-tools`, {\n body: { tools: declarations(tools) },\n signal,\n });\n }\n\n /**\n * Declares your functions as tools on `id` and runs them as the agent calls\n * them — the browser half of client tools, on the end-user token.\n *\n * Belongs on this client and not only on the operator one: the implementation\n * runs where the app runs, and an api_key is tenant-wide and can never be\n * shipped to a browser. Keep the session alive for as long as the\n * conversation is on screen, and `stop()` it when it isn't.\n *\n * The runner opens its own event stream by default. If you already subscribe\n * to the conversation, pass `watch: false` and call `session.poke()` from\n * `onOpen` and `onClientToolCall` instead: same behaviour over one connection.\n *\n * ```ts\n * const session = client.serveClientTools(id, { tools, watch: false });\n * client.subscribe(id, {\n * onOpen: () => session.poke(),\n * onClientToolCall: () => session.poke(),\n * });\n * ```\n */\n serveClientTools(id: string, options: ServeClientToolsOptions): ClientToolsSession {\n return serveClientTools(\n this.#transport,\n async () => `${await this.#base()}/${encodeURIComponent(id)}`,\n id,\n options,\n );\n }\n\n /** Injects an instruction mid-turn: unlike `sendMessage`, it lands while the\n * agent is already working and redirects it. */\n async steer(id: string, content: string, signal?: AbortSignal): Promise<void> {\n await this.#transport.request<WireEvent>(\"POST\", `${await this.#base()}/${id}/steer`, {\n body: { content },\n signal,\n });\n }\n\n /**\n * Live view of one conversation: messages, the agent's activity, and its plan.\n * Resumes from the last frame after a drop, so a reconnect loses nothing.\n *\n * By default it also backfills the whole log on connect, which makes the\n * subscription the single source of truth for a short conversation. Pass\n * `since` — the newest `changeSeq` you already hold, from `listMessagesPage` —\n * to skip that backfill and receive only what is new; that is what makes\n * paging backwards meaningful, since otherwise the stream re-delivers the\n * history you just paged through.\n */\n subscribe(\n id: string,\n handlers: ConversationHandlers,\n opts: { since?: number } = {},\n ): ConversationSubscription {\n const controller = new AbortController();\n // Arguments seen on this connection, for the activities that arrive after\n // them. The call is always persisted before the tool runs, so a result can\n // find its arguments here; one that reconnects past its own `llm_call`\n // simply reports none, exactly as before.\n const streamedArgs = new Map<string, Record<string, unknown>>();\n void this.#base().then((base) => {\n if (controller.signal.aborted) return;\n\n if (\n handlers.onMessage ||\n handlers.onEvent ||\n handlers.onTodos ||\n handlers.onClientToolCall ||\n handlers.onToolActivity ||\n handlers.onTurnDone ||\n handlers.onActivity ||\n handlers.onOpen\n ) {\n void readSse<WireEvent | WireTurnStatus>({\n url: this.#transport.url(`${base}/${id}/events/stream`),\n // Both on one connection, because the ordering between them is the\n // point: the frame that ends a turn must not overtake the reply that\n // ended it, and only a shared stream can promise that.\n event: [\"conversation_event\", \"conversation_status\"],\n // The server catches up everything past this cursor before going\n // live, so an event that lands between the history page and this\n // connection is delivered rather than dropped.\n lastEventId: opts.since === undefined ? undefined : String(opts.since),\n headers: () => this.#transport.streamHeaders(),\n fetchImpl: this.#transport.fetchImpl,\n signal: controller.signal,\n onError: handlers.onError,\n onOpen: handlers.onOpen,\n onEvent: (frame, name) => {\n if (name === \"conversation_status\") {\n handlers.onActivity?.(toTurnStatus(frame as WireTurnStatus));\n return;\n }\n const raw = frame as WireEvent;\n // Ahead of every projection, so an app taking both sees the row\n // before whatever it became.\n handlers.onEvent?.(raw as ConversationEvent);\n const message = toMessage(raw);\n if (message) handlers.onMessage?.(message);\n const todos = toTodos(raw);\n if (todos) handlers.onTodos?.(todos, raw.seq);\n const turnDone = toTurnDone(raw);\n if (turnDone !== null) handlers.onTurnDone?.(turnDone);\n const call = toClientToolCall(raw);\n if (call) handlers.onClientToolCall?.(call);\n for (const call of toToolCallArguments(raw)) {\n streamedArgs.set(call.toolCallId, call.arguments);\n }\n const activity = toToolActivity(raw);\n if (activity) handlers.onToolActivity?.(withToolArguments(activity, streamedArgs));\n // After the handlers, so a caller that persists on this signal never\n // records a cursor covering a message it hasn't stored yet.\n handlers.onCursor?.(raw.change_seq);\n },\n }).catch((err) => handlers.onError?.(err));\n }\n\n if (handlers.onConversation) {\n void readSse<WireConversation>({\n url: this.#transport.url(`${base}/${id}/meta/stream`),\n event: \"conversation_meta\",\n headers: () => this.#transport.streamHeaders(),\n fetchImpl: this.#transport.fetchImpl,\n signal: controller.signal,\n onError: handlers.onError,\n onEvent: (raw) => handlers.onConversation?.(toConversation(raw)),\n }).catch((err) => handlers.onError?.(err));\n }\n });\n\n return { close: () => controller.abort() };\n }\n\n /** Live chat list. Fires per conversation whose activity advances; upsert by\n * id and re-sort by `lastActivityAt` locally. */\n subscribeToConversations(handlers: ListHandlers): ConversationSubscription {\n const controller = new AbortController();\n void this.#base().then((base) => {\n if (controller.signal.aborted) return;\n void readSse<WireConversation>({\n url: this.#transport.url(`${base}/stream`, { origin: \"interactive\" }),\n event: \"conversation\",\n headers: () => this.#transport.streamHeaders(),\n fetchImpl: this.#transport.fetchImpl,\n signal: controller.signal,\n onError: handlers.onError,\n onEvent: (raw) => handlers.onConversation(toConversation(raw)),\n }).catch((err) => handlers.onError?.(err));\n });\n return { close: () => controller.abort() };\n }\n}\n\n/**\n * Client for an end user in a browser or mobile app, authenticated with a\n * short-lived user token. Reaches only the conversation surface, and only that\n * user's own rows — the server enforces both.\n */\nexport function createUserClient(options: ClientOptions): AgentClient {\n return new AgentClient(options);\n}\n"
26
+ ],
27
+ "mappings": "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",
28
+ "debugId": "135CEC176CA70F7564756E2164756E21",
29
+ "names": []
30
+ }