@ggui-ai/ui-gen 0.8.0 → 0.9.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 (52) hide show
  1. package/dist/adapters/generation-dispatch.d.ts +10 -0
  2. package/dist/adapters/generation-dispatch.js +172 -1392
  3. package/dist/adapters/generation-dispatch.js.map +1 -1
  4. package/dist/advanced/index.d.ts +1 -1
  5. package/dist/advanced/index.js +191 -1403
  6. package/dist/advanced/index.js.map +1 -1
  7. package/dist/boilerplate.js +3 -2
  8. package/dist/boilerplate.js.map +1 -1
  9. package/dist/compose.js +5 -5
  10. package/dist/compose.js.map +1 -1
  11. package/dist/{create-ui-generator-GX7tvbyH.d.ts → create-ui-generator-B9kV4U9h.d.ts} +13 -0
  12. package/dist/evaluation/axis-checks/index.js +32 -1
  13. package/dist/evaluation/axis-checks/index.js.map +1 -1
  14. package/dist/evaluation/axis-checks/registry.js +32 -1
  15. package/dist/evaluation/axis-checks/registry.js.map +1 -1
  16. package/dist/evaluation/index.js +57 -12
  17. package/dist/evaluation/index.js.map +1 -1
  18. package/dist/fragments/index.js +5 -5
  19. package/dist/fragments/index.js.map +1 -1
  20. package/dist/harness/index.d.ts +4 -125
  21. package/dist/harness/index.js +34 -19
  22. package/dist/harness/index.js.map +1 -1
  23. package/dist/harness/runtime.d.ts +9 -0
  24. package/dist/harness/runtime.js +3 -2
  25. package/dist/harness/runtime.js.map +1 -1
  26. package/dist/harness/types-public.js +8 -7
  27. package/dist/harness/types-public.js.map +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +191 -1403
  30. package/dist/index.js.map +1 -1
  31. package/dist/llm-router-1TyI0_TV.d.ts +156 -0
  32. package/dist/providers/index.d.ts +35 -93
  33. package/dist/providers/index.js +13 -8
  34. package/dist/providers/index.js.map +1 -1
  35. package/dist/validation/index.js +2 -2
  36. package/dist/validation/index.js.map +1 -1
  37. package/package.json +18 -18
  38. package/src/adapters/generation-dispatch.ts +19 -2
  39. package/src/boilerplate/system-prompt.ts +3 -2
  40. package/src/create-ui-generator.ts +44 -11
  41. package/src/evaluation/axis-checks/checks/state-merge.ts +1 -1
  42. package/src/evaluation/axis-checks/checks/universal.ts +39 -0
  43. package/src/evaluation/llm-evaluator.ts +13 -3
  44. package/src/evaluation/visual-evaluator.ts +5 -1
  45. package/src/fragments/realtime.ts +3 -3
  46. package/src/fragments/state.ts +2 -2
  47. package/src/harness/coding/init-session.ts +4 -1
  48. package/src/harness/coding/run-eval-round.ts +6 -0
  49. package/src/harness/llm-router.ts +59 -14
  50. package/src/harness/runtime.ts +8 -0
  51. package/src/providers/bedrock.ts +84 -22
  52. package/src/validation/ui-compiler.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/provider-adapter.ts","../../src/providers/anthropic-wire.ts","../../src/providers/http.ts","../../src/providers/anthropic.ts","../../src/providers/google.ts","../../src/providers/openai.ts","../../src/providers/openrouter.ts","../../src/providers/bedrock.ts","../../src/providers/index.ts"],"names":["PROVIDER","DEFAULT_ENDPOINT","DEFAULT_MAX_TOKENS"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Provider adapter contract — the narrow surface every concrete LLM\n * provider client (Anthropic, Google, OpenAI, OpenRouter) implements\n * before the generator wires them in.\n *\n * The contract is deliberately defined independently of concrete\n * adapters so:\n *\n * - Adapter implementations can be written against a stable surface —\n * every concrete adapter MUST pass\n * {@link providerAdapterContract} or it isn't a `ProviderAdapter`.\n * - Downstream callers (`createUiGenerator`, render handlers, retry /\n * backoff plumbing) build against ONE structured failure shape\n * ({@link ProviderError}) instead of inventing per-provider error\n * UX.\n * - The negotiator + cache layers can branch on\n * `error.kind === 'rate-limited'` etc. without parsing strings.\n *\n * **Scope:**\n *\n * - Defines the interface, the response shape, the error shape,\n * and a contract test runner that asserts every adapter\n * satisfies the seam.\n * - Does NOT call any LLM. The contract is structural; this\n * package's own tests exercise the runner against a deterministic\n * fixture adapter (`provider-adapter-mock.test-util.ts`).\n *\n * **Design choices, locked:**\n *\n * - One discriminated `ProviderError.kind` union, not per-provider\n * subclasses. Every provider's raw error funnels through\n * `mapError` into one of these kinds. Callers branch on `kind`.\n * - Every error carries `provider` + `message`; transport-shaped\n * errors carry `status`; backoff-shaped errors carry\n * `retryAfterSec`. Optional fields don't appear when they don't\n * apply (no `status: undefined` noise in serialized logs).\n * - `validateConfig` is synchronous + does NO I/O. It catches the\n * \"operator never configured the provider\" case (missing key,\n * malformed model id) before we attempt a network call.\n * - `complete` is the single-completion seam. Streaming, tool\n * calling, function calling, and harness retry land in higher\n * layers — adapters stay narrow.\n */\nimport type { LlmProvider, LlmRoute } from '@ggui-ai/protocol';\n\n/**\n * One LLM completion request as the adapter sees it. Plain data so\n * tests can construct it without DI.\n *\n * `route` is a discriminated `LlmRoute` — `(provider, model)` typed\n * together so the model id is structurally constrained to its\n * provider's namespace (per the `MODELS` registry in\n * `@ggui-ai/protocol/types/llm-route`). This makes the #22 / #42 bug\n * class — passing a LiteLLM-prefixed `'anthropic/claude-haiku-4-5'`\n * where Anthropic expected the wire id `'claude-haiku-4-5-20251001'` —\n * a compile error at every adapter call site. The adapter reads the\n * wire-canonical string off `request.route.model` and passes it\n * verbatim to the provider SDK; no transformation step exists to\n * forget.\n */\nexport interface ProviderRequest {\n /** API key. Resolved upstream by `@ggui-ai/cli/byok-resolver`. */\n readonly apiKey: string;\n /**\n * Discriminated `(provider, model)` route. `route.model` is the\n * wire-canonical id the provider's API expects — adapters pass it\n * verbatim with no stripping or remapping.\n */\n readonly route: LlmRoute;\n /** System prompt text. Adapter wires it into the provider's slot. */\n readonly systemPrompt: string;\n /** User prompt text. */\n readonly userPrompt: string;\n /**\n * Optional cap on output tokens. Adapters MUST honor when the\n * provider supports it; when absent, adapters use the provider\n * default.\n */\n readonly maxTokens?: number;\n /**\n * Optional cancellation. Adapters MUST forward into the provider\n * SDK's abort surface and reject with `ProviderError{kind:'aborted'}`\n * when fired.\n */\n readonly signal?: AbortSignal;\n}\n\n/**\n * Successful provider response, normalized.\n *\n * Tool-calling output, multi-turn dialogue, structured-output\n * coercion all land in higher layers — this contract intentionally\n * stays narrow: text + usage + finish reason. The harness layer\n * composes adapters into multi-turn loops.\n */\nexport interface ProviderResponse {\n /** The completion text returned by the provider. */\n readonly text: string;\n /** Token usage, per-call. Required — adapters synthesize 0 if the\n * provider didn't report it (and document that in their adapter). */\n readonly usage: {\n readonly inputTokens: number;\n readonly outputTokens: number;\n };\n /**\n * Why the model stopped. Mapped through a normalized union so\n * callers don't have to know each provider's vocabulary.\n *\n * - `'stop'` model emitted EOS / stop sequence\n * - `'length'` hit `maxTokens` or provider context limit\n * - `'content-filter'` provider safety filter intervened\n * - `'other'` anything else (provider-specific reason)\n */\n readonly finishReason: 'stop' | 'length' | 'content-filter' | 'other';\n}\n\n/**\n * The structured failure contract. Every concrete adapter's\n * `mapError` MUST funnel raw provider errors into this shape so\n * downstream code branches on `kind`, not on string parsing.\n *\n * Discriminator + optional carriers:\n *\n * - `'no-credentials'` — no key supplied (pre-flight failure;\n * usually surfaced by `validateConfig`,\n * not `mapError`).\n * - `'unauthorized'` — provider returned 401. Key invalid /\n * revoked / wrong type.\n * - `'forbidden'` — provider returned 403. Quota exhausted,\n * org-level block, model not allowed for\n * this key. (Distinct from 401 because\n * \"rotate the key\" doesn't help.)\n * - `'rate-limited'` — provider returned 429. Carries\n * `retryAfterSec` when the provider\n * advertised one (`Retry-After` header).\n * - `'server-error'` — provider returned 5xx. Retryable.\n * - `'client-error'` — provider returned other 4xx. Usually\n * non-retryable (bad model id, malformed\n * request).\n * - `'network'` — TCP-level failure, DNS, EAI_AGAIN, etc.\n * No `status`. Retryable.\n * - `'invalid-response'` — provider returned 2xx with a body the\n * adapter couldn't parse. Bug in the\n * adapter or in the provider; treat as\n * non-retryable.\n * - `'aborted'` — caller aborted via `signal`.\n * - `'unknown'` — last-resort bucket. Adapters that hit\n * this should be patched to map the\n * specific case explicitly.\n */\nexport type ProviderErrorKind =\n | 'no-credentials'\n | 'unauthorized'\n | 'forbidden'\n | 'rate-limited'\n | 'server-error'\n | 'client-error'\n | 'network'\n | 'invalid-response'\n | 'aborted'\n | 'unknown';\n\nexport interface ProviderError {\n readonly kind: ProviderErrorKind;\n readonly provider: LlmProvider;\n /** Human-readable message. Safe to log; should not contain key\n * material — adapters MUST scrub before placing here. */\n readonly message: string;\n /** HTTP status when transport-shaped. Absent for pre-flight,\n * network, aborted, invalid-response. */\n readonly status?: number;\n /**\n * Seconds to wait before retrying. Set ONLY for `'rate-limited'`\n * when the provider advertised a `Retry-After` header. Higher-level\n * retry policy uses this when present; falls back to its own\n * exponential backoff when absent.\n */\n readonly retryAfterSec?: number;\n}\n\n/**\n * Pre-flight config validation. Synchronous, no I/O. Catches:\n *\n * - missing or empty API key → no-credentials\n * - missing or empty model id → client-error\n *\n * Adapters MAY widen the check with provider-specific rules\n * (e.g. \"openrouter model id MUST contain a `/`\"). Failures\n * surface through the same {@link ProviderError} so callers branch\n * on one union.\n */\nexport type ProviderValidation =\n | { readonly ok: true }\n | { readonly ok: false; readonly error: ProviderError };\n\n/**\n * The contract every provider client implements.\n */\nexport interface ProviderAdapter {\n /** Provider this adapter speaks to. Stable identifier; lets the\n * caller route a `ProviderRequest` to the right adapter. */\n readonly provider: LlmProvider;\n /**\n * Pre-flight check. MUST return synchronously and MUST NOT touch\n * the network. Returns `{ok: true}` when the request is at least\n * structurally valid; returns `{ok: false, error}` otherwise.\n */\n validateConfig(request: Pick<ProviderRequest, 'apiKey' | 'route'>): ProviderValidation;\n /**\n * Single-completion call. Resolves with `{ok: true, response}` on\n * success or `{ok: false, error}` on any failure (network,\n * provider 4xx/5xx, abort). Implementations MUST:\n *\n * 1. Funnel every raw provider error through `mapError`.\n * 2. NOT throw. The result discriminator IS the error path.\n * 3. Forward `request.signal` into the provider SDK's abort\n * mechanism + return `kind:'aborted'` when fired.\n */\n complete(request: ProviderRequest): Promise<ProviderResult>;\n /**\n * Map an arbitrary thrown / rejected value into a\n * {@link ProviderError}. Exposed (not just internal) so test\n * harnesses + retry policies can normalize errors without going\n * through `complete`.\n *\n * MUST NEVER throw — `mapError(unknown)` is the safety net.\n */\n mapError(raw: unknown): ProviderError;\n}\n\n/**\n * Discriminated result of a `complete` call. Mirrors `validateConfig`\n * so callers never have to handle thrown errors from this seam.\n */\nexport type ProviderResult =\n | { readonly ok: true; readonly response: ProviderResponse }\n | { readonly ok: false; readonly error: ProviderError };\n\n// ─── Helpers concrete adapters compose with ────────────────────────\n\n/**\n * Build a `ProviderError` of the supplied kind. Centralized so\n * concrete adapters don't drift on field shape. Provider-aware so\n * callers don't have to thread it through.\n */\nexport function makeProviderError(args: {\n readonly kind: ProviderErrorKind;\n readonly provider: LlmProvider;\n readonly message: string;\n readonly status?: number;\n readonly retryAfterSec?: number;\n}): ProviderError {\n const out: ProviderError = {\n kind: args.kind,\n provider: args.provider,\n message: args.message,\n ...(args.status !== undefined ? { status: args.status } : {}),\n ...(args.retryAfterSec !== undefined\n ? { retryAfterSec: args.retryAfterSec }\n : {}),\n };\n return out;\n}\n\n/**\n * Map an HTTP status code to the canonical error kind. Adapters\n * call this from `mapError` after they've classified the failure as\n * \"the provider returned a status we understand\". Network / abort /\n * pre-flight live outside this mapping.\n */\nexport function statusToErrorKind(status: number): ProviderErrorKind {\n if (status === 401) return 'unauthorized';\n if (status === 403) return 'forbidden';\n if (status === 429) return 'rate-limited';\n if (status >= 500 && status < 600) return 'server-error';\n if (status >= 400 && status < 500) return 'client-error';\n return 'unknown';\n}\n\n/**\n * Default `validateConfig` implementation. Concrete adapters\n * compose this and add their own provider-specific checks on top.\n *\n * Catches the two universal failures: missing key + missing model.\n * Returns `{ok: true}` when both are present.\n *\n * The model-id check is defense-in-depth — typed `LlmRoute` callers\n * cannot construct a route with an empty model string, but the\n * adapter still validates at runtime in case the request crossed an\n * untyped JSON boundary (e.g. deserialized from a wire format).\n */\nexport function defaultValidateConfig(\n provider: LlmProvider,\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n): ProviderValidation {\n if (!request.apiKey || request.apiKey.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'no-credentials',\n provider,\n message: `${provider}: no API key supplied`,\n }),\n };\n }\n if (!request.route?.model || request.route.model.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'client-error',\n provider,\n message: `${provider}: model id is required`,\n }),\n };\n }\n return { ok: true };\n}\n","/**\n * Shared parser for the Anthropic Messages success envelope.\n *\n * Two adapters consume the SAME wire shape: the direct-API adapter\n * (`./anthropic.ts`, `POST api.anthropic.com/v1/messages`) and the\n * Bedrock adapter (`./bedrock.ts` — Bedrock's Anthropic-flavored\n * endpoint returns the identical envelope). One parser, two callers;\n * the only per-adapter variance is the `provider` prefix on error\n * messages.\n *\n * Takes `unknown` (rather than any SDK `Message` type) so callers are\n * robust to SDK version drift across pnpm-hoisted copies.\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n makeProviderError,\n type ProviderError,\n type ProviderResponse,\n} from '../provider-adapter.js';\n\n/**\n * Parse an Anthropic Messages response body into the normalized\n * {@link ProviderResponse} shape.\n *\n * `stop_reason` → `finishReason` normalization:\n *\n * - `end_turn` / `stop_sequence` → `'stop'`\n * - `max_tokens` → `'length'`\n * - everything else → `'other'` (`tool_use`,\n * `pause_turn`, `refusal`, future stop reasons all bucket here —\n * content-filter surfaces via 4xx errors on Anthropic, not\n * `stop_reason`)\n */\nexport function parseAnthropicMessagesResponse(\n raw: unknown,\n provider: LlmProvider,\n):\n | { ok: true; response: ProviderResponse }\n | { ok: false; error: ProviderError } {\n if (!raw || typeof raw !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: response body was not an object`,\n }),\n };\n }\n const obj = raw as Record<string, unknown>;\n const content = obj['content'];\n if (!Array.isArray(content)) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: response missing \\`content\\` array`,\n }),\n };\n }\n\n // Concatenate every text block. Anthropic sometimes splits a\n // response across multiple text blocks; tool_use / thinking blocks\n // (when present) are filtered out — the single-completion contract\n // here doesn't surface them.\n const text = content\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const b = block as Record<string, unknown>;\n if (b['type'] === 'text' && typeof b['text'] === 'string') {\n return b['text'] as string;\n }\n return '';\n })\n .join('');\n\n const usage = obj['usage'] as Record<string, unknown> | undefined;\n const inputTokens =\n usage && typeof usage['input_tokens'] === 'number'\n ? (usage['input_tokens'] as number)\n : 0;\n const outputTokens =\n usage && typeof usage['output_tokens'] === 'number'\n ? (usage['output_tokens'] as number)\n : 0;\n\n const stopReason = obj['stop_reason'];\n let finishReason: ProviderResponse['finishReason'];\n if (stopReason === 'end_turn' || stopReason === 'stop_sequence') {\n finishReason = 'stop';\n } else if (stopReason === 'max_tokens') {\n finishReason = 'length';\n } else {\n finishReason = 'other';\n }\n\n return {\n ok: true,\n response: {\n text,\n usage: { inputTokens, outputTokens },\n finishReason,\n },\n };\n}\n","/**\n * Shared fetch helpers for concrete provider adapters.\n *\n * Every adapter uses native Node `fetch` (Node 20+ has it global).\n * Heavy provider SDKs are intentionally NOT pulled in — the OSS\n * `@ggui-ai/ui-gen` stays lean, and each adapter is a thin REST\n * wrapper over the contract locked in `../provider-adapter.ts`.\n *\n * The helpers here centralize the three cross-cutting concerns every\n * adapter shares:\n *\n * 1. Parse a `Retry-After` header (seconds OR HTTP-date) into a\n * monotonic seconds number. Used when the provider returns 429.\n * 2. Classify a caught `fetch` rejection into `aborted` / `network` /\n * `unknown` without the adapter re-deriving the rules.\n * 3. Read a response body at most once and parse JSON defensively so\n * `invalid-response` maps cleanly when the server returns 2xx with\n * a non-JSON body.\n *\n * These helpers NEVER throw — every path returns a value. Adapters\n * funnel every raw throw through `mapError`, which itself never\n * throws, per the ProviderAdapter contract.\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n makeProviderError,\n statusToErrorKind,\n type ProviderError,\n} from '../provider-adapter.js';\n\n/**\n * Parse a `Retry-After` header value into positive seconds.\n * Accepts either a numeric seconds string (`\"30\"`) or an HTTP-date\n * (`\"Wed, 21 Oct 2026 07:28:00 GMT\"`). Returns `undefined` on\n * anything unparseable — callers treat absence as \"no hint, fall back\n * to exponential backoff\".\n */\nexport function parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n // Seconds form.\n const asNumber = Number(trimmed);\n if (Number.isFinite(asNumber) && asNumber > 0) {\n return Math.ceil(asNumber);\n }\n // HTTP-date form. `Date.parse` returns NaN on malformed.\n const asDate = Date.parse(trimmed);\n if (!Number.isFinite(asDate)) return undefined;\n const deltaMs = asDate - Date.now();\n if (deltaMs <= 0) return undefined;\n return Math.ceil(deltaMs / 1000);\n}\n\n/**\n * Classify a raw value thrown by `fetch` (or an adapter's internal\n * parse step) into a {@link ProviderError}. Order of checks matters —\n * abort first so aborted network calls don't look like generic\n * network failures.\n */\nexport function classifyFetchError(\n raw: unknown,\n provider: LlmProvider,\n signal?: AbortSignal,\n): ProviderError {\n // 1. AbortSignal fired. Prefer the signal's own state over the raw\n // error shape — some runtimes throw plain `Error('aborted')`.\n if (signal?.aborted) {\n return makeProviderError({\n kind: 'aborted',\n provider,\n message:\n signal.reason instanceof Error\n ? signal.reason.message\n : typeof signal.reason === 'string'\n ? signal.reason\n : 'request aborted',\n });\n }\n\n // 2. DOMException / Error with name === 'AbortError'.\n if (isAbortLike(raw)) {\n return makeProviderError({\n kind: 'aborted',\n provider,\n message:\n raw instanceof Error && raw.message ? raw.message : 'request aborted',\n });\n }\n\n // 3. TypeError from `fetch` = transport failure (DNS, TCP, TLS).\n // Anything else that is an Error we treat as network by default;\n // adapters map 2xx-parse failures through `invalid-response`\n // EXPLICITLY on the success path, so here network is the\n // conservative bucket.\n if (raw instanceof Error) {\n return makeProviderError({\n kind: 'network',\n provider,\n message: raw.message || 'network failure',\n });\n }\n if (typeof raw === 'string') {\n return makeProviderError({\n kind: 'unknown',\n provider,\n message: raw,\n });\n }\n return makeProviderError({\n kind: 'unknown',\n provider,\n message: 'unknown transport failure',\n });\n}\n\nfunction isAbortLike(raw: unknown): boolean {\n if (!raw || typeof raw !== 'object') return false;\n const obj = raw as Record<string, unknown>;\n return obj['name'] === 'AbortError';\n}\n\n/**\n * Consume a response body once and parse it as JSON. Returns a\n * discriminated union so the caller can branch cleanly on success /\n * JSON parse failure / text body without re-reading the stream.\n *\n * MUST be called at most once per Response — Response bodies can\n * only be read once, and we don't re-stream on failure.\n */\nexport async function readJsonBody(\n response: Response,\n): Promise<\n | { ok: true; json: unknown; text: string }\n | { ok: false; text: string }\n> {\n let text = '';\n try {\n text = await response.text();\n } catch {\n return { ok: false, text: '' };\n }\n if (text.length === 0) {\n return { ok: false, text: '' };\n }\n try {\n const json = JSON.parse(text) as unknown;\n return { ok: true, json, text };\n } catch {\n return { ok: false, text };\n }\n}\n\n/**\n * Build a `ProviderError` for a non-2xx HTTP response. Handles 429\n * `Retry-After` extraction automatically. The `message` field MUST\n * NOT include request body contents — raw response text is truncated\n * + sanitized here so adapters can pass it straight through without\n * worrying about leaking key material they put in the request.\n *\n * (Adapters set the `apiKey` in a request HEADER, not the body — so\n * response-text echo doesn't normally contain the key. Still, truncate\n * to keep log lines readable and remove the theoretical footgun of a\n * provider echoing `Authorization:` back in an error message.)\n */\nexport function errorFromHttpResponse(args: {\n readonly provider: LlmProvider;\n readonly response: Response;\n readonly bodyText: string;\n}): ProviderError {\n const { provider, response, bodyText } = args;\n const status = response.status;\n const kind = statusToErrorKind(status);\n const retryAfter =\n kind === 'rate-limited'\n ? parseRetryAfter(response.headers.get('retry-after'))\n : undefined;\n const snippet = truncateForMessage(bodyText);\n const message = snippet\n ? `${provider}: ${status} ${response.statusText || ''} — ${snippet}`.trim()\n : `${provider}: ${status} ${response.statusText || ''}`.trim();\n return makeProviderError({\n kind,\n provider,\n message,\n status,\n ...(retryAfter !== undefined ? { retryAfterSec: retryAfter } : {}),\n });\n}\n\n/**\n * Truncate a response body snippet to keep log lines + error\n * messages bounded. 240 chars is enough for the typical provider's\n * `{\"error\":{\"message\":\"...\"}}` shape without truncating critical\n * detail; adapters that want the full body can grab it off `bodyText`\n * directly.\n */\nexport function truncateForMessage(text: string, max: number = 240): string {\n if (text.length <= max) return text;\n return `${text.slice(0, max - 1)}…`;\n}\n","/**\n * Concrete Anthropic `ProviderAdapter`.\n *\n * Hits `POST https://api.anthropic.com/v1/messages` directly with\n * native `fetch`. No `@anthropic-ai/sdk` dep — keeping\n * `@ggui-ai/ui-gen` lean is load-bearing; every consumer of the\n * generator contract (OSS + hosted) downloads this package at\n * install time.\n *\n * Wire shape (as of `anthropic-version: 2023-06-01`, stable):\n *\n * Request:\n * POST /v1/messages\n * x-api-key: <apiKey>\n * anthropic-version: 2023-06-01\n * content-type: application/json\n * {\n * model, max_tokens, system, messages: [{role:'user', content}]\n * }\n *\n * Response (200):\n * {\n * content: [{type:'text', text:'...'}],\n * stop_reason: 'end_turn'|'max_tokens'|'stop_sequence'|'tool_use',\n * usage: { input_tokens, output_tokens }\n * }\n *\n * `stop_reason` → `finishReason` normalization (implemented in\n * `./anthropic-wire.ts`, shared with the Bedrock adapter):\n *\n * - `end_turn` / `stop_sequence` → `'stop'`\n * - `max_tokens` → `'length'`\n * - everything else → `'other'`\n *\n * (Anthropic does not surface a distinct `content-filter` stop reason\n * on v1/messages today; filtering shows up as a 400 error with a\n * `permission_error` / `invalid_request_error` body instead. That\n * path maps to `client-error` through `statusToErrorKind`.)\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n defaultValidateConfig,\n makeProviderError,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport { parseAnthropicMessagesResponse } from './anthropic-wire.js';\nimport {\n classifyFetchError,\n errorFromHttpResponse,\n readJsonBody,\n} from './http.js';\n\nconst PROVIDER: LlmProvider = 'anthropic';\nconst DEFAULT_ENDPOINT = 'https://api.anthropic.com/v1/messages';\nconst DEFAULT_API_VERSION = '2023-06-01';\nconst DEFAULT_MAX_TOKENS = 4096;\n\nexport interface AnthropicAdapterOptions {\n /** Override for tests + self-hosted proxies. */\n readonly endpoint?: string;\n /** Override `anthropic-version` header. */\n readonly apiVersion?: string;\n /** Optional fetch override for tests / instrumentation. */\n readonly fetch?: typeof globalThis.fetch;\n}\n\nexport function createAnthropicAdapter(\n options: AnthropicAdapterOptions = {},\n): ProviderAdapter {\n const endpoint = options.endpoint ?? DEFAULT_ENDPOINT;\n const apiVersion = options.apiVersion ?? DEFAULT_API_VERSION;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n function mapError(raw: unknown): ProviderError {\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n return defaultValidateConfig(PROVIDER, request);\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = defaultValidateConfig(PROVIDER, request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return { ok: false, error: classifyFetchError(null, PROVIDER, request.signal) };\n }\n\n let response: Response;\n try {\n response = await fetchImpl(endpoint, {\n method: 'POST',\n headers: {\n 'x-api-key': request.apiKey,\n 'anthropic-version': apiVersion,\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n model: request.route.model,\n max_tokens: request.maxTokens ?? DEFAULT_MAX_TOKENS,\n system: request.systemPrompt,\n messages: [{ role: 'user', content: request.userPrompt }],\n }),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (err) {\n return { ok: false, error: classifyFetchError(err, PROVIDER, request.signal) };\n }\n\n const body = await readJsonBody(response);\n\n if (!response.ok) {\n return {\n ok: false,\n error: errorFromHttpResponse({\n provider: PROVIDER,\n response,\n bodyText: body.ok ? body.text : body.text,\n }),\n };\n }\n\n if (!body.ok) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'anthropic: 2xx response was not JSON',\n }),\n };\n }\n\n // Success-envelope parsing is shared with the Bedrock adapter\n // (same wire shape) — see `./anthropic-wire.ts`.\n const parsed = parseAnthropicMessagesResponse(body.json, PROVIDER);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n","/**\n * Concrete Google (Gemini) `ProviderAdapter`.\n *\n * Uses the Gemini v1beta `generateContent` REST endpoint. No\n * `@google/genai` SDK dep — keeping ui-gen lean.\n *\n * Wire shape:\n *\n * Request:\n * POST /v1beta/models/{model}:generateContent?key={apiKey}\n * content-type: application/json\n * {\n * systemInstruction: { parts: [{ text: systemPrompt }] },\n * contents: [\n * { role: 'user', parts: [{ text: userPrompt }] },\n * ],\n * generationConfig: { maxOutputTokens?: maxTokens },\n * }\n *\n * Response (200):\n * {\n * candidates: [{\n * content: { parts: [{ text: '...' }], role: 'model' },\n * finishReason: 'STOP'|'MAX_TOKENS'|'SAFETY'|'RECITATION'|'OTHER',\n * }],\n * usageMetadata: {\n * promptTokenCount, candidatesTokenCount, totalTokenCount,\n * }\n * }\n *\n * Gemini caveats the harness treats honestly:\n *\n * - 401 on a missing/malformed API key; 403 on quota / model\n * access denied. `statusToErrorKind` handles both.\n * - `?key=` goes in the URL query string per Google's API key\n * convention. The adapter URL-encodes the key defensively — even\n * though keys are typically URL-safe, a paste accident MUST NOT\n * produce a malformed URL that `fetch` would 400 on.\n * - `finishReason` may be `'OTHER'` or absent entirely; we default\n * to `'other'`.\n * - Safety blocks surface as `finishReason: 'SAFETY'` → maps to\n * `'content-filter'`.\n * - Version is `v1beta` because `v1` lacks `systemInstruction`\n * support at time of writing.\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n defaultValidateConfig,\n makeProviderError,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResponse,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport {\n classifyFetchError,\n errorFromHttpResponse,\n readJsonBody,\n} from './http.js';\n\nconst PROVIDER: LlmProvider = 'google';\nconst DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta';\n\nexport interface GoogleAdapterOptions {\n /** Override the API base URL. Test harnesses point at a local mock. */\n readonly baseUrl?: string;\n readonly fetch?: typeof globalThis.fetch;\n}\n\nexport function createGoogleAdapter(\n options: GoogleAdapterOptions = {},\n): ProviderAdapter {\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n function mapError(raw: unknown): ProviderError {\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n return defaultValidateConfig(PROVIDER, request);\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = defaultValidateConfig(PROVIDER, request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return { ok: false, error: classifyFetchError(null, PROVIDER, request.signal) };\n }\n\n const url = `${baseUrl}/models/${encodeURIComponent(request.route.model)}:generateContent?key=${encodeURIComponent(request.apiKey)}`;\n\n const body: Record<string, unknown> = {\n systemInstruction: {\n parts: [{ text: request.systemPrompt }],\n },\n contents: [\n { role: 'user', parts: [{ text: request.userPrompt }] },\n ],\n };\n if (request.maxTokens !== undefined) {\n body['generationConfig'] = { maxOutputTokens: request.maxTokens };\n }\n\n let response: Response;\n try {\n response = await fetchImpl(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (err) {\n return { ok: false, error: classifyFetchError(err, PROVIDER, request.signal) };\n }\n\n const parsedBody = await readJsonBody(response);\n\n if (!response.ok) {\n return {\n ok: false,\n error: errorFromHttpResponse({\n provider: PROVIDER,\n response,\n bodyText: parsedBody.ok ? parsedBody.text : parsedBody.text,\n }),\n };\n }\n\n if (!parsedBody.ok) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'google: 2xx response was not JSON',\n }),\n };\n }\n\n const parsed = parseGoogleResponse(parsedBody.json);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n\nfunction parseGoogleResponse(\n raw: unknown,\n):\n | { ok: true; response: ProviderResponse }\n | { ok: false; error: ProviderError } {\n if (!raw || typeof raw !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'google: response body was not an object',\n }),\n };\n }\n const obj = raw as Record<string, unknown>;\n const candidates = obj['candidates'];\n if (!Array.isArray(candidates) || candidates.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'google: response missing candidates[]',\n }),\n };\n }\n const first = candidates[0] as Record<string, unknown> | undefined;\n if (!first || typeof first !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'google: candidates[0] was not an object',\n }),\n };\n }\n\n const content = first['content'] as Record<string, unknown> | undefined;\n const parts = content && Array.isArray(content['parts']) ? (content['parts'] as unknown[]) : [];\n const text = parts\n .map((p) => {\n if (!p || typeof p !== 'object') return '';\n const part = p as Record<string, unknown>;\n return typeof part['text'] === 'string' ? (part['text'] as string) : '';\n })\n .join('');\n\n const finishRaw = first['finishReason'];\n let finishReason: ProviderResponse['finishReason'];\n if (finishRaw === 'STOP') {\n finishReason = 'stop';\n } else if (finishRaw === 'MAX_TOKENS') {\n finishReason = 'length';\n } else if (finishRaw === 'SAFETY' || finishRaw === 'RECITATION') {\n finishReason = 'content-filter';\n } else {\n finishReason = 'other';\n }\n\n const usage = obj['usageMetadata'] as Record<string, unknown> | undefined;\n const inputTokens =\n usage && typeof usage['promptTokenCount'] === 'number'\n ? (usage['promptTokenCount'] as number)\n : 0;\n const outputTokens =\n usage && typeof usage['candidatesTokenCount'] === 'number'\n ? (usage['candidatesTokenCount'] as number)\n : 0;\n\n return {\n ok: true,\n response: {\n text,\n usage: { inputTokens, outputTokens },\n finishReason,\n },\n };\n}\n","/**\n * Concrete OpenAI `ProviderAdapter`.\n *\n * Hits `POST https://api.openai.com/v1/chat/completions` with native\n * `fetch`. No `openai` SDK dep — same leanness reason as the\n * Anthropic adapter.\n *\n * Wire shape (chat completions v1, stable):\n *\n * Request:\n * POST /v1/chat/completions\n * authorization: Bearer <apiKey>\n * content-type: application/json\n * {\n * model, max_tokens?, messages: [\n * {role:'system', content: systemPrompt},\n * {role:'user', content: userPrompt},\n * ]\n * }\n *\n * Response (200):\n * {\n * choices: [{\n * message: { role: 'assistant', content: '...' },\n * finish_reason: 'stop'|'length'|'content_filter'|'tool_calls'|...,\n * }],\n * usage: { prompt_tokens, completion_tokens, total_tokens }\n * }\n *\n * `finish_reason` → `finishReason` normalization:\n *\n * - `'stop'` → `'stop'`\n * - `'length'` → `'length'`\n * - `'content_filter'` → `'content-filter'`\n * - everything else → `'other'`\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n defaultValidateConfig,\n makeProviderError,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResponse,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport {\n classifyFetchError,\n errorFromHttpResponse,\n readJsonBody,\n} from './http.js';\n\nconst PROVIDER: LlmProvider = 'openai';\nconst DEFAULT_ENDPOINT = 'https://api.openai.com/v1/chat/completions';\n\nexport interface OpenAiAdapterOptions {\n readonly endpoint?: string;\n readonly fetch?: typeof globalThis.fetch;\n}\n\nexport function createOpenAiAdapter(\n options: OpenAiAdapterOptions = {},\n): ProviderAdapter {\n const endpoint = options.endpoint ?? DEFAULT_ENDPOINT;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n function mapError(raw: unknown): ProviderError {\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n return defaultValidateConfig(PROVIDER, request);\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = defaultValidateConfig(PROVIDER, request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return { ok: false, error: classifyFetchError(null, PROVIDER, request.signal) };\n }\n\n let response: Response;\n try {\n response = await fetchImpl(endpoint, {\n method: 'POST',\n headers: {\n authorization: `Bearer ${request.apiKey}`,\n 'content-type': 'application/json',\n },\n body: JSON.stringify(buildOpenAiBody(request)),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (err) {\n return { ok: false, error: classifyFetchError(err, PROVIDER, request.signal) };\n }\n\n const body = await readJsonBody(response);\n\n if (!response.ok) {\n return {\n ok: false,\n error: errorFromHttpResponse({\n provider: PROVIDER,\n response,\n bodyText: body.ok ? body.text : body.text,\n }),\n };\n }\n\n if (!body.ok) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'openai: 2xx response was not JSON',\n }),\n };\n }\n\n const parsed = parseOpenAiResponse(body.json, PROVIDER);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n\n/**\n * Build the OpenAI request body. Exported (package-private) so the\n * OpenRouter adapter can reuse it — OpenRouter is wire-compatible\n * with OpenAI's chat-completions shape.\n *\n * Token-cap parameter selection:\n *\n * - `gpt-5*`, `o1*`, `o3*`, `o4*` (reasoning + new-API models) →\n * `max_completion_tokens`. The legacy `max_tokens` field returns\n * 400 `unsupported_parameter` on these models per the OpenAI 2024-09\n * deprecation: \"Unsupported parameter: 'max_tokens' is not supported\n * with this model. Use 'max_completion_tokens' instead.\"\n * - Everything else (`gpt-4*`, `gpt-3.5*`, etc.) → `max_tokens` for\n * backwards-compat with the chat-completions field that's been\n * stable since 2023.\n *\n * Heuristic chosen over a hard model-list because new gpt-5.x variants\n * ship continuously; the prefix is the contract OpenAI exposes. Same\n * heuristic applies to OpenRouter which wires to backing models — when\n * a caller picks `gpt-5.6-luna` through OpenRouter the same rule fires.\n */\nexport function buildOpenAiBody(request: ProviderRequest): Record<string, unknown> {\n const body: Record<string, unknown> = {\n model: request.route.model,\n messages: [\n { role: 'system', content: request.systemPrompt },\n { role: 'user', content: request.userPrompt },\n ],\n };\n if (request.maxTokens !== undefined) {\n body[selectMaxTokensField(request.route.model)] = request.maxTokens;\n }\n return body;\n}\n\n/**\n * Pick which token-cap field name to send. Bare-string match on the\n * leading model identifier — no SDK lookup, no async; runs once per\n * request body build.\n */\nexport function selectMaxTokensField(model: string): 'max_tokens' | 'max_completion_tokens' {\n const m = model.toLowerCase();\n if (m.startsWith('gpt-5') || m.startsWith('o1') || m.startsWith('o3') || m.startsWith('o4')) {\n return 'max_completion_tokens';\n }\n return 'max_tokens';\n}\n\n/**\n * Parse an OpenAI-shape chat-completions response. Reused by the\n * OpenRouter adapter (wire-compatible).\n */\nexport function parseOpenAiResponse(\n raw: unknown,\n provider: LlmProvider,\n):\n | { ok: true; response: ProviderResponse }\n | { ok: false; error: ProviderError } {\n if (!raw || typeof raw !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: response body was not an object`,\n }),\n };\n }\n const obj = raw as Record<string, unknown>;\n const choices = obj['choices'];\n if (!Array.isArray(choices) || choices.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: response missing choices[]`,\n }),\n };\n }\n const first = choices[0] as Record<string, unknown> | undefined;\n if (!first || typeof first !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: choices[0] was not an object`,\n }),\n };\n }\n\n const message = first['message'] as Record<string, unknown> | undefined;\n const text =\n message && typeof message['content'] === 'string'\n ? (message['content'] as string)\n : '';\n\n const finishRaw = first['finish_reason'];\n let finishReason: ProviderResponse['finishReason'];\n if (finishRaw === 'stop') {\n finishReason = 'stop';\n } else if (finishRaw === 'length') {\n finishReason = 'length';\n } else if (finishRaw === 'content_filter') {\n finishReason = 'content-filter';\n } else {\n finishReason = 'other';\n }\n\n const usage = obj['usage'] as Record<string, unknown> | undefined;\n const inputTokens =\n usage && typeof usage['prompt_tokens'] === 'number'\n ? (usage['prompt_tokens'] as number)\n : 0;\n const outputTokens =\n usage && typeof usage['completion_tokens'] === 'number'\n ? (usage['completion_tokens'] as number)\n : 0;\n\n return {\n ok: true,\n response: {\n text,\n usage: { inputTokens, outputTokens },\n finishReason,\n },\n };\n}\n","/**\n * Concrete OpenRouter `ProviderAdapter`.\n *\n * OpenRouter exposes an OpenAI-compatible chat-completions API at\n * `https://openrouter.ai/api/v1/chat/completions`. Request + response\n * shapes match OpenAI's — so this adapter reuses\n * `buildOpenAiBody` / `parseOpenAiResponse` and just swaps endpoint +\n * recommended headers.\n *\n * OpenRouter-specific:\n * - Model IDs are namespaced: `'anthropic/claude-opus-4'`,\n * `'openai/gpt-4o'`, etc. The OSS generator surface accepts an\n * opaque string — OpenRouter model IDs pass through verbatim.\n * - `HTTP-Referer` + `X-Title` headers are OPTIONAL per OpenRouter's\n * docs but strongly recommended for usage analytics. They DO NOT\n * carry auth — safe to expose publicly. Adapters accept overrides\n * via options; OSS default is `'https://ggui.ai'` / `'ggui'`.\n * - 401 / 402 (insufficient credit) / 429 (rate limit) come back in\n * the same shape as OpenAI — `statusToErrorKind` handles them.\n * 402 maps to `'client-error'` by default; OpenRouter's own\n * `type: 'payment_required'` is surfaced in the message string.\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n defaultValidateConfig,\n makeProviderError,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport {\n classifyFetchError,\n errorFromHttpResponse,\n readJsonBody,\n} from './http.js';\nimport { buildOpenAiBody, parseOpenAiResponse } from './openai.js';\n\nconst PROVIDER: LlmProvider = 'openrouter';\nconst DEFAULT_ENDPOINT = 'https://openrouter.ai/api/v1/chat/completions';\nconst DEFAULT_REFERRER = 'https://ggui.ai';\nconst DEFAULT_TITLE = 'ggui';\n\nexport interface OpenRouterAdapterOptions {\n readonly endpoint?: string;\n readonly referer?: string;\n readonly title?: string;\n readonly fetch?: typeof globalThis.fetch;\n}\n\nexport function createOpenRouterAdapter(\n options: OpenRouterAdapterOptions = {},\n): ProviderAdapter {\n const endpoint = options.endpoint ?? DEFAULT_ENDPOINT;\n const referer = options.referer ?? DEFAULT_REFERRER;\n const title = options.title ?? DEFAULT_TITLE;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n function mapError(raw: unknown): ProviderError {\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n return defaultValidateConfig(PROVIDER, request);\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = defaultValidateConfig(PROVIDER, request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return { ok: false, error: classifyFetchError(null, PROVIDER, request.signal) };\n }\n\n let response: Response;\n try {\n response = await fetchImpl(endpoint, {\n method: 'POST',\n headers: {\n authorization: `Bearer ${request.apiKey}`,\n 'content-type': 'application/json',\n 'HTTP-Referer': referer,\n 'X-Title': title,\n },\n body: JSON.stringify(buildOpenAiBody(request)),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (err) {\n return { ok: false, error: classifyFetchError(err, PROVIDER, request.signal) };\n }\n\n const body = await readJsonBody(response);\n\n if (!response.ok) {\n return {\n ok: false,\n error: errorFromHttpResponse({\n provider: PROVIDER,\n response,\n bodyText: body.ok ? body.text : body.text,\n }),\n };\n }\n\n if (!body.ok) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'openrouter: 2xx response was not JSON',\n }),\n };\n }\n\n const parsed = parseOpenAiResponse(body.json, PROVIDER);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n","/**\n * Concrete AWS Bedrock `ProviderAdapter` — invokes Anthropic Claude\n * models on Bedrock via the official `@anthropic-ai/bedrock-sdk`\n * package. IAM-based auth (no API key in flight); the AWS credential\n * chain (IRSA pod token / `~/.aws/credentials` / env vars) supplies\n * SigV4 signatures automatically.\n *\n * ## Why this adapter exists\n *\n * Anyone running the generator on an AWS-credentialed host (EC2, ECS,\n * Lambda, EKS) can target Bedrock without managing API keys: IAM is\n * the auth boundary, AWS rotates host credentials automatically, and\n * a misconfigured IAM role surfaces as a clear `AccessDeniedException`\n * the SDK funnels through `mapError`. The alternative — parking a\n * provider API key in a secrets store and lazily fetching it on first\n * render — works but adds operational surface (a seed ceremony,\n * key-rotation discipline, a misconfig mode where the secret is\n * empty); Bedrock removes all of it.\n *\n * ## Wire shape\n *\n * The Bedrock SDK's `client.messages.create(...)` mirrors the direct\n * Anthropic API surface 1:1 — same request body fields (`model`,\n * `max_tokens`, `system`, `messages`), same response shape (`content[]`\n * with `{type:'text', text}` blocks, `stop_reason`, `usage`). Both\n * adapters therefore share ONE success-envelope parser —\n * {@link parseAnthropicMessagesResponse} in `./anthropic-wire.ts`.\n * Streaming is supported by the SDK\n * (`client.messages.stream(...)` returns an async iterable) but this\n * adapter uses the non-streaming `create(...)` call to match the\n * single-completion {@link ProviderAdapter} contract; higher layers\n * (`UiGenerator`) compose multi-turn loops above the seam.\n *\n * ## Auth — no API key in `ProviderRequest`\n *\n * The {@link ProviderAdapter} contract types `ProviderRequest.apiKey`\n * as a required string because direct API providers need it on the\n * wire. Bedrock doesn't — the SDK signs requests with AWS credentials\n * resolved at process boot. Two compatible options were considered:\n *\n * 1. Add an `auth: 'apiKey' | 'iam'` discriminator to\n * `ProviderAdapter` + thread it through every adapter.\n * 2. Override `validateConfig` so this adapter accepts (and ignores)\n * whatever the caller puts in `apiKey` — `'iam'` / sentinel /\n * empty string all pass.\n *\n * Option 2 wins on cost: ZERO callers, contract, or tests change.\n * Callers pass a sentinel (e.g. `'bedrock-iam'`) so the model-id\n * check still gates on a non-empty value. Future work could add the\n * discriminator if a third auth mode (e.g. cross-account assume-role)\n * lands.\n *\n * ## Model IDs — pass-through\n *\n * Bedrock and the direct Anthropic API use OVERLAPPING but DISTINCT\n * model id namespaces:\n *\n * - Direct API: `claude-haiku-4-5`, `claude-opus-4-7`, etc.\n * - Bedrock foundation models: `anthropic.claude-sonnet-4-6`\n * - Bedrock cross-region inference profiles: `us.anthropic.claude-haiku-4-5-20251001-v1:0`\n *\n * The adapter passes whatever `request.model` contains straight to\n * Bedrock — translation lives in the caller (model picker / deployment\n * config). Supply a Bedrock foundation-model or inference-profile id,\n * not a direct-API model name.\n *\n * ## Failure mapping\n *\n * The bedrock-sdk throws `APIError` subclasses (`AuthenticationError`,\n * `PermissionDeniedError`, `RateLimitError`, `InternalServerError`,\n * etc.) that all carry a numeric `.status` property. We classify them\n * by structural duck-typing (`typeof err.status === 'number'`) rather\n * than `instanceof Anthropic.APIError` because pnpm hoisting often\n * resolves multiple `@anthropic-ai/sdk` versions across the workspace\n * — the bedrock-sdk's nested SDK and ui-gen's direct SDK can diverge,\n * and `instanceof` then silently returns false for valid errors.\n * Duck-typing on `.status` is robust to that drift and matches the\n * SDK's documented API contract (every subclass exposes `.status`).\n *\n * Transport-shaped errors (`APIConnectionError`, `APIUserAbortError`)\n * carry NO status — they fall through to {@link classifyFetchError}\n * for the standard `network` / `aborted` mapping.\n *\n * AWS-specific failure modes (`AccessDeniedException` — wrong IAM\n * grants; `ThrottlingException` — Bedrock rate limit;\n * `ValidationException` — bad model id) all surface as `APIError`\n * subclasses in the SDK, distinguished by `.status` (403 / 429 / 400\n * respectively).\n */\nimport { AnthropicBedrock } from '@anthropic-ai/bedrock-sdk';\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n makeProviderError,\n statusToErrorKind,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport { parseAnthropicMessagesResponse } from './anthropic-wire.js';\nimport { classifyFetchError } from './http.js';\n\n/**\n * `LlmProvider` slot this adapter targets. Bedrock has its own slot\n * in the `LlmProvider` union (alongside `'anthropic'` direct API) so\n * downstream code can branch on adapter choice — pricing tables,\n * model-id namespaces, and credential-source logging all differ.\n */\nconst PROVIDER: LlmProvider = 'bedrock';\nconst DEFAULT_MAX_TOKENS = 4096;\n\n/**\n * Constructor options for the Bedrock adapter.\n *\n * `region` is the only required option in the common case — IAM\n * credentials come from the standard AWS chain (IRSA pod token in\n * EKS, instance role on EC2, env vars or shared credentials file\n * locally). Tests pass `clientFactory` to inject a mock SDK client.\n */\nexport interface BedrockAdapterOptions {\n /**\n * AWS region for Bedrock invocations. Required for IAM-scoped\n * resource ARNs to resolve (model ARNs include the region;\n * cross-region inference profiles do their own internal failover\n * but the request still has to land in ONE region). Common values:\n * `'us-east-1'`, `'us-west-2'`. Reads from `process.env.AWS_REGION`\n * by default to match the rest of the AWS SDK chain.\n */\n readonly region?: string;\n /**\n * Optional client factory override — used by tests to inject a\n * mock or stub `AnthropicBedrock` client without actually hitting\n * AWS. Production callers leave this unset; the adapter constructs\n * the real client lazily on first `complete(...)` call.\n */\n readonly clientFactory?: (region: string) => AnthropicBedrock;\n}\n\n/**\n * Construct an AWS Bedrock provider adapter.\n *\n * No API key — IAM is the auth boundary. The returned `ProviderAdapter`\n * satisfies the same contract as `createAnthropicAdapter`, so it\n * slots into `createUiGenerator({ adapter })` interchangeably (modulo\n * the per-provider model-id namespace differences).\n */\nexport function createBedrockAdapter(\n options: BedrockAdapterOptions = {},\n): ProviderAdapter {\n const region = options.region ?? process.env['AWS_REGION'] ?? 'us-east-1';\n const clientFactory =\n options.clientFactory ?? ((r: string) => new AnthropicBedrock({ awsRegion: r }));\n\n let cachedClient: AnthropicBedrock | null = null;\n function getClient(): AnthropicBedrock {\n if (cachedClient) return cachedClient;\n cachedClient = clientFactory(region);\n return cachedClient;\n }\n\n function mapError(raw: unknown): ProviderError {\n // Structural duck-typing: every SDK `APIError` subclass with a\n // server response carries a numeric `.status` property. We check\n // for that field (rather than `instanceof Anthropic.APIError`) to\n // dodge the pnpm-hoist version-drift footgun documented at the\n // top of this file. Aborted / transport errors lack `.status` and\n // fall through to `classifyFetchError`.\n if (raw && typeof raw === 'object' && 'status' in raw) {\n const status = (raw as { status: unknown }).status;\n if (typeof status === 'number' && status > 0) {\n const name = raw instanceof Error ? raw.name : 'APIError';\n const message = raw instanceof Error ? raw.message : String(raw);\n return makeProviderError({\n kind: statusToErrorKind(status),\n provider: PROVIDER,\n message: `bedrock: ${status} ${name} — ${message}`,\n status,\n });\n }\n }\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n /**\n * Validate Bedrock-specific config. Differs from\n * `defaultValidateConfig` because Bedrock has NO request-level\n * API key — `request.apiKey` is ignored (callers pass a sentinel\n * like `'bedrock-iam'` so the type contract holds).\n * Only the model id is required to be non-empty; auth issues\n * surface from the SDK as `AccessDeniedException` at call time.\n */\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n if (!request.route?.model || request.route.model.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'client-error',\n provider: PROVIDER,\n message: 'bedrock: model id is required',\n }),\n };\n }\n return { ok: true };\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = this.validateConfig(request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return {\n ok: false,\n error: classifyFetchError(null, PROVIDER, request.signal),\n };\n }\n\n const client = getClient();\n // The SDK's `Message` return type drifts between\n // `@anthropic-ai/sdk` versions (pnpm hoists multiple copies in\n // this workspace today). We type the captured value as\n // `unknown` here and let `parseAnthropicMessagesResponse`\n // validate the narrow shape we actually consume — fields beyond\n // `content` / `stop_reason` / `usage` are version-volatile\n // (thinking blocks, tool-use blocks, beta-feature additions)\n // and not load-bearing for the harness's single-completion\n // contract.\n let raw: unknown;\n try {\n raw = await client.messages.create(\n {\n model: request.route.model,\n max_tokens: request.maxTokens ?? DEFAULT_MAX_TOKENS,\n system: request.systemPrompt,\n messages: [{ role: 'user', content: request.userPrompt }],\n },\n {\n // SDK forwards `signal` into the underlying fetch — same\n // abort semantics as the direct-API adapter.\n ...(request.signal ? { signal: request.signal } : {}),\n },\n );\n } catch (err) {\n // Re-check signal first — aborted-during-await loses the abort\n // signal in the SDK's error wrapping on some runtimes.\n if (request.signal?.aborted) {\n return {\n ok: false,\n error: classifyFetchError(err, PROVIDER, request.signal),\n };\n }\n return { ok: false, error: mapError(err) };\n }\n\n // Success-envelope parsing is shared with the direct-API\n // adapter — Bedrock's Anthropic-flavored endpoint returns the\n // identical envelope as `api.anthropic.com/v1/messages`. See\n // `./anthropic-wire.ts`. (Takes `unknown` rather than the SDK's\n // `Message` type so the adapter is robust to SDK version drift\n // across pnpm-hoisted copies — see the failure-mapping\n // docstring above for context.)\n const parsed = parseAnthropicMessagesResponse(raw, PROVIDER);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n","/**\n * Public barrel for `@ggui-ai/ui-gen/providers`.\n *\n * Concrete {@link ProviderAdapter} implementations for the LLM\n * providers ggui supports today: Anthropic (direct API), Google,\n * OpenAI, OpenRouter, and AWS Bedrock (Anthropic models via IAM).\n *\n * Every adapter satisfies the structural\n * {@link import('../provider-adapter.js').ProviderAdapter} contract.\n * The four direct-API adapters compose\n * `defaultValidateConfig` + `makeProviderError` + `statusToErrorKind`\n * + the shared helpers in `./http.ts` and pull NO vendor SDK (~10MB\n * savings). Bedrock is the exception — it pulls\n * `@anthropic-ai/bedrock-sdk` (a zero-dep package over native fetch)\n * because rolling our own AWS SigV4 signer for one provider isn't a\n * reasonable trade.\n *\n * Typical usage from the CLI:\n *\n * ```ts\n * import { createAnthropicAdapter } from '@ggui-ai/ui-gen/providers';\n * import { createUiGenerator } from '@ggui-ai/ui-gen';\n *\n * const adapter = createAnthropicAdapter();\n * const generator = createUiGenerator({ adapter });\n * const result = await generator.generate({ request, llm, providerKey, blueprints });\n * ```\n *\n * Bedrock pool path (no API key — IAM at process boot):\n *\n * ```ts\n * import { createBedrockAdapter } from '@ggui-ai/ui-gen/providers';\n * const adapter = createBedrockAdapter({ region: 'us-east-1' });\n * // pass `providerKey: { provider: 'bedrock', key: 'bedrock-iam' }`\n * // (sentinel — adapter ignores; satisfies the non-empty contract).\n * ```\n */\nexport { createAnthropicAdapter } from './anthropic.js';\nexport type { AnthropicAdapterOptions } from './anthropic.js';\n\nexport { createGoogleAdapter } from './google.js';\nexport type { GoogleAdapterOptions } from './google.js';\n\nexport { createOpenAiAdapter } from './openai.js';\nexport type { OpenAiAdapterOptions } from './openai.js';\n\nexport { createOpenRouterAdapter } from './openrouter.js';\nexport type { OpenRouterAdapterOptions } from './openrouter.js';\n\nexport { createBedrockAdapter } from './bedrock.js';\nexport type { BedrockAdapterOptions } from './bedrock.js';\n\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport type { ProviderAdapter } from '../provider-adapter.js';\nimport { createAnthropicAdapter } from './anthropic.js';\nimport { createGoogleAdapter } from './google.js';\nimport { createOpenAiAdapter } from './openai.js';\nimport { createOpenRouterAdapter } from './openrouter.js';\nimport { createBedrockAdapter } from './bedrock.js';\n\n/**\n * Construct the default adapter for a given provider. Every entry in\n * the `LlmProvider` union now has a concrete adapter — Bedrock joined\n * the open surface because it's the cleanest pool-path\n * (`mcp.ggui.ai` free-credit) story (IAM auth, no API key in flight,\n * AWS-managed cost reporting).\n *\n * Callers that want custom options (test fetch, proxy endpoint,\n * OpenRouter referer, Bedrock region) should construct the concrete\n * adapter directly — this helper is a sensible default for the\n * common case.\n */\nexport function selectAdapter(provider: LlmProvider): ProviderAdapter {\n switch (provider) {\n case 'anthropic':\n return createAnthropicAdapter();\n case 'google':\n return createGoogleAdapter();\n case 'openai':\n return createOpenAiAdapter();\n case 'openrouter':\n return createOpenRouterAdapter();\n case 'bedrock':\n return createBedrockAdapter();\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/provider-adapter.ts","../../src/providers/anthropic-wire.ts","../../src/providers/http.ts","../../src/providers/anthropic.ts","../../src/providers/google.ts","../../src/providers/openai.ts","../../src/providers/openrouter.ts","../../src/providers/bedrock.ts","../../src/providers/index.ts"],"names":["PROVIDER","DEFAULT_ENDPOINT","DEFAULT_MAX_TOKENS"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Provider adapter contract — the narrow surface every concrete LLM\n * provider client (Anthropic, Google, OpenAI, OpenRouter) implements\n * before the generator wires them in.\n *\n * The contract is deliberately defined independently of concrete\n * adapters so:\n *\n * - Adapter implementations can be written against a stable surface —\n * every concrete adapter MUST pass\n * {@link providerAdapterContract} or it isn't a `ProviderAdapter`.\n * - Downstream callers (`createUiGenerator`, render handlers, retry /\n * backoff plumbing) build against ONE structured failure shape\n * ({@link ProviderError}) instead of inventing per-provider error\n * UX.\n * - The negotiator + cache layers can branch on\n * `error.kind === 'rate-limited'` etc. without parsing strings.\n *\n * **Scope:**\n *\n * - Defines the interface, the response shape, the error shape,\n * and a contract test runner that asserts every adapter\n * satisfies the seam.\n * - Does NOT call any LLM. The contract is structural; this\n * package's own tests exercise the runner against a deterministic\n * fixture adapter (`provider-adapter-mock.test-util.ts`).\n *\n * **Design choices, locked:**\n *\n * - One discriminated `ProviderError.kind` union, not per-provider\n * subclasses. Every provider's raw error funnels through\n * `mapError` into one of these kinds. Callers branch on `kind`.\n * - Every error carries `provider` + `message`; transport-shaped\n * errors carry `status`; backoff-shaped errors carry\n * `retryAfterSec`. Optional fields don't appear when they don't\n * apply (no `status: undefined` noise in serialized logs).\n * - `validateConfig` is synchronous + does NO I/O. It catches the\n * \"operator never configured the provider\" case (missing key,\n * malformed model id) before we attempt a network call.\n * - `complete` is the single-completion seam. Streaming, tool\n * calling, function calling, and harness retry land in higher\n * layers — adapters stay narrow.\n */\nimport type { LlmProvider, LlmRoute } from '@ggui-ai/protocol';\n\n/**\n * One LLM completion request as the adapter sees it. Plain data so\n * tests can construct it without DI.\n *\n * `route` is a discriminated `LlmRoute` — `(provider, model)` typed\n * together so the model id is structurally constrained to its\n * provider's namespace (per the `MODELS` registry in\n * `@ggui-ai/protocol/types/llm-route`). This makes the #22 / #42 bug\n * class — passing a LiteLLM-prefixed `'anthropic/claude-haiku-4-5'`\n * where Anthropic expected the wire id `'claude-haiku-4-5-20251001'` —\n * a compile error at every adapter call site. The adapter reads the\n * wire-canonical string off `request.route.model` and passes it\n * verbatim to the provider SDK; no transformation step exists to\n * forget.\n */\nexport interface ProviderRequest {\n /** API key. Resolved upstream by `@ggui-ai/cli/byok-resolver`. */\n readonly apiKey: string;\n /**\n * Discriminated `(provider, model)` route. `route.model` is the\n * wire-canonical id the provider's API expects — adapters pass it\n * verbatim with no stripping or remapping.\n */\n readonly route: LlmRoute;\n /** System prompt text. Adapter wires it into the provider's slot. */\n readonly systemPrompt: string;\n /** User prompt text. */\n readonly userPrompt: string;\n /**\n * Optional cap on output tokens. Adapters MUST honor when the\n * provider supports it; when absent, adapters use the provider\n * default.\n */\n readonly maxTokens?: number;\n /**\n * Optional cancellation. Adapters MUST forward into the provider\n * SDK's abort surface and reject with `ProviderError{kind:'aborted'}`\n * when fired.\n */\n readonly signal?: AbortSignal;\n}\n\n/**\n * Successful provider response, normalized.\n *\n * Tool-calling output, multi-turn dialogue, structured-output\n * coercion all land in higher layers — this contract intentionally\n * stays narrow: text + usage + finish reason. The harness layer\n * composes adapters into multi-turn loops.\n */\nexport interface ProviderResponse {\n /** The completion text returned by the provider. */\n readonly text: string;\n /** Token usage, per-call. Required — adapters synthesize 0 if the\n * provider didn't report it (and document that in their adapter). */\n readonly usage: {\n readonly inputTokens: number;\n readonly outputTokens: number;\n };\n /**\n * Why the model stopped. Mapped through a normalized union so\n * callers don't have to know each provider's vocabulary.\n *\n * - `'stop'` model emitted EOS / stop sequence\n * - `'length'` hit `maxTokens` or provider context limit\n * - `'content-filter'` provider safety filter intervened\n * - `'other'` anything else (provider-specific reason)\n */\n readonly finishReason: 'stop' | 'length' | 'content-filter' | 'other';\n}\n\n/**\n * The structured failure contract. Every concrete adapter's\n * `mapError` MUST funnel raw provider errors into this shape so\n * downstream code branches on `kind`, not on string parsing.\n *\n * Discriminator + optional carriers:\n *\n * - `'no-credentials'` — no key supplied (pre-flight failure;\n * usually surfaced by `validateConfig`,\n * not `mapError`).\n * - `'unauthorized'` — provider returned 401. Key invalid /\n * revoked / wrong type.\n * - `'forbidden'` — provider returned 403. Quota exhausted,\n * org-level block, model not allowed for\n * this key. (Distinct from 401 because\n * \"rotate the key\" doesn't help.)\n * - `'rate-limited'` — provider returned 429. Carries\n * `retryAfterSec` when the provider\n * advertised one (`Retry-After` header).\n * - `'server-error'` — provider returned 5xx. Retryable.\n * - `'client-error'` — provider returned other 4xx. Usually\n * non-retryable (bad model id, malformed\n * request).\n * - `'network'` — TCP-level failure, DNS, EAI_AGAIN, etc.\n * No `status`. Retryable.\n * - `'invalid-response'` — provider returned 2xx with a body the\n * adapter couldn't parse. Bug in the\n * adapter or in the provider; treat as\n * non-retryable.\n * - `'aborted'` — caller aborted via `signal`.\n * - `'unknown'` — last-resort bucket. Adapters that hit\n * this should be patched to map the\n * specific case explicitly.\n */\nexport type ProviderErrorKind =\n | 'no-credentials'\n | 'unauthorized'\n | 'forbidden'\n | 'rate-limited'\n | 'server-error'\n | 'client-error'\n | 'network'\n | 'invalid-response'\n | 'aborted'\n | 'unknown';\n\nexport interface ProviderError {\n readonly kind: ProviderErrorKind;\n readonly provider: LlmProvider;\n /** Human-readable message. Safe to log; should not contain key\n * material — adapters MUST scrub before placing here. */\n readonly message: string;\n /** HTTP status when transport-shaped. Absent for pre-flight,\n * network, aborted, invalid-response. */\n readonly status?: number;\n /**\n * Seconds to wait before retrying. Set ONLY for `'rate-limited'`\n * when the provider advertised a `Retry-After` header. Higher-level\n * retry policy uses this when present; falls back to its own\n * exponential backoff when absent.\n */\n readonly retryAfterSec?: number;\n}\n\n/**\n * Pre-flight config validation. Synchronous, no I/O. Catches:\n *\n * - missing or empty API key → no-credentials\n * - missing or empty model id → client-error\n *\n * Adapters MAY widen the check with provider-specific rules\n * (e.g. \"openrouter model id MUST contain a `/`\"). Failures\n * surface through the same {@link ProviderError} so callers branch\n * on one union.\n */\nexport type ProviderValidation =\n | { readonly ok: true }\n | { readonly ok: false; readonly error: ProviderError };\n\n/**\n * The contract every provider client implements.\n */\nexport interface ProviderAdapter {\n /** Provider this adapter speaks to. Stable identifier; lets the\n * caller route a `ProviderRequest` to the right adapter. */\n readonly provider: LlmProvider;\n /**\n * Pre-flight check. MUST return synchronously and MUST NOT touch\n * the network. Returns `{ok: true}` when the request is at least\n * structurally valid; returns `{ok: false, error}` otherwise.\n */\n validateConfig(request: Pick<ProviderRequest, 'apiKey' | 'route'>): ProviderValidation;\n /**\n * Single-completion call. Resolves with `{ok: true, response}` on\n * success or `{ok: false, error}` on any failure (network,\n * provider 4xx/5xx, abort). Implementations MUST:\n *\n * 1. Funnel every raw provider error through `mapError`.\n * 2. NOT throw. The result discriminator IS the error path.\n * 3. Forward `request.signal` into the provider SDK's abort\n * mechanism + return `kind:'aborted'` when fired.\n */\n complete(request: ProviderRequest): Promise<ProviderResult>;\n /**\n * Map an arbitrary thrown / rejected value into a\n * {@link ProviderError}. Exposed (not just internal) so test\n * harnesses + retry policies can normalize errors without going\n * through `complete`.\n *\n * MUST NEVER throw — `mapError(unknown)` is the safety net.\n */\n mapError(raw: unknown): ProviderError;\n}\n\n/**\n * Discriminated result of a `complete` call. Mirrors `validateConfig`\n * so callers never have to handle thrown errors from this seam.\n */\nexport type ProviderResult =\n | { readonly ok: true; readonly response: ProviderResponse }\n | { readonly ok: false; readonly error: ProviderError };\n\n// ─── Helpers concrete adapters compose with ────────────────────────\n\n/**\n * Build a `ProviderError` of the supplied kind. Centralized so\n * concrete adapters don't drift on field shape. Provider-aware so\n * callers don't have to thread it through.\n */\nexport function makeProviderError(args: {\n readonly kind: ProviderErrorKind;\n readonly provider: LlmProvider;\n readonly message: string;\n readonly status?: number;\n readonly retryAfterSec?: number;\n}): ProviderError {\n const out: ProviderError = {\n kind: args.kind,\n provider: args.provider,\n message: args.message,\n ...(args.status !== undefined ? { status: args.status } : {}),\n ...(args.retryAfterSec !== undefined\n ? { retryAfterSec: args.retryAfterSec }\n : {}),\n };\n return out;\n}\n\n/**\n * Map an HTTP status code to the canonical error kind. Adapters\n * call this from `mapError` after they've classified the failure as\n * \"the provider returned a status we understand\". Network / abort /\n * pre-flight live outside this mapping.\n */\nexport function statusToErrorKind(status: number): ProviderErrorKind {\n if (status === 401) return 'unauthorized';\n if (status === 403) return 'forbidden';\n if (status === 429) return 'rate-limited';\n if (status >= 500 && status < 600) return 'server-error';\n if (status >= 400 && status < 500) return 'client-error';\n return 'unknown';\n}\n\n/**\n * Default `validateConfig` implementation. Concrete adapters\n * compose this and add their own provider-specific checks on top.\n *\n * Catches the two universal failures: missing key + missing model.\n * Returns `{ok: true}` when both are present.\n *\n * The model-id check is defense-in-depth — typed `LlmRoute` callers\n * cannot construct a route with an empty model string, but the\n * adapter still validates at runtime in case the request crossed an\n * untyped JSON boundary (e.g. deserialized from a wire format).\n */\nexport function defaultValidateConfig(\n provider: LlmProvider,\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n): ProviderValidation {\n if (!request.apiKey || request.apiKey.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'no-credentials',\n provider,\n message: `${provider}: no API key supplied`,\n }),\n };\n }\n if (!request.route?.model || request.route.model.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'client-error',\n provider,\n message: `${provider}: model id is required`,\n }),\n };\n }\n return { ok: true };\n}\n","/**\n * Shared parser for the Anthropic Messages success envelope.\n *\n * Two adapters consume the SAME wire shape: the direct-API adapter\n * (`./anthropic.ts`, `POST api.anthropic.com/v1/messages`) and the\n * Bedrock adapter (`./bedrock.ts` — Bedrock's Anthropic-flavored\n * endpoint returns the identical envelope). One parser, two callers;\n * the only per-adapter variance is the `provider` prefix on error\n * messages.\n *\n * Takes `unknown` (rather than any SDK `Message` type) so callers are\n * robust to SDK version drift across pnpm-hoisted copies.\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n makeProviderError,\n type ProviderError,\n type ProviderResponse,\n} from '../provider-adapter.js';\n\n/**\n * Parse an Anthropic Messages response body into the normalized\n * {@link ProviderResponse} shape.\n *\n * `stop_reason` → `finishReason` normalization:\n *\n * - `end_turn` / `stop_sequence` → `'stop'`\n * - `max_tokens` → `'length'`\n * - everything else → `'other'` (`tool_use`,\n * `pause_turn`, `refusal`, future stop reasons all bucket here —\n * content-filter surfaces via 4xx errors on Anthropic, not\n * `stop_reason`)\n */\nexport function parseAnthropicMessagesResponse(\n raw: unknown,\n provider: LlmProvider,\n):\n | { ok: true; response: ProviderResponse }\n | { ok: false; error: ProviderError } {\n if (!raw || typeof raw !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: response body was not an object`,\n }),\n };\n }\n const obj = raw as Record<string, unknown>;\n const content = obj['content'];\n if (!Array.isArray(content)) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: response missing \\`content\\` array`,\n }),\n };\n }\n\n // Concatenate every text block. Anthropic sometimes splits a\n // response across multiple text blocks; tool_use / thinking blocks\n // (when present) are filtered out — the single-completion contract\n // here doesn't surface them.\n const text = content\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const b = block as Record<string, unknown>;\n if (b['type'] === 'text' && typeof b['text'] === 'string') {\n return b['text'] as string;\n }\n return '';\n })\n .join('');\n\n const usage = obj['usage'] as Record<string, unknown> | undefined;\n const inputTokens =\n usage && typeof usage['input_tokens'] === 'number'\n ? (usage['input_tokens'] as number)\n : 0;\n const outputTokens =\n usage && typeof usage['output_tokens'] === 'number'\n ? (usage['output_tokens'] as number)\n : 0;\n\n const stopReason = obj['stop_reason'];\n let finishReason: ProviderResponse['finishReason'];\n if (stopReason === 'end_turn' || stopReason === 'stop_sequence') {\n finishReason = 'stop';\n } else if (stopReason === 'max_tokens') {\n finishReason = 'length';\n } else {\n finishReason = 'other';\n }\n\n return {\n ok: true,\n response: {\n text,\n usage: { inputTokens, outputTokens },\n finishReason,\n },\n };\n}\n","/**\n * Shared fetch helpers for concrete provider adapters.\n *\n * Every adapter uses native Node `fetch` (Node 20+ has it global).\n * Heavy provider SDKs are intentionally NOT pulled in — the OSS\n * `@ggui-ai/ui-gen` stays lean, and each adapter is a thin REST\n * wrapper over the contract locked in `../provider-adapter.ts`.\n *\n * The helpers here centralize the three cross-cutting concerns every\n * adapter shares:\n *\n * 1. Parse a `Retry-After` header (seconds OR HTTP-date) into a\n * monotonic seconds number. Used when the provider returns 429.\n * 2. Classify a caught `fetch` rejection into `aborted` / `network` /\n * `unknown` without the adapter re-deriving the rules.\n * 3. Read a response body at most once and parse JSON defensively so\n * `invalid-response` maps cleanly when the server returns 2xx with\n * a non-JSON body.\n *\n * These helpers NEVER throw — every path returns a value. Adapters\n * funnel every raw throw through `mapError`, which itself never\n * throws, per the ProviderAdapter contract.\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n makeProviderError,\n statusToErrorKind,\n type ProviderError,\n} from '../provider-adapter.js';\n\n/**\n * Parse a `Retry-After` header value into positive seconds.\n * Accepts either a numeric seconds string (`\"30\"`) or an HTTP-date\n * (`\"Wed, 21 Oct 2026 07:28:00 GMT\"`). Returns `undefined` on\n * anything unparseable — callers treat absence as \"no hint, fall back\n * to exponential backoff\".\n */\nexport function parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n // Seconds form.\n const asNumber = Number(trimmed);\n if (Number.isFinite(asNumber) && asNumber > 0) {\n return Math.ceil(asNumber);\n }\n // HTTP-date form. `Date.parse` returns NaN on malformed.\n const asDate = Date.parse(trimmed);\n if (!Number.isFinite(asDate)) return undefined;\n const deltaMs = asDate - Date.now();\n if (deltaMs <= 0) return undefined;\n return Math.ceil(deltaMs / 1000);\n}\n\n/**\n * Classify a raw value thrown by `fetch` (or an adapter's internal\n * parse step) into a {@link ProviderError}. Order of checks matters —\n * abort first so aborted network calls don't look like generic\n * network failures.\n */\nexport function classifyFetchError(\n raw: unknown,\n provider: LlmProvider,\n signal?: AbortSignal,\n): ProviderError {\n // 1. AbortSignal fired. Prefer the signal's own state over the raw\n // error shape — some runtimes throw plain `Error('aborted')`.\n if (signal?.aborted) {\n return makeProviderError({\n kind: 'aborted',\n provider,\n message:\n signal.reason instanceof Error\n ? signal.reason.message\n : typeof signal.reason === 'string'\n ? signal.reason\n : 'request aborted',\n });\n }\n\n // 2. DOMException / Error with name === 'AbortError'.\n if (isAbortLike(raw)) {\n return makeProviderError({\n kind: 'aborted',\n provider,\n message:\n raw instanceof Error && raw.message ? raw.message : 'request aborted',\n });\n }\n\n // 3. TypeError from `fetch` = transport failure (DNS, TCP, TLS).\n // Anything else that is an Error we treat as network by default;\n // adapters map 2xx-parse failures through `invalid-response`\n // EXPLICITLY on the success path, so here network is the\n // conservative bucket.\n if (raw instanceof Error) {\n return makeProviderError({\n kind: 'network',\n provider,\n message: raw.message || 'network failure',\n });\n }\n if (typeof raw === 'string') {\n return makeProviderError({\n kind: 'unknown',\n provider,\n message: raw,\n });\n }\n return makeProviderError({\n kind: 'unknown',\n provider,\n message: 'unknown transport failure',\n });\n}\n\nfunction isAbortLike(raw: unknown): boolean {\n if (!raw || typeof raw !== 'object') return false;\n const obj = raw as Record<string, unknown>;\n return obj['name'] === 'AbortError';\n}\n\n/**\n * Consume a response body once and parse it as JSON. Returns a\n * discriminated union so the caller can branch cleanly on success /\n * JSON parse failure / text body without re-reading the stream.\n *\n * MUST be called at most once per Response — Response bodies can\n * only be read once, and we don't re-stream on failure.\n */\nexport async function readJsonBody(\n response: Response,\n): Promise<\n | { ok: true; json: unknown; text: string }\n | { ok: false; text: string }\n> {\n let text = '';\n try {\n text = await response.text();\n } catch {\n return { ok: false, text: '' };\n }\n if (text.length === 0) {\n return { ok: false, text: '' };\n }\n try {\n const json = JSON.parse(text) as unknown;\n return { ok: true, json, text };\n } catch {\n return { ok: false, text };\n }\n}\n\n/**\n * Build a `ProviderError` for a non-2xx HTTP response. Handles 429\n * `Retry-After` extraction automatically. The `message` field MUST\n * NOT include request body contents — raw response text is truncated\n * + sanitized here so adapters can pass it straight through without\n * worrying about leaking key material they put in the request.\n *\n * (Adapters set the `apiKey` in a request HEADER, not the body — so\n * response-text echo doesn't normally contain the key. Still, truncate\n * to keep log lines readable and remove the theoretical footgun of a\n * provider echoing `Authorization:` back in an error message.)\n */\nexport function errorFromHttpResponse(args: {\n readonly provider: LlmProvider;\n readonly response: Response;\n readonly bodyText: string;\n}): ProviderError {\n const { provider, response, bodyText } = args;\n const status = response.status;\n const kind = statusToErrorKind(status);\n const retryAfter =\n kind === 'rate-limited'\n ? parseRetryAfter(response.headers.get('retry-after'))\n : undefined;\n const snippet = truncateForMessage(bodyText);\n const message = snippet\n ? `${provider}: ${status} ${response.statusText || ''} — ${snippet}`.trim()\n : `${provider}: ${status} ${response.statusText || ''}`.trim();\n return makeProviderError({\n kind,\n provider,\n message,\n status,\n ...(retryAfter !== undefined ? { retryAfterSec: retryAfter } : {}),\n });\n}\n\n/**\n * Truncate a response body snippet to keep log lines + error\n * messages bounded. 240 chars is enough for the typical provider's\n * `{\"error\":{\"message\":\"...\"}}` shape without truncating critical\n * detail; adapters that want the full body can grab it off `bodyText`\n * directly.\n */\nexport function truncateForMessage(text: string, max: number = 240): string {\n if (text.length <= max) return text;\n return `${text.slice(0, max - 1)}…`;\n}\n","/**\n * Concrete Anthropic `ProviderAdapter`.\n *\n * Hits `POST https://api.anthropic.com/v1/messages` directly with\n * native `fetch`. No `@anthropic-ai/sdk` dep — keeping\n * `@ggui-ai/ui-gen` lean is load-bearing; every consumer of the\n * generator contract (OSS + hosted) downloads this package at\n * install time.\n *\n * Wire shape (as of `anthropic-version: 2023-06-01`, stable):\n *\n * Request:\n * POST /v1/messages\n * x-api-key: <apiKey>\n * anthropic-version: 2023-06-01\n * content-type: application/json\n * {\n * model, max_tokens, system, messages: [{role:'user', content}]\n * }\n *\n * Response (200):\n * {\n * content: [{type:'text', text:'...'}],\n * stop_reason: 'end_turn'|'max_tokens'|'stop_sequence'|'tool_use',\n * usage: { input_tokens, output_tokens }\n * }\n *\n * `stop_reason` → `finishReason` normalization (implemented in\n * `./anthropic-wire.ts`, shared with the Bedrock adapter):\n *\n * - `end_turn` / `stop_sequence` → `'stop'`\n * - `max_tokens` → `'length'`\n * - everything else → `'other'`\n *\n * (Anthropic does not surface a distinct `content-filter` stop reason\n * on v1/messages today; filtering shows up as a 400 error with a\n * `permission_error` / `invalid_request_error` body instead. That\n * path maps to `client-error` through `statusToErrorKind`.)\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n defaultValidateConfig,\n makeProviderError,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport { parseAnthropicMessagesResponse } from './anthropic-wire.js';\nimport {\n classifyFetchError,\n errorFromHttpResponse,\n readJsonBody,\n} from './http.js';\n\nconst PROVIDER: LlmProvider = 'anthropic';\nconst DEFAULT_ENDPOINT = 'https://api.anthropic.com/v1/messages';\nconst DEFAULT_API_VERSION = '2023-06-01';\nconst DEFAULT_MAX_TOKENS = 4096;\n\nexport interface AnthropicAdapterOptions {\n /** Override for tests + self-hosted proxies. */\n readonly endpoint?: string;\n /** Override `anthropic-version` header. */\n readonly apiVersion?: string;\n /** Optional fetch override for tests / instrumentation. */\n readonly fetch?: typeof globalThis.fetch;\n}\n\nexport function createAnthropicAdapter(\n options: AnthropicAdapterOptions = {},\n): ProviderAdapter {\n const endpoint = options.endpoint ?? DEFAULT_ENDPOINT;\n const apiVersion = options.apiVersion ?? DEFAULT_API_VERSION;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n function mapError(raw: unknown): ProviderError {\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n return defaultValidateConfig(PROVIDER, request);\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = defaultValidateConfig(PROVIDER, request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return { ok: false, error: classifyFetchError(null, PROVIDER, request.signal) };\n }\n\n let response: Response;\n try {\n response = await fetchImpl(endpoint, {\n method: 'POST',\n headers: {\n 'x-api-key': request.apiKey,\n 'anthropic-version': apiVersion,\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n model: request.route.model,\n max_tokens: request.maxTokens ?? DEFAULT_MAX_TOKENS,\n system: request.systemPrompt,\n messages: [{ role: 'user', content: request.userPrompt }],\n }),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (err) {\n return { ok: false, error: classifyFetchError(err, PROVIDER, request.signal) };\n }\n\n const body = await readJsonBody(response);\n\n if (!response.ok) {\n return {\n ok: false,\n error: errorFromHttpResponse({\n provider: PROVIDER,\n response,\n bodyText: body.ok ? body.text : body.text,\n }),\n };\n }\n\n if (!body.ok) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'anthropic: 2xx response was not JSON',\n }),\n };\n }\n\n // Success-envelope parsing is shared with the Bedrock adapter\n // (same wire shape) — see `./anthropic-wire.ts`.\n const parsed = parseAnthropicMessagesResponse(body.json, PROVIDER);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n","/**\n * Concrete Google (Gemini) `ProviderAdapter`.\n *\n * Uses the Gemini v1beta `generateContent` REST endpoint. No\n * `@google/genai` SDK dep — keeping ui-gen lean.\n *\n * Wire shape:\n *\n * Request:\n * POST /v1beta/models/{model}:generateContent?key={apiKey}\n * content-type: application/json\n * {\n * systemInstruction: { parts: [{ text: systemPrompt }] },\n * contents: [\n * { role: 'user', parts: [{ text: userPrompt }] },\n * ],\n * generationConfig: { maxOutputTokens?: maxTokens },\n * }\n *\n * Response (200):\n * {\n * candidates: [{\n * content: { parts: [{ text: '...' }], role: 'model' },\n * finishReason: 'STOP'|'MAX_TOKENS'|'SAFETY'|'RECITATION'|'OTHER',\n * }],\n * usageMetadata: {\n * promptTokenCount, candidatesTokenCount, totalTokenCount,\n * }\n * }\n *\n * Gemini caveats the harness treats honestly:\n *\n * - 401 on a missing/malformed API key; 403 on quota / model\n * access denied. `statusToErrorKind` handles both.\n * - `?key=` goes in the URL query string per Google's API key\n * convention. The adapter URL-encodes the key defensively — even\n * though keys are typically URL-safe, a paste accident MUST NOT\n * produce a malformed URL that `fetch` would 400 on.\n * - `finishReason` may be `'OTHER'` or absent entirely; we default\n * to `'other'`.\n * - Safety blocks surface as `finishReason: 'SAFETY'` → maps to\n * `'content-filter'`.\n * - Version is `v1beta` because `v1` lacks `systemInstruction`\n * support at time of writing.\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n defaultValidateConfig,\n makeProviderError,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResponse,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport {\n classifyFetchError,\n errorFromHttpResponse,\n readJsonBody,\n} from './http.js';\n\nconst PROVIDER: LlmProvider = 'google';\nconst DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta';\n\nexport interface GoogleAdapterOptions {\n /** Override the API base URL. Test harnesses point at a local mock. */\n readonly baseUrl?: string;\n readonly fetch?: typeof globalThis.fetch;\n}\n\nexport function createGoogleAdapter(\n options: GoogleAdapterOptions = {},\n): ProviderAdapter {\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n function mapError(raw: unknown): ProviderError {\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n return defaultValidateConfig(PROVIDER, request);\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = defaultValidateConfig(PROVIDER, request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return { ok: false, error: classifyFetchError(null, PROVIDER, request.signal) };\n }\n\n const url = `${baseUrl}/models/${encodeURIComponent(request.route.model)}:generateContent?key=${encodeURIComponent(request.apiKey)}`;\n\n const body: Record<string, unknown> = {\n systemInstruction: {\n parts: [{ text: request.systemPrompt }],\n },\n contents: [\n { role: 'user', parts: [{ text: request.userPrompt }] },\n ],\n };\n if (request.maxTokens !== undefined) {\n body['generationConfig'] = { maxOutputTokens: request.maxTokens };\n }\n\n let response: Response;\n try {\n response = await fetchImpl(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (err) {\n return { ok: false, error: classifyFetchError(err, PROVIDER, request.signal) };\n }\n\n const parsedBody = await readJsonBody(response);\n\n if (!response.ok) {\n return {\n ok: false,\n error: errorFromHttpResponse({\n provider: PROVIDER,\n response,\n bodyText: parsedBody.ok ? parsedBody.text : parsedBody.text,\n }),\n };\n }\n\n if (!parsedBody.ok) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'google: 2xx response was not JSON',\n }),\n };\n }\n\n const parsed = parseGoogleResponse(parsedBody.json);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n\nfunction parseGoogleResponse(\n raw: unknown,\n):\n | { ok: true; response: ProviderResponse }\n | { ok: false; error: ProviderError } {\n if (!raw || typeof raw !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'google: response body was not an object',\n }),\n };\n }\n const obj = raw as Record<string, unknown>;\n const candidates = obj['candidates'];\n if (!Array.isArray(candidates) || candidates.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'google: response missing candidates[]',\n }),\n };\n }\n const first = candidates[0] as Record<string, unknown> | undefined;\n if (!first || typeof first !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'google: candidates[0] was not an object',\n }),\n };\n }\n\n const content = first['content'] as Record<string, unknown> | undefined;\n const parts = content && Array.isArray(content['parts']) ? (content['parts'] as unknown[]) : [];\n const text = parts\n .map((p) => {\n if (!p || typeof p !== 'object') return '';\n const part = p as Record<string, unknown>;\n return typeof part['text'] === 'string' ? (part['text'] as string) : '';\n })\n .join('');\n\n const finishRaw = first['finishReason'];\n let finishReason: ProviderResponse['finishReason'];\n if (finishRaw === 'STOP') {\n finishReason = 'stop';\n } else if (finishRaw === 'MAX_TOKENS') {\n finishReason = 'length';\n } else if (finishRaw === 'SAFETY' || finishRaw === 'RECITATION') {\n finishReason = 'content-filter';\n } else {\n finishReason = 'other';\n }\n\n const usage = obj['usageMetadata'] as Record<string, unknown> | undefined;\n const inputTokens =\n usage && typeof usage['promptTokenCount'] === 'number'\n ? (usage['promptTokenCount'] as number)\n : 0;\n const outputTokens =\n usage && typeof usage['candidatesTokenCount'] === 'number'\n ? (usage['candidatesTokenCount'] as number)\n : 0;\n\n return {\n ok: true,\n response: {\n text,\n usage: { inputTokens, outputTokens },\n finishReason,\n },\n };\n}\n","/**\n * Concrete OpenAI `ProviderAdapter`.\n *\n * Hits `POST https://api.openai.com/v1/chat/completions` with native\n * `fetch`. No `openai` SDK dep — same leanness reason as the\n * Anthropic adapter.\n *\n * Wire shape (chat completions v1, stable):\n *\n * Request:\n * POST /v1/chat/completions\n * authorization: Bearer <apiKey>\n * content-type: application/json\n * {\n * model, max_tokens?, messages: [\n * {role:'system', content: systemPrompt},\n * {role:'user', content: userPrompt},\n * ]\n * }\n *\n * Response (200):\n * {\n * choices: [{\n * message: { role: 'assistant', content: '...' },\n * finish_reason: 'stop'|'length'|'content_filter'|'tool_calls'|...,\n * }],\n * usage: { prompt_tokens, completion_tokens, total_tokens }\n * }\n *\n * `finish_reason` → `finishReason` normalization:\n *\n * - `'stop'` → `'stop'`\n * - `'length'` → `'length'`\n * - `'content_filter'` → `'content-filter'`\n * - everything else → `'other'`\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n defaultValidateConfig,\n makeProviderError,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResponse,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport {\n classifyFetchError,\n errorFromHttpResponse,\n readJsonBody,\n} from './http.js';\n\nconst PROVIDER: LlmProvider = 'openai';\nconst DEFAULT_ENDPOINT = 'https://api.openai.com/v1/chat/completions';\n\nexport interface OpenAiAdapterOptions {\n readonly endpoint?: string;\n readonly fetch?: typeof globalThis.fetch;\n}\n\nexport function createOpenAiAdapter(\n options: OpenAiAdapterOptions = {},\n): ProviderAdapter {\n const endpoint = options.endpoint ?? DEFAULT_ENDPOINT;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n function mapError(raw: unknown): ProviderError {\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n return defaultValidateConfig(PROVIDER, request);\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = defaultValidateConfig(PROVIDER, request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return { ok: false, error: classifyFetchError(null, PROVIDER, request.signal) };\n }\n\n let response: Response;\n try {\n response = await fetchImpl(endpoint, {\n method: 'POST',\n headers: {\n authorization: `Bearer ${request.apiKey}`,\n 'content-type': 'application/json',\n },\n body: JSON.stringify(buildOpenAiBody(request)),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (err) {\n return { ok: false, error: classifyFetchError(err, PROVIDER, request.signal) };\n }\n\n const body = await readJsonBody(response);\n\n if (!response.ok) {\n return {\n ok: false,\n error: errorFromHttpResponse({\n provider: PROVIDER,\n response,\n bodyText: body.ok ? body.text : body.text,\n }),\n };\n }\n\n if (!body.ok) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'openai: 2xx response was not JSON',\n }),\n };\n }\n\n const parsed = parseOpenAiResponse(body.json, PROVIDER);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n\n/**\n * Build the OpenAI request body. Exported (package-private) so the\n * OpenRouter adapter can reuse it — OpenRouter is wire-compatible\n * with OpenAI's chat-completions shape.\n *\n * Token-cap parameter selection:\n *\n * - `gpt-5*`, `o1*`, `o3*`, `o4*` (reasoning + new-API models) →\n * `max_completion_tokens`. The legacy `max_tokens` field returns\n * 400 `unsupported_parameter` on these models per the OpenAI 2024-09\n * deprecation: \"Unsupported parameter: 'max_tokens' is not supported\n * with this model. Use 'max_completion_tokens' instead.\"\n * - Everything else (`gpt-4*`, `gpt-3.5*`, etc.) → `max_tokens` for\n * backwards-compat with the chat-completions field that's been\n * stable since 2023.\n *\n * Heuristic chosen over a hard model-list because new gpt-5.x variants\n * ship continuously; the prefix is the contract OpenAI exposes. Same\n * heuristic applies to OpenRouter which wires to backing models — when\n * a caller picks `gpt-5.6-luna` through OpenRouter the same rule fires.\n */\nexport function buildOpenAiBody(request: ProviderRequest): Record<string, unknown> {\n const body: Record<string, unknown> = {\n model: request.route.model,\n messages: [\n { role: 'system', content: request.systemPrompt },\n { role: 'user', content: request.userPrompt },\n ],\n };\n if (request.maxTokens !== undefined) {\n body[selectMaxTokensField(request.route.model)] = request.maxTokens;\n }\n return body;\n}\n\n/**\n * Pick which token-cap field name to send. Bare-string match on the\n * leading model identifier — no SDK lookup, no async; runs once per\n * request body build.\n */\nexport function selectMaxTokensField(model: string): 'max_tokens' | 'max_completion_tokens' {\n const m = model.toLowerCase();\n if (m.startsWith('gpt-5') || m.startsWith('o1') || m.startsWith('o3') || m.startsWith('o4')) {\n return 'max_completion_tokens';\n }\n return 'max_tokens';\n}\n\n/**\n * Parse an OpenAI-shape chat-completions response. Reused by the\n * OpenRouter adapter (wire-compatible).\n */\nexport function parseOpenAiResponse(\n raw: unknown,\n provider: LlmProvider,\n):\n | { ok: true; response: ProviderResponse }\n | { ok: false; error: ProviderError } {\n if (!raw || typeof raw !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: response body was not an object`,\n }),\n };\n }\n const obj = raw as Record<string, unknown>;\n const choices = obj['choices'];\n if (!Array.isArray(choices) || choices.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: response missing choices[]`,\n }),\n };\n }\n const first = choices[0] as Record<string, unknown> | undefined;\n if (!first || typeof first !== 'object') {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider,\n message: `${provider}: choices[0] was not an object`,\n }),\n };\n }\n\n const message = first['message'] as Record<string, unknown> | undefined;\n const text =\n message && typeof message['content'] === 'string'\n ? (message['content'] as string)\n : '';\n\n const finishRaw = first['finish_reason'];\n let finishReason: ProviderResponse['finishReason'];\n if (finishRaw === 'stop') {\n finishReason = 'stop';\n } else if (finishRaw === 'length') {\n finishReason = 'length';\n } else if (finishRaw === 'content_filter') {\n finishReason = 'content-filter';\n } else {\n finishReason = 'other';\n }\n\n const usage = obj['usage'] as Record<string, unknown> | undefined;\n const inputTokens =\n usage && typeof usage['prompt_tokens'] === 'number'\n ? (usage['prompt_tokens'] as number)\n : 0;\n const outputTokens =\n usage && typeof usage['completion_tokens'] === 'number'\n ? (usage['completion_tokens'] as number)\n : 0;\n\n return {\n ok: true,\n response: {\n text,\n usage: { inputTokens, outputTokens },\n finishReason,\n },\n };\n}\n","/**\n * Concrete OpenRouter `ProviderAdapter`.\n *\n * OpenRouter exposes an OpenAI-compatible chat-completions API at\n * `https://openrouter.ai/api/v1/chat/completions`. Request + response\n * shapes match OpenAI's — so this adapter reuses\n * `buildOpenAiBody` / `parseOpenAiResponse` and just swaps endpoint +\n * recommended headers.\n *\n * OpenRouter-specific:\n * - Model IDs are namespaced: `'anthropic/claude-opus-4'`,\n * `'openai/gpt-4o'`, etc. The OSS generator surface accepts an\n * opaque string — OpenRouter model IDs pass through verbatim.\n * - `HTTP-Referer` + `X-Title` headers are OPTIONAL per OpenRouter's\n * docs but strongly recommended for usage analytics. They DO NOT\n * carry auth — safe to expose publicly. Adapters accept overrides\n * via options; OSS default is `'https://ggui.ai'` / `'ggui'`.\n * - 401 / 402 (insufficient credit) / 429 (rate limit) come back in\n * the same shape as OpenAI — `statusToErrorKind` handles them.\n * 402 maps to `'client-error'` by default; OpenRouter's own\n * `type: 'payment_required'` is surfaced in the message string.\n */\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n defaultValidateConfig,\n makeProviderError,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport {\n classifyFetchError,\n errorFromHttpResponse,\n readJsonBody,\n} from './http.js';\nimport { buildOpenAiBody, parseOpenAiResponse } from './openai.js';\n\nconst PROVIDER: LlmProvider = 'openrouter';\nconst DEFAULT_ENDPOINT = 'https://openrouter.ai/api/v1/chat/completions';\nconst DEFAULT_REFERRER = 'https://ggui.ai';\nconst DEFAULT_TITLE = 'ggui';\n\nexport interface OpenRouterAdapterOptions {\n readonly endpoint?: string;\n readonly referer?: string;\n readonly title?: string;\n readonly fetch?: typeof globalThis.fetch;\n}\n\nexport function createOpenRouterAdapter(\n options: OpenRouterAdapterOptions = {},\n): ProviderAdapter {\n const endpoint = options.endpoint ?? DEFAULT_ENDPOINT;\n const referer = options.referer ?? DEFAULT_REFERRER;\n const title = options.title ?? DEFAULT_TITLE;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n function mapError(raw: unknown): ProviderError {\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n return defaultValidateConfig(PROVIDER, request);\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = defaultValidateConfig(PROVIDER, request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return { ok: false, error: classifyFetchError(null, PROVIDER, request.signal) };\n }\n\n let response: Response;\n try {\n response = await fetchImpl(endpoint, {\n method: 'POST',\n headers: {\n authorization: `Bearer ${request.apiKey}`,\n 'content-type': 'application/json',\n 'HTTP-Referer': referer,\n 'X-Title': title,\n },\n body: JSON.stringify(buildOpenAiBody(request)),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (err) {\n return { ok: false, error: classifyFetchError(err, PROVIDER, request.signal) };\n }\n\n const body = await readJsonBody(response);\n\n if (!response.ok) {\n return {\n ok: false,\n error: errorFromHttpResponse({\n provider: PROVIDER,\n response,\n bodyText: body.ok ? body.text : body.text,\n }),\n };\n }\n\n if (!body.ok) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'invalid-response',\n provider: PROVIDER,\n message: 'openrouter: 2xx response was not JSON',\n }),\n };\n }\n\n const parsed = parseOpenAiResponse(body.json, PROVIDER);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n","/**\n * Concrete AWS Bedrock `ProviderAdapter` — invokes Anthropic Claude\n * models on Bedrock via the official `@anthropic-ai/bedrock-sdk`\n * package. IAM-based auth (no API key in flight); the AWS credential\n * chain (IRSA pod token / `~/.aws/credentials` / env vars) supplies\n * SigV4 signatures automatically.\n *\n * ## Why this adapter exists\n *\n * Anyone running the generator on an AWS-credentialed host (EC2, ECS,\n * Lambda, EKS) can target Bedrock without managing API keys: IAM is\n * the auth boundary, AWS rotates host credentials automatically, and\n * a misconfigured IAM role surfaces as a clear `AccessDeniedException`\n * the SDK funnels through `mapError`. The alternative — parking a\n * provider API key in a secrets store and lazily fetching it on first\n * render — works but adds operational surface (a seed ceremony,\n * key-rotation discipline, a misconfig mode where the secret is\n * empty); Bedrock removes all of it.\n *\n * ## Wire shape\n *\n * The Bedrock SDK's `client.messages.create(...)` mirrors the direct\n * Anthropic API surface 1:1 — same request body fields (`model`,\n * `max_tokens`, `system`, `messages`), same response shape (`content[]`\n * with `{type:'text', text}` blocks, `stop_reason`, `usage`). Both\n * adapters therefore share ONE success-envelope parser —\n * {@link parseAnthropicMessagesResponse} in `./anthropic-wire.ts`.\n * Streaming is supported by the SDK\n * (`client.messages.stream(...)` returns an async iterable) but this\n * adapter uses the non-streaming `create(...)` call to match the\n * single-completion {@link ProviderAdapter} contract; higher layers\n * (`UiGenerator`) compose multi-turn loops above the seam.\n *\n * ## Auth — no API key in `ProviderRequest`\n *\n * The {@link ProviderAdapter} contract types `ProviderRequest.apiKey`\n * as a required string because direct API providers need it on the\n * wire. Bedrock doesn't — the SDK signs requests with AWS credentials\n * resolved at process boot. Two compatible options were considered:\n *\n * 1. Add an `auth: 'apiKey' | 'iam'` discriminator to\n * `ProviderAdapter` + thread it through every adapter.\n * 2. Override `validateConfig` so this adapter accepts (and ignores)\n * whatever the caller puts in `apiKey` — `'iam'` / sentinel /\n * empty string all pass.\n *\n * Option 2 wins on cost: ZERO callers, contract, or tests change.\n * Callers pass a sentinel (e.g. `'bedrock-iam'`) so the model-id\n * check still gates on a non-empty value. Future work could add the\n * discriminator if a third auth mode (e.g. cross-account assume-role)\n * lands.\n *\n * ## Model IDs — pass-through, endpoint chosen by ID shape\n *\n * Bedrock serves Anthropic models through TWO endpoints with DISJOINT\n * model-id namespaces (live-probed against us-east-1, 2026-08-13):\n *\n * - **bedrock-runtime** (`AnthropicBedrock`): serves ONLY\n * cross-region inference-profile ids —\n * `us.anthropic.claude-haiku-4-5-20251001-v1:0` etc. Bare\n * `anthropic.*` foundation ids are rejected with 400\n * \"on-demand throughput isn't supported\".\n * - **Messages-API endpoint / Mantle** (`AnthropicBedrockMantle`):\n * serves ONLY region-less `anthropic.*` ids —\n * `anthropic.claude-opus-5`, `anthropic.claude-haiku-4-5`. The\n * Claude 5 family and Opus 4.8 exist ONLY here. Profile ids are\n * rejected with 404. Requires the account to have enabled Claude\n * in Amazon Bedrock (otherwise every id 403s \"not available for\n * this account\").\n *\n * Because the namespaces never overlap, the adapter routes each\n * request by shape: ids starting `anthropic.` go to Mantle, region-\n * prefixed ids (`us.` / `eu.` / `apac.` / `global.`) go to\n * bedrock-runtime. The id itself passes through untranslated —\n * supply a Bedrock id, not a direct-API model name.\n *\n * ## Failure mapping\n *\n * The bedrock-sdk throws `APIError` subclasses (`AuthenticationError`,\n * `PermissionDeniedError`, `RateLimitError`, `InternalServerError`,\n * etc.) that all carry a numeric `.status` property. We classify them\n * by structural duck-typing (`typeof err.status === 'number'`) rather\n * than `instanceof Anthropic.APIError` because pnpm hoisting often\n * resolves multiple `@anthropic-ai/sdk` versions across the workspace\n * — the bedrock-sdk's nested SDK and ui-gen's direct SDK can diverge,\n * and `instanceof` then silently returns false for valid errors.\n * Duck-typing on `.status` is robust to that drift and matches the\n * SDK's documented API contract (every subclass exposes `.status`).\n *\n * Transport-shaped errors (`APIConnectionError`, `APIUserAbortError`)\n * carry NO status — they fall through to {@link classifyFetchError}\n * for the standard `network` / `aborted` mapping.\n *\n * AWS-specific failure modes (`AccessDeniedException` — wrong IAM\n * grants; `ThrottlingException` — Bedrock rate limit;\n * `ValidationException` — bad model id) all surface as `APIError`\n * subclasses in the SDK, distinguished by `.status` (403 / 429 / 400\n * respectively).\n */\nimport { AnthropicBedrock, AnthropicBedrockMantle } from '@anthropic-ai/bedrock-sdk';\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport {\n makeProviderError,\n statusToErrorKind,\n type ProviderAdapter,\n type ProviderError,\n type ProviderRequest,\n type ProviderResult,\n type ProviderValidation,\n} from '../provider-adapter.js';\nimport { parseAnthropicMessagesResponse } from './anthropic-wire.js';\nimport { classifyFetchError } from './http.js';\n\n/**\n * `LlmProvider` slot this adapter targets. Bedrock has its own slot\n * in the `LlmProvider` union (alongside `'anthropic'` direct API) so\n * downstream code can branch on adapter choice — pricing tables,\n * model-id namespaces, and credential-source logging all differ.\n */\nconst PROVIDER: LlmProvider = 'bedrock';\nconst DEFAULT_MAX_TOKENS = 4096;\n\n/**\n * Which Bedrock endpoint a model id resolves to. The namespaces are\n * disjoint (see the docstring above), so the shape of the id fully\n * determines the endpoint — no configuration knob needed.\n */\nexport type BedrockEndpoint = 'runtime' | 'mantle';\n\n/**\n * Structural slice of the two SDK clients the adapter actually drives —\n * the seam that lets tests inject a stub without standing up a real\n * AWS client. Both `AnthropicBedrock` and `AnthropicBedrockMantle`\n * satisfy it (the adapter's single-completion contract only ever calls\n * non-streaming `messages.create`; the response is parsed from\n * `unknown` by `parseAnthropicMessagesResponse`, so the SDK's\n * version-volatile `Message` type is deliberately not part of the\n * seam).\n */\nexport interface BedrockMessagesClient {\n readonly messages: {\n create(\n body: {\n model: string;\n max_tokens: number;\n system?: string;\n messages: Array<{ role: 'user'; content: string }>;\n },\n options?: { signal?: AbortSignal },\n ): Promise<unknown>;\n };\n}\n\n/**\n * Route a Bedrock model id to its serving endpoint. Region-less\n * `anthropic.*` ids exist only on the Messages-API (Mantle) endpoint;\n * everything else (region-prefixed inference profiles, ARNs) belongs\n * to bedrock-runtime.\n */\nexport function bedrockEndpointFor(model: string): BedrockEndpoint {\n return model.startsWith('anthropic.') ? 'mantle' : 'runtime';\n}\n\n/**\n * Constructor options for the Bedrock adapter.\n *\n * `region` is the only required option in the common case — IAM\n * credentials come from the standard AWS chain (IRSA pod token in\n * EKS, instance role on EC2, env vars or shared credentials file\n * locally). Tests pass `clientFactory` to inject a mock SDK client.\n */\nexport interface BedrockAdapterOptions {\n /**\n * AWS region for Bedrock invocations. Required for IAM-scoped\n * resource ARNs to resolve (model ARNs include the region;\n * cross-region inference profiles do their own internal failover\n * but the request still has to land in ONE region). Common values:\n * `'us-east-1'`, `'us-west-2'`. Reads from `process.env.AWS_REGION`\n * by default to match the rest of the AWS SDK chain.\n */\n readonly region?: string;\n /**\n * Optional client factory override — used by tests to inject a\n * mock or stub client without actually hitting AWS. Called with the\n * endpoint the request's model id routed to (`'runtime'` →\n * `AnthropicBedrock`, `'mantle'` → `AnthropicBedrockMantle`).\n * Production callers leave this unset; the adapter constructs the\n * real client lazily on first `complete(...)` call per endpoint.\n */\n readonly clientFactory?: (\n region: string,\n endpoint: BedrockEndpoint,\n ) => BedrockMessagesClient;\n}\n\n/**\n * Construct an AWS Bedrock provider adapter.\n *\n * No API key — IAM is the auth boundary. The returned `ProviderAdapter`\n * satisfies the same contract as `createAnthropicAdapter`, so it\n * slots into `createUiGenerator({ adapter })` interchangeably (modulo\n * the per-provider model-id namespace differences).\n */\nexport function createBedrockAdapter(\n options: BedrockAdapterOptions = {},\n): ProviderAdapter {\n const region = options.region ?? process.env['AWS_REGION'] ?? 'us-east-1';\n const clientFactory =\n options.clientFactory ??\n ((r: string, endpoint: BedrockEndpoint): BedrockMessagesClient =>\n endpoint === 'mantle'\n ? new AnthropicBedrockMantle({ awsRegion: r })\n : new AnthropicBedrock({ awsRegion: r }));\n\n const cachedClients: Partial<Record<BedrockEndpoint, BedrockMessagesClient>> = {};\n function getClient(endpoint: BedrockEndpoint): BedrockMessagesClient {\n const cached = cachedClients[endpoint];\n if (cached) return cached;\n const created = clientFactory(region, endpoint);\n cachedClients[endpoint] = created;\n return created;\n }\n\n function mapError(raw: unknown): ProviderError {\n // Structural duck-typing: every SDK `APIError` subclass with a\n // server response carries a numeric `.status` property. We check\n // for that field (rather than `instanceof Anthropic.APIError`) to\n // dodge the pnpm-hoist version-drift footgun documented at the\n // top of this file. Aborted / transport errors lack `.status` and\n // fall through to `classifyFetchError`.\n if (raw && typeof raw === 'object' && 'status' in raw) {\n const status = (raw as { status: unknown }).status;\n if (typeof status === 'number' && status > 0) {\n const name = raw instanceof Error ? raw.name : 'APIError';\n const message = raw instanceof Error ? raw.message : String(raw);\n return makeProviderError({\n kind: statusToErrorKind(status),\n provider: PROVIDER,\n message: `bedrock: ${status} ${name} — ${message}`,\n status,\n });\n }\n }\n return classifyFetchError(raw, PROVIDER);\n }\n\n return {\n provider: PROVIDER,\n /**\n * Validate Bedrock-specific config. Differs from\n * `defaultValidateConfig` because Bedrock has NO request-level\n * API key — `request.apiKey` is ignored (callers pass a sentinel\n * like `'bedrock-iam'` so the type contract holds).\n * Only the model id is required to be non-empty; auth issues\n * surface from the SDK as `AccessDeniedException` at call time.\n */\n validateConfig(\n request: Pick<ProviderRequest, 'apiKey' | 'route'>,\n ): ProviderValidation {\n if (!request.route?.model || request.route.model.length === 0) {\n return {\n ok: false,\n error: makeProviderError({\n kind: 'client-error',\n provider: PROVIDER,\n message: 'bedrock: model id is required',\n }),\n };\n }\n return { ok: true };\n },\n mapError,\n async complete(request: ProviderRequest): Promise<ProviderResult> {\n const pre = this.validateConfig(request);\n if (!pre.ok) return { ok: false, error: pre.error };\n if (request.signal?.aborted) {\n return {\n ok: false,\n error: classifyFetchError(null, PROVIDER, request.signal),\n };\n }\n\n const client = getClient(bedrockEndpointFor(request.route.model));\n // The SDK's `Message` return type drifts between\n // `@anthropic-ai/sdk` versions (pnpm hoists multiple copies in\n // this workspace today). We type the captured value as\n // `unknown` here and let `parseAnthropicMessagesResponse`\n // validate the narrow shape we actually consume — fields beyond\n // `content` / `stop_reason` / `usage` are version-volatile\n // (thinking blocks, tool-use blocks, beta-feature additions)\n // and not load-bearing for the harness's single-completion\n // contract.\n let raw: unknown;\n try {\n raw = await client.messages.create(\n {\n model: request.route.model,\n max_tokens: request.maxTokens ?? DEFAULT_MAX_TOKENS,\n system: request.systemPrompt,\n messages: [{ role: 'user', content: request.userPrompt }],\n },\n {\n // SDK forwards `signal` into the underlying fetch — same\n // abort semantics as the direct-API adapter.\n ...(request.signal ? { signal: request.signal } : {}),\n },\n );\n } catch (err) {\n // Re-check signal first — aborted-during-await loses the abort\n // signal in the SDK's error wrapping on some runtimes.\n if (request.signal?.aborted) {\n return {\n ok: false,\n error: classifyFetchError(err, PROVIDER, request.signal),\n };\n }\n return { ok: false, error: mapError(err) };\n }\n\n // Success-envelope parsing is shared with the direct-API\n // adapter — Bedrock's Anthropic-flavored endpoint returns the\n // identical envelope as `api.anthropic.com/v1/messages`. See\n // `./anthropic-wire.ts`. (Takes `unknown` rather than the SDK's\n // `Message` type so the adapter is robust to SDK version drift\n // across pnpm-hoisted copies — see the failure-mapping\n // docstring above for context.)\n const parsed = parseAnthropicMessagesResponse(raw, PROVIDER);\n if (!parsed.ok) return { ok: false, error: parsed.error };\n return { ok: true, response: parsed.response };\n },\n };\n}\n","/**\n * Public barrel for `@ggui-ai/ui-gen/providers`.\n *\n * Concrete {@link ProviderAdapter} implementations for the LLM\n * providers ggui supports today: Anthropic (direct API), Google,\n * OpenAI, OpenRouter, and AWS Bedrock (Anthropic models via IAM).\n *\n * Every adapter satisfies the structural\n * {@link import('../provider-adapter.js').ProviderAdapter} contract.\n * The four direct-API adapters compose\n * `defaultValidateConfig` + `makeProviderError` + `statusToErrorKind`\n * + the shared helpers in `./http.ts` and pull NO vendor SDK (~10MB\n * savings). Bedrock is the exception — it pulls\n * `@anthropic-ai/bedrock-sdk` (a zero-dep package over native fetch)\n * because rolling our own AWS SigV4 signer for one provider isn't a\n * reasonable trade.\n *\n * Typical usage from the CLI:\n *\n * ```ts\n * import { createAnthropicAdapter } from '@ggui-ai/ui-gen/providers';\n * import { createUiGenerator } from '@ggui-ai/ui-gen';\n *\n * const adapter = createAnthropicAdapter();\n * const generator = createUiGenerator({ adapter });\n * const result = await generator.generate({ request, llm, providerKey, blueprints });\n * ```\n *\n * Bedrock pool path (no API key — IAM at process boot):\n *\n * ```ts\n * import { createBedrockAdapter } from '@ggui-ai/ui-gen/providers';\n * const adapter = createBedrockAdapter({ region: 'us-east-1' });\n * // pass `providerKey: { provider: 'bedrock', key: 'bedrock-iam' }`\n * // (sentinel — adapter ignores; satisfies the non-empty contract).\n * ```\n */\nexport { createAnthropicAdapter } from './anthropic.js';\nexport type { AnthropicAdapterOptions } from './anthropic.js';\n\nexport { createGoogleAdapter } from './google.js';\nexport type { GoogleAdapterOptions } from './google.js';\n\nexport { createOpenAiAdapter } from './openai.js';\nexport type { OpenAiAdapterOptions } from './openai.js';\n\nexport { createOpenRouterAdapter } from './openrouter.js';\nexport type { OpenRouterAdapterOptions } from './openrouter.js';\n\nexport { createBedrockAdapter } from './bedrock.js';\nexport type { BedrockAdapterOptions } from './bedrock.js';\n\nimport type { LlmProvider } from '@ggui-ai/mcp-server-core';\nimport type { ProviderAdapter } from '../provider-adapter.js';\nimport { createAnthropicAdapter } from './anthropic.js';\nimport { createGoogleAdapter } from './google.js';\nimport { createOpenAiAdapter } from './openai.js';\nimport { createOpenRouterAdapter } from './openrouter.js';\nimport { createBedrockAdapter } from './bedrock.js';\n\n/**\n * Construct the default adapter for a given provider. Every entry in\n * the `LlmProvider` union now has a concrete adapter — Bedrock joined\n * the open surface because it's the cleanest pool-path\n * (`mcp.ggui.ai` free-credit) story (IAM auth, no API key in flight,\n * AWS-managed cost reporting).\n *\n * Callers that want custom options (test fetch, proxy endpoint,\n * OpenRouter referer, Bedrock region) should construct the concrete\n * adapter directly — this helper is a sensible default for the\n * common case.\n */\nexport function selectAdapter(provider: LlmProvider): ProviderAdapter {\n switch (provider) {\n case 'anthropic':\n return createAnthropicAdapter();\n case 'google':\n return createGoogleAdapter();\n case 'openai':\n return createOpenAiAdapter();\n case 'openrouter':\n return createOpenRouterAdapter();\n case 'bedrock':\n return createBedrockAdapter();\n }\n}\n"]}
@@ -374,8 +374,8 @@ var SANDBOX_EXTERNALS = [
374
374
  "@ggui-ai/design/*",
375
375
  "@ggui-ai/wire",
376
376
  "@ggui-ai/wire/*",
377
- "@ggui-ai/react",
378
- "@ggui-ai/react/*"
377
+ "@ggui-ai/mcp-apps-react",
378
+ "@ggui-ai/mcp-apps-react/*"
379
379
  ];
380
380
  var MAX_BUNDLE_SIZE = 2 * 1024 * 1024;
381
381
  function cssInlinePlugin() {