@coder/ai-sdk-agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +188 -0
- package/dist/index.d.ts +526 -0
- package/dist/index.js +930 -0
- package/dist/index.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent/coder-agent.ts","../src/errors.ts","../src/coder/types.ts","../src/coder/ws.ts","../src/coder/client.ts","../src/model/prompt.ts","../src/model/translate.ts","../src/model/language-model.ts"],"sourcesContent":["import {\n type Agent,\n type StopCondition,\n stepCountIs,\n type SystemModelMessage,\n type ToolChoice,\n ToolLoopAgent,\n type ToolSet,\n} from \"ai\";\nimport { CoderChatClient, type CoderChatClientOptions } from \"../coder/client.js\";\nimport { CoderAgentError } from \"../errors.js\";\nimport { CoderLanguageModel } from \"../model/language-model.js\";\n\ntype InnerAgent<TOOLS extends ToolSet> = ToolLoopAgent<never, TOOLS, never>;\n\n/** Default step ceiling. Each \"step\" is one client-tool round-trip; chatd caps\n * its own server-side loop at 1200 steps independently. */\nconst DEFAULT_STOP = stepCountIs(64);\n\nexport interface CoderAgentSettings<TOOLS extends ToolSet = {}> {\n // --- connection (provide a client, or baseUrl + token) ---\n /** A pre-built {@link CoderChatClient}. Mutually exclusive with baseUrl/token. */\n client?: CoderChatClient;\n /** Coder deployment base URL, e.g. `https://dev.coder.com`. */\n baseUrl?: string;\n /** Coder API/session token (sent as `Coder-Session-Token`). */\n token?: string;\n fetch?: CoderChatClientOptions[\"fetch\"];\n webSocketFactory?: CoderChatClientOptions[\"webSocketFactory\"];\n\n // --- Coder chat configuration ---\n /** Organization UUID that owns the chat (required). */\n organizationId: string;\n /** Model hint: UUID, `provider:model`, model id, or display-name substring. */\n model?: string;\n /** Bind the chat to a Coder workspace (enables workspace-scoped tools). */\n workspaceId?: string;\n /** chatd-side MCP servers to enable for this chat. */\n mcpServerIds?: string[];\n /** chatd plan mode. */\n planMode?: \"\" | \"plan\";\n /** Resume an existing chat (session) instead of creating a new one. */\n chatId?: string;\n\n // --- agent configuration ---\n /** Stable agent id (exposed as {@link CoderAgent.id}). */\n id?: string;\n /** System instructions → chatd `system_prompt`. */\n instructions?: string | SystemModelMessage | Array<SystemModelMessage>;\n /** Custom (client-executed) tools. Each should have an `execute` for scripting. */\n tools?: TOOLS;\n toolChoice?: ToolChoice<NoInfer<TOOLS>>;\n /** Stop condition(s) for the AI SDK loop. Default `stepCountIs(64)`. */\n stopWhen?: StopCondition<NoInfer<TOOLS>> | Array<StopCondition<NoInfer<TOOLS>>>;\n /**\n * SDK-level retries. Default `0`: this agent owns server-side chat state, so\n * SDK retries could duplicate a turn. Override with care.\n */\n maxRetries?: number;\n}\n\n/**\n * An AI SDK-compliant agent backed by a remote Coder `chatd` agent runtime.\n *\n * `new CoderAgent({ ... })` returns an object that implements the AI SDK\n * `Agent` interface (`generate()`/`stream()`), so it composes with the rest of\n * the AI SDK ecosystem. Internally it wraps a {@link ToolLoopAgent} whose model\n * is a {@link CoderLanguageModel}; chatd runs the actual agent loop server-side.\n *\n * One `CoderAgent` instance corresponds to one chatd chat (\"session\"): the chat\n * is created on the first `generate()`/`stream()` and reused for subsequent\n * turns. Use {@link CoderAgent.resetSession} to start a fresh chat.\n */\nexport class CoderAgent<TOOLS extends ToolSet = {}> implements Agent<never, TOOLS, never> {\n readonly version = \"agent-v1\" as const;\n\n readonly #client: CoderChatClient;\n readonly #model: CoderLanguageModel;\n readonly #inner: InnerAgent<TOOLS>;\n\n constructor(settings: CoderAgentSettings<TOOLS>) {\n if (settings.client) {\n this.#client = settings.client;\n } else if (settings.baseUrl && settings.token) {\n this.#client = new CoderChatClient({\n baseUrl: settings.baseUrl,\n token: settings.token,\n fetch: settings.fetch,\n webSocketFactory: settings.webSocketFactory,\n });\n } else {\n throw new CoderAgentError(\n \"CoderAgent requires either `client` or both `baseUrl` and `token`.\",\n );\n }\n\n this.#model = new CoderLanguageModel({\n client: this.#client,\n organizationId: settings.organizationId,\n model: settings.model,\n workspaceId: settings.workspaceId,\n mcpServerIds: settings.mcpServerIds,\n planMode: settings.planMode,\n chatId: settings.chatId,\n });\n\n this.#inner = new ToolLoopAgent<never, TOOLS, never>({\n model: this.#model,\n id: settings.id,\n instructions: settings.instructions,\n tools: settings.tools,\n toolChoice: settings.toolChoice,\n stopWhen: settings.stopWhen ?? DEFAULT_STOP,\n maxRetries: settings.maxRetries ?? 0,\n });\n }\n\n get id(): string | undefined {\n return this.#inner.id;\n }\n\n get tools(): TOOLS {\n return this.#inner.tools;\n }\n\n /** The underlying chatd client. */\n get client(): CoderChatClient {\n return this.#client;\n }\n\n /** The current chatd chat id, once a turn has started. */\n get chatId(): string | undefined {\n return this.#model.chatId;\n }\n\n generate(\n options: Parameters<InnerAgent<TOOLS>[\"generate\"]>[0],\n ): ReturnType<InnerAgent<TOOLS>[\"generate\"]> {\n return this.#inner.generate(options);\n }\n\n stream(\n options: Parameters<InnerAgent<TOOLS>[\"stream\"]>[0],\n ): ReturnType<InnerAgent<TOOLS>[\"stream\"]> {\n return this.#inner.stream(options);\n }\n\n // --- session helpers ------------------------------------------------------\n\n /** Start a fresh chatd chat on the next turn. */\n resetSession(): void {\n this.#model.resetSession();\n }\n\n /** Interrupt the in-flight generation, if any. */\n async interrupt(): Promise<void> {\n const id = this.#model.chatId;\n if (id) await this.#client.interruptChat(id);\n }\n\n /** Archive the underlying chat (safe cleanup; hides it from listings). */\n async archive(): Promise<void> {\n const id = this.#model.chatId;\n if (id) await this.#client.archiveChat(id);\n }\n}\n","import type { ChatErrorPayload } from \"./coder/types.js\";\n\n/** Base error for all `@coder/ai-sdk-agent` failures. */\nexport class CoderAgentError extends Error {\n override name = \"CoderAgentError\";\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n }\n}\n\n/** An HTTP request to the Coder API failed. */\nexport class CoderApiError extends CoderAgentError {\n override name = \"CoderApiError\";\n readonly status: number;\n readonly detail: string | undefined;\n readonly method: string;\n readonly path: string;\n constructor(args: {\n status: number;\n method: string;\n path: string;\n message: string;\n detail?: string;\n }) {\n super(\n `Coder API ${args.method} ${args.path} failed (${args.status}): ${args.message}` +\n (args.detail ? ` — ${args.detail}` : \"\"),\n );\n this.status = args.status;\n this.detail = args.detail;\n this.method = args.method;\n this.path = args.path;\n }\n}\n\n/** A chat generation ended in an error status. */\nexport class CoderChatError extends CoderAgentError {\n override name = \"CoderChatError\";\n readonly kind: string | undefined;\n readonly provider: string | undefined;\n readonly retryable: boolean;\n readonly statusCode: number | undefined;\n constructor(payload: ChatErrorPayload) {\n super(payload.detail ? `${payload.message}: ${payload.detail}` : payload.message);\n this.kind = payload.kind;\n this.provider = payload.provider;\n this.retryable = payload.retryable ?? false;\n this.statusCode = payload.status_code;\n }\n}\n","/**\n * Wire types for Coder's experimental `chatd` chat API\n * (`/api/experimental/chats`). These mirror the Go types in\n * `coder/coder`'s `codersdk/chats.go` (JSON shapes), restricted to the subset\n * this client uses. Field names use snake_case to match the wire format.\n *\n * NOTE: The chatd API is experimental and may change between Coder releases.\n */\n\n// ---------------------------------------------------------------------------\n// Input (client -> server)\n// ---------------------------------------------------------------------------\n\nexport type ChatInputPartType = \"text\" | \"file\" | \"file-reference\";\n\nexport interface ChatInputPart {\n type: ChatInputPartType;\n text?: string;\n file_id?: string;\n file_name?: string;\n start_line?: number;\n end_line?: number;\n content?: string;\n}\n\nexport type ChatClientType = \"ui\" | \"api\";\nexport type ChatPlanMode = \"\" | \"plan\";\nexport type ChatBusyBehavior = \"queue\" | \"interrupt\";\n\n/**\n * A client-executed (\"dynamic\") tool definition. chatd never executes these;\n * when the model calls one, the chat enters `requires_action` and the client\n * must execute it and submit results via {@link SubmitToolResultsRequest}.\n *\n * NOTE: the JSON key is `input_schema` (snake_case), per chatd.\n */\nexport interface DynamicTool {\n name: string;\n description?: string;\n /** A JSON Schema object describing the tool input. */\n input_schema: unknown;\n}\n\nexport interface CreateChatRequest {\n organization_id: string;\n content: ChatInputPart[];\n system_prompt?: string;\n workspace_id?: string;\n model_config_id?: string;\n mcp_server_ids?: string[];\n labels?: Record<string, string>;\n unsafe_dynamic_tools?: DynamicTool[];\n plan_mode?: ChatPlanMode;\n client_type?: ChatClientType;\n}\n\nexport interface CreateChatMessageRequest {\n content: ChatInputPart[];\n model_config_id?: string;\n mcp_server_ids?: string[];\n busy_behavior?: ChatBusyBehavior;\n plan_mode?: ChatPlanMode;\n}\n\n/** Result of a single client-executed tool call. */\nexport interface ToolResult {\n tool_call_id: string;\n /** JSON-serializable tool output. */\n output: unknown;\n is_error?: boolean;\n}\n\nexport interface SubmitToolResultsRequest {\n results: ToolResult[];\n}\n\nexport interface UpdateChatRequest {\n title?: string;\n archived?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Output (server -> client)\n// ---------------------------------------------------------------------------\n\nexport type ChatStatus =\n | \"waiting\"\n | \"pending\"\n | \"running\"\n | \"paused\"\n | \"completed\"\n | \"error\"\n | \"requires_action\"\n | \"interrupting\";\n\nexport type ChatMessageRole = \"system\" | \"user\" | \"assistant\" | \"tool\";\n\nexport type ChatMessagePartType =\n | \"text\"\n | \"reasoning\"\n | \"tool-call\"\n | \"tool-result\"\n | \"source\"\n | \"file\"\n | \"file-reference\"\n | \"context-file\"\n | \"skill\";\n\n/**\n * A part of a chat message. chatd models this as a single flat struct with a\n * `type` discriminator and many optional fields (see `codersdk.ChatMessagePart`),\n * so we mirror that shape rather than a strict discriminated union.\n */\nexport interface ChatMessagePart {\n type: ChatMessagePartType;\n\n // text / reasoning\n text?: string;\n signature?: string;\n\n // tool-call / tool-result\n tool_call_id?: string;\n tool_name?: string;\n mcp_server_config_id?: string | null;\n /** tool-call: complete arguments (JSON value). */\n args?: unknown;\n /** tool-call: incremental argument text chunk during streaming. */\n args_delta?: string;\n parsed_commands?: string[][];\n /** tool-result: complete result (JSON value). */\n result?: unknown;\n /** tool-result: incremental result text chunk during streaming. */\n result_delta?: string;\n result_reset?: boolean;\n is_error?: boolean;\n is_media?: boolean;\n provider_executed?: boolean;\n created_at?: string;\n completed_at?: string;\n\n // source\n source_id?: string;\n url?: string;\n title?: string;\n\n // file\n media_type?: string;\n name?: string;\n file_id?: string | null;\n\n // file-reference\n file_name?: string;\n start_line?: number;\n end_line?: number;\n content?: string;\n\n // skill\n skill_name?: string;\n skill_description?: string;\n}\n\nexport interface ChatMessageUsage {\n input_tokens?: number;\n output_tokens?: number;\n total_tokens?: number;\n reasoning_tokens?: number;\n cache_creation_tokens?: number;\n cache_read_tokens?: number;\n context_limit?: number;\n}\n\nexport interface ChatMessage {\n id: number;\n chat_id: string;\n created_by?: string;\n model_config_id?: string;\n created_at: string;\n role: ChatMessageRole;\n content?: ChatMessagePart[];\n usage?: ChatMessageUsage;\n}\n\nexport interface ChatErrorPayload {\n message: string;\n detail?: string;\n kind?: string;\n provider?: string;\n retryable?: boolean;\n status_code?: number;\n}\n\nexport interface Chat {\n id: string;\n organization_id: string;\n owner_id: string;\n owner_username?: string;\n workspace_id?: string | null;\n agent_id?: string | null;\n parent_chat_id?: string | null;\n root_chat_id?: string | null;\n last_model_config_id?: string;\n title: string;\n status: ChatStatus;\n plan_mode?: ChatPlanMode;\n last_error?: ChatErrorPayload | null;\n created_at: string;\n updated_at: string;\n archived: boolean;\n mcp_server_ids?: string[];\n client_type?: ChatClientType;\n}\n\nexport interface ChatQueuedMessage {\n id: number;\n chat_id: string;\n content: ChatMessagePart[];\n created_at: string;\n}\n\nexport interface CreateChatMessageResponse {\n message?: ChatMessage;\n queued_message?: ChatQueuedMessage;\n queued: boolean;\n warnings?: string[];\n}\n\nexport interface ChatMessagesResponse {\n messages: ChatMessage[];\n queued_messages: ChatQueuedMessage[];\n has_more: boolean;\n}\n\nexport interface ChatModelConfig {\n id: string;\n provider: string;\n ai_provider_id?: string;\n model: string;\n display_name: string;\n enabled?: boolean;\n is_default?: boolean;\n context_limit?: number;\n compression_threshold?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Stream events (WebSocket `/stream`)\n// ---------------------------------------------------------------------------\n\nexport type ChatStreamEventType =\n | \"message_part\"\n | \"message\"\n | \"status\"\n | \"error\"\n | \"queue_update\"\n | \"retry\"\n | \"action_required\"\n | \"preview_reset\"\n | \"history_reset\";\n\nexport interface ChatStreamMessagePart {\n role?: ChatMessageRole;\n part: ChatMessagePart;\n history_version?: number;\n generation_attempt?: number;\n seq?: number;\n}\n\nexport interface ChatStreamStatus {\n status: ChatStatus;\n}\n\nexport interface ChatStreamToolCall {\n tool_call_id: string;\n tool_name: string;\n /** JSON string of the tool-call arguments. */\n args: string;\n}\n\nexport interface ChatStreamActionRequired {\n tool_calls: ChatStreamToolCall[];\n}\n\nexport interface ChatStreamRetry {\n attempt: number;\n delay_ms: number;\n error: string;\n kind?: string;\n provider?: string;\n status_code?: number;\n retrying_at: string;\n}\n\nexport interface ChatStreamEvent {\n type: ChatStreamEventType;\n chat_id: string;\n message?: ChatMessage;\n message_part?: ChatStreamMessagePart;\n status?: ChatStreamStatus;\n error?: ChatErrorPayload;\n retry?: ChatStreamRetry;\n queued_messages?: ChatQueuedMessage[];\n action_required?: ChatStreamActionRequired;\n}\n\n/** Terminal statuses: the chat has stopped generating for this turn. */\nexport const TERMINAL_STATUSES: ReadonlySet<ChatStatus> = new Set<ChatStatus>([\n \"waiting\",\n \"completed\",\n \"error\",\n \"requires_action\",\n]);\n","import NodeWebSocket from \"ws\";\nimport { CoderAgentError } from \"../errors.js\";\nimport type { ChatStreamEvent } from \"./types.js\";\n\n/**\n * A minimal WebSocket factory abstraction so the stream reader can run on\n * Node (via the `ws` package, with header auth) or in environments that\n * provide a global `WebSocket` (browsers, where auth must go in the query\n * string). Node is the default target.\n */\nexport interface WebSocketLike {\n send(data: string): void;\n close(code?: number): void;\n addEventListener(type: \"open\", cb: () => void): void;\n addEventListener(type: \"message\", cb: (ev: { data: unknown }) => void): void;\n addEventListener(type: \"error\", cb: (ev: unknown) => void): void;\n addEventListener(type: \"close\", cb: (ev: { code?: number; reason?: string }) => void): void;\n removeEventListener(type: \"open\", cb: () => void): void;\n removeEventListener(type: \"message\", cb: (ev: { data: unknown }) => void): void;\n removeEventListener(type: \"error\", cb: (ev: unknown) => void): void;\n removeEventListener(type: \"close\", cb: (ev: { code?: number; reason?: string }) => void): void;\n}\n\nexport type WebSocketFactory = (\n url: string,\n protocols: { headers: Record<string, string> },\n) => WebSocketLike;\n\nconst defaultFactory: WebSocketFactory = (url, { headers }) => {\n // `ws` accepts custom handshake headers, which lets us authenticate with the\n // `Coder-Session-Token` header instead of leaking the token into the URL.\n return new NodeWebSocket(url, { headers }) as unknown as WebSocketLike;\n};\n\nfunction httpToWs(baseUrl: string): string {\n if (baseUrl.startsWith(\"https://\")) return `wss://${baseUrl.slice(\"https://\".length)}`;\n if (baseUrl.startsWith(\"http://\")) return `ws://${baseUrl.slice(\"http://\".length)}`;\n return baseUrl;\n}\n\nexport interface StreamChatEventsOptions {\n baseUrl: string;\n token: string;\n chatId: string;\n /** Only stream events for messages with id greater than this. */\n afterId?: number;\n signal?: AbortSignal;\n webSocketFactory?: WebSocketFactory;\n}\n\n/**\n * Opens the chatd `/stream` WebSocket and yields decoded {@link ChatStreamEvent}s\n * as an async iterable. Each text frame from chatd is a JSON array of events;\n * we flatten them into a single stream.\n *\n * The chat stream is a live subscription that stays open after a turn settles,\n * so callers should `break` out of the loop once they observe a terminal status\n * — that triggers generator cleanup, which closes the socket.\n */\nexport async function* streamChatEvents(\n options: StreamChatEventsOptions,\n): AsyncGenerator<ChatStreamEvent, void, void> {\n const { baseUrl, token, chatId, afterId, signal } = options;\n const factory = options.webSocketFactory ?? defaultFactory;\n\n const wsBase = httpToWs(baseUrl);\n const query = afterId !== undefined ? `?after_id=${afterId}` : \"\";\n const url = `${wsBase}/api/experimental/chats/${chatId}/stream${query}`;\n\n const queue: ChatStreamEvent[] = [];\n let resolveNext: (() => void) | undefined;\n let finished = false;\n let failure: Error | undefined;\n\n const wake = () => {\n resolveNext?.();\n resolveNext = undefined;\n };\n\n const ws = factory(url, { headers: { \"Coder-Session-Token\": token } });\n\n const onAbort = () => {\n finished = true;\n try {\n ws.close(1000);\n } catch {\n /* ignore */\n }\n wake();\n };\n let abortListenerAdded = false;\n if (signal) {\n if (signal.aborted) onAbort();\n else {\n signal.addEventListener(\"abort\", onAbort, { once: true });\n abortListenerAdded = true;\n }\n }\n\n const onMessage = (ev: { data: unknown }): void => {\n if (finished) return;\n let batch: unknown;\n try {\n const data = typeof ev.data === \"string\" ? ev.data : String(ev.data);\n batch = JSON.parse(data);\n } catch (err) {\n failure = new CoderAgentError(\"failed to parse chat stream frame\", { cause: err });\n finished = true;\n wake();\n return;\n }\n if (Array.isArray(batch)) {\n for (const e of batch) queue.push(e as ChatStreamEvent);\n } else if (batch && typeof batch === \"object\") {\n queue.push(batch as ChatStreamEvent);\n }\n wake();\n };\n const onError = (ev: unknown): void => {\n if (finished) return;\n const message =\n ev && typeof ev === \"object\" && \"message\" in ev\n ? String((ev as { message: unknown }).message)\n : \"chat stream socket error\";\n failure = new CoderAgentError(message);\n finished = true;\n wake();\n };\n const onClose = (): void => {\n finished = true;\n wake();\n };\n ws.addEventListener(\"message\", onMessage);\n ws.addEventListener(\"error\", onError);\n ws.addEventListener(\"close\", onClose);\n\n try {\n while (true) {\n while (queue.length > 0) {\n const next = queue.shift() as ChatStreamEvent;\n yield next;\n }\n if (failure) throw failure;\n if (finished) return;\n await new Promise<void>((resolve) => {\n resolveNext = resolve;\n });\n }\n } finally {\n finished = true;\n if (signal && abortListenerAdded) signal.removeEventListener(\"abort\", onAbort);\n ws.removeEventListener(\"message\", onMessage);\n ws.removeEventListener(\"error\", onError);\n ws.removeEventListener(\"close\", onClose);\n try {\n ws.close(1000);\n } catch {\n /* ignore */\n }\n }\n}\n","import { CoderApiError } from \"../errors.js\";\nimport {\n type Chat,\n type ChatMessagesResponse,\n type ChatModelConfig,\n type ChatStreamEvent,\n type CreateChatMessageRequest,\n type CreateChatMessageResponse,\n type CreateChatRequest,\n type SubmitToolResultsRequest,\n type UpdateChatRequest,\n} from \"./types.js\";\nimport { streamChatEvents, type WebSocketFactory } from \"./ws.js\";\n\nexport interface CoderChatClientOptions {\n /** Base URL of the Coder deployment, e.g. `https://dev.coder.com`. */\n baseUrl: string;\n /** Coder API token or session token (sent as `Coder-Session-Token`). */\n token: string;\n /** Custom fetch implementation (defaults to global `fetch`). */\n fetch?: typeof globalThis.fetch;\n /** Custom WebSocket factory (defaults to the `ws` package on Node). */\n webSocketFactory?: WebSocketFactory;\n}\n\nconst API_PREFIX = \"/api/experimental/chats\";\n\n/**\n * A thin, typed client for Coder's experimental `chatd` API. This is a\n * TypeScript port of the chat surface of `codersdk.ExperimentalClient`.\n */\nexport class CoderChatClient {\n readonly baseUrl: string;\n readonly #token: string;\n readonly #fetch: typeof globalThis.fetch;\n readonly #webSocketFactory: WebSocketFactory | undefined;\n\n constructor(options: CoderChatClientOptions) {\n // Normalize: strip a single trailing slash.\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.#token = options.token;\n this.#fetch = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.#webSocketFactory = options.webSocketFactory;\n }\n\n async #request<T>(\n method: string,\n path: string,\n body?: unknown,\n signal?: AbortSignal,\n ): Promise<T> {\n const headers: Record<string, string> = { \"Coder-Session-Token\": this.#token };\n if (body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n\n const res = await this.#fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n signal,\n });\n\n const text = await res.text();\n let parsed: unknown;\n try {\n parsed = text.length > 0 ? JSON.parse(text) : undefined;\n } catch {\n parsed = undefined;\n }\n\n if (!res.ok) {\n const errObj = (parsed ?? {}) as { message?: string; detail?: string };\n throw new CoderApiError({\n status: res.status,\n method,\n path,\n message: errObj.message ?? res.statusText ?? \"request failed\",\n detail: errObj.detail,\n });\n }\n return parsed as T;\n }\n\n // --- REST -----------------------------------------------------------------\n\n listModelConfigs(signal?: AbortSignal): Promise<ChatModelConfig[]> {\n return this.#request<ChatModelConfig[]>(\n \"GET\",\n `${API_PREFIX}/model-configs`,\n undefined,\n signal,\n );\n }\n\n createChat(req: CreateChatRequest, signal?: AbortSignal): Promise<Chat> {\n return this.#request<Chat>(\"POST\", API_PREFIX, req, signal);\n }\n\n getChat(chatId: string, signal?: AbortSignal): Promise<Chat> {\n return this.#request<Chat>(\"GET\", `${API_PREFIX}/${chatId}`, undefined, signal);\n }\n\n createChatMessage(\n chatId: string,\n req: CreateChatMessageRequest,\n signal?: AbortSignal,\n ): Promise<CreateChatMessageResponse> {\n return this.#request<CreateChatMessageResponse>(\n \"POST\",\n `${API_PREFIX}/${chatId}/messages`,\n req,\n signal,\n );\n }\n\n getMessages(\n chatId: string,\n opts?: { before_id?: number; after_id?: number; limit?: number },\n signal?: AbortSignal,\n ): Promise<ChatMessagesResponse> {\n const params = new URLSearchParams();\n if (opts?.before_id !== undefined) params.set(\"before_id\", String(opts.before_id));\n if (opts?.after_id !== undefined) params.set(\"after_id\", String(opts.after_id));\n if (opts?.limit !== undefined) params.set(\"limit\", String(opts.limit));\n const q = params.toString();\n return this.#request<ChatMessagesResponse>(\n \"GET\",\n `${API_PREFIX}/${chatId}/messages${q ? `?${q}` : \"\"}`,\n undefined,\n signal,\n );\n }\n\n submitToolResults(\n chatId: string,\n req: SubmitToolResultsRequest,\n signal?: AbortSignal,\n ): Promise<void> {\n return this.#request<void>(\"POST\", `${API_PREFIX}/${chatId}/tool-results`, req, signal);\n }\n\n interruptChat(chatId: string, signal?: AbortSignal): Promise<Chat> {\n return this.#request<Chat>(\"POST\", `${API_PREFIX}/${chatId}/interrupt`, undefined, signal);\n }\n\n updateChat(chatId: string, req: UpdateChatRequest, signal?: AbortSignal): Promise<void> {\n return this.#request<void>(\"PATCH\", `${API_PREFIX}/${chatId}`, req, signal);\n }\n\n /** Convenience: archive a chat (soft-hide; safe for cleanup). */\n archiveChat(chatId: string, signal?: AbortSignal): Promise<void> {\n return this.updateChat(chatId, { archived: true }, signal);\n }\n\n // --- Streaming ------------------------------------------------------------\n\n streamEvents(\n chatId: string,\n opts?: { afterId?: number; signal?: AbortSignal },\n ): AsyncGenerator<ChatStreamEvent, void, void> {\n return streamChatEvents({\n baseUrl: this.baseUrl,\n token: this.#token,\n chatId,\n afterId: opts?.afterId,\n signal: opts?.signal,\n webSocketFactory: this.#webSocketFactory,\n });\n }\n\n // --- Helpers --------------------------------------------------------------\n\n /**\n * Resolves a user-friendly model hint to a model-config UUID.\n *\n * Accepts: a config UUID (returned as-is), a `provider:model` id\n * (e.g. `anthropic:claude-haiku-4-5-20251001`), a bare model id, or a\n * display-name substring (case-insensitive). Returns `undefined` if no\n * match is found, in which case the caller should let chatd pick the default.\n */\n async resolveModelConfigId(hint: string, signal?: AbortSignal): Promise<string | undefined> {\n const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n if (UUID_RE.test(hint)) return hint;\n\n const configs = await this.listModelConfigs(signal);\n const lower = hint.toLowerCase();\n // `provider:model` form.\n const colon = hint.indexOf(\":\");\n const provider = colon >= 0 ? hint.slice(0, colon).toLowerCase() : undefined;\n const model = colon >= 0 ? hint.slice(colon + 1).toLowerCase() : lower;\n\n const candidates = configs.filter((c) => c.enabled !== false);\n const pool = candidates.length > 0 ? candidates : configs;\n\n const exact = pool.find(\n (c) =>\n c.model.toLowerCase() === model &&\n (provider === undefined || c.provider.toLowerCase() === provider),\n );\n if (exact) return exact.id;\n\n const byModel = pool.find((c) => c.model.toLowerCase() === model);\n if (byModel) return byModel.id;\n\n const byDisplay = pool.find((c) => c.display_name.toLowerCase().includes(lower));\n if (byDisplay) return byDisplay.id;\n\n const byModelSubstring = pool.find((c) => c.model.toLowerCase().includes(model));\n return byModelSubstring?.id;\n }\n}\n","import type {\n LanguageModelV3CallOptions,\n LanguageModelV3Message,\n LanguageModelV3Prompt,\n LanguageModelV3ToolResultOutput,\n} from \"@ai-sdk/provider\";\nimport type { ChatInputPart, DynamicTool, ToolResult } from \"../coder/types.js\";\n\n/** Concatenated system messages, mapped to chatd's `system_prompt`. */\nexport function extractSystemPrompt(prompt: LanguageModelV3Prompt): string | undefined {\n const parts = prompt.filter(\n (m): m is Extract<LanguageModelV3Message, { role: \"system\" }> => m.role === \"system\",\n );\n if (parts.length === 0) return undefined;\n const joined = parts\n .map((m) => m.content)\n .join(\"\\n\\n\")\n .trim();\n return joined.length > 0 ? joined : undefined;\n}\n\nfunction userContentToInputParts(\n message: Extract<LanguageModelV3Message, { role: \"user\" }>,\n): ChatInputPart[] {\n const out: ChatInputPart[] = [];\n for (const part of message.content) {\n if (part.type === \"text\" && part.text.length > 0) {\n out.push({ type: \"text\", text: part.text });\n }\n // NOTE: file/image input parts are not yet forwarded to chatd.\n }\n return out;\n}\n\nfunction toolResultOutputToChatd(output: LanguageModelV3ToolResultOutput): {\n value: unknown;\n isError: boolean;\n} {\n switch (output.type) {\n case \"text\":\n return { value: output.value, isError: false };\n case \"json\":\n return { value: output.value, isError: false };\n case \"error-text\":\n return { value: output.value, isError: true };\n case \"error-json\":\n return { value: output.value, isError: true };\n case \"execution-denied\":\n return { value: { execution_denied: true, reason: output.reason }, isError: true };\n case \"content\":\n return { value: output.value, isError: false };\n default:\n return { value: output, isError: false };\n }\n}\n\nexport type TurnAction =\n | { kind: \"new-turn\"; content: ChatInputPart[] }\n | { kind: \"resume\"; toolResults: ToolResult[] }\n | { kind: \"noop\" };\n\n/**\n * Decides what to do with a fresh `doStream`/`doGenerate` prompt:\n * - trailing `tool` message(s) → resume the in-flight chatd turn by submitting\n * those tool results (the AI SDK executed a client tool between steps);\n * - otherwise the trailing `user` message → a new turn.\n */\nexport function classifyTurnAction(prompt: LanguageModelV3Prompt): TurnAction {\n if (prompt.length === 0) return { kind: \"noop\" };\n const last = prompt[prompt.length - 1];\n if (!last) return { kind: \"noop\" };\n\n if (last.role === \"tool\") {\n const toolResults: ToolResult[] = [];\n // Collect from all trailing consecutive tool messages.\n for (let i = prompt.length - 1; i >= 0; i--) {\n const m = prompt[i];\n if (!m || m.role !== \"tool\") break;\n for (const part of m.content) {\n if (part.type !== \"tool-result\") continue;\n const { value, isError } = toolResultOutputToChatd(part.output);\n toolResults.unshift({ tool_call_id: part.toolCallId, output: value, is_error: isError });\n }\n }\n return { kind: \"resume\", toolResults };\n }\n\n if (last.role === \"user\") {\n return { kind: \"new-turn\", content: userContentToInputParts(last) };\n }\n\n return { kind: \"noop\" };\n}\n\n/** Maps AI SDK function tools to chatd client-executed (\"dynamic\") tools. */\nexport function toolsToDynamicTools(tools: LanguageModelV3CallOptions[\"tools\"]): DynamicTool[] {\n if (!tools) return [];\n const out: DynamicTool[] = [];\n for (const tool of tools) {\n if (tool.type !== \"function\") continue; // provider tools are not forwarded\n out.push({\n name: tool.name,\n description: tool.description,\n input_schema: tool.inputSchema,\n });\n }\n return out;\n}\n\n/** The set of tool names the AI SDK side owns (i.e. client-executed). */\nexport function dynamicToolNames(tools: LanguageModelV3CallOptions[\"tools\"]): Set<string> {\n const names = new Set<string>();\n for (const tool of tools ?? []) {\n if (tool.type === \"function\") names.add(tool.name);\n }\n return names;\n}\n","import type {\n LanguageModelV3FinishReason,\n LanguageModelV3StreamPart,\n LanguageModelV3Usage,\n} from \"@ai-sdk/provider\";\nimport { CoderChatError } from \"../errors.js\";\nimport {\n type ChatErrorPayload,\n type ChatMessage,\n type ChatMessagePart,\n type ChatMessageUsage,\n type ChatStatus,\n type ChatStreamEvent,\n TERMINAL_STATUSES,\n} from \"../coder/types.js\";\n\nfunction mapUsage(u: ChatMessageUsage | undefined): LanguageModelV3Usage {\n return {\n inputTokens: {\n total: u?.input_tokens,\n noCache: undefined,\n cacheRead: u?.cache_read_tokens,\n cacheWrite: u?.cache_creation_tokens,\n },\n outputTokens: {\n total: u?.output_tokens,\n text: undefined,\n reasoning: u?.reasoning_tokens,\n },\n };\n}\n\nfunction jsonResult(value: unknown): NonNullable<unknown> {\n // chatd tool results are arbitrary JSON; the V3 tool-result `result` must be\n // a non-null JSON value.\n return (value ?? {}) as NonNullable<unknown>;\n}\n\n/**\n * Translates one chatd turn's {@link ChatStreamEvent} stream into a sequence of\n * `LanguageModelV3StreamPart`s for the AI SDK.\n *\n * Two text/reasoning modes, decided per turn from the wire behavior:\n * - **delta mode** — chatd streamed `message_part` deltas; we emit those and\n * treat the trailing full `message` snapshot as a no-op for text/reasoning.\n * - **snapshot mode** — fast turns where only full `message` snapshots arrive;\n * we diff each snapshot's full text against what we've already emitted.\n * Both paths track an emitted-length cursor, so neither double-counts.\n *\n * Client (custom) tool calls are emitted from the reliable `action_required`\n * event and left for the AI SDK to execute. chatd's own server-side tools are\n * surfaced best-effort as `providerExecuted` tool calls/results.\n */\nexport class TurnTranslator {\n readonly #dynamicToolNames: ReadonlySet<string>;\n\n #seq = 0;\n #text = { id: undefined as string | undefined, len: 0, sawDelta: false };\n #reasoning = { id: undefined as string | undefined, len: 0, sawDelta: false };\n #currentAssistantId: number | undefined;\n\n #serverToolCalls = new Set<string>();\n #serverToolResults = new Set<string>();\n #clientToolCalls = new Set<string>();\n #clientToolCallSeen = false;\n\n #usage: ChatMessageUsage | undefined;\n #error: ChatErrorPayload | undefined;\n #terminalStatus: ChatStatus | undefined;\n #maxMessageId = 0;\n\n constructor(opts: { dynamicToolNames: ReadonlySet<string> }) {\n this.#dynamicToolNames = opts.dynamicToolNames;\n }\n\n get terminalStatus(): ChatStatus | undefined {\n return this.#terminalStatus;\n }\n /** Whether a client (custom) tool call has been emitted this turn. */\n get clientToolCallSeen(): boolean {\n return this.#clientToolCallSeen;\n }\n get maxMessageId(): number {\n return this.#maxMessageId;\n }\n get error(): ChatErrorPayload | undefined {\n return this.#error;\n }\n\n // --- block helpers --------------------------------------------------------\n\n #openText(out: LanguageModelV3StreamPart[]): void {\n if (this.#reasoning.id) this.#closeReasoning(out);\n if (!this.#text.id) {\n this.#text.id = `text-${++this.#seq}`;\n this.#text.len = 0;\n out.push({ type: \"text-start\", id: this.#text.id });\n }\n }\n #closeText(out: LanguageModelV3StreamPart[]): void {\n if (this.#text.id) {\n out.push({ type: \"text-end\", id: this.#text.id });\n this.#text.id = undefined;\n this.#text.len = 0;\n }\n }\n #openReasoning(out: LanguageModelV3StreamPart[]): void {\n if (this.#text.id) this.#closeText(out);\n if (!this.#reasoning.id) {\n this.#reasoning.id = `reasoning-${++this.#seq}`;\n this.#reasoning.len = 0;\n out.push({ type: \"reasoning-start\", id: this.#reasoning.id });\n }\n }\n #closeReasoning(out: LanguageModelV3StreamPart[]): void {\n if (this.#reasoning.id) {\n out.push({ type: \"reasoning-end\", id: this.#reasoning.id });\n this.#reasoning.id = undefined;\n this.#reasoning.len = 0;\n }\n }\n\n #emitTextUpTo(out: LanguageModelV3StreamPart[], full: string): void {\n if (full.length <= this.#text.len && this.#text.id) return;\n this.#openText(out);\n if (full.length > this.#text.len) {\n out.push({\n type: \"text-delta\",\n id: this.#text.id as string,\n delta: full.slice(this.#text.len),\n });\n this.#text.len = full.length;\n }\n }\n #emitReasoningUpTo(out: LanguageModelV3StreamPart[], full: string): void {\n if (full.length <= this.#reasoning.len && this.#reasoning.id) return;\n this.#openReasoning(out);\n if (full.length > this.#reasoning.len) {\n out.push({\n type: \"reasoning-delta\",\n id: this.#reasoning.id as string,\n delta: full.slice(this.#reasoning.len),\n });\n this.#reasoning.len = full.length;\n }\n }\n\n // --- tool helpers ---------------------------------------------------------\n\n #isClientTool(name: string | undefined): boolean {\n return name !== undefined && this.#dynamicToolNames.has(name);\n }\n\n #emitServerToolCall(out: LanguageModelV3StreamPart[], part: ChatMessagePart): void {\n const id = part.tool_call_id;\n const name = part.tool_name;\n if (!id || !name) return;\n if (part.args === undefined) return; // wait for complete args (snapshot)\n if (this.#serverToolCalls.has(id)) return;\n this.#serverToolCalls.add(id);\n out.push({ type: \"tool-input-start\", id, toolName: name, providerExecuted: true });\n out.push({ type: \"tool-input-end\", id });\n out.push({\n type: \"tool-call\",\n toolCallId: id,\n toolName: name,\n input: typeof part.args === \"string\" ? part.args : JSON.stringify(part.args),\n providerExecuted: true,\n });\n }\n\n #emitServerToolResult(out: LanguageModelV3StreamPart[], part: ChatMessagePart): void {\n const id = part.tool_call_id;\n const name = part.tool_name;\n if (!id || !name) return;\n if (part.result === undefined) return;\n if (this.#serverToolResults.has(id)) return;\n this.#serverToolResults.add(id);\n out.push({\n type: \"tool-result\",\n toolCallId: id,\n toolName: name,\n result: jsonResult(part.result),\n isError: part.is_error ?? false,\n });\n }\n\n // --- ingest ---------------------------------------------------------------\n\n ingest(ev: ChatStreamEvent): LanguageModelV3StreamPart[] {\n const out: LanguageModelV3StreamPart[] = [];\n switch (ev.type) {\n case \"message_part\":\n this.#ingestMessagePart(out, ev);\n break;\n case \"message\":\n if (ev.message) this.#ingestMessage(out, ev.message);\n break;\n case \"action_required\":\n for (const tc of ev.action_required?.tool_calls ?? []) {\n if (this.#clientToolCalls.has(tc.tool_call_id)) continue;\n this.#closeText(out);\n this.#closeReasoning(out);\n this.#clientToolCalls.add(tc.tool_call_id);\n this.#clientToolCallSeen = true;\n out.push({ type: \"tool-input-start\", id: tc.tool_call_id, toolName: tc.tool_name });\n out.push({ type: \"tool-input-end\", id: tc.tool_call_id });\n out.push({\n type: \"tool-call\",\n toolCallId: tc.tool_call_id,\n toolName: tc.tool_name,\n input: tc.args,\n });\n }\n break;\n case \"error\":\n if (ev.error) {\n this.#error = ev.error;\n out.push({ type: \"error\", error: new CoderChatError(ev.error) });\n }\n break;\n case \"status\":\n if (ev.status && TERMINAL_STATUSES.has(ev.status.status)) {\n this.#terminalStatus = ev.status.status;\n }\n break;\n default:\n break; // retry / queue_update / preview_reset / history_reset\n }\n return out;\n }\n\n #ingestMessagePart(out: LanguageModelV3StreamPart[], ev: ChatStreamEvent): void {\n const mp = ev.message_part;\n if (!mp || (mp.role !== \"assistant\" && mp.role !== \"tool\")) return;\n const part = mp.part;\n switch (part.type) {\n case \"text\":\n this.#text.sawDelta = true;\n this.#openText(out);\n if (part.text) {\n out.push({ type: \"text-delta\", id: this.#text.id as string, delta: part.text });\n this.#text.len += part.text.length;\n }\n break;\n case \"reasoning\":\n this.#reasoning.sawDelta = true;\n this.#openReasoning(out);\n if (part.text) {\n out.push({ type: \"reasoning-delta\", id: this.#reasoning.id as string, delta: part.text });\n this.#reasoning.len += part.text.length;\n }\n break;\n case \"tool-call\":\n this.#closeText(out);\n this.#closeReasoning(out);\n if (!this.#isClientTool(part.tool_name)) this.#emitServerToolCall(out, part);\n break;\n case \"tool-result\":\n if (!this.#isClientTool(part.tool_name)) this.#emitServerToolResult(out, part);\n break;\n default:\n break;\n }\n }\n\n #ingestMessage(out: LanguageModelV3StreamPart[], message: ChatMessage): void {\n if (message.id > this.#maxMessageId) this.#maxMessageId = message.id;\n if (message.usage && (message.role === \"assistant\" || message.role === \"tool\")) {\n this.#usage = message.usage;\n }\n const content = message.content ?? [];\n\n if (message.role === \"assistant\") {\n // New assistant message boundary: close prior blocks and reset cursors.\n if (this.#currentAssistantId !== undefined && this.#currentAssistantId !== message.id) {\n this.#closeText(out);\n this.#closeReasoning(out);\n this.#text.sawDelta = false;\n this.#reasoning.sawDelta = false;\n }\n this.#currentAssistantId = message.id;\n\n if (!this.#text.sawDelta) {\n const full = content\n .filter((p) => p.type === \"text\")\n .map((p) => p.text ?? \"\")\n .join(\"\");\n if (full.length > 0) this.#emitTextUpTo(out, full);\n }\n if (!this.#reasoning.sawDelta) {\n const full = content\n .filter((p) => p.type === \"reasoning\")\n .map((p) => p.text ?? \"\")\n .join(\"\");\n if (full.length > 0) this.#emitReasoningUpTo(out, full);\n }\n for (const part of content) {\n if (part.type === \"tool-call\" && !this.#isClientTool(part.tool_name))\n this.#emitServerToolCall(out, part);\n else if (part.type === \"tool-result\" && !this.#isClientTool(part.tool_name))\n this.#emitServerToolResult(out, part);\n }\n } else if (message.role === \"tool\") {\n for (const part of content) {\n if (part.type === \"tool-result\" && !this.#isClientTool(part.tool_name))\n this.#emitServerToolResult(out, part);\n }\n }\n }\n\n // --- finish ---------------------------------------------------------------\n\n finish(): LanguageModelV3StreamPart[] {\n const out: LanguageModelV3StreamPart[] = [];\n this.#closeText(out);\n this.#closeReasoning(out);\n\n let unified: LanguageModelV3FinishReason[\"unified\"];\n if (this.#error || this.#terminalStatus === \"error\") unified = \"error\";\n else if (this.#clientToolCallSeen || this.#terminalStatus === \"requires_action\")\n unified = \"tool-calls\";\n else unified = \"stop\";\n\n out.push({\n type: \"finish\",\n usage: mapUsage(this.#usage),\n finishReason: { unified, raw: this.#terminalStatus },\n });\n return out;\n }\n}\n","import type {\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3Content,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamPart,\n LanguageModelV3StreamResult,\n LanguageModelV3Usage,\n} from \"@ai-sdk/provider\";\nimport { CoderAgentError, CoderChatError } from \"../errors.js\";\nimport { CoderChatClient } from \"../coder/client.js\";\nimport type { CreateChatRequest } from \"../coder/types.js\";\nimport {\n classifyTurnAction,\n dynamicToolNames,\n extractSystemPrompt,\n toolsToDynamicTools,\n} from \"./prompt.js\";\nimport { TurnTranslator } from \"./translate.js\";\n\nconst EMPTY_USAGE: LanguageModelV3Usage = {\n inputTokens: {\n total: undefined,\n noCache: undefined,\n cacheRead: undefined,\n cacheWrite: undefined,\n },\n outputTokens: { total: undefined, text: undefined, reasoning: undefined },\n};\n\nexport interface CoderLanguageModelConfig {\n client: CoderChatClient;\n organizationId: string;\n /** Model hint (UUID, `provider:model`, model id, or display-name substring). */\n model?: string;\n /** Bind the chat to a Coder workspace (enables workspace tools). */\n workspaceId?: string;\n /** chatd-side MCP servers to enable. */\n mcpServerIds?: string[];\n planMode?: \"\" | \"plan\";\n /** Resume an existing chat instead of creating a new one. */\n chatId?: string;\n}\n\n/**\n * A {@link LanguageModelV3} that is backed by a remote Coder `chatd` agent\n * runtime instead of a raw LLM. One model instance owns one chatd chat\n * (a \"session\"): the chat is created lazily on the first turn and reused for\n * subsequent turns and for client-tool resume steps.\n *\n * The chatd server runs the agent loop (model calls, server-side tools,\n * compaction) itself. This model therefore represents *one chatd segment* per\n * `doStream` call — it advances the chat until it settles (`waiting`/\n * `completed`) or pauses for a client tool (`requires_action`). When the AI SDK\n * executes a client tool and calls `doStream` again with the tool result, this\n * model resumes the same chat. The two loops mesh at the client-tool boundary.\n *\n * NOTE: a single model instance is single-flight — do not run concurrent\n * generations against the same instance/session.\n */\nexport class CoderLanguageModel implements LanguageModelV3 {\n readonly specificationVersion = \"v3\" as const;\n readonly provider = \"coder.chatd\";\n readonly modelId: string;\n readonly supportedUrls: Record<string, RegExp[]> = {};\n\n readonly #config: CoderLanguageModelConfig;\n #chatId: string | undefined;\n #lastSeenMessageId = 0;\n #resolvedModelConfigId: string | undefined;\n #modelResolved = false;\n readonly #submittedToolCallIds = new Set<string>();\n #inFlight = false;\n\n constructor(config: CoderLanguageModelConfig) {\n this.#config = config;\n this.modelId = config.model ?? \"chatd\";\n this.#chatId = config.chatId;\n }\n\n get chatId(): string | undefined {\n return this.#chatId;\n }\n\n /** Drops the current session so the next turn creates a fresh chat. */\n resetSession(): void {\n this.#chatId = undefined;\n this.#lastSeenMessageId = 0;\n this.#submittedToolCallIds.clear();\n }\n\n async #resolveModelConfigId(signal?: AbortSignal): Promise<string | undefined> {\n if (this.#modelResolved) return this.#resolvedModelConfigId;\n if (this.#config.model) {\n this.#resolvedModelConfigId = await this.#config.client.resolveModelConfigId(\n this.#config.model,\n signal,\n );\n }\n this.#modelResolved = true;\n return this.#resolvedModelConfigId;\n }\n\n async *#runTurn(\n options: LanguageModelV3CallOptions,\n ): AsyncGenerator<LanguageModelV3StreamPart, void, void> {\n // A single model instance owns one chatd session's mutable state, so it is\n // single-flight: reject overlapping turns rather than silently corrupting\n // chatId / lastSeenMessageId / submitted tool-call tracking.\n if (this.#inFlight) {\n throw new CoderAgentError(\n \"A generation is already in flight on this CoderAgent (single-flight). Use a separate CoderAgent instance for concurrent sessions.\",\n );\n }\n this.#inFlight = true;\n try {\n const { prompt, abortSignal: signal } = options;\n yield { type: \"stream-start\", warnings: [] };\n\n const action = classifyTurnAction(prompt);\n if (action.kind === \"noop\") {\n throw new CoderAgentError(\n \"CoderAgent received a prompt with no user message or tool results to act on.\",\n );\n }\n\n const translator = new TurnTranslator({ dynamicToolNames: dynamicToolNames(options.tools) });\n let afterId: number | undefined;\n\n if (action.kind === \"new-turn\") {\n const modelConfigId = await this.#resolveModelConfigId(signal);\n if (!this.#chatId) {\n const req: CreateChatRequest = {\n organization_id: this.#config.organizationId,\n content: action.content,\n client_type: \"api\",\n };\n const system = extractSystemPrompt(prompt);\n if (system) req.system_prompt = system;\n const tools = toolsToDynamicTools(options.tools);\n if (tools.length > 0) req.unsafe_dynamic_tools = tools;\n if (modelConfigId) req.model_config_id = modelConfigId;\n if (this.#config.workspaceId) req.workspace_id = this.#config.workspaceId;\n if (this.#config.mcpServerIds?.length) req.mcp_server_ids = this.#config.mcpServerIds;\n if (this.#config.planMode) req.plan_mode = this.#config.planMode;\n const chat = await this.#config.client.createChat(req, signal);\n this.#chatId = chat.id;\n afterId = this.#lastSeenMessageId > 0 ? this.#lastSeenMessageId : undefined;\n } else {\n const resp = await this.#config.client.createChatMessage(\n this.#chatId,\n {\n content: action.content,\n ...(modelConfigId ? { model_config_id: modelConfigId } : {}),\n },\n signal,\n );\n afterId = resp.message?.id ?? this.#lastSeenMessageId;\n }\n } else {\n // resume\n if (!this.#chatId)\n throw new CoderChatError({ message: \"cannot submit tool results before a chat exists\" });\n const fresh = action.toolResults.filter(\n (r) => !this.#submittedToolCallIds.has(r.tool_call_id),\n );\n if (fresh.length > 0) {\n await this.#config.client.submitToolResults(this.#chatId, { results: fresh }, signal);\n for (const r of fresh) this.#submittedToolCallIds.add(r.tool_call_id);\n }\n afterId = this.#lastSeenMessageId;\n }\n\n const chatId = this.#chatId as string;\n // chatd emits the `requires_action` status BEFORE the `action_required`\n // event that carries the pending tool calls, so for that status we keep\n // reading until the client tool calls have actually been emitted (bounded\n // by a safety counter, since the stream is a live subscription).\n let sinceRequiresAction = 0;\n for await (const ev of this.#config.client.streamEvents(chatId, { afterId, signal })) {\n for (const part of translator.ingest(ev)) yield part;\n const status = translator.terminalStatus;\n if (status) {\n if (status !== \"requires_action\") break;\n if (translator.clientToolCallSeen) break;\n if (++sinceRequiresAction > 200) break;\n }\n }\n\n if (signal?.aborted && !translator.terminalStatus) {\n throw signal.reason ?? new DOMException(\"The operation was aborted.\", \"AbortError\");\n }\n\n for (const part of translator.finish()) yield part;\n if (translator.maxMessageId > this.#lastSeenMessageId)\n this.#lastSeenMessageId = translator.maxMessageId;\n } finally {\n this.#inFlight = false;\n }\n }\n\n async doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult> {\n const gen = this.#runTurn(options);\n const stream = new ReadableStream<LanguageModelV3StreamPart>({\n async pull(controller) {\n try {\n const { value, done } = await gen.next();\n if (done) controller.close();\n else controller.enqueue(value);\n } catch (err) {\n controller.error(err);\n }\n },\n async cancel() {\n await gen.return();\n },\n });\n return { stream };\n }\n\n async doGenerate(options: LanguageModelV3CallOptions): Promise<LanguageModelV3GenerateResult> {\n const content: LanguageModelV3Content[] = [];\n const textBuf = new Map<string, string>();\n const reasoningBuf = new Map<string, string>();\n let usage: LanguageModelV3Usage = EMPTY_USAGE;\n let finishReason: LanguageModelV3GenerateResult[\"finishReason\"] = {\n unified: \"stop\",\n raw: undefined,\n };\n const warnings: LanguageModelV3GenerateResult[\"warnings\"] = [];\n\n for await (const part of this.#runTurn(options)) {\n switch (part.type) {\n case \"stream-start\":\n warnings.push(...part.warnings);\n break;\n case \"text-start\":\n textBuf.set(part.id, \"\");\n break;\n case \"text-delta\":\n textBuf.set(part.id, (textBuf.get(part.id) ?? \"\") + part.delta);\n break;\n case \"text-end\": {\n const t = textBuf.get(part.id) ?? \"\";\n if (t.length > 0) content.push({ type: \"text\", text: t });\n textBuf.delete(part.id);\n break;\n }\n case \"reasoning-start\":\n reasoningBuf.set(part.id, \"\");\n break;\n case \"reasoning-delta\":\n reasoningBuf.set(part.id, (reasoningBuf.get(part.id) ?? \"\") + part.delta);\n break;\n case \"reasoning-end\": {\n const t = reasoningBuf.get(part.id) ?? \"\";\n if (t.length > 0) content.push({ type: \"reasoning\", text: t });\n reasoningBuf.delete(part.id);\n break;\n }\n case \"tool-call\":\n case \"tool-result\":\n case \"source\":\n case \"file\":\n content.push(part);\n break;\n case \"finish\":\n usage = part.usage;\n finishReason = part.finishReason;\n break;\n case \"error\":\n throw part.error instanceof Error\n ? part.error\n : new CoderChatError({ message: String(part.error) });\n default:\n break;\n }\n }\n\n return { content, finishReason, usage, warnings };\n }\n}\n"],"mappings":";AAAA;AAAA,EAGE;AAAA,EAGA;AAAA,OAEK;;;ACLA,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAChC,OAAO;AAAA,EAChB,YAAY,SAAiB,SAA+B;AAC1D,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;AAGO,IAAM,gBAAN,cAA4B,gBAAgB;AAAA,EACxC,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,YAAY,MAMT;AACD;AAAA,MACE,aAAa,KAAK,MAAM,IAAI,KAAK,IAAI,YAAY,KAAK,MAAM,MAAM,KAAK,OAAO,MAC3E,KAAK,SAAS,WAAM,KAAK,MAAM,KAAK;AAAA,IACzC;AACA,SAAK,SAAS,KAAK;AACnB,SAAK,SAAS,KAAK;AACnB,SAAK,SAAS,KAAK;AACnB,SAAK,OAAO,KAAK;AAAA,EACnB;AACF;AAGO,IAAM,iBAAN,cAA6B,gBAAgB;AAAA,EACzC,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,YAAY,SAA2B;AACrC,UAAM,QAAQ,SAAS,GAAG,QAAQ,OAAO,KAAK,QAAQ,MAAM,KAAK,QAAQ,OAAO;AAChF,SAAK,OAAO,QAAQ;AACpB,SAAK,WAAW,QAAQ;AACxB,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,aAAa,QAAQ;AAAA,EAC5B;AACF;;;ACgQO,IAAM,oBAA6C,oBAAI,IAAgB;AAAA,EAC5E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;ACtTD,OAAO,mBAAmB;AA4B1B,IAAM,iBAAmC,CAAC,KAAK,EAAE,QAAQ,MAAM;AAG7D,SAAO,IAAI,cAAc,KAAK,EAAE,QAAQ,CAAC;AAC3C;AAEA,SAAS,SAAS,SAAyB;AACzC,MAAI,QAAQ,WAAW,UAAU,EAAG,QAAO,SAAS,QAAQ,MAAM,WAAW,MAAM,CAAC;AACpF,MAAI,QAAQ,WAAW,SAAS,EAAG,QAAO,QAAQ,QAAQ,MAAM,UAAU,MAAM,CAAC;AACjF,SAAO;AACT;AAqBA,gBAAuB,iBACrB,SAC6C;AAC7C,QAAM,EAAE,SAAS,OAAO,QAAQ,SAAS,OAAO,IAAI;AACpD,QAAM,UAAU,QAAQ,oBAAoB;AAE5C,QAAM,SAAS,SAAS,OAAO;AAC/B,QAAM,QAAQ,YAAY,SAAY,aAAa,OAAO,KAAK;AAC/D,QAAM,MAAM,GAAG,MAAM,2BAA2B,MAAM,UAAU,KAAK;AAErE,QAAM,QAA2B,CAAC;AAClC,MAAI;AACJ,MAAI,WAAW;AACf,MAAI;AAEJ,QAAM,OAAO,MAAM;AACjB,kBAAc;AACd,kBAAc;AAAA,EAChB;AAEA,QAAM,KAAK,QAAQ,KAAK,EAAE,SAAS,EAAE,uBAAuB,MAAM,EAAE,CAAC;AAErE,QAAM,UAAU,MAAM;AACpB,eAAW;AACX,QAAI;AACF,SAAG,MAAM,GAAI;AAAA,IACf,QAAQ;AAAA,IAER;AACA,SAAK;AAAA,EACP;AACA,MAAI,qBAAqB;AACzB,MAAI,QAAQ;AACV,QAAI,OAAO,QAAS,SAAQ;AAAA,SACvB;AACH,aAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACxD,2BAAqB;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,YAAY,CAAC,OAAgC;AACjD,QAAI,SAAU;AACd,QAAI;AACJ,QAAI;AACF,YAAM,OAAO,OAAO,GAAG,SAAS,WAAW,GAAG,OAAO,OAAO,GAAG,IAAI;AACnE,cAAQ,KAAK,MAAM,IAAI;AAAA,IACzB,SAAS,KAAK;AACZ,gBAAU,IAAI,gBAAgB,qCAAqC,EAAE,OAAO,IAAI,CAAC;AACjF,iBAAW;AACX,WAAK;AACL;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,iBAAW,KAAK,MAAO,OAAM,KAAK,CAAoB;AAAA,IACxD,WAAW,SAAS,OAAO,UAAU,UAAU;AAC7C,YAAM,KAAK,KAAwB;AAAA,IACrC;AACA,SAAK;AAAA,EACP;AACA,QAAM,UAAU,CAAC,OAAsB;AACrC,QAAI,SAAU;AACd,UAAM,UACJ,MAAM,OAAO,OAAO,YAAY,aAAa,KACzC,OAAQ,GAA4B,OAAO,IAC3C;AACN,cAAU,IAAI,gBAAgB,OAAO;AACrC,eAAW;AACX,SAAK;AAAA,EACP;AACA,QAAM,UAAU,MAAY;AAC1B,eAAW;AACX,SAAK;AAAA,EACP;AACA,KAAG,iBAAiB,WAAW,SAAS;AACxC,KAAG,iBAAiB,SAAS,OAAO;AACpC,KAAG,iBAAiB,SAAS,OAAO;AAEpC,MAAI;AACF,WAAO,MAAM;AACX,aAAO,MAAM,SAAS,GAAG;AACvB,cAAM,OAAO,MAAM,MAAM;AACzB,cAAM;AAAA,MACR;AACA,UAAI,QAAS,OAAM;AACnB,UAAI,SAAU;AACd,YAAM,IAAI,QAAc,CAAC,YAAY;AACnC,sBAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF,UAAE;AACA,eAAW;AACX,QAAI,UAAU,mBAAoB,QAAO,oBAAoB,SAAS,OAAO;AAC7E,OAAG,oBAAoB,WAAW,SAAS;AAC3C,OAAG,oBAAoB,SAAS,OAAO;AACvC,OAAG,oBAAoB,SAAS,OAAO;AACvC,QAAI;AACF,SAAG,MAAM,GAAI;AAAA,IACf,QAAQ;AAAA,IAER;AAAA,EACF;AACF;;;ACvIA,IAAM,aAAa;AAMZ,IAAM,kBAAN,MAAsB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAiC;AAE3C,SAAK,UAAU,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAChD,SAAK,SAAS,QAAQ;AACtB,SAAK,SAAS,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;AAC/D,SAAK,oBAAoB,QAAQ;AAAA,EACnC;AAAA,EAEA,MAAM,SACJ,QACA,MACA,MACA,QACY;AACZ,UAAM,UAAkC,EAAE,uBAAuB,KAAK,OAAO;AAC7E,QAAI,SAAS,OAAW,SAAQ,cAAc,IAAI;AAElD,UAAM,MAAM,MAAM,KAAK,OAAO,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MACtD;AAAA,MACA;AAAA,MACA,MAAM,SAAS,SAAY,SAAY,KAAK,UAAU,IAAI;AAAA,MAC1D;AAAA,IACF,CAAC;AAED,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,SAAS,IAAI,KAAK,MAAM,IAAI,IAAI;AAAA,IAChD,QAAQ;AACN,eAAS;AAAA,IACX;AAEA,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,SAAU,UAAU,CAAC;AAC3B,YAAM,IAAI,cAAc;AAAA,QACtB,QAAQ,IAAI;AAAA,QACZ;AAAA,QACA;AAAA,QACA,SAAS,OAAO,WAAW,IAAI,cAAc;AAAA,QAC7C,QAAQ,OAAO;AAAA,MACjB,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,iBAAiB,QAAkD;AACjE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,UAAU;AAAA,MACb;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,KAAwB,QAAqC;AACtE,WAAO,KAAK,SAAe,QAAQ,YAAY,KAAK,MAAM;AAAA,EAC5D;AAAA,EAEA,QAAQ,QAAgB,QAAqC;AAC3D,WAAO,KAAK,SAAe,OAAO,GAAG,UAAU,IAAI,MAAM,IAAI,QAAW,MAAM;AAAA,EAChF;AAAA,EAEA,kBACE,QACA,KACA,QACoC;AACpC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,UAAU,IAAI,MAAM;AAAA,MACvB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YACE,QACA,MACA,QAC+B;AAC/B,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,MAAM,cAAc,OAAW,QAAO,IAAI,aAAa,OAAO,KAAK,SAAS,CAAC;AACjF,QAAI,MAAM,aAAa,OAAW,QAAO,IAAI,YAAY,OAAO,KAAK,QAAQ,CAAC;AAC9E,QAAI,MAAM,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACrE,UAAM,IAAI,OAAO,SAAS;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,UAAU,IAAI,MAAM,YAAY,IAAI,IAAI,CAAC,KAAK,EAAE;AAAA,MACnD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,kBACE,QACA,KACA,QACe;AACf,WAAO,KAAK,SAAe,QAAQ,GAAG,UAAU,IAAI,MAAM,iBAAiB,KAAK,MAAM;AAAA,EACxF;AAAA,EAEA,cAAc,QAAgB,QAAqC;AACjE,WAAO,KAAK,SAAe,QAAQ,GAAG,UAAU,IAAI,MAAM,cAAc,QAAW,MAAM;AAAA,EAC3F;AAAA,EAEA,WAAW,QAAgB,KAAwB,QAAqC;AACtF,WAAO,KAAK,SAAe,SAAS,GAAG,UAAU,IAAI,MAAM,IAAI,KAAK,MAAM;AAAA,EAC5E;AAAA;AAAA,EAGA,YAAY,QAAgB,QAAqC;AAC/D,WAAO,KAAK,WAAW,QAAQ,EAAE,UAAU,KAAK,GAAG,MAAM;AAAA,EAC3D;AAAA;AAAA,EAIA,aACE,QACA,MAC6C;AAC7C,WAAO,iBAAiB;AAAA,MACtB,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,MACZ;AAAA,MACA,SAAS,MAAM;AAAA,MACf,QAAQ,MAAM;AAAA,MACd,kBAAkB,KAAK;AAAA,IACzB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,qBAAqB,MAAc,QAAmD;AAC1F,UAAM,UAAU;AAChB,QAAI,QAAQ,KAAK,IAAI,EAAG,QAAO;AAE/B,UAAM,UAAU,MAAM,KAAK,iBAAiB,MAAM;AAClD,UAAM,QAAQ,KAAK,YAAY;AAE/B,UAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,UAAM,WAAW,SAAS,IAAI,KAAK,MAAM,GAAG,KAAK,EAAE,YAAY,IAAI;AACnE,UAAM,QAAQ,SAAS,IAAI,KAAK,MAAM,QAAQ,CAAC,EAAE,YAAY,IAAI;AAEjE,UAAM,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,KAAK;AAC5D,UAAM,OAAO,WAAW,SAAS,IAAI,aAAa;AAElD,UAAM,QAAQ,KAAK;AAAA,MACjB,CAAC,MACC,EAAE,MAAM,YAAY,MAAM,UACzB,aAAa,UAAa,EAAE,SAAS,YAAY,MAAM;AAAA,IAC5D;AACA,QAAI,MAAO,QAAO,MAAM;AAExB,UAAM,UAAU,KAAK,KAAK,CAAC,MAAM,EAAE,MAAM,YAAY,MAAM,KAAK;AAChE,QAAI,QAAS,QAAO,QAAQ;AAE5B,UAAM,YAAY,KAAK,KAAK,CAAC,MAAM,EAAE,aAAa,YAAY,EAAE,SAAS,KAAK,CAAC;AAC/E,QAAI,UAAW,QAAO,UAAU;AAEhC,UAAM,mBAAmB,KAAK,KAAK,CAAC,MAAM,EAAE,MAAM,YAAY,EAAE,SAAS,KAAK,CAAC;AAC/E,WAAO,kBAAkB;AAAA,EAC3B;AACF;;;ACxMO,SAAS,oBAAoB,QAAmD;AACrF,QAAM,QAAQ,OAAO;AAAA,IACnB,CAAC,MAAgE,EAAE,SAAS;AAAA,EAC9E;AACA,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,SAAS,MACZ,IAAI,CAAC,MAAM,EAAE,OAAO,EACpB,KAAK,MAAM,EACX,KAAK;AACR,SAAO,OAAO,SAAS,IAAI,SAAS;AACtC;AAEA,SAAS,wBACP,SACiB;AACjB,QAAM,MAAuB,CAAC;AAC9B,aAAW,QAAQ,QAAQ,SAAS;AAClC,QAAI,KAAK,SAAS,UAAU,KAAK,KAAK,SAAS,GAAG;AAChD,UAAI,KAAK,EAAE,MAAM,QAAQ,MAAM,KAAK,KAAK,CAAC;AAAA,IAC5C;AAAA,EAEF;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,QAG/B;AACA,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,EAAE,OAAO,OAAO,OAAO,SAAS,MAAM;AAAA,IAC/C,KAAK;AACH,aAAO,EAAE,OAAO,OAAO,OAAO,SAAS,MAAM;AAAA,IAC/C,KAAK;AACH,aAAO,EAAE,OAAO,OAAO,OAAO,SAAS,KAAK;AAAA,IAC9C,KAAK;AACH,aAAO,EAAE,OAAO,OAAO,OAAO,SAAS,KAAK;AAAA,IAC9C,KAAK;AACH,aAAO,EAAE,OAAO,EAAE,kBAAkB,MAAM,QAAQ,OAAO,OAAO,GAAG,SAAS,KAAK;AAAA,IACnF,KAAK;AACH,aAAO,EAAE,OAAO,OAAO,OAAO,SAAS,MAAM;AAAA,IAC/C;AACE,aAAO,EAAE,OAAO,QAAQ,SAAS,MAAM;AAAA,EAC3C;AACF;AAaO,SAAS,mBAAmB,QAA2C;AAC5E,MAAI,OAAO,WAAW,EAAG,QAAO,EAAE,MAAM,OAAO;AAC/C,QAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,MAAI,CAAC,KAAM,QAAO,EAAE,MAAM,OAAO;AAEjC,MAAI,KAAK,SAAS,QAAQ;AACxB,UAAM,cAA4B,CAAC;AAEnC,aAAS,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3C,YAAM,IAAI,OAAO,CAAC;AAClB,UAAI,CAAC,KAAK,EAAE,SAAS,OAAQ;AAC7B,iBAAW,QAAQ,EAAE,SAAS;AAC5B,YAAI,KAAK,SAAS,cAAe;AACjC,cAAM,EAAE,OAAO,QAAQ,IAAI,wBAAwB,KAAK,MAAM;AAC9D,oBAAY,QAAQ,EAAE,cAAc,KAAK,YAAY,QAAQ,OAAO,UAAU,QAAQ,CAAC;AAAA,MACzF;AAAA,IACF;AACA,WAAO,EAAE,MAAM,UAAU,YAAY;AAAA,EACvC;AAEA,MAAI,KAAK,SAAS,QAAQ;AACxB,WAAO,EAAE,MAAM,YAAY,SAAS,wBAAwB,IAAI,EAAE;AAAA,EACpE;AAEA,SAAO,EAAE,MAAM,OAAO;AACxB;AAGO,SAAS,oBAAoB,OAA2D;AAC7F,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,MAAqB,CAAC;AAC5B,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,WAAY;AAC9B,QAAI,KAAK;AAAA,MACP,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,cAAc,KAAK;AAAA,IACrB,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAGO,SAAS,iBAAiB,OAAyD;AACxF,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,QAAQ,SAAS,CAAC,GAAG;AAC9B,QAAI,KAAK,SAAS,WAAY,OAAM,IAAI,KAAK,IAAI;AAAA,EACnD;AACA,SAAO;AACT;;;ACpGA,SAAS,SAAS,GAAuD;AACvE,SAAO;AAAA,IACL,aAAa;AAAA,MACX,OAAO,GAAG;AAAA,MACV,SAAS;AAAA,MACT,WAAW,GAAG;AAAA,MACd,YAAY,GAAG;AAAA,IACjB;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,GAAG;AAAA,MACV,MAAM;AAAA,MACN,WAAW,GAAG;AAAA,IAChB;AAAA,EACF;AACF;AAEA,SAAS,WAAW,OAAsC;AAGxD,SAAQ,SAAS,CAAC;AACpB;AAiBO,IAAM,iBAAN,MAAqB;AAAA,EACjB;AAAA,EAET,OAAO;AAAA,EACP,QAAQ,EAAE,IAAI,QAAiC,KAAK,GAAG,UAAU,MAAM;AAAA,EACvE,aAAa,EAAE,IAAI,QAAiC,KAAK,GAAG,UAAU,MAAM;AAAA,EAC5E;AAAA,EAEA,mBAAmB,oBAAI,IAAY;AAAA,EACnC,qBAAqB,oBAAI,IAAY;AAAA,EACrC,mBAAmB,oBAAI,IAAY;AAAA,EACnC,sBAAsB;AAAA,EAEtB;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAEhB,YAAY,MAAiD;AAC3D,SAAK,oBAAoB,KAAK;AAAA,EAChC;AAAA,EAEA,IAAI,iBAAyC;AAC3C,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAEA,IAAI,qBAA8B;AAChC,WAAO,KAAK;AAAA,EACd;AAAA,EACA,IAAI,eAAuB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EACA,IAAI,QAAsC;AACxC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAIA,UAAU,KAAwC;AAChD,QAAI,KAAK,WAAW,GAAI,MAAK,gBAAgB,GAAG;AAChD,QAAI,CAAC,KAAK,MAAM,IAAI;AAClB,WAAK,MAAM,KAAK,QAAQ,EAAE,KAAK,IAAI;AACnC,WAAK,MAAM,MAAM;AACjB,UAAI,KAAK,EAAE,MAAM,cAAc,IAAI,KAAK,MAAM,GAAG,CAAC;AAAA,IACpD;AAAA,EACF;AAAA,EACA,WAAW,KAAwC;AACjD,QAAI,KAAK,MAAM,IAAI;AACjB,UAAI,KAAK,EAAE,MAAM,YAAY,IAAI,KAAK,MAAM,GAAG,CAAC;AAChD,WAAK,MAAM,KAAK;AAChB,WAAK,MAAM,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EACA,eAAe,KAAwC;AACrD,QAAI,KAAK,MAAM,GAAI,MAAK,WAAW,GAAG;AACtC,QAAI,CAAC,KAAK,WAAW,IAAI;AACvB,WAAK,WAAW,KAAK,aAAa,EAAE,KAAK,IAAI;AAC7C,WAAK,WAAW,MAAM;AACtB,UAAI,KAAK,EAAE,MAAM,mBAAmB,IAAI,KAAK,WAAW,GAAG,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,gBAAgB,KAAwC;AACtD,QAAI,KAAK,WAAW,IAAI;AACtB,UAAI,KAAK,EAAE,MAAM,iBAAiB,IAAI,KAAK,WAAW,GAAG,CAAC;AAC1D,WAAK,WAAW,KAAK;AACrB,WAAK,WAAW,MAAM;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,cAAc,KAAkC,MAAoB;AAClE,QAAI,KAAK,UAAU,KAAK,MAAM,OAAO,KAAK,MAAM,GAAI;AACpD,SAAK,UAAU,GAAG;AAClB,QAAI,KAAK,SAAS,KAAK,MAAM,KAAK;AAChC,UAAI,KAAK;AAAA,QACP,MAAM;AAAA,QACN,IAAI,KAAK,MAAM;AAAA,QACf,OAAO,KAAK,MAAM,KAAK,MAAM,GAAG;AAAA,MAClC,CAAC;AACD,WAAK,MAAM,MAAM,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EACA,mBAAmB,KAAkC,MAAoB;AACvE,QAAI,KAAK,UAAU,KAAK,WAAW,OAAO,KAAK,WAAW,GAAI;AAC9D,SAAK,eAAe,GAAG;AACvB,QAAI,KAAK,SAAS,KAAK,WAAW,KAAK;AACrC,UAAI,KAAK;AAAA,QACP,MAAM;AAAA,QACN,IAAI,KAAK,WAAW;AAAA,QACpB,OAAO,KAAK,MAAM,KAAK,WAAW,GAAG;AAAA,MACvC,CAAC;AACD,WAAK,WAAW,MAAM,KAAK;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA,EAIA,cAAc,MAAmC;AAC/C,WAAO,SAAS,UAAa,KAAK,kBAAkB,IAAI,IAAI;AAAA,EAC9D;AAAA,EAEA,oBAAoB,KAAkC,MAA6B;AACjF,UAAM,KAAK,KAAK;AAChB,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,MAAM,CAAC,KAAM;AAClB,QAAI,KAAK,SAAS,OAAW;AAC7B,QAAI,KAAK,iBAAiB,IAAI,EAAE,EAAG;AACnC,SAAK,iBAAiB,IAAI,EAAE;AAC5B,QAAI,KAAK,EAAE,MAAM,oBAAoB,IAAI,UAAU,MAAM,kBAAkB,KAAK,CAAC;AACjF,QAAI,KAAK,EAAE,MAAM,kBAAkB,GAAG,CAAC;AACvC,QAAI,KAAK;AAAA,MACP,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,KAAK,UAAU,KAAK,IAAI;AAAA,MAC3E,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,sBAAsB,KAAkC,MAA6B;AACnF,UAAM,KAAK,KAAK;AAChB,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,MAAM,CAAC,KAAM;AAClB,QAAI,KAAK,WAAW,OAAW;AAC/B,QAAI,KAAK,mBAAmB,IAAI,EAAE,EAAG;AACrC,SAAK,mBAAmB,IAAI,EAAE;AAC9B,QAAI,KAAK;AAAA,MACP,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,QAAQ,WAAW,KAAK,MAAM;AAAA,MAC9B,SAAS,KAAK,YAAY;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,OAAO,IAAkD;AACvD,UAAM,MAAmC,CAAC;AAC1C,YAAQ,GAAG,MAAM;AAAA,MACf,KAAK;AACH,aAAK,mBAAmB,KAAK,EAAE;AAC/B;AAAA,MACF,KAAK;AACH,YAAI,GAAG,QAAS,MAAK,eAAe,KAAK,GAAG,OAAO;AACnD;AAAA,MACF,KAAK;AACH,mBAAW,MAAM,GAAG,iBAAiB,cAAc,CAAC,GAAG;AACrD,cAAI,KAAK,iBAAiB,IAAI,GAAG,YAAY,EAAG;AAChD,eAAK,WAAW,GAAG;AACnB,eAAK,gBAAgB,GAAG;AACxB,eAAK,iBAAiB,IAAI,GAAG,YAAY;AACzC,eAAK,sBAAsB;AAC3B,cAAI,KAAK,EAAE,MAAM,oBAAoB,IAAI,GAAG,cAAc,UAAU,GAAG,UAAU,CAAC;AAClF,cAAI,KAAK,EAAE,MAAM,kBAAkB,IAAI,GAAG,aAAa,CAAC;AACxD,cAAI,KAAK;AAAA,YACP,MAAM;AAAA,YACN,YAAY,GAAG;AAAA,YACf,UAAU,GAAG;AAAA,YACb,OAAO,GAAG;AAAA,UACZ,CAAC;AAAA,QACH;AACA;AAAA,MACF,KAAK;AACH,YAAI,GAAG,OAAO;AACZ,eAAK,SAAS,GAAG;AACjB,cAAI,KAAK,EAAE,MAAM,SAAS,OAAO,IAAI,eAAe,GAAG,KAAK,EAAE,CAAC;AAAA,QACjE;AACA;AAAA,MACF,KAAK;AACH,YAAI,GAAG,UAAU,kBAAkB,IAAI,GAAG,OAAO,MAAM,GAAG;AACxD,eAAK,kBAAkB,GAAG,OAAO;AAAA,QACnC;AACA;AAAA,MACF;AACE;AAAA,IACJ;AACA,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB,KAAkC,IAA2B;AAC9E,UAAM,KAAK,GAAG;AACd,QAAI,CAAC,MAAO,GAAG,SAAS,eAAe,GAAG,SAAS,OAAS;AAC5D,UAAM,OAAO,GAAG;AAChB,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,aAAK,MAAM,WAAW;AACtB,aAAK,UAAU,GAAG;AAClB,YAAI,KAAK,MAAM;AACb,cAAI,KAAK,EAAE,MAAM,cAAc,IAAI,KAAK,MAAM,IAAc,OAAO,KAAK,KAAK,CAAC;AAC9E,eAAK,MAAM,OAAO,KAAK,KAAK;AAAA,QAC9B;AACA;AAAA,MACF,KAAK;AACH,aAAK,WAAW,WAAW;AAC3B,aAAK,eAAe,GAAG;AACvB,YAAI,KAAK,MAAM;AACb,cAAI,KAAK,EAAE,MAAM,mBAAmB,IAAI,KAAK,WAAW,IAAc,OAAO,KAAK,KAAK,CAAC;AACxF,eAAK,WAAW,OAAO,KAAK,KAAK;AAAA,QACnC;AACA;AAAA,MACF,KAAK;AACH,aAAK,WAAW,GAAG;AACnB,aAAK,gBAAgB,GAAG;AACxB,YAAI,CAAC,KAAK,cAAc,KAAK,SAAS,EAAG,MAAK,oBAAoB,KAAK,IAAI;AAC3E;AAAA,MACF,KAAK;AACH,YAAI,CAAC,KAAK,cAAc,KAAK,SAAS,EAAG,MAAK,sBAAsB,KAAK,IAAI;AAC7E;AAAA,MACF;AACE;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,eAAe,KAAkC,SAA4B;AAC3E,QAAI,QAAQ,KAAK,KAAK,cAAe,MAAK,gBAAgB,QAAQ;AAClE,QAAI,QAAQ,UAAU,QAAQ,SAAS,eAAe,QAAQ,SAAS,SAAS;AAC9E,WAAK,SAAS,QAAQ;AAAA,IACxB;AACA,UAAM,UAAU,QAAQ,WAAW,CAAC;AAEpC,QAAI,QAAQ,SAAS,aAAa;AAEhC,UAAI,KAAK,wBAAwB,UAAa,KAAK,wBAAwB,QAAQ,IAAI;AACrF,aAAK,WAAW,GAAG;AACnB,aAAK,gBAAgB,GAAG;AACxB,aAAK,MAAM,WAAW;AACtB,aAAK,WAAW,WAAW;AAAA,MAC7B;AACA,WAAK,sBAAsB,QAAQ;AAEnC,UAAI,CAAC,KAAK,MAAM,UAAU;AACxB,cAAM,OAAO,QACV,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EACvB,KAAK,EAAE;AACV,YAAI,KAAK,SAAS,EAAG,MAAK,cAAc,KAAK,IAAI;AAAA,MACnD;AACA,UAAI,CAAC,KAAK,WAAW,UAAU;AAC7B,cAAM,OAAO,QACV,OAAO,CAAC,MAAM,EAAE,SAAS,WAAW,EACpC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EACvB,KAAK,EAAE;AACV,YAAI,KAAK,SAAS,EAAG,MAAK,mBAAmB,KAAK,IAAI;AAAA,MACxD;AACA,iBAAW,QAAQ,SAAS;AAC1B,YAAI,KAAK,SAAS,eAAe,CAAC,KAAK,cAAc,KAAK,SAAS;AACjE,eAAK,oBAAoB,KAAK,IAAI;AAAA,iBAC3B,KAAK,SAAS,iBAAiB,CAAC,KAAK,cAAc,KAAK,SAAS;AACxE,eAAK,sBAAsB,KAAK,IAAI;AAAA,MACxC;AAAA,IACF,WAAW,QAAQ,SAAS,QAAQ;AAClC,iBAAW,QAAQ,SAAS;AAC1B,YAAI,KAAK,SAAS,iBAAiB,CAAC,KAAK,cAAc,KAAK,SAAS;AACnE,eAAK,sBAAsB,KAAK,IAAI;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,SAAsC;AACpC,UAAM,MAAmC,CAAC;AAC1C,SAAK,WAAW,GAAG;AACnB,SAAK,gBAAgB,GAAG;AAExB,QAAI;AACJ,QAAI,KAAK,UAAU,KAAK,oBAAoB,QAAS,WAAU;AAAA,aACtD,KAAK,uBAAuB,KAAK,oBAAoB;AAC5D,gBAAU;AAAA,QACP,WAAU;AAEf,QAAI,KAAK;AAAA,MACP,MAAM;AAAA,MACN,OAAO,SAAS,KAAK,MAAM;AAAA,MAC3B,cAAc,EAAE,SAAS,KAAK,KAAK,gBAAgB;AAAA,IACrD,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;ACvTA,IAAM,cAAoC;AAAA,EACxC,aAAa;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,IACT,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAAA,EACA,cAAc,EAAE,OAAO,QAAW,MAAM,QAAW,WAAW,OAAU;AAC1E;AAgCO,IAAM,qBAAN,MAAoD;AAAA,EAChD,uBAAuB;AAAA,EACvB,WAAW;AAAA,EACX;AAAA,EACA,gBAA0C,CAAC;AAAA,EAE3C;AAAA,EACT;AAAA,EACA,qBAAqB;AAAA,EACrB;AAAA,EACA,iBAAiB;AAAA,EACR,wBAAwB,oBAAI,IAAY;AAAA,EACjD,YAAY;AAAA,EAEZ,YAAY,QAAkC;AAC5C,SAAK,UAAU;AACf,SAAK,UAAU,OAAO,SAAS;AAC/B,SAAK,UAAU,OAAO;AAAA,EACxB;AAAA,EAEA,IAAI,SAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,eAAqB;AACnB,SAAK,UAAU;AACf,SAAK,qBAAqB;AAC1B,SAAK,sBAAsB,MAAM;AAAA,EACnC;AAAA,EAEA,MAAM,sBAAsB,QAAmD;AAC7E,QAAI,KAAK,eAAgB,QAAO,KAAK;AACrC,QAAI,KAAK,QAAQ,OAAO;AACtB,WAAK,yBAAyB,MAAM,KAAK,QAAQ,OAAO;AAAA,QACtD,KAAK,QAAQ;AAAA,QACb;AAAA,MACF;AAAA,IACF;AACA,SAAK,iBAAiB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAO,SACL,SACuD;AAIvD,QAAI,KAAK,WAAW;AAClB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,SAAK,YAAY;AACjB,QAAI;AACF,YAAM,EAAE,QAAQ,aAAa,OAAO,IAAI;AACxC,YAAM,EAAE,MAAM,gBAAgB,UAAU,CAAC,EAAE;AAE3C,YAAM,SAAS,mBAAmB,MAAM;AACxC,UAAI,OAAO,SAAS,QAAQ;AAC1B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,aAAa,IAAI,eAAe,EAAE,kBAAkB,iBAAiB,QAAQ,KAAK,EAAE,CAAC;AAC3F,UAAI;AAEJ,UAAI,OAAO,SAAS,YAAY;AAC9B,cAAM,gBAAgB,MAAM,KAAK,sBAAsB,MAAM;AAC7D,YAAI,CAAC,KAAK,SAAS;AACjB,gBAAM,MAAyB;AAAA,YAC7B,iBAAiB,KAAK,QAAQ;AAAA,YAC9B,SAAS,OAAO;AAAA,YAChB,aAAa;AAAA,UACf;AACA,gBAAM,SAAS,oBAAoB,MAAM;AACzC,cAAI,OAAQ,KAAI,gBAAgB;AAChC,gBAAM,QAAQ,oBAAoB,QAAQ,KAAK;AAC/C,cAAI,MAAM,SAAS,EAAG,KAAI,uBAAuB;AACjD,cAAI,cAAe,KAAI,kBAAkB;AACzC,cAAI,KAAK,QAAQ,YAAa,KAAI,eAAe,KAAK,QAAQ;AAC9D,cAAI,KAAK,QAAQ,cAAc,OAAQ,KAAI,iBAAiB,KAAK,QAAQ;AACzE,cAAI,KAAK,QAAQ,SAAU,KAAI,YAAY,KAAK,QAAQ;AACxD,gBAAM,OAAO,MAAM,KAAK,QAAQ,OAAO,WAAW,KAAK,MAAM;AAC7D,eAAK,UAAU,KAAK;AACpB,oBAAU,KAAK,qBAAqB,IAAI,KAAK,qBAAqB;AAAA,QACpE,OAAO;AACL,gBAAM,OAAO,MAAM,KAAK,QAAQ,OAAO;AAAA,YACrC,KAAK;AAAA,YACL;AAAA,cACE,SAAS,OAAO;AAAA,cAChB,GAAI,gBAAgB,EAAE,iBAAiB,cAAc,IAAI,CAAC;AAAA,YAC5D;AAAA,YACA;AAAA,UACF;AACA,oBAAU,KAAK,SAAS,MAAM,KAAK;AAAA,QACrC;AAAA,MACF,OAAO;AAEL,YAAI,CAAC,KAAK;AACR,gBAAM,IAAI,eAAe,EAAE,SAAS,kDAAkD,CAAC;AACzF,cAAM,QAAQ,OAAO,YAAY;AAAA,UAC/B,CAAC,MAAM,CAAC,KAAK,sBAAsB,IAAI,EAAE,YAAY;AAAA,QACvD;AACA,YAAI,MAAM,SAAS,GAAG;AACpB,gBAAM,KAAK,QAAQ,OAAO,kBAAkB,KAAK,SAAS,EAAE,SAAS,MAAM,GAAG,MAAM;AACpF,qBAAW,KAAK,MAAO,MAAK,sBAAsB,IAAI,EAAE,YAAY;AAAA,QACtE;AACA,kBAAU,KAAK;AAAA,MACjB;AAEA,YAAM,SAAS,KAAK;AAKpB,UAAI,sBAAsB;AAC1B,uBAAiB,MAAM,KAAK,QAAQ,OAAO,aAAa,QAAQ,EAAE,SAAS,OAAO,CAAC,GAAG;AACpF,mBAAW,QAAQ,WAAW,OAAO,EAAE,EAAG,OAAM;AAChD,cAAM,SAAS,WAAW;AAC1B,YAAI,QAAQ;AACV,cAAI,WAAW,kBAAmB;AAClC,cAAI,WAAW,mBAAoB;AACnC,cAAI,EAAE,sBAAsB,IAAK;AAAA,QACnC;AAAA,MACF;AAEA,UAAI,QAAQ,WAAW,CAAC,WAAW,gBAAgB;AACjD,cAAM,OAAO,UAAU,IAAI,aAAa,8BAA8B,YAAY;AAAA,MACpF;AAEA,iBAAW,QAAQ,WAAW,OAAO,EAAG,OAAM;AAC9C,UAAI,WAAW,eAAe,KAAK;AACjC,aAAK,qBAAqB,WAAW;AAAA,IACzC,UAAE;AACA,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,SAA2E;AACxF,UAAM,MAAM,KAAK,SAAS,OAAO;AACjC,UAAM,SAAS,IAAI,eAA0C;AAAA,MAC3D,MAAM,KAAK,YAAY;AACrB,YAAI;AACF,gBAAM,EAAE,OAAO,KAAK,IAAI,MAAM,IAAI,KAAK;AACvC,cAAI,KAAM,YAAW,MAAM;AAAA,cACtB,YAAW,QAAQ,KAAK;AAAA,QAC/B,SAAS,KAAK;AACZ,qBAAW,MAAM,GAAG;AAAA,QACtB;AAAA,MACF;AAAA,MACA,MAAM,SAAS;AACb,cAAM,IAAI,OAAO;AAAA,MACnB;AAAA,IACF,CAAC;AACD,WAAO,EAAE,OAAO;AAAA,EAClB;AAAA,EAEA,MAAM,WAAW,SAA6E;AAC5F,UAAM,UAAoC,CAAC;AAC3C,UAAM,UAAU,oBAAI,IAAoB;AACxC,UAAM,eAAe,oBAAI,IAAoB;AAC7C,QAAI,QAA8B;AAClC,QAAI,eAA8D;AAAA,MAChE,SAAS;AAAA,MACT,KAAK;AAAA,IACP;AACA,UAAM,WAAsD,CAAC;AAE7D,qBAAiB,QAAQ,KAAK,SAAS,OAAO,GAAG;AAC/C,cAAQ,KAAK,MAAM;AAAA,QACjB,KAAK;AACH,mBAAS,KAAK,GAAG,KAAK,QAAQ;AAC9B;AAAA,QACF,KAAK;AACH,kBAAQ,IAAI,KAAK,IAAI,EAAE;AACvB;AAAA,QACF,KAAK;AACH,kBAAQ,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,EAAE,KAAK,MAAM,KAAK,KAAK;AAC9D;AAAA,QACF,KAAK,YAAY;AACf,gBAAM,IAAI,QAAQ,IAAI,KAAK,EAAE,KAAK;AAClC,cAAI,EAAE,SAAS,EAAG,SAAQ,KAAK,EAAE,MAAM,QAAQ,MAAM,EAAE,CAAC;AACxD,kBAAQ,OAAO,KAAK,EAAE;AACtB;AAAA,QACF;AAAA,QACA,KAAK;AACH,uBAAa,IAAI,KAAK,IAAI,EAAE;AAC5B;AAAA,QACF,KAAK;AACH,uBAAa,IAAI,KAAK,KAAK,aAAa,IAAI,KAAK,EAAE,KAAK,MAAM,KAAK,KAAK;AACxE;AAAA,QACF,KAAK,iBAAiB;AACpB,gBAAM,IAAI,aAAa,IAAI,KAAK,EAAE,KAAK;AACvC,cAAI,EAAE,SAAS,EAAG,SAAQ,KAAK,EAAE,MAAM,aAAa,MAAM,EAAE,CAAC;AAC7D,uBAAa,OAAO,KAAK,EAAE;AAC3B;AAAA,QACF;AAAA,QACA,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH,kBAAQ,KAAK,IAAI;AACjB;AAAA,QACF,KAAK;AACH,kBAAQ,KAAK;AACb,yBAAe,KAAK;AACpB;AAAA,QACF,KAAK;AACH,gBAAM,KAAK,iBAAiB,QACxB,KAAK,QACL,IAAI,eAAe,EAAE,SAAS,OAAO,KAAK,KAAK,EAAE,CAAC;AAAA,QACxD;AACE;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,cAAc,OAAO,SAAS;AAAA,EAClD;AACF;;;APxQA,IAAM,eAAe,YAAY,EAAE;AAwD5B,IAAM,aAAN,MAAmF;AAAA,EAC/E,UAAU;AAAA,EAEV;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,UAAqC;AAC/C,QAAI,SAAS,QAAQ;AACnB,WAAK,UAAU,SAAS;AAAA,IAC1B,WAAW,SAAS,WAAW,SAAS,OAAO;AAC7C,WAAK,UAAU,IAAI,gBAAgB;AAAA,QACjC,SAAS,SAAS;AAAA,QAClB,OAAO,SAAS;AAAA,QAChB,OAAO,SAAS;AAAA,QAChB,kBAAkB,SAAS;AAAA,MAC7B,CAAC;AAAA,IACH,OAAO;AACL,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,SAAS,IAAI,mBAAmB;AAAA,MACnC,QAAQ,KAAK;AAAA,MACb,gBAAgB,SAAS;AAAA,MACzB,OAAO,SAAS;AAAA,MAChB,aAAa,SAAS;AAAA,MACtB,cAAc,SAAS;AAAA,MACvB,UAAU,SAAS;AAAA,MACnB,QAAQ,SAAS;AAAA,IACnB,CAAC;AAED,SAAK,SAAS,IAAI,cAAmC;AAAA,MACnD,OAAO,KAAK;AAAA,MACZ,IAAI,SAAS;AAAA,MACb,cAAc,SAAS;AAAA,MACvB,OAAO,SAAS;AAAA,MAChB,YAAY,SAAS;AAAA,MACrB,UAAU,SAAS,YAAY;AAAA,MAC/B,YAAY,SAAS,cAAc;AAAA,IACrC,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,KAAyB;AAC3B,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,QAAe;AACjB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA,EAGA,IAAI,SAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,SAA6B;AAC/B,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,SACE,SAC2C;AAC3C,WAAO,KAAK,OAAO,SAAS,OAAO;AAAA,EACrC;AAAA,EAEA,OACE,SACyC;AACzC,WAAO,KAAK,OAAO,OAAO,OAAO;AAAA,EACnC;AAAA;AAAA;AAAA,EAKA,eAAqB;AACnB,SAAK,OAAO,aAAa;AAAA,EAC3B;AAAA;AAAA,EAGA,MAAM,YAA2B;AAC/B,UAAM,KAAK,KAAK,OAAO;AACvB,QAAI,GAAI,OAAM,KAAK,QAAQ,cAAc,EAAE;AAAA,EAC7C;AAAA;AAAA,EAGA,MAAM,UAAyB;AAC7B,UAAM,KAAK,KAAK,OAAO;AACvB,QAAI,GAAI,OAAM,KAAK,QAAQ,YAAY,EAAE;AAAA,EAC3C;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@coder/ai-sdk-agent",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A Vercel AI SDK-compliant agent backed by Coder Agents, Coder's server-side agent runtime. `new CoderAgent()` returns a real AI SDK Agent (generate/stream).",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agent",
|
|
7
|
+
"ai",
|
|
8
|
+
"ai-sdk",
|
|
9
|
+
"coder",
|
|
10
|
+
"llm",
|
|
11
|
+
"streaming",
|
|
12
|
+
"tools",
|
|
13
|
+
"vercel-ai-sdk"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/coder/ai-sdk/tree/main/packages/agent#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/coder/ai-sdk/issues"
|
|
18
|
+
},
|
|
19
|
+
"license": "Apache-2.0",
|
|
20
|
+
"author": "Coder Technologies, Inc. (https://coder.com)",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/coder/ai-sdk.git",
|
|
24
|
+
"directory": "packages/agent"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"type": "module",
|
|
31
|
+
"sideEffects": false,
|
|
32
|
+
"main": "./dist/index.js",
|
|
33
|
+
"module": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"exports": {
|
|
36
|
+
".": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"import": "./dist/index.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"ws": "^8.18.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@ai-sdk/provider": "3.0.10",
|
|
49
|
+
"@ai-sdk/react": "3.0.208",
|
|
50
|
+
"@types/node": "^25.9.3",
|
|
51
|
+
"@types/ws": "^8.18.1",
|
|
52
|
+
"ai": "^6.0.206",
|
|
53
|
+
"tsup": "^8.5.1",
|
|
54
|
+
"tsx": "^4.22.4",
|
|
55
|
+
"typescript": "^6.0.3",
|
|
56
|
+
"vitest": "^4.1.8",
|
|
57
|
+
"zod": "4.4.3"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"ai": "^6.0.0",
|
|
61
|
+
"zod": "^3.23.0 || ^4.0.0"
|
|
62
|
+
},
|
|
63
|
+
"peerDependenciesMeta": {
|
|
64
|
+
"zod": {
|
|
65
|
+
"optional": true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"engines": {
|
|
69
|
+
"node": ">=20"
|
|
70
|
+
},
|
|
71
|
+
"scripts": {
|
|
72
|
+
"build": "tsup",
|
|
73
|
+
"typecheck": "tsc --noEmit",
|
|
74
|
+
"test": "vitest run test/unit",
|
|
75
|
+
"test:unit": "vitest run test/unit",
|
|
76
|
+
"test:e2e": "vitest run test/e2e",
|
|
77
|
+
"test:watch": "vitest",
|
|
78
|
+
"example:generate": "tsx examples/01-generate.ts",
|
|
79
|
+
"example:stream": "tsx examples/02-stream.ts",
|
|
80
|
+
"example:tool": "tsx examples/03-custom-tool.ts",
|
|
81
|
+
"example:multi-turn": "tsx examples/04-multi-turn.ts"
|
|
82
|
+
}
|
|
83
|
+
}
|