agent-framework-js 0.3.0 → 0.4.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +6 -0
  3. package/dist/{chunk-PYIZ4PT3.js → chunk-3KU76DCP.js} +3 -3
  4. package/dist/{chunk-PYIZ4PT3.js.map → chunk-3KU76DCP.js.map} +1 -1
  5. package/dist/{chunk-IHMPSELC.cjs → chunk-5KC6X2T5.cjs} +5 -5
  6. package/dist/{chunk-IHMPSELC.cjs.map → chunk-5KC6X2T5.cjs.map} +1 -1
  7. package/dist/{chunk-XMDGLQFL.cjs → chunk-JLPLGU7O.cjs} +15 -3
  8. package/dist/chunk-JLPLGU7O.cjs.map +1 -0
  9. package/dist/{chunk-FOTCUNP5.cjs → chunk-N64ZFATA.cjs} +5 -2
  10. package/dist/chunk-N64ZFATA.cjs.map +1 -0
  11. package/dist/{chunk-ACBIHS5H.js → chunk-QXAJ4DUJ.js} +5 -2
  12. package/dist/chunk-QXAJ4DUJ.js.map +1 -0
  13. package/dist/{chunk-YH5746OF.js → chunk-QYG4HLIC.js} +3 -3
  14. package/dist/{chunk-YH5746OF.js.map → chunk-QYG4HLIC.js.map} +1 -1
  15. package/dist/{chunk-GYDY3KX5.cjs → chunk-U3ULJMNH.cjs} +4 -4
  16. package/dist/{chunk-GYDY3KX5.cjs.map → chunk-U3ULJMNH.cjs.map} +1 -1
  17. package/dist/{chunk-QD2FFISV.js → chunk-YVJGF4HQ.js} +16 -4
  18. package/dist/chunk-YVJGF4HQ.js.map +1 -0
  19. package/dist/index.cjs +31 -31
  20. package/dist/index.d.cts +5 -0
  21. package/dist/index.d.ts +5 -0
  22. package/dist/index.js +4 -4
  23. package/dist/mcp/index.cjs +4 -4
  24. package/dist/mcp/index.js +2 -2
  25. package/dist/persistence/index.cjs +5 -5
  26. package/dist/persistence/index.js +2 -2
  27. package/dist/providers/index.cjs +7 -6
  28. package/dist/providers/index.d.cts +10 -0
  29. package/dist/providers/index.d.ts +10 -0
  30. package/dist/providers/index.js +2 -1
  31. package/package.json +7 -7
  32. package/dist/chunk-ACBIHS5H.js.map +0 -1
  33. package/dist/chunk-FOTCUNP5.cjs.map +0 -1
  34. package/dist/chunk-QD2FFISV.js.map +0 -1
  35. package/dist/chunk-XMDGLQFL.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/providers/provider.ts","../src/providers/retry.ts","../src/providers/openai-compatible.ts","../src/providers/copilot.ts"],"names":[],"mappings":"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","file":"chunk-YVJGF4HQ.js","sourcesContent":["/**\n * LLM provider abstraction. Agents and workflows depend only on this interface,\n * never on a concrete provider, so new providers can be added without changing\n * agent/workflow code. (FR-007)\n *\n * Credentials are always obtained via a caller-supplied callback and are never\n * bundled, persisted, or logged by the framework. (FR-005a, FR-008)\n *\n * @packageDocumentation\n */\n\nimport type { Message, ModelCapabilities } from \"../core/types.js\";\nimport { ValidationError } from \"../core/errors.js\";\n\n/** A caller-supplied source of credentials. The framework never stores the value. */\nexport interface CredentialSource {\n\t/** Return the current credential (token/api key). May be async. */\n\tgetCredential(): string | Promise<string>;\n}\n\n/**\n * Model configuration for a provider. A provider may expose **one or more** models\n * (e.g. GitHub Copilot offers several; an OpenAI-compatible endpoint is usually one).\n * Supply either a single `capabilities` object or an array via `models`.\n */\nexport interface ModelSelectionOptions {\n\t/** Single-model shorthand. */\n\tcapabilities?: ModelCapabilities;\n\t/** One or more models this provider can use. */\n\tmodels?: ModelCapabilities[];\n\t/** Name of the default model (defaults to the first entry). */\n\tdefaultModel?: string;\n}\n\n/** Resolved model set with a default and a lookup helper. */\nexport interface ResolvedModels {\n\t/** All configured models (at least one). */\n\tmodels: ModelCapabilities[];\n\t/** The default model used when a request does not specify one. */\n\tdefaultModel: ModelCapabilities;\n\t/** Look up a model by name, or return the default when omitted. */\n\tmodelOf(name?: string): ModelCapabilities;\n}\n\n/**\n * Normalize {@link ModelSelectionOptions} into a model list, a default, and a\n * lookup helper. Throws {@link ValidationError} if no model is configured or a\n * named model is missing.\n *\n * @example\n * ```ts\n * const { defaultModel, modelOf } = resolveModels({\n * models: [\n * { model: \"gpt-4o\", maxInputTokens: 128000, maxOutputTokens: 16000 },\n * { model: \"o3-mini\", maxInputTokens: 200000, maxOutputTokens: 100000, supportsReasoning: true },\n * ],\n * defaultModel: \"gpt-4o\",\n * });\n * ```\n */\nexport function resolveModels(options: ModelSelectionOptions): ResolvedModels {\n\tconst models = options.models ?? (options.capabilities ? [options.capabilities] : []);\n\tif (models.length === 0) {\n\t\tthrow new ValidationError(\"Provider requires at least one model (set `capabilities` or `models`)\");\n\t}\n\tconst defaultModel = options.defaultModel\n\t\t? models.find((m) => m.model === options.defaultModel)\n\t\t: models[0];\n\tif (!defaultModel) {\n\t\tthrow new ValidationError(`defaultModel \"${options.defaultModel}\" is not present in models`);\n\t}\n\tconst modelOf = (name?: string): ModelCapabilities => {\n\t\tif (!name) return defaultModel;\n\t\tconst found = models.find((m) => m.model === name);\n\t\tif (!found) {\n\t\t\tthrow new ValidationError(`Model \"${name}\" is not configured for this provider`);\n\t\t}\n\t\treturn found;\n\t};\n\treturn { models, defaultModel, modelOf };\n}\n\n/** A tool description passed to the provider so the model can decide to call it. */\nexport interface ToolSpec {\n\tname: string;\n\tdescription: string;\n\tinputSchema: Record<string, unknown>;\n}\n\n/** A request to generate a model response. */\nexport interface GenerateRequest {\n\tmessages: Message[];\n\ttools?: ToolSpec[];\n\t/** Which configured model to use; defaults to the provider's default model. */\n\tmodel?: string;\n\t/** Abort signal to cancel an in-flight request. */\n\tsignal?: AbortSignal;\n}\n\n/** A tool call requested by the model. */\nexport interface ToolCall {\n\tid: string;\n\tname: string;\n\t/** Raw JSON arguments (validated by the tools module before invocation). */\n\targuments: unknown;\n}\n\n/** A complete (non-streaming) model response. */\nexport interface GenerateResponse {\n\t/** Final answer text. */\n\ttext: string;\n\t/** Reasoning/thinking content — only present for reasoning-capable models. (FR-003a) */\n\treasoning?: string;\n\t/**\n\t * Opaque reasoning blob (e.g. Claude thinking signature) to round-trip on the\n\t * next assistant turn for thinking continuity. Never logged or inspected.\n\t */\n\treasoningOpaque?: string;\n\t/** Tool calls the model wants to make, if any. */\n\ttoolCalls?: ToolCall[];\n\t/** Approximate token usage if reported by the provider. */\n\tusage?: { inputTokens?: number; outputTokens?: number };\n}\n\n/** An incremental streaming chunk. */\nexport type GenerateChunk =\n\t| { type: \"text\"; text: string }\n\t| { type: \"reasoning\"; text: string }\n\t| { type: \"tool-call\"; toolCall: ToolCall }\n\t| { type: \"done\"; response: GenerateResponse };\n\n/**\n * An LLM backend. Implementations adapt a concrete API (Copilot, OpenAI-compatible)\n * onto this uniform surface.\n */\nexport interface Provider {\n\t/** Stable provider identifier, e.g. `\"openai-compatible\"`. */\n\treadonly name: string;\n\t/** The default model's capability configuration. (FR-007a) */\n\treadonly capabilities: ModelCapabilities;\n\t/** All models this provider is configured with (one or more). */\n\treadonly models: ModelCapabilities[];\n\t/** Look up a configured model by name, or the default when omitted. */\n\tmodel(name?: string): ModelCapabilities;\n\t/** Generate a complete response. */\n\tgenerate(req: GenerateRequest): Promise<GenerateResponse>;\n\t/** Generate a streamed response. */\n\tgenerateStream(req: GenerateRequest): AsyncIterable<GenerateChunk>;\n}\n","/**\n * Exponential-backoff retry for transient provider failures. Transient errors\n * (429 with Retry-After, 5xx, network/timeout) are retried; auth/4xx fail fast.\n * (FR-008a)\n *\n * @packageDocumentation\n */\n\nimport { ProviderError } from \"../core/errors.js\";\n\n/** Retry tuning. All fields have safe defaults. */\nexport interface RetryOptions {\n\t/** Maximum retry attempts after the first try. Default 3. */\n\tmaxRetries?: number;\n\t/** Base delay in ms for backoff. Default 250. */\n\tbaseDelayMs?: number;\n\t/** Maximum delay cap in ms. Default 8000. */\n\tmaxDelayMs?: number;\n}\n\nconst DEFAULTS: Required<RetryOptions> = {\n\tmaxRetries: 3,\n\tbaseDelayMs: 250,\n\tmaxDelayMs: 8000,\n};\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((r) => setTimeout(r, ms));\n}\n\n/**\n * Run `fn`, retrying transient {@link ProviderError}s with exponential backoff\n * and jitter. Non-transient errors are rethrown immediately (fail fast).\n *\n * @param fn - The operation to attempt. It should throw a {@link ProviderError}.\n * @param opts - Retry tuning.\n * @param retryAfterMs - Optional hook returning a server-specified delay (Retry-After).\n */\nexport async function withRetry<T>(\n\tfn: () => Promise<T>,\n\topts?: RetryOptions,\n\tretryAfterMs?: (err: ProviderError) => number | undefined,\n): Promise<T> {\n\tconst cfg = { ...DEFAULTS, ...opts };\n\tlet attempt = 0;\n\n\tfor (; ;) {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (err) {\n\t\t\tconst isRetryable = err instanceof ProviderError && err.retryable;\n\t\t\tif (!isRetryable || attempt >= cfg.maxRetries) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tconst serverDelay = retryAfterMs?.(err as ProviderError);\n\t\t\tconst backoff = Math.min(cfg.baseDelayMs * 2 ** attempt, cfg.maxDelayMs);\n\t\t\tconst jitter = Math.random() * cfg.baseDelayMs;\n\t\t\tawait sleep(serverDelay ?? backoff + jitter);\n\t\t\tattempt++;\n\t\t}\n\t}\n}\n\n/** Map an HTTP status to a {@link ProviderError} with the right retry semantics. */\nexport function providerErrorFromStatus(status: number, message: string): ProviderError {\n\tif (status === 429 || status >= 500) {\n\t\treturn new ProviderError(message, \"transient\", { status });\n\t}\n\tif (status === 401 || status === 403) {\n\t\treturn new ProviderError(message, \"auth\", { status });\n\t}\n\treturn new ProviderError(message, \"client\", { status });\n}\n","/**\n * OpenAI-compatible provider. Targets any endpoint speaking the OpenAI\n * `/chat/completions` API, including local servers such as LM Studio via a custom\n * `baseUrl`, and GitHub Copilot (see {@link createCopilotProvider}). (FR-006)\n *\n * Provider compatibility notes (handled here so callers don't have to):\n * - Tool names are sanitized to `^[a-zA-Z0-9_-]+$` on the wire (OpenAI/Copilot\n * reject dotted names like `webiq.browse`) and translated back to the registry\n * key when the model calls them.\n * - Assistant turns that requested tools emit `tool_calls` with `content: null`\n * so strict providers (e.g. Anthropic) can pair each tool result with its call.\n * - Streaming responses accumulate `delta.tool_calls[]` keyed by `index`\n * (fragments may start at a non-zero index when reasoning occupies 0/1).\n * - Some reasoning models report `finish_reason: \"tool_calls\"` from the\n * non-streaming endpoint without a `tool_calls` array; `generate` transparently\n * re-requests in streaming mode and assembles them, failing loud (typed\n * {@link ProviderError}) rather than silently stopping if none materialize.\n *\n * @packageDocumentation\n */\n\nimport type { Message, ContentPart, MessageToolCall } from \"../core/types.js\";\nimport { ProviderError } from \"../core/errors.js\";\nimport type {\n\tProvider,\n\tCredentialSource,\n\tGenerateRequest,\n\tGenerateResponse,\n\tGenerateChunk,\n\tToolCall,\n\tToolSpec,\n} from \"./provider.js\";\nimport { resolveModels, type ModelSelectionOptions } from \"./provider.js\";\nimport { withRetry, providerErrorFromStatus, type RetryOptions } from \"./retry.js\";\n\n/**\n * Options for {@link createOpenAICompatibleProvider}.\n *\n * Supply a single model via `capabilities`, or multiple via `models` (most\n * OpenAI-compatible endpoints expose one model, but multiple are supported).\n */\nexport interface OpenAICompatibleProviderOptions extends CredentialSource, ModelSelectionOptions {\n\t/** Base URL of the OpenAI-compatible API, e.g. `http://localhost:1234/v1`. */\n\tbaseUrl: string;\n\t/**\n\t * Extra request headers merged into every call (e.g. provider-required\n\t * identification headers). The `authorization` header is always set from\n\t * `getCredential()` and cannot be overridden here.\n\t */\n\theaders?: Record<string, string>;\n\t/** Retry tuning for transient failures. */\n\tretry?: RetryOptions;\n\t/** Optional custom fetch (for testing or non-standard runtimes). */\n\tfetchImpl?: typeof fetch;\n}\n\ninterface OpenAIMessage {\n\trole: string;\n\tcontent: unknown;\n\ttool_calls?: Array<{ id: string; type: \"function\"; function: { name: string; arguments: string } }>;\n\ttool_call_id?: string;\n\tname?: string;\n\treasoning_opaque?: string;\n}\n\n/** OpenAI/Copilot require tool names to match `^[a-zA-Z0-9_-]{1,128}$`. */\nconst UNSAFE_TOOL_NAME_CHARS = /[^a-zA-Z0-9_-]/g;\n\n/**\n * Sanitize a (possibly namespaced) tool name for the wire. Dotted MCP names like\n * `webiq.browse` become `webiq_browse`; the original is recovered via the\n * per-request name map when the model calls the tool.\n */\nfunction sanitizeToolName(name: string): string {\n\treturn name.replace(UNSAFE_TOOL_NAME_CHARS, \"_\");\n}\n\nfunction toOpenAIContent(parts: ContentPart[]): unknown {\n\tif (parts.every((p) => p.type === \"text\")) {\n\t\treturn parts.map((p) => (p as { text: string }).text).join(\"\");\n\t}\n\treturn parts.map((p) =>\n\t\tp.type === \"text\"\n\t\t\t? { type: \"text\", text: p.text }\n\t\t\t: { type: \"image_url\", image_url: { url: p.data } },\n\t);\n}\n\nfunction toWireToolCalls(\n\ttoolCalls: MessageToolCall[],\n): Array<{ id: string; type: \"function\"; function: { name: string; arguments: string } }> {\n\treturn toolCalls.map((tc) => ({\n\t\tid: tc.id,\n\t\ttype: \"function\",\n\t\tfunction: {\n\t\t\tname: sanitizeToolName(tc.name),\n\t\t\targuments:\n\t\t\t\ttypeof tc.arguments === \"string\" ? tc.arguments : JSON.stringify(tc.arguments ?? {}),\n\t\t},\n\t}));\n}\n\nfunction toOpenAIMessages(messages: Message[]): OpenAIMessage[] {\n\treturn messages.map((m) => {\n\t\tconst msg: OpenAIMessage = { role: m.role, content: toOpenAIContent(m.parts) };\n\t\tif (m.toolCalls && m.toolCalls.length > 0) {\n\t\t\tmsg.tool_calls = toWireToolCalls(m.toolCalls);\n\t\t\t// Strict providers require `content: null` (not \"\") on an assistant turn\n\t\t\t// that only carries tool calls.\n\t\t\tconst hasText = m.parts.some((p) => p.type === \"text\" && p.text.length > 0);\n\t\t\tif (!hasText) msg.content = null;\n\t\t}\n\t\tif (m.toolCallId) msg.tool_call_id = m.toolCallId;\n\t\tif (m.name) msg.name = sanitizeToolName(m.name);\n\t\tif (m.reasoningOpaque) msg.reasoning_opaque = m.reasoningOpaque;\n\t\treturn msg;\n\t});\n}\n\n/** Wire tool specs plus a map from sanitized name back to the registry key. */\ninterface WireTools {\n\ttools?: Array<{ type: \"function\"; function: { name: string; description: string; parameters: unknown } }>;\n\tnameMap: Map<string, string>;\n}\n\nfunction buildWireTools(specs?: ToolSpec[]): WireTools {\n\tconst nameMap = new Map<string, string>();\n\tif (!specs || specs.length === 0) return { tools: undefined, nameMap };\n\tconst tools = specs.map((t) => {\n\t\tconst wireName = sanitizeToolName(t.name);\n\t\tnameMap.set(wireName, t.name);\n\t\treturn {\n\t\t\ttype: \"function\" as const,\n\t\t\tfunction: { name: wireName, description: t.description, parameters: t.inputSchema },\n\t\t};\n\t});\n\treturn { tools, nameMap };\n}\n\n/**\n * Create an OpenAI-compatible provider (works with LM Studio, vLLM, etc.).\n *\n * @example\n * ```ts\n * const provider = createOpenAICompatibleProvider({\n * baseUrl: \"http://localhost:1234/v1\",\n * getCredential: () => process.env.LMSTUDIO_KEY ?? \"\",\n * capabilities: { model: \"local\", maxInputTokens: 262144, maxOutputTokens: 32000 },\n * });\n * ```\n */\nexport function createOpenAICompatibleProvider(\n\toptions: OpenAICompatibleProviderOptions,\n): Provider {\n\tconst doFetch = options.fetchImpl ?? globalThis.fetch;\n\tconst url = `${options.baseUrl.replace(/\\/$/, \"\")}/chat/completions`;\n\tconst { models, defaultModel, modelOf } = resolveModels(options);\n\n\tasync function authHeaders(): Promise<Record<string, string>> {\n\t\tconst cred = await options.getCredential();\n\t\t// content-type first, then caller headers (may override it), then the\n\t\t// credential-derived authorization which always wins.\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"content-type\": \"application/json\",\n\t\t\t...(options.headers ?? {}),\n\t\t};\n\t\tif (cred) headers[\"authorization\"] = `Bearer ${cred}`;\n\t\treturn headers;\n\t}\n\n\tfunction body(req: GenerateRequest, stream: boolean, wire: WireTools): string {\n\t\treturn JSON.stringify({\n\t\t\tmodel: modelOf(req.model).model,\n\t\t\tmessages: toOpenAIMessages(req.messages),\n\t\t\tstream,\n\t\t\t...(wire.tools ? { tools: wire.tools } : {}),\n\t\t});\n\t}\n\n\tfunction parseToolCalls(raw: unknown, nameMap: Map<string, string>): ToolCall[] | undefined {\n\t\tconst calls = (raw as {\n\t\t\ttool_calls?: Array<{ id: string; function: { name: string; arguments: string } }>;\n\t\t})?.tool_calls;\n\t\tif (!calls || calls.length === 0) return undefined;\n\t\treturn calls.map((c) => ({\n\t\t\tid: c.id,\n\t\t\tname: nameMap.get(c.function.name) ?? c.function.name,\n\t\t\targuments: safeJson(c.function.arguments),\n\t\t}));\n\t}\n\n\tasync function generate(req: GenerateRequest): Promise<GenerateResponse> {\n\t\treturn withRetry(async () => {\n\t\t\tconst wire = buildWireTools(req.tools);\n\t\t\tlet res: Response;\n\t\t\ttry {\n\t\t\t\tres = await doFetch(url, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: await authHeaders(),\n\t\t\t\t\tbody: body(req, false, wire),\n\t\t\t\t\tsignal: req.signal,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tthrow new ProviderError(`Network error: ${(e as Error).message}`, \"transient\");\n\t\t\t}\n\t\t\tif (!res.ok) throw providerErrorFromStatus(res.status, `Provider returned ${res.status}`);\n\n\t\t\tlet json: Record<string, unknown>;\n\t\t\ttry {\n\t\t\t\tjson = (await res.json()) as Record<string, unknown>;\n\t\t\t} catch {\n\t\t\t\tthrow new ProviderError(\"Malformed provider response\", \"malformed\");\n\t\t\t}\n\t\t\tconst choice = (\n\t\t\t\tjson[\"choices\"] as Array<{ message: Record<string, unknown>; finish_reason?: string }>\n\t\t\t)?.[0];\n\t\t\tif (!choice) throw new ProviderError(\"Provider returned no choices\", \"malformed\");\n\t\t\tconst message = choice.message;\n\t\t\tconst reasoningModel = modelOf(req.model).supportsReasoning;\n\t\t\tlet toolCalls = parseToolCalls(message, wire.nameMap);\n\n\t\t\t// Bug 4(b): some reasoning models report `finish_reason: \"tool_calls\"` from\n\t\t\t// the non-streaming endpoint without a `tool_calls` array. Re-request in\n\t\t\t// streaming mode and assemble them so the agent loop can proceed.\n\t\t\tif ((!toolCalls || toolCalls.length === 0) && choice.finish_reason === \"tool_calls\") {\n\t\t\t\tconst assembled = await assembleViaStream(req);\n\t\t\t\ttoolCalls = assembled.toolCalls;\n\t\t\t\tif (!toolCalls || toolCalls.length === 0) {\n\t\t\t\t\tthrow new ProviderError(\n\t\t\t\t\t\t\"Provider signaled tool_calls but returned none (even when streamed)\",\n\t\t\t\t\t\t\"malformed\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\ttext: (message[\"content\"] as string) ?? assembled.text ?? \"\",\n\t\t\t\t\treasoning: reasoningModel\n\t\t\t\t\t\t? ((message[\"reasoning\"] as string) ?? assembled.reasoning ?? undefined)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\treasoningOpaque: reasoningModel\n\t\t\t\t\t\t? ((message[\"reasoning_opaque\"] as string) ?? assembled.reasoningOpaque ?? undefined)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\ttoolCalls,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttext: (message[\"content\"] as string) ?? \"\",\n\t\t\t\treasoning: reasoningModel ? ((message[\"reasoning\"] as string) ?? undefined) : undefined,\n\t\t\t\treasoningOpaque: reasoningModel\n\t\t\t\t\t? ((message[\"reasoning_opaque\"] as string) ?? undefined)\n\t\t\t\t\t: undefined,\n\t\t\t\ttoolCalls,\n\t\t\t};\n\t\t}, options.retry);\n\t}\n\n\t/** Drive a streaming request to completion and return its assembled final response. */\n\tasync function assembleViaStream(req: GenerateRequest): Promise<GenerateResponse> {\n\t\tlet final: GenerateResponse = { text: \"\" };\n\t\tfor await (const chunk of generateStream(req)) {\n\t\t\tif (chunk.type === \"done\") final = chunk.response;\n\t\t}\n\t\treturn final;\n\t}\n\n\tasync function* generateStream(req: GenerateRequest): AsyncIterable<GenerateChunk> {\n\t\tconst wire = buildWireTools(req.tools);\n\t\tlet res: Response;\n\t\ttry {\n\t\t\tres = await doFetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: await authHeaders(),\n\t\t\t\tbody: body(req, true, wire),\n\t\t\t\tsignal: req.signal,\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tthrow new ProviderError(`Network error: ${(e as Error).message}`, \"transient\");\n\t\t}\n\t\tif (!res.ok) throw providerErrorFromStatus(res.status, `Provider returned ${res.status}`);\n\t\tif (!res.body) throw new ProviderError(\"Provider returned no stream body\", \"malformed\");\n\n\t\tconst reasoningModel = modelOf(req.model).supportsReasoning;\n\t\tconst reader = res.body.getReader();\n\t\tconst decoder = new TextDecoder();\n\t\tlet buffer = \"\";\n\t\tlet text = \"\";\n\t\tlet reasoning = \"\";\n\t\tlet reasoningOpaque = \"\";\n\t\t// Accumulate streamed tool-call fragments keyed by their `index` (which may\n\t\t// start at a non-zero value when reasoning deltas occupy the first indices).\n\t\tconst toolAccum = new Map<number, { id?: string; name?: string; args: string }>();\n\n\t\tfor (; ;) {\n\t\t\tconst { value, done } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t\tconst lines = buffer.split(\"\\n\");\n\t\t\tbuffer = lines.pop() ?? \"\";\n\t\t\tfor (const line of lines) {\n\t\t\t\tconst trimmed = line.trim();\n\t\t\t\tif (!trimmed.startsWith(\"data:\")) continue;\n\t\t\t\tconst data = trimmed.slice(5).trim();\n\t\t\t\tif (data === \"[DONE]\") continue;\n\t\t\t\tconst parsed = safeJson(data) as\n\t\t\t\t\t| {\n\t\t\t\t\t\tchoices?: Array<{\n\t\t\t\t\t\t\tdelta?: {\n\t\t\t\t\t\t\t\tcontent?: string;\n\t\t\t\t\t\t\t\treasoning?: string;\n\t\t\t\t\t\t\t\treasoning_opaque?: string;\n\t\t\t\t\t\t\t\ttool_calls?: Array<{\n\t\t\t\t\t\t\t\t\tindex?: number;\n\t\t\t\t\t\t\t\t\tid?: string;\n\t\t\t\t\t\t\t\t\tfunction?: { name?: string; arguments?: string };\n\t\t\t\t\t\t\t\t}>;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}>;\n\t\t\t\t\t}\n\t\t\t\t\t| undefined;\n\t\t\t\tconst delta = parsed?.choices?.[0]?.delta;\n\t\t\t\tif (!delta) continue;\n\t\t\t\tif (delta.content) {\n\t\t\t\t\ttext += delta.content;\n\t\t\t\t\tyield { type: \"text\", text: delta.content };\n\t\t\t\t}\n\t\t\t\tif (delta.reasoning && reasoningModel) {\n\t\t\t\t\treasoning += delta.reasoning;\n\t\t\t\t\tyield { type: \"reasoning\", text: delta.reasoning };\n\t\t\t\t}\n\t\t\t\tif (delta.reasoning_opaque && reasoningModel) {\n\t\t\t\t\treasoningOpaque += delta.reasoning_opaque;\n\t\t\t\t}\n\t\t\t\tif (delta.tool_calls) {\n\t\t\t\t\tfor (const frag of delta.tool_calls) {\n\t\t\t\t\t\tconst idx = frag.index ?? 0;\n\t\t\t\t\t\tconst slot = toolAccum.get(idx) ?? { args: \"\" };\n\t\t\t\t\t\tif (frag.id) slot.id = frag.id;\n\t\t\t\t\t\tif (frag.function?.name) slot.name = frag.function.name;\n\t\t\t\t\t\tif (frag.function?.arguments) slot.args += frag.function.arguments;\n\t\t\t\t\t\ttoolAccum.set(idx, slot);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Materialize accumulated tool calls (sorted by stream index) and surface\n\t\t// them both as chunks and in the final `done` response.\n\t\tconst toolCalls: ToolCall[] = [...toolAccum.entries()]\n\t\t\t.sort((a, b) => a[0] - b[0])\n\t\t\t.filter(([, s]) => s.name)\n\t\t\t.map(([idx, s]) => ({\n\t\t\t\tid: s.id ?? `call_${idx}`,\n\t\t\t\tname: wire.nameMap.get(s.name as string) ?? (s.name as string),\n\t\t\t\targuments: safeJson(s.args) ?? {},\n\t\t\t}));\n\t\tfor (const toolCall of toolCalls) {\n\t\t\tyield { type: \"tool-call\", toolCall };\n\t\t}\n\t\tyield {\n\t\t\ttype: \"done\",\n\t\t\tresponse: {\n\t\t\t\ttext,\n\t\t\t\treasoning: reasoning || undefined,\n\t\t\t\treasoningOpaque: reasoningOpaque || undefined,\n\t\t\t\ttoolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n\t\t\t},\n\t\t};\n\t}\n\n\treturn {\n\t\tname: \"openai-compatible\",\n\t\tcapabilities: defaultModel,\n\t\tmodels,\n\t\tmodel: modelOf,\n\t\tgenerate,\n\t\tgenerateStream,\n\t};\n}\n\nfunction safeJson(s: string): unknown {\n\ttry {\n\t\treturn JSON.parse(s);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n","/**\n * GitHub Copilot provider. (FR-005)\n *\n * Copilot's chat API is OpenAI-compatible, so this provider configures the shared\n * OpenAI-compatible transport with Copilot's endpoint and the caller-supplied\n * credential (a Copilot/GitHub token). The token is obtained via callback and is\n * never bundled, persisted, or logged. (FR-005a)\n *\n * In a frontend-only deployment the end user supplies their own token (it stays\n * client-side); in a backend deployment the developer may supply it, or the user\n * sends it per request over SSL/TLS and the backend must not log or persist it.\n *\n * Note: the Copilot API (`api.githubcopilot.com`) sends no CORS headers, so it\n * cannot be called directly from a browser. A browser deployment must route through\n * a backend/proxy (set `baseUrl` to it); constructing this provider in a browser\n * against the default host throws {@link RuntimeUnsupportedError}.\n *\n * @packageDocumentation\n */\n\nimport type { Provider, CredentialSource, ModelSelectionOptions } from \"./provider.js\";\nimport type { RetryOptions } from \"./retry.js\";\nimport { createOpenAICompatibleProvider } from \"./openai-compatible.js\";\nimport { detectRuntime } from \"../core/runtime.js\";\nimport { RuntimeUnsupportedError } from \"../core/errors.js\";\n\n/** Default Copilot-compatible chat completions base URL. */\nconst DEFAULT_COPILOT_BASE_URL = \"https://api.githubcopilot.com\";\n\n/**\n * Headers `api.githubcopilot.com` requires on every request. Omitting any of\n * these causes the API to reject the call with HTTP 400. They are sent by default\n * and can be overridden per option via `headers`.\n */\nconst COPILOT_DEFAULT_HEADERS: Record<string, string> = {\n\t\"Editor-Version\": \"vscode/1.95.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.20.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n\t\"Openai-Intent\": \"conversation-panel\",\n};\n\n/**\n * Options for {@link createCopilotProvider}.\n *\n * GitHub Copilot exposes several models, so configure them via `models` (with an\n * optional `defaultModel`). A single `capabilities` object is also accepted.\n */\nexport interface CopilotProviderOptions extends CredentialSource, ModelSelectionOptions {\n\t/** Override the Copilot base URL if needed. */\n\tbaseUrl?: string;\n\t/**\n\t * Extra/override request headers. Merged over the required Copilot defaults\n\t * (`Editor-Version`, `Editor-Plugin-Version`, `Copilot-Integration-Id`,\n\t * `Openai-Intent`), so you can adjust them without losing the others.\n\t */\n\theaders?: Record<string, string>;\n\t/** Retry tuning for transient failures. */\n\tretry?: RetryOptions;\n\t/** Optional custom fetch (for testing or non-standard runtimes). */\n\tfetchImpl?: typeof fetch;\n}\n\n/**\n * Create a GitHub Copilot provider.\n *\n * @example Single model\n * ```ts\n * const provider = createCopilotProvider({\n * getCredential: () => myCopilotToken, // never logged or persisted\n * capabilities: { model: \"gpt-4o\", maxInputTokens: 128000, maxOutputTokens: 16000 },\n * });\n * ```\n *\n * @example Multiple models\n * ```ts\n * const provider = createCopilotProvider({\n * getCredential: () => myCopilotToken,\n * models: [\n * { model: \"gpt-4o\", maxInputTokens: 128000, maxOutputTokens: 16000, supportsVision: true },\n * { model: \"o3-mini\", maxInputTokens: 200000, maxOutputTokens: 100000, supportsReasoning: true },\n * ],\n * defaultModel: \"gpt-4o\",\n * });\n * // Pick a model per request: provider.generate({ messages, model: \"o3-mini\" })\n * ```\n *\n * @throws {RuntimeUnsupportedError} when constructed in a browser against the\n * default Copilot host. `api.githubcopilot.com` does not send CORS headers, so a\n * browser cannot call it directly — host a small backend/proxy and point `baseUrl`\n * at it (which lifts this guard), or run the provider server-side (Node/edge).\n */\nexport function createCopilotProvider(options: CopilotProviderOptions): Provider {\n\tconst baseUrl = options.baseUrl ?? DEFAULT_COPILOT_BASE_URL;\n\n\t// Frontend-only guard: the Copilot API has no CORS support, so a browser must\n\t// route through a backend/proxy. Setting a custom `baseUrl` (your proxy) is the\n\t// supported opt-in and lifts this guard. Edge/Node (server-side) are unaffected.\n\tconst usingDefaultHost = baseUrl === DEFAULT_COPILOT_BASE_URL;\n\tif (usingDefaultHost && detectRuntime().isBrowser) {\n\t\tthrow new RuntimeUnsupportedError(\n\t\t\t\"GitHub Copilot directly from a browser (the Copilot API sends no CORS headers)\",\n\t\t\t{\n\t\t\t\treason: \"cors\",\n\t\t\t\tremedy:\n\t\t\t\t\t\"Run a lightweight backend/proxy (e.g. a Vite dev-server proxy or a small server route) \" +\n\t\t\t\t\t\"that forwards to https://api.githubcopilot.com, then set `baseUrl` to your proxy URL. \" +\n\t\t\t\t\t\"Alternatively, run the Copilot provider server-side (Node or an edge function).\",\n\t\t\t},\n\t\t);\n\t}\n\n\tconst inner = createOpenAICompatibleProvider({\n\t\tbaseUrl,\n\t\tgetCredential: options.getCredential,\n\t\tcapabilities: options.capabilities,\n\t\tmodels: options.models,\n\t\tdefaultModel: options.defaultModel,\n\t\t// Copilot rejects calls missing its identification headers; defaults are\n\t\t// applied here and remain overridable via `options.headers`.\n\t\theaders: { ...COPILOT_DEFAULT_HEADERS, ...(options.headers ?? {}) },\n\t\tretry: options.retry,\n\t\tfetchImpl: options.fetchImpl,\n\t});\n\t// Preserve the provider contract but report the Copilot name.\n\treturn {\n\t\tname: \"copilot\",\n\t\tcapabilities: inner.capabilities,\n\t\tmodels: inner.models,\n\t\tmodel: inner.model.bind(inner),\n\t\tgenerate: inner.generate.bind(inner),\n\t\tgenerateStream: inner.generateStream.bind(inner),\n\t};\n}\n"]}
package/dist/index.cjs CHANGED
@@ -9,12 +9,12 @@ var chunkWSMYH2IN_cjs = require('./chunk-WSMYH2IN.cjs');
9
9
  var chunkTAMJ5HSR_cjs = require('./chunk-TAMJ5HSR.cjs');
10
10
  var chunkKEI3EALJ_cjs = require('./chunk-KEI3EALJ.cjs');
11
11
  var chunkFSDMBWQV_cjs = require('./chunk-FSDMBWQV.cjs');
12
+ var chunkU3ULJMNH_cjs = require('./chunk-U3ULJMNH.cjs');
12
13
  var chunkV6O6SYAN_cjs = require('./chunk-V6O6SYAN.cjs');
13
- var chunkGYDY3KX5_cjs = require('./chunk-GYDY3KX5.cjs');
14
- var chunkIHMPSELC_cjs = require('./chunk-IHMPSELC.cjs');
14
+ var chunk5KC6X2T5_cjs = require('./chunk-5KC6X2T5.cjs');
15
15
  var chunkI55OVD23_cjs = require('./chunk-I55OVD23.cjs');
16
- var chunkFOTCUNP5_cjs = require('./chunk-FOTCUNP5.cjs');
17
- var chunkXMDGLQFL_cjs = require('./chunk-XMDGLQFL.cjs');
16
+ var chunkJLPLGU7O_cjs = require('./chunk-JLPLGU7O.cjs');
17
+ var chunkN64ZFATA_cjs = require('./chunk-N64ZFATA.cjs');
18
18
  var chunkMQ2XTH3S_cjs = require('./chunk-MQ2XTH3S.cjs');
19
19
  var chunkIJASUMIQ_cjs = require('./chunk-IJASUMIQ.cjs');
20
20
 
@@ -112,6 +112,14 @@ Object.defineProperty(exports, "composeMiddleware", {
112
112
  enumerable: true,
113
113
  get: function () { return chunkFSDMBWQV_cjs.composeMiddleware; }
114
114
  });
115
+ Object.defineProperty(exports, "connectMCP", {
116
+ enumerable: true,
117
+ get: function () { return chunkU3ULJMNH_cjs.connectMCP; }
118
+ });
119
+ Object.defineProperty(exports, "mcpToolToTool", {
120
+ enumerable: true,
121
+ get: function () { return chunkU3ULJMNH_cjs.mcpToolToTool; }
122
+ });
115
123
  Object.defineProperty(exports, "configureObservability", {
116
124
  enumerable: true,
117
125
  get: function () { return chunkV6O6SYAN_cjs.configureObservability; }
@@ -128,25 +136,17 @@ Object.defineProperty(exports, "withSpan", {
128
136
  enumerable: true,
129
137
  get: function () { return chunkV6O6SYAN_cjs.withSpan; }
130
138
  });
131
- Object.defineProperty(exports, "connectMCP", {
132
- enumerable: true,
133
- get: function () { return chunkGYDY3KX5_cjs.connectMCP; }
134
- });
135
- Object.defineProperty(exports, "mcpToolToTool", {
136
- enumerable: true,
137
- get: function () { return chunkGYDY3KX5_cjs.mcpToolToTool; }
138
- });
139
139
  Object.defineProperty(exports, "ThreadPersistence", {
140
140
  enumerable: true,
141
- get: function () { return chunkIHMPSELC_cjs.ThreadPersistence; }
141
+ get: function () { return chunk5KC6X2T5_cjs.ThreadPersistence; }
142
142
  });
143
143
  Object.defineProperty(exports, "createBrowserStore", {
144
144
  enumerable: true,
145
- get: function () { return chunkIHMPSELC_cjs.createBrowserStore; }
145
+ get: function () { return chunk5KC6X2T5_cjs.createBrowserStore; }
146
146
  });
147
147
  Object.defineProperty(exports, "createMemoryStore", {
148
148
  enumerable: true,
149
- get: function () { return chunkIHMPSELC_cjs.createMemoryStore; }
149
+ get: function () { return chunk5KC6X2T5_cjs.createMemoryStore; }
150
150
  });
151
151
  Object.defineProperty(exports, "Thread", {
152
152
  enumerable: true,
@@ -168,37 +168,37 @@ Object.defineProperty(exports, "textMessage", {
168
168
  enumerable: true,
169
169
  get: function () { return chunkI55OVD23_cjs.textMessage; }
170
170
  });
171
- Object.defineProperty(exports, "detectRuntime", {
171
+ Object.defineProperty(exports, "createCopilotProvider", {
172
172
  enumerable: true,
173
- get: function () { return chunkFOTCUNP5_cjs.detectRuntime; }
173
+ get: function () { return chunkJLPLGU7O_cjs.createCopilotProvider; }
174
174
  });
175
- Object.defineProperty(exports, "requireCapability", {
175
+ Object.defineProperty(exports, "createOpenAICompatibleProvider", {
176
176
  enumerable: true,
177
- get: function () { return chunkFOTCUNP5_cjs.requireCapability; }
177
+ get: function () { return chunkJLPLGU7O_cjs.createOpenAICompatibleProvider; }
178
178
  });
179
- Object.defineProperty(exports, "resetRuntimeCache", {
179
+ Object.defineProperty(exports, "providerErrorFromStatus", {
180
180
  enumerable: true,
181
- get: function () { return chunkFOTCUNP5_cjs.resetRuntimeCache; }
181
+ get: function () { return chunkJLPLGU7O_cjs.providerErrorFromStatus; }
182
182
  });
183
- Object.defineProperty(exports, "createCopilotProvider", {
183
+ Object.defineProperty(exports, "resolveModels", {
184
184
  enumerable: true,
185
- get: function () { return chunkXMDGLQFL_cjs.createCopilotProvider; }
185
+ get: function () { return chunkJLPLGU7O_cjs.resolveModels; }
186
186
  });
187
- Object.defineProperty(exports, "createOpenAICompatibleProvider", {
187
+ Object.defineProperty(exports, "withRetry", {
188
188
  enumerable: true,
189
- get: function () { return chunkXMDGLQFL_cjs.createOpenAICompatibleProvider; }
189
+ get: function () { return chunkJLPLGU7O_cjs.withRetry; }
190
190
  });
191
- Object.defineProperty(exports, "providerErrorFromStatus", {
191
+ Object.defineProperty(exports, "detectRuntime", {
192
192
  enumerable: true,
193
- get: function () { return chunkXMDGLQFL_cjs.providerErrorFromStatus; }
193
+ get: function () { return chunkN64ZFATA_cjs.detectRuntime; }
194
194
  });
195
- Object.defineProperty(exports, "resolveModels", {
195
+ Object.defineProperty(exports, "requireCapability", {
196
196
  enumerable: true,
197
- get: function () { return chunkXMDGLQFL_cjs.resolveModels; }
197
+ get: function () { return chunkN64ZFATA_cjs.requireCapability; }
198
198
  });
199
- Object.defineProperty(exports, "withRetry", {
199
+ Object.defineProperty(exports, "resetRuntimeCache", {
200
200
  enumerable: true,
201
- get: function () { return chunkXMDGLQFL_cjs.withRetry; }
201
+ get: function () { return chunkN64ZFATA_cjs.resetRuntimeCache; }
202
202
  });
203
203
  Object.defineProperty(exports, "CheckpointError", {
204
204
  enumerable: true,
package/dist/index.d.cts CHANGED
@@ -34,6 +34,11 @@ interface RuntimeCapabilities {
34
34
  hasIndexedDB: boolean;
35
35
  /** Running under Node.js. */
36
36
  isNode: boolean;
37
+ /**
38
+ * Running inside a web browser (has `window`/`document`). Distinguished from
39
+ * edge runtimes, which also lack Node but make server-side (CORS-free) requests.
40
+ */
41
+ isBrowser: boolean;
37
42
  }
38
43
  /** Detect the current runtime's capabilities (memoized). */
39
44
  declare function detectRuntime(): RuntimeCapabilities;
package/dist/index.d.ts CHANGED
@@ -34,6 +34,11 @@ interface RuntimeCapabilities {
34
34
  hasIndexedDB: boolean;
35
35
  /** Running under Node.js. */
36
36
  isNode: boolean;
37
+ /**
38
+ * Running inside a web browser (has `window`/`document`). Distinguished from
39
+ * edge runtimes, which also lack Node but make server-side (CORS-free) requests.
40
+ */
41
+ isBrowser: boolean;
37
42
  }
38
43
  /** Detect the current runtime's capabilities (memoized). */
39
44
  declare function detectRuntime(): RuntimeCapabilities;
package/dist/index.js CHANGED
@@ -7,12 +7,12 @@ export { SkillIndex, defineSkill, loadSource } from './chunk-YCBDEEAV.js';
7
7
  export { ToolRegistry, namespacedName, validateArgs } from './chunk-HGEPXJDG.js';
8
8
  export { useMiddleware } from './chunk-IUKD54F7.js';
9
9
  export { composeMiddleware } from './chunk-7ZXUIHLH.js';
10
+ export { connectMCP, mcpToolToTool } from './chunk-QYG4HLIC.js';
10
11
  export { configureObservability, isObservabilityEnabled, resetObservability, withSpan } from './chunk-5PDJOBTD.js';
11
- export { connectMCP, mcpToolToTool } from './chunk-YH5746OF.js';
12
- export { ThreadPersistence, createBrowserStore, createMemoryStore } from './chunk-PYIZ4PT3.js';
12
+ export { ThreadPersistence, createBrowserStore, createMemoryStore } from './chunk-3KU76DCP.js';
13
13
  export { Thread, estimateTokens, hasImage, messageText, textMessage } from './chunk-LC54DGGR.js';
14
- export { detectRuntime, requireCapability, resetRuntimeCache } from './chunk-ACBIHS5H.js';
15
- export { createCopilotProvider, createOpenAICompatibleProvider, providerErrorFromStatus, resolveModels, withRetry } from './chunk-QD2FFISV.js';
14
+ export { createCopilotProvider, createOpenAICompatibleProvider, providerErrorFromStatus, resolveModels, withRetry } from './chunk-YVJGF4HQ.js';
15
+ export { detectRuntime, requireCapability, resetRuntimeCache } from './chunk-QXAJ4DUJ.js';
16
16
  export { CheckpointError, FrameworkError, MCPError, ProviderError, RuntimeUnsupportedError, ToolError, ValidationError } from './chunk-IXV4UIF5.js';
17
17
  export { REDACTED, redact } from './chunk-DEABART4.js';
18
18
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkGYDY3KX5_cjs = require('../chunk-GYDY3KX5.cjs');
4
- require('../chunk-FOTCUNP5.cjs');
3
+ var chunkU3ULJMNH_cjs = require('../chunk-U3ULJMNH.cjs');
4
+ require('../chunk-N64ZFATA.cjs');
5
5
  require('../chunk-MQ2XTH3S.cjs');
6
6
  require('../chunk-IJASUMIQ.cjs');
7
7
 
@@ -9,11 +9,11 @@ require('../chunk-IJASUMIQ.cjs');
9
9
 
10
10
  Object.defineProperty(exports, "connectMCP", {
11
11
  enumerable: true,
12
- get: function () { return chunkGYDY3KX5_cjs.connectMCP; }
12
+ get: function () { return chunkU3ULJMNH_cjs.connectMCP; }
13
13
  });
14
14
  Object.defineProperty(exports, "mcpToolToTool", {
15
15
  enumerable: true,
16
- get: function () { return chunkGYDY3KX5_cjs.mcpToolToTool; }
16
+ get: function () { return chunkU3ULJMNH_cjs.mcpToolToTool; }
17
17
  });
18
18
  //# sourceMappingURL=index.cjs.map
19
19
  //# sourceMappingURL=index.cjs.map
package/dist/mcp/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export { connectMCP, mcpToolToTool } from '../chunk-YH5746OF.js';
2
- import '../chunk-ACBIHS5H.js';
1
+ export { connectMCP, mcpToolToTool } from '../chunk-QYG4HLIC.js';
2
+ import '../chunk-QXAJ4DUJ.js';
3
3
  import '../chunk-IXV4UIF5.js';
4
4
  import '../chunk-DEABART4.js';
5
5
  //# sourceMappingURL=index.js.map
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkIHMPSELC_cjs = require('../chunk-IHMPSELC.cjs');
3
+ var chunk5KC6X2T5_cjs = require('../chunk-5KC6X2T5.cjs');
4
4
  require('../chunk-I55OVD23.cjs');
5
- require('../chunk-FOTCUNP5.cjs');
5
+ require('../chunk-N64ZFATA.cjs');
6
6
  require('../chunk-MQ2XTH3S.cjs');
7
7
  require('../chunk-IJASUMIQ.cjs');
8
8
 
@@ -10,15 +10,15 @@ require('../chunk-IJASUMIQ.cjs');
10
10
 
11
11
  Object.defineProperty(exports, "ThreadPersistence", {
12
12
  enumerable: true,
13
- get: function () { return chunkIHMPSELC_cjs.ThreadPersistence; }
13
+ get: function () { return chunk5KC6X2T5_cjs.ThreadPersistence; }
14
14
  });
15
15
  Object.defineProperty(exports, "createBrowserStore", {
16
16
  enumerable: true,
17
- get: function () { return chunkIHMPSELC_cjs.createBrowserStore; }
17
+ get: function () { return chunk5KC6X2T5_cjs.createBrowserStore; }
18
18
  });
19
19
  Object.defineProperty(exports, "createMemoryStore", {
20
20
  enumerable: true,
21
- get: function () { return chunkIHMPSELC_cjs.createMemoryStore; }
21
+ get: function () { return chunk5KC6X2T5_cjs.createMemoryStore; }
22
22
  });
23
23
  //# sourceMappingURL=index.cjs.map
24
24
  //# sourceMappingURL=index.cjs.map
@@ -1,6 +1,6 @@
1
- export { ThreadPersistence, createBrowserStore, createMemoryStore } from '../chunk-PYIZ4PT3.js';
1
+ export { ThreadPersistence, createBrowserStore, createMemoryStore } from '../chunk-3KU76DCP.js';
2
2
  import '../chunk-LC54DGGR.js';
3
- import '../chunk-ACBIHS5H.js';
3
+ import '../chunk-QXAJ4DUJ.js';
4
4
  import '../chunk-IXV4UIF5.js';
5
5
  import '../chunk-DEABART4.js';
6
6
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkXMDGLQFL_cjs = require('../chunk-XMDGLQFL.cjs');
3
+ var chunkJLPLGU7O_cjs = require('../chunk-JLPLGU7O.cjs');
4
+ require('../chunk-N64ZFATA.cjs');
4
5
  require('../chunk-MQ2XTH3S.cjs');
5
6
  require('../chunk-IJASUMIQ.cjs');
6
7
 
@@ -8,23 +9,23 @@ require('../chunk-IJASUMIQ.cjs');
8
9
 
9
10
  Object.defineProperty(exports, "createCopilotProvider", {
10
11
  enumerable: true,
11
- get: function () { return chunkXMDGLQFL_cjs.createCopilotProvider; }
12
+ get: function () { return chunkJLPLGU7O_cjs.createCopilotProvider; }
12
13
  });
13
14
  Object.defineProperty(exports, "createOpenAICompatibleProvider", {
14
15
  enumerable: true,
15
- get: function () { return chunkXMDGLQFL_cjs.createOpenAICompatibleProvider; }
16
+ get: function () { return chunkJLPLGU7O_cjs.createOpenAICompatibleProvider; }
16
17
  });
17
18
  Object.defineProperty(exports, "providerErrorFromStatus", {
18
19
  enumerable: true,
19
- get: function () { return chunkXMDGLQFL_cjs.providerErrorFromStatus; }
20
+ get: function () { return chunkJLPLGU7O_cjs.providerErrorFromStatus; }
20
21
  });
21
22
  Object.defineProperty(exports, "resolveModels", {
22
23
  enumerable: true,
23
- get: function () { return chunkXMDGLQFL_cjs.resolveModels; }
24
+ get: function () { return chunkJLPLGU7O_cjs.resolveModels; }
24
25
  });
25
26
  Object.defineProperty(exports, "withRetry", {
26
27
  enumerable: true,
27
- get: function () { return chunkXMDGLQFL_cjs.withRetry; }
28
+ get: function () { return chunkJLPLGU7O_cjs.withRetry; }
28
29
  });
29
30
  //# sourceMappingURL=index.cjs.map
30
31
  //# sourceMappingURL=index.cjs.map
@@ -99,6 +99,11 @@ declare function createOpenAICompatibleProvider(options: OpenAICompatibleProvide
99
99
  * client-side); in a backend deployment the developer may supply it, or the user
100
100
  * sends it per request over SSL/TLS and the backend must not log or persist it.
101
101
  *
102
+ * Note: the Copilot API (`api.githubcopilot.com`) sends no CORS headers, so it
103
+ * cannot be called directly from a browser. A browser deployment must route through
104
+ * a backend/proxy (set `baseUrl` to it); constructing this provider in a browser
105
+ * against the default host throws {@link RuntimeUnsupportedError}.
106
+ *
102
107
  * @packageDocumentation
103
108
  */
104
109
 
@@ -145,6 +150,11 @@ interface CopilotProviderOptions extends CredentialSource, ModelSelectionOptions
145
150
  * });
146
151
  * // Pick a model per request: provider.generate({ messages, model: "o3-mini" })
147
152
  * ```
153
+ *
154
+ * @throws {RuntimeUnsupportedError} when constructed in a browser against the
155
+ * default Copilot host. `api.githubcopilot.com` does not send CORS headers, so a
156
+ * browser cannot call it directly — host a small backend/proxy and point `baseUrl`
157
+ * at it (which lifts this guard), or run the provider server-side (Node/edge).
148
158
  */
149
159
  declare function createCopilotProvider(options: CopilotProviderOptions): Provider;
150
160
 
@@ -99,6 +99,11 @@ declare function createOpenAICompatibleProvider(options: OpenAICompatibleProvide
99
99
  * client-side); in a backend deployment the developer may supply it, or the user
100
100
  * sends it per request over SSL/TLS and the backend must not log or persist it.
101
101
  *
102
+ * Note: the Copilot API (`api.githubcopilot.com`) sends no CORS headers, so it
103
+ * cannot be called directly from a browser. A browser deployment must route through
104
+ * a backend/proxy (set `baseUrl` to it); constructing this provider in a browser
105
+ * against the default host throws {@link RuntimeUnsupportedError}.
106
+ *
102
107
  * @packageDocumentation
103
108
  */
104
109
 
@@ -145,6 +150,11 @@ interface CopilotProviderOptions extends CredentialSource, ModelSelectionOptions
145
150
  * });
146
151
  * // Pick a model per request: provider.generate({ messages, model: "o3-mini" })
147
152
  * ```
153
+ *
154
+ * @throws {RuntimeUnsupportedError} when constructed in a browser against the
155
+ * default Copilot host. `api.githubcopilot.com` does not send CORS headers, so a
156
+ * browser cannot call it directly — host a small backend/proxy and point `baseUrl`
157
+ * at it (which lifts this guard), or run the provider server-side (Node/edge).
148
158
  */
149
159
  declare function createCopilotProvider(options: CopilotProviderOptions): Provider;
150
160
 
@@ -1,4 +1,5 @@
1
- export { createCopilotProvider, createOpenAICompatibleProvider, providerErrorFromStatus, resolveModels, withRetry } from '../chunk-QD2FFISV.js';
1
+ export { createCopilotProvider, createOpenAICompatibleProvider, providerErrorFromStatus, resolveModels, withRetry } from '../chunk-YVJGF4HQ.js';
2
+ import '../chunk-QXAJ4DUJ.js';
2
3
  import '../chunk-IXV4UIF5.js';
3
4
  import '../chunk-DEABART4.js';
4
5
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-framework-js",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Modular, tree-shakeable JavaScript/TypeScript agent framework for no-backend deployments (browser, edge, Node). Agents, tools, MCP, skills, multi-agent workflows, middleware, persistence, and OpenTelemetry observability.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -130,16 +130,16 @@
130
130
  }
131
131
  },
132
132
  "devDependencies": {
133
+ "@eslint/js": "^10.0.0",
133
134
  "@modelcontextprotocol/sdk": "^1.0.0",
134
135
  "@opentelemetry/api": "^1.9.0",
135
- "@types/node": "^20.14.0",
136
- "@typescript-eslint/eslint-plugin": "^7.16.0",
137
- "@typescript-eslint/parser": "^7.16.0",
138
- "eslint": "^8.57.0",
136
+ "@types/node": "^25.0.0",
137
+ "eslint": "^10.0.0",
139
138
  "prettier": "^3.3.0",
140
139
  "tsup": "^8.2.0",
141
- "typescript": "^5.5.0",
142
- "vitest": "^2.0.0",
140
+ "typescript": "^6.0.0",
141
+ "typescript-eslint": "^8.61.0",
142
+ "vitest": "^4.0.0",
143
143
  "yaml": "^2.5.0"
144
144
  }
145
145
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/runtime.ts"],"names":[],"mappings":";;;AAuBA,IAAI,MAAA;AAGG,SAAS,aAAA,GAAqC;AACpD,EAAA,IAAI,QAAQ,OAAO,MAAA;AAEnB,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,MAAM,IAAA,GAAO,EAAE,SAAS,CAAA;AACxB,EAAA,MAAM,SAAS,OAAO,IAAA,KAAS,eAAe,CAAC,CAAC,KAAK,QAAA,EAAU,IAAA;AAE/D,EAAA,MAAA,GAAS;AAAA,IACR,MAAA;AAAA;AAAA,IAEA,eAAA,EAAiB,MAAA;AAAA,IACjB,eAAA,EAAiB,OAAO,CAAA,CAAE,cAAc,CAAA,KAAM,WAAA;AAAA,IAC9C,YAAA,EAAc,OAAO,CAAA,CAAE,WAAW,CAAA,KAAM;AAAA,GACzC;AACA,EAAA,OAAO,MAAA;AACR;AASO,SAAS,iBAAA,CACf,YACA,OAAA,EACO;AACP,EAAA,IAAI,CAAC,aAAA,EAAc,CAAE,UAAU,CAAA,EAAG;AACjC,IAAA,MAAM,IAAI,uBAAA,CAAwB,OAAA,EAAS,EAAE,YAAY,CAAA;AAAA,EAC1D;AACD;AAGO,SAAS,iBAAA,GAA0B;AACzC,EAAA,MAAA,GAAS,MAAA;AACV","file":"chunk-ACBIHS5H.js","sourcesContent":["/**\n * Runtime capability detection. The framework runs in browsers, edge runtimes,\n * and Node. Features that need Node-only APIs (process spawning, filesystem) are\n * gated behind these checks and throw {@link RuntimeUnsupportedError} when used\n * in a runtime that cannot support them. (FR-030, FR-030a)\n *\n * @packageDocumentation\n */\n\nimport { RuntimeUnsupportedError } from \"./errors.js\";\n\n/** Describes which optional capabilities the current runtime supports. */\nexport interface RuntimeCapabilities {\n\t/** Can spawn child processes (Node only) — required for stdio MCP transport. */\n\tcanSpawnProcess: boolean;\n\t/** Has `localStorage` available (browsers). */\n\thasLocalStorage: boolean;\n\t/** Has `indexedDB` available (browsers). */\n\thasIndexedDB: boolean;\n\t/** Running under Node.js. */\n\tisNode: boolean;\n}\n\nlet cached: RuntimeCapabilities | undefined;\n\n/** Detect the current runtime's capabilities (memoized). */\nexport function detectRuntime(): RuntimeCapabilities {\n\tif (cached) return cached;\n\n\tconst g = globalThis as Record<string, unknown>;\n\tconst proc = g[\"process\"] as { versions?: { node?: string } } | undefined;\n\tconst isNode = typeof proc !== \"undefined\" && !!proc.versions?.node;\n\n\tcached = {\n\t\tisNode,\n\t\t// Process spawning requires Node's child_process; treat Node as capable.\n\t\tcanSpawnProcess: isNode,\n\t\thasLocalStorage: typeof g[\"localStorage\"] !== \"undefined\",\n\t\thasIndexedDB: typeof g[\"indexedDB\"] !== \"undefined\",\n\t};\n\treturn cached;\n}\n\n/**\n * Assert that a runtime capability is present, throwing a typed error otherwise.\n *\n * @param capability - The capability key to require.\n * @param feature - Human-readable feature name used in the error message.\n * @throws {RuntimeUnsupportedError} when the capability is unavailable.\n */\nexport function requireCapability(\n\tcapability: keyof RuntimeCapabilities,\n\tfeature: string,\n): void {\n\tif (!detectRuntime()[capability]) {\n\t\tthrow new RuntimeUnsupportedError(feature, { capability });\n\t}\n}\n\n/** Reset the memoized detection — intended for tests only. */\nexport function resetRuntimeCache(): void {\n\tcached = undefined;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/runtime.ts"],"names":["RuntimeUnsupportedError"],"mappings":";;;;;AAuBA,IAAI,MAAA;AAGG,SAAS,aAAA,GAAqC;AACpD,EAAA,IAAI,QAAQ,OAAO,MAAA;AAEnB,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,MAAM,IAAA,GAAO,EAAE,SAAS,CAAA;AACxB,EAAA,MAAM,SAAS,OAAO,IAAA,KAAS,eAAe,CAAC,CAAC,KAAK,QAAA,EAAU,IAAA;AAE/D,EAAA,MAAA,GAAS;AAAA,IACR,MAAA;AAAA;AAAA,IAEA,eAAA,EAAiB,MAAA;AAAA,IACjB,eAAA,EAAiB,OAAO,CAAA,CAAE,cAAc,CAAA,KAAM,WAAA;AAAA,IAC9C,YAAA,EAAc,OAAO,CAAA,CAAE,WAAW,CAAA,KAAM;AAAA,GACzC;AACA,EAAA,OAAO,MAAA;AACR;AASO,SAAS,iBAAA,CACf,YACA,OAAA,EACO;AACP,EAAA,IAAI,CAAC,aAAA,EAAc,CAAE,UAAU,CAAA,EAAG;AACjC,IAAA,MAAM,IAAIA,yCAAA,CAAwB,OAAA,EAAS,EAAE,YAAY,CAAA;AAAA,EAC1D;AACD;AAGO,SAAS,iBAAA,GAA0B;AACzC,EAAA,MAAA,GAAS,MAAA;AACV","file":"chunk-FOTCUNP5.cjs","sourcesContent":["/**\n * Runtime capability detection. The framework runs in browsers, edge runtimes,\n * and Node. Features that need Node-only APIs (process spawning, filesystem) are\n * gated behind these checks and throw {@link RuntimeUnsupportedError} when used\n * in a runtime that cannot support them. (FR-030, FR-030a)\n *\n * @packageDocumentation\n */\n\nimport { RuntimeUnsupportedError } from \"./errors.js\";\n\n/** Describes which optional capabilities the current runtime supports. */\nexport interface RuntimeCapabilities {\n\t/** Can spawn child processes (Node only) — required for stdio MCP transport. */\n\tcanSpawnProcess: boolean;\n\t/** Has `localStorage` available (browsers). */\n\thasLocalStorage: boolean;\n\t/** Has `indexedDB` available (browsers). */\n\thasIndexedDB: boolean;\n\t/** Running under Node.js. */\n\tisNode: boolean;\n}\n\nlet cached: RuntimeCapabilities | undefined;\n\n/** Detect the current runtime's capabilities (memoized). */\nexport function detectRuntime(): RuntimeCapabilities {\n\tif (cached) return cached;\n\n\tconst g = globalThis as Record<string, unknown>;\n\tconst proc = g[\"process\"] as { versions?: { node?: string } } | undefined;\n\tconst isNode = typeof proc !== \"undefined\" && !!proc.versions?.node;\n\n\tcached = {\n\t\tisNode,\n\t\t// Process spawning requires Node's child_process; treat Node as capable.\n\t\tcanSpawnProcess: isNode,\n\t\thasLocalStorage: typeof g[\"localStorage\"] !== \"undefined\",\n\t\thasIndexedDB: typeof g[\"indexedDB\"] !== \"undefined\",\n\t};\n\treturn cached;\n}\n\n/**\n * Assert that a runtime capability is present, throwing a typed error otherwise.\n *\n * @param capability - The capability key to require.\n * @param feature - Human-readable feature name used in the error message.\n * @throws {RuntimeUnsupportedError} when the capability is unavailable.\n */\nexport function requireCapability(\n\tcapability: keyof RuntimeCapabilities,\n\tfeature: string,\n): void {\n\tif (!detectRuntime()[capability]) {\n\t\tthrow new RuntimeUnsupportedError(feature, { capability });\n\t}\n}\n\n/** Reset the memoized detection — intended for tests only. */\nexport function resetRuntimeCache(): void {\n\tcached = undefined;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/providers/provider.ts","../src/providers/retry.ts","../src/providers/openai-compatible.ts","../src/providers/copilot.ts"],"names":[],"mappings":";;;AA4DO,SAAS,cAAc,OAAA,EAAgD;AAC7E,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,KAAW,OAAA,CAAQ,eAAe,CAAC,OAAA,CAAQ,YAAY,CAAA,GAAI,EAAC,CAAA;AACnF,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,gBAAgB,uEAAuE,CAAA;AAAA,EAClG;AACA,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,YAAA,GAC1B,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,KAAU,OAAA,CAAQ,YAAY,CAAA,GACnD,OAAO,CAAC,CAAA;AACX,EAAA,IAAI,CAAC,YAAA,EAAc;AAClB,IAAA,MAAM,IAAI,eAAA,CAAgB,CAAA,cAAA,EAAiB,OAAA,CAAQ,YAAY,CAAA,0BAAA,CAA4B,CAAA;AAAA,EAC5F;AACA,EAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAAqC;AACrD,IAAA,IAAI,CAAC,MAAM,OAAO,YAAA;AAClB,IAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,IAAI,CAAA;AACjD,IAAA,IAAI,CAAC,KAAA,EAAO;AACX,MAAA,MAAM,IAAI,eAAA,CAAgB,CAAA,OAAA,EAAU,IAAI,CAAA,qCAAA,CAAuC,CAAA;AAAA,IAChF;AACA,IAAA,OAAO,KAAA;AAAA,EACR,CAAA;AACA,EAAA,OAAO,EAAE,MAAA,EAAQ,YAAA,EAAc,OAAA,EAAQ;AACxC;;;AC5DA,IAAM,QAAA,GAAmC;AAAA,EACxC,UAAA,EAAY,CAAA;AAAA,EACZ,WAAA,EAAa,GAAA;AAAA,EACb,UAAA,EAAY;AACb,CAAA;AAEA,SAAS,MAAM,EAAA,EAA2B;AACzC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,MAAM,UAAA,CAAW,CAAA,EAAG,EAAE,CAAC,CAAA;AAC5C;AAUA,eAAsB,SAAA,CACrB,EAAA,EACA,IAAA,EACA,YAAA,EACa;AACb,EAAA,MAAM,GAAA,GAAM,EAAE,GAAG,QAAA,EAAU,GAAG,IAAA,EAAK;AACnC,EAAA,IAAI,OAAA,GAAU,CAAA;AAEd,EAAA,WAAU;AACT,IAAA,IAAI;AACH,MAAA,OAAO,MAAM,EAAA,EAAG;AAAA,IACjB,SAAS,GAAA,EAAK;AACb,MAAA,MAAM,WAAA,GAAc,GAAA,YAAe,aAAA,IAAiB,GAAA,CAAI,SAAA;AACxD,MAAA,IAAI,CAAC,WAAA,IAAe,OAAA,IAAW,GAAA,CAAI,UAAA,EAAY;AAC9C,QAAA,MAAM,GAAA;AAAA,MACP;AACA,MAAA,MAAM,WAAA,GAAc,eAAe,GAAoB,CAAA;AACvD,MAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,GAAA,CAAI,cAAc,CAAA,IAAK,OAAA,EAAS,IAAI,UAAU,CAAA;AACvE,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,CAAI,WAAA;AACnC,MAAA,MAAM,KAAA,CAAM,WAAA,IAAe,OAAA,GAAU,MAAM,CAAA;AAC3C,MAAA,OAAA,EAAA;AAAA,IACD;AAAA,EACD;AACD;AAGO,SAAS,uBAAA,CAAwB,QAAgB,OAAA,EAAgC;AACvF,EAAA,IAAI,MAAA,KAAW,GAAA,IAAO,MAAA,IAAU,GAAA,EAAK;AACpC,IAAA,OAAO,IAAI,aAAA,CAAc,OAAA,EAAS,WAAA,EAAa,EAAE,QAAQ,CAAA;AAAA,EAC1D;AACA,EAAA,IAAI,MAAA,KAAW,GAAA,IAAO,MAAA,KAAW,GAAA,EAAK;AACrC,IAAA,OAAO,IAAI,aAAA,CAAc,OAAA,EAAS,MAAA,EAAQ,EAAE,QAAQ,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,IAAI,aAAA,CAAc,OAAA,EAAS,QAAA,EAAU,EAAE,QAAQ,CAAA;AACvD;;;ACNA,IAAM,sBAAA,GAAyB,iBAAA;AAO/B,SAAS,iBAAiB,IAAA,EAAsB;AAC/C,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,sBAAA,EAAwB,GAAG,CAAA;AAChD;AAEA,SAAS,gBAAgB,KAAA,EAA+B;AACvD,EAAA,IAAI,MAAM,KAAA,CAAM,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,MAAM,CAAA,EAAG;AAC1C,IAAA,OAAO,KAAA,CAAM,IAAI,CAAC,CAAA,KAAO,EAAuB,IAAI,CAAA,CAAE,KAAK,EAAE,CAAA;AAAA,EAC9D;AACA,EAAA,OAAO,KAAA,CAAM,GAAA;AAAA,IAAI,CAAC,MACjB,CAAA,CAAE,IAAA,KAAS,SACR,EAAE,IAAA,EAAM,QAAQ,IAAA,EAAM,CAAA,CAAE,MAAK,GAC7B,EAAE,MAAM,WAAA,EAAa,SAAA,EAAW,EAAE,GAAA,EAAK,CAAA,CAAE,MAAK;AAAE,GACpD;AACD;AAEA,SAAS,gBACR,SAAA,EACyF;AACzF,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,CAAC,EAAA,MAAQ;AAAA,IAC7B,IAAI,EAAA,CAAG,EAAA;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,QAAA,EAAU;AAAA,MACT,IAAA,EAAM,gBAAA,CAAiB,EAAA,CAAG,IAAI,CAAA;AAAA,MAC9B,SAAA,EACC,OAAO,EAAA,CAAG,SAAA,KAAc,QAAA,GAAW,EAAA,CAAG,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAA,IAAa,EAAE;AAAA;AACrF,GACD,CAAE,CAAA;AACH;AAEA,SAAS,iBAAiB,QAAA,EAAsC;AAC/D,EAAA,OAAO,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM;AAC1B,IAAA,MAAM,GAAA,GAAqB,EAAE,IAAA,EAAM,CAAA,CAAE,MAAM,OAAA,EAAS,eAAA,CAAgB,CAAA,CAAE,KAAK,CAAA,EAAE;AAC7E,IAAA,IAAI,CAAA,CAAE,SAAA,IAAa,CAAA,CAAE,SAAA,CAAU,SAAS,CAAA,EAAG;AAC1C,MAAA,GAAA,CAAI,UAAA,GAAa,eAAA,CAAgB,CAAA,CAAE,SAAS,CAAA;AAG5C,MAAA,MAAM,OAAA,GAAU,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,MAAA,IAAU,CAAA,CAAE,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AAC1E,MAAA,IAAI,CAAC,OAAA,EAAS,GAAA,CAAI,OAAA,GAAU,IAAA;AAAA,IAC7B;AACA,IAAA,IAAI,CAAA,CAAE,UAAA,EAAY,GAAA,CAAI,YAAA,GAAe,CAAA,CAAE,UAAA;AACvC,IAAA,IAAI,EAAE,IAAA,EAAM,GAAA,CAAI,IAAA,GAAO,gBAAA,CAAiB,EAAE,IAAI,CAAA;AAC9C,IAAA,IAAI,CAAA,CAAE,eAAA,EAAiB,GAAA,CAAI,gBAAA,GAAmB,CAAA,CAAE,eAAA;AAChD,IAAA,OAAO,GAAA;AAAA,EACR,CAAC,CAAA;AACF;AAQA,SAAS,eAAe,KAAA,EAA+B;AACtD,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAoB;AACxC,EAAA,IAAI,CAAC,SAAS,KAAA,CAAM,MAAA,KAAW,GAAG,OAAO,EAAE,KAAA,EAAO,MAAA,EAAW,OAAA,EAAQ;AACrE,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM;AAC9B,IAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,CAAA,CAAE,IAAI,CAAA;AACxC,IAAA,OAAA,CAAQ,GAAA,CAAI,QAAA,EAAU,CAAA,CAAE,IAAI,CAAA;AAC5B,IAAA,OAAO;AAAA,MACN,IAAA,EAAM,UAAA;AAAA,MACN,QAAA,EAAU,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,CAAA,CAAE,WAAA,EAAa,UAAA,EAAY,CAAA,CAAE,WAAA;AAAY,KACnF;AAAA,EACD,CAAC,CAAA;AACD,EAAA,OAAO,EAAE,OAAO,OAAA,EAAQ;AACzB;AAcO,SAAS,+BACf,OAAA,EACW;AACX,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,SAAA,IAAa,UAAA,CAAW,KAAA;AAChD,EAAA,MAAM,MAAM,CAAA,EAAG,OAAA,CAAQ,QAAQ,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,iBAAA,CAAA;AACjD,EAAA,MAAM,EAAE,MAAA,EAAQ,YAAA,EAAc,OAAA,EAAQ,GAAI,cAAc,OAAO,CAAA;AAE/D,EAAA,eAAe,WAAA,GAA+C;AAC7D,IAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,aAAA,EAAc;AAGzC,IAAA,MAAM,OAAA,GAAkC;AAAA,MACvC,cAAA,EAAgB,kBAAA;AAAA,MAChB,GAAI,OAAA,CAAQ,OAAA,IAAW;AAAC,KACzB;AACA,IAAA,IAAI,IAAA,EAAM,OAAA,CAAQ,eAAe,CAAA,GAAI,UAAU,IAAI,CAAA,CAAA;AACnD,IAAA,OAAO,OAAA;AAAA,EACR;AAEA,EAAA,SAAS,IAAA,CAAK,GAAA,EAAsB,MAAA,EAAiB,IAAA,EAAyB;AAC7E,IAAA,OAAO,KAAK,SAAA,CAAU;AAAA,MACrB,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,CAAE,KAAA;AAAA,MAC1B,QAAA,EAAU,gBAAA,CAAiB,GAAA,CAAI,QAAQ,CAAA;AAAA,MACvC,MAAA;AAAA,MACA,GAAI,KAAK,KAAA,GAAQ,EAAE,OAAO,IAAA,CAAK,KAAA,KAAU;AAAC,KAC1C,CAAA;AAAA,EACF;AAEA,EAAA,SAAS,cAAA,CAAe,KAAc,OAAA,EAAsD;AAC3F,IAAA,MAAM,QAAS,GAAA,EAEX,UAAA;AACJ,IAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,KAAW,GAAG,OAAO,MAAA;AACzC,IAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACxB,IAAI,CAAA,CAAE,EAAA;AAAA,MACN,IAAA,EAAM,QAAQ,GAAA,CAAI,CAAA,CAAE,SAAS,IAAI,CAAA,IAAK,EAAE,QAAA,CAAS,IAAA;AAAA,MACjD,SAAA,EAAW,QAAA,CAAS,CAAA,CAAE,QAAA,CAAS,SAAS;AAAA,KACzC,CAAE,CAAA;AAAA,EACH;AAEA,EAAA,eAAe,SAAS,GAAA,EAAiD;AACxE,IAAA,OAAO,UAAU,YAAY;AAC5B,MAAA,MAAM,IAAA,GAAO,cAAA,CAAe,GAAA,CAAI,KAAK,CAAA;AACrC,MAAA,IAAI,GAAA;AACJ,MAAA,IAAI;AACH,QAAA,GAAA,GAAM,MAAM,QAAQ,GAAA,EAAK;AAAA,UACxB,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS,MAAM,WAAA,EAAY;AAAA,UAC3B,IAAA,EAAM,IAAA,CAAK,GAAA,EAAK,KAAA,EAAO,IAAI,CAAA;AAAA,UAC3B,QAAQ,GAAA,CAAI;AAAA,SACZ,CAAA;AAAA,MACF,SAAS,CAAA,EAAG;AACX,QAAA,MAAM,IAAI,aAAA,CAAc,CAAA,eAAA,EAAmB,CAAA,CAAY,OAAO,IAAI,WAAW,CAAA;AAAA,MAC9E;AACA,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,uBAAA,CAAwB,IAAI,MAAA,EAAQ,CAAA,kBAAA,EAAqB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAExF,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AACH,QAAA,IAAA,GAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,MACxB,CAAA,CAAA,MAAQ;AACP,QAAA,MAAM,IAAI,aAAA,CAAc,6BAAA,EAA+B,WAAW,CAAA;AAAA,MACnE;AACA,MAAA,MAAM,MAAA,GACL,IAAA,CAAK,SAAS,CAAA,GACX,CAAC,CAAA;AACL,MAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,aAAA,CAAc,gCAAgC,WAAW,CAAA;AAChF,MAAA,MAAM,UAAU,MAAA,CAAO,OAAA;AACvB,MAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,CAAE,iBAAA;AAC1C,MAAA,IAAI,SAAA,GAAY,cAAA,CAAe,OAAA,EAAS,IAAA,CAAK,OAAO,CAAA;AAKpD,MAAA,IAAA,CAAK,CAAC,SAAA,IAAa,SAAA,CAAU,WAAW,CAAA,KAAM,MAAA,CAAO,kBAAkB,YAAA,EAAc;AACpF,QAAA,MAAM,SAAA,GAAY,MAAM,iBAAA,CAAkB,GAAG,CAAA;AAC7C,QAAA,SAAA,GAAY,SAAA,CAAU,SAAA;AACtB,QAAA,IAAI,CAAC,SAAA,IAAa,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG;AACzC,UAAA,MAAM,IAAI,aAAA;AAAA,YACT,qEAAA;AAAA,YACA;AAAA,WACD;AAAA,QACD;AACA,QAAA,OAAO;AAAA,UACN,IAAA,EAAO,OAAA,CAAQ,SAAS,CAAA,IAAgB,UAAU,IAAA,IAAQ,EAAA;AAAA,UAC1D,WAAW,cAAA,GACN,OAAA,CAAQ,WAAW,CAAA,IAAgB,SAAA,CAAU,aAAa,KAAA,CAAA,GAC5D,KAAA,CAAA;AAAA,UACH,iBAAiB,cAAA,GACZ,OAAA,CAAQ,kBAAkB,CAAA,IAAgB,SAAA,CAAU,mBAAmB,KAAA,CAAA,GACzE,KAAA,CAAA;AAAA,UACH;AAAA,SACD;AAAA,MACD;AAEA,MAAA,OAAO;AAAA,QACN,IAAA,EAAO,OAAA,CAAQ,SAAS,CAAA,IAAgB,EAAA;AAAA,QACxC,SAAA,EAAW,cAAA,GAAmB,OAAA,CAAQ,WAAW,KAAgB,KAAA,CAAA,GAAa,KAAA,CAAA;AAAA,QAC9E,eAAA,EAAiB,cAAA,GACZ,OAAA,CAAQ,kBAAkB,KAAgB,KAAA,CAAA,GAC5C,KAAA,CAAA;AAAA,QACH;AAAA,OACD;AAAA,IACD,CAAA,EAAG,QAAQ,KAAK,CAAA;AAAA,EACjB;AAGA,EAAA,eAAe,kBAAkB,GAAA,EAAiD;AACjF,IAAA,IAAI,KAAA,GAA0B,EAAE,IAAA,EAAM,EAAA,EAAG;AACzC,IAAA,WAAA,MAAiB,KAAA,IAAS,cAAA,CAAe,GAAG,CAAA,EAAG;AAC9C,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,MAAA,EAAQ,KAAA,GAAQ,KAAA,CAAM,QAAA;AAAA,IAC1C;AACA,IAAA,OAAO,KAAA;AAAA,EACR;AAEA,EAAA,gBAAgB,eAAe,GAAA,EAAoD;AAClF,IAAA,MAAM,IAAA,GAAO,cAAA,CAAe,GAAA,CAAI,KAAK,CAAA;AACrC,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACH,MAAA,GAAA,GAAM,MAAM,QAAQ,GAAA,EAAK;AAAA,QACxB,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,MAAM,WAAA,EAAY;AAAA,QAC3B,IAAA,EAAM,IAAA,CAAK,GAAA,EAAK,IAAA,EAAM,IAAI,CAAA;AAAA,QAC1B,QAAQ,GAAA,CAAI;AAAA,OACZ,CAAA;AAAA,IACF,SAAS,CAAA,EAAG;AACX,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,eAAA,EAAmB,CAAA,CAAY,OAAO,IAAI,WAAW,CAAA;AAAA,IAC9E;AACA,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,uBAAA,CAAwB,IAAI,MAAA,EAAQ,CAAA,kBAAA,EAAqB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AACxF,IAAA,IAAI,CAAC,GAAA,CAAI,IAAA,QAAY,IAAI,aAAA,CAAc,oCAAoC,WAAW,CAAA;AAEtF,IAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,CAAE,iBAAA;AAC1C,IAAA,MAAM,MAAA,GAAS,GAAA,CAAI,IAAA,CAAK,SAAA,EAAU;AAClC,IAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,IAAA,IAAI,MAAA,GAAS,EAAA;AACb,IAAA,IAAI,IAAA,GAAO,EAAA;AACX,IAAA,IAAI,SAAA,GAAY,EAAA;AAChB,IAAA,IAAI,eAAA,GAAkB,EAAA;AAGtB,IAAA,MAAM,SAAA,uBAAgB,GAAA,EAA0D;AAEhF,IAAA,WAAU;AACT,MAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,MAAA,IAAI,IAAA,EAAM;AACV,MAAA,MAAA,IAAU,QAAQ,MAAA,CAAO,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAChD,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAC/B,MAAA,MAAA,GAAS,KAAA,CAAM,KAAI,IAAK,EAAA;AACxB,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACzB,QAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,QAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,OAAO,CAAA,EAAG;AAClC,QAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,CAAC,EAAE,IAAA,EAAK;AACnC,QAAA,IAAI,SAAS,QAAA,EAAU;AACvB,QAAA,MAAM,MAAA,GAAS,SAAS,IAAI,CAAA;AAgB5B,QAAA,MAAM,KAAA,GAAQ,MAAA,EAAQ,OAAA,GAAU,CAAC,CAAA,EAAG,KAAA;AACpC,QAAA,IAAI,CAAC,KAAA,EAAO;AACZ,QAAA,IAAI,MAAM,OAAA,EAAS;AAClB,UAAA,IAAA,IAAQ,KAAA,CAAM,OAAA;AACd,UAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,MAAM,OAAA,EAAQ;AAAA,QAC3C;AACA,QAAA,IAAI,KAAA,CAAM,aAAa,cAAA,EAAgB;AACtC,UAAA,SAAA,IAAa,KAAA,CAAM,SAAA;AACnB,UAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,IAAA,EAAM,MAAM,SAAA,EAAU;AAAA,QAClD;AACA,QAAA,IAAI,KAAA,CAAM,oBAAoB,cAAA,EAAgB;AAC7C,UAAA,eAAA,IAAmB,KAAA,CAAM,gBAAA;AAAA,QAC1B;AACA,QAAA,IAAI,MAAM,UAAA,EAAY;AACrB,UAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,UAAA,EAAY;AACpC,YAAA,MAAM,GAAA,GAAM,KAAK,KAAA,IAAS,CAAA;AAC1B,YAAA,MAAM,OAAO,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA,IAAK,EAAE,MAAM,EAAA,EAAG;AAC9C,YAAA,IAAI,IAAA,CAAK,EAAA,EAAI,IAAA,CAAK,EAAA,GAAK,IAAA,CAAK,EAAA;AAC5B,YAAA,IAAI,KAAK,QAAA,EAAU,IAAA,EAAM,IAAA,CAAK,IAAA,GAAO,KAAK,QAAA,CAAS,IAAA;AACnD,YAAA,IAAI,KAAK,QAAA,EAAU,SAAA,EAAW,IAAA,CAAK,IAAA,IAAQ,KAAK,QAAA,CAAS,SAAA;AACzD,YAAA,SAAA,CAAU,GAAA,CAAI,KAAK,IAAI,CAAA;AAAA,UACxB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAIA,IAAA,MAAM,SAAA,GAAwB,CAAC,GAAG,SAAA,CAAU,SAAS,CAAA,CACnD,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,CAAC,IAAI,CAAA,CAAE,CAAC,CAAC,CAAA,CAC1B,MAAA,CAAO,CAAC,GAAG,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,CACxB,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,CAAC,CAAA,MAAO;AAAA,MACnB,EAAA,EAAI,CAAA,CAAE,EAAA,IAAM,CAAA,KAAA,EAAQ,GAAG,CAAA,CAAA;AAAA,MACvB,MAAM,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA,CAAE,IAAc,KAAM,CAAA,CAAE,IAAA;AAAA,MAC/C,SAAA,EAAW,QAAA,CAAS,CAAA,CAAE,IAAI,KAAK;AAAC,KACjC,CAAE,CAAA;AACH,IAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AACjC,MAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,QAAA,EAAS;AAAA,IACrC;AACA,IAAA,MAAM;AAAA,MACL,IAAA,EAAM,MAAA;AAAA,MACN,QAAA,EAAU;AAAA,QACT,IAAA;AAAA,QACA,WAAW,SAAA,IAAa,MAAA;AAAA,QACxB,iBAAiB,eAAA,IAAmB,MAAA;AAAA,QACpC,SAAA,EAAW,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,SAAA,GAAY;AAAA;AAC/C,KACD;AAAA,EACD;AAEA,EAAA,OAAO;AAAA,IACN,IAAA,EAAM,mBAAA;AAAA,IACN,YAAA,EAAc,YAAA;AAAA,IACd,MAAA;AAAA,IACA,KAAA,EAAO,OAAA;AAAA,IACP,QAAA;AAAA,IACA;AAAA,GACD;AACD;AAEA,SAAS,SAAS,CAAA,EAAoB;AACrC,EAAA,IAAI;AACH,IAAA,OAAO,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,EACpB,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,MAAA;AAAA,EACR;AACD;;;AC7WA,IAAM,wBAAA,GAA2B,+BAAA;AAOjC,IAAM,uBAAA,GAAkD;AAAA,EACvD,gBAAA,EAAkB,eAAA;AAAA,EAClB,uBAAA,EAAyB,qBAAA;AAAA,EACzB,wBAAA,EAA0B,aAAA;AAAA,EAC1B,eAAA,EAAiB;AAClB,CAAA;AA+CO,SAAS,sBAAsB,OAAA,EAA2C;AAChF,EAAA,MAAM,QAAQ,8BAAA,CAA+B;AAAA,IAC5C,OAAA,EAAS,QAAQ,OAAA,IAAW,wBAAA;AAAA,IAC5B,eAAe,OAAA,CAAQ,aAAA;AAAA,IACvB,cAAc,OAAA,CAAQ,YAAA;AAAA,IACtB,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,cAAc,OAAA,CAAQ,YAAA;AAAA;AAAA;AAAA,IAGtB,OAAA,EAAS,EAAE,GAAG,uBAAA,EAAyB,GAAI,OAAA,CAAQ,OAAA,IAAW,EAAC,EAAG;AAAA,IAClE,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,WAAW,OAAA,CAAQ;AAAA,GACnB,CAAA;AAED,EAAA,OAAO;AAAA,IACN,IAAA,EAAM,SAAA;AAAA,IACN,cAAc,KAAA,CAAM,YAAA;AAAA,IACpB,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA;AAAA,IAC7B,QAAA,EAAU,KAAA,CAAM,QAAA,CAAS,IAAA,CAAK,KAAK,CAAA;AAAA,IACnC,cAAA,EAAgB,KAAA,CAAM,cAAA,CAAe,IAAA,CAAK,KAAK;AAAA,GAChD;AACD","file":"chunk-QD2FFISV.js","sourcesContent":["/**\n * LLM provider abstraction. Agents and workflows depend only on this interface,\n * never on a concrete provider, so new providers can be added without changing\n * agent/workflow code. (FR-007)\n *\n * Credentials are always obtained via a caller-supplied callback and are never\n * bundled, persisted, or logged by the framework. (FR-005a, FR-008)\n *\n * @packageDocumentation\n */\n\nimport type { Message, ModelCapabilities } from \"../core/types.js\";\nimport { ValidationError } from \"../core/errors.js\";\n\n/** A caller-supplied source of credentials. The framework never stores the value. */\nexport interface CredentialSource {\n\t/** Return the current credential (token/api key). May be async. */\n\tgetCredential(): string | Promise<string>;\n}\n\n/**\n * Model configuration for a provider. A provider may expose **one or more** models\n * (e.g. GitHub Copilot offers several; an OpenAI-compatible endpoint is usually one).\n * Supply either a single `capabilities` object or an array via `models`.\n */\nexport interface ModelSelectionOptions {\n\t/** Single-model shorthand. */\n\tcapabilities?: ModelCapabilities;\n\t/** One or more models this provider can use. */\n\tmodels?: ModelCapabilities[];\n\t/** Name of the default model (defaults to the first entry). */\n\tdefaultModel?: string;\n}\n\n/** Resolved model set with a default and a lookup helper. */\nexport interface ResolvedModels {\n\t/** All configured models (at least one). */\n\tmodels: ModelCapabilities[];\n\t/** The default model used when a request does not specify one. */\n\tdefaultModel: ModelCapabilities;\n\t/** Look up a model by name, or return the default when omitted. */\n\tmodelOf(name?: string): ModelCapabilities;\n}\n\n/**\n * Normalize {@link ModelSelectionOptions} into a model list, a default, and a\n * lookup helper. Throws {@link ValidationError} if no model is configured or a\n * named model is missing.\n *\n * @example\n * ```ts\n * const { defaultModel, modelOf } = resolveModels({\n * models: [\n * { model: \"gpt-4o\", maxInputTokens: 128000, maxOutputTokens: 16000 },\n * { model: \"o3-mini\", maxInputTokens: 200000, maxOutputTokens: 100000, supportsReasoning: true },\n * ],\n * defaultModel: \"gpt-4o\",\n * });\n * ```\n */\nexport function resolveModels(options: ModelSelectionOptions): ResolvedModels {\n\tconst models = options.models ?? (options.capabilities ? [options.capabilities] : []);\n\tif (models.length === 0) {\n\t\tthrow new ValidationError(\"Provider requires at least one model (set `capabilities` or `models`)\");\n\t}\n\tconst defaultModel = options.defaultModel\n\t\t? models.find((m) => m.model === options.defaultModel)\n\t\t: models[0];\n\tif (!defaultModel) {\n\t\tthrow new ValidationError(`defaultModel \"${options.defaultModel}\" is not present in models`);\n\t}\n\tconst modelOf = (name?: string): ModelCapabilities => {\n\t\tif (!name) return defaultModel;\n\t\tconst found = models.find((m) => m.model === name);\n\t\tif (!found) {\n\t\t\tthrow new ValidationError(`Model \"${name}\" is not configured for this provider`);\n\t\t}\n\t\treturn found;\n\t};\n\treturn { models, defaultModel, modelOf };\n}\n\n/** A tool description passed to the provider so the model can decide to call it. */\nexport interface ToolSpec {\n\tname: string;\n\tdescription: string;\n\tinputSchema: Record<string, unknown>;\n}\n\n/** A request to generate a model response. */\nexport interface GenerateRequest {\n\tmessages: Message[];\n\ttools?: ToolSpec[];\n\t/** Which configured model to use; defaults to the provider's default model. */\n\tmodel?: string;\n\t/** Abort signal to cancel an in-flight request. */\n\tsignal?: AbortSignal;\n}\n\n/** A tool call requested by the model. */\nexport interface ToolCall {\n\tid: string;\n\tname: string;\n\t/** Raw JSON arguments (validated by the tools module before invocation). */\n\targuments: unknown;\n}\n\n/** A complete (non-streaming) model response. */\nexport interface GenerateResponse {\n\t/** Final answer text. */\n\ttext: string;\n\t/** Reasoning/thinking content — only present for reasoning-capable models. (FR-003a) */\n\treasoning?: string;\n\t/**\n\t * Opaque reasoning blob (e.g. Claude thinking signature) to round-trip on the\n\t * next assistant turn for thinking continuity. Never logged or inspected.\n\t */\n\treasoningOpaque?: string;\n\t/** Tool calls the model wants to make, if any. */\n\ttoolCalls?: ToolCall[];\n\t/** Approximate token usage if reported by the provider. */\n\tusage?: { inputTokens?: number; outputTokens?: number };\n}\n\n/** An incremental streaming chunk. */\nexport type GenerateChunk =\n\t| { type: \"text\"; text: string }\n\t| { type: \"reasoning\"; text: string }\n\t| { type: \"tool-call\"; toolCall: ToolCall }\n\t| { type: \"done\"; response: GenerateResponse };\n\n/**\n * An LLM backend. Implementations adapt a concrete API (Copilot, OpenAI-compatible)\n * onto this uniform surface.\n */\nexport interface Provider {\n\t/** Stable provider identifier, e.g. `\"openai-compatible\"`. */\n\treadonly name: string;\n\t/** The default model's capability configuration. (FR-007a) */\n\treadonly capabilities: ModelCapabilities;\n\t/** All models this provider is configured with (one or more). */\n\treadonly models: ModelCapabilities[];\n\t/** Look up a configured model by name, or the default when omitted. */\n\tmodel(name?: string): ModelCapabilities;\n\t/** Generate a complete response. */\n\tgenerate(req: GenerateRequest): Promise<GenerateResponse>;\n\t/** Generate a streamed response. */\n\tgenerateStream(req: GenerateRequest): AsyncIterable<GenerateChunk>;\n}\n","/**\n * Exponential-backoff retry for transient provider failures. Transient errors\n * (429 with Retry-After, 5xx, network/timeout) are retried; auth/4xx fail fast.\n * (FR-008a)\n *\n * @packageDocumentation\n */\n\nimport { ProviderError } from \"../core/errors.js\";\n\n/** Retry tuning. All fields have safe defaults. */\nexport interface RetryOptions {\n\t/** Maximum retry attempts after the first try. Default 3. */\n\tmaxRetries?: number;\n\t/** Base delay in ms for backoff. Default 250. */\n\tbaseDelayMs?: number;\n\t/** Maximum delay cap in ms. Default 8000. */\n\tmaxDelayMs?: number;\n}\n\nconst DEFAULTS: Required<RetryOptions> = {\n\tmaxRetries: 3,\n\tbaseDelayMs: 250,\n\tmaxDelayMs: 8000,\n};\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((r) => setTimeout(r, ms));\n}\n\n/**\n * Run `fn`, retrying transient {@link ProviderError}s with exponential backoff\n * and jitter. Non-transient errors are rethrown immediately (fail fast).\n *\n * @param fn - The operation to attempt. It should throw a {@link ProviderError}.\n * @param opts - Retry tuning.\n * @param retryAfterMs - Optional hook returning a server-specified delay (Retry-After).\n */\nexport async function withRetry<T>(\n\tfn: () => Promise<T>,\n\topts?: RetryOptions,\n\tretryAfterMs?: (err: ProviderError) => number | undefined,\n): Promise<T> {\n\tconst cfg = { ...DEFAULTS, ...opts };\n\tlet attempt = 0;\n\n\tfor (; ;) {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (err) {\n\t\t\tconst isRetryable = err instanceof ProviderError && err.retryable;\n\t\t\tif (!isRetryable || attempt >= cfg.maxRetries) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tconst serverDelay = retryAfterMs?.(err as ProviderError);\n\t\t\tconst backoff = Math.min(cfg.baseDelayMs * 2 ** attempt, cfg.maxDelayMs);\n\t\t\tconst jitter = Math.random() * cfg.baseDelayMs;\n\t\t\tawait sleep(serverDelay ?? backoff + jitter);\n\t\t\tattempt++;\n\t\t}\n\t}\n}\n\n/** Map an HTTP status to a {@link ProviderError} with the right retry semantics. */\nexport function providerErrorFromStatus(status: number, message: string): ProviderError {\n\tif (status === 429 || status >= 500) {\n\t\treturn new ProviderError(message, \"transient\", { status });\n\t}\n\tif (status === 401 || status === 403) {\n\t\treturn new ProviderError(message, \"auth\", { status });\n\t}\n\treturn new ProviderError(message, \"client\", { status });\n}\n","/**\n * OpenAI-compatible provider. Targets any endpoint speaking the OpenAI\n * `/chat/completions` API, including local servers such as LM Studio via a custom\n * `baseUrl`, and GitHub Copilot (see {@link createCopilotProvider}). (FR-006)\n *\n * Provider compatibility notes (handled here so callers don't have to):\n * - Tool names are sanitized to `^[a-zA-Z0-9_-]+$` on the wire (OpenAI/Copilot\n * reject dotted names like `webiq.browse`) and translated back to the registry\n * key when the model calls them.\n * - Assistant turns that requested tools emit `tool_calls` with `content: null`\n * so strict providers (e.g. Anthropic) can pair each tool result with its call.\n * - Streaming responses accumulate `delta.tool_calls[]` keyed by `index`\n * (fragments may start at a non-zero index when reasoning occupies 0/1).\n * - Some reasoning models report `finish_reason: \"tool_calls\"` from the\n * non-streaming endpoint without a `tool_calls` array; `generate` transparently\n * re-requests in streaming mode and assembles them, failing loud (typed\n * {@link ProviderError}) rather than silently stopping if none materialize.\n *\n * @packageDocumentation\n */\n\nimport type { Message, ContentPart, MessageToolCall } from \"../core/types.js\";\nimport { ProviderError } from \"../core/errors.js\";\nimport type {\n\tProvider,\n\tCredentialSource,\n\tGenerateRequest,\n\tGenerateResponse,\n\tGenerateChunk,\n\tToolCall,\n\tToolSpec,\n} from \"./provider.js\";\nimport { resolveModels, type ModelSelectionOptions } from \"./provider.js\";\nimport { withRetry, providerErrorFromStatus, type RetryOptions } from \"./retry.js\";\n\n/**\n * Options for {@link createOpenAICompatibleProvider}.\n *\n * Supply a single model via `capabilities`, or multiple via `models` (most\n * OpenAI-compatible endpoints expose one model, but multiple are supported).\n */\nexport interface OpenAICompatibleProviderOptions extends CredentialSource, ModelSelectionOptions {\n\t/** Base URL of the OpenAI-compatible API, e.g. `http://localhost:1234/v1`. */\n\tbaseUrl: string;\n\t/**\n\t * Extra request headers merged into every call (e.g. provider-required\n\t * identification headers). The `authorization` header is always set from\n\t * `getCredential()` and cannot be overridden here.\n\t */\n\theaders?: Record<string, string>;\n\t/** Retry tuning for transient failures. */\n\tretry?: RetryOptions;\n\t/** Optional custom fetch (for testing or non-standard runtimes). */\n\tfetchImpl?: typeof fetch;\n}\n\ninterface OpenAIMessage {\n\trole: string;\n\tcontent: unknown;\n\ttool_calls?: Array<{ id: string; type: \"function\"; function: { name: string; arguments: string } }>;\n\ttool_call_id?: string;\n\tname?: string;\n\treasoning_opaque?: string;\n}\n\n/** OpenAI/Copilot require tool names to match `^[a-zA-Z0-9_-]{1,128}$`. */\nconst UNSAFE_TOOL_NAME_CHARS = /[^a-zA-Z0-9_-]/g;\n\n/**\n * Sanitize a (possibly namespaced) tool name for the wire. Dotted MCP names like\n * `webiq.browse` become `webiq_browse`; the original is recovered via the\n * per-request name map when the model calls the tool.\n */\nfunction sanitizeToolName(name: string): string {\n\treturn name.replace(UNSAFE_TOOL_NAME_CHARS, \"_\");\n}\n\nfunction toOpenAIContent(parts: ContentPart[]): unknown {\n\tif (parts.every((p) => p.type === \"text\")) {\n\t\treturn parts.map((p) => (p as { text: string }).text).join(\"\");\n\t}\n\treturn parts.map((p) =>\n\t\tp.type === \"text\"\n\t\t\t? { type: \"text\", text: p.text }\n\t\t\t: { type: \"image_url\", image_url: { url: p.data } },\n\t);\n}\n\nfunction toWireToolCalls(\n\ttoolCalls: MessageToolCall[],\n): Array<{ id: string; type: \"function\"; function: { name: string; arguments: string } }> {\n\treturn toolCalls.map((tc) => ({\n\t\tid: tc.id,\n\t\ttype: \"function\",\n\t\tfunction: {\n\t\t\tname: sanitizeToolName(tc.name),\n\t\t\targuments:\n\t\t\t\ttypeof tc.arguments === \"string\" ? tc.arguments : JSON.stringify(tc.arguments ?? {}),\n\t\t},\n\t}));\n}\n\nfunction toOpenAIMessages(messages: Message[]): OpenAIMessage[] {\n\treturn messages.map((m) => {\n\t\tconst msg: OpenAIMessage = { role: m.role, content: toOpenAIContent(m.parts) };\n\t\tif (m.toolCalls && m.toolCalls.length > 0) {\n\t\t\tmsg.tool_calls = toWireToolCalls(m.toolCalls);\n\t\t\t// Strict providers require `content: null` (not \"\") on an assistant turn\n\t\t\t// that only carries tool calls.\n\t\t\tconst hasText = m.parts.some((p) => p.type === \"text\" && p.text.length > 0);\n\t\t\tif (!hasText) msg.content = null;\n\t\t}\n\t\tif (m.toolCallId) msg.tool_call_id = m.toolCallId;\n\t\tif (m.name) msg.name = sanitizeToolName(m.name);\n\t\tif (m.reasoningOpaque) msg.reasoning_opaque = m.reasoningOpaque;\n\t\treturn msg;\n\t});\n}\n\n/** Wire tool specs plus a map from sanitized name back to the registry key. */\ninterface WireTools {\n\ttools?: Array<{ type: \"function\"; function: { name: string; description: string; parameters: unknown } }>;\n\tnameMap: Map<string, string>;\n}\n\nfunction buildWireTools(specs?: ToolSpec[]): WireTools {\n\tconst nameMap = new Map<string, string>();\n\tif (!specs || specs.length === 0) return { tools: undefined, nameMap };\n\tconst tools = specs.map((t) => {\n\t\tconst wireName = sanitizeToolName(t.name);\n\t\tnameMap.set(wireName, t.name);\n\t\treturn {\n\t\t\ttype: \"function\" as const,\n\t\t\tfunction: { name: wireName, description: t.description, parameters: t.inputSchema },\n\t\t};\n\t});\n\treturn { tools, nameMap };\n}\n\n/**\n * Create an OpenAI-compatible provider (works with LM Studio, vLLM, etc.).\n *\n * @example\n * ```ts\n * const provider = createOpenAICompatibleProvider({\n * baseUrl: \"http://localhost:1234/v1\",\n * getCredential: () => process.env.LMSTUDIO_KEY ?? \"\",\n * capabilities: { model: \"local\", maxInputTokens: 262144, maxOutputTokens: 32000 },\n * });\n * ```\n */\nexport function createOpenAICompatibleProvider(\n\toptions: OpenAICompatibleProviderOptions,\n): Provider {\n\tconst doFetch = options.fetchImpl ?? globalThis.fetch;\n\tconst url = `${options.baseUrl.replace(/\\/$/, \"\")}/chat/completions`;\n\tconst { models, defaultModel, modelOf } = resolveModels(options);\n\n\tasync function authHeaders(): Promise<Record<string, string>> {\n\t\tconst cred = await options.getCredential();\n\t\t// content-type first, then caller headers (may override it), then the\n\t\t// credential-derived authorization which always wins.\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"content-type\": \"application/json\",\n\t\t\t...(options.headers ?? {}),\n\t\t};\n\t\tif (cred) headers[\"authorization\"] = `Bearer ${cred}`;\n\t\treturn headers;\n\t}\n\n\tfunction body(req: GenerateRequest, stream: boolean, wire: WireTools): string {\n\t\treturn JSON.stringify({\n\t\t\tmodel: modelOf(req.model).model,\n\t\t\tmessages: toOpenAIMessages(req.messages),\n\t\t\tstream,\n\t\t\t...(wire.tools ? { tools: wire.tools } : {}),\n\t\t});\n\t}\n\n\tfunction parseToolCalls(raw: unknown, nameMap: Map<string, string>): ToolCall[] | undefined {\n\t\tconst calls = (raw as {\n\t\t\ttool_calls?: Array<{ id: string; function: { name: string; arguments: string } }>;\n\t\t})?.tool_calls;\n\t\tif (!calls || calls.length === 0) return undefined;\n\t\treturn calls.map((c) => ({\n\t\t\tid: c.id,\n\t\t\tname: nameMap.get(c.function.name) ?? c.function.name,\n\t\t\targuments: safeJson(c.function.arguments),\n\t\t}));\n\t}\n\n\tasync function generate(req: GenerateRequest): Promise<GenerateResponse> {\n\t\treturn withRetry(async () => {\n\t\t\tconst wire = buildWireTools(req.tools);\n\t\t\tlet res: Response;\n\t\t\ttry {\n\t\t\t\tres = await doFetch(url, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: await authHeaders(),\n\t\t\t\t\tbody: body(req, false, wire),\n\t\t\t\t\tsignal: req.signal,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tthrow new ProviderError(`Network error: ${(e as Error).message}`, \"transient\");\n\t\t\t}\n\t\t\tif (!res.ok) throw providerErrorFromStatus(res.status, `Provider returned ${res.status}`);\n\n\t\t\tlet json: Record<string, unknown>;\n\t\t\ttry {\n\t\t\t\tjson = (await res.json()) as Record<string, unknown>;\n\t\t\t} catch {\n\t\t\t\tthrow new ProviderError(\"Malformed provider response\", \"malformed\");\n\t\t\t}\n\t\t\tconst choice = (\n\t\t\t\tjson[\"choices\"] as Array<{ message: Record<string, unknown>; finish_reason?: string }>\n\t\t\t)?.[0];\n\t\t\tif (!choice) throw new ProviderError(\"Provider returned no choices\", \"malformed\");\n\t\t\tconst message = choice.message;\n\t\t\tconst reasoningModel = modelOf(req.model).supportsReasoning;\n\t\t\tlet toolCalls = parseToolCalls(message, wire.nameMap);\n\n\t\t\t// Bug 4(b): some reasoning models report `finish_reason: \"tool_calls\"` from\n\t\t\t// the non-streaming endpoint without a `tool_calls` array. Re-request in\n\t\t\t// streaming mode and assemble them so the agent loop can proceed.\n\t\t\tif ((!toolCalls || toolCalls.length === 0) && choice.finish_reason === \"tool_calls\") {\n\t\t\t\tconst assembled = await assembleViaStream(req);\n\t\t\t\ttoolCalls = assembled.toolCalls;\n\t\t\t\tif (!toolCalls || toolCalls.length === 0) {\n\t\t\t\t\tthrow new ProviderError(\n\t\t\t\t\t\t\"Provider signaled tool_calls but returned none (even when streamed)\",\n\t\t\t\t\t\t\"malformed\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\ttext: (message[\"content\"] as string) ?? assembled.text ?? \"\",\n\t\t\t\t\treasoning: reasoningModel\n\t\t\t\t\t\t? ((message[\"reasoning\"] as string) ?? assembled.reasoning ?? undefined)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\treasoningOpaque: reasoningModel\n\t\t\t\t\t\t? ((message[\"reasoning_opaque\"] as string) ?? assembled.reasoningOpaque ?? undefined)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\ttoolCalls,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttext: (message[\"content\"] as string) ?? \"\",\n\t\t\t\treasoning: reasoningModel ? ((message[\"reasoning\"] as string) ?? undefined) : undefined,\n\t\t\t\treasoningOpaque: reasoningModel\n\t\t\t\t\t? ((message[\"reasoning_opaque\"] as string) ?? undefined)\n\t\t\t\t\t: undefined,\n\t\t\t\ttoolCalls,\n\t\t\t};\n\t\t}, options.retry);\n\t}\n\n\t/** Drive a streaming request to completion and return its assembled final response. */\n\tasync function assembleViaStream(req: GenerateRequest): Promise<GenerateResponse> {\n\t\tlet final: GenerateResponse = { text: \"\" };\n\t\tfor await (const chunk of generateStream(req)) {\n\t\t\tif (chunk.type === \"done\") final = chunk.response;\n\t\t}\n\t\treturn final;\n\t}\n\n\tasync function* generateStream(req: GenerateRequest): AsyncIterable<GenerateChunk> {\n\t\tconst wire = buildWireTools(req.tools);\n\t\tlet res: Response;\n\t\ttry {\n\t\t\tres = await doFetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: await authHeaders(),\n\t\t\t\tbody: body(req, true, wire),\n\t\t\t\tsignal: req.signal,\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tthrow new ProviderError(`Network error: ${(e as Error).message}`, \"transient\");\n\t\t}\n\t\tif (!res.ok) throw providerErrorFromStatus(res.status, `Provider returned ${res.status}`);\n\t\tif (!res.body) throw new ProviderError(\"Provider returned no stream body\", \"malformed\");\n\n\t\tconst reasoningModel = modelOf(req.model).supportsReasoning;\n\t\tconst reader = res.body.getReader();\n\t\tconst decoder = new TextDecoder();\n\t\tlet buffer = \"\";\n\t\tlet text = \"\";\n\t\tlet reasoning = \"\";\n\t\tlet reasoningOpaque = \"\";\n\t\t// Accumulate streamed tool-call fragments keyed by their `index` (which may\n\t\t// start at a non-zero value when reasoning deltas occupy the first indices).\n\t\tconst toolAccum = new Map<number, { id?: string; name?: string; args: string }>();\n\n\t\tfor (; ;) {\n\t\t\tconst { value, done } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t\tconst lines = buffer.split(\"\\n\");\n\t\t\tbuffer = lines.pop() ?? \"\";\n\t\t\tfor (const line of lines) {\n\t\t\t\tconst trimmed = line.trim();\n\t\t\t\tif (!trimmed.startsWith(\"data:\")) continue;\n\t\t\t\tconst data = trimmed.slice(5).trim();\n\t\t\t\tif (data === \"[DONE]\") continue;\n\t\t\t\tconst parsed = safeJson(data) as\n\t\t\t\t\t| {\n\t\t\t\t\t\tchoices?: Array<{\n\t\t\t\t\t\t\tdelta?: {\n\t\t\t\t\t\t\t\tcontent?: string;\n\t\t\t\t\t\t\t\treasoning?: string;\n\t\t\t\t\t\t\t\treasoning_opaque?: string;\n\t\t\t\t\t\t\t\ttool_calls?: Array<{\n\t\t\t\t\t\t\t\t\tindex?: number;\n\t\t\t\t\t\t\t\t\tid?: string;\n\t\t\t\t\t\t\t\t\tfunction?: { name?: string; arguments?: string };\n\t\t\t\t\t\t\t\t}>;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}>;\n\t\t\t\t\t}\n\t\t\t\t\t| undefined;\n\t\t\t\tconst delta = parsed?.choices?.[0]?.delta;\n\t\t\t\tif (!delta) continue;\n\t\t\t\tif (delta.content) {\n\t\t\t\t\ttext += delta.content;\n\t\t\t\t\tyield { type: \"text\", text: delta.content };\n\t\t\t\t}\n\t\t\t\tif (delta.reasoning && reasoningModel) {\n\t\t\t\t\treasoning += delta.reasoning;\n\t\t\t\t\tyield { type: \"reasoning\", text: delta.reasoning };\n\t\t\t\t}\n\t\t\t\tif (delta.reasoning_opaque && reasoningModel) {\n\t\t\t\t\treasoningOpaque += delta.reasoning_opaque;\n\t\t\t\t}\n\t\t\t\tif (delta.tool_calls) {\n\t\t\t\t\tfor (const frag of delta.tool_calls) {\n\t\t\t\t\t\tconst idx = frag.index ?? 0;\n\t\t\t\t\t\tconst slot = toolAccum.get(idx) ?? { args: \"\" };\n\t\t\t\t\t\tif (frag.id) slot.id = frag.id;\n\t\t\t\t\t\tif (frag.function?.name) slot.name = frag.function.name;\n\t\t\t\t\t\tif (frag.function?.arguments) slot.args += frag.function.arguments;\n\t\t\t\t\t\ttoolAccum.set(idx, slot);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Materialize accumulated tool calls (sorted by stream index) and surface\n\t\t// them both as chunks and in the final `done` response.\n\t\tconst toolCalls: ToolCall[] = [...toolAccum.entries()]\n\t\t\t.sort((a, b) => a[0] - b[0])\n\t\t\t.filter(([, s]) => s.name)\n\t\t\t.map(([idx, s]) => ({\n\t\t\t\tid: s.id ?? `call_${idx}`,\n\t\t\t\tname: wire.nameMap.get(s.name as string) ?? (s.name as string),\n\t\t\t\targuments: safeJson(s.args) ?? {},\n\t\t\t}));\n\t\tfor (const toolCall of toolCalls) {\n\t\t\tyield { type: \"tool-call\", toolCall };\n\t\t}\n\t\tyield {\n\t\t\ttype: \"done\",\n\t\t\tresponse: {\n\t\t\t\ttext,\n\t\t\t\treasoning: reasoning || undefined,\n\t\t\t\treasoningOpaque: reasoningOpaque || undefined,\n\t\t\t\ttoolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n\t\t\t},\n\t\t};\n\t}\n\n\treturn {\n\t\tname: \"openai-compatible\",\n\t\tcapabilities: defaultModel,\n\t\tmodels,\n\t\tmodel: modelOf,\n\t\tgenerate,\n\t\tgenerateStream,\n\t};\n}\n\nfunction safeJson(s: string): unknown {\n\ttry {\n\t\treturn JSON.parse(s);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n","/**\n * GitHub Copilot provider. (FR-005)\n *\n * Copilot's chat API is OpenAI-compatible, so this provider configures the shared\n * OpenAI-compatible transport with Copilot's endpoint and the caller-supplied\n * credential (a Copilot/GitHub token). The token is obtained via callback and is\n * never bundled, persisted, or logged. (FR-005a)\n *\n * In a frontend-only deployment the end user supplies their own token (it stays\n * client-side); in a backend deployment the developer may supply it, or the user\n * sends it per request over SSL/TLS and the backend must not log or persist it.\n *\n * @packageDocumentation\n */\n\nimport type { Provider, CredentialSource, ModelSelectionOptions } from \"./provider.js\";\nimport type { RetryOptions } from \"./retry.js\";\nimport { createOpenAICompatibleProvider } from \"./openai-compatible.js\";\n\n/** Default Copilot-compatible chat completions base URL. */\nconst DEFAULT_COPILOT_BASE_URL = \"https://api.githubcopilot.com\";\n\n/**\n * Headers `api.githubcopilot.com` requires on every request. Omitting any of\n * these causes the API to reject the call with HTTP 400. They are sent by default\n * and can be overridden per option via `headers`.\n */\nconst COPILOT_DEFAULT_HEADERS: Record<string, string> = {\n\t\"Editor-Version\": \"vscode/1.95.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.20.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n\t\"Openai-Intent\": \"conversation-panel\",\n};\n\n/**\n * Options for {@link createCopilotProvider}.\n *\n * GitHub Copilot exposes several models, so configure them via `models` (with an\n * optional `defaultModel`). A single `capabilities` object is also accepted.\n */\nexport interface CopilotProviderOptions extends CredentialSource, ModelSelectionOptions {\n\t/** Override the Copilot base URL if needed. */\n\tbaseUrl?: string;\n\t/**\n\t * Extra/override request headers. Merged over the required Copilot defaults\n\t * (`Editor-Version`, `Editor-Plugin-Version`, `Copilot-Integration-Id`,\n\t * `Openai-Intent`), so you can adjust them without losing the others.\n\t */\n\theaders?: Record<string, string>;\n\t/** Retry tuning for transient failures. */\n\tretry?: RetryOptions;\n\t/** Optional custom fetch (for testing or non-standard runtimes). */\n\tfetchImpl?: typeof fetch;\n}\n\n/**\n * Create a GitHub Copilot provider.\n *\n * @example Single model\n * ```ts\n * const provider = createCopilotProvider({\n * getCredential: () => myCopilotToken, // never logged or persisted\n * capabilities: { model: \"gpt-4o\", maxInputTokens: 128000, maxOutputTokens: 16000 },\n * });\n * ```\n *\n * @example Multiple models\n * ```ts\n * const provider = createCopilotProvider({\n * getCredential: () => myCopilotToken,\n * models: [\n * { model: \"gpt-4o\", maxInputTokens: 128000, maxOutputTokens: 16000, supportsVision: true },\n * { model: \"o3-mini\", maxInputTokens: 200000, maxOutputTokens: 100000, supportsReasoning: true },\n * ],\n * defaultModel: \"gpt-4o\",\n * });\n * // Pick a model per request: provider.generate({ messages, model: \"o3-mini\" })\n * ```\n */\nexport function createCopilotProvider(options: CopilotProviderOptions): Provider {\n\tconst inner = createOpenAICompatibleProvider({\n\t\tbaseUrl: options.baseUrl ?? DEFAULT_COPILOT_BASE_URL,\n\t\tgetCredential: options.getCredential,\n\t\tcapabilities: options.capabilities,\n\t\tmodels: options.models,\n\t\tdefaultModel: options.defaultModel,\n\t\t// Copilot rejects calls missing its identification headers; defaults are\n\t\t// applied here and remain overridable via `options.headers`.\n\t\theaders: { ...COPILOT_DEFAULT_HEADERS, ...(options.headers ?? {}) },\n\t\tretry: options.retry,\n\t\tfetchImpl: options.fetchImpl,\n\t});\n\t// Preserve the provider contract but report the Copilot name.\n\treturn {\n\t\tname: \"copilot\",\n\t\tcapabilities: inner.capabilities,\n\t\tmodels: inner.models,\n\t\tmodel: inner.model.bind(inner),\n\t\tgenerate: inner.generate.bind(inner),\n\t\tgenerateStream: inner.generateStream.bind(inner),\n\t};\n}\n"]}