@toothfairyai/tfdesign 0.4.8 → 0.4.9-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/web/out/404/index.html +1 -1
- package/apps/web/out/404.html +1 -1
- package/apps/web/out/__next.$oc$slug.__PAGE__.txt +3 -3
- package/apps/web/out/__next.$oc$slug.txt +3 -3
- package/apps/web/out/__next._full.txt +16 -16
- package/apps/web/out/__next._head.txt +4 -4
- package/apps/web/out/__next._index.txt +6 -7
- package/apps/web/out/__next._tree.txt +3 -3
- package/apps/web/out/_next/static/chunks/0-94cql6nl0jv.css +2 -0
- package/apps/web/out/_next/static/chunks/0-_4nyrx9a0p_.js +4586 -0
- package/apps/web/out/_next/static/chunks/012el4mxdksfa.js +1 -0
- package/apps/web/out/_next/static/chunks/033hdyh92lap-.js +1 -0
- package/apps/web/out/_next/static/chunks/{0~saitcv01ulm.js → 09kj3eb8dudq..js} +1 -3
- package/apps/web/out/_next/static/chunks/0eyc01y70gfu8.js +5 -0
- package/apps/web/out/_next/static/chunks/0gfud9-ayub5k.css +1 -0
- package/apps/web/out/_next/static/chunks/0otg4bwz5am.y.css +2 -0
- package/apps/web/out/_next/static/chunks/0qgizcmqgdduz.js +1 -0
- package/apps/web/out/_next/static/chunks/0rjd9p0m-xust.js +31 -0
- package/apps/web/out/_next/static/chunks/111k.piti8qwb.js +1 -0
- package/apps/web/out/_next/static/chunks/1434omkut_t67.js +1 -0
- package/apps/web/out/_next/static/chunks/{turbopack-0qjykn58ffuft.js → turbopack-15aa1bhzoau.r.js} +1 -3
- package/apps/web/out/_not-found/__next._full.txt +23 -19
- package/apps/web/out/_not-found/__next._head.txt +4 -4
- package/apps/web/out/_not-found/__next._index.txt +6 -7
- package/apps/web/out/_not-found/__next._not-found.__PAGE__.txt +2 -2
- package/apps/web/out/_not-found/__next._not-found.txt +3 -3
- package/apps/web/out/_not-found/__next._tree.txt +3 -3
- package/apps/web/out/_not-found/index.html +1 -1
- package/apps/web/out/_not-found/index.txt +23 -19
- package/apps/web/out/align-center.png +0 -0
- package/apps/web/out/align-right.png +0 -0
- package/apps/web/out/align-text.png +0 -0
- package/apps/web/out/app-icon.png +0 -0
- package/apps/web/out/app-icon.svg +1 -1
- package/apps/web/out/bottom-alignment.png +0 -0
- package/apps/web/out/fonts/Gilroy-Regular.woff2 +0 -0
- package/apps/web/out/fonts/Gilroy-SemiBold.woff2 +0 -0
- package/apps/web/out/html2canvas.min.js +20 -0
- package/apps/web/out/icon-add-file.png +0 -0
- package/apps/web/out/icon-copy.png +0 -0
- package/apps/web/out/icon-remove.png +0 -0
- package/apps/web/out/index.html +1 -1
- package/apps/web/out/index.txt +16 -16
- package/apps/web/out/left-alignment.png +0 -0
- package/apps/web/out/logo.svg +14 -5
- package/apps/web/out/top-alignment.png +0 -0
- package/dist/{chunk-VIER63EE.js → chunk-Q2ALQSZX.js} +590 -110
- package/dist/cli.js +20 -5
- package/dist/{server-RXVSJGZG.js → server-PZVSL7GD.js} +1 -1
- package/package.json +11 -1
- package/apps/web/out/_next/static/chunks/00.vhdzyqgugx.js.map +0 -1
- package/apps/web/out/_next/static/chunks/026q~go~dh3ct.js.map +0 -1
- package/apps/web/out/_next/static/chunks/03lp76x6ml3q7.js.map +0 -1
- package/apps/web/out/_next/static/chunks/03rwb84ufo-ml.css +0 -2
- package/apps/web/out/_next/static/chunks/03~yq9q893hmn.js.map +0 -1
- package/apps/web/out/_next/static/chunks/05z1ica28h4v4.js.map +0 -1
- package/apps/web/out/_next/static/chunks/06pwisw_r78h0.js.map +0 -1
- package/apps/web/out/_next/static/chunks/07e0~_ag4wd_2.js +0 -3
- package/apps/web/out/_next/static/chunks/0856t9l8e24kl.js +0 -3459
- package/apps/web/out/_next/static/chunks/09dn2kc7uy573.css +0 -3
- package/apps/web/out/_next/static/chunks/0_h7u0wcctdvf.js.map +0 -1
- package/apps/web/out/_next/static/chunks/0bfs9u56d4mzi.js.map +0 -1
- package/apps/web/out/_next/static/chunks/0bnhnqs10zvm0.js +0 -3
- package/apps/web/out/_next/static/chunks/0b~oqibb-klk8.js.map +0 -1
- package/apps/web/out/_next/static/chunks/0dlz0h-q.e8t5.js.map +0 -1
- package/apps/web/out/_next/static/chunks/0e2qn3b70-t2i.js +0 -34
- package/apps/web/out/_next/static/chunks/0fv_wqm4-r1hb.js +0 -12
- package/apps/web/out/_next/static/chunks/0fysc_wo2kzsu.js.map +0 -1
- package/apps/web/out/_next/static/chunks/0i-mjuoftnsa3.js +0 -3
- package/apps/web/out/_next/static/chunks/0ix3s5zdxhkjq.js +0 -12
- package/apps/web/out/_next/static/chunks/0ovz1kz3yt45_.js +0 -33
- package/apps/web/out/_next/static/chunks/0ps7zql~4nu4c.js.map +0 -1
- package/apps/web/out/_next/static/chunks/0qans9q_q-pop.js +0 -7
- package/apps/web/out/_next/static/chunks/0t3k3fodzjqbk.js +0 -3
- package/apps/web/out/_next/static/chunks/0vh07vpip-7jr.js.map +0 -1
- package/apps/web/out/_next/static/chunks/0weq586uhw-26.js.map +0 -1
- package/apps/web/out/_next/static/chunks/0y1f9xlua9~_u.css +0 -2
- package/apps/web/out/_next/static/chunks/0zvsnz1lw0thi.js.map +0 -1
- package/apps/web/out/_next/static/chunks/0~ge_azerwvf9.css.map +0 -6
- package/apps/web/out/_next/static/chunks/0~wbkak703p3z.js +0 -3
- package/apps/web/out/_next/static/chunks/11uef98fc_tfp.css.map +0 -1
- package/apps/web/out/_next/static/chunks/14hojq718_2.u.js +0 -34
- package/apps/web/out/_next/static/chunks/15j8a~eyh6.eg.css.map +0 -1
- package/apps/web/out/_next/static/chunks/16cm9w~y8~hqh.js.map +0 -1
- package/apps/web/out/_next/static/chunks/17p64lujxa85m.js +0 -3
- package/apps/web/out/agent-icons/aider.png +0 -0
- package/apps/web/out/agent-icons/amr.svg +0 -8
- package/apps/web/out/agent-icons/antigravity.svg +0 -1
- package/apps/web/out/agent-icons/claude.svg +0 -1
- package/apps/web/out/agent-icons/codex.svg +0 -1
- package/apps/web/out/agent-icons/copilot.svg +0 -1
- package/apps/web/out/agent-icons/cursor-agent.svg +0 -1
- package/apps/web/out/agent-icons/deepseek.svg +0 -1
- package/apps/web/out/agent-icons/devin.png +0 -0
- package/apps/web/out/agent-icons/gemini.svg +0 -1
- package/apps/web/out/agent-icons/grok-build.svg +0 -15
- package/apps/web/out/agent-icons/hermes.svg +0 -1
- package/apps/web/out/agent-icons/kilo.svg +0 -1
- package/apps/web/out/agent-icons/kimi.svg +0 -1
- package/apps/web/out/agent-icons/kiro.svg +0 -1
- package/apps/web/out/agent-icons/mimo.svg +0 -1
- package/apps/web/out/agent-icons/opencode.svg +0 -1
- package/apps/web/out/agent-icons/pi.svg +0 -1
- package/apps/web/out/agent-icons/qoder.svg +0 -1
- package/apps/web/out/agent-icons/qwen.svg +0 -1
- package/apps/web/out/agent-icons/reasonix.svg +0 -37
- package/apps/web/out/agent-icons/trae-cli.png +0 -0
- package/apps/web/out/agent-icons/vibe.svg +0 -1
- package/apps/web/out/brand-icon.svg +0 -5
- package/apps/web/out/desktop-pet/__next._full.txt +0 -20
- package/apps/web/out/desktop-pet/__next._head.txt +0 -6
- package/apps/web/out/desktop-pet/__next._index.txt +0 -8
- package/apps/web/out/desktop-pet/__next._tree.txt +0 -3
- package/apps/web/out/desktop-pet/__next.desktop-pet.__PAGE__.txt +0 -6
- package/apps/web/out/desktop-pet/__next.desktop-pet.txt +0 -5
- package/apps/web/out/desktop-pet/index.html +0 -1
- package/apps/web/out/desktop-pet/index.txt +0 -20
- package/apps/web/out/logo.png +0 -0
- package/apps/web/out/model-icons/black-forest-labs.svg +0 -10
- package/apps/web/out/model-icons/bytedance.svg +0 -1
- package/apps/web/out/model-icons/elevenlabs.svg +0 -1
- package/apps/web/out/model-icons/fishaudio.svg +0 -1
- package/apps/web/out/model-icons/flux.svg +0 -1
- package/apps/web/out/model-icons/google-gemini.svg +0 -1
- package/apps/web/out/model-icons/minimax.svg +0 -1
- package/apps/web/out/model-icons/openai.svg +0 -1
- package/apps/web/out/model-icons/openrouter.svg +0 -1
- package/apps/web/out/model-icons/suno.svg +0 -1
- package/apps/web/out/model-icons/x.svg +0 -1
- package/apps/web/out/official_badge.svg +0 -48
- package/apps/web/out/remixicon.woff2 +0 -0
- /package/apps/web/out/_next/static/{EOfAKklAkTBpVS50QG3jX → LZdEU9ZvDchB9VDyfg54d}/_buildManifest.js +0 -0
- /package/apps/web/out/_next/static/{EOfAKklAkTBpVS50QG3jX → LZdEU9ZvDchB9VDyfg54d}/_clientMiddlewareManifest.js +0 -0
- /package/apps/web/out/_next/static/{EOfAKklAkTBpVS50QG3jX → LZdEU9ZvDchB9VDyfg54d}/_ssgManifest.js +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["turbopack:///[project]/apps/web/src/media/models.ts","turbopack:///[project]/apps/web/src/providers/registry.ts","turbopack:///[project]/apps/web/src/state/projects.ts","turbopack:///[project]/apps/web/src/state/litellm-models.json.[json].cjs/turbopack:///apps/web/src/state/litellm-models.json","turbopack:///[project]/apps/web/src/state/maxTokens.ts","turbopack:///[project]/apps/web/src/state/config.ts","turbopack:///[project]/apps/web/src/providers/api-proxy.ts","turbopack:///[project]/apps/web/src/utils/apiProtocol.ts","turbopack:///[project]/apps/web/src/providers/openai-compatible.ts","turbopack:///[project]/apps/web/src/state/appearance.ts","turbopack:///[project]/apps/web/src/utils/notifications.ts","turbopack:///[project]/apps/web/src/components/pet/PetOverlay.tsx","turbopack:///[project]/apps/web/src/components/pet/pets.ts","turbopack:///[project]/apps/web/src/components/pet/codexAtlas.ts","turbopack:///[project]/apps/web/src/components/pet/PetSpriteFace.tsx","turbopack:///[project]/apps/web/src/components/pet/taskCenter.ts"],"sourcesContent":["/**\n * Single source of truth for the media-generation model registry.\n *\n * Both the frontend (NewProjectPanel model pickers, Settings dialog\n * provider list) and the daemon (od media generate dispatcher) consume\n * this registry. When you add a model entry here, the picker shows it,\n * the daemon can dispatch to it, and the Settings dialog knows which\n * API keys are needed.\n *\n * The model catalogue mirrors the breadth of lobehub's model-bank:\n * every image / video model that lobehub natively supports is listed\n * here so the user can pick from the same surface area without us\n * re-implementing every provider's transport. For provider integrations\n * we only ship the two flagship paths today — OpenAI (gpt-image-*) and\n * Volcengine Ark (Seedance 2.0) — the rest fall back to a placeholder\n * with a clear \"no provider integration yet\" note. The contract the\n * code agent follows is identical regardless.\n *\n * The daemon imports the JS mirror of this file at\n * daemon/media-models.js (kept in sync by review).\n */\n\nimport type { AudioKind, MediaAspect } from '../types';\n\n/**\n * Provider identifier — used both as a grouping key in the picker and as\n * the lookup key for API-credentials in `AppConfig.mediaProviders`. New\n * providers must be added to {@link MEDIA_PROVIDERS} below.\n */\nexport type MediaProviderId =\n | 'openai'\n | 'volcengine'\n | 'grok'\n | 'hyperframes'\n | 'nanobanana'\n | 'imagerouter'\n | 'openrouter'\n | 'custom-image'\n | 'comfyui'\n | 'bfl'\n | 'fal'\n | 'replicate'\n | 'google'\n | 'midjourney'\n | 'kling'\n | 'minimax'\n | 'suno'\n | 'udio'\n | 'elevenlabs'\n | 'fishaudio'\n | 'senseaudio'\n | 'tavily'\n | 'leonardo'\n | 'toothfairyai'\n | 'stub';\n\nexport interface MediaProvider {\n id: MediaProviderId;\n /** Display name shown in Settings + ModelPicker headers. */\n label: string;\n /** Short marketing-style sub-label. */\n hint: string;\n /** Whether the daemon ships a real integration for this provider. */\n integrated: boolean;\n /** Whether the provider needs user-supplied credentials. */\n credentialsRequired?: boolean;\n /** Whether the provider should appear in Settings -> Media. */\n settingsVisible?: boolean;\n /** Default base URL the daemon hits when no override is configured. */\n defaultBaseUrl?: string;\n /** Documentation URL for getting an API key. */\n docsUrl?: string;\n /** Whether Settings should expose a custom model override field. */\n supportsCustomModel?: boolean;\n /** Placeholder text for custom model override fields in Settings. */\n customModelPlaceholder?: string;\n}\n\n/**\n * Catalogue of providers. The Settings dialog renders one section per\n * entry; the new-project model picker uses {@link integrated} to flag\n * cards that will silently fall back to a stub if the user hasn't\n * configured a key.\n */\nexport const MEDIA_PROVIDERS: MediaProvider[] = [\n {\n id: 'openai',\n label: 'OpenAI',\n hint: 'gpt-image-2 / dall-e-3',\n integrated: true,\n defaultBaseUrl: 'https://api.openai.com/v1',\n docsUrl: 'https://platform.openai.com/api-keys',\n },\n {\n id: 'volcengine',\n label: 'Volcengine Ark (Doubao)',\n hint: 'Seedance 2.0 / Seedream',\n integrated: true,\n defaultBaseUrl: 'https://ark.cn-beijing.volces.com/api/v3',\n docsUrl: 'https://console.volcengine.com/ark',\n },\n {\n id: 'grok',\n label: 'xAI Grok Imagine',\n hint: 'grok-imagine — image + video with native audio',\n integrated: true,\n defaultBaseUrl: 'https://api.x.ai/v1',\n docsUrl: 'https://docs.x.ai/developers/model-capabilities/video/generation',\n },\n {\n id: 'hyperframes',\n label: 'HyperFrames',\n hint: 'Local HTML -> MP4 renderer',\n integrated: true,\n credentialsRequired: false,\n settingsVisible: false,\n docsUrl: 'https://hyperframes.heygen.com',\n },\n {\n id: 'nanobanana',\n label: 'Nano Banana',\n hint: 'Google official by default; custom gateway configurable',\n integrated: true,\n defaultBaseUrl: 'https://generativelanguage.googleapis.com',\n docsUrl: 'https://ai.google.dev/gemini-api/docs/api-key',\n supportsCustomModel: true,\n },\n {\n id: 'imagerouter',\n label: 'ImageRouter',\n hint: 'OpenAI-compatible image + video routing',\n integrated: true,\n defaultBaseUrl: 'https://api.imagerouter.io/v1/openai',\n docsUrl: 'https://docs.imagerouter.io/api-reference/image-generation/',\n supportsCustomModel: true,\n customModelPlaceholder: 'openai/gpt-image-2 or xAI/grok-imagine-video',\n },\n {\n id: 'openrouter',\n label: 'OpenRouter',\n hint: 'Unified gateway for image + video models',\n integrated: true,\n credentialsRequired: true,\n settingsVisible: true,\n defaultBaseUrl: 'https://openrouter.ai/api/v1',\n docsUrl: 'https://openrouter.ai/settings/keys',\n },\n {\n id: 'custom-image',\n label: 'Custom Image API',\n hint: 'OpenAI-compatible images/generations + images/edits (local or cloud)',\n integrated: true,\n docsUrl: 'https://platform.openai.com/docs/api-reference/images',\n supportsCustomModel: true,\n customModelPlaceholder: 'my-image-model',\n },\n {\n id: 'comfyui',\n label: 'ComfyUI',\n hint: 'Local JSON workflow server (planned adapter)',\n integrated: false,\n defaultBaseUrl: 'http://127.0.0.1:8188',\n docsUrl: 'https://docs.comfy.org/development/core-concepts/workflow',\n },\n {\n id: 'bfl',\n label: 'Black Forest Labs',\n hint: 'FLUX 1.1 Pro / FLUX Pro / Dev',\n integrated: false,\n defaultBaseUrl: 'https://api.bfl.ai',\n docsUrl: 'https://docs.bfl.ai/quick_start/create_account',\n },\n {\n id: 'fal',\n label: 'Fal.ai',\n hint: 'FLUX / Sora / Veo / Wan / Ideogram / Recraft and any fal-ai/* model',\n integrated: true,\n defaultBaseUrl: 'https://fal.run',\n docsUrl: 'https://fal.ai/dashboard/keys',\n supportsCustomModel: true,\n },\n {\n id: 'leonardo',\n label: 'Leonardo.ai',\n hint: 'Phoenix / Kino XL / FLUX',\n integrated: true,\n credentialsRequired: true,\n settingsVisible: true,\n defaultBaseUrl: 'https://cloud.leonardo.ai/api/rest/v1',\n docsUrl: 'https://docs.leonardo.ai/docs/create-an-api-key',\n },\n {\n id: 'replicate',\n label: 'Replicate',\n hint: 'FLUX / SDXL / Ideogram',\n integrated: false,\n defaultBaseUrl: 'https://api.replicate.com/v1',\n docsUrl: 'https://replicate.com/account/api-tokens',\n },\n {\n id: 'google',\n label: 'Google AI / Vertex',\n hint: 'Imagen 4 / Veo 3 / Lyria',\n integrated: false,\n docsUrl: 'https://ai.google.dev/gemini-api/docs/api-key',\n },\n {\n id: 'kling',\n label: 'Kuaishou Kling',\n hint: 'Kling 1.6 / 2.0 video',\n integrated: false,\n docsUrl: 'https://klingai.com/dev-center',\n },\n {\n id: 'midjourney',\n label: 'Midjourney (proxy)',\n hint: 'midjourney-v7',\n integrated: false,\n },\n {\n id: 'minimax',\n label: 'MiniMax',\n hint: 'TTS / video-01',\n integrated: true,\n defaultBaseUrl: 'https://api.minimaxi.chat/v1',\n docsUrl: 'https://platform.minimaxi.com',\n },\n {\n id: 'suno',\n label: 'Suno',\n hint: 'Music generation',\n integrated: false,\n },\n {\n id: 'udio',\n label: 'Udio',\n hint: 'Music generation',\n integrated: false,\n },\n {\n id: 'elevenlabs',\n label: 'ElevenLabs',\n hint: 'Voice / SFX',\n integrated: true,\n defaultBaseUrl: 'https://api.elevenlabs.io',\n docsUrl: 'https://elevenlabs.io/app/settings/api-keys',\n },\n {\n id: 'fishaudio',\n label: 'FishAudio',\n hint: 'Speech / voice clone',\n integrated: true,\n defaultBaseUrl: 'https://api.fish.audio',\n docsUrl: 'https://fish.audio',\n },\n {\n id: 'senseaudio',\n label: 'SenseAudio',\n hint: '',\n integrated: true,\n defaultBaseUrl: 'https://api.senseaudio.cn',\n docsUrl: 'https://docs.senseaudio.cn',\n },\n {\n id: 'tavily',\n label: 'Tavily Search',\n hint: 'Agent-callable web research',\n integrated: true,\n defaultBaseUrl: 'https://api.tavily.com',\n docsUrl: 'https://app.tavily.com/home',\n },\n {\n id: 'toothfairyai',\n label: 'ToothFairyAI',\n hint: 'TF backend — unified media generation',\n integrated: true,\n credentialsRequired: false,\n defaultBaseUrl: 'https://api.toothfairylab.link',\n },\n {\n id: 'stub',\n label: 'Stub (placeholder)',\n hint: 'Deterministic local placeholder bytes',\n integrated: true,\n // Internal fixture provider used by the daemon for deterministic\n // tests / offline demos. Hidden from Settings the same way\n // HyperFrames is — end users have nothing to configure here, and\n // exposing it pollutes the provider list.\n settingsVisible: false,\n },\n];\n\nexport interface MediaModel {\n /** Stable ID used in metadata.imageModel / videoModel / audioModel. */\n id: string;\n /** Short label shown in pickers. */\n label: string;\n /** Vendor / context hint shown under the label. */\n hint: string;\n /** Provider this model is dispatched through. */\n provider: MediaProviderId;\n /**\n * Capabilities the agent may rely on when planning. Used downstream by\n * the dispatcher to decide which provider call to make.\n */\n caps?: string[];\n /** Marks the default-checked card per surface in the picker. */\n default?: boolean;\n}\n\n/**\n * Image generation models. Mirrors the breadth of\n * `packages/model-bank/src/aiModels/openai.ts` and friends in lobehub.\n */\nexport const IMAGE_MODELS: MediaModel[] = [\n // OpenAI — fully integrated path.\n {\n id: 'gpt-image-2',\n label: 'gpt-image-2',\n hint: 'OpenAI · 4K, native multimodal',\n provider: 'openai',\n caps: ['t2i', 'i2i', 'inpaint'],\n default: true,\n },\n {\n id: 'gpt-image-1.5',\n label: 'gpt-image-1.5',\n hint: 'OpenAI · 4× faster than gpt-image-1',\n provider: 'openai',\n caps: ['t2i', 'i2i', 'inpaint'],\n },\n {\n id: 'gpt-image-1',\n label: 'gpt-image-1',\n hint: 'OpenAI · ChatGPT native',\n provider: 'openai',\n caps: ['t2i', 'i2i', 'inpaint'],\n },\n {\n id: 'gpt-image-1-mini',\n label: 'gpt-image-1-mini',\n hint: 'OpenAI · low-cost variant',\n provider: 'openai',\n caps: ['t2i', 'i2i'],\n },\n {\n id: 'dall-e-3',\n label: 'dall-e-3',\n hint: 'OpenAI · classic',\n provider: 'openai',\n caps: ['t2i'],\n },\n {\n id: 'dall-e-2',\n label: 'dall-e-2',\n hint: 'OpenAI · legacy',\n provider: 'openai',\n caps: ['t2i'],\n },\n\n // Volcengine — Doubao Seedream image generation.\n {\n id: 'doubao-seedream-3-0-t2i-250415',\n label: 'seedream-3.0',\n hint: 'ByteDance · Doubao image',\n provider: 'volcengine',\n caps: ['t2i'],\n },\n {\n id: 'doubao-seededit-3-0-i2i-250628',\n label: 'seededit-3.0',\n hint: 'ByteDance · image edit',\n provider: 'volcengine',\n caps: ['i2i'],\n },\n\n // SenseAudio — synchronous /v1/image/sync, Bearer auth, reference URL or data URI.\n {\n id: 'senseaudio-image-2.0-260319',\n label: 'senseaudio-image-2.0',\n hint: 'SenseAudio · multi-aspect, latest',\n provider: 'senseaudio',\n caps: ['t2i', 'i2i'],\n },\n {\n id: 'senseaudio-image-1.0-260319',\n label: 'senseaudio-image-1.0',\n hint: 'SenseAudio · standard',\n provider: 'senseaudio',\n caps: ['t2i', 'i2i'],\n },\n {\n id: 'doubao-seedream-5-0-260128',\n label: 'seedream-5.0',\n hint: 'SenseAudio · ByteDance Seedream 5.0 hi-res',\n provider: 'senseaudio',\n caps: ['t2i', 'i2i'],\n },\n\n // xAI Grok Imagine — text-to-image (1k/2k, 11+ aspect ratios).\n {\n id: 'grok-imagine-image',\n label: 'grok-imagine-image',\n hint: 'xAI · 2K text-to-image',\n provider: 'grok',\n caps: ['t2i'],\n },\n\n // Nano Banana — Google-compatible generateContent image path.\n {\n id: 'gemini-3.1-flash-image-preview',\n label: 'nano-banana-2',\n hint: 'Nano Banana · text-to-image',\n provider: 'nanobanana',\n caps: ['t2i'],\n },\n\n // ImageRouter — OpenAI-compatible routed image models.\n {\n id: 'openai/gpt-image-2',\n label: 'openai/gpt-image-2',\n hint: 'ImageRouter · routed GPT Image',\n provider: 'imagerouter',\n caps: ['t2i'],\n },\n {\n id: 'openai/gpt-image-1.5',\n label: 'openai/gpt-image-1.5',\n hint: 'ImageRouter · routed GPT Image',\n provider: 'imagerouter',\n caps: ['t2i'],\n },\n {\n id: 'black-forest-labs/FLUX-1.1-pro',\n label: 'FLUX-1.1-pro',\n hint: 'ImageRouter · Black Forest Labs',\n provider: 'imagerouter',\n caps: ['t2i'],\n },\n\n // OpenRouter image models.\n { id: 'openrouter/google/gemini-2.5-flash-image', label: 'gemini-flash-image (OR)', hint: 'OpenRouter · Gemini', provider: 'openrouter', caps: ['t2i'] },\n { id: 'openrouter/black-forest-labs/flux-1.1-pro', label: 'flux-1.1-pro (OR)', hint: 'OpenRouter · BFL', provider: 'openrouter', caps: ['t2i'] },\n { id: 'openrouter/recraft/recraft-v3', label: 'recraft-v3 (OR)', hint: 'OpenRouter · Recraft', provider: 'openrouter', caps: ['t2i'] },\n\n // Custom OpenAI-compatible image generation + edit endpoints.\n {\n id: 'custom-image',\n label: 'custom-image',\n hint: 'Custom · OpenAI-compatible endpoint',\n provider: 'custom-image',\n caps: ['t2i', 'i2i'],\n },\n\n // Black Forest Labs FLUX family.\n { id: 'flux-1.1-pro', label: 'flux-1.1-pro', hint: 'BFL · flagship', provider: 'bfl', caps: ['t2i', 'i2i'] },\n { id: 'flux-pro', label: 'flux-pro', hint: 'BFL', provider: 'bfl', caps: ['t2i'] },\n { id: 'flux-dev', label: 'flux-dev', hint: 'BFL · open weights', provider: 'bfl', caps: ['t2i'] },\n { id: 'flux-schnell', label: 'flux-schnell', hint: 'BFL · fast', provider: 'bfl', caps: ['t2i'] },\n { id: 'flux-kontext-pro', label: 'flux-kontext-pro', hint: 'BFL · in-context edits', provider: 'bfl', caps: ['t2i', 'i2i'] },\n\n // Google.\n { id: 'imagen-4', label: 'imagen-4', hint: 'Google · latest', provider: 'google', caps: ['t2i'] },\n { id: 'imagen-3', label: 'imagen-3', hint: 'Google', provider: 'google', caps: ['t2i'] },\n { id: 'gemini-3-pro-image-preview', label: 'gemini-3-pro-image', hint: 'Google · Nano Banana Pro', provider: 'google', caps: ['t2i', 'i2i'] },\n\n // Replicate hosted image models.\n { id: 'ideogram-v2', label: 'ideogram-v2', hint: 'Replicate · typography', provider: 'replicate', caps: ['t2i'] },\n { id: 'sdxl', label: 'stable-diffusion-xl', hint: 'Replicate · SDXL', provider: 'replicate', caps: ['t2i'] },\n\n // Fal.ai image models — pass any fal-ai/* path as model for custom models.\n { id: 'flux-pro-ultra', label: 'flux-pro-ultra', hint: 'Fal · FLUX 1.1 Pro Ultra · highest quality', provider: 'fal', caps: ['t2i'] },\n { id: 'flux-dev-fal', label: 'flux-dev (fal)', hint: 'Fal · FLUX Dev · open weights', provider: 'fal', caps: ['t2i'] },\n { id: 'flux-schnell-fal', label: 'flux-schnell (fal)', hint: 'Fal · FLUX Schnell · fastest / cheapest', provider: 'fal', caps: ['t2i'] },\n { id: 'ideogram-v3-fal', label: 'ideogram-v3', hint: 'Fal · Ideogram v3 · typography + design', provider: 'fal', caps: ['t2i'] },\n { id: 'recraft-v3-fal', label: 'recraft-v3', hint: 'Fal · Recraft v3 · vector + illustration', provider: 'fal', caps: ['t2i'] },\n { id: 'sd-3.5', label: 'stable-diffusion-3.5', hint: 'Fal · SD 3.5', provider: 'fal', caps: ['t2i'] },\n\n // Leonardo.ai models\n { id: 'leonardo-phoenix', label: 'Phoenix', hint: 'Leonardo · versatile', provider: 'leonardo', caps: ['t2i'] },\n { id: 'leonardo-kino-xl', label: 'Kino XL', hint: 'Leonardo · cinematic', provider: 'leonardo', caps: ['t2i'] },\n { id: 'leonardo-flux-dev', label: 'FLUX Dev', hint: 'Leonardo · FLUX', provider: 'leonardo', caps: ['t2i'] },\n { id: 'leonardo-flux-schnell', label: 'FLUX Schnell', hint: 'Leonardo · fast', provider: 'leonardo', caps: ['t2i'] },\n { id: 'leonardo-anime-pastel', label: 'Anime Pastel Dream', hint: 'Leonardo · anime', provider: 'leonardo', caps: ['t2i'] },\n\n // Midjourney via community proxies.\n { id: 'midjourney-v7', label: 'midjourney-v7', hint: 'Midjourney · via proxy', provider: 'midjourney', caps: ['t2i'] },\n\n // ToothFairyAI backend models.\n { id: 'mystica_sd', label: 'Mystica SD', hint: 'TF · nano-banana-pro', provider: 'toothfairyai', caps: ['t2i'] },\n { id: 'mystica_realism_sd', label: 'Mystica Realism', hint: 'TF · flux-dev-realism', provider: 'toothfairyai', caps: ['t2i'] },\n { id: 'sorcerer_canvas', label: 'Sorcerer Canvas', hint: 'TF · nano-banana-pro', provider: 'toothfairyai', caps: ['t2i'] },\n { id: 'sorcerer_vision', label: 'Sorcerer Vision', hint: 'TF · imagen-4-fast', provider: 'toothfairyai', caps: ['t2i'] },\n { id: 'mystica_vision', label: 'Mystica Vision', hint: 'TF · imagen-4', provider: 'toothfairyai', caps: ['t2i'] },\n];\n\n/**\n * Video generation models. Mirrors lobehub's volcengine.ts (Seedance,\n * Seedance Lite), kling.ts and friends.\n */\nexport const VIDEO_MODELS: MediaModel[] = [\n // Volcengine — Seedance 2.0 (integrated).\n {\n id: 'doubao-seedance-2-0-260128',\n label: 'seedance-2.0',\n hint: 'ByteDance · t2v + i2v + audio',\n provider: 'volcengine',\n caps: ['t2v', 'i2v', 'audio'],\n default: true,\n },\n {\n id: 'doubao-seedance-2-0-fast-260128',\n label: 'seedance-2.0-fast',\n hint: 'ByteDance · faster, cheaper',\n provider: 'volcengine',\n caps: ['t2v', 'i2v', 'audio'],\n },\n {\n id: 'doubao-seedance-1-0-pro-250528',\n label: 'seedance-1.0-pro',\n hint: 'ByteDance · 1.0',\n provider: 'volcengine',\n caps: ['t2v', 'i2v'],\n },\n {\n id: 'doubao-seedance-1-0-lite-i2v-250428',\n label: 'seedance-1.0-lite-i2v',\n hint: 'ByteDance · image-to-video',\n provider: 'volcengine',\n caps: ['i2v'],\n },\n {\n id: 'doubao-seedance-1-0-lite-t2v-250428',\n label: 'seedance-1.0-lite-t2v',\n hint: 'ByteDance · text-to-video',\n provider: 'volcengine',\n caps: ['t2v'],\n },\n\n // xAI Grok Imagine — 720p t2v + i2v with natively generated audio.\n {\n id: 'grok-imagine-video',\n label: 'grok-imagine-video',\n hint: 'xAI · 720p t2v + i2v + native audio',\n provider: 'grok',\n caps: ['t2v', 'i2v', 'audio'],\n },\n\n // OpenRouter video models.\n { id: 'openrouter/bytedance/seedance-2.0:1080p', label: 'seedance-2.0 1080p (OR)', hint: 'OpenRouter · ByteDance · 1080p', provider: 'openrouter', caps: ['t2v', 'i2v'], default: true },\n { id: 'openrouter/bytedance/seedance-2.0', label: 'seedance-2.0 720p (OR)', hint: 'OpenRouter · ByteDance · 720p', provider: 'openrouter', caps: ['t2v', 'i2v'] },\n { id: 'openrouter/bytedance/seedance-2.0:480p', label: 'seedance-2.0 480p (OR)', hint: 'OpenRouter · ByteDance · 480p', provider: 'openrouter', caps: ['t2v', 'i2v'] },\n { id: 'openrouter/google/veo-3.1', label: 'veo-3.1 (OR)', hint: 'OpenRouter · Google', provider: 'openrouter', caps: ['t2v', 'i2v', 'audio'] },\n { id: 'openrouter/alibaba/wan-2.7', label: 'wan-2.7 (OR)', hint: 'OpenRouter · Alibaba', provider: 'openrouter', caps: ['t2v', 'i2v'] },\n { id: 'openrouter/kwaivgi/kling-v3.0-pro', label: 'kling-v3.0-pro (OR)', hint: 'OpenRouter · Kuaishou', provider: 'openrouter', caps: ['t2v', 'i2v'] },\n\n // ImageRouter — routed video models.\n {\n id: 'xAI/grok-imagine-video',\n label: 'xAI/grok-imagine-video',\n hint: 'ImageRouter · routed video',\n provider: 'imagerouter',\n caps: ['t2v', 'audio'],\n },\n {\n id: 'bytedance/seedance-1.5-pro',\n label: 'seedance-1.5-pro',\n hint: 'ImageRouter · Bytedance',\n provider: 'imagerouter',\n caps: ['t2v'],\n },\n {\n id: 'google/veo-3.1-lite',\n label: 'veo-3.1-lite',\n hint: 'ImageRouter · Google',\n provider: 'imagerouter',\n caps: ['t2v'],\n },\n\n // Kuaishou Kling.\n { id: 'kling-2.0', label: 'kling-2.0', hint: 'Kuaishou · latest', provider: 'kling', caps: ['t2v', 'i2v'] },\n { id: 'kling-1.6', label: 'kling-1.6', hint: 'Kuaishou', provider: 'kling', caps: ['t2v', 'i2v'] },\n { id: 'kling-1.5', label: 'kling-1.5', hint: 'Kuaishou', provider: 'kling', caps: ['t2v', 'i2v'] },\n\n // Google Veo.\n { id: 'veo-3', label: 'veo-3', hint: 'Google · sound-on', provider: 'google', caps: ['t2v', 'audio'] },\n { id: 'veo-2', label: 'veo-2', hint: 'Google', provider: 'google', caps: ['t2v'] },\n\n // Fal.ai video models — pass any fal-ai/* path as model for custom models.\n { id: 'veo-3-fal', label: 'veo-3 (fal)', hint: 'Fal · Google Veo 3 · sound-on', provider: 'fal', caps: ['t2v', 'audio'] },\n { id: 'veo-2-fal', label: 'veo-2 (fal)', hint: 'Fal · Google Veo 2', provider: 'fal', caps: ['t2v'] },\n { id: 'wan-2.1-t2v', label: 'wan-2.1-t2v', hint: 'Fal · Wan 2.1 text-to-video', provider: 'fal', caps: ['t2v'] },\n { id: 'wan-2.1-i2v', label: 'wan-2.1-i2v', hint: 'Fal · Wan 2.1 image-to-video', provider: 'fal', caps: ['i2v'] },\n { id: 'seedance-1-pro-fal', label: 'seedance-1-pro (fal)', hint: 'Fal · Seedance 1 Pro', provider: 'fal', caps: ['t2v', 'i2v'] },\n { id: 'kling-2.1-t2v-fal', label: 'kling-2.1 (fal)', hint: 'Fal · Kling 2.1 Pro text-to-video', provider: 'fal', caps: ['t2v'] },\n { id: 'sora-2', label: 'sora-2', hint: 'Fal · OpenAI Sora 2', provider: 'fal', caps: ['t2v'] },\n { id: 'sora-2-pro', label: 'sora-2-pro', hint: 'Fal · OpenAI Sora 2 Pro', provider: 'fal', caps: ['t2v'] },\n\n // MiniMax video.\n { id: 'minimax-video-01', label: 'video-01', hint: 'MiniMax · Hailuo', provider: 'minimax', caps: ['t2v', 'i2v'] },\n { id: 'hyperframes-html', label: 'hyperframes-html', hint: 'HyperFrames · local HTML renderer', provider: 'hyperframes', caps: ['t2v'] },\n\n // ToothFairyAI video models.\n { id: 'sorcerer_motion', label: 'Sorcerer Motion', hint: 'TF · veo-3.1-fast', provider: 'toothfairyai', caps: ['t2v'], default: true },\n { id: 'mystica_motion', label: 'Mystica Motion', hint: 'TF · veo-3.1', provider: 'toothfairyai', caps: ['t2v'] },\n { id: 'mystica_motion_pro', label: 'Mystica Motion Pro', hint: 'TF · veo-3', provider: 'toothfairyai', caps: ['t2v'] },\n { id: 'mystica_video_sd', label: 'Mystica Video SD', hint: 'TF · minimax-video-01', provider: 'toothfairyai', caps: ['t2v'] },\n];\n\nexport const AUDIO_MODELS_BY_KIND: Record<AudioKind, MediaModel[]> = {\n music: [\n { id: 'suno-v5', label: 'suno-v5', hint: 'Suno · default', provider: 'suno', caps: ['music'], default: true },\n { id: 'suno-v4-5', label: 'suno-v4.5', hint: 'Suno', provider: 'suno', caps: ['music'] },\n { id: 'udio-v2', label: 'udio-v2', hint: 'Udio', provider: 'udio', caps: ['music'] },\n { id: 'lyria-2', label: 'lyria-2', hint: 'Google', provider: 'google', caps: ['music'] },\n ],\n speech: [\n { id: 'minimax-tts', label: 'minimax-tts', hint: 'MiniMax', provider: 'minimax', caps: ['tts'], default: true },\n { id: 'fish-speech-2', label: 'fish-speech-2', hint: 'FishAudio', provider: 'fishaudio', caps: ['tts', 'voice-clone'] },\n { id: 'elevenlabs-v3', label: 'elevenlabs-v3', hint: 'ElevenLabs', provider: 'elevenlabs', caps: ['tts', 'voice-clone'] },\n { id: 'senseaudio-tts', label: 'senseaudio-tts', hint: 'SenseAudio', provider: 'senseaudio', caps: ['tts', 'voice-clone'] },\n { id: 'doubao-tts', label: 'doubao-tts', hint: 'Volcengine', provider: 'volcengine', caps: ['tts'] },\n { id: 'gpt-4o-mini-tts', label: 'gpt-4o-mini-tts', hint: 'OpenAI', provider: 'openai', caps: ['tts'] },\n ],\n sfx: [\n { id: 'elevenlabs-sfx', label: 'elevenlabs-sfx', hint: 'ElevenLabs SFX', provider: 'elevenlabs', caps: ['sfx'], default: true },\n { id: 'audiocraft', label: 'audiocraft', hint: 'Meta · open', provider: 'replicate', caps: ['sfx', 'music'] },\n\n // ToothFairyAI audio models.\n { id: 'mystica_music', label: 'Mystica Music', hint: 'TF · music generation', provider: 'toothfairyai', caps: ['music'] },\n { id: 'mystica_voice', label: 'Mystica Voice', hint: 'TF · TTS generation', provider: 'toothfairyai', caps: ['tts'] },\n { id: 'mystica_sfx', label: 'Mystica SFX', hint: 'TF · sound effects', provider: 'toothfairyai', caps: ['sfx'] },\n ],\n};\n\nexport const MEDIA_ASPECTS: MediaAspect[] = ['1:1', '16:9', '9:16', '4:3', '3:4'];\n\nexport const VIDEO_LENGTHS_SEC: number[] = [3, 5, 8, 10, 15, 30];\nexport const AUDIO_DURATIONS_SEC: number[] = [5, 10, 15, 30, 60, 120];\n\nexport const DEFAULT_IMAGE_MODEL =\n IMAGE_MODELS.find((m) => m.default)?.id ?? IMAGE_MODELS[0]!.id;\nexport const DEFAULT_VIDEO_MODEL =\n VIDEO_MODELS.find((m) => m.default)?.id ?? VIDEO_MODELS[0]!.id;\nexport const DEFAULT_AUDIO_MODEL: Record<AudioKind, string> = {\n music:\n AUDIO_MODELS_BY_KIND.music.find((m) => m.default)?.id\n ?? AUDIO_MODELS_BY_KIND.music[0]!.id,\n speech:\n AUDIO_MODELS_BY_KIND.speech.find((m) => m.default)?.id\n ?? AUDIO_MODELS_BY_KIND.speech[0]!.id,\n sfx:\n AUDIO_MODELS_BY_KIND.sfx.find((m) => m.default)?.id\n ?? AUDIO_MODELS_BY_KIND.sfx[0]!.id,\n};\n\n/**\n * Look up a model record across all surfaces by ID. Returns null if the\n * agent passes an unknown model — the dispatcher rejects with a clear\n * error so the agent re-plans instead of silently falling back.\n */\nexport function findMediaModel(id: string): MediaModel | null {\n const all: MediaModel[] = [\n ...IMAGE_MODELS,\n ...VIDEO_MODELS,\n ...AUDIO_MODELS_BY_KIND.music,\n ...AUDIO_MODELS_BY_KIND.speech,\n ...AUDIO_MODELS_BY_KIND.sfx,\n ];\n return all.find((m) => m.id === id) ?? null;\n}\n\nexport function findProvider(id: MediaProviderId): MediaProvider | null {\n return MEDIA_PROVIDERS.find((p) => p.id === id) ?? null;\n}\n\n/** All model IDs grouped by surface, used for prompt-side disclosure. */\nexport function modelIdsBySurface(): {\n image: string[];\n video: string[];\n audio: { music: string[]; speech: string[]; sfx: string[] };\n} {\n return {\n image: IMAGE_MODELS.map((m) => m.id),\n video: VIDEO_MODELS.map((m) => m.id),\n audio: {\n music: AUDIO_MODELS_BY_KIND.music.map((m) => m.id),\n speech: AUDIO_MODELS_BY_KIND.speech.map((m) => m.id),\n sfx: AUDIO_MODELS_BY_KIND.sfx.map((m) => m.id),\n },\n };\n}\n\n/**\n * Group a flat list of {@link MediaModel} by provider while preserving\n * the catalogue order. Used by the picker to render section headers.\n */\nexport function groupByProvider(models: MediaModel[]): Array<{\n provider: MediaProvider;\n models: MediaModel[];\n}> {\n const order: MediaProviderId[] = [];\n const map = new Map<MediaProviderId, MediaModel[]>();\n for (const m of models) {\n if (!map.has(m.provider)) {\n order.push(m.provider);\n map.set(m.provider, []);\n }\n map.get(m.provider)!.push(m);\n }\n return order\n .map((id) => {\n const provider = findProvider(id);\n const list = map.get(id) ?? [];\n return provider ? { provider, models: list } : null;\n })\n .filter((entry): entry is { provider: MediaProvider; models: MediaModel[] } => entry != null);\n}\n","import type {\n ConnectorAuthConfigPrepareResponse,\n ConnectorDetail,\n ConnectorConnectResponse,\n ConnectorDiscoveryResponse,\n ConnectorDetailResponse,\n ConnectorListResponse,\n ConnectorStatusResponse,\n ImportGitHubDesignSystemRequest,\n ImportGitHubDesignSystemResponse,\n OpenDesignGithubLatestReleaseResponse,\n ImportLocalDesignSystemRequest,\n ImportLocalDesignSystemResponse,\n ReplaceProjectWorkingDirResponse,\n} from '@open-design/contracts';\nimport type {\n AgentInfo,\n AppVersionInfo,\n AppVersionResponse,\n ChatAttachment,\n CodexPetSummary,\n CodexPetsResponse,\n InstallDesignSystemResponse,\n InstallInput,\n InstallSkillResponse,\n SyncCommunityPetsRequest,\n SyncCommunityPetsResponse,\n PreviewComment,\n PreviewCommentStatus,\n PreviewCommentUpsertRequest,\n CloudflarePagesDeploySelection,\n CloudflarePagesZonesResponse,\n DeployConfigResponse,\n DeployProjectFileResponse,\n DesignSystemDetail,\n DesignSystemFileDetail,\n DesignSystemFileSummary,\n DesignSystemGenerationJob,\n DesignSystemPackageAudit,\n DesignSystemProvenance,\n DesignSystemRevision,\n DesignSystemRevisionJobRequest,\n DesignSystemRevisionStatus,\n DesignSystemSummary,\n LiveArtifact,\n LiveArtifactRefreshLogEntry,\n LiveArtifactSummary,\n Project,\n ProjectDeploymentsResponse,\n PromptTemplateDetail,\n PromptTemplateSummary,\n ProjectFile,\n RenameProjectFileResponse,\n SkillDetail,\n SkillSummary,\n UpdateDeployConfigRequest,\n} from '../types';\nimport type { ArtifactManifest } from '../artifacts/types';\nimport {\n isOpenDesignHostAvailable,\n openHostExternalUrl,\n} from '@open-design/host';\n\nexport const DEFAULT_DEPLOY_PROVIDER_ID = 'vercel-self';\nexport const CLOUDFLARE_PAGES_PROVIDER_ID = 'cloudflare-pages';\nexport const DEPLOY_PROVIDER_IDS = [\n DEFAULT_DEPLOY_PROVIDER_ID,\n CLOUDFLARE_PAGES_PROVIDER_ID,\n] as const;\n\nexport type WebDeployProviderId = (typeof DEPLOY_PROVIDER_IDS)[number];\n\nexport type WebDeployConfigResponse = DeployConfigResponse;\nexport type WebUpdateDeployConfigRequest = UpdateDeployConfigRequest;\nexport type WebDeploymentInfo = ProjectDeploymentsResponse['deployments'][number];\nexport type WebDeployProjectFileResponse = DeployProjectFileResponse;\nexport type WebCloudflarePagesDeploySelection = CloudflarePagesDeploySelection;\nexport type WebCloudflarePagesZonesResponse = CloudflarePagesZonesResponse;\n\nexport function isDeployProviderId(value: unknown): value is WebDeployProviderId {\n return typeof value === 'string' && (DEPLOY_PROVIDER_IDS as readonly string[]).includes(value);\n}\n\nfunction deployProviderQuery(providerId?: WebDeployProviderId): string {\n return providerId ? `?providerId=${encodeURIComponent(providerId)}` : '';\n}\n\nexport async function fetchAgents(options?: { throwOnError?: boolean }): Promise<AgentInfo[]> {\n try {\n const resp = await fetch('/api/agents', { cache: 'no-store' });\n if (!resp.ok) {\n if (options?.throwOnError) throw new Error(`agents ${resp.status}`);\n return [];\n }\n const json = (await resp.json()) as { agents: AgentInfo[] };\n return json.agents ?? [];\n } catch (err) {\n if (options?.throwOnError) throw err;\n return [];\n }\n}\n\nexport async function fetchSkills(): Promise<SkillSummary[]> {\n try {\n const resp = await fetch('/api/skills');\n if (!resp.ok) return [];\n const json = (await resp.json()) as { skills: SkillSummary[] };\n return json.skills ?? [];\n } catch {\n return [];\n }\n}\n\n// Design templates — the rendering catalogue (decks, prototypes, image/\n// video/audio templates). Same SkillSummary shape as functional skills,\n// fetched from a separate registry root so the EntryView Templates tab\n// and Settings → Skills surface stay decoupled. See\n// specs/current/skills-and-design-templates.md.\nexport async function fetchDesignTemplates(): Promise<SkillSummary[]> {\n try {\n const resp = await fetch('/api/design-templates');\n if (!resp.ok) return [];\n const json = (await resp.json()) as { designTemplates: SkillSummary[] };\n return json.designTemplates ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function fetchDesignTemplate(id: string): Promise<SkillDetail | null> {\n try {\n const resp = await fetch(`/api/design-templates/${encodeURIComponent(id)}`);\n if (!resp.ok) return null;\n return (await resp.json()) as SkillDetail;\n } catch {\n return null;\n }\n}\n\n// Pets packaged by the Codex `hatch-pet` skill — surfaced so the web\n// pet settings can offer one-click adoption right after the agent run\n// finishes. Returns an empty list (not an error) when the registry\n// folder is missing so the \"Recently hatched\" UI can simply render an\n// empty state.\nexport async function fetchCodexPets(): Promise<CodexPetsResponse> {\n try {\n const resp = await fetch('/api/codex-pets');\n if (!resp.ok) return { pets: [], rootDir: '' };\n return (await resp.json()) as CodexPetsResponse;\n } catch {\n return { pets: [], rootDir: '' };\n }\n}\n\n// One-click trigger for the daemon-side port of `sync-community-pets`.\n// Always resolves with a summary (even when the daemon errored) so the\n// caller can render a status line without having to wrap in try/catch\n// on every keystroke.\nexport async function syncCommunityPets(\n input?: SyncCommunityPetsRequest,\n): Promise<SyncCommunityPetsResponse & { error?: string }> {\n try {\n const resp = await fetch('/api/codex-pets/sync', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input ?? {}),\n });\n if (!resp.ok) {\n const payload = (await resp.json().catch(() => null)) as\n | { error?: string }\n | null;\n return {\n wrote: 0,\n skipped: 0,\n failed: 0,\n total: 0,\n rootDir: '',\n errors: [],\n error: payload?.error ?? `Sync failed (${resp.status})`,\n };\n }\n return (await resp.json()) as SyncCommunityPetsResponse;\n } catch (err) {\n return {\n wrote: 0,\n skipped: 0,\n failed: 0,\n total: 0,\n rootDir: '',\n errors: [],\n error: err instanceof Error ? err.message : 'Sync request failed',\n };\n }\n}\n\nexport function codexPetSpritesheetUrl(pet: CodexPetSummary): string {\n // The daemon stamps an absolute path-prefix in `spritesheetUrl`; if\n // that prefix is empty (default), it is already a same-origin path\n // we can hand to <img src> or fetch() as-is.\n return pet.spritesheetUrl;\n}\n\n// Body for POST /api/skills/import. Mirrors the contracts type but is\n// repeated here so the registry module is self-describing for callers.\nexport interface SkillImportInput {\n name: string;\n description?: string;\n body: string;\n triggers?: string[];\n}\n\nexport interface SkillImportError {\n code?: string;\n message: string;\n}\n\nexport async function importSkill(\n input: SkillImportInput,\n): Promise<{ skill: SkillSummary } | { error: SkillImportError }> {\n try {\n const resp = await fetch('/api/skills/import', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) {\n const payload = (await resp.json().catch(() => null)) as\n | { error?: SkillImportError }\n | null;\n return {\n error: {\n code: payload?.error?.code,\n message: payload?.error?.message ?? `Import failed (${resp.status}).`,\n },\n };\n }\n return (await resp.json()) as { skill: SkillSummary };\n } catch (err) {\n return {\n error: {\n message: err instanceof Error ? err.message : 'Import request failed.',\n },\n };\n }\n}\n\n// Update an existing skill's body. For built-in skills the daemon writes\n// a \"shadow\" copy under the user-skills root; the next listSkills() pass\n// surfaces it in place of the bundled copy. The id passed here must\n// match the SKILL.md frontmatter `name` — the daemon refuses cross-id\n// renames so callers can drop \"edit\" into the same surface they use for\n// \"edit my own draft\".\nexport interface SkillUpdateInput {\n name?: string;\n description?: string;\n body: string;\n triggers?: string[];\n}\n\nexport async function updateSkill(\n id: string,\n input: SkillUpdateInput,\n): Promise<{ skill: SkillSummary } | { error: SkillImportError }> {\n try {\n const resp = await fetch(`/api/skills/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) {\n const payload = (await resp.json().catch(() => null)) as\n | { error?: SkillImportError }\n | null;\n return {\n error: {\n code: payload?.error?.code,\n message:\n payload?.error?.message ?? `Update failed (${resp.status}).`,\n },\n };\n }\n return (await resp.json()) as { skill: SkillSummary };\n } catch (err) {\n return {\n error: {\n message: err instanceof Error ? err.message : 'Update request failed.',\n },\n };\n }\n}\n\nexport interface SkillFileEntry {\n path: string;\n kind: 'file' | 'directory';\n size: number | null;\n}\n\nexport async function fetchSkillFiles(id: string): Promise<SkillFileEntry[]> {\n try {\n const resp = await fetch(\n `/api/skills/${encodeURIComponent(id)}/files`,\n );\n if (!resp.ok) return [];\n const json = (await resp.json()) as { files: SkillFileEntry[] };\n return json.files ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function deleteSkill(\n id: string,\n): Promise<{ ok: true } | { error: SkillImportError }> {\n try {\n const resp = await fetch(`/api/skills/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n if (!resp.ok) {\n const payload = (await resp.json().catch(() => null)) as\n | { error?: SkillImportError }\n | null;\n return {\n error: {\n code: payload?.error?.code,\n message: payload?.error?.message ?? `Delete failed (${resp.status}).`,\n },\n };\n }\n return { ok: true };\n } catch (err) {\n return {\n error: {\n message: err instanceof Error ? err.message : 'Delete request failed.',\n },\n };\n }\n}\n\nexport async function fetchSkill(id: string): Promise<SkillDetail | null> {\n try {\n const resp = await fetch(`/api/skills/${encodeURIComponent(id)}`);\n if (!resp.ok) return null;\n return (await resp.json()) as SkillDetail;\n } catch {\n return null;\n }\n}\n\nexport async function fetchDesignSystems(): Promise<DesignSystemSummary[]> {\n const result = await fetchDesignSystemsResult();\n return result.ok ? result.designSystems : [];\n}\n\n// Discriminated-union variant: surfaces the fetch outcome instead of\n// collapsing a network/HTTP failure into an empty array. The mid-chat\n// design-system picker uses this so it can render a load-failure state\n// instead of silently showing an empty catalog, which would otherwise\n// be indistinguishable from \"registry truly has no systems.\"\nexport type DesignSystemsResult =\n | { ok: true; designSystems: DesignSystemSummary[] }\n | { ok: false };\n\nexport async function fetchDesignSystemsResult(): Promise<DesignSystemsResult> {\n try {\n const resp = await fetch('/api/design-systems');\n if (!resp.ok) return { ok: false };\n const json = (await resp.json()) as { designSystems?: DesignSystemSummary[] };\n return { ok: true, designSystems: json.designSystems ?? [] };\n } catch {\n return { ok: false };\n }\n}\n\nexport async function fetchDesignSystem(id: string): Promise<DesignSystemDetail | null> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}`);\n if (!resp.ok) return null;\n return parseDesignSystemDetail(await resp.json());\n } catch {\n return null;\n }\n}\n\nexport async function fetchDesignSystemFiles(\n id: string,\n): Promise<DesignSystemFileSummary[]> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}/files`);\n if (!resp.ok) return [];\n const json = (await resp.json()) as { files: DesignSystemFileSummary[] };\n return json.files ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function fetchDesignSystemFile(\n id: string,\n filePath: string,\n): Promise<DesignSystemFileDetail | null> {\n try {\n const resp = await fetch(\n `/api/design-systems/${encodeURIComponent(id)}/file?path=${encodeURIComponent(filePath)}`,\n );\n if (!resp.ok) return null;\n const json = (await resp.json()) as { file?: DesignSystemFileDetail };\n return json.file ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function ensureDesignSystemWorkspace(\n id: string,\n): Promise<{ project: Project; files: ProjectFile[] } | null> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}/workspace`, {\n method: 'POST',\n });\n if (!resp.ok) return null;\n return (await resp.json()) as { project: Project; files: ProjectFile[] };\n } catch {\n return null;\n }\n}\n\nfunction parseDesignSystemDetail(json: unknown): DesignSystemDetail | null {\n if (!json || typeof json !== 'object') return null;\n const wrapper = json as { designSystem?: DesignSystemDetail };\n return wrapper.designSystem ?? (json as DesignSystemDetail);\n}\n\nexport interface DesignSystemDraftInput {\n title: string;\n summary?: string;\n category?: string;\n surface?: 'web' | 'image' | 'video' | 'audio';\n status?: 'draft' | 'published';\n artifactMode?: 'generated' | 'agent-managed';\n body?: string;\n sourceNotes?: string;\n provenance?: DesignSystemProvenance;\n}\n\nexport async function createDesignSystemDraft(\n input: DesignSystemDraftInput,\n): Promise<DesignSystemDetail | null> {\n try {\n const resp = await fetch('/api/design-systems', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) return null;\n return parseDesignSystemDetail(await resp.json());\n } catch {\n return null;\n }\n}\n\nexport async function startDesignSystemGenerationJob(\n input: DesignSystemDraftInput,\n): Promise<DesignSystemGenerationJob | null> {\n try {\n const resp = await fetch('/api/design-systems/generation-jobs', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) return null;\n const json = (await resp.json()) as { job?: DesignSystemGenerationJob };\n return json.job ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function fetchDesignSystemGenerationJob(\n id: string,\n): Promise<DesignSystemGenerationJob | null> {\n try {\n const resp = await fetch(`/api/design-systems/generation-jobs/${encodeURIComponent(id)}`);\n if (!resp.ok) return null;\n const json = (await resp.json()) as { job?: DesignSystemGenerationJob };\n return json.job ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function fetchProjectDesignSystemPackageAudit(\n projectId: string,\n): Promise<DesignSystemPackageAudit | null> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/design-system-package-audit`,\n { cache: 'no-store' },\n );\n if (!resp.ok) return null;\n const json = (await resp.json()) as { audit?: DesignSystemPackageAudit };\n return json.audit ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function fetchDesignSystemRevisions(\n id: string,\n): Promise<DesignSystemRevision[]> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}/revisions`);\n if (!resp.ok) return [];\n const json = (await resp.json()) as { revisions?: DesignSystemRevision[] };\n return json.revisions ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function updateDesignSystemRevisionStatus(\n id: string,\n revisionId: string,\n status: Extract<DesignSystemRevisionStatus, 'accepted' | 'rejected'>,\n): Promise<DesignSystemRevision | null> {\n try {\n const resp = await fetch(\n `/api/design-systems/${encodeURIComponent(id)}/revisions/${encodeURIComponent(revisionId)}`,\n {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ status }),\n },\n );\n if (!resp.ok) return null;\n const json = (await resp.json()) as { revision?: DesignSystemRevision };\n return json.revision ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function startDesignSystemRevisionJob(\n id: string,\n input: DesignSystemRevisionJobRequest,\n): Promise<DesignSystemGenerationJob | null> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}/revision-jobs`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) return null;\n const json = (await resp.json()) as { job?: DesignSystemGenerationJob };\n return json.job ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function updateDesignSystemDraft(\n id: string,\n input: Partial<DesignSystemDraftInput>,\n): Promise<DesignSystemDetail | null> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) return null;\n return parseDesignSystemDetail(await resp.json());\n } catch {\n return null;\n }\n}\n\nexport async function deleteDesignSystemDraft(id: string): Promise<boolean> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n return resp.ok;\n } catch {\n return false;\n }\n}\n\nexport async function importLocalDesignSystem(\n input: ImportLocalDesignSystemRequest,\n): Promise<ImportLocalDesignSystemResponse | { error: SkillImportError }> {\n try {\n const resp = await fetch('/api/design-systems/import/local', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) {\n return { error: await readImportError(resp) };\n }\n return (await resp.json()) as ImportLocalDesignSystemResponse;\n } catch (err) {\n return {\n error: {\n message: err instanceof Error ? err.message : 'Import request failed.',\n },\n };\n }\n}\n\nexport async function importGitHubDesignSystem(\n input: ImportGitHubDesignSystemRequest,\n): Promise<ImportGitHubDesignSystemResponse | { error: SkillImportError }> {\n try {\n const resp = await fetch('/api/design-systems/import/github', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) return { error: await readImportError(resp) };\n return (await resp.json()) as ImportGitHubDesignSystemResponse;\n } catch (err) {\n return {\n error: {\n message: err instanceof Error ? err.message : 'Import request failed.',\n },\n };\n }\n}\n\nasync function readImportError(resp: Response): Promise<SkillImportError> {\n const payload = (await resp.json().catch(() => null)) as\n | { error?: SkillImportError | string; message?: string }\n | null;\n const error = payload?.error;\n if (typeof error === 'object' && error !== null) return error;\n return {\n message:\n typeof error === 'string'\n ? error\n : payload?.message ?? `Import failed (${resp.status}).`,\n };\n}\n\nexport async function fetchPromptTemplates(): Promise<PromptTemplateSummary[]> {\n try {\n const resp = await fetch('/api/prompt-templates');\n if (!resp.ok) return [];\n const json = (await resp.json()) as { promptTemplates: PromptTemplateSummary[] };\n return json.promptTemplates ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function fetchPromptTemplate(\n surface: 'image' | 'video',\n id: string,\n): Promise<PromptTemplateDetail | null> {\n try {\n const resp = await fetch(\n `/api/prompt-templates/${encodeURIComponent(surface)}/${encodeURIComponent(id)}`,\n );\n if (!resp.ok) return null;\n const json = (await resp.json()) as { promptTemplate: PromptTemplateDetail };\n return json.promptTemplate ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function daemonIsLive(): Promise<boolean> {\n try {\n const resp = await fetch('/api/health');\n return resp.ok;\n } catch {\n return false;\n }\n}\n\nexport async function fetchConnectors(): Promise<ConnectorDetail[]> {\n try {\n const resp = await fetch('/api/connectors');\n if (!resp.ok) return [];\n const json = (await resp.json()) as ConnectorListResponse;\n return json.connectors ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function fetchConnectorStatuses(options?: {\n signal?: AbortSignal;\n}): Promise<ConnectorStatusResponse['statuses']> {\n try {\n const resp = await fetch('/api/connectors/status', { signal: options?.signal });\n if (!resp.ok) return {};\n const json = (await resp.json()) as ConnectorStatusResponse;\n return json.statuses ?? {};\n } catch {\n return {};\n }\n}\n\nlet connectorDiscoveryCache: ConnectorDetail[] | null = null;\nlet connectorDiscoveryPromise: Promise<ConnectorDetail[]> | null = null;\n\nexport async function fetchConnectorDiscovery(options: { refresh?: boolean } = {}): Promise<ConnectorDetail[]> {\n if (options.refresh) {\n connectorDiscoveryCache = null;\n connectorDiscoveryPromise = null;\n }\n if (connectorDiscoveryCache && !options.refresh) return connectorDiscoveryCache;\n if (connectorDiscoveryPromise && !options.refresh) return connectorDiscoveryPromise;\n\n const promise = (async () => {\n try {\n const params = options.refresh ? '?refresh=true' : '';\n const resp = await fetch(`/api/connectors/discovery${params}`);\n if (!resp.ok) return [];\n const json = (await resp.json()) as ConnectorDiscoveryResponse;\n const connectors = json.connectors ?? [];\n connectorDiscoveryCache = connectors;\n return connectors;\n } catch {\n return [];\n } finally {\n connectorDiscoveryPromise = null;\n }\n })();\n connectorDiscoveryPromise = promise;\n return promise;\n}\n\nexport async function fetchConnectorDetail(\n connectorId: string,\n options: { hydrateTools?: boolean; toolsLimit?: number; toolsCursor?: string } = {},\n): Promise<ConnectorDetail | null> {\n try {\n const params = new URLSearchParams();\n if (options.hydrateTools) params.set('hydrateTools', 'true');\n if (options.toolsLimit !== undefined) params.set('toolsLimit', String(options.toolsLimit));\n if (options.toolsCursor) params.set('toolsCursor', options.toolsCursor);\n const query = params.toString();\n const resp = await fetch(`/api/connectors/${encodeURIComponent(connectorId)}${query ? `?${query}` : ''}`);\n if (!resp.ok) return null;\n const json = (await resp.json()) as ConnectorDetailResponse;\n return json.connector ?? null;\n } catch {\n return null;\n }\n}\n\nexport interface ConnectorActionResult {\n connector: ConnectorDetail | null;\n auth?: ConnectorConnectResponse['auth'];\n error?: string;\n}\n\nfunction popupBlockedMessage(): string {\n return 'Popup blocked. Allow popups for Open Design and try again.';\n}\n\nexport async function openExternalUrl(url: string): Promise<boolean> {\n if (isOpenDesignHostAvailable()) {\n const opened = await openHostExternalUrl(url);\n if (opened.ok) return true;\n }\n try {\n const resp = await fetch('/api/system/open-external', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ url }),\n });\n if (resp.ok) {\n const json = (await resp.json().catch(() => null)) as { ok?: unknown } | null;\n if (json?.ok === true) return true;\n }\n } catch {\n // Fall through to current-tab navigation below.\n }\n try {\n window.location.assign(url);\n } catch {\n return false;\n }\n return false;\n}\n\nasync function decodeConnectorError(resp: Response): Promise<string> {\n try {\n const payload = (await resp.json()) as { error?: { message?: string } } | null;\n return payload?.error?.message?.trim() || `Connector request failed (${resp.status})`;\n } catch {\n return `Connector request failed (${resp.status})`;\n }\n}\n\nexport async function connectConnector(connectorId: string): Promise<ConnectorActionResult> {\n let authWindow: Window | null = null;\n const useExternalBrowser = isOpenDesignHostAvailable();\n try {\n if (!useExternalBrowser) {\n authWindow = window.open('about:blank', '_blank');\n renderConnectorAuthLoading(authWindow, {\n title: 'Initializing auth config…',\n body: 'Creating or reusing the Composio auth configuration for this app. This can take a moment the first time.',\n });\n }\n const prepare = await prepareConnectorAuthConfig(connectorId);\n if (prepare.status !== 'ready') {\n renderConnectorAuthError(authWindow, prepare.message);\n return { connector: null, error: prepare.message };\n }\n renderConnectorAuthLoading(authWindow, {\n title: 'Opening authorization…',\n body: 'The auth config is ready. Preparing the provider authorization page.',\n });\n const resp = await fetch(`/api/connectors/${encodeURIComponent(connectorId)}/connect`, {\n method: 'POST',\n });\n if (!resp.ok) {\n const error = await decodeConnectorError(resp);\n renderConnectorAuthError(authWindow, error);\n return { connector: null, error };\n }\n const json = (await resp.json()) as ConnectorConnectResponse;\n if (json.auth?.kind === 'redirect_required' && json.auth.redirectUrl) {\n if (useExternalBrowser) {\n const opened = await openHostExternalUrl(json.auth.redirectUrl);\n if (!opened.ok) {\n return {\n connector: json.connector ?? null,\n auth: json.auth,\n error: popupBlockedMessage(),\n };\n }\n } else if (authWindow) {\n openConnectorAuthRedirect(authWindow, json.auth.redirectUrl);\n } else {\n // The embedded browser can block even the synchronous placeholder\n // popup. Ask the local daemon to open the system browser; if that\n // route is unavailable, openExternalUrl falls back to current-tab\n // navigation.\n await openExternalUrl(json.auth.redirectUrl);\n }\n } else if (json.auth?.kind === 'connected') {\n renderConnectorAuthInfo(authWindow, {\n title: 'Already connected',\n body: 'This connector is already authorized. You can close this window.',\n });\n } else if (json.auth?.kind === 'pending') {\n renderConnectorAuthInfo(authWindow, {\n title: 'Authorization pending',\n body: 'Authorization is in progress but no redirect URL was returned. Watch for an email confirmation, or open the Composio dashboard to continue.',\n });\n } else {\n renderConnectorAuthInfo(authWindow, {\n title: 'No authorization URL returned',\n body: 'The connector responded without a redirect URL. If this seems wrong, retry from Settings → Connectors, and confirm your Composio API key.',\n });\n }\n return { connector: json.connector ?? null, ...(json.auth === undefined ? {} : { auth: json.auth }) };\n } catch (err) {\n renderConnectorAuthError(authWindow, err instanceof Error && err.message ? err.message : 'Could not start connector authentication.');\n return {\n connector: null,\n error: err instanceof Error && err.message ? err.message : 'Could not start connector authentication.',\n };\n }\n}\n\nasync function prepareConnectorAuthConfig(connectorId: string): Promise<{ status: 'ready' } | { status: 'error'; message: string }> {\n const resp = await fetch('/api/connectors/auth-configs/prepare', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ connectorIds: [connectorId] }),\n });\n if (!resp.ok) {\n return { status: 'error', message: await decodeConnectorError(resp) };\n }\n const json = (await resp.json()) as ConnectorAuthConfigPrepareResponse;\n const result = json.results?.[connectorId];\n if (!result) return { status: 'error', message: 'Auth config initialization did not return a result.' };\n if (result.status === 'ready') return { status: 'ready' };\n return { status: 'error', message: result.message };\n}\n\nfunction openConnectorAuthRedirect(authWindow: Window | null, redirectUrl: string): void {\n if (authWindow) {\n renderConnectorAuthRedirect(authWindow, redirectUrl);\n try {\n authWindow.location.replace(redirectUrl);\n return;\n } catch {\n // Some embedded browsers block async popup navigation. Leave the\n // clickable fallback in the popup so the user can continue.\n }\n }\n const opened = window.open(redirectUrl, '_blank');\n if (!opened) window.location.assign(redirectUrl);\n}\n\nfunction renderConnectorAuthLoading(authWindow: Window | null, copy: { title: string; body: string }): void {\n if (!authWindow) return;\n try {\n authWindow.document.title = 'Connecting…';\n authWindow.document.body.innerHTML = `\n <main style=\"min-height:100vh;display:grid;place-items:center;margin:0;background:#0f1115;color:#f6f7fb;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;\">\n <div style=\"display:grid;gap:14px;justify-items:center;text-align:center;padding:32px;\">\n <div aria-hidden=\"true\" style=\"width:28px;height:28px;border-radius:999px;border:3px solid rgba(255,255,255,.22);border-top-color:#fff;animation:od-spin .8s linear infinite;\"></div>\n <div style=\"font-size:15px;font-weight:600;\">${escapeHtmlText(copy.title)}</div>\n <div style=\"max-width:300px;color:rgba(246,247,251,.72);font-size:13px;line-height:1.5;\">${escapeHtmlText(copy.body)}</div>\n </div>\n <style>@keyframes od-spin{to{transform:rotate(360deg)}}</style>\n </main>\n `;\n } catch {\n /* Popup may be unavailable or already navigated; ignore. */\n }\n}\n\nfunction renderConnectorAuthInfo(authWindow: Window | null, copy: { title: string; body: string }): void {\n if (!authWindow) return;\n try {\n authWindow.document.title = copy.title;\n authWindow.document.body.innerHTML = `\n <main style=\"min-height:100vh;display:grid;place-items:center;margin:0;background:#0f1115;color:#f6f7fb;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;\">\n <div style=\"display:grid;gap:14px;justify-items:center;text-align:center;padding:32px;\">\n <div style=\"font-size:15px;font-weight:600;\">${escapeHtmlText(copy.title)}</div>\n <div style=\"max-width:360px;color:rgba(246,247,251,.72);font-size:13px;line-height:1.5;\">${escapeHtmlText(copy.body)}</div>\n </div>\n </main>\n `;\n } catch {\n /* Popup may be unavailable or already navigated; ignore. */\n }\n}\n\nfunction renderConnectorAuthRedirect(authWindow: Window, redirectUrl: string): void {\n try {\n authWindow.document.title = 'Continue authorization';\n authWindow.document.body.innerHTML = `\n <main style=\"min-height:100vh;display:grid;place-items:center;margin:0;background:#0f1115;color:#f6f7fb;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;\">\n <div style=\"display:grid;gap:14px;justify-items:center;text-align:center;padding:32px;\">\n <div style=\"font-size:15px;font-weight:600;\">Continue authorization</div>\n <div style=\"max-width:300px;color:rgba(246,247,251,.72);font-size:13px;line-height:1.5;\">If this window does not redirect automatically, use the button below.</div>\n <a href=\"${escapeHtmlAttribute(redirectUrl)}\" style=\"display:inline-flex;align-items:center;justify-content:center;min-width:164px;border-radius:8px;padding:9px 14px;background:#df7b56;color:#fff;text-decoration:none;font-size:13px;font-weight:600;\">Open Composio</a>\n </div>\n </main>\n `;\n } catch {\n /* Popup may already be cross-origin; navigation fallback still runs. */\n }\n}\n\nasync function readConnectorApiErrorMessage(resp: Response): Promise<string> {\n try {\n const payload = await resp.json() as { error?: { message?: string }; message?: string };\n return payload.error?.message ?? payload.message ?? `Connection failed (${resp.status})`;\n } catch {\n return `Connection failed (${resp.status})`;\n }\n}\n\nfunction renderConnectorAuthError(authWindow: Window | null, message: string): void {\n if (!authWindow) return;\n try {\n authWindow.document.title = 'Connection failed';\n authWindow.document.body.innerHTML = `\n <main style=\"min-height:100vh;display:grid;place-items:center;margin:0;background:#0f1115;color:#f6f7fb;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;\">\n <div style=\"display:grid;gap:14px;justify-items:center;text-align:center;padding:32px;\">\n <div style=\"font-size:15px;font-weight:600;\">Connection failed</div>\n <div style=\"max-width:360px;color:rgba(246,247,251,.72);font-size:13px;line-height:1.5;\">${escapeHtmlText(message)}</div>\n </div>\n </main>\n `;\n } catch {\n /* Popup may be unavailable or already navigated; ignore. */\n }\n}\n\nfunction escapeHtmlText(value: string): string {\n return value.replace(/[&<>]/g, (char) => {\n switch (char) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n default:\n return char;\n }\n });\n}\n\nfunction escapeHtmlAttribute(value: string): string {\n return value.replace(/[&<>\"']/g, (char) => {\n switch (char) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n case '\"':\n return '"';\n case \"'\":\n return ''';\n default:\n return char;\n }\n });\n}\n\nexport async function disconnectConnector(connectorId: string): Promise<ConnectorDetail | null> {\n try {\n const resp = await fetch(`/api/connectors/${encodeURIComponent(connectorId)}/connection`, {\n method: 'DELETE',\n });\n if (!resp.ok) return null;\n const json = (await resp.json()) as ConnectorDetailResponse;\n return json.connector ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function cancelConnectorAuthorization(connectorId: string): Promise<ConnectorDetail | null> {\n try {\n const resp = await fetch(`/api/connectors/${encodeURIComponent(connectorId)}/authorization/cancel`, {\n method: 'POST',\n });\n if (!resp.ok) return null;\n const json = (await resp.json()) as ConnectorDetailResponse;\n return json.connector ?? null;\n } catch {\n return null;\n }\n}\n\nfunction isAppVersionInfo(value: unknown): value is AppVersionInfo {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as Partial<AppVersionInfo>;\n return (\n typeof candidate.version === 'string' &&\n typeof candidate.channel === 'string' &&\n typeof candidate.packaged === 'boolean' &&\n typeof candidate.platform === 'string' &&\n typeof candidate.arch === 'string'\n );\n}\n\nexport async function fetchAppVersionInfo(): Promise<AppVersionInfo | null> {\n try {\n const resp = await fetch('/api/version');\n if (!resp.ok) return null;\n const json = (await resp.json()) as Partial<AppVersionResponse>;\n return isAppVersionInfo(json.version) ? json.version : null;\n } catch {\n return null;\n }\n}\n\nexport type LatestGithubReleaseInfo = {\n tagName: string;\n htmlUrl: string;\n stale: boolean;\n};\n\nexport async function fetchLatestGithubReleaseInfo(): Promise<LatestGithubReleaseInfo | null> {\n try {\n const resp = await fetch('/api/github/open-design/releases/latest');\n if (!resp.ok) return null;\n const json = (await resp.json()) as Partial<OpenDesignGithubLatestReleaseResponse>;\n if (typeof json.tag_name !== 'string' || typeof json.html_url !== 'string') return null;\n return {\n tagName: json.tag_name,\n htmlUrl: json.html_url,\n stale: json.stale === true,\n };\n } catch {\n return null;\n }\n}\n\nexport type SkillExampleResult =\n | { html: string }\n // The skill declares a non-HTML preview surface (image / markdown / …)\n // and the daemon's `/example` endpoint only ships HTML, so calling it\n // would 404 into a misleading \"failed to fetch\" state. The modal\n // renders a calm \"no shipped preview\" affordance instead. The `kind`\n // is the raw `od.preview.type` from SKILL.md so future preview kinds\n // can be picked up by name without a registry change. Issue #897.\n | { unavailable: true; kind: string }\n | { error: string };\n\n// Returns a discriminated result so callers can distinguish a real\n// failure (network error, daemon unreachable, server error) from a\n// normal load or a missing shipped preview. Previously this collapsed\n// every failure into `null`, which left the example preview modal stuck\n// at its loading state with no recovery affordance. Issue #860.\n//\n// `previewType` is the skill's `od.preview.type` (defaults to `'html'`\n// daemon-side). Anything other than `'html'` short-circuits to an\n// `unavailable` result so we don't fire a network call against a\n// daemon endpoint that only resolves HTML files. Issue #897.\nexport async function fetchSkillExample(\n id: string,\n previewType: string = 'html',\n): Promise<SkillExampleResult> {\n if (previewType !== 'html') {\n return { unavailable: true, kind: previewType };\n }\n try {\n const resp = await fetch(`/api/skills/${encodeURIComponent(id)}/example`);\n if (!resp.ok) {\n if (resp.status === 404) {\n return { unavailable: true, kind: 'html' };\n }\n return { error: `HTTP ${resp.status}` };\n }\n return { html: await resp.text() };\n } catch (err) {\n const message = err instanceof Error ? err.message : 'network error';\n return { error: message };\n }\n}\n\nexport async function fetchDeployConfig(\n providerId?: WebDeployProviderId,\n): Promise<WebDeployConfigResponse | null> {\n try {\n const resp = await fetch(`/api/deploy/config${deployProviderQuery(providerId)}`);\n if (!resp.ok) return null;\n return (await resp.json()) as WebDeployConfigResponse;\n } catch {\n return null;\n }\n}\n\nexport async function updateDeployConfig(\n input: WebUpdateDeployConfigRequest,\n): Promise<WebDeployConfigResponse | null> {\n try {\n const resp = await fetch('/api/deploy/config', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) {\n const payload = (await resp.json().catch(() => null)) as\n | { error?: { message?: string }; message?: string }\n | null;\n throw new Error(payload?.error?.message || payload?.message || `Could not save deploy config (${resp.status})`);\n }\n return (await resp.json()) as WebDeployConfigResponse;\n } catch (err) {\n if (err instanceof Error) throw err;\n return null;\n }\n}\n\nexport async function fetchCloudflarePagesZones(): Promise<WebCloudflarePagesZonesResponse | null> {\n try {\n const resp = await fetch('/api/deploy/cloudflare-pages/zones');\n if (!resp.ok) {\n const payload = (await resp.json().catch(() => null)) as\n | { error?: { message?: string }; message?: string }\n | null;\n throw new Error(payload?.error?.message || payload?.message || `Could not load Cloudflare zones (${resp.status})`);\n }\n return (await resp.json()) as WebCloudflarePagesZonesResponse;\n } catch (err) {\n if (err instanceof Error) throw err;\n return null;\n }\n}\n\nexport async function fetchProjectDeployments(\n projectId: string,\n): Promise<WebDeploymentInfo[]> {\n try {\n const resp = await fetch(`/api/projects/${encodeURIComponent(projectId)}/deployments`);\n if (!resp.ok) return [];\n const json = (await resp.json()) as ProjectDeploymentsResponse;\n return (json.deployments ?? []) as WebDeploymentInfo[];\n } catch {\n return [];\n }\n}\n\nexport async function deployProjectFile(\n projectId: string,\n fileName: string,\n providerId: WebDeployProviderId = DEFAULT_DEPLOY_PROVIDER_ID,\n cloudflarePages?: WebCloudflarePagesDeploySelection,\n): Promise<WebDeployProjectFileResponse> {\n const body = {\n fileName,\n providerId,\n ...(cloudflarePages ? { cloudflarePages } : {}),\n };\n const resp = await fetch(`/api/projects/${encodeURIComponent(projectId)}/deploy`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (!resp.ok) {\n const payload = (await resp.json().catch(() => null)) as\n | { error?: { message?: string }; message?: string }\n | null;\n throw new Error(payload?.error?.message || payload?.message || `Deploy failed (${resp.status})`);\n }\n return (await resp.json()) as WebDeployProjectFileResponse;\n}\n\nexport async function checkDeploymentLink(\n projectId: string,\n deploymentId: string,\n): Promise<WebDeployProjectFileResponse> {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/deployments/${encodeURIComponent(deploymentId)}/check-link`,\n { method: 'POST' },\n );\n if (!resp.ok) {\n const payload = (await resp.json().catch(() => null)) as\n | { error?: { message?: string }; message?: string }\n | null;\n throw new Error(payload?.error?.message || payload?.message || `Link check failed (${resp.status})`);\n }\n return (await resp.json()) as WebDeployProjectFileResponse;\n}\n\n// Project files — all paths are scoped under .od/projects/<id>/ on disk.\n\nexport async function fetchProjectFiles(projectId: string): Promise<ProjectFile[]> {\n try {\n const resp = await fetch(`/api/projects/${encodeURIComponent(projectId)}/files`);\n if (!resp.ok) return [];\n const json = (await resp.json()) as { files: ProjectFile[] };\n return json.files ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function fetchLiveArtifacts(projectId: string): Promise<LiveArtifactSummary[]> {\n try {\n const resp = await fetch(`/api/live-artifacts?projectId=${encodeURIComponent(projectId)}`);\n if (!resp.ok) return [];\n const json = (await resp.json()) as {\n artifacts?: LiveArtifactSummary[];\n liveArtifacts?: LiveArtifactSummary[];\n };\n return json.liveArtifacts ?? json.artifacts ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function fetchLiveArtifact(\n projectId: string,\n artifactId: string,\n): Promise<LiveArtifact | null> {\n try {\n const resp = await fetch(liveArtifactDetailUrl(projectId, artifactId));\n if (!resp.ok) return null;\n const json = (await resp.json()) as {\n artifact?: LiveArtifact;\n liveArtifact?: LiveArtifact;\n };\n return json.liveArtifact ?? json.artifact ?? null;\n } catch {\n return null;\n }\n}\n\nexport interface LiveArtifactRefreshResult {\n artifact: LiveArtifact;\n refresh: {\n id: string;\n status: 'succeeded';\n refreshedSourceCount: number;\n };\n}\n\nexport class LiveArtifactRefreshError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly code?: string,\n ) {\n super(message);\n this.name = 'LiveArtifactRefreshError';\n }\n}\n\nexport async function refreshLiveArtifact(\n projectId: string,\n artifactId: string,\n): Promise<LiveArtifactRefreshResult> {\n let resp: Response;\n try {\n resp = await fetch(\n `/api/live-artifacts/${encodeURIComponent(artifactId)}/refresh?projectId=${encodeURIComponent(projectId)}`,\n { method: 'POST' },\n );\n } catch (error) {\n throw new LiveArtifactRefreshError(\n error instanceof Error ? error.message : 'Refresh request failed.',\n 0,\n );\n }\n\n if (!resp.ok) {\n const errorBody = await readApiErrorBody(resp);\n throw new LiveArtifactRefreshError(errorBody.message, resp.status, errorBody.code);\n }\n\n return (await resp.json()) as LiveArtifactRefreshResult;\n}\n\nexport async function fetchLiveArtifactRefreshes(\n projectId: string,\n artifactId: string,\n): Promise<LiveArtifactRefreshLogEntry[]> {\n try {\n const resp = await fetch(\n `/api/live-artifacts/${encodeURIComponent(artifactId)}/refreshes?projectId=${encodeURIComponent(projectId)}`,\n );\n if (!resp.ok) return [];\n const json = (await resp.json()) as { refreshes?: LiveArtifactRefreshLogEntry[] };\n return json.refreshes ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function updateLiveArtifact(\n projectId: string,\n artifactId: string,\n input: Pick<LiveArtifact, 'title' | 'status' | 'pinned' | 'preview'> & {\n slug?: string;\n document?: LiveArtifact['document'];\n },\n): Promise<LiveArtifact> {\n let resp: Response;\n try {\n resp = await fetch(\n `/api/live-artifacts/${encodeURIComponent(artifactId)}?projectId=${encodeURIComponent(projectId)}`,\n {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n },\n );\n } catch (error) {\n throw new LiveArtifactRefreshError(\n error instanceof Error ? error.message : 'Update request failed.',\n 0,\n );\n }\n\n if (!resp.ok) {\n const errorBody = await readApiErrorBody(resp);\n throw new LiveArtifactRefreshError(errorBody.message, resp.status, errorBody.code);\n }\n\n const json = (await resp.json()) as { artifact?: LiveArtifact; liveArtifact?: LiveArtifact };\n const artifact = json.liveArtifact ?? json.artifact;\n if (!artifact) throw new LiveArtifactRefreshError('Update response did not include a live artifact.', resp.status);\n return artifact;\n}\n\nexport async function deleteLiveArtifact(projectId: string, artifactId: string): Promise<boolean> {\n try {\n const resp = await fetch(\n `/api/live-artifacts/${encodeURIComponent(artifactId)}?projectId=${encodeURIComponent(projectId)}`,\n { method: 'DELETE' },\n );\n return resp.ok;\n } catch {\n return false;\n }\n}\n\nasync function readApiErrorBody(resp: Response): Promise<{ message: string; code?: string }> {\n try {\n const json = (await resp.json()) as { error?: { code?: string; message?: string }; message?: string };\n const message = json.error?.message ?? json.message;\n return {\n message: typeof message === 'string' && message.length > 0 ? message : `Request failed (${resp.status}).`,\n ...(typeof json.error?.code === 'string' ? { code: json.error.code } : {}),\n };\n } catch {\n return { message: `Request failed (${resp.status}).` };\n }\n}\n\nexport function liveArtifactDetailUrl(projectId: string, artifactId: string): string {\n return `/api/live-artifacts/${encodeURIComponent(artifactId)}?projectId=${encodeURIComponent(projectId)}`;\n}\n\nexport type LiveArtifactPreviewVariant = 'rendered' | 'template' | 'rendered-source';\n\nexport function liveArtifactPreviewUrl(projectId: string, artifactId: string, variant: LiveArtifactPreviewVariant = 'rendered'): string {\n const variantQuery = variant === 'rendered' ? '' : `&variant=${encodeURIComponent(variant)}`;\n return `/api/live-artifacts/${encodeURIComponent(artifactId)}/preview?projectId=${encodeURIComponent(projectId)}${variantQuery}`;\n}\n\nexport async function fetchLiveArtifactCode(\n projectId: string,\n artifactId: string,\n variant: Exclude<LiveArtifactPreviewVariant, 'rendered'>,\n): Promise<string | null> {\n try {\n const resp = await fetch(liveArtifactPreviewUrl(projectId, artifactId, variant), { cache: 'no-store' });\n if (!resp.ok) return null;\n return await resp.text();\n } catch {\n return null;\n }\n}\n\nexport function projectFileUrl(projectId: string, name: string): string {\n return projectRawUrl(projectId, name);\n}\n\nexport interface ProjectFilePreviewSection {\n title: string;\n lines: string[];\n}\n\nexport interface ProjectFilePreview {\n kind: 'pdf' | 'document' | 'presentation' | 'spreadsheet';\n title: string;\n sections: ProjectFilePreviewSection[];\n}\n\nexport async function fetchProjectFilePreview(\n projectId: string,\n name: string,\n): Promise<ProjectFilePreview | null> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/files/${encodeURIComponent(name)}/preview`,\n );\n if (!resp.ok) return null;\n return (await resp.json()) as ProjectFilePreview;\n } catch {\n return null;\n }\n}\n\nexport async function fetchProjectFileText(\n projectId: string,\n name: string,\n options?: { cache?: RequestCache; cacheBustKey?: string | number },\n): Promise<string | null> {\n const url = projectFileUrl(projectId, name);\n const cacheBustKey = options?.cacheBustKey;\n const requestUrl =\n cacheBustKey == null\n ? url\n : `${url}${url.includes('?') ? '&' : '?'}cacheBust=${encodeURIComponent(String(cacheBustKey))}`;\n const init: RequestInit = {};\n if (options?.cache) init.cache = options.cache;\n\n try {\n const resp = await fetch(requestUrl, init);\n if (!resp.ok) {\n console.warn('[fetchProjectFileText] failed:', {\n name,\n projectId,\n status: resp.status,\n statusText: resp.statusText,\n url: requestUrl,\n });\n return null;\n }\n return await resp.text();\n } catch (err) {\n console.warn('[fetchProjectFileText] failed:', {\n error: err,\n name,\n projectId,\n url: requestUrl,\n });\n return null;\n }\n}\n\nexport async function fetchPreviewComments(\n projectId: string,\n conversationId: string,\n): Promise<PreviewComment[]> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations/${encodeURIComponent(conversationId)}/comments`,\n );\n if (!resp.ok) return [];\n const json = (await resp.json()) as { comments: PreviewComment[] };\n return json.comments ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function upsertPreviewComment(\n projectId: string,\n conversationId: string,\n input: PreviewCommentUpsertRequest,\n): Promise<PreviewComment | null> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations/${encodeURIComponent(conversationId)}/comments`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n },\n );\n if (!resp.ok) return null;\n const json = (await resp.json()) as { comment: PreviewComment };\n return json.comment ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function patchPreviewCommentStatus(\n projectId: string,\n conversationId: string,\n commentId: string,\n status: PreviewCommentStatus,\n): Promise<PreviewComment | null> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations/${encodeURIComponent(conversationId)}/comments/${encodeURIComponent(commentId)}`,\n {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ status }),\n },\n );\n if (!resp.ok) return null;\n const json = (await resp.json()) as { comment: PreviewComment };\n return json.comment ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function deletePreviewComment(\n projectId: string,\n conversationId: string,\n commentId: string,\n): Promise<boolean> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations/${encodeURIComponent(conversationId)}/comments/${encodeURIComponent(commentId)}`,\n { method: 'DELETE' },\n );\n return resp.ok;\n } catch {\n return false;\n }\n}\n\nexport async function writeProjectTextFile(\n projectId: string,\n name: string,\n content: string,\n options?: { artifactManifest?: ArtifactManifest },\n): Promise<ProjectFile | null> {\n const result = await writeProjectTextFileDetailed(projectId, name, content, options);\n return result.ok ? result.file : null;\n}\n\nexport type WriteProjectTextFileResult =\n | { ok: true; file: ProjectFile }\n | { ok: false; status?: number; code?: string; message: string };\n\nexport async function writeProjectTextFileDetailed(\n projectId: string,\n name: string,\n content: string,\n options?: { artifactManifest?: ArtifactManifest },\n): Promise<WriteProjectTextFileResult> {\n try {\n const resp = await fetch(`/api/projects/${encodeURIComponent(projectId)}/files`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name, content, artifactManifest: options?.artifactManifest }),\n });\n if (!resp.ok) {\n const body = await readApiErrorBody(resp);\n return {\n ok: false,\n status: resp.status,\n code: body.code,\n message: body.message || resp.statusText || 'Save failed',\n };\n }\n const json = (await resp.json()) as { file: ProjectFile };\n return { ok: true, file: json.file };\n } catch {\n return { ok: false, message: 'Network error while saving the file' };\n }\n}\n\nexport async function writeProjectBase64File(\n projectId: string,\n name: string,\n base64: string,\n): Promise<ProjectFile | null> {\n try {\n const resp = await fetch(`/api/projects/${encodeURIComponent(projectId)}/files`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name, content: base64, encoding: 'base64' }),\n });\n if (!resp.ok) return null;\n const json = (await resp.json()) as { file: ProjectFile };\n return json.file;\n } catch {\n return null;\n }\n}\n\nexport async function uploadProjectFile(\n projectId: string,\n file: File,\n desiredName?: string,\n): Promise<ProjectFile | null> {\n try {\n const form = new FormData();\n form.append('file', file);\n if (desiredName) form.append('name', desiredName);\n const resp = await fetch(`/api/projects/${encodeURIComponent(projectId)}/files`, {\n method: 'POST',\n body: form,\n });\n if (!resp.ok) return null;\n const json = (await resp.json()) as { file: ProjectFile };\n return json.file;\n } catch {\n return null;\n }\n}\n\n// Multi-file project upload used by the chat composer's paste / drop /\n// picker. Each file lands flat in the project folder; the response is\n// reshaped into ChatAttachments so the composer can stage them without a\n// follow-up listFiles round-trip.\nconst PROJECT_UPLOAD_BATCH_SIZE = 12;\n\nexport interface ProjectUploadFailure {\n name: string;\n code?: string;\n error?: string;\n}\n\nexport interface UploadProjectFilesResult {\n uploaded: ChatAttachment[];\n failed: ProjectUploadFailure[];\n error?: string;\n}\n\nexport async function uploadProjectFiles(\n projectId: string,\n files: File[],\n): Promise<UploadProjectFilesResult> {\n if (files.length === 0) return { uploaded: [], failed: [] };\n\n const uploaded: ChatAttachment[] = [];\n const failed: ProjectUploadFailure[] = [];\n let error: string | undefined;\n\n for (let i = 0; i < files.length; i += PROJECT_UPLOAD_BATCH_SIZE) {\n const batch = files.slice(i, i + PROJECT_UPLOAD_BATCH_SIZE);\n const remaining = files.slice(i + PROJECT_UPLOAD_BATCH_SIZE);\n const form = new FormData();\n for (const f of batch) form.append('files', f);\n\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/upload`,\n { method: 'POST', body: form },\n );\n\n if (!resp.ok) {\n const payload = (await resp.json().catch(() => null)) as\n | { code?: string; error?: string }\n | null;\n error = payload?.error ?? `upload failed (${resp.status})`;\n for (const f of batch) {\n failed.push({ name: f.name, code: payload?.code, error: error });\n }\n for (const f of remaining) {\n failed.push({ name: f.name, code: payload?.code, error: error });\n }\n break;\n }\n\n const json = (await resp.json()) as {\n files: { name: string; path: string; size?: number; originalName?: string }[];\n };\n const responseFiles = json.files ?? [];\n uploaded.push(\n ...responseFiles.map((f) => ({\n path: f.path,\n name: f.originalName ?? f.name,\n kind: looksLikeImage(f.name) ? ('image' as const) : ('file' as const),\n size: f.size,\n })),\n );\n // Server preserves request order; any dropped files are unmatched at the batch tail.\n if (responseFiles.length < batch.length) {\n error ??= 'some files could not be stored';\n for (const f of batch.slice(responseFiles.length)) {\n failed.push({\n name: f.name,\n error: error ?? 'some files could not be stored',\n });\n }\n }\n } catch {\n error = 'upload request failed';\n for (const f of batch) {\n failed.push({ name: f.name, error });\n }\n for (const f of remaining) {\n failed.push({ name: f.name, error });\n }\n break;\n }\n }\n\n return { uploaded, failed, error };\n}\n\n// Stable URL that serves a project file with its original mime — for\n// thumbnails in the staged-attachment chips and for any preview iframe\n// that needs to point at the live file (not a srcDoc).\nexport function projectRawUrl(projectId: string, filePath: string): string {\n // Encode each path segment individually so a slash inside the file\n // path stays a path separator, not %2F.\n const safePath = filePath\n .split('/')\n .map((seg) => encodeURIComponent(seg))\n .join('/');\n return `/api/projects/${encodeURIComponent(projectId)}/raw/${safePath}`;\n}\n\nfunction looksLikeImage(name: string): boolean {\n return /\\.(png|jpe?g|gif|webp|svg|avif|bmp)$/i.test(name);\n}\n\nexport async function deleteProjectFile(\n projectId: string,\n name: string,\n): Promise<boolean> {\n try {\n const resp = await fetch(\n projectRawUrl(projectId, name),\n { method: 'DELETE' },\n );\n return resp.ok;\n } catch {\n return false;\n }\n}\n\nexport async function renameProjectFile(\n projectId: string,\n from: string,\n to: string,\n): Promise<RenameProjectFileResponse> {\n const resp = await fetch(`/api/projects/${encodeURIComponent(projectId)}/files/rename`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ from, to }),\n });\n if (!resp.ok) {\n const errorBody = await readApiErrorBody(resp);\n throw new Error(errorBody.message);\n }\n return (await resp.json()) as RenameProjectFileResponse;\n}\n\nexport async function openFolderDialog(): Promise<string | null> {\n try {\n const resp = await fetch('/api/dialog/open-folder', { method: 'POST' });\n if (!resp.ok) return null;\n const data = await resp.json();\n return typeof data.path === 'string' && data.path.length > 0 ? data.path : null;\n } catch {\n return null;\n }\n}\n\n// \"Replace working directory\" — points an existing project at a new\n// folder. Mirrors the import-folder trust gate but updates the current\n// project record instead of creating a new project.\nexport async function replaceProjectWorkingDir(\n projectId: string,\n baseDir: string,\n desktopImportToken?: string,\n): Promise<ReplaceProjectWorkingDirResponse> {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (desktopImportToken) {\n headers['x-od-desktop-import-token'] = desktopImportToken;\n }\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/working-dir`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify({ baseDir }),\n },\n );\n if (!resp.ok) {\n const body = await readApiErrorBody(resp);\n throw new Error(body.message);\n }\n return (await resp.json()) as ReplaceProjectWorkingDirResponse;\n}\n\n// Hand-off (open project in local app). The daemon enumerates installed\n// editors on demand (PATH probe + macOS bundle scan), and the POST\n// endpoint spawns the chosen app with the project's resolvedDir.\nexport async function fetchHostEditors(): Promise<\n import('@open-design/contracts').HostEditorsResponse\n> {\n const resp = await fetch('/api/editors');\n if (!resp.ok) throw new Error(`GET /api/editors failed: ${resp.status}`);\n return (await resp.json()) as import('@open-design/contracts').HostEditorsResponse;\n}\n\nexport async function openProjectInEditor(\n projectId: string,\n editorId: import('@open-design/contracts').HostEditorId,\n): Promise<import('@open-design/contracts').OpenProjectInEditorResponse> {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/open-in`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ editorId }),\n },\n );\n if (!resp.ok) {\n const body = await readApiErrorBody(resp);\n throw new Error(body.message);\n }\n return (await resp.json()) as import('@open-design/contracts').OpenProjectInEditorResponse;\n}\n\nexport async function fetchDesignSystemPreview(id: string): Promise<string | null> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}/preview`);\n if (!resp.ok) return null;\n return await resp.text();\n } catch {\n return null;\n }\n}\n\nexport async function fetchDesignSystemShowcase(id: string): Promise<string | null> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}/showcase`);\n if (!resp.ok) return null;\n return await resp.text();\n } catch {\n return null;\n }\n}\n\n// Fetch the sandboxed HTML preview the daemon serves for a plugin.\n// Mirrors fetchSkillExample's discriminated result so the modal can\n// surface a Retry button instead of staying stuck at \"Loading…\" when\n// a plugin ships no preview entry or the asset is missing on disk.\n//\n// 404 is mapped to `unavailable` (mirroring the skill helper's #897\n// behavior) because the daemon returns 404 when the manifest's\n// `preview.entry` points at a file that doesn't ship — a missing\n// asset for an otherwise valid plugin is not an error the user can\n// retry their way out of. Surfacing the calm \"no shipped preview\"\n// placeholder is the truthful UX.\nexport async function fetchPluginPreviewHtml(\n id: string,\n): Promise<SkillExampleResult> {\n try {\n const resp = await fetch(\n `/api/plugins/${encodeURIComponent(id)}/preview`,\n );\n if (!resp.ok) {\n if (resp.status === 404) return { unavailable: true, kind: 'html' };\n return { error: `HTTP ${resp.status}` };\n }\n return { html: await resp.text() };\n } catch (err) {\n const message = err instanceof Error ? err.message : 'network error';\n return { error: message };\n }\n}\n\n// Fetch a single example output by stem (matches the basename of the\n// `od.useCase.exampleOutputs[].path` minus its extension). 404 is\n// mapped to `unavailable` for the same reason as fetchPluginPreviewHtml.\nexport async function fetchPluginExampleHtml(\n pluginId: string,\n stem: string,\n): Promise<SkillExampleResult> {\n try {\n const resp = await fetch(\n `/api/plugins/${encodeURIComponent(pluginId)}/example/${encodeURIComponent(stem)}`,\n );\n if (!resp.ok) {\n if (resp.status === 404) return { unavailable: true, kind: 'html' };\n return { error: `HTTP ${resp.status}` };\n }\n return { html: await resp.text() };\n } catch (err) {\n const message = err instanceof Error ? err.message : 'network error';\n return { error: message };\n }\n}\n\n// Fetch a raw text asset shipped inside a plugin (DESIGN.md,\n// SKILL.md, README.md, etc.). Returns null on any error so the\n// caller can fall back to a placeholder; callers that need a\n// distinguishable failure should switch to the discriminated\n// SkillExampleResult shape used by the HTML helpers above.\nexport async function fetchPluginAssetText(\n pluginId: string,\n relpath: string,\n): Promise<string | null> {\n try {\n const resp = await fetch(\n `/api/plugins/${encodeURIComponent(pluginId)}/asset/${encodePluginAssetPath(relpath)}`,\n );\n if (!resp.ok) return null;\n return await resp.text();\n } catch {\n return null;\n }\n}\n\nfunction encodePluginAssetPath(relpath: string): string {\n return relpath\n .replace(/^\\.\\//, '')\n .split(/[\\\\/]/)\n .filter(Boolean)\n .map((seg) => encodeURIComponent(seg))\n .join('/');\n}\n\nexport async function installSkill(\n input: InstallInput,\n): Promise<{ skill: SkillSummary } | { error: string }> {\n try {\n const resp = await fetch('/api/skills/install', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n const json = await resp.json();\n if (!resp.ok) return { error: json.error ?? 'Install failed' };\n return json as InstallSkillResponse;\n } catch {\n return { error: 'Network error' };\n }\n}\n\nexport async function uninstallSkill(\n id: string,\n): Promise<{ ok: true } | { error: string }> {\n try {\n const resp = await fetch(`/api/skills/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n const json = await resp.json();\n if (!resp.ok) return { error: json.error ?? 'Uninstall failed' };\n return { ok: true };\n } catch {\n return { error: 'Network error' };\n }\n}\n\nexport async function installDesignSystem(\n input: InstallInput,\n): Promise<{ designSystem: DesignSystemSummary } | { error: string }> {\n try {\n const resp = await fetch('/api/design-systems/install', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n const json = await resp.json();\n if (!resp.ok) return { error: json.error ?? 'Install failed' };\n return json as InstallDesignSystemResponse;\n } catch {\n return { error: 'Network error' };\n }\n}\n\nexport async function uninstallDesignSystem(\n id: string,\n): Promise<{ ok: true } | { error: string }> {\n try {\n const resp = await fetch(`/api/design-systems/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n const json = await resp.json();\n if (!resp.ok) return { error: json.error ?? 'Uninstall failed' };\n return { ok: true };\n } catch {\n return { error: 'Network error' };\n }\n}\n","// Project / conversation / message / tab persistence — backed by the\n// daemon's SQLite store. All writes round-trip through HTTP so projects\n// stay coherent across multiple browser tabs and across restarts.\n//\n// These helpers fail soft (returning null / [] on transport errors) so\n// the UI can stay rendered when the daemon is briefly unreachable.\n\nimport type {\n AppliedPluginSnapshot,\n ApplyResult,\n CreatePluginShareProjectResponse,\n ImportFolderRequest,\n ImportFolderResponse,\n InstalledPluginRecord,\n PluginInstallOutcome,\n PluginShareAction,\n ProjectPluginFolderInstallRequest,\n} from '@open-design/contracts';\nimport { randomUUID } from '../utils/uuid';\nimport type {\n ChatMessage,\n Conversation,\n OpenTabsState,\n Project,\n ProjectMetadata,\n ProjectTemplate,\n} from '../types';\n\nexport type { PluginInstallOutcome } from '@open-design/contracts';\nexport type { PluginShareAction } from '@open-design/contracts';\n\nexport async function listProjects(): Promise<Project[]> {\n try {\n const resp = await fetch('/api/projects');\n if (!resp.ok) return [];\n const json = (await resp.json()) as { projects: Project[] };\n return json.projects ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function getProject(id: string): Promise<Project | null> {\n try {\n const resp = await fetch(`/api/projects/${encodeURIComponent(id)}`);\n if (!resp.ok) return null;\n const json = (await resp.json()) as { project: Project };\n return json.project;\n } catch {\n return null;\n }\n}\n\nexport async function createProject(input: {\n name: string;\n projectLocationId?: string;\n skillId: string | null;\n designSystemId: string | null;\n pendingPrompt?: string;\n metadata?: ProjectMetadata;\n // Plan §3.A1 / spec §11.5 — POST /api/projects accepts a pluginId\n // (or pre-applied snapshot id) to resolve and pin a plugin to the new\n // project. Used by the PluginLoopHome flow on Home.\n pluginId?: string;\n appliedPluginSnapshotId?: string;\n pluginInputs?: Record<string, unknown>;\n}): Promise<{ project: Project; conversationId: string; appliedPluginSnapshotId?: string } | null> {\n try {\n // `randomUUID` falls back to `crypto.getRandomValues` / `Math.random`\n // when `crypto.randomUUID` is unavailable. Open Design served over\n // plain HTTP on a LAN IP (Docker / unRAID self-hosting) is a\n // non-secure context, where `crypto.randomUUID` is undefined and\n // calling it directly throws — the surrounding try/catch then turns\n // the Create button into a silent no-op (issue #849).\n const id = randomUUID();\n const resp = await fetch('/api/projects', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id, ...input }),\n });\n if (!resp.ok) return null;\n return (await resp.json()) as {\n project: Project;\n conversationId: string;\n appliedPluginSnapshotId?: string;\n };\n } catch {\n return null;\n }\n}\n\nexport async function importFolderProject(\n input: ImportFolderRequest,\n): Promise<ImportFolderResponse> {\n const resp = await fetch('/api/import/folder', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) {\n let message = 'Failed to import folder';\n try {\n const body = await resp.json();\n if (body?.error?.message) message = body.error.message;\n } catch { /* use default message */ }\n throw new Error(message);\n }\n return (await resp.json()) as ImportFolderResponse;\n}\n\nexport async function importClaudeDesignZip(\n file: File,\n): Promise<{ project: Project; conversationId: string; entryFile: string }> {\n const form = new FormData();\n form.append('file', file);\n const resp = await fetch('/api/import/claude-design', {\n method: 'POST',\n body: form,\n });\n if (!resp.ok) {\n const payload = await resp.json().catch(() => null);\n const message =\n payload != null &&\n typeof payload === 'object' &&\n typeof (payload as { error?: unknown }).error === 'string'\n ? (payload as { error: string }).error\n : `Import failed (${resp.status})`;\n throw new Error(message);\n }\n return (await resp.json()) as {\n project: Project;\n conversationId: string;\n entryFile: string;\n };\n}\n\n// ---------- templates ----------\n\nexport async function listTemplates(): Promise<ProjectTemplate[]> {\n try {\n const resp = await fetch('/api/templates');\n if (!resp.ok) return [];\n const json = (await resp.json()) as { templates: ProjectTemplate[] };\n return json.templates ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function getTemplate(id: string): Promise<ProjectTemplate | null> {\n try {\n const resp = await fetch(`/api/templates/${encodeURIComponent(id)}`);\n if (!resp.ok) return null;\n const json = (await resp.json()) as { template: ProjectTemplate };\n return json.template;\n } catch {\n return null;\n }\n}\n\nexport async function saveTemplate(input: {\n name: string;\n description?: string;\n sourceProjectId: string;\n}): Promise<ProjectTemplate | null> {\n try {\n const resp = await fetch('/api/templates', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n if (!resp.ok) return null;\n const json = (await resp.json()) as { template: ProjectTemplate };\n return json.template;\n } catch {\n return null;\n }\n}\n\nexport async function deleteTemplate(id: string): Promise<boolean> {\n try {\n const resp = await fetch(`/api/templates/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n return resp.ok;\n } catch {\n return false;\n }\n}\n\ntype ProjectPatch = Omit<Partial<Project>, 'pendingPrompt' | 'customInstructions'> & {\n pendingPrompt?: Project['pendingPrompt'] | null;\n customInstructions?: string | null;\n};\n\nexport async function patchProject(\n id: string,\n patch: ProjectPatch,\n): Promise<Project | null> {\n try {\n const resp = await fetch(`/api/projects/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(patch),\n });\n if (!resp.ok) return null;\n const json = (await resp.json()) as { project: Project };\n return json.project;\n } catch {\n return null;\n }\n}\n\nexport async function deleteProject(id: string): Promise<boolean> {\n try {\n const resp = await fetch(`/api/projects/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n return resp.ok;\n } catch {\n return false;\n }\n}\n\n// ---------- conversations ----------\n\nexport async function listConversations(\n projectId: string,\n): Promise<Conversation[]> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations`,\n );\n if (!resp.ok) return [];\n const json = (await resp.json()) as { conversations: Conversation[] };\n return json.conversations ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function createConversation(\n projectId: string,\n title?: string,\n): Promise<Conversation | null> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ title }),\n },\n );\n if (!resp.ok) return null;\n const json = (await resp.json()) as { conversation: Conversation };\n return json.conversation;\n } catch {\n return null;\n }\n}\n\nexport async function patchConversation(\n projectId: string,\n conversationId: string,\n patch: Partial<Conversation>,\n): Promise<Conversation | null> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations/${encodeURIComponent(conversationId)}`,\n {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(patch),\n },\n );\n if (!resp.ok) return null;\n const json = (await resp.json()) as { conversation: Conversation };\n return json.conversation;\n } catch {\n return null;\n }\n}\n\nexport async function deleteConversation(\n projectId: string,\n conversationId: string,\n): Promise<boolean> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations/${encodeURIComponent(conversationId)}`,\n { method: 'DELETE' },\n );\n return resp.ok;\n } catch {\n return false;\n }\n}\n\n// ---------- messages ----------\n\nexport async function listMessages(\n projectId: string,\n conversationId: string,\n): Promise<ChatMessage[]> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations/${encodeURIComponent(conversationId)}/messages`,\n );\n if (!resp.ok) return [];\n const json = (await resp.json()) as { messages: ChatMessage[] };\n return json.messages ?? [];\n } catch {\n return [];\n }\n}\n\nexport interface SaveMessageOptions {\n telemetryFinalized?: boolean;\n // Set during page-unload paths (pagehide / visibilitychange→hidden) so\n // the in-flight PUT survives even if the document tears down before the\n // response arrives. Without keepalive the browser cancels the fetch\n // and the daemon never sees the final buffered text chunk.\n keepalive?: boolean;\n}\n\nexport async function saveMessage(\n projectId: string,\n conversationId: string,\n message: ChatMessage,\n options: SaveMessageOptions = {},\n): Promise<void> {\n try {\n const body = options.telemetryFinalized\n ? { ...message, telemetryFinalized: true }\n : message;\n await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/conversations/${encodeURIComponent(conversationId)}/messages/${encodeURIComponent(message.id)}`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n ...(options.keepalive ? { keepalive: true } : {}),\n },\n );\n } catch {\n // best-effort persistence — UI keeps the message in-memory either way\n }\n}\n\n// ---------- tabs ----------\n\nexport async function loadTabs(projectId: string): Promise<OpenTabsState> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/tabs`,\n );\n if (!resp.ok) return { tabs: [], active: null };\n return (await resp.json()) as OpenTabsState;\n } catch {\n return { tabs: [], active: null };\n }\n}\n\nexport async function saveTabs(\n projectId: string,\n state: OpenTabsState,\n): Promise<void> {\n try {\n await fetch(`/api/projects/${encodeURIComponent(projectId)}/tabs`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(state),\n });\n } catch {\n // best-effort\n }\n}\n\n// ---------- plugins ----------\n// Plan §3.C1 — plugin discovery + apply.\n//\n// applyPlugin() is the canonical entry point for both the inline rail\n// (NewProjectPanel + ChatComposer) and the marketplace detail page. It\n// hits POST /api/plugins/:id/apply, which is the same pure resolver\n// the daemon uses; the response carries everything the composer needs:\n// - query (pre-filled brief)\n// - contextItems (chip strip)\n// - inputs (form fields)\n// - appliedPlugin (snapshot id; sent back on POST /api/runs to pin\n// the prompt block to the frozen view)\n\nexport interface ListPluginsOptions {\n includeHidden?: boolean;\n}\n\nexport async function listPlugins(\n options: ListPluginsOptions = {},\n): Promise<InstalledPluginRecord[]> {\n try {\n const resp = await fetch('/api/plugins');\n if (!resp.ok) return [];\n const json = (await resp.json()) as { plugins?: InstalledPluginRecord[] };\n const plugins = json.plugins ?? [];\n return options.includeHidden ? plugins : plugins.filter(isVisiblePlugin);\n } catch {\n return [];\n }\n}\n\nexport function isVisiblePlugin(plugin: InstalledPluginRecord): boolean {\n const od = (plugin.manifest?.od ?? {}) as Record<string, unknown>;\n return od.hidden !== true;\n}\n\ninterface PluginInstallEvent {\n kind?: 'progress' | 'success' | 'error';\n phase?: string;\n message?: string;\n plugin?: InstalledPluginRecord;\n warnings?: string[];\n}\n\nexport async function installPluginSource(source: string): Promise<PluginInstallOutcome> {\n const log: string[] = [];\n try {\n const resp = await fetch('/api/plugins/install', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ source }),\n });\n if (!resp.ok) {\n const message = await readErrorMessage(resp);\n return { ok: false, warnings: [], message, log };\n }\n if (!resp.body) {\n return {\n ok: false,\n warnings: [],\n message: 'Install stream did not start.',\n log,\n };\n }\n\n let success: InstalledPluginRecord | undefined;\n let warnings: string[] = [];\n let errorMessage: string | undefined;\n for await (const ev of readServerSentEvents(resp.body)) {\n if (ev.message) log.push(ev.message);\n if (ev.warnings) warnings = ev.warnings;\n if (ev.kind === 'success') success = ev.plugin;\n if (ev.kind === 'error') errorMessage = ev.message ?? 'Install failed.';\n }\n return {\n ok: Boolean(success) && !errorMessage,\n plugin: success,\n warnings,\n message: errorMessage ?? (success ? `Installed ${success.title}.` : 'Install finished.'),\n log,\n };\n } catch (err) {\n return {\n ok: false,\n warnings: [],\n message: (err as Error).message,\n log,\n };\n }\n}\n\nexport async function uploadPluginZip(file: File): Promise<PluginInstallOutcome> {\n const form = new FormData();\n form.append('file', file);\n return postPluginUpload('/api/plugins/upload-zip', form);\n}\n\nexport async function uploadPluginFolder(files: File[]): Promise<PluginInstallOutcome> {\n const form = new FormData();\n for (const file of files) {\n const relativePath = getUploadRelativePath(file);\n form.append('files', file, file.name);\n form.append('paths', relativePath);\n }\n return postPluginUpload('/api/plugins/upload-folder', form);\n}\n\nexport async function installGeneratedPluginFolder(\n projectId: string,\n relativePath: string,\n): Promise<PluginInstallOutcome> {\n try {\n const request: ProjectPluginFolderInstallRequest = { path: relativePath };\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/plugins/install-folder`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n },\n );\n const outcome = await readPluginInstallOutcome(resp);\n if (outcome.ok && typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('open-design:plugins-changed'));\n }\n return outcome;\n } catch (err) {\n return {\n ok: false,\n warnings: [],\n message: (err as Error).message,\n log: [],\n };\n }\n}\n\nexport interface PluginShareOutcome {\n ok: boolean;\n message: string;\n url?: string;\n log?: string[];\n code?: string;\n}\n\nexport interface PluginShareTaskStart {\n taskId: string;\n action: 'publish-github' | 'contribute-open-design';\n path: string;\n status: 'queued' | 'running' | 'done' | 'failed';\n startedAt: number;\n}\n\nexport interface PluginShareTaskResult {\n message: string;\n url?: string;\n log?: string[];\n}\n\nexport interface PluginShareTaskError {\n message: string;\n code?: string;\n log?: string[];\n}\n\nexport interface PluginShareTaskSnapshot {\n taskId: string;\n action: 'publish-github' | 'contribute-open-design';\n path: string;\n status: 'queued' | 'running' | 'done' | 'failed';\n startedAt: number;\n endedAt?: number | null;\n progress: string[];\n nextSince: number;\n result?: PluginShareTaskResult;\n error?: PluginShareTaskError;\n}\n\nexport async function publishGeneratedPluginToGitHub(\n projectId: string,\n relativePath: string,\n): Promise<PluginShareOutcome> {\n return postGeneratedPluginShareAction(projectId, relativePath, 'publish-github');\n}\n\nexport async function contributeGeneratedPluginToOpenDesign(\n projectId: string,\n relativePath: string,\n): Promise<PluginShareOutcome> {\n return postGeneratedPluginShareAction(projectId, relativePath, 'contribute-open-design');\n}\n\nexport async function startGeneratedPluginShareTask(\n projectId: string,\n relativePath: string,\n action: 'publish-github' | 'contribute-open-design',\n): Promise<PluginShareTaskStart> {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/plugins/share-tasks`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: relativePath, action }),\n },\n );\n const body = await resp.json().catch(() => null) as Partial<PluginShareTaskStart> & {\n error?: string | { message?: string };\n message?: string;\n } | null;\n if (!resp.ok || !body?.taskId || !body?.action || !body?.path || !body?.status || !body?.startedAt) {\n const errorMessage =\n body?.message\n ?? (typeof body?.error === 'string' ? body.error : body?.error?.message)\n ?? 'Could not start plugin share task.';\n throw new Error(errorMessage);\n }\n return {\n taskId: body.taskId,\n action: body.action,\n path: body.path,\n status: body.status,\n startedAt: body.startedAt,\n };\n}\n\nexport async function waitGeneratedPluginShareTask(\n taskId: string,\n since: number,\n timeoutMs = 25_000,\n): Promise<PluginShareTaskSnapshot> {\n const resp = await fetch(`/api/plugins/share-tasks/${encodeURIComponent(taskId)}/wait`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ since, timeoutMs }),\n });\n const body = await resp.json().catch(() => null) as PluginShareTaskSnapshot & {\n error?: string | { message?: string };\n message?: string;\n } | null;\n if (!resp.ok || !body?.taskId) {\n const errorMessage =\n body?.message\n ?? (typeof body?.error === 'string' ? body.error : body?.error?.message)\n ?? 'Could not fetch plugin share task.';\n throw new Error(errorMessage);\n }\n return body;\n}\n\nexport type PluginShareProjectOutcome =\n | (CreatePluginShareProjectResponse & { ok: true })\n | {\n ok: false;\n message: string;\n code?: string;\n };\n\nexport async function createPluginShareProject(\n pluginId: string,\n action: PluginShareAction,\n locale?: string,\n): Promise<PluginShareProjectOutcome> {\n try {\n const resp = await fetch(\n `/api/plugins/${encodeURIComponent(pluginId)}/share-project`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n action,\n ...(locale ? { locale } : {}),\n }),\n },\n );\n const body = (await resp.json().catch(() => null)) as\n | (Partial<CreatePluginShareProjectResponse> & {\n error?: string | { code?: string; message?: string };\n code?: string;\n })\n | null;\n if (resp.ok && body?.ok && body.project && body.conversationId) {\n return body as CreatePluginShareProjectResponse & { ok: true };\n }\n const errorMessage =\n typeof body?.error === 'string' ? body.error : body?.error?.message;\n const fallbackMessage = resp.statusText || 'Could not create plugin share project.';\n const message = body?.message ?? errorMessage ?? fallbackMessage;\n const code =\n body?.code ?? (typeof body?.error === 'object' ? body.error.code : undefined);\n return {\n ok: false,\n message,\n ...(code ? { code } : {}),\n };\n } catch (err) {\n return {\n ok: false,\n message: (err as Error).message,\n };\n }\n}\n\nasync function postGeneratedPluginShareAction(\n projectId: string,\n relativePath: string,\n action: 'publish-github' | 'contribute-open-design',\n): Promise<PluginShareOutcome> {\n try {\n const resp = await fetch(\n `/api/projects/${encodeURIComponent(projectId)}/plugins/${action}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: relativePath }),\n },\n );\n const body = (await resp.json().catch(() => null)) as Partial<PluginShareOutcome> | null;\n return {\n ok: Boolean(resp.ok && body?.ok),\n message: body?.message ?? (resp.ok ? 'Action finished.' : 'Plugin share action failed.'),\n ...(body?.url ? { url: body.url } : {}),\n ...(body?.log ? { log: body.log } : {}),\n ...(body?.code ? { code: body.code } : {}),\n };\n } catch (err) {\n return {\n ok: false,\n message: (err as Error).message,\n log: [],\n };\n }\n}\n\nexport async function upgradePlugin(id: string): Promise<PluginInstallOutcome> {\n const log: string[] = [];\n try {\n const resp = await fetch(`/api/plugins/${encodeURIComponent(id)}/upgrade`, {\n method: 'POST',\n });\n if (!resp.ok) {\n const message = await readErrorMessage(resp);\n return { ok: false, warnings: [], message, log };\n }\n if (!resp.body) {\n return {\n ok: false,\n warnings: [],\n message: 'Upgrade stream did not start.',\n log,\n };\n }\n let success: InstalledPluginRecord | undefined;\n let warnings: string[] = [];\n let errorMessage: string | undefined;\n for await (const ev of readServerSentEvents(resp.body)) {\n if (ev.message) log.push(ev.message);\n if (ev.warnings) warnings = ev.warnings;\n if (ev.kind === 'success') success = ev.plugin;\n if (ev.kind === 'error') errorMessage = ev.message ?? 'Upgrade failed.';\n }\n return {\n ok: Boolean(success) && !errorMessage,\n plugin: success,\n warnings,\n message: errorMessage ?? (success ? `Upgraded ${success.title}.` : 'Upgrade finished.'),\n log,\n };\n } catch (err) {\n return {\n ok: false,\n warnings: [],\n message: (err as Error).message,\n log,\n };\n }\n}\n\nasync function postPluginUpload(url: string, form: FormData): Promise<PluginInstallOutcome> {\n try {\n const resp = await fetch(url, {\n method: 'POST',\n body: form,\n });\n const json = (await resp.json()) as Partial<PluginInstallOutcome> & {\n error?: string | { message?: string };\n };\n if (resp.ok && json.ok) {\n return {\n ok: true,\n plugin: json.plugin,\n warnings: json.warnings ?? [],\n message: json.message ?? 'Plugin installed.',\n log: json.log ?? [],\n };\n }\n const message =\n json.message ??\n (typeof json.error === 'string' ? json.error : json.error?.message) ??\n resp.statusText;\n return {\n ok: false,\n warnings: json.warnings ?? [],\n message,\n log: json.log ?? [],\n };\n } catch (err) {\n return {\n ok: false,\n warnings: [],\n message: (err as Error).message,\n log: [],\n };\n }\n}\n\nasync function readPluginInstallOutcome(resp: Response): Promise<PluginInstallOutcome> {\n const json = (await resp.json()) as Partial<PluginInstallOutcome> & {\n error?: string | { message?: string };\n };\n if (resp.ok && json.ok) {\n return {\n ok: true,\n ...(json.plugin ? { plugin: json.plugin } : {}),\n warnings: json.warnings ?? [],\n message: json.message ?? 'Plugin installed.',\n log: json.log ?? [],\n };\n }\n const message =\n json.message ??\n (typeof json.error === 'string' ? json.error : json.error?.message) ??\n resp.statusText;\n return {\n ok: false,\n ...(json.plugin ? { plugin: json.plugin } : {}),\n warnings: json.warnings ?? [],\n message,\n log: json.log ?? [],\n };\n}\n\nfunction getUploadRelativePath(file: File): string {\n const withRelativePath = file as File & { webkitRelativePath?: string };\n return withRelativePath.webkitRelativePath || file.name;\n}\n\nexport async function uninstallPlugin(id: string): Promise<boolean> {\n try {\n const resp = await fetch(`/api/plugins/${encodeURIComponent(id)}/uninstall`, {\n method: 'POST',\n });\n return resp.ok;\n } catch {\n return false;\n }\n}\n\nexport interface PluginMarketplace {\n id: string;\n url: string;\n trust: PluginMarketplaceTrust;\n specVersion?: string;\n version?: string;\n addedAt?: number;\n refreshedAt?: number;\n manifest: {\n name?: string;\n version?: string;\n plugins?: PluginMarketplaceEntry[];\n };\n}\n\nexport type PluginMarketplaceTrust = 'official' | 'trusted' | 'restricted';\n\nexport interface PluginMarketplaceEntry {\n name: string;\n source: string;\n version?: string;\n ref?: string;\n dist?: {\n type?: string;\n archive?: string;\n integrity?: string;\n manifestDigest?: string;\n };\n versions?: Array<{\n version: string;\n source?: string;\n ref?: string;\n dist?: {\n type?: string;\n archive?: string;\n integrity?: string;\n manifestDigest?: string;\n };\n integrity?: string;\n manifestDigest?: string;\n deprecated?: boolean | string;\n yanked?: boolean;\n yankedAt?: string;\n yankReason?: string;\n }>;\n distTags?: Record<string, string>;\n integrity?: string;\n manifestDigest?: string;\n publisher?: {\n id?: string;\n github?: string;\n url?: string;\n };\n homepage?: string;\n license?: string;\n permissions?: string[];\n capabilitiesSummary?: string[];\n deprecated?: boolean | string;\n yanked?: boolean;\n yankedAt?: string;\n yankReason?: string;\n tags?: string[];\n title?: string;\n description?: string;\n icon?: string;\n}\n\nexport interface PluginMarketplaceMutationOutcome {\n ok: boolean;\n marketplace?: PluginMarketplace;\n message: string;\n}\n\nexport async function listPluginMarketplaces(): Promise<PluginMarketplace[]> {\n try {\n const resp = await fetch('/api/marketplaces');\n if (!resp.ok) return [];\n const json = (await resp.json()) as { marketplaces?: PluginMarketplace[] };\n return json.marketplaces ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function addPluginMarketplace(input: {\n url: string;\n trust: PluginMarketplaceTrust;\n}): Promise<PluginMarketplaceMutationOutcome> {\n try {\n const resp = await fetch('/api/marketplaces', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(input),\n });\n return readPluginMarketplaceOutcome(resp, 'Marketplace source added.');\n } catch (err) {\n return { ok: false, message: (err as Error).message };\n }\n}\n\nexport async function refreshPluginMarketplace(\n id: string,\n): Promise<PluginMarketplaceMutationOutcome> {\n try {\n const resp = await fetch(`/api/marketplaces/${encodeURIComponent(id)}/refresh`, {\n method: 'POST',\n });\n return readPluginMarketplaceOutcome(resp, 'Marketplace source refreshed.');\n } catch (err) {\n return { ok: false, message: (err as Error).message };\n }\n}\n\nexport async function removePluginMarketplace(\n id: string,\n): Promise<PluginMarketplaceMutationOutcome> {\n try {\n const resp = await fetch(`/api/marketplaces/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n if (!resp.ok) {\n return { ok: false, message: await readErrorMessage(resp) };\n }\n return { ok: true, message: 'Marketplace source removed.' };\n } catch (err) {\n return { ok: false, message: (err as Error).message };\n }\n}\n\nexport async function setPluginMarketplaceTrust(\n id: string,\n trust: PluginMarketplaceTrust,\n): Promise<PluginMarketplaceMutationOutcome> {\n try {\n const resp = await fetch(`/api/marketplaces/${encodeURIComponent(id)}/trust`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ trust }),\n });\n return readPluginMarketplaceOutcome(resp, 'Marketplace trust updated.');\n } catch (err) {\n return { ok: false, message: (err as Error).message };\n }\n}\n\nasync function readPluginMarketplaceOutcome(\n resp: Response,\n successMessage: string,\n): Promise<PluginMarketplaceMutationOutcome> {\n if (!resp.ok) {\n return { ok: false, message: await readErrorMessage(resp) };\n }\n const marketplace = (await resp.json().catch(() => null)) as PluginMarketplace | null;\n return {\n ok: true,\n ...(marketplace ? { marketplace } : {}),\n message: successMessage,\n };\n}\n\nexport async function applyPlugin(\n pluginId: string,\n options: {\n inputs?: Record<string, unknown>;\n projectId?: string;\n grantCaps?: string[];\n locale?: string;\n } = {},\n): Promise<ApplyResult | null> {\n try {\n const resp = await fetch(\n `/api/plugins/${encodeURIComponent(pluginId)}/apply`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n inputs: options.inputs ?? {},\n projectId: options.projectId,\n grantCaps: options.grantCaps ?? [],\n locale: options.locale,\n }),\n },\n );\n if (!resp.ok) return null;\n const json = (await resp.json()) as ApplyResult & { ok?: boolean };\n return json;\n } catch {\n return null;\n }\n}\n\nasync function readErrorMessage(resp: Response): Promise<string> {\n try {\n const json = (await resp.json()) as {\n error?: string | { message?: string; data?: { errors?: unknown } };\n errors?: unknown;\n message?: string;\n };\n const message =\n json.message ??\n (typeof json.error === 'string' ? json.error : json.error?.message);\n const details = extractErrorDetails(\n typeof json.error === 'object' ? json.error.data?.errors : undefined,\n json.errors,\n );\n if (message && details.length > 0) return `${message}: ${details.join('; ')}`;\n if (message) return message;\n } catch {\n // Fall through to the status text below.\n }\n return resp.statusText || `HTTP ${resp.status}`;\n}\n\nfunction extractErrorDetails(...values: unknown[]): string[] {\n return values.flatMap((value) => {\n if (!Array.isArray(value)) return [];\n return value.flatMap((item) => {\n if (typeof item === 'string' && item.trim()) return [item.trim()];\n if (item && typeof item === 'object' && 'message' in item) {\n const message = (item as { message?: unknown }).message;\n if (typeof message === 'string' && message.trim()) return [message.trim()];\n }\n return [];\n });\n });\n}\n\nasync function* readServerSentEvents(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<PluginInstallEvent, void, void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split(/\\n\\n/);\n buffer = parts.pop() ?? '';\n for (const part of parts) {\n const event = parseServerSentEvent(part);\n if (event) yield event;\n }\n }\n buffer += decoder.decode();\n const event = parseServerSentEvent(buffer);\n if (event) yield event;\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction parseServerSentEvent(raw: string): PluginInstallEvent | null {\n const data = raw\n .split('\\n')\n .filter((line) => line.startsWith('data:'))\n .map((line) => line.slice(5).trimStart())\n .join('\\n');\n if (!data) return null;\n try {\n return JSON.parse(data) as PluginInstallEvent;\n } catch {\n return null;\n }\n}\n\n// Fetch the immutable snapshot pinned to a project / conversation.\n// Used by ProjectView to surface the active plugin as a context chip\n// on user messages instead of re-rendering the inline plugin rail\n// (the user already picked a plugin on Home — re-prompting is noise).\nexport async function fetchAppliedPluginSnapshot(\n snapshotId: string,\n): Promise<AppliedPluginSnapshot | null> {\n try {\n const resp = await fetch(\n `/api/applied-plugins/${encodeURIComponent(snapshotId)}`,\n );\n if (!resp.ok) return null;\n return (await resp.json()) as AppliedPluginSnapshot;\n } catch {\n return null;\n }\n}\n\n// Render the brief that the composer should display for the active\n// applied plugin. Substitutes `{{var}}` placeholders inside\n// useCase.query against the user-supplied inputs map; missing values\n// stay as `{{var}}` so the gating \"fill required\" hint stays visible.\nexport function renderPluginBriefTemplate(\n template: string,\n inputs: Record<string, unknown>,\n): string {\n return template.replace(/\\{\\{\\s*([a-zA-Z_][\\w-]*)\\s*\\}\\}/g, (full, key) => {\n if (key in inputs) {\n const v = inputs[key];\n if (v === undefined || v === null || v === '') return full;\n return String(v);\n }\n return full;\n });\n}\n\nexport function resolvePluginQueryFallback(\n value: unknown,\n locale?: string,\n fallbackLocale: string = 'en',\n): string {\n if (!value) return '';\n if (typeof value === 'string') return value;\n if (!isStringMap(value)) return '';\n\n const candidates = [\n locale,\n locale?.split('-')[0],\n fallbackLocale,\n fallbackLocale.split('-')[0],\n ].filter((candidate): candidate is string => Boolean(candidate));\n\n for (const candidate of candidates) {\n const resolved = value[candidate];\n if (typeof resolved === 'string' && resolved.length > 0) return resolved;\n }\n\n return Object.values(value).find((entry) => entry.length > 0) ?? '';\n}\n\nfunction isStringMap(value: unknown): value is Record<string, string> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n return Object.values(value).every((entry) => typeof entry === 'string');\n}\n","{\"_source\":\"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json\",\"_generated_at\":\"2026-05-02\",\"_license\":\"BerriAI/litellm is MIT-licensed; see https://github.com/BerriAI/litellm/blob/main/LICENSE\",\"models\":{\"ai21.j2-mid-v1\":8191,\"ai21.j2-ultra-v1\":8191,\"ai21.jamba-1-5-large-v1:0\":256000,\"ai21.jamba-1-5-mini-v1:0\":256000,\"ai21.jamba-instruct-v1:0\":4096,\"amazon-nova/nova-lite-v1\":10000,\"amazon-nova/nova-micro-v1\":10000,\"amazon-nova/nova-premier-v1\":10000,\"amazon-nova/nova-pro-v1\":10000,\"amazon.nova-2-lite-v1:0\":64000,\"amazon.nova-2-pro-preview-20251202-v1:0\":64000,\"amazon.nova-lite-v1:0\":10000,\"amazon.nova-micro-v1:0\":10000,\"amazon.nova-pro-v1:0\":10000,\"amazon.titan-text-express-v1\":8000,\"amazon.titan-text-lite-v1\":4000,\"amazon.titan-text-premier-v1:0\":32000,\"anthropic.claude-3-5-haiku-20241022-v1:0\":8192,\"anthropic.claude-3-5-sonnet-20240620-v1:0\":4096,\"anthropic.claude-3-5-sonnet-20241022-v2:0\":8192,\"anthropic.claude-3-7-sonnet-20240620-v1:0\":8192,\"anthropic.claude-3-7-sonnet-20250219-v1:0\":8192,\"anthropic.claude-3-haiku-20240307-v1:0\":4096,\"anthropic.claude-3-opus-20240229-v1:0\":4096,\"anthropic.claude-3-sonnet-20240229-v1:0\":4096,\"anthropic.claude-haiku-4-5-20251001-v1:0\":64000,\"anthropic.claude-haiku-4-5@20251001\":64000,\"anthropic.claude-instant-v1\":8191,\"anthropic.claude-mythos-preview\":128000,\"anthropic.claude-opus-4-1-20250805-v1:0\":32000,\"anthropic.claude-opus-4-20250514-v1:0\":32000,\"anthropic.claude-opus-4-5-20251101-v1:0\":64000,\"anthropic.claude-opus-4-6-v1\":128000,\"anthropic.claude-opus-4-7\":128000,\"anthropic.claude-sonnet-4-20250514-v1:0\":64000,\"anthropic.claude-sonnet-4-5-20250929-v1:0\":64000,\"anthropic.claude-sonnet-4-6\":64000,\"anthropic.claude-v1\":8191,\"anthropic.claude-v2:1\":8191,\"anyscale/codellama/CodeLlama-34b-Instruct-hf\":4096,\"anyscale/codellama/CodeLlama-70b-Instruct-hf\":4096,\"anyscale/google/gemma-7b-it\":8192,\"anyscale/HuggingFaceH4/zephyr-7b-beta\":16384,\"anyscale/meta-llama/Llama-2-13b-chat-hf\":4096,\"anyscale/meta-llama/Llama-2-70b-chat-hf\":4096,\"anyscale/meta-llama/Llama-2-7b-chat-hf\":4096,\"anyscale/meta-llama/Meta-Llama-3-70B-Instruct\":8192,\"anyscale/meta-llama/Meta-Llama-3-8B-Instruct\":8192,\"anyscale/mistralai/Mistral-7B-Instruct-v0.1\":16384,\"anyscale/mistralai/Mixtral-8x22B-Instruct-v0.1\":65536,\"anyscale/mistralai/Mixtral-8x7B-Instruct-v0.1\":16384,\"apac.amazon.nova-2-lite-v1:0\":64000,\"apac.amazon.nova-2-pro-preview-20251202-v1:0\":64000,\"apac.amazon.nova-lite-v1:0\":10000,\"apac.amazon.nova-micro-v1:0\":10000,\"apac.amazon.nova-pro-v1:0\":10000,\"apac.anthropic.claude-3-5-sonnet-20240620-v1:0\":4096,\"apac.anthropic.claude-3-5-sonnet-20241022-v2:0\":8192,\"apac.anthropic.claude-3-haiku-20240307-v1:0\":4096,\"apac.anthropic.claude-3-sonnet-20240229-v1:0\":4096,\"apac.anthropic.claude-haiku-4-5-20251001-v1:0\":64000,\"apac.anthropic.claude-sonnet-4-20250514-v1:0\":64000,\"au.anthropic.claude-haiku-4-5-20251001-v1:0\":64000,\"au.anthropic.claude-opus-4-6-v1\":128000,\"au.anthropic.claude-opus-4-7\":128000,\"au.anthropic.claude-sonnet-4-5-20250929-v1:0\":64000,\"au.anthropic.claude-sonnet-4-6\":64000,\"azure_ai/claude-haiku-4-5\":64000,\"azure_ai/claude-opus-4-1\":32000,\"azure_ai/claude-opus-4-5\":64000,\"azure_ai/claude-opus-4-6\":128000,\"azure_ai/claude-opus-4-7\":128000,\"azure_ai/claude-sonnet-4-5\":64000,\"azure_ai/claude-sonnet-4-6\":64000,\"azure_ai/deepseek-r1\":8192,\"azure_ai/deepseek-v3\":8192,\"azure_ai/deepseek-v3-0324\":8192,\"azure_ai/deepseek-v3.2\":163840,\"azure_ai/deepseek-v3.2-speciale\":163840,\"azure_ai/global/grok-3\":131072,\"azure_ai/global/grok-3-mini\":131072,\"azure_ai/gpt-oss-120b\":131072,\"azure_ai/grok-3\":131072,\"azure_ai/grok-3-mini\":131072,\"azure_ai/grok-4\":131072,\"azure_ai/grok-4-1-fast-non-reasoning\":131072,\"azure_ai/grok-4-1-fast-reasoning\":131072,\"azure_ai/grok-4-fast-non-reasoning\":131072,\"azure_ai/grok-4-fast-reasoning\":131072,\"azure_ai/grok-code-fast-1\":131072,\"azure_ai/jais-30b-chat\":8192,\"azure_ai/jamba-instruct\":4096,\"azure_ai/kimi-k2.5\":262144,\"azure_ai/Llama-3.2-11B-Vision-Instruct\":2048,\"azure_ai/Llama-3.2-90B-Vision-Instruct\":2048,\"azure_ai/Llama-3.3-70B-Instruct\":2048,\"azure_ai/Llama-4-Maverick-17B-128E-Instruct-FP8\":16384,\"azure_ai/Llama-4-Scout-17B-16E-Instruct\":16384,\"azure_ai/MAI-DS-R1\":8192,\"azure_ai/Meta-Llama-3-70B-Instruct\":2048,\"azure_ai/Meta-Llama-3.1-405B-Instruct\":2048,\"azure_ai/Meta-Llama-3.1-70B-Instruct\":2048,\"azure_ai/Meta-Llama-3.1-8B-Instruct\":2048,\"azure_ai/ministral-3b\":4096,\"azure_ai/mistral-large\":8191,\"azure_ai/mistral-large-2407\":4096,\"azure_ai/mistral-large-3\":8191,\"azure_ai/mistral-large-latest\":4096,\"azure_ai/mistral-medium-2505\":8191,\"azure_ai/mistral-nemo\":4096,\"azure_ai/mistral-small\":8191,\"azure_ai/mistral-small-2503\":128000,\"azure_ai/Phi-3-medium-128k-instruct\":4096,\"azure_ai/Phi-3-medium-4k-instruct\":4096,\"azure_ai/Phi-3-mini-128k-instruct\":4096,\"azure_ai/Phi-3-mini-4k-instruct\":4096,\"azure_ai/Phi-3-small-128k-instruct\":4096,\"azure_ai/Phi-3-small-8k-instruct\":4096,\"azure_ai/Phi-3.5-mini-instruct\":4096,\"azure_ai/Phi-3.5-MoE-instruct\":4096,\"azure_ai/Phi-3.5-vision-instruct\":4096,\"azure_ai/Phi-4\":16384,\"azure_ai/Phi-4-mini-instruct\":4096,\"azure_ai/Phi-4-mini-reasoning\":4096,\"azure_ai/Phi-4-multimodal-instruct\":4096,\"azure_ai/Phi-4-reasoning\":4096,\"azure/command-r-plus\":4096,\"azure/computer-use-preview\":1024,\"azure/eu/gpt-4o-2024-08-06\":16384,\"azure/eu/gpt-4o-2024-11-20\":16384,\"azure/eu/gpt-4o-mini-2024-07-18\":16384,\"azure/eu/gpt-4o-mini-realtime-preview-2024-12-17\":4096,\"azure/eu/gpt-4o-realtime-preview-2024-10-01\":4096,\"azure/eu/gpt-4o-realtime-preview-2024-12-17\":4096,\"azure/eu/gpt-5-2025-08-07\":128000,\"azure/eu/gpt-5-mini-2025-08-07\":128000,\"azure/eu/gpt-5-nano-2025-08-07\":128000,\"azure/eu/gpt-5.1\":128000,\"azure/eu/gpt-5.1-chat\":128000,\"azure/eu/o1-2024-12-17\":100000,\"azure/eu/o1-mini-2024-09-12\":65536,\"azure/eu/o1-preview-2024-09-12\":32768,\"azure/eu/o3-mini-2025-01-31\":100000,\"azure/global-standard/gpt-4o-2024-08-06\":16384,\"azure/global-standard/gpt-4o-2024-11-20\":16384,\"azure/global-standard/gpt-4o-mini\":16384,\"azure/global/gpt-4o-2024-08-06\":16384,\"azure/global/gpt-4o-2024-11-20\":16384,\"azure/global/gpt-5.1\":128000,\"azure/global/gpt-5.1-chat\":128000,\"azure/gpt-3.5-turbo\":4096,\"azure/gpt-3.5-turbo-0125\":4096,\"azure/gpt-35-turbo\":4096,\"azure/gpt-35-turbo-0125\":4096,\"azure/gpt-35-turbo-1106\":4096,\"azure/gpt-35-turbo-16k\":4096,\"azure/gpt-35-turbo-16k-0613\":4096,\"azure/gpt-4\":4096,\"azure/gpt-4-0125-preview\":4096,\"azure/gpt-4-0613\":4096,\"azure/gpt-4-1106-preview\":4096,\"azure/gpt-4-32k\":4096,\"azure/gpt-4-32k-0613\":4096,\"azure/gpt-4-turbo\":4096,\"azure/gpt-4-turbo-2024-04-09\":4096,\"azure/gpt-4-turbo-vision-preview\":4096,\"azure/gpt-4.1\":32768,\"azure/gpt-4.1-2025-04-14\":32768,\"azure/gpt-4.1-mini\":32768,\"azure/gpt-4.1-mini-2025-04-14\":32768,\"azure/gpt-4.1-nano\":32768,\"azure/gpt-4.1-nano-2025-04-14\":32768,\"azure/gpt-4.5-preview\":16384,\"azure/gpt-4o\":16384,\"azure/gpt-4o-2024-05-13\":4096,\"azure/gpt-4o-2024-08-06\":16384,\"azure/gpt-4o-2024-11-20\":16384,\"azure/gpt-4o-audio-preview-2024-12-17\":16384,\"azure/gpt-4o-mini\":16384,\"azure/gpt-4o-mini-2024-07-18\":16384,\"azure/gpt-4o-mini-audio-preview-2024-12-17\":16384,\"azure/gpt-4o-mini-realtime-preview-2024-12-17\":4096,\"azure/gpt-4o-realtime-preview-2024-10-01\":4096,\"azure/gpt-4o-realtime-preview-2024-12-17\":4096,\"azure/gpt-5\":128000,\"azure/gpt-5-2025-08-07\":128000,\"azure/gpt-5-chat\":16384,\"azure/gpt-5-chat-latest\":16384,\"azure/gpt-5-mini\":128000,\"azure/gpt-5-mini-2025-08-07\":128000,\"azure/gpt-5-nano\":128000,\"azure/gpt-5-nano-2025-08-07\":128000,\"azure/gpt-5.1\":128000,\"azure/gpt-5.1-2025-11-13\":128000,\"azure/gpt-5.1-chat\":128000,\"azure/gpt-5.1-chat-2025-11-13\":16384,\"azure/gpt-5.2\":128000,\"azure/gpt-5.2-2025-12-11\":128000,\"azure/gpt-5.2-chat\":16384,\"azure/gpt-5.2-chat-2025-12-11\":16384,\"azure/gpt-5.3-chat\":16384,\"azure/gpt-5.4\":128000,\"azure/gpt-5.4-2026-03-05\":128000,\"azure/gpt-5.4-mini\":128000,\"azure/gpt-5.4-mini-2026-03-17\":128000,\"azure/gpt-5.4-nano\":128000,\"azure/gpt-5.4-nano-2026-03-17\":128000,\"azure/gpt-5.5\":128000,\"azure/gpt-5.5-2026-04-23\":128000,\"azure/gpt-audio-1.5-2026-02-23\":16384,\"azure/gpt-audio-2025-08-28\":16384,\"azure/gpt-audio-mini-2025-10-06\":16384,\"azure/gpt-realtime-1.5-2026-02-23\":4096,\"azure/gpt-realtime-2025-08-28\":4096,\"azure/gpt-realtime-mini-2025-10-06\":4096,\"azure/mistral-large-2402\":32000,\"azure/mistral-large-latest\":32000,\"azure/o1\":100000,\"azure/o1-2024-12-17\":100000,\"azure/o1-mini\":65536,\"azure/o1-mini-2024-09-12\":65536,\"azure/o1-preview\":32768,\"azure/o1-preview-2024-09-12\":32768,\"azure/o3\":100000,\"azure/o3-2025-04-16\":100000,\"azure/o3-mini\":100000,\"azure/o3-mini-2025-01-31\":100000,\"azure/o4-mini\":100000,\"azure/o4-mini-2025-04-16\":100000,\"azure/us/gpt-4.1-2025-04-14\":32768,\"azure/us/gpt-4.1-mini-2025-04-14\":32768,\"azure/us/gpt-4.1-nano-2025-04-14\":32768,\"azure/us/gpt-4o-2024-08-06\":16384,\"azure/us/gpt-4o-2024-11-20\":16384,\"azure/us/gpt-4o-mini-2024-07-18\":16384,\"azure/us/gpt-4o-mini-realtime-preview-2024-12-17\":4096,\"azure/us/gpt-4o-realtime-preview-2024-10-01\":4096,\"azure/us/gpt-4o-realtime-preview-2024-12-17\":4096,\"azure/us/gpt-5-2025-08-07\":128000,\"azure/us/gpt-5-mini-2025-08-07\":128000,\"azure/us/gpt-5-nano-2025-08-07\":128000,\"azure/us/gpt-5.1\":128000,\"azure/us/gpt-5.1-chat\":128000,\"azure/us/o1-2024-12-17\":100000,\"azure/us/o1-mini-2024-09-12\":65536,\"azure/us/o1-preview-2024-09-12\":32768,\"azure/us/o3-2025-04-16\":100000,\"azure/us/o3-mini-2025-01-31\":100000,\"azure/us/o4-mini-2025-04-16\":100000,\"bedrock_mantle/openai.gpt-oss-120b\":32768,\"bedrock_mantle/openai.gpt-oss-20b\":32768,\"bedrock_mantle/openai.gpt-oss-safeguard-120b\":65536,\"bedrock_mantle/openai.gpt-oss-safeguard-20b\":65536,\"bedrock/*/1-month-commitment/cohere.command-light-text-v14\":4096,\"bedrock/*/1-month-commitment/cohere.command-text-v14\":4096,\"bedrock/*/6-month-commitment/cohere.command-light-text-v14\":4096,\"bedrock/*/6-month-commitment/cohere.command-text-v14\":4096,\"bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-instant-v1\":8191,\"bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-v1\":8191,\"bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-v2:1\":8191,\"bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-instant-v1\":8191,\"bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-v1\":8191,\"bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-v2:1\":8191,\"bedrock/ap-northeast-1/anthropic.claude-instant-v1\":8191,\"bedrock/ap-northeast-1/anthropic.claude-v1\":8191,\"bedrock/ap-northeast-1/anthropic.claude-v2:1\":8191,\"bedrock/ap-northeast-1/deepseek.v3.2\":163840,\"bedrock/ap-northeast-1/minimax.minimax-m2.1\":8192,\"bedrock/ap-northeast-1/minimax.minimax-m2.5\":8192,\"bedrock/ap-northeast-1/moonshotai.kimi-k2-thinking\":262144,\"bedrock/ap-northeast-1/moonshotai.kimi-k2.5\":262144,\"bedrock/ap-northeast-1/qwen.qwen3-coder-next\":8192,\"bedrock/ap-south-1/deepseek.v3.2\":163840,\"bedrock/ap-south-1/meta.llama3-70b-instruct-v1:0\":8192,\"bedrock/ap-south-1/meta.llama3-8b-instruct-v1:0\":8192,\"bedrock/ap-south-1/minimax.minimax-m2.1\":8192,\"bedrock/ap-south-1/minimax.minimax-m2.5\":8192,\"bedrock/ap-south-1/moonshotai.kimi-k2-thinking\":262144,\"bedrock/ap-south-1/moonshotai.kimi-k2.5\":262144,\"bedrock/ap-south-1/qwen.qwen3-coder-next\":8192,\"bedrock/ap-southeast-2/minimax.minimax-m2.5\":8192,\"bedrock/ap-southeast-3/deepseek.v3.2\":163840,\"bedrock/ap-southeast-3/minimax.minimax-m2.1\":8192,\"bedrock/ap-southeast-3/minimax.minimax-m2.5\":8192,\"bedrock/ap-southeast-3/moonshotai.kimi-k2.5\":262144,\"bedrock/ap-southeast-3/qwen.qwen3-coder-next\":8192,\"bedrock/ca-central-1/meta.llama3-70b-instruct-v1:0\":8192,\"bedrock/ca-central-1/meta.llama3-8b-instruct-v1:0\":8192,\"bedrock/eu-central-1/1-month-commitment/anthropic.claude-instant-v1\":8191,\"bedrock/eu-central-1/1-month-commitment/anthropic.claude-v1\":8191,\"bedrock/eu-central-1/1-month-commitment/anthropic.claude-v2:1\":8191,\"bedrock/eu-central-1/6-month-commitment/anthropic.claude-instant-v1\":8191,\"bedrock/eu-central-1/6-month-commitment/anthropic.claude-v1\":8191,\"bedrock/eu-central-1/6-month-commitment/anthropic.claude-v2:1\":8191,\"bedrock/eu-central-1/anthropic.claude-instant-v1\":8191,\"bedrock/eu-central-1/anthropic.claude-v1\":8191,\"bedrock/eu-central-1/anthropic.claude-v2:1\":8191,\"bedrock/eu-central-1/minimax.minimax-m2.1\":8192,\"bedrock/eu-central-1/minimax.minimax-m2.5\":8192,\"bedrock/eu-central-1/qwen.qwen3-coder-next\":8192,\"bedrock/eu-north-1/deepseek.v3.2\":163840,\"bedrock/eu-north-1/minimax.minimax-m2.1\":8192,\"bedrock/eu-north-1/minimax.minimax-m2.5\":8192,\"bedrock/eu-north-1/moonshotai.kimi-k2.5\":262144,\"bedrock/eu-south-1/minimax.minimax-m2.1\":8192,\"bedrock/eu-south-1/minimax.minimax-m2.5\":8192,\"bedrock/eu-south-1/qwen.qwen3-coder-next\":8192,\"bedrock/eu-west-1/meta.llama3-70b-instruct-v1:0\":8192,\"bedrock/eu-west-1/meta.llama3-8b-instruct-v1:0\":8192,\"bedrock/eu-west-1/minimax.minimax-m2.1\":8192,\"bedrock/eu-west-1/minimax.minimax-m2.5\":8192,\"bedrock/eu-west-1/qwen.qwen3-coder-next\":8192,\"bedrock/eu-west-2/meta.llama3-70b-instruct-v1:0\":8192,\"bedrock/eu-west-2/meta.llama3-8b-instruct-v1:0\":8192,\"bedrock/eu-west-2/minimax.minimax-m2.1\":8192,\"bedrock/eu-west-2/minimax.minimax-m2.5\":8192,\"bedrock/eu-west-2/qwen.qwen3-coder-next\":8192,\"bedrock/eu-west-3/mistral.mistral-7b-instruct-v0:2\":8191,\"bedrock/eu-west-3/mistral.mistral-large-2402-v1:0\":8191,\"bedrock/eu-west-3/mistral.mixtral-8x7b-instruct-v0:1\":8191,\"bedrock/invoke/anthropic.claude-3-5-sonnet-20240620-v1:0\":4096,\"bedrock/moonshotai.kimi-k2-thinking\":262144,\"bedrock/moonshotai.kimi-k2.5\":262144,\"bedrock/sa-east-1/deepseek.v3.2\":163840,\"bedrock/sa-east-1/meta.llama3-70b-instruct-v1:0\":8192,\"bedrock/sa-east-1/meta.llama3-8b-instruct-v1:0\":8192,\"bedrock/sa-east-1/minimax.minimax-m2.1\":8192,\"bedrock/sa-east-1/minimax.minimax-m2.5\":8192,\"bedrock/sa-east-1/moonshotai.kimi-k2-thinking\":262144,\"bedrock/sa-east-1/moonshotai.kimi-k2.5\":262144,\"bedrock/sa-east-1/qwen.qwen3-coder-next\":8192,\"bedrock/us-east-1/1-month-commitment/anthropic.claude-instant-v1\":8191,\"bedrock/us-east-1/1-month-commitment/anthropic.claude-v1\":8191,\"bedrock/us-east-1/1-month-commitment/anthropic.claude-v2:1\":8191,\"bedrock/us-east-1/6-month-commitment/anthropic.claude-instant-v1\":8191,\"bedrock/us-east-1/6-month-commitment/anthropic.claude-v1\":8191,\"bedrock/us-east-1/6-month-commitment/anthropic.claude-v2:1\":8191,\"bedrock/us-east-1/anthropic.claude-instant-v1\":8191,\"bedrock/us-east-1/anthropic.claude-v1\":8191,\"bedrock/us-east-1/anthropic.claude-v2:1\":8191,\"bedrock/us-east-1/deepseek.v3.2\":163840,\"bedrock/us-east-1/meta.llama3-70b-instruct-v1:0\":8192,\"bedrock/us-east-1/meta.llama3-8b-instruct-v1:0\":8192,\"bedrock/us-east-1/minimax.minimax-m2.1\":8192,\"bedrock/us-east-1/minimax.minimax-m2.5\":8192,\"bedrock/us-east-1/mistral.mistral-7b-instruct-v0:2\":8191,\"bedrock/us-east-1/mistral.mistral-large-2402-v1:0\":8191,\"bedrock/us-east-1/mistral.mixtral-8x7b-instruct-v0:1\":8191,\"bedrock/us-east-1/moonshotai.kimi-k2-thinking\":262144,\"bedrock/us-east-1/moonshotai.kimi-k2.5\":262144,\"bedrock/us-east-1/qwen.qwen3-coder-next\":8192,\"bedrock/us-east-1/zai.glm-5\":128000,\"bedrock/us-east-2/deepseek.v3.2\":163840,\"bedrock/us-east-2/minimax.minimax-m2.1\":8192,\"bedrock/us-east-2/minimax.minimax-m2.5\":8192,\"bedrock/us-east-2/moonshotai.kimi-k2-thinking\":262144,\"bedrock/us-east-2/moonshotai.kimi-k2.5\":262144,\"bedrock/us-east-2/qwen.qwen3-coder-next\":8192,\"bedrock/us-gov-east-1/amazon.nova-pro-v1:0\":10000,\"bedrock/us-gov-east-1/amazon.titan-text-express-v1\":8000,\"bedrock/us-gov-east-1/amazon.titan-text-lite-v1\":4000,\"bedrock/us-gov-east-1/amazon.titan-text-premier-v1:0\":32000,\"bedrock/us-gov-east-1/anthropic.claude-3-5-sonnet-20240620-v1:0\":8192,\"bedrock/us-gov-east-1/anthropic.claude-3-haiku-20240307-v1:0\":4096,\"bedrock/us-gov-east-1/anthropic.claude-haiku-4-5-20251001-v1:0\":64000,\"bedrock/us-gov-east-1/anthropic.claude-sonnet-4-5-20250929-v1:0\":8192,\"bedrock/us-gov-east-1/claude-sonnet-4-5-20250929-v1:0\":8192,\"bedrock/us-gov-east-1/meta.llama3-70b-instruct-v1:0\":2048,\"bedrock/us-gov-east-1/meta.llama3-8b-instruct-v1:0\":2048,\"bedrock/us-gov-west-1/amazon.nova-pro-v1:0\":10000,\"bedrock/us-gov-west-1/amazon.titan-text-express-v1\":8000,\"bedrock/us-gov-west-1/amazon.titan-text-lite-v1\":4000,\"bedrock/us-gov-west-1/amazon.titan-text-premier-v1:0\":32000,\"bedrock/us-gov-west-1/anthropic.claude-3-5-sonnet-20240620-v1:0\":8192,\"bedrock/us-gov-west-1/anthropic.claude-3-7-sonnet-20250219-v1:0\":8192,\"bedrock/us-gov-west-1/anthropic.claude-3-haiku-20240307-v1:0\":4096,\"bedrock/us-gov-west-1/anthropic.claude-haiku-4-5-20251001-v1:0\":64000,\"bedrock/us-gov-west-1/anthropic.claude-sonnet-4-5-20250929-v1:0\":8192,\"bedrock/us-gov-west-1/claude-sonnet-4-5-20250929-v1:0\":8192,\"bedrock/us-gov-west-1/meta.llama3-70b-instruct-v1:0\":2048,\"bedrock/us-gov-west-1/meta.llama3-8b-instruct-v1:0\":2048,\"bedrock/us-west-1/meta.llama3-70b-instruct-v1:0\":8192,\"bedrock/us-west-1/meta.llama3-8b-instruct-v1:0\":8192,\"bedrock/us-west-2/1-month-commitment/anthropic.claude-instant-v1\":8191,\"bedrock/us-west-2/1-month-commitment/anthropic.claude-v1\":8191,\"bedrock/us-west-2/1-month-commitment/anthropic.claude-v2:1\":8191,\"bedrock/us-west-2/6-month-commitment/anthropic.claude-instant-v1\":8191,\"bedrock/us-west-2/6-month-commitment/anthropic.claude-v1\":8191,\"bedrock/us-west-2/6-month-commitment/anthropic.claude-v2:1\":8191,\"bedrock/us-west-2/anthropic.claude-instant-v1\":8191,\"bedrock/us-west-2/anthropic.claude-v1\":8191,\"bedrock/us-west-2/anthropic.claude-v2:1\":8191,\"bedrock/us-west-2/deepseek.v3.2\":163840,\"bedrock/us-west-2/minimax.minimax-m2.1\":8192,\"bedrock/us-west-2/minimax.minimax-m2.5\":8192,\"bedrock/us-west-2/mistral.mistral-7b-instruct-v0:2\":8191,\"bedrock/us-west-2/mistral.mistral-large-2402-v1:0\":8191,\"bedrock/us-west-2/mistral.mixtral-8x7b-instruct-v0:1\":8191,\"bedrock/us-west-2/moonshotai.kimi-k2-thinking\":262144,\"bedrock/us-west-2/moonshotai.kimi-k2.5\":262144,\"bedrock/us-west-2/qwen.qwen3-coder-next\":8192,\"bedrock/us-west-2/zai.glm-5\":128000,\"bedrock/us.anthropic.claude-3-5-haiku-20241022-v1:0\":8192,\"cerebras/gpt-oss-120b\":32768,\"cerebras/llama-3.3-70b\":128000,\"cerebras/llama3.1-70b\":128000,\"cerebras/llama3.1-8b\":128000,\"cerebras/qwen-3-32b\":128000,\"cerebras/zai-glm-4.6\":128000,\"cerebras/zai-glm-4.7\":128000,\"chatdolphin\":16384,\"chatgpt-4o-latest\":4096,\"claude-3-7-sonnet-20250219\":64000,\"claude-3-haiku-20240307\":4096,\"claude-3-opus-20240229\":4096,\"claude-4-opus-20250514\":32000,\"claude-4-sonnet-20250514\":64000,\"claude-haiku-4-5\":64000,\"claude-haiku-4-5-20251001\":64000,\"claude-opus-4-1\":32000,\"claude-opus-4-1-20250805\":32000,\"claude-opus-4-20250514\":32000,\"claude-opus-4-5\":64000,\"claude-opus-4-5-20251101\":64000,\"claude-opus-4-6\":128000,\"claude-opus-4-6-20260205\":128000,\"claude-opus-4-7\":128000,\"claude-opus-4-7-20260416\":128000,\"claude-sonnet-4-20250514\":64000,\"claude-sonnet-4-5\":64000,\"claude-sonnet-4-5-20250929\":64000,\"claude-sonnet-4-5-20250929-v1:0\":64000,\"claude-sonnet-4-6\":64000,\"cloudflare/@cf/meta/llama-2-7b-chat-fp16\":3072,\"cloudflare/@cf/meta/llama-2-7b-chat-int8\":2048,\"cloudflare/@cf/mistral/mistral-7b-instruct-v0.1\":8192,\"cloudflare/@hf/thebloke/codellama-7b-instruct-awq\":4096,\"codestral/codestral-2405\":8191,\"codestral/codestral-latest\":8191,\"cohere.command-light-text-v14\":4096,\"cohere.command-r-plus-v1:0\":4096,\"cohere.command-r-v1:0\":4096,\"cohere.command-text-v14\":4096,\"command-a-03-2025\":8000,\"command-light\":4096,\"command-r\":4096,\"command-r-08-2024\":4096,\"command-r-plus\":4096,\"command-r-plus-08-2024\":4096,\"command-r7b-12-2024\":4096,\"computer-use-preview\":1024,\"dashscope/qwen-coder\":16384,\"dashscope/qwen-flash\":32768,\"dashscope/qwen-flash-2025-07-28\":32768,\"dashscope/qwen-max\":8192,\"dashscope/qwen-plus\":16384,\"dashscope/qwen-plus-2025-01-25\":8192,\"dashscope/qwen-plus-2025-04-28\":16384,\"dashscope/qwen-plus-2025-07-14\":16384,\"dashscope/qwen-plus-2025-07-28\":32768,\"dashscope/qwen-plus-2025-09-11\":32768,\"dashscope/qwen-plus-latest\":32768,\"dashscope/qwen-turbo\":16384,\"dashscope/qwen-turbo-2024-11-01\":8192,\"dashscope/qwen-turbo-2025-04-28\":16384,\"dashscope/qwen-turbo-latest\":16384,\"dashscope/qwen3-30b-a3b\":16384,\"dashscope/qwen3-coder-flash\":65536,\"dashscope/qwen3-coder-flash-2025-07-28\":65536,\"dashscope/qwen3-coder-plus\":65536,\"dashscope/qwen3-coder-plus-2025-07-22\":65536,\"dashscope/qwen3-max\":65536,\"dashscope/qwen3-max-2026-01-23\":65536,\"dashscope/qwen3-max-preview\":65536,\"dashscope/qwen3-next-80b-a3b-instruct\":65536,\"dashscope/qwen3-next-80b-a3b-thinking\":65536,\"dashscope/qwen3-vl-235b-a22b-instruct\":32768,\"dashscope/qwen3-vl-235b-a22b-thinking\":32768,\"dashscope/qwen3-vl-32b-instruct\":32768,\"dashscope/qwen3-vl-32b-thinking\":32768,\"dashscope/qwen3-vl-plus\":32768,\"dashscope/qwen3.5-plus\":65536,\"dashscope/qwq-plus\":8192,\"databricks/databricks-claude-3-7-sonnet\":128000,\"databricks/databricks-claude-haiku-4-5\":64000,\"databricks/databricks-claude-opus-4\":32000,\"databricks/databricks-claude-opus-4-1\":32000,\"databricks/databricks-claude-opus-4-5\":64000,\"databricks/databricks-claude-sonnet-4\":64000,\"databricks/databricks-claude-sonnet-4-1\":64000,\"databricks/databricks-claude-sonnet-4-5\":64000,\"databricks/databricks-gemini-2-5-flash\":65535,\"databricks/databricks-gemini-2-5-pro\":65536,\"databricks/databricks-gemma-3-12b\":32000,\"databricks/databricks-gpt-5\":128000,\"databricks/databricks-gpt-5-1\":128000,\"databricks/databricks-gpt-5-mini\":128000,\"databricks/databricks-gpt-5-nano\":128000,\"databricks/databricks-gpt-oss-120b\":131072,\"databricks/databricks-gpt-oss-20b\":131072,\"databricks/databricks-llama-2-70b-chat\":4096,\"databricks/databricks-llama-4-maverick\":128000,\"databricks/databricks-meta-llama-3-1-405b-instruct\":128000,\"databricks/databricks-meta-llama-3-1-8b-instruct\":128000,\"databricks/databricks-meta-llama-3-3-70b-instruct\":128000,\"databricks/databricks-meta-llama-3-70b-instruct\":128000,\"databricks/databricks-mixtral-8x7b-instruct\":4096,\"databricks/databricks-mpt-30b-instruct\":8192,\"databricks/databricks-mpt-7b-instruct\":8192,\"deepinfra/allenai/olmOCR-7B-0725-FP8\":16384,\"deepinfra/anthropic/claude-3-7-sonnet-latest\":200000,\"deepinfra/anthropic/claude-4-opus\":200000,\"deepinfra/anthropic/claude-4-sonnet\":200000,\"deepinfra/deepseek-ai/DeepSeek-R1\":163840,\"deepinfra/deepseek-ai/DeepSeek-R1-0528\":163840,\"deepinfra/deepseek-ai/DeepSeek-R1-0528-Turbo\":32768,\"deepinfra/deepseek-ai/DeepSeek-R1-Distill-Llama-70B\":131072,\"deepinfra/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B\":131072,\"deepinfra/deepseek-ai/DeepSeek-R1-Turbo\":40960,\"deepinfra/deepseek-ai/DeepSeek-V3\":163840,\"deepinfra/deepseek-ai/DeepSeek-V3-0324\":163840,\"deepinfra/deepseek-ai/DeepSeek-V3.1\":163840,\"deepinfra/deepseek-ai/DeepSeek-V3.1-Terminus\":163840,\"deepinfra/google/gemini-2.0-flash-001\":1000000,\"deepinfra/google/gemini-2.5-flash\":1000000,\"deepinfra/google/gemini-2.5-pro\":1000000,\"deepinfra/google/gemma-3-12b-it\":131072,\"deepinfra/google/gemma-3-27b-it\":131072,\"deepinfra/google/gemma-3-4b-it\":131072,\"deepinfra/Gryphe/MythoMax-L2-13b\":4096,\"deepinfra/meta-llama/Llama-3.2-11B-Vision-Instruct\":131072,\"deepinfra/meta-llama/Llama-3.2-3B-Instruct\":131072,\"deepinfra/meta-llama/Llama-3.3-70B-Instruct\":131072,\"deepinfra/meta-llama/Llama-3.3-70B-Instruct-Turbo\":131072,\"deepinfra/meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8\":1048576,\"deepinfra/meta-llama/Llama-4-Scout-17B-16E-Instruct\":327680,\"deepinfra/meta-llama/Llama-Guard-3-8B\":131072,\"deepinfra/meta-llama/Llama-Guard-4-12B\":163840,\"deepinfra/meta-llama/Meta-Llama-3-8B-Instruct\":8192,\"deepinfra/meta-llama/Meta-Llama-3.1-70B-Instruct\":131072,\"deepinfra/meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo\":131072,\"deepinfra/meta-llama/Meta-Llama-3.1-8B-Instruct\":131072,\"deepinfra/meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo\":131072,\"deepinfra/microsoft/phi-4\":16384,\"deepinfra/microsoft/WizardLM-2-8x22B\":65536,\"deepinfra/mistralai/Mistral-Nemo-Instruct-2407\":131072,\"deepinfra/mistralai/Mistral-Small-24B-Instruct-2501\":32768,\"deepinfra/mistralai/Mistral-Small-3.2-24B-Instruct-2506\":128000,\"deepinfra/mistralai/Mixtral-8x7B-Instruct-v0.1\":32768,\"deepinfra/moonshotai/Kimi-K2-Instruct\":131072,\"deepinfra/moonshotai/Kimi-K2-Instruct-0905\":262144,\"deepinfra/NousResearch/Hermes-3-Llama-3.1-405B\":131072,\"deepinfra/NousResearch/Hermes-3-Llama-3.1-70B\":131072,\"deepinfra/nvidia/Llama-3.1-Nemotron-70B-Instruct\":131072,\"deepinfra/nvidia/Llama-3.3-Nemotron-Super-49B-v1.5\":131072,\"deepinfra/nvidia/NVIDIA-Nemotron-Nano-9B-v2\":131072,\"deepinfra/openai/gpt-oss-120b\":131072,\"deepinfra/openai/gpt-oss-20b\":131072,\"deepinfra/Qwen/Qwen2.5-72B-Instruct\":32768,\"deepinfra/Qwen/Qwen2.5-7B-Instruct\":32768,\"deepinfra/Qwen/Qwen2.5-VL-32B-Instruct\":128000,\"deepinfra/Qwen/Qwen3-14B\":40960,\"deepinfra/Qwen/Qwen3-235B-A22B\":40960,\"deepinfra/Qwen/Qwen3-235B-A22B-Instruct-2507\":262144,\"deepinfra/Qwen/Qwen3-235B-A22B-Thinking-2507\":262144,\"deepinfra/Qwen/Qwen3-30B-A3B\":40960,\"deepinfra/Qwen/Qwen3-32B\":40960,\"deepinfra/Qwen/Qwen3-Coder-480B-A35B-Instruct\":262144,\"deepinfra/Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo\":262144,\"deepinfra/Qwen/Qwen3-Next-80B-A3B-Instruct\":262144,\"deepinfra/Qwen/Qwen3-Next-80B-A3B-Thinking\":262144,\"deepinfra/Qwen/QwQ-32B\":131072,\"deepinfra/Sao10K/L3-8B-Lunaris-v1-Turbo\":8192,\"deepinfra/Sao10K/L3.1-70B-Euryale-v2.2\":131072,\"deepinfra/Sao10K/L3.3-70B-Euryale-v2.3\":131072,\"deepinfra/zai-org/GLM-4.5\":131072,\"deepseek-chat\":8192,\"deepseek-reasoner\":65536,\"deepseek-v3-2-251201\":32768,\"deepseek.v3-v1:0\":81920,\"deepseek.v3.2\":163840,\"deepseek/deepseek-chat\":8192,\"deepseek/deepseek-coder\":4096,\"deepseek/deepseek-r1\":8192,\"deepseek/deepseek-reasoner\":65536,\"deepseek/deepseek-v3\":8192,\"deepseek/deepseek-v3.2\":163840,\"eu.amazon.nova-2-lite-v1:0\":64000,\"eu.amazon.nova-2-pro-preview-20251202-v1:0\":64000,\"eu.amazon.nova-lite-v1:0\":10000,\"eu.amazon.nova-micro-v1:0\":10000,\"eu.amazon.nova-pro-v1:0\":10000,\"eu.anthropic.claude-3-5-haiku-20241022-v1:0\":8192,\"eu.anthropic.claude-3-5-sonnet-20240620-v1:0\":4096,\"eu.anthropic.claude-3-5-sonnet-20241022-v2:0\":8192,\"eu.anthropic.claude-3-7-sonnet-20250219-v1:0\":8192,\"eu.anthropic.claude-3-haiku-20240307-v1:0\":4096,\"eu.anthropic.claude-3-opus-20240229-v1:0\":4096,\"eu.anthropic.claude-3-sonnet-20240229-v1:0\":4096,\"eu.anthropic.claude-haiku-4-5-20251001-v1:0\":64000,\"eu.anthropic.claude-opus-4-1-20250805-v1:0\":32000,\"eu.anthropic.claude-opus-4-20250514-v1:0\":32000,\"eu.anthropic.claude-opus-4-5-20251101-v1:0\":64000,\"eu.anthropic.claude-opus-4-6-v1\":128000,\"eu.anthropic.claude-opus-4-7\":128000,\"eu.anthropic.claude-sonnet-4-20250514-v1:0\":64000,\"eu.anthropic.claude-sonnet-4-5-20250929-v1:0\":64000,\"eu.anthropic.claude-sonnet-4-6\":64000,\"eu.deepseek.v3.2\":163840,\"eu.meta.llama3-2-1b-instruct-v1:0\":4096,\"eu.meta.llama3-2-3b-instruct-v1:0\":4096,\"eu.mistral.pixtral-large-2502-v1:0\":4096,\"featherless_ai/featherless-ai/Qwerky-72B\":4096,\"featherless_ai/featherless-ai/Qwerky-QwQ-32B\":4096,\"fireworks_ai/accounts/fireworks/models/chronos-hermes-13b-v2\":4096,\"fireworks_ai/accounts/fireworks/models/code-llama-13b\":16384,\"fireworks_ai/accounts/fireworks/models/code-llama-13b-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/code-llama-13b-python\":16384,\"fireworks_ai/accounts/fireworks/models/code-llama-34b\":16384,\"fireworks_ai/accounts/fireworks/models/code-llama-34b-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/code-llama-34b-python\":16384,\"fireworks_ai/accounts/fireworks/models/code-llama-70b\":4096,\"fireworks_ai/accounts/fireworks/models/code-llama-70b-instruct\":4096,\"fireworks_ai/accounts/fireworks/models/code-llama-70b-python\":4096,\"fireworks_ai/accounts/fireworks/models/code-llama-7b\":16384,\"fireworks_ai/accounts/fireworks/models/code-llama-7b-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/code-llama-7b-python\":16384,\"fireworks_ai/accounts/fireworks/models/code-qwen-1p5-7b\":65536,\"fireworks_ai/accounts/fireworks/models/codegemma-2b\":8192,\"fireworks_ai/accounts/fireworks/models/codegemma-7b\":8192,\"fireworks_ai/accounts/fireworks/models/cogito-671b-v2-p1\":163840,\"fireworks_ai/accounts/fireworks/models/cogito-v1-preview-llama-3b\":131072,\"fireworks_ai/accounts/fireworks/models/cogito-v1-preview-llama-70b\":131072,\"fireworks_ai/accounts/fireworks/models/cogito-v1-preview-llama-8b\":131072,\"fireworks_ai/accounts/fireworks/models/cogito-v1-preview-qwen-14b\":131072,\"fireworks_ai/accounts/fireworks/models/cogito-v1-preview-qwen-32b\":131072,\"fireworks_ai/accounts/fireworks/models/dbrx-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/deepseek-coder-1b-base\":16384,\"fireworks_ai/accounts/fireworks/models/deepseek-coder-33b-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/deepseek-coder-7b-base\":4096,\"fireworks_ai/accounts/fireworks/models/deepseek-coder-7b-base-v1p5\":4096,\"fireworks_ai/accounts/fireworks/models/deepseek-coder-7b-instruct-v1p5\":4096,\"fireworks_ai/accounts/fireworks/models/deepseek-coder-v2-instruct\":65536,\"fireworks_ai/accounts/fireworks/models/deepseek-coder-v2-lite-base\":163840,\"fireworks_ai/accounts/fireworks/models/deepseek-coder-v2-lite-instruct\":163840,\"fireworks_ai/accounts/fireworks/models/deepseek-prover-v2\":163840,\"fireworks_ai/accounts/fireworks/models/deepseek-r1\":20480,\"fireworks_ai/accounts/fireworks/models/deepseek-r1-0528\":160000,\"fireworks_ai/accounts/fireworks/models/deepseek-r1-0528-distill-qwen3-8b\":131072,\"fireworks_ai/accounts/fireworks/models/deepseek-r1-basic\":20480,\"fireworks_ai/accounts/fireworks/models/deepseek-r1-distill-llama-70b\":131072,\"fireworks_ai/accounts/fireworks/models/deepseek-r1-distill-llama-8b\":131072,\"fireworks_ai/accounts/fireworks/models/deepseek-r1-distill-qwen-14b\":131072,\"fireworks_ai/accounts/fireworks/models/deepseek-r1-distill-qwen-1p5b\":131072,\"fireworks_ai/accounts/fireworks/models/deepseek-r1-distill-qwen-32b\":131072,\"fireworks_ai/accounts/fireworks/models/deepseek-r1-distill-qwen-7b\":131072,\"fireworks_ai/accounts/fireworks/models/deepseek-v2-lite-chat\":163840,\"fireworks_ai/accounts/fireworks/models/deepseek-v2p5\":32768,\"fireworks_ai/accounts/fireworks/models/deepseek-v3\":8192,\"fireworks_ai/accounts/fireworks/models/deepseek-v3-0324\":163840,\"fireworks_ai/accounts/fireworks/models/deepseek-v3p1\":8192,\"fireworks_ai/accounts/fireworks/models/deepseek-v3p1-terminus\":8192,\"fireworks_ai/accounts/fireworks/models/deepseek-v3p2\":163840,\"fireworks_ai/accounts/fireworks/models/devstral-small-2505\":131072,\"fireworks_ai/accounts/fireworks/models/dobby-mini-unhinged-plus-llama-3-1-8b\":131072,\"fireworks_ai/accounts/fireworks/models/dobby-unhinged-llama-3-3-70b-new\":131072,\"fireworks_ai/accounts/fireworks/models/dolphin-2-9-2-qwen2-72b\":131072,\"fireworks_ai/accounts/fireworks/models/dolphin-2p6-mixtral-8x7b\":32768,\"fireworks_ai/accounts/fireworks/models/ernie-4p5-21b-a3b-pt\":4096,\"fireworks_ai/accounts/fireworks/models/ernie-4p5-300b-a47b-pt\":4096,\"fireworks_ai/accounts/fireworks/models/fare-20b\":131072,\"fireworks_ai/accounts/fireworks/models/firefunction-v1\":32768,\"fireworks_ai/accounts/fireworks/models/firefunction-v2\":8192,\"fireworks_ai/accounts/fireworks/models/firellava-13b\":4096,\"fireworks_ai/accounts/fireworks/models/firesearch-ocr-v6\":8192,\"fireworks_ai/accounts/fireworks/models/flux-1-dev\":4096,\"fireworks_ai/accounts/fireworks/models/flux-1-dev-controlnet-union\":4096,\"fireworks_ai/accounts/fireworks/models/flux-1-schnell\":4096,\"fireworks_ai/accounts/fireworks/models/gemma-2b-it\":8192,\"fireworks_ai/accounts/fireworks/models/gemma-3-27b-it\":131072,\"fireworks_ai/accounts/fireworks/models/gemma-7b\":8192,\"fireworks_ai/accounts/fireworks/models/gemma-7b-it\":8192,\"fireworks_ai/accounts/fireworks/models/gemma2-9b-it\":8192,\"fireworks_ai/accounts/fireworks/models/glm-4p5\":96000,\"fireworks_ai/accounts/fireworks/models/glm-4p5-air\":96000,\"fireworks_ai/accounts/fireworks/models/glm-4p5v\":131072,\"fireworks_ai/accounts/fireworks/models/glm-4p6\":202800,\"fireworks_ai/accounts/fireworks/models/glm-4p7\":202800,\"fireworks_ai/accounts/fireworks/models/gpt-oss-120b\":131072,\"fireworks_ai/accounts/fireworks/models/gpt-oss-20b\":131072,\"fireworks_ai/accounts/fireworks/models/gpt-oss-safeguard-120b\":131072,\"fireworks_ai/accounts/fireworks/models/gpt-oss-safeguard-20b\":131072,\"fireworks_ai/accounts/fireworks/models/hermes-2-pro-mistral-7b\":32768,\"fireworks_ai/accounts/fireworks/models/internvl3-38b\":16384,\"fireworks_ai/accounts/fireworks/models/internvl3-78b\":16384,\"fireworks_ai/accounts/fireworks/models/internvl3-8b\":16384,\"fireworks_ai/accounts/fireworks/models/kat-coder\":262144,\"fireworks_ai/accounts/fireworks/models/kat-dev-32b\":131072,\"fireworks_ai/accounts/fireworks/models/kat-dev-72b-exp\":131072,\"fireworks_ai/accounts/fireworks/models/kimi-k2-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/kimi-k2-instruct-0905\":32768,\"fireworks_ai/accounts/fireworks/models/kimi-k2-thinking\":262144,\"fireworks_ai/accounts/fireworks/models/kimi-k2p5\":262144,\"fireworks_ai/accounts/fireworks/models/llama-guard-2-8b\":8192,\"fireworks_ai/accounts/fireworks/models/llama-guard-3-1b\":131072,\"fireworks_ai/accounts/fireworks/models/llama-guard-3-8b\":131072,\"fireworks_ai/accounts/fireworks/models/llama-v2-13b\":4096,\"fireworks_ai/accounts/fireworks/models/llama-v2-13b-chat\":4096,\"fireworks_ai/accounts/fireworks/models/llama-v2-70b\":4096,\"fireworks_ai/accounts/fireworks/models/llama-v2-70b-chat\":2048,\"fireworks_ai/accounts/fireworks/models/llama-v2-7b\":4096,\"fireworks_ai/accounts/fireworks/models/llama-v2-7b-chat\":4096,\"fireworks_ai/accounts/fireworks/models/llama-v3-70b-instruct\":8192,\"fireworks_ai/accounts/fireworks/models/llama-v3-70b-instruct-hf\":8192,\"fireworks_ai/accounts/fireworks/models/llama-v3-8b\":8192,\"fireworks_ai/accounts/fireworks/models/llama-v3-8b-instruct-hf\":8192,\"fireworks_ai/accounts/fireworks/models/llama-v3p1-405b-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/llama-v3p1-405b-instruct-long\":4096,\"fireworks_ai/accounts/fireworks/models/llama-v3p1-70b-instruct\":131072,\"fireworks_ai/accounts/fireworks/models/llama-v3p1-70b-instruct-1b\":4096,\"fireworks_ai/accounts/fireworks/models/llama-v3p1-8b-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/llama-v3p1-nemotron-70b-instruct\":131072,\"fireworks_ai/accounts/fireworks/models/llama-v3p2-11b-vision-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/llama-v3p2-1b\":131072,\"fireworks_ai/accounts/fireworks/models/llama-v3p2-1b-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/llama-v3p2-3b\":131072,\"fireworks_ai/accounts/fireworks/models/llama-v3p2-3b-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/llama-v3p2-90b-vision-instruct\":16384,\"fireworks_ai/accounts/fireworks/models/llama-v3p3-70b-instruct\":131072,\"fireworks_ai/accounts/fireworks/models/llama4-maverick-instruct-basic\":131072,\"fireworks_ai/accounts/fireworks/models/llama4-scout-instruct-basic\":131072,\"fireworks_ai/accounts/fireworks/models/llamaguard-7b\":4096,\"fireworks_ai/accounts/fireworks/models/llava-yi-34b\":4096,\"fireworks_ai/accounts/fireworks/models/minimax-m1-80k\":4096,\"fireworks_ai/accounts/fireworks/models/minimax-m2\":4096,\"fireworks_ai/accounts/fireworks/models/minimax-m2p1\":204800,\"fireworks_ai/accounts/fireworks/models/ministral-3-14b-instruct-2512\":256000,\"fireworks_ai/accounts/fireworks/models/ministral-3-3b-instruct-2512\":256000,\"fireworks_ai/accounts/fireworks/models/ministral-3-8b-instruct-2512\":256000,\"fireworks_ai/accounts/fireworks/models/mistral-7b\":32768,\"fireworks_ai/accounts/fireworks/models/mistral-7b-instruct-4k\":32768,\"fireworks_ai/accounts/fireworks/models/mistral-7b-instruct-v0p2\":32768,\"fireworks_ai/accounts/fireworks/models/mistral-7b-instruct-v3\":32768,\"fireworks_ai/accounts/fireworks/models/mistral-7b-v0p2\":32768,\"fireworks_ai/accounts/fireworks/models/mistral-large-3-fp8\":256000,\"fireworks_ai/accounts/fireworks/models/mistral-nemo-base-2407\":128000,\"fireworks_ai/accounts/fireworks/models/mistral-nemo-instruct-2407\":128000,\"fireworks_ai/accounts/fireworks/models/mistral-small-24b-instruct-2501\":32768,\"fireworks_ai/accounts/fireworks/models/mixtral-8x22b\":65536,\"fireworks_ai/accounts/fireworks/models/mixtral-8x22b-instruct\":65536,\"fireworks_ai/accounts/fireworks/models/mixtral-8x22b-instruct-hf\":65536,\"fireworks_ai/accounts/fireworks/models/mixtral-8x7b\":32768,\"fireworks_ai/accounts/fireworks/models/mixtral-8x7b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/mixtral-8x7b-instruct-hf\":32768,\"fireworks_ai/accounts/fireworks/models/mythomax-l2-13b\":4096,\"fireworks_ai/accounts/fireworks/models/nemotron-nano-v2-12b-vl\":4096,\"fireworks_ai/accounts/fireworks/models/nous-capybara-7b-v1p9\":32768,\"fireworks_ai/accounts/fireworks/models/nous-hermes-2-mixtral-8x7b-dpo\":32768,\"fireworks_ai/accounts/fireworks/models/nous-hermes-2-yi-34b\":4096,\"fireworks_ai/accounts/fireworks/models/nous-hermes-llama2-13b\":4096,\"fireworks_ai/accounts/fireworks/models/nous-hermes-llama2-70b\":4096,\"fireworks_ai/accounts/fireworks/models/nous-hermes-llama2-7b\":4096,\"fireworks_ai/accounts/fireworks/models/nvidia-nemotron-nano-12b-v2\":131072,\"fireworks_ai/accounts/fireworks/models/nvidia-nemotron-nano-9b-v2\":131072,\"fireworks_ai/accounts/fireworks/models/openchat-3p5-0106-7b\":8192,\"fireworks_ai/accounts/fireworks/models/openhermes-2-mistral-7b\":32768,\"fireworks_ai/accounts/fireworks/models/openhermes-2p5-mistral-7b\":32768,\"fireworks_ai/accounts/fireworks/models/openorca-7b\":32768,\"fireworks_ai/accounts/fireworks/models/phi-2-3b\":2048,\"fireworks_ai/accounts/fireworks/models/phi-3-mini-128k-instruct\":131072,\"fireworks_ai/accounts/fireworks/models/phi-3-vision-128k-instruct\":32064,\"fireworks_ai/accounts/fireworks/models/phind-code-llama-34b-python-v1\":16384,\"fireworks_ai/accounts/fireworks/models/phind-code-llama-34b-v1\":16384,\"fireworks_ai/accounts/fireworks/models/phind-code-llama-34b-v2\":16384,\"fireworks_ai/accounts/fireworks/models/pythia-12b\":2048,\"fireworks_ai/accounts/fireworks/models/qwen-qwq-32b-preview\":32768,\"fireworks_ai/accounts/fireworks/models/qwen-v2p5-14b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen-v2p5-7b\":131072,\"fireworks_ai/accounts/fireworks/models/qwen1p5-72b-chat\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2-72b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2-7b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2-vl-2b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2-vl-72b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2-vl-7b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-0p5b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-14b\":131072,\"fireworks_ai/accounts/fireworks/models/qwen2p5-1p5b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-32b\":131072,\"fireworks_ai/accounts/fireworks/models/qwen2p5-32b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-72b\":131072,\"fireworks_ai/accounts/fireworks/models/qwen2p5-72b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-7b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-0p5b\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-0p5b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-14b\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-14b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-1p5b\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-1p5b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct\":4096,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct-128k\":131072,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct-32k-rope\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct-64k\":65536,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-3b\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-3b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-7b\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-coder-7b-instruct\":32768,\"fireworks_ai/accounts/fireworks/models/qwen2p5-math-72b-instruct\":4096,\"fireworks_ai/accounts/fireworks/models/qwen2p5-vl-32b-instruct\":128000,\"fireworks_ai/accounts/fireworks/models/qwen2p5-vl-3b-instruct\":128000,\"fireworks_ai/accounts/fireworks/models/qwen2p5-vl-72b-instruct\":128000,\"fireworks_ai/accounts/fireworks/models/qwen2p5-vl-7b-instruct\":128000,\"fireworks_ai/accounts/fireworks/models/qwen3-0p6b\":40960,\"fireworks_ai/accounts/fireworks/models/qwen3-14b\":40960,\"fireworks_ai/accounts/fireworks/models/qwen3-1p7b\":131072,\"fireworks_ai/accounts/fireworks/models/qwen3-1p7b-fp8-draft\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-1p7b-fp8-draft-131072\":131072,\"fireworks_ai/accounts/fireworks/models/qwen3-1p7b-fp8-draft-40960\":40960,\"fireworks_ai/accounts/fireworks/models/qwen3-235b-a22b\":131072,\"fireworks_ai/accounts/fireworks/models/qwen3-235b-a22b-instruct-2507\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-235b-a22b-thinking-2507\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-30b-a3b\":131072,\"fireworks_ai/accounts/fireworks/models/qwen3-30b-a3b-instruct-2507\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-30b-a3b-thinking-2507\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-32b\":131072,\"fireworks_ai/accounts/fireworks/models/qwen3-4b\":40960,\"fireworks_ai/accounts/fireworks/models/qwen3-4b-instruct-2507\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-8b\":40960,\"fireworks_ai/accounts/fireworks/models/qwen3-coder-30b-a3b-instruct\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-coder-480b-a35b-instruct\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-coder-480b-instruct-bf16\":4096,\"fireworks_ai/accounts/fireworks/models/qwen3-next-80b-a3b-instruct\":4096,\"fireworks_ai/accounts/fireworks/models/qwen3-next-80b-a3b-thinking\":4096,\"fireworks_ai/accounts/fireworks/models/qwen3-vl-235b-a22b-instruct\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-vl-235b-a22b-thinking\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-vl-30b-a3b-instruct\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-vl-30b-a3b-thinking\":262144,\"fireworks_ai/accounts/fireworks/models/qwen3-vl-32b-instruct\":4096,\"fireworks_ai/accounts/fireworks/models/qwen3-vl-8b-instruct\":4096,\"fireworks_ai/accounts/fireworks/models/qwq-32b\":131072,\"fireworks_ai/accounts/fireworks/models/rolm-ocr\":128000,\"fireworks_ai/accounts/fireworks/models/snorkel-mistral-7b-pairrm-dpo\":32768,\"fireworks_ai/accounts/fireworks/models/stablecode-3b\":4096,\"fireworks_ai/accounts/fireworks/models/starcoder-16b\":8192,\"fireworks_ai/accounts/fireworks/models/starcoder-7b\":8192,\"fireworks_ai/accounts/fireworks/models/starcoder2-15b\":16384,\"fireworks_ai/accounts/fireworks/models/starcoder2-3b\":16384,\"fireworks_ai/accounts/fireworks/models/starcoder2-7b\":16384,\"fireworks_ai/accounts/fireworks/models/toppy-m-7b\":32768,\"fireworks_ai/accounts/fireworks/models/yi-34b\":4096,\"fireworks_ai/accounts/fireworks/models/yi-34b-200k-capybara\":200000,\"fireworks_ai/accounts/fireworks/models/yi-34b-chat\":4096,\"fireworks_ai/accounts/fireworks/models/yi-6b\":4096,\"fireworks_ai/accounts/fireworks/models/yi-large\":32768,\"fireworks_ai/accounts/fireworks/models/zephyr-7b-beta\":32768,\"fireworks_ai/glm-4p7\":202800,\"fireworks_ai/kimi-k2p5\":262144,\"fireworks_ai/minimax-m2p1\":204800,\"friendliai/meta-llama-3.1-70b-instruct\":8192,\"friendliai/meta-llama-3.1-8b-instruct\":8192,\"ft:gpt-3.5-turbo\":4096,\"ft:gpt-3.5-turbo-0125\":4096,\"ft:gpt-3.5-turbo-0613\":4096,\"ft:gpt-3.5-turbo-1106\":4096,\"ft:gpt-4-0613\":4096,\"ft:gpt-4.1-2025-04-14\":32768,\"ft:gpt-4.1-mini-2025-04-14\":32768,\"ft:gpt-4.1-nano-2025-04-14\":32768,\"ft:gpt-4o-2024-08-06\":16384,\"ft:gpt-4o-2024-11-20\":16384,\"ft:gpt-4o-mini-2024-07-18\":16384,\"ft:o4-mini-2025-04-16\":100000,\"gemini-2.0-flash\":8192,\"gemini-2.0-flash-001\":8192,\"gemini-2.0-flash-lite\":8192,\"gemini-2.0-flash-lite-001\":8192,\"gemini-2.5-computer-use-preview-10-2025\":64000,\"gemini-2.5-flash\":65535,\"gemini-2.5-flash-lite\":65535,\"gemini-2.5-flash-lite-preview-06-17\":65535,\"gemini-2.5-flash-lite-preview-09-2025\":65535,\"gemini-2.5-flash-native-audio-latest\":8192,\"gemini-2.5-flash-native-audio-preview-09-2025\":8192,\"gemini-2.5-flash-native-audio-preview-12-2025\":8192,\"gemini-2.5-flash-preview-09-2025\":65535,\"gemini-2.5-pro\":65535,\"gemini-2.5-pro-preview-tts\":65535,\"gemini-3-flash-preview\":65535,\"gemini-3-pro-preview\":65535,\"gemini-3.1-flash-lite-preview\":65536,\"gemini-3.1-flash-live-preview\":65536,\"gemini-3.1-pro-preview\":65536,\"gemini-3.1-pro-preview-customtools\":65536,\"gemini-exp-1206\":65535,\"gemini-flash-latest\":65535,\"gemini-flash-lite-latest\":65535,\"gemini-pro-latest\":65535,\"gemini-robotics-er-1.5-preview\":65535,\"gemini/gemini-2.0-flash\":8192,\"gemini/gemini-2.0-flash-001\":8192,\"gemini/gemini-2.0-flash-lite\":8192,\"gemini/gemini-2.0-flash-lite-001\":8192,\"gemini/gemini-2.5-computer-use-preview-10-2025\":64000,\"gemini/gemini-2.5-flash\":65535,\"gemini/gemini-2.5-flash-lite\":65535,\"gemini/gemini-2.5-flash-lite-preview-06-17\":65535,\"gemini/gemini-2.5-flash-lite-preview-09-2025\":65535,\"gemini/gemini-2.5-flash-native-audio-latest\":8192,\"gemini/gemini-2.5-flash-native-audio-preview-09-2025\":8192,\"gemini/gemini-2.5-flash-native-audio-preview-12-2025\":8192,\"gemini/gemini-2.5-flash-preview-09-2025\":65535,\"gemini/gemini-2.5-pro\":65535,\"gemini/gemini-2.5-pro-preview-tts\":65535,\"gemini/gemini-3-flash-preview\":65535,\"gemini/gemini-3-pro-preview\":65535,\"gemini/gemini-3.1-flash-lite-preview\":65536,\"gemini/gemini-3.1-flash-live-preview\":65536,\"gemini/gemini-3.1-pro-preview\":65536,\"gemini/gemini-3.1-pro-preview-customtools\":65536,\"gemini/gemini-exp-1114\":8192,\"gemini/gemini-exp-1206\":8192,\"gemini/gemini-flash-latest\":65535,\"gemini/gemini-flash-lite-latest\":65535,\"gemini/gemini-gemma-2-27b-it\":8192,\"gemini/gemini-gemma-2-9b-it\":8192,\"gemini/gemini-pro-latest\":65535,\"gemini/gemini-robotics-er-1.5-preview\":65535,\"gemini/gemma-3-27b-it\":8192,\"gemini/learnlm-1.5-pro-experimental\":8192,\"gemini/lyria-3-clip-preview\":8192,\"gemini/lyria-3-pro-preview\":8192,\"gigachat/GigaChat-2-Lite\":8192,\"gigachat/GigaChat-2-Max\":8192,\"gigachat/GigaChat-2-Pro\":8192,\"github_copilot/claude-haiku-4.5\":16000,\"github_copilot/claude-opus-4.5\":16000,\"github_copilot/claude-opus-4.6-fast\":16000,\"github_copilot/claude-opus-41\":16000,\"github_copilot/claude-sonnet-4\":16000,\"github_copilot/claude-sonnet-4.5\":16000,\"github_copilot/gemini-2.5-pro\":64000,\"github_copilot/gemini-3-pro-preview\":64000,\"github_copilot/gpt-3.5-turbo\":4096,\"github_copilot/gpt-3.5-turbo-0613\":4096,\"github_copilot/gpt-4\":4096,\"github_copilot/gpt-4-0613\":4096,\"github_copilot/gpt-4-o-preview\":4096,\"github_copilot/gpt-4.1\":16384,\"github_copilot/gpt-4.1-2025-04-14\":16384,\"github_copilot/gpt-4o\":4096,\"github_copilot/gpt-4o-2024-05-13\":4096,\"github_copilot/gpt-4o-2024-08-06\":16384,\"github_copilot/gpt-4o-2024-11-20\":16384,\"github_copilot/gpt-4o-mini\":4096,\"github_copilot/gpt-4o-mini-2024-07-18\":4096,\"github_copilot/gpt-5\":128000,\"github_copilot/gpt-5-mini\":64000,\"github_copilot/gpt-5.1\":64000,\"github_copilot/gpt-5.2\":64000,\"glm-4-7-251222\":131072,\"global.amazon.nova-2-lite-v1:0\":64000,\"global.anthropic.claude-haiku-4-5-20251001-v1:0\":64000,\"global.anthropic.claude-opus-4-5-20251101-v1:0\":64000,\"global.anthropic.claude-opus-4-6-v1\":128000,\"global.anthropic.claude-opus-4-7\":128000,\"global.anthropic.claude-sonnet-4-20250514-v1:0\":64000,\"global.anthropic.claude-sonnet-4-5-20250929-v1:0\":64000,\"global.anthropic.claude-sonnet-4-6\":64000,\"gmi/anthropic/claude-opus-4\":32000,\"gmi/anthropic/claude-opus-4.5\":32000,\"gmi/anthropic/claude-sonnet-4\":32000,\"gmi/anthropic/claude-sonnet-4.5\":32000,\"gmi/deepseek-ai/DeepSeek-V3-0324\":16384,\"gmi/deepseek-ai/DeepSeek-V3.2\":16384,\"gmi/google/gemini-3-flash-preview\":65536,\"gmi/google/gemini-3-pro-preview\":65536,\"gmi/MiniMaxAI/MiniMax-M2.1\":16384,\"gmi/moonshotai/Kimi-K2-Thinking\":16384,\"gmi/openai/gpt-4o\":16384,\"gmi/openai/gpt-4o-mini\":16384,\"gmi/openai/gpt-5\":32000,\"gmi/openai/gpt-5.1\":32000,\"gmi/openai/gpt-5.2\":32000,\"gmi/Qwen/Qwen3-VL-235B-A22B-Instruct-FP8\":16384,\"gmi/zai-org/GLM-4.7-FP8\":16384,\"google.gemma-3-12b-it\":8192,\"google.gemma-3-27b-it\":8192,\"google.gemma-3-4b-it\":8192,\"gpt-3.5-turbo\":4096,\"gpt-3.5-turbo-0125\":4096,\"gpt-3.5-turbo-1106\":4096,\"gpt-3.5-turbo-16k\":4096,\"gpt-4\":4096,\"gpt-4-0125-preview\":4096,\"gpt-4-0314\":4096,\"gpt-4-0613\":4096,\"gpt-4-1106-preview\":4096,\"gpt-4-turbo\":4096,\"gpt-4-turbo-2024-04-09\":4096,\"gpt-4-turbo-preview\":4096,\"gpt-4.1\":32768,\"gpt-4.1-2025-04-14\":32768,\"gpt-4.1-mini\":32768,\"gpt-4.1-mini-2025-04-14\":32768,\"gpt-4.1-nano\":32768,\"gpt-4.1-nano-2025-04-14\":32768,\"gpt-4o\":16384,\"gpt-4o-2024-05-13\":4096,\"gpt-4o-2024-08-06\":16384,\"gpt-4o-2024-11-20\":16384,\"gpt-4o-audio-preview\":16384,\"gpt-4o-audio-preview-2024-12-17\":16384,\"gpt-4o-audio-preview-2025-06-03\":16384,\"gpt-4o-mini\":16384,\"gpt-4o-mini-2024-07-18\":16384,\"gpt-4o-mini-audio-preview\":16384,\"gpt-4o-mini-audio-preview-2024-12-17\":16384,\"gpt-4o-mini-realtime-preview\":4096,\"gpt-4o-mini-realtime-preview-2024-12-17\":4096,\"gpt-4o-mini-search-preview\":16384,\"gpt-4o-mini-search-preview-2025-03-11\":16384,\"gpt-4o-realtime-preview\":4096,\"gpt-4o-realtime-preview-2024-12-17\":4096,\"gpt-4o-realtime-preview-2025-06-03\":4096,\"gpt-4o-search-preview\":16384,\"gpt-4o-search-preview-2025-03-11\":16384,\"gpt-5\":128000,\"gpt-5-2025-08-07\":128000,\"gpt-5-chat\":16384,\"gpt-5-chat-latest\":16384,\"gpt-5-mini\":128000,\"gpt-5-mini-2025-08-07\":128000,\"gpt-5-nano\":128000,\"gpt-5-nano-2025-08-07\":128000,\"gpt-5-search-api\":128000,\"gpt-5-search-api-2025-10-14\":128000,\"gpt-5.1\":128000,\"gpt-5.1-2025-11-13\":128000,\"gpt-5.1-chat-latest\":16384,\"gpt-5.2\":128000,\"gpt-5.2-2025-12-11\":128000,\"gpt-5.2-chat-latest\":16384,\"gpt-5.3-chat-latest\":16384,\"gpt-5.4\":128000,\"gpt-5.4-2026-03-05\":128000,\"gpt-5.4-mini\":128000,\"gpt-5.4-mini-2026-03-17\":128000,\"gpt-5.4-nano\":128000,\"gpt-5.4-nano-2026-03-17\":128000,\"gpt-5.5\":128000,\"gpt-5.5-2026-04-23\":128000,\"gpt-audio\":16384,\"gpt-audio-1.5\":16384,\"gpt-audio-2025-08-28\":16384,\"gpt-audio-mini\":16384,\"gpt-audio-mini-2025-10-06\":16384,\"gpt-audio-mini-2025-12-15\":16384,\"gpt-realtime\":4096,\"gpt-realtime-1.5\":4096,\"gpt-realtime-2025-08-28\":4096,\"gpt-realtime-mini\":4096,\"gpt-realtime-mini-2025-10-06\":4096,\"gpt-realtime-mini-2025-12-15\":4096,\"gradient_ai/alibaba-qwen3-32b\":40960,\"gradient_ai/anthropic-claude-3-opus\":1024,\"gradient_ai/anthropic-claude-3.5-haiku\":1024,\"gradient_ai/anthropic-claude-3.5-sonnet\":1024,\"gradient_ai/anthropic-claude-3.7-sonnet\":1024,\"gradient_ai/deepseek-r1-distill-llama-70b\":8000,\"gradient_ai/llama3-8b-instruct\":512,\"gradient_ai/llama3.3-70b-instruct\":2048,\"gradient_ai/mistral-nemo-instruct-2407\":512,\"gradient_ai/openai-gpt-4o\":16384,\"gradient_ai/openai-gpt-4o-mini\":16384,\"gradient_ai/openai-o3\":100000,\"gradient_ai/openai-o3-mini\":100000,\"groq/gemma-7b-it\":8192,\"groq/llama-3.1-8b-instant\":8192,\"groq/llama-3.3-70b-versatile\":32768,\"groq/meta-llama/llama-4-maverick-17b-128e-instruct\":8192,\"groq/meta-llama/llama-4-scout-17b-16e-instruct\":8192,\"groq/meta-llama/llama-guard-4-12b\":8192,\"groq/moonshotai/kimi-k2-instruct-0905\":16384,\"groq/openai/gpt-oss-120b\":32766,\"groq/openai/gpt-oss-20b\":32768,\"groq/openai/gpt-oss-safeguard-20b\":65536,\"groq/qwen/qwen3-32b\":131000,\"heroku/claude-3-5-haiku\":8192,\"heroku/claude-3-5-sonnet-latest\":8192,\"heroku/claude-3-7-sonnet\":8192,\"heroku/claude-4-sonnet\":8192,\"hyperbolic/deepseek-ai/DeepSeek-R1\":32768,\"hyperbolic/deepseek-ai/DeepSeek-R1-0528\":131072,\"hyperbolic/deepseek-ai/DeepSeek-V3\":32768,\"hyperbolic/deepseek-ai/DeepSeek-V3-0324\":32768,\"hyperbolic/meta-llama/Llama-3.2-3B-Instruct\":32768,\"hyperbolic/meta-llama/Llama-3.3-70B-Instruct\":131072,\"hyperbolic/meta-llama/Meta-Llama-3-70B-Instruct\":131072,\"hyperbolic/meta-llama/Meta-Llama-3.1-405B-Instruct\":32768,\"hyperbolic/meta-llama/Meta-Llama-3.1-70B-Instruct\":32768,\"hyperbolic/meta-llama/Meta-Llama-3.1-8B-Instruct\":32768,\"hyperbolic/moonshotai/Kimi-K2-Instruct\":131072,\"hyperbolic/NousResearch/Hermes-3-Llama-3.1-70B\":32768,\"hyperbolic/Qwen/Qwen2.5-72B-Instruct\":131072,\"hyperbolic/Qwen/Qwen2.5-Coder-32B-Instruct\":32768,\"hyperbolic/Qwen/Qwen3-235B-A22B\":131072,\"hyperbolic/Qwen/QwQ-32B\":131072,\"jamba-1.5\":256000,\"jamba-1.5-large\":256000,\"jamba-1.5-large@001\":256000,\"jamba-1.5-mini\":256000,\"jamba-1.5-mini@001\":256000,\"jamba-large-1.6\":256000,\"jamba-large-1.7\":256000,\"jamba-mini-1.6\":256000,\"jamba-mini-1.7\":256000,\"jp.anthropic.claude-haiku-4-5-20251001-v1:0\":64000,\"jp.anthropic.claude-sonnet-4-5-20250929-v1:0\":64000,\"kimi-k2-thinking-251104\":32768,\"lambda_ai/deepseek-llama3.3-70b\":131072,\"lambda_ai/deepseek-r1-0528\":131072,\"lambda_ai/deepseek-r1-671b\":131072,\"lambda_ai/deepseek-v3-0324\":131072,\"lambda_ai/hermes3-405b\":131072,\"lambda_ai/hermes3-70b\":131072,\"lambda_ai/hermes3-8b\":131072,\"lambda_ai/lfm-40b\":131072,\"lambda_ai/lfm-7b\":131072,\"lambda_ai/llama-4-maverick-17b-128e-instruct-fp8\":8192,\"lambda_ai/llama-4-scout-17b-16e-instruct\":8192,\"lambda_ai/llama3.1-405b-instruct-fp8\":131072,\"lambda_ai/llama3.1-70b-instruct-fp8\":131072,\"lambda_ai/llama3.1-8b-instruct\":131072,\"lambda_ai/llama3.1-nemotron-70b-instruct-fp8\":131072,\"lambda_ai/llama3.2-11b-vision-instruct\":131072,\"lambda_ai/llama3.2-3b-instruct\":131072,\"lambda_ai/llama3.3-70b-instruct-fp8\":131072,\"lambda_ai/qwen25-coder-32b-instruct\":131072,\"lambda_ai/qwen3-32b-fp8\":131072,\"lemonade/Gemma-3-4b-it-GGUF\":8192,\"lemonade/gpt-oss-120b-mxfp-GGUF\":32768,\"lemonade/gpt-oss-20b-mxfp4-GGUF\":32768,\"lemonade/Qwen3-4B-Instruct-2507-GGUF\":32768,\"lemonade/Qwen3-Coder-30B-A3B-Instruct-GGUF\":32768,\"llamagate/codellama-7b\":4096,\"llamagate/deepseek-coder-6.7b\":4096,\"llamagate/deepseek-r1-7b-qwen\":16384,\"llamagate/deepseek-r1-8b\":16384,\"llamagate/dolphin3-8b\":8192,\"llamagate/gemma3-4b\":8192,\"llamagate/llama-3.1-8b\":8192,\"llamagate/llama-3.2-3b\":8192,\"llamagate/llava-7b\":2048,\"llamagate/mistral-7b-v0.3\":8192,\"llamagate/openthinker-7b\":8192,\"llamagate/qwen2.5-coder-7b\":8192,\"llamagate/qwen3-8b\":8192,\"llamagate/qwen3-vl-8b\":8192,\"medlm-large\":1024,\"medlm-medium\":8192,\"meta_llama/Llama-3.3-70B-Instruct\":4028,\"meta_llama/Llama-3.3-8B-Instruct\":4028,\"meta_llama/Llama-4-Maverick-17B-128E-Instruct-FP8\":4028,\"meta_llama/Llama-4-Scout-17B-16E-Instruct-FP8\":4028,\"meta.llama2-13b-chat-v1\":4096,\"meta.llama2-70b-chat-v1\":4096,\"meta.llama3-1-405b-instruct-v1:0\":4096,\"meta.llama3-1-70b-instruct-v1:0\":2048,\"meta.llama3-1-8b-instruct-v1:0\":2048,\"meta.llama3-2-11b-instruct-v1:0\":4096,\"meta.llama3-2-1b-instruct-v1:0\":4096,\"meta.llama3-2-3b-instruct-v1:0\":4096,\"meta.llama3-2-90b-instruct-v1:0\":4096,\"meta.llama3-3-70b-instruct-v1:0\":4096,\"meta.llama3-70b-instruct-v1:0\":8192,\"meta.llama3-8b-instruct-v1:0\":8192,\"meta.llama4-maverick-17b-instruct-v1:0\":4096,\"meta.llama4-scout-17b-instruct-v1:0\":4096,\"minimax.minimax-m2\":8192,\"minimax.minimax-m2.1\":8192,\"minimax.minimax-m2.5\":8192,\"minimax/MiniMax-M2\":8192,\"minimax/MiniMax-M2.1\":8192,\"minimax/MiniMax-M2.1-lightning\":8192,\"minimax/MiniMax-M2.5\":8192,\"minimax/MiniMax-M2.5-lightning\":8192,\"mistral.devstral-2-123b\":8192,\"mistral.magistral-small-2509\":8192,\"mistral.ministral-3-14b-instruct\":8192,\"mistral.ministral-3-3b-instruct\":8192,\"mistral.ministral-3-8b-instruct\":8192,\"mistral.mistral-7b-instruct-v0:2\":8191,\"mistral.mistral-large-2402-v1:0\":8191,\"mistral.mistral-large-2407-v1:0\":8191,\"mistral.mistral-large-3-675b-instruct\":8192,\"mistral.mistral-small-2402-v1:0\":8191,\"mistral.mixtral-8x7b-instruct-v0:1\":8191,\"mistral.voxtral-mini-3b-2507\":8192,\"mistral.voxtral-small-24b-2507\":8192,\"mistral/codestral-2405\":8191,\"mistral/codestral-2508\":256000,\"mistral/codestral-latest\":8191,\"mistral/codestral-mamba-latest\":256000,\"mistral/devstral-2512\":256000,\"mistral/devstral-latest\":256000,\"mistral/devstral-medium-2507\":128000,\"mistral/devstral-medium-latest\":256000,\"mistral/devstral-small-2505\":128000,\"mistral/devstral-small-2507\":128000,\"mistral/devstral-small-latest\":256000,\"mistral/labs-devstral-small-2512\":256000,\"mistral/magistral-medium-1-2-2509\":40000,\"mistral/magistral-medium-2506\":40000,\"mistral/magistral-medium-2509\":40000,\"mistral/magistral-medium-latest\":40000,\"mistral/magistral-small-1-2-2509\":40000,\"mistral/magistral-small-2506\":40000,\"mistral/magistral-small-latest\":40000,\"mistral/ministral-3-14b-2512\":262144,\"mistral/ministral-3-3b-2512\":131072,\"mistral/ministral-3-8b-2512\":262144,\"mistral/mistral-large-2402\":8191,\"mistral/mistral-large-2407\":128000,\"mistral/mistral-large-2411\":128000,\"mistral/mistral-large-2512\":262144,\"mistral/mistral-large-3\":262144,\"mistral/mistral-large-latest\":262144,\"mistral/mistral-medium\":8191,\"mistral/mistral-medium-2312\":8191,\"mistral/mistral-medium-2505\":8191,\"mistral/mistral-medium-3-1-2508\":131072,\"mistral/mistral-medium-latest\":131072,\"mistral/mistral-small\":8191,\"mistral/mistral-small-3-2-2506\":131072,\"mistral/mistral-small-latest\":131072,\"mistral/mistral-tiny\":8191,\"mistral/open-codestral-mamba\":256000,\"mistral/open-mistral-7b\":8191,\"mistral/open-mistral-nemo\":128000,\"mistral/open-mistral-nemo-2407\":128000,\"mistral/open-mixtral-8x22b\":8191,\"mistral/open-mixtral-8x7b\":8191,\"mistral/pixtral-12b-2409\":128000,\"mistral/pixtral-large-2411\":128000,\"mistral/pixtral-large-latest\":128000,\"moonshot.kimi-k2-thinking\":8192,\"moonshot/kimi-k2-0711-preview\":131072,\"moonshot/kimi-k2-0905-preview\":262144,\"moonshot/kimi-k2-thinking\":262144,\"moonshot/kimi-k2-thinking-turbo\":262144,\"moonshot/kimi-k2-turbo-preview\":262144,\"moonshot/kimi-k2.5\":262144,\"moonshot/kimi-k2.6\":262144,\"moonshot/kimi-latest\":131072,\"moonshot/kimi-latest-128k\":131072,\"moonshot/kimi-latest-32k\":32768,\"moonshot/kimi-latest-8k\":8192,\"moonshot/kimi-thinking-preview\":131072,\"moonshot/moonshot-v1-128k\":131072,\"moonshot/moonshot-v1-128k-0430\":131072,\"moonshot/moonshot-v1-128k-vision-preview\":131072,\"moonshot/moonshot-v1-32k\":32768,\"moonshot/moonshot-v1-32k-0430\":32768,\"moonshot/moonshot-v1-32k-vision-preview\":32768,\"moonshot/moonshot-v1-8k\":8192,\"moonshot/moonshot-v1-8k-0430\":8192,\"moonshot/moonshot-v1-8k-vision-preview\":8192,\"moonshot/moonshot-v1-auto\":131072,\"moonshotai.kimi-k2.5\":262144,\"morph/morph-v3-fast\":16000,\"morph/morph-v3-large\":16000,\"nebius/deepseek-ai/DeepSeek-R1\":128000,\"nebius/deepseek-ai/DeepSeek-R1-0528\":164000,\"nebius/deepseek-ai/DeepSeek-R1-Distill-Llama-70B\":128000,\"nebius/deepseek-ai/DeepSeek-V3\":128000,\"nebius/deepseek-ai/DeepSeek-V3-0324\":128000,\"nebius/google/gemma-3-27b-it\":128000,\"nebius/meta-llama/Llama-3.3-70B-Instruct\":128000,\"nebius/meta-llama/Llama-Guard-3-8B\":128000,\"nebius/meta-llama/Meta-Llama-3.1-405B-Instruct\":128000,\"nebius/meta-llama/Meta-Llama-3.1-70B-Instruct\":128000,\"nebius/meta-llama/Meta-Llama-3.1-8B-Instruct\":128000,\"nebius/mistralai/Mistral-Nemo-Instruct-2407\":128000,\"nebius/NousResearch/Hermes-3-Llama-3.1-405B\":128000,\"nebius/nvidia/Llama-3.1-Nemotron-Ultra-253B-v1\":128000,\"nebius/nvidia/Llama-3.3-Nemotron-Super-49B-v1\":131072,\"nebius/Qwen/Qwen2-VL-72B-Instruct\":131072,\"nebius/Qwen/Qwen2-VL-7B-Instruct\":131072,\"nebius/Qwen/Qwen2.5-32B-Instruct\":128000,\"nebius/Qwen/Qwen2.5-72B-Instruct\":128000,\"nebius/Qwen/Qwen2.5-Coder-7B\":32768,\"nebius/Qwen/Qwen2.5-VL-72B-Instruct\":131072,\"nebius/Qwen/Qwen3-14B\":32768,\"nebius/Qwen/Qwen3-235B-A22B\":262144,\"nebius/Qwen/Qwen3-30B-A3B\":32768,\"nebius/Qwen/Qwen3-32B\":32768,\"nebius/Qwen/Qwen3-4B\":32768,\"nebius/Qwen/QwQ-32B\":32768,\"novita/baichuan/baichuan-m2-32b\":131072,\"novita/baidu/ernie-4.5-21B-a3b\":8000,\"novita/baidu/ernie-4.5-21B-a3b-thinking\":65536,\"novita/baidu/ernie-4.5-300b-a47b-paddle\":12000,\"novita/baidu/ernie-4.5-vl-28b-a3b\":8000,\"novita/baidu/ernie-4.5-vl-28b-a3b-thinking\":65536,\"novita/baidu/ernie-4.5-vl-424b-a47b\":16000,\"novita/deepseek/deepseek-ocr\":8192,\"novita/deepseek/deepseek-prover-v2-671b\":160000,\"novita/deepseek/deepseek-r1-0528\":32768,\"novita/deepseek/deepseek-r1-0528-qwen3-8b\":32000,\"novita/deepseek/deepseek-r1-distill-llama-70b\":8192,\"novita/deepseek/deepseek-r1-distill-qwen-14b\":16384,\"novita/deepseek/deepseek-r1-distill-qwen-32b\":32000,\"novita/deepseek/deepseek-r1-turbo\":16000,\"novita/deepseek/deepseek-v3-0324\":163840,\"novita/deepseek/deepseek-v3-turbo\":16000,\"novita/deepseek/deepseek-v3.1\":32768,\"novita/deepseek/deepseek-v3.1-terminus\":32768,\"novita/deepseek/deepseek-v3.2\":65536,\"novita/deepseek/deepseek-v3.2-exp\":65536,\"novita/google/gemma-3-12b-it\":8192,\"novita/google/gemma-3-27b-it\":16384,\"novita/gryphe/mythomax-l2-13b\":3200,\"novita/kwaipilot/kat-coder-pro\":128000,\"novita/meta-llama/llama-3-70b-instruct\":8000,\"novita/meta-llama/llama-3-8b-instruct\":8192,\"novita/meta-llama/llama-3.1-8b-instruct\":16384,\"novita/meta-llama/llama-3.2-3b-instruct\":32000,\"novita/meta-llama/llama-3.3-70b-instruct\":120000,\"novita/meta-llama/llama-4-maverick-17b-128e-instruct-fp8\":8192,\"novita/meta-llama/llama-4-scout-17b-16e-instruct\":131072,\"novita/microsoft/wizardlm-2-8x22b\":8000,\"novita/minimax/minimax-m2\":131072,\"novita/minimax/minimax-m2.1\":131072,\"novita/minimaxai/minimax-m1-80k\":40000,\"novita/mistralai/mistral-nemo\":16000,\"novita/moonshotai/kimi-k2-0905\":262144,\"novita/moonshotai/kimi-k2-instruct\":131072,\"novita/moonshotai/kimi-k2-thinking\":262144,\"novita/nousresearch/hermes-2-pro-llama-3-8b\":8192,\"novita/openai/gpt-oss-120b\":32768,\"novita/openai/gpt-oss-20b\":32768,\"novita/paddlepaddle/paddleocr-vl\":16384,\"novita/qwen/qwen-2.5-72b-instruct\":8192,\"novita/qwen/qwen-mt-plus\":8192,\"novita/qwen/qwen2.5-7b-instruct\":32000,\"novita/qwen/qwen2.5-vl-72b-instruct\":32768,\"novita/qwen/qwen3-235b-a22b-fp8\":20000,\"novita/qwen/qwen3-235b-a22b-instruct-2507\":16384,\"novita/qwen/qwen3-235b-a22b-thinking-2507\":32768,\"novita/qwen/qwen3-30b-a3b-fp8\":20000,\"novita/qwen/qwen3-32b-fp8\":20000,\"novita/qwen/qwen3-4b-fp8\":20000,\"novita/qwen/qwen3-8b-fp8\":20000,\"novita/qwen/qwen3-coder-30b-a3b-instruct\":32768,\"novita/qwen/qwen3-coder-480b-a35b-instruct\":65536,\"novita/qwen/qwen3-max\":65536,\"novita/qwen/qwen3-next-80b-a3b-instruct\":32768,\"novita/qwen/qwen3-next-80b-a3b-thinking\":32768,\"novita/qwen/qwen3-omni-30b-a3b-instruct\":16384,\"novita/qwen/qwen3-omni-30b-a3b-thinking\":16384,\"novita/qwen/qwen3-vl-235b-a22b-instruct\":32768,\"novita/qwen/qwen3-vl-235b-a22b-thinking\":32768,\"novita/qwen/qwen3-vl-30b-a3b-instruct\":32768,\"novita/qwen/qwen3-vl-30b-a3b-thinking\":32768,\"novita/qwen/qwen3-vl-8b-instruct\":32768,\"novita/sao10k/l3-70b-euryale-v2.1\":8192,\"novita/sao10k/l3-8b-lunaris\":8192,\"novita/Sao10K/L3-8B-Stheno-v3.2\":32000,\"novita/sao10k/l31-70b-euryale-v2.2\":8192,\"novita/skywork/r1v4-lite\":65536,\"novita/xiaomimimo/mimo-v2-flash\":32000,\"novita/zai-org/autoglm-phone-9b-multilingual\":65536,\"novita/zai-org/glm-4.5\":98304,\"novita/zai-org/glm-4.5-air\":98304,\"novita/zai-org/glm-4.5v\":16384,\"novita/zai-org/glm-4.6\":131072,\"novita/zai-org/glm-4.6v\":32768,\"novita/zai-org/glm-4.7\":131072,\"nvidia.nemotron-nano-12b-v2\":8192,\"nvidia.nemotron-nano-3-30b\":8192,\"nvidia.nemotron-nano-9b-v2\":8192,\"nvidia.nemotron-super-3-120b\":32768,\"o1\":100000,\"o1-2024-12-17\":100000,\"o3\":100000,\"o3-2025-04-16\":100000,\"o3-mini\":100000,\"o3-mini-2025-01-31\":100000,\"o4-mini\":100000,\"o4-mini-2025-04-16\":100000,\"oci/cohere.command-a-03-2025\":4000,\"oci/cohere.command-a-reasoning-08-2025\":4000,\"oci/cohere.command-a-translate-08-2025\":4000,\"oci/cohere.command-a-vision-07-2025\":4000,\"oci/cohere.command-latest\":4000,\"oci/cohere.command-plus-latest\":4000,\"oci/cohere.command-r-08-2024\":4000,\"oci/cohere.command-r-plus-08-2024\":4000,\"oci/google.gemini-2.5-flash\":65536,\"oci/google.gemini-2.5-flash-lite\":65536,\"oci/google.gemini-2.5-pro\":65536,\"oci/meta.llama-3.1-405b-instruct\":4000,\"oci/meta.llama-3.1-70b-instruct\":4000,\"oci/meta.llama-3.2-11b-vision-instruct\":4000,\"oci/meta.llama-3.2-90b-vision-instruct\":4000,\"oci/meta.llama-3.3-70b-instruct\":4000,\"oci/meta.llama-3.3-70b-instruct-fp8-dynamic\":4000,\"oci/meta.llama-4-maverick-17b-128e-instruct-fp8\":4000,\"oci/meta.llama-4-scout-17b-16e-instruct\":4000,\"oci/xai.grok-3\":131072,\"oci/xai.grok-3-fast\":131072,\"oci/xai.grok-3-mini\":131072,\"oci/xai.grok-3-mini-fast\":131072,\"oci/xai.grok-4\":128000,\"oci/xai.grok-4-fast\":131072,\"oci/xai.grok-4.1-fast\":131072,\"oci/xai.grok-4.20\":131072,\"oci/xai.grok-4.20-multi-agent\":131072,\"oci/xai.grok-code-fast-1\":131072,\"ollama/codegeex4\":8192,\"ollama/deepseek-coder-v2-instruct\":8192,\"ollama/deepseek-coder-v2-lite-instruct\":8192,\"ollama/deepseek-v3.1:671b-cloud\":163840,\"ollama/gpt-oss:120b-cloud\":131072,\"ollama/gpt-oss:20b-cloud\":131072,\"ollama/internlm2_5-20b-chat\":8192,\"ollama/llama2\":4096,\"ollama/llama2:13b\":4096,\"ollama/llama2:70b\":4096,\"ollama/llama2:7b\":4096,\"ollama/llama3\":8192,\"ollama/llama3:70b\":8192,\"ollama/llama3:8b\":8192,\"ollama/llama3.1\":8192,\"ollama/mistral-7B-Instruct-v0.1\":8192,\"ollama/mistral-7B-Instruct-v0.2\":32768,\"ollama/mistral-large-instruct-2407\":8192,\"ollama/mixtral-8x22B-Instruct-v0.1\":65536,\"ollama/mixtral-8x7B-Instruct-v0.1\":32768,\"ollama/qwen3-coder:480b-cloud\":262144,\"openai.gpt-oss-120b-1:0\":128000,\"openai.gpt-oss-20b-1:0\":128000,\"openai.gpt-oss-safeguard-120b\":8192,\"openai.gpt-oss-safeguard-20b\":8192,\"openrouter/anthropic/claude-3-haiku\":4096,\"openrouter/anthropic/claude-3.5-sonnet\":8192,\"openrouter/anthropic/claude-3.7-sonnet\":128000,\"openrouter/anthropic/claude-haiku-4.5\":200000,\"openrouter/anthropic/claude-opus-4\":32000,\"openrouter/anthropic/claude-opus-4.1\":32000,\"openrouter/anthropic/claude-opus-4.5\":32000,\"openrouter/anthropic/claude-opus-4.6\":128000,\"openrouter/anthropic/claude-opus-4.7\":128000,\"openrouter/anthropic/claude-sonnet-4\":64000,\"openrouter/anthropic/claude-sonnet-4.5\":1000000,\"openrouter/anthropic/claude-sonnet-4.6\":128000,\"openrouter/bytedance/ui-tars-1.5-7b\":2048,\"openrouter/deepseek/deepseek-chat\":8192,\"openrouter/deepseek/deepseek-chat-v3-0324\":8192,\"openrouter/deepseek/deepseek-chat-v3.1\":163840,\"openrouter/deepseek/deepseek-r1\":8192,\"openrouter/deepseek/deepseek-r1-0528\":8192,\"openrouter/deepseek/deepseek-v3.2\":163840,\"openrouter/deepseek/deepseek-v3.2-exp\":163840,\"openrouter/google/gemini-2.0-flash-001\":8192,\"openrouter/google/gemini-2.5-flash\":8192,\"openrouter/google/gemini-2.5-pro\":8192,\"openrouter/google/gemini-3-flash-preview\":65535,\"openrouter/google/gemini-3-pro-preview\":65535,\"openrouter/google/gemini-3.1-flash-lite-preview\":65536,\"openrouter/google/gemini-3.1-pro-preview\":65536,\"openrouter/gryphe/mythomax-l2-13b\":8192,\"openrouter/mancer/weaver\":2000,\"openrouter/meta-llama/llama-3-70b-instruct\":8000,\"openrouter/minimax/minimax-m2\":204800,\"openrouter/minimax/minimax-m2.1\":64000,\"openrouter/minimax/minimax-m2.5\":65536,\"openrouter/mistralai/devstral-2512\":65536,\"openrouter/mistralai/ministral-14b-2512\":262144,\"openrouter/mistralai/ministral-3b-2512\":131072,\"openrouter/mistralai/ministral-8b-2512\":262144,\"openrouter/mistralai/mistral-7b-instruct\":8191,\"openrouter/mistralai/mistral-large\":8191,\"openrouter/mistralai/mistral-large-2512\":262144,\"openrouter/mistralai/mistral-small-3.1-24b-instruct\":131072,\"openrouter/mistralai/mistral-small-3.2-24b-instruct\":128000,\"openrouter/mistralai/mixtral-8x22b-instruct\":65536,\"openrouter/moonshotai/kimi-k2.5\":262144,\"openrouter/openai/gpt-3.5-turbo\":4096,\"openrouter/openai/gpt-3.5-turbo-16k\":4096,\"openrouter/openai/gpt-4\":4096,\"openrouter/openai/gpt-4.1\":32768,\"openrouter/openai/gpt-4.1-mini\":32768,\"openrouter/openai/gpt-4.1-nano\":32768,\"openrouter/openai/gpt-4o\":4096,\"openrouter/openai/gpt-4o-2024-05-13\":4096,\"openrouter/openai/gpt-5\":128000,\"openrouter/openai/gpt-5-chat\":16384,\"openrouter/openai/gpt-5-codex\":128000,\"openrouter/openai/gpt-5-mini\":128000,\"openrouter/openai/gpt-5-nano\":128000,\"openrouter/openai/gpt-5.1-codex-max\":128000,\"openrouter/openai/gpt-5.2\":128000,\"openrouter/openai/gpt-5.2-chat\":16384,\"openrouter/openai/gpt-5.2-codex\":128000,\"openrouter/openai/gpt-5.2-pro\":128000,\"openrouter/openai/gpt-oss-120b\":32768,\"openrouter/openai/gpt-oss-20b\":32768,\"openrouter/openai/o1\":100000,\"openrouter/openai/o3-mini\":65536,\"openrouter/openai/o3-mini-high\":65536,\"openrouter/openrouter/auto\":2000000,\"openrouter/openrouter/bodybuilder\":128000,\"openrouter/openrouter/free\":200000,\"openrouter/qwen/qwen-2.5-coder-32b-instruct\":33792,\"openrouter/qwen/qwen-vl-plus\":2048,\"openrouter/qwen/qwen3-235b-a22b-2507\":262144,\"openrouter/qwen/qwen3-235b-a22b-thinking-2507\":262144,\"openrouter/qwen/qwen3-coder\":262100,\"openrouter/qwen/qwen3-coder-plus\":65536,\"openrouter/qwen/qwen3.5-122b-a10b\":65536,\"openrouter/qwen/qwen3.5-27b\":65536,\"openrouter/qwen/qwen3.5-35b-a3b\":65536,\"openrouter/qwen/qwen3.5-397b-a17b\":65536,\"openrouter/qwen/qwen3.5-flash-02-23\":65536,\"openrouter/qwen/qwen3.5-plus-02-15\":65536,\"openrouter/switchpoint/router\":131072,\"openrouter/undi95/remm-slerp-l2-13b\":4096,\"openrouter/x-ai/grok-4\":256000,\"openrouter/xiaomi/mimo-v2-flash\":16384,\"openrouter/z-ai/glm-4.6\":131000,\"openrouter/z-ai/glm-4.6:exacto\":131000,\"openrouter/z-ai/glm-4.7\":64000,\"openrouter/z-ai/glm-4.7-flash\":32000,\"openrouter/z-ai/glm-5\":128000,\"ovhcloud/DeepSeek-R1-Distill-Llama-70B\":131000,\"ovhcloud/gpt-oss-120b\":131000,\"ovhcloud/gpt-oss-20b\":131000,\"ovhcloud/Llama-3.1-8B-Instruct\":131000,\"ovhcloud/llava-v1.6-mistral-7b-hf\":32000,\"ovhcloud/mamba-codestral-7B-v0.1\":256000,\"ovhcloud/Meta-Llama-3_1-70B-Instruct\":131000,\"ovhcloud/Meta-Llama-3_3-70B-Instruct\":131000,\"ovhcloud/Mistral-7B-Instruct-v0.3\":127000,\"ovhcloud/Mistral-Nemo-Instruct-2407\":118000,\"ovhcloud/Mistral-Small-3.2-24B-Instruct-2506\":128000,\"ovhcloud/Mixtral-8x7B-Instruct-v0.1\":32000,\"ovhcloud/Qwen2.5-Coder-32B-Instruct\":32000,\"ovhcloud/Qwen2.5-VL-72B-Instruct\":32000,\"ovhcloud/Qwen3-32B\":32000,\"palm/chat-bison\":4096,\"palm/chat-bison-001\":4096,\"perplexity/codellama-34b-instruct\":16384,\"perplexity/codellama-70b-instruct\":16384,\"perplexity/llama-2-70b-chat\":4096,\"perplexity/llama-3.1-70b-instruct\":131072,\"perplexity/llama-3.1-8b-instruct\":131072,\"perplexity/mistral-7b-instruct\":4096,\"perplexity/mixtral-8x7b-instruct\":4096,\"perplexity/pplx-70b-chat\":4096,\"perplexity/pplx-70b-online\":4096,\"perplexity/pplx-7b-chat\":8192,\"perplexity/pplx-7b-online\":4096,\"perplexity/sonar\":128000,\"perplexity/sonar-deep-research\":128000,\"perplexity/sonar-medium-chat\":16384,\"perplexity/sonar-medium-online\":12000,\"perplexity/sonar-pro\":8000,\"perplexity/sonar-reasoning\":128000,\"perplexity/sonar-reasoning-pro\":128000,\"perplexity/sonar-small-chat\":16384,\"perplexity/sonar-small-online\":12000,\"publicai/aisingapore/Gemma-SEA-LION-v4-27B-IT\":4096,\"publicai/aisingapore/Qwen-SEA-LION-v4-32B-IT\":4096,\"publicai/allenai/Olmo-3-32B-Think\":4096,\"publicai/allenai/Olmo-3-7B-Instruct\":4096,\"publicai/allenai/Olmo-3-7B-Think\":4096,\"publicai/BSC-LT/ALIA-40b-instruct_Q8_0\":4096,\"publicai/BSC-LT/salamandra-7b-instruct-tools-16k\":4096,\"publicai/swiss-ai/apertus-70b-instruct\":4096,\"publicai/swiss-ai/apertus-8b-instruct\":4096,\"qwen.qwen3-235b-a22b-2507-v1:0\":131072,\"qwen.qwen3-32b-v1:0\":16384,\"qwen.qwen3-coder-30b-a3b-v1:0\":131072,\"qwen.qwen3-coder-480b-a35b-v1:0\":65536,\"qwen.qwen3-coder-next\":8192,\"qwen.qwen3-next-80b-a3b\":8192,\"qwen.qwen3-vl-235b-a22b\":8192,\"replicate/deepseek-ai/deepseek-r1\":8192,\"replicate/deepseek-ai/deepseek-v3\":8192,\"replicate/deepseek-ai/deepseek-v3.1\":163840,\"replicate/meta/llama-2-13b\":4096,\"replicate/meta/llama-2-13b-chat\":4096,\"replicate/meta/llama-2-70b\":4096,\"replicate/meta/llama-2-70b-chat\":4096,\"replicate/meta/llama-2-7b\":4096,\"replicate/meta/llama-2-7b-chat\":4096,\"replicate/meta/llama-3-70b\":8192,\"replicate/meta/llama-3-70b-instruct\":8192,\"replicate/meta/llama-3-8b\":8086,\"replicate/meta/llama-3-8b-instruct\":8086,\"replicate/mistralai/mistral-7b-instruct-v0.2\":4096,\"replicate/mistralai/mistral-7b-v0.1\":4096,\"replicate/mistralai/mixtral-8x7b-instruct-v0.1\":4096,\"sagemaker/meta-textgeneration-llama-2-13b-f\":4096,\"sagemaker/meta-textgeneration-llama-2-70b-b-f\":4096,\"sagemaker/meta-textgeneration-llama-2-7b-f\":4096,\"sambanova/DeepSeek-R1\":32768,\"sambanova/DeepSeek-R1-Distill-Llama-70B\":131072,\"sambanova/DeepSeek-V3-0324\":32768,\"sambanova/DeepSeek-V3.1\":32768,\"sambanova/gpt-oss-120b\":131072,\"sambanova/Llama-4-Maverick-17B-128E-Instruct\":131072,\"sambanova/Llama-4-Scout-17B-16E-Instruct\":8192,\"sambanova/Meta-Llama-3.1-405B-Instruct\":16384,\"sambanova/Meta-Llama-3.1-8B-Instruct\":16384,\"sambanova/Meta-Llama-3.2-1B-Instruct\":16384,\"sambanova/Meta-Llama-3.2-3B-Instruct\":4096,\"sambanova/Meta-Llama-3.3-70B-Instruct\":131072,\"sambanova/Meta-Llama-Guard-3-8B\":16384,\"sambanova/Qwen2-Audio-7B-Instruct\":4096,\"sambanova/Qwen3-32B\":8192,\"sambanova/QwQ-32B\":16384,\"sarvam/sarvam-m\":32000,\"snowflake/claude-3-5-sonnet\":8192,\"snowflake/deepseek-r1\":8192,\"snowflake/gemma-7b\":8192,\"snowflake/jamba-1.5-large\":8192,\"snowflake/jamba-1.5-mini\":8192,\"snowflake/jamba-instruct\":8192,\"snowflake/llama2-70b-chat\":8192,\"snowflake/llama3-70b\":8192,\"snowflake/llama3-8b\":8192,\"snowflake/llama3.1-405b\":8192,\"snowflake/llama3.1-70b\":8192,\"snowflake/llama3.1-8b\":8192,\"snowflake/llama3.2-1b\":8192,\"snowflake/llama3.2-3b\":8192,\"snowflake/llama3.3-70b\":8192,\"snowflake/mistral-7b\":8192,\"snowflake/mistral-large\":8192,\"snowflake/mistral-large2\":8192,\"snowflake/mixtral-8x7b\":8192,\"snowflake/reka-core\":8192,\"snowflake/reka-flash\":8192,\"snowflake/snowflake-arctic\":8192,\"snowflake/snowflake-llama-3.1-405b\":8192,\"snowflake/snowflake-llama-3.3-70b\":8192,\"together_ai/deepseek-ai/DeepSeek-R1\":20480,\"together_ai/deepseek-ai/DeepSeek-V3\":8192,\"together_ai/deepseek-ai/DeepSeek-V3.1\":16384,\"together_ai/moonshotai/Kimi-K2.5\":256000,\"together_ai/openai/gpt-oss-120b\":131072,\"together_ai/zai-org/GLM-4.6\":200000,\"together_ai/zai-org/GLM-4.7\":200000,\"together-ai-8.1b-21b\":1000,\"us-gov.anthropic.claude-sonnet-4-5-20250929-v1:0\":64000,\"us.amazon.nova-2-lite-v1:0\":64000,\"us.amazon.nova-2-pro-preview-20251202-v1:0\":64000,\"us.amazon.nova-lite-v1:0\":10000,\"us.amazon.nova-micro-v1:0\":10000,\"us.amazon.nova-premier-v1:0\":10000,\"us.amazon.nova-pro-v1:0\":10000,\"us.anthropic.claude-3-5-haiku-20241022-v1:0\":8192,\"us.anthropic.claude-3-5-sonnet-20240620-v1:0\":4096,\"us.anthropic.claude-3-5-sonnet-20241022-v2:0\":8192,\"us.anthropic.claude-3-7-sonnet-20250219-v1:0\":8192,\"us.anthropic.claude-3-haiku-20240307-v1:0\":4096,\"us.anthropic.claude-3-opus-20240229-v1:0\":4096,\"us.anthropic.claude-3-sonnet-20240229-v1:0\":4096,\"us.anthropic.claude-haiku-4-5-20251001-v1:0\":64000,\"us.anthropic.claude-opus-4-1-20250805-v1:0\":32000,\"us.anthropic.claude-opus-4-20250514-v1:0\":32000,\"us.anthropic.claude-opus-4-5-20251101-v1:0\":64000,\"us.anthropic.claude-opus-4-6-v1\":128000,\"us.anthropic.claude-opus-4-7\":128000,\"us.anthropic.claude-sonnet-4-20250514-v1:0\":64000,\"us.anthropic.claude-sonnet-4-5-20250929-v1:0\":64000,\"us.anthropic.claude-sonnet-4-6\":64000,\"us.deepseek.r1-v1:0\":4096,\"us.deepseek.v3.2\":163840,\"us.meta.llama3-1-405b-instruct-v1:0\":4096,\"us.meta.llama3-1-70b-instruct-v1:0\":2048,\"us.meta.llama3-1-8b-instruct-v1:0\":2048,\"us.meta.llama3-2-11b-instruct-v1:0\":4096,\"us.meta.llama3-2-1b-instruct-v1:0\":4096,\"us.meta.llama3-2-3b-instruct-v1:0\":4096,\"us.meta.llama3-2-90b-instruct-v1:0\":4096,\"us.meta.llama3-3-70b-instruct-v1:0\":4096,\"us.meta.llama4-maverick-17b-instruct-v1:0\":4096,\"us.meta.llama4-scout-17b-instruct-v1:0\":4096,\"us.mistral.pixtral-large-2502-v1:0\":4096,\"us.writer.palmyra-x4-v1:0\":8192,\"us.writer.palmyra-x5-v1:0\":8192,\"v0/v0-1.0-md\":128000,\"v0/v0-1.5-lg\":512000,\"v0/v0-1.5-md\":128000,\"vercel_ai_gateway/alibaba/qwen-3-14b\":16384,\"vercel_ai_gateway/alibaba/qwen-3-235b\":16384,\"vercel_ai_gateway/alibaba/qwen-3-30b\":16384,\"vercel_ai_gateway/alibaba/qwen-3-32b\":16384,\"vercel_ai_gateway/alibaba/qwen3-coder\":66536,\"vercel_ai_gateway/amazon/nova-lite\":8192,\"vercel_ai_gateway/amazon/nova-micro\":8192,\"vercel_ai_gateway/amazon/nova-pro\":8192,\"vercel_ai_gateway/anthropic/claude-3-5-sonnet\":8192,\"vercel_ai_gateway/anthropic/claude-3-5-sonnet-20241022\":8192,\"vercel_ai_gateway/anthropic/claude-3-7-sonnet\":64000,\"vercel_ai_gateway/anthropic/claude-3-haiku\":4096,\"vercel_ai_gateway/anthropic/claude-3-opus\":4096,\"vercel_ai_gateway/anthropic/claude-3.5-haiku\":8192,\"vercel_ai_gateway/anthropic/claude-3.5-sonnet\":8192,\"vercel_ai_gateway/anthropic/claude-3.7-sonnet\":64000,\"vercel_ai_gateway/anthropic/claude-4-opus\":32000,\"vercel_ai_gateway/anthropic/claude-4-sonnet\":64000,\"vercel_ai_gateway/anthropic/claude-haiku-4.5\":64000,\"vercel_ai_gateway/anthropic/claude-opus-4\":32000,\"vercel_ai_gateway/anthropic/claude-opus-4.1\":32000,\"vercel_ai_gateway/anthropic/claude-opus-4.5\":64000,\"vercel_ai_gateway/anthropic/claude-opus-4.6\":64000,\"vercel_ai_gateway/anthropic/claude-sonnet-4\":64000,\"vercel_ai_gateway/anthropic/claude-sonnet-4.5\":64000,\"vercel_ai_gateway/cohere/command-a\":8000,\"vercel_ai_gateway/cohere/command-r\":4096,\"vercel_ai_gateway/cohere/command-r-plus\":4096,\"vercel_ai_gateway/deepseek/deepseek-r1\":8192,\"vercel_ai_gateway/deepseek/deepseek-r1-distill-llama-70b\":131072,\"vercel_ai_gateway/deepseek/deepseek-v3\":8192,\"vercel_ai_gateway/google/gemini-2.0-flash\":8192,\"vercel_ai_gateway/google/gemini-2.0-flash-lite\":8192,\"vercel_ai_gateway/google/gemini-2.5-flash\":65536,\"vercel_ai_gateway/google/gemini-2.5-pro\":65536,\"vercel_ai_gateway/google/gemma-2-9b\":8192,\"vercel_ai_gateway/inception/mercury-coder-small\":16384,\"vercel_ai_gateway/meta/llama-3-70b\":8192,\"vercel_ai_gateway/meta/llama-3-8b\":8192,\"vercel_ai_gateway/meta/llama-3.1-70b\":8192,\"vercel_ai_gateway/meta/llama-3.1-8b\":131072,\"vercel_ai_gateway/meta/llama-3.2-11b\":8192,\"vercel_ai_gateway/meta/llama-3.2-1b\":8192,\"vercel_ai_gateway/meta/llama-3.2-3b\":8192,\"vercel_ai_gateway/meta/llama-3.2-90b\":8192,\"vercel_ai_gateway/meta/llama-3.3-70b\":8192,\"vercel_ai_gateway/meta/llama-4-maverick\":8192,\"vercel_ai_gateway/meta/llama-4-scout\":8192,\"vercel_ai_gateway/mistral/codestral\":4000,\"vercel_ai_gateway/mistral/devstral-small\":128000,\"vercel_ai_gateway/mistral/magistral-medium\":64000,\"vercel_ai_gateway/mistral/magistral-small\":64000,\"vercel_ai_gateway/mistral/ministral-3b\":4000,\"vercel_ai_gateway/mistral/ministral-8b\":4000,\"vercel_ai_gateway/mistral/mistral-large\":4000,\"vercel_ai_gateway/mistral/mistral-saba-24b\":32768,\"vercel_ai_gateway/mistral/mistral-small\":4000,\"vercel_ai_gateway/mistral/mixtral-8x22b-instruct\":2048,\"vercel_ai_gateway/mistral/pixtral-12b\":4000,\"vercel_ai_gateway/mistral/pixtral-large\":4000,\"vercel_ai_gateway/moonshotai/kimi-k2\":16384,\"vercel_ai_gateway/morph/morph-v3-fast\":16384,\"vercel_ai_gateway/morph/morph-v3-large\":16384,\"vercel_ai_gateway/openai/gpt-3.5-turbo\":4096,\"vercel_ai_gateway/openai/gpt-3.5-turbo-instruct\":4096,\"vercel_ai_gateway/openai/gpt-4-turbo\":4096,\"vercel_ai_gateway/openai/gpt-4.1\":32768,\"vercel_ai_gateway/openai/gpt-4.1-mini\":32768,\"vercel_ai_gateway/openai/gpt-4.1-nano\":32768,\"vercel_ai_gateway/openai/gpt-4o\":16384,\"vercel_ai_gateway/openai/gpt-4o-mini\":16384,\"vercel_ai_gateway/openai/o1\":100000,\"vercel_ai_gateway/openai/o3\":100000,\"vercel_ai_gateway/openai/o3-mini\":100000,\"vercel_ai_gateway/openai/o4-mini\":100000,\"vercel_ai_gateway/perplexity/sonar\":8000,\"vercel_ai_gateway/perplexity/sonar-pro\":8000,\"vercel_ai_gateway/perplexity/sonar-reasoning\":8000,\"vercel_ai_gateway/perplexity/sonar-reasoning-pro\":8000,\"vercel_ai_gateway/vercel/v0-1.0-md\":32000,\"vercel_ai_gateway/vercel/v0-1.5-md\":32768,\"vercel_ai_gateway/xai/grok-2\":4000,\"vercel_ai_gateway/xai/grok-2-vision\":32768,\"vercel_ai_gateway/xai/grok-3\":131072,\"vercel_ai_gateway/xai/grok-3-fast\":131072,\"vercel_ai_gateway/xai/grok-3-mini\":131072,\"vercel_ai_gateway/xai/grok-3-mini-fast\":131072,\"vercel_ai_gateway/xai/grok-4\":256000,\"vercel_ai_gateway/zai/glm-4.5\":131072,\"vercel_ai_gateway/zai/glm-4.5-air\":96000,\"vercel_ai_gateway/zai/glm-4.6\":200000,\"vertex_ai/claude-3-5-haiku\":8192,\"vertex_ai/claude-3-5-haiku@20241022\":8192,\"vertex_ai/claude-3-5-sonnet\":8192,\"vertex_ai/claude-3-5-sonnet@20240620\":8192,\"vertex_ai/claude-3-7-sonnet@20250219\":8192,\"vertex_ai/claude-3-haiku\":4096,\"vertex_ai/claude-3-haiku@20240307\":4096,\"vertex_ai/claude-3-opus\":4096,\"vertex_ai/claude-3-opus@20240229\":4096,\"vertex_ai/claude-3-sonnet\":4096,\"vertex_ai/claude-3-sonnet@20240229\":4096,\"vertex_ai/claude-haiku-4-5\":8192,\"vertex_ai/claude-haiku-4-5@20251001\":8192,\"vertex_ai/claude-opus-4\":32000,\"vertex_ai/claude-opus-4-1\":32000,\"vertex_ai/claude-opus-4-1@20250805\":32000,\"vertex_ai/claude-opus-4-5\":64000,\"vertex_ai/claude-opus-4-5@20251101\":64000,\"vertex_ai/claude-opus-4-6\":128000,\"vertex_ai/claude-opus-4-6@default\":128000,\"vertex_ai/claude-opus-4-7\":128000,\"vertex_ai/claude-opus-4-7@default\":128000,\"vertex_ai/claude-opus-4@20250514\":32000,\"vertex_ai/claude-sonnet-4\":64000,\"vertex_ai/claude-sonnet-4-5\":64000,\"vertex_ai/claude-sonnet-4-5@20250929\":64000,\"vertex_ai/claude-sonnet-4-6\":64000,\"vertex_ai/claude-sonnet-4-6@default\":64000,\"vertex_ai/claude-sonnet-4@20250514\":64000,\"vertex_ai/codestral-2\":128000,\"vertex_ai/codestral-2@001\":128000,\"vertex_ai/codestral-2501\":128000,\"vertex_ai/codestral@2405\":128000,\"vertex_ai/codestral@latest\":128000,\"vertex_ai/deepseek-ai/deepseek-r1-0528-maas\":8192,\"vertex_ai/deepseek-ai/deepseek-v3.1-maas\":32768,\"vertex_ai/deepseek-ai/deepseek-v3.2-maas\":32768,\"vertex_ai/gemini-3-flash-preview\":65535,\"vertex_ai/gemini-3-pro-preview\":65535,\"vertex_ai/gemini-3.1-flash-lite-preview\":65536,\"vertex_ai/gemini-3.1-pro-preview\":65536,\"vertex_ai/gemini-3.1-pro-preview-customtools\":65536,\"vertex_ai/jamba-1.5\":256000,\"vertex_ai/jamba-1.5-large\":256000,\"vertex_ai/jamba-1.5-large@001\":256000,\"vertex_ai/jamba-1.5-mini\":256000,\"vertex_ai/jamba-1.5-mini@001\":256000,\"vertex_ai/meta/llama-3.1-405b-instruct-maas\":2048,\"vertex_ai/meta/llama-3.1-70b-instruct-maas\":2048,\"vertex_ai/meta/llama-3.1-8b-instruct-maas\":2048,\"vertex_ai/meta/llama-3.2-90b-vision-instruct-maas\":2048,\"vertex_ai/meta/llama-4-maverick-17b-128e-instruct-maas\":1000000,\"vertex_ai/meta/llama-4-maverick-17b-16e-instruct-maas\":1000000,\"vertex_ai/meta/llama-4-scout-17b-128e-instruct-maas\":10000000,\"vertex_ai/meta/llama-4-scout-17b-16e-instruct-maas\":10000000,\"vertex_ai/meta/llama3-405b-instruct-maas\":32000,\"vertex_ai/meta/llama3-70b-instruct-maas\":32000,\"vertex_ai/meta/llama3-8b-instruct-maas\":32000,\"vertex_ai/minimaxai/minimax-m2-maas\":196608,\"vertex_ai/mistral-large-2411\":8191,\"vertex_ai/mistral-large@2407\":8191,\"vertex_ai/mistral-large@2411-001\":8191,\"vertex_ai/mistral-large@latest\":8191,\"vertex_ai/mistral-medium-3\":8191,\"vertex_ai/mistral-medium-3@001\":8191,\"vertex_ai/mistral-nemo@2407\":128000,\"vertex_ai/mistral-nemo@latest\":128000,\"vertex_ai/mistral-small-2503\":128000,\"vertex_ai/mistral-small-2503@001\":8191,\"vertex_ai/mistralai/codestral-2\":128000,\"vertex_ai/mistralai/codestral-2@001\":128000,\"vertex_ai/mistralai/mistral-medium-3\":8191,\"vertex_ai/mistralai/mistral-medium-3@001\":8191,\"vertex_ai/moonshotai/kimi-k2-thinking-maas\":256000,\"vertex_ai/openai/gpt-oss-120b-maas\":32768,\"vertex_ai/openai/gpt-oss-20b-maas\":32768,\"vertex_ai/qwen/qwen3-235b-a22b-instruct-2507-maas\":16384,\"vertex_ai/qwen/qwen3-coder-480b-a35b-instruct-maas\":32768,\"vertex_ai/qwen/qwen3-next-80b-a3b-instruct-maas\":262144,\"vertex_ai/qwen/qwen3-next-80b-a3b-thinking-maas\":262144,\"vertex_ai/zai-org/glm-4.7-maas\":128000,\"vertex_ai/zai-org/glm-5-maas\":128000,\"volcengine/doubao-seed-2-0-code-preview-260215\":128000,\"volcengine/doubao-seed-2-0-lite-260215\":128000,\"volcengine/doubao-seed-2-0-mini-260215\":128000,\"volcengine/doubao-seed-2-0-pro-260215\":128000,\"wandb/deepseek-ai/DeepSeek-R1-0528\":161000,\"wandb/deepseek-ai/DeepSeek-V3-0324\":161000,\"wandb/deepseek-ai/DeepSeek-V3.1\":128000,\"wandb/meta-llama/Llama-3.1-8B-Instruct\":128000,\"wandb/meta-llama/Llama-3.3-70B-Instruct\":128000,\"wandb/meta-llama/Llama-4-Scout-17B-16E-Instruct\":64000,\"wandb/microsoft/Phi-4-mini-instruct\":128000,\"wandb/MiniMaxAI/MiniMax-M2.5\":197000,\"wandb/moonshotai/Kimi-K2-Instruct\":128000,\"wandb/moonshotai/Kimi-K2.5\":262144,\"wandb/openai/gpt-oss-120b\":131072,\"wandb/openai/gpt-oss-20b\":131072,\"wandb/Qwen/Qwen3-235B-A22B-Instruct-2507\":262144,\"wandb/Qwen/Qwen3-235B-A22B-Thinking-2507\":262144,\"wandb/Qwen/Qwen3-Coder-480B-A35B-Instruct\":262144,\"wandb/zai-org/GLM-4.5\":131072,\"watsonx/bigscience/mt0-xxl-13b\":8192,\"watsonx/core42/jais-13b-chat\":8192,\"watsonx/google/flan-t5-xl-3b\":8192,\"watsonx/ibm/granite-13b-chat-v2\":8192,\"watsonx/ibm/granite-13b-instruct-v2\":8192,\"watsonx/ibm/granite-3-3-8b-instruct\":8192,\"watsonx/ibm/granite-3-8b-instruct\":1024,\"watsonx/ibm/granite-4-h-small\":20480,\"watsonx/ibm/granite-guardian-3-2-2b\":8192,\"watsonx/ibm/granite-guardian-3-3-8b\":8192,\"watsonx/ibm/granite-ttm-1024-96-r2\":512,\"watsonx/ibm/granite-ttm-1536-96-r2\":512,\"watsonx/ibm/granite-ttm-512-96-r2\":512,\"watsonx/ibm/granite-vision-3-2-2b\":8192,\"watsonx/meta-llama/llama-3-2-11b-vision-instruct\":128000,\"watsonx/meta-llama/llama-3-2-1b-instruct\":128000,\"watsonx/meta-llama/llama-3-2-3b-instruct\":128000,\"watsonx/meta-llama/llama-3-2-90b-vision-instruct\":128000,\"watsonx/meta-llama/llama-3-3-70b-instruct\":128000,\"watsonx/meta-llama/llama-4-maverick-17b\":128000,\"watsonx/meta-llama/llama-guard-3-11b-vision\":128000,\"watsonx/mistralai/mistral-large\":16384,\"watsonx/mistralai/mistral-medium-2505\":128000,\"watsonx/mistralai/mistral-small-2503\":32000,\"watsonx/mistralai/mistral-small-3-1-24b-instruct-2503\":32000,\"watsonx/mistralai/pixtral-12b-2409\":128000,\"watsonx/openai/gpt-oss-120b\":8192,\"watsonx/sdaia/allam-1-13b-instruct\":8192,\"writer.palmyra-x4-v1:0\":8192,\"writer.palmyra-x5-v1:0\":8192,\"xai/grok-2\":131072,\"xai/grok-2-1212\":131072,\"xai/grok-2-latest\":131072,\"xai/grok-2-vision\":32768,\"xai/grok-2-vision-1212\":32768,\"xai/grok-2-vision-latest\":32768,\"xai/grok-3\":131072,\"xai/grok-3-beta\":131072,\"xai/grok-3-fast-beta\":131072,\"xai/grok-3-fast-latest\":131072,\"xai/grok-3-latest\":131072,\"xai/grok-3-mini\":131072,\"xai/grok-3-mini-beta\":131072,\"xai/grok-3-mini-fast\":131072,\"xai/grok-3-mini-fast-beta\":131072,\"xai/grok-3-mini-fast-latest\":131072,\"xai/grok-3-mini-latest\":131072,\"xai/grok-4\":256000,\"xai/grok-4-0709\":256000,\"xai/grok-4-1-fast\":2000000,\"xai/grok-4-1-fast-non-reasoning\":2000000,\"xai/grok-4-1-fast-non-reasoning-latest\":2000000,\"xai/grok-4-1-fast-reasoning\":2000000,\"xai/grok-4-1-fast-reasoning-latest\":2000000,\"xai/grok-4-fast-non-reasoning\":2000000,\"xai/grok-4-fast-reasoning\":2000000,\"xai/grok-4-latest\":256000,\"xai/grok-4.20-0309-reasoning\":2000000,\"xai/grok-4.20-beta-0309-non-reasoning\":2000000,\"xai/grok-4.20-beta-0309-reasoning\":2000000,\"xai/grok-4.20-multi-agent-beta-0309\":2000000,\"xai/grok-beta\":131072,\"xai/grok-code-fast\":256000,\"xai/grok-code-fast-1\":256000,\"xai/grok-code-fast-1-0825\":256000,\"xai/grok-vision-beta\":8192,\"zai.glm-4.7\":128000,\"zai.glm-4.7-flash\":128000,\"zai.glm-5\":128000,\"zai/glm-4-32b-0414-128k\":32000,\"zai/glm-4.5\":32000,\"zai/glm-4.5-air\":32000,\"zai/glm-4.5-airx\":32000,\"zai/glm-4.5-flash\":32000,\"zai/glm-4.5-x\":32000,\"zai/glm-4.5v\":32000,\"zai/glm-4.6\":128000,\"zai/glm-4.7\":128000,\"zai/glm-5\":128000,\"zai/glm-5-code\":128000}}","import type { AppConfig } from '../types';\nimport litellmData from './litellm-models.json';\n\n// Per-model output cap, used to default `max_tokens` so users on supported\n// models don't have to find Settings to avoid mid-stream truncation.\n//\n// Source of truth: vendored slice of BerriAI/litellm's\n// model_prices_and_context_window.json (MIT). Regenerate with:\n// node --experimental-strip-types scripts/sync-litellm-models.ts\n//\n// Anything LiteLLM doesn't track (or where its value is wrong for our\n// usage) goes in OVERRIDES; unknown models fall through to FALLBACK.\nexport const FALLBACK_MAX_TOKENS = 8192;\n\n// Bounds the user can express via the Settings override. Source of truth\n// for both the UI input attributes and runtime validation in\n// `effectiveMaxTokens`, so a stale or hand-edited localStorage value\n// can't sneak past the UI's promise.\nexport const MIN_MAX_TOKENS = 1024;\nexport const MAX_MAX_TOKENS = 200000;\n\nconst LITELLM_MODELS = litellmData.models as Record<string, number>;\n\nconst OVERRIDES: Record<string, number> = {\n // LiteLLM lists MiMo via OpenRouter and Novita aliases (16k / 32k) but\n // not the canonical `mimo-v2.5-pro` id we hand to Xiaomi's direct API.\n // 32k matches what issue #29 reports as the working ceiling.\n 'mimo-v2.5-pro': 32768,\n\n // DeepSeek v4 models not tracked by LiteLLM as of 2026-05-07.\n // Spec: https://platform.deepseek.com/docs/model-cards\n 'deepseek-v4-pro': 384000,\n 'deepseek-v4-flash': 384000,\n\n // Ollama Cloud models. LiteLLM keys this set under `ollama/`-prefixed\n // ids (many with `-cloud` suffixes), so the bare model-id lookups never\n // match. Add overrides so chat doesn't silently clip at 8192 tokens.\n // 131072 (128k) is a safe floor for all Ollama Cloud models.\n 'cogito-2.1:671b': 131072,\n 'deepseek-v3.1:671b': 163840,\n 'deepseek-v3.2': 163840,\n 'devstral-2:123b': 131072,\n 'devstral-small-2:24b': 131072,\n 'gemini-3-flash-preview': 131072,\n 'gemma3:4b': 131072,\n 'gemma3:12b': 131072,\n 'gemma3:27b': 131072,\n 'gemma4:31b': 131072,\n 'glm-4.6': 131072,\n 'glm-4.7': 131072,\n 'glm-5': 131072,\n 'glm-5.1': 131072,\n 'gpt-oss:20b': 131072,\n 'gpt-oss:120b': 131072,\n 'kimi-k2:1t': 131072,\n 'kimi-k2-thinking': 131072,\n 'kimi-k2.5': 131072,\n 'kimi-k2.6': 131072,\n 'minimax-m2': 131072,\n 'minimax-m2.1': 131072,\n 'minimax-m2.5': 131072,\n 'minimax-m2.7': 131072,\n 'ministral-3:3b': 131072,\n 'ministral-3:8b': 131072,\n 'ministral-3:14b': 131072,\n 'mistral-large-3:675b': 131072,\n 'nemotron-3-nano:30b': 131072,\n 'nemotron-3-super': 131072,\n 'qwen3-coder:480b': 262144,\n 'qwen3-coder-next': 131072,\n 'qwen3-next:80b': 131072,\n 'qwen3-vl:235b': 131072,\n 'qwen3-vl:235b-instruct': 131072,\n 'qwen3.5:397b': 131072,\n 'rnj-1:8b': 131072,\n};\n\nexport function modelMaxTokensDefault(model: string): number {\n return OVERRIDES[model] ?? LITELLM_MODELS[model] ?? FALLBACK_MAX_TOKENS;\n}\n\nfunction isValidOverride(value: number | undefined): value is number {\n return (\n typeof value === 'number' &&\n Number.isInteger(value) &&\n value >= MIN_MAX_TOKENS &&\n value <= MAX_MAX_TOKENS\n );\n}\n\nexport function effectiveMaxTokens(cfg: Pick<AppConfig, 'maxTokens' | 'model'>): number {\n // Out-of-range or non-integer overrides (stale localStorage, hand-edited\n // config, future schema drift) fall back to the model default rather\n // than silently shipping an invalid `max_tokens` upstream.\n if (isValidOverride(cfg.maxTokens)) return cfg.maxTokens;\n return modelMaxTokensDefault(cfg.model);\n}\n","import type { AppConfigPrefs } from '@open-design/contracts';\nimport { MEDIA_PROVIDERS } from '../media/models';\nimport { isOpenAICompatible } from '../providers/openai-compatible';\nimport type {\n ApiProtocol,\n AppConfig,\n MediaProviderCredentials,\n NotificationsConfig,\n OrbitConfig,\n PetConfig,\n} from '../types';\nimport {\n DEFAULT_ACCENT_COLOR,\n normalizeAccentColor,\n} from './appearance';\nimport {\n DEFAULT_FAILURE_SOUND_ID,\n DEFAULT_SUCCESS_SOUND_ID,\n} from '../utils/notifications';\n\nconst STORAGE_KEY = 'open-design:config';\nconst CONFIG_MIGRATION_VERSION = 1;\n\n// Hatched out of the box, but tucked away — the user has to go through\n// either the entry-view \"adopt a pet\" callout or Settings → Pets to\n// summon them. Keeps the workspace quiet for first-run users.\n// Both switches default off so first-run users are not greeted by a\n// surprise sound or a permission prompt; they can opt in from Settings →\n// Notifications when they want it.\nexport const DEFAULT_NOTIFICATIONS: NotificationsConfig = {\n soundEnabled: false,\n successSoundId: DEFAULT_SUCCESS_SOUND_ID,\n failureSoundId: DEFAULT_FAILURE_SOUND_ID,\n desktopEnabled: false,\n};\n\nexport const DEFAULT_PET: PetConfig = {\n adopted: false,\n enabled: false,\n petId: 'mochi',\n custom: {\n name: 'Buddy',\n glyph: '🦄',\n accent: '#c96442',\n greeting: 'Hi! I am here whenever you need me.',\n },\n};\n\nexport const DEFAULT_ORBIT: OrbitConfig = {\n enabled: false,\n time: '08:00',\n // Ship with the general-purpose Orbit briefing skill pre-selected so a\n // fresh install runs against a real adaptive template instead of the\n // bare built-in prompt. Users can clear it from Settings → Orbit to fall\n // back to the built-in prompt or pick another scenario === 'orbit' skill.\n templateSkillId: 'orbit-general',\n};\n\nexport const DEFAULT_CONFIG: AppConfig = {\n mode: 'daemon',\n apiKey: '',\n baseUrl: 'https://api.anthropic.com',\n model: 'claude-sonnet-4-5',\n // New configs should be explicit. loadConfig() still detects parsed legacy\n // saved configs that did not have this field and migrates those from their\n // saved baseUrl/model before applying the current migration version.\n apiProtocol: 'anthropic',\n apiVersion: '',\n apiProtocolConfigs: {},\n configMigrationVersion: CONFIG_MIGRATION_VERSION,\n apiProviderBaseUrl: 'https://api.anthropic.com',\n agentId: null,\n skillId: null,\n designSystemId: null,\n onboardingCompleted: false,\n theme: 'system',\n accentColor: DEFAULT_ACCENT_COLOR,\n mediaProviders: {},\n composio: {},\n agentModels: {},\n agentCliEnv: {},\n pet: DEFAULT_PET,\n notifications: DEFAULT_NOTIFICATIONS,\n orbit: DEFAULT_ORBIT,\n projectLocations: [],\n defaultProjectLocationId: 'default',\n // Telemetry defaults to ON so fresh-install users emit onboarding /\n // ui_click events from the first frame. The disclosure modal still\n // appears after `onboardingCompleted` flips, and Settings → Privacy\n // remains the one-click opt-out. Without these defaults the gate at\n // `daemon/src/analytics.ts` (`if (telemetry?.metrics !== true) return`)\n // dropped every event fired during onboarding because no consent\n // existed yet — observed live on the nightly.10 QA run, which left\n // zero `page_view pn=onboarding` rows on PostHog despite the user\n // completing the flow. `artifactManifest` stays off; the existing\n // PrivacySection lets the user enable it explicitly.\n telemetry: { metrics: true, content: true, artifactManifest: false },\n};\n\n/** Well-known providers with pre-filled base URLs. */\nexport interface KnownProvider {\n label: string;\n protocol: ApiProtocol;\n baseUrl: string;\n /** Default model to apply when the provider is selected. */\n model: string;\n /** Optional provider-specific model choices shown in Settings. */\n models?: string[];\n /** Some local/self-hosted endpoints do not require bearer credentials. */\n requiresApiKey?: boolean;\n}\n\n// Some providers appear more than once because they expose both\n// Anthropic-compatible (/v1/messages) and OpenAI-compatible\n// (/v1/chat/completions) gateways. Keep those entries separate so the Settings\n// UI can scope quick-fill presets and model suggestions to the selected\n// protocol.\n//\n// Model lists are hand-curated from provider docs/current public presets rather\n// than fetched dynamically. To add a provider, include a user-facing label, the\n// protocol that determines request routing, the base URL, a default model, and\n// optional provider-specific model choices.\nexport const KNOWN_PROVIDERS: KnownProvider[] = [\n {\n label: 'Anthropic (Claude)',\n protocol: 'anthropic',\n baseUrl: 'https://api.anthropic.com',\n model: 'claude-sonnet-4-5',\n models: ['claude-sonnet-4-5', 'claude-opus-4-5', 'claude-haiku-4-5'],\n },\n {\n label: 'DeepSeek — Anthropic',\n protocol: 'anthropic',\n baseUrl: 'https://api.deepseek.com/anthropic',\n model: 'deepseek-chat',\n models: [\n 'deepseek-chat',\n 'deepseek-reasoner',\n 'deepseek-v4-flash',\n 'deepseek-v4-pro',\n ],\n },\n {\n label: 'MiniMax — Anthropic',\n protocol: 'anthropic',\n baseUrl: 'https://api.minimaxi.com/anthropic',\n model: 'MiniMax-M2.7-highspeed',\n models: [\n 'MiniMax-M2.7-highspeed',\n 'MiniMax-M2.7',\n 'MiniMax-M2.5-highspeed',\n 'MiniMax-M2.5',\n 'MiniMax-M2.1-highspeed',\n 'MiniMax-M2.1',\n 'MiniMax-M2',\n ],\n },\n {\n label: 'OpenAI',\n protocol: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n model: 'gpt-4o',\n models: ['gpt-4o', 'gpt-4o-mini', 'o3', 'o4-mini'],\n },\n {\n label: 'OpenRouter',\n protocol: 'openai',\n baseUrl: 'https://openrouter.ai/api/v1',\n model: 'anthropic/claude-3.7-sonnet',\n models: [\n 'anthropic/claude-3.7-sonnet',\n 'anthropic/claude-3.5-sonnet',\n 'google/gemini-2.5-flash',\n 'google/gemini-2.5-pro',\n 'openai/gpt-4o',\n 'openai/o3-mini',\n 'deepseek/deepseek-chat',\n 'deepseek/deepseek-r1',\n ],\n },\n {\n label: 'Azure OpenAI',\n protocol: 'azure',\n baseUrl: '',\n model: '',\n models: [],\n },\n {\n label: 'Google Gemini',\n protocol: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com',\n model: 'gemini-2.0-flash',\n models: ['gemini-2.0-flash', 'gemini-2.0-flash-lite', 'gemini-1.5-pro', 'gemini-1.5-flash'],\n },\n {\n label: 'DeepSeek — OpenAI',\n protocol: 'openai',\n baseUrl: 'https://api.deepseek.com',\n model: 'deepseek-chat',\n models: [\n 'deepseek-chat',\n 'deepseek-reasoner',\n 'deepseek-v4-flash',\n 'deepseek-v4-pro',\n ],\n },\n {\n label: 'MiniMax — OpenAI',\n protocol: 'openai',\n baseUrl: 'https://api.minimaxi.com/v1',\n model: 'MiniMax-M2.7-highspeed',\n models: [\n 'MiniMax-M2.7-highspeed',\n 'MiniMax-M2.7',\n 'MiniMax-M2.5-highspeed',\n 'MiniMax-M2.5',\n 'MiniMax-M2.1-highspeed',\n 'MiniMax-M2.1',\n 'MiniMax-M2',\n ],\n },\n {\n label: 'MiMo (Xiaomi) — OpenAI',\n protocol: 'openai',\n baseUrl: 'https://token-plan-cn.xiaomimimo.com/v1',\n model: 'mimo-v2.5-pro',\n models: ['mimo-v2.5-pro'],\n },\n {\n label: 'Ollama Cloud (managed)',\n protocol: 'ollama',\n baseUrl: 'https://ollama.com',\n model: 'gpt-oss:120b',\n models: [\n 'cogito-2.1:671b',\n 'deepseek-v3.1:671b',\n 'deepseek-v3.2',\n 'deepseek-v4-flash',\n 'deepseek-v4-pro',\n 'devstral-2:123b',\n 'devstral-small-2:24b',\n 'gemini-3-flash-preview',\n 'gemma3:4b',\n 'gemma3:12b',\n 'gemma3:27b',\n 'gemma4:31b',\n 'glm-4.6',\n 'glm-4.7',\n 'glm-5',\n 'glm-5.1',\n 'gpt-oss:20b',\n 'gpt-oss:120b',\n 'kimi-k2:1t',\n 'kimi-k2-thinking',\n 'kimi-k2.5',\n 'kimi-k2.6',\n 'minimax-m2',\n 'minimax-m2.1',\n 'minimax-m2.5',\n 'minimax-m2.7',\n 'ministral-3:3b',\n 'ministral-3:8b',\n 'ministral-3:14b',\n 'mistral-large-3:675b',\n 'nemotron-3-nano:30b',\n 'nemotron-3-super',\n 'qwen3-coder:480b',\n 'qwen3-coder-next',\n 'qwen3-next:80b',\n 'qwen3-vl:235b',\n 'qwen3-vl:235b-instruct',\n 'qwen3.5:397b',\n 'rnj-1:8b',\n ],\n },\n {\n label: 'Ollama Self-hosted (local)',\n protocol: 'ollama',\n baseUrl: 'http://localhost:11434',\n model: 'gemma3:4b',\n models: ['gemma3:4b', 'gemma3:12b', 'gemma3:27b', 'gpt-oss:20b'],\n requiresApiKey: false,\n },\n {\n label: 'MiMo (Xiaomi) — Anthropic',\n protocol: 'anthropic',\n baseUrl: 'https://token-plan-cn.xiaomimimo.com/anthropic',\n model: 'mimo-v2.5-pro',\n models: ['mimo-v2.5-pro'],\n },\n {\n label: 'SenseAudio',\n protocol: 'senseaudio',\n baseUrl: 'https://api.senseaudio.cn',\n model: 'senseaudio-s2',\n models: [\n 'senseaudio-s2',\n 'senseaudio-s2-flash',\n 'deepseek-v4-flash',\n 'deepseek-v4-pro',\n 'glm-5.1',\n 'kimi-k2.6',\n 'MiniMax-M2.7-highspeed',\n 'MiniMax-M2.7',\n ],\n },\n];\n\nfunction normalizePet(input: Partial<PetConfig> | undefined): PetConfig {\n if (!input) return { ...DEFAULT_PET, custom: { ...DEFAULT_PET.custom } };\n // Merge stored values onto defaults so newly-added fields land safely\n // when an older config is rehydrated.\n return {\n ...DEFAULT_PET,\n ...input,\n custom: { ...DEFAULT_PET.custom, ...(input.custom ?? {}) },\n };\n}\n\nfunction normalizeNotifications(\n input: Partial<NotificationsConfig> | undefined,\n): NotificationsConfig {\n return { ...DEFAULT_NOTIFICATIONS, ...(input ?? {}) };\n}\n\nfunction normalizeOrbit(input: Partial<OrbitConfig> | undefined): OrbitConfig {\n const time = typeof input?.time === 'string' && isValidOrbitTime(input.time)\n ? input.time\n : DEFAULT_ORBIT.time;\n return { ...DEFAULT_ORBIT, ...(input ?? {}), time };\n}\n\nfunction isValidOrbitTime(time: string): boolean {\n const match = /^(\\d{2}):(\\d{2})$/.exec(time);\n if (!match) return false;\n const hours = Number(match[1]);\n const minutes = Number(match[2]);\n return hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59;\n}\n\nfunction inferApiProtocol(model: string, baseUrl: string): ApiProtocol {\n try {\n const normalized = (baseUrl || '').toLowerCase();\n // Any config pointing at ollama.com should resolve to the new ollama\n // protocol so both chat and the connection test hit the native Ollama\n // proxy instead of the Anthropic or OpenAI paths.\n if (normalized.includes('ollama.com')) return 'ollama';\n // SenseAudio host gets routed to its own proxy so the daemon log line\n // and the BYOK tab UI stay consistent with the protocol the user\n // picked — even though the on-wire shape is OpenAI-compatible.\n if (normalized.includes('senseaudio.cn')) return 'senseaudio';\n return isOpenAICompatible(model, baseUrl) ? 'openai' : 'anthropic';\n } catch {\n // Preserve the rest of the user's settings even if an old saved base URL is\n // malformed enough for URL parsing to throw. Anthropic is the safest default\n // because it matches the original built-in provider.\n return 'anthropic';\n }\n}\n\nexport function loadConfig(): AppConfig {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) {\n return {\n ...DEFAULT_CONFIG,\n pet: normalizePet(DEFAULT_PET),\n notifications: normalizeNotifications(DEFAULT_NOTIFICATIONS),\n orbit: normalizeOrbit(DEFAULT_ORBIT),\n };\n }\n const parsed = JSON.parse(raw) as Partial<AppConfig>;\n // Strip daemon-owned privacy fields if a stale localStorage payload\n // still carries them. Older builds wrote these to localStorage; we\n // now treat the daemon as authoritative so the user can rotate /\n // revoke without leaving residue in browser storage.\n for (const key of DAEMON_OWNED_KEYS) {\n delete (parsed as Record<string, unknown>)[key];\n }\n const parsedHasApiProtocol = Object.prototype.hasOwnProperty.call(\n parsed,\n 'apiProtocol',\n );\n const merged: AppConfig = {\n ...DEFAULT_CONFIG,\n ...parsed,\n apiProtocolConfigs: { ...(parsed.apiProtocolConfigs ?? {}) },\n mediaProviders: { ...(parsed.mediaProviders ?? {}) },\n composio: { ...(parsed.composio ?? {}) },\n agentModels: { ...(parsed.agentModels ?? {}) },\n agentCliEnv: { ...(parsed.agentCliEnv ?? {}) },\n accentColor: normalizeAccentColor(parsed.accentColor) ?? DEFAULT_CONFIG.accentColor,\n pet: normalizePet(parsed.pet),\n notifications: normalizeNotifications(parsed.notifications),\n orbit: normalizeOrbit(parsed.orbit),\n };\n\n if (parsed.configMigrationVersion !== CONFIG_MIGRATION_VERSION) {\n // Migration v1: configs saved before apiProtocol existed need an explicit\n // protocol so old OpenAI-compatible endpoints keep routing correctly.\n // This is version-gated instead of only field-gated so a later imported\n // legacy config can be migrated when it is loaded.\n if (!parsedHasApiProtocol) {\n merged.apiProtocol = inferApiProtocol(merged.model, merged.baseUrl);\n // Ollama Cloud legacy configs may carry a base URL that includes\n // /api or /api/ — normalize to the host root so the daemon's own\n // /api/chat appending doesn't double up.\n if (merged.apiProtocol === 'ollama') {\n merged.baseUrl = merged.baseUrl\n .replace(/\\/api\\/?$/, '')\n .replace(/\\/+$/, '');\n }\n // Also set apiProviderBaseUrl so setApiProtocol() can correctly identify\n // whether the user is on a known provider and switch defaults appropriately.\n // null means \"custom/unknown provider\" so the protocol switch won't override\n // their custom base URL.\n const knownProvider = KNOWN_PROVIDERS.find(\n (p) => p.baseUrl === merged.baseUrl,\n );\n merged.apiProviderBaseUrl = knownProvider?.baseUrl ?? null;\n }\n merged.configMigrationVersion = CONFIG_MIGRATION_VERSION;\n }\n\n return merged;\n } catch {\n return {\n ...DEFAULT_CONFIG,\n pet: normalizePet(DEFAULT_PET),\n notifications: normalizeNotifications(DEFAULT_NOTIFICATIONS),\n orbit: normalizeOrbit(DEFAULT_ORBIT),\n };\n }\n}\n\ninterface PublicComposioConfigResponse {\n configured?: boolean;\n apiKeyTail?: string;\n}\n\ninterface PublicMediaProviderConfigEntry {\n configured?: boolean;\n source?: string;\n apiKeyTail?: string;\n baseUrl?: string;\n model?: string;\n}\n\ninterface PublicMediaProviderConfigResponse {\n providers?: Record<string, PublicMediaProviderConfigEntry>;\n}\n\nexport type DaemonMediaProvidersFetchResult =\n | {\n status: 'ok';\n providers: AppConfig['mediaProviders'];\n }\n | {\n status: 'error';\n };\n\ninterface MediaProviderDaemonWriteEntry {\n apiKey?: string;\n preserveApiKey?: boolean;\n baseUrl?: string;\n model?: string;\n}\n\ninterface MediaProviderDaemonWriteRequest {\n providers: Record<string, MediaProviderDaemonWriteEntry>;\n force: boolean;\n}\n\nfunction hasAnyDaemonManagedMediaProvider(\n providers: Record<string, MediaProviderCredentials> | null | undefined,\n): boolean {\n if (!providers) return false;\n return Object.values(providers).some((entry) => isStoredMediaProviderEntryPresent(entry));\n}\n\nfunction hasRecoverableLocalMediaProviderFields(\n entry: MediaProviderCredentials | null | undefined,\n): boolean {\n return Boolean(\n entry?.apiKey?.trim()\n || entry?.baseUrl?.trim()\n || entry?.model?.trim(),\n );\n}\n\nfunction isMarkerOnlyMediaProviderEntry(\n entry: MediaProviderCredentials | null | undefined,\n): boolean {\n return isStoredMediaProviderEntryPresent(entry)\n && !hasRecoverableLocalMediaProviderFields(entry);\n}\n\nexport function isStoredMediaProviderEntryPresent(\n entry: MediaProviderCredentials | null | undefined,\n): boolean {\n return Boolean(\n entry?.apiKey?.trim()\n || entry?.baseUrl?.trim()\n || entry?.model?.trim()\n || entry?.apiKeyConfigured\n || entry?.apiKeyTail?.trim(),\n );\n}\n\nexport function isStoredMediaProviderEntryEmpty(\n entry: MediaProviderCredentials | null | undefined,\n): boolean {\n return !isStoredMediaProviderEntryPresent(entry);\n}\n\nfunction defaultBaseUrlForProvider(providerId: string): string {\n return MEDIA_PROVIDERS.find((provider) => provider.id === providerId)?.defaultBaseUrl ?? '';\n}\n\nexport function buildMediaProvidersForDaemonSave(\n currentProviders: Record<string, MediaProviderCredentials> | undefined,\n daemonProviders: Record<string, MediaProviderCredentials> | null | undefined,\n options?: { force?: boolean },\n): MediaProviderDaemonWriteRequest {\n const providers: Record<string, MediaProviderDaemonWriteEntry> = {};\n for (const [providerId, currentEntry] of Object.entries(currentProviders ?? {})) {\n const daemonEntry = daemonProviders?.[providerId];\n const apiKey = currentEntry?.apiKey?.trim() ?? '';\n const hasStoredKeyMarker = Boolean(\n currentEntry?.apiKeyTail?.trim()\n || daemonEntry?.apiKeyTail?.trim(),\n );\n const preserveApiKey = !apiKey && Boolean(\n currentEntry?.apiKeyConfigured\n && hasStoredKeyMarker,\n );\n const explicitBaseUrl =\n currentEntry?.baseUrl?.trim()\n || daemonEntry?.baseUrl?.trim()\n || '';\n const model = currentEntry?.model?.trim() || daemonEntry?.model?.trim() || '';\n if (!apiKey && !preserveApiKey && !explicitBaseUrl && !model) continue;\n const baseUrl = explicitBaseUrl || defaultBaseUrlForProvider(providerId);\n providers[providerId] = {\n ...(apiKey ? { apiKey } : {}),\n ...(preserveApiKey ? { preserveApiKey: true } : {}),\n ...(baseUrl ? { baseUrl } : {}),\n ...(model ? { model } : {}),\n };\n }\n return {\n providers,\n force: Boolean(options?.force),\n };\n}\n\nexport async function fetchComposioConfigFromDaemon(): Promise<AppConfig['composio'] | null> {\n try {\n const response = await fetch('/api/connectors/composio/config');\n if (!response.ok) return null;\n const payload = await response.json() as PublicComposioConfigResponse;\n return {\n apiKey: '',\n apiKeyConfigured: Boolean(payload.configured),\n apiKeyTail: payload.apiKeyTail ?? '',\n };\n } catch {\n return null;\n }\n}\n\nexport async function fetchMediaProvidersFromDaemon(): Promise<DaemonMediaProvidersFetchResult> {\n try {\n const response = await fetch('/api/media/config');\n if (!response.ok) return { status: 'error' };\n const payload = await response.json() as PublicMediaProviderConfigResponse;\n const rawProviders = payload.providers ?? {};\n const providers: AppConfig['mediaProviders'] = {};\n for (const [providerId, entry] of Object.entries(rawProviders)) {\n providers[providerId] = {\n apiKey: '',\n apiKeyConfigured: Boolean(entry?.configured),\n apiKeyTail: entry?.apiKeyTail ?? '',\n baseUrl: entry?.baseUrl ?? '',\n ...(typeof entry?.source === 'string' && entry.source.trim()\n ? { source: entry.source.trim() }\n : {}),\n ...(typeof entry?.model === 'string' && entry.model.trim()\n ? { model: entry.model.trim() }\n : {}),\n };\n }\n return {\n status: 'ok',\n providers,\n };\n } catch {\n return { status: 'error' };\n }\n}\n\nexport async function syncComposioConfigToDaemon(\n config: AppConfig['composio'] | undefined,\n): Promise<boolean> {\n const apiKey = config?.apiKey ?? '';\n const payload = {\n ...(apiKey.trim() || !config?.apiKeyConfigured ? { apiKey } : {}),\n };\n try {\n const response = await fetch('/api/connectors/composio/config', {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n });\n return response.ok;\n } catch {\n return false;\n }\n}\n\n// Privacy-sensitive fields the user can revoke. We deliberately keep\n// these out of localStorage so the daemon remains the single source of\n// truth: clearing app-config.json (or rotating via \"Delete my data\")\n// fully resets the install identity, with no residual cohort key\n// silently sitting in browser storage where the user can't see it.\nconst DAEMON_OWNED_KEYS = new Set<keyof AppConfig>([\n 'installationId',\n 'telemetry',\n 'privacyDecisionAt',\n]);\n\nconst AGENT_CLI_SECRET_ENV_KEYS = new Set(['ANTHROPIC_API_KEY', 'CODEX_API_KEY', 'OPENAI_API_KEY']);\n\nfunction sanitizeAgentCliEnv(agentCliEnv: AppConfig['agentCliEnv']): AppConfig['agentCliEnv'] {\n if (!agentCliEnv) return agentCliEnv;\n const sanitized: NonNullable<AppConfig['agentCliEnv']> = {};\n for (const [agentId, env] of Object.entries(agentCliEnv)) {\n const safeEnv = Object.fromEntries(\n Object.entries(env ?? {}).filter(([key]) => !AGENT_CLI_SECRET_ENV_KEYS.has(key)),\n );\n sanitized[agentId] = safeEnv;\n }\n return sanitized;\n}\n\nexport function saveConfig(config: AppConfig): void {\n const sanitized: AppConfig = { ...config, agentCliEnv: sanitizeAgentCliEnv(config.agentCliEnv) };\n for (const key of DAEMON_OWNED_KEYS) {\n delete (sanitized as unknown as Record<string, unknown>)[key];\n }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(sanitized));\n}\n\nexport function mergeDaemonConfig(\n localConfig: AppConfig,\n daemonConfig: AppConfigPrefs | null,\n): AppConfig {\n const next = { ...localConfig };\n if (!daemonConfig) return next;\n\n if (daemonConfig.onboardingCompleted != null) {\n next.onboardingCompleted = daemonConfig.onboardingCompleted;\n }\n if (daemonConfig.agentId !== undefined) {\n next.agentId = daemonConfig.agentId;\n }\n if (daemonConfig.skillId !== undefined) {\n next.skillId = daemonConfig.skillId;\n }\n if (daemonConfig.designSystemId !== undefined) {\n next.designSystemId = daemonConfig.designSystemId;\n }\n if (daemonConfig.agentModels) {\n next.agentModels = {\n ...(next.agentModels ?? {}),\n ...daemonConfig.agentModels,\n };\n }\n next.agentCliEnv = daemonConfig.agentCliEnv ?? {};\n if (daemonConfig.disabledSkills !== undefined) {\n next.disabledSkills = daemonConfig.disabledSkills;\n }\n if (daemonConfig.disabledDesignSystems !== undefined) {\n next.disabledDesignSystems = daemonConfig.disabledDesignSystems;\n }\n if (daemonConfig.orbit !== undefined) {\n next.orbit = normalizeOrbit(daemonConfig.orbit);\n }\n if (daemonConfig.installationId !== undefined) {\n next.installationId = daemonConfig.installationId;\n }\n if (daemonConfig.telemetry !== undefined) {\n next.telemetry = { ...daemonConfig.telemetry };\n }\n if (daemonConfig.privacyDecisionAt !== undefined) {\n next.privacyDecisionAt = daemonConfig.privacyDecisionAt;\n } else if (\n daemonConfig.installationId !== undefined ||\n daemonConfig.telemetry !== undefined\n ) {\n // One-shot migration for configs created before privacyDecisionAt\n // existed. If the daemon already has an id or telemetry prefs, the user\n // has resolved the first-run prompt and should not see it again.\n next.privacyDecisionAt = Date.now();\n }\n if (daemonConfig.customInstructions !== undefined) {\n next.customInstructions = daemonConfig.customInstructions ?? undefined;\n }\n if (daemonConfig.projectLocations !== undefined) {\n next.projectLocations = daemonConfig.projectLocations;\n }\n if (daemonConfig.defaultProjectLocationId !== undefined) {\n next.defaultProjectLocationId = daemonConfig.defaultProjectLocationId ?? 'default';\n }\n return next;\n}\n\nexport function mergeDaemonMediaProviders(\n localConfig: AppConfig,\n daemonProviders: AppConfig['mediaProviders'] | null,\n options?: {\n preserveLocalProviderIds?: ReadonlySet<string>;\n },\n): AppConfig {\n if (daemonProviders == null) {\n return { ...localConfig };\n }\n\n if (!hasAnyDaemonManagedMediaProvider(daemonProviders)) {\n return {\n ...localConfig,\n mediaProviders: Object.fromEntries(\n Object.entries(localConfig.mediaProviders ?? {}).filter(([, entry]) => !isMarkerOnlyMediaProviderEntry(entry)),\n ),\n };\n }\n\n const mediaProviders = { ...(localConfig.mediaProviders ?? {}) };\n for (const [providerId, daemonEntry] of Object.entries(daemonProviders ?? {})) {\n if (!isStoredMediaProviderEntryPresent(daemonEntry)) continue;\n const localEntry = mediaProviders[providerId];\n const preserveLocalPendingEdit = Boolean(\n options?.preserveLocalProviderIds?.has(providerId)\n && hasRecoverableLocalMediaProviderFields(localEntry),\n );\n mediaProviders[providerId] = preserveLocalPendingEdit\n ? { ...daemonEntry, ...localEntry }\n : { ...daemonEntry };\n }\n\n return {\n ...localConfig,\n mediaProviders,\n };\n}\n\nexport function hasAnyConfiguredProvider(\n providers: Record<string, MediaProviderCredentials> | undefined,\n): boolean {\n if (!providers) return false;\n return Object.values(providers).some((entry) => isStoredMediaProviderEntryPresent(entry));\n}\n\nexport function shouldSyncLocalMediaProvidersToDaemon(\n localProviders: Record<string, MediaProviderCredentials> | undefined,\n daemonProviders: Record<string, MediaProviderCredentials> | null | undefined,\n): boolean {\n return daemonProviders != null\n && Object.values(localProviders ?? {}).some((entry) => hasRecoverableLocalMediaProviderFields(entry))\n && !hasAnyDaemonManagedMediaProvider(daemonProviders);\n}\n\nexport async function syncMediaProvidersToDaemon(\n providers: Record<string, MediaProviderCredentials> | undefined,\n options?: {\n force?: boolean;\n daemonProviders?: Record<string, MediaProviderCredentials> | null;\n throwOnError?: boolean;\n },\n): Promise<void> {\n if (!providers) return;\n try {\n const payload = buildMediaProvidersForDaemonSave(\n providers,\n options?.daemonProviders,\n { force: options?.force },\n );\n const response = await fetch('/api/media/config', {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n });\n if (!response.ok) throw new Error(`Failed to sync media config (${response.status})`);\n } catch {\n if (options?.throwOnError) throw new Error('Media config save failed');\n // Daemon offline; localStorage keeps the user's copy for the next save.\n }\n}\n\nexport async function fetchDaemonConfig(): Promise<AppConfigPrefs | null> {\n try {\n const res = await fetch('/api/app-config');\n if (!res.ok) return null;\n const data = await res.json();\n return data?.config ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function syncConfigToDaemon(\n config: AppConfig,\n options?: { throwOnError?: boolean },\n): Promise<void> {\n const prefs: AppConfigPrefs = {\n onboardingCompleted: config.onboardingCompleted,\n agentId: config.agentId,\n agentModels: config.agentModels,\n agentCliEnv: config.agentCliEnv,\n skillId: config.skillId,\n designSystemId: config.designSystemId,\n disabledSkills: config.disabledSkills,\n disabledDesignSystems: config.disabledDesignSystems,\n orbit: normalizeOrbit(config.orbit),\n installationId: config.installationId,\n telemetry: config.telemetry,\n privacyDecisionAt: config.privacyDecisionAt,\n customInstructions: config.customInstructions ?? null,\n projectLocations: config.projectLocations ?? [],\n defaultProjectLocationId: config.defaultProjectLocationId ?? 'default',\n };\n try {\n const response = await fetch('/api/app-config', {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(prefs),\n });\n if (!response.ok) throw new Error(`Failed to sync app config (${response.status})`);\n } catch (error) {\n if (options?.throwOnError) throw error;\n // Daemon offline; localStorage keeps the user's copy for the next save.\n }\n}\n","import { effectiveMaxTokens } from '../state/maxTokens';\nimport type { AppConfig, ChatMessage } from '../types';\nimport type {\n ProxyImageContentBlock,\n ProxyMessage,\n ProxyMessageContent,\n ProxyTextContentBlock,\n} from '@open-design/contracts';\nimport { projectFileUrl } from './registry';\nimport type { StreamHandlers } from './anthropic';\nimport { parseSseFrame } from './sse';\nimport { isAnthropicSupportedImagePath } from '../utils/apiProtocol';\n\n/**\n * Optional per-request context that some protocols thread into the\n * proxy body or use to prepare provider-native message payloads:\n * - `projectId` lets the `generate_image` tool write into the active\n * project's folder instead of a daemon-global cache, and lets the\n * Anthropic proxy resolve image attachments into content blocks.\n * - `byokImageModel` is the user's BYOK Settings default for the\n * image tool. The LLM can still override per-call via the tool's\n * `model` arg; this is just the fallback when it omits one.\n * Other protocols ignore unknown body fields, so callers are free to\n * pass this for every protocol.\n */\nexport interface ProxyContext {\n projectId?: string;\n byokImageModel?: string;\n}\n\nexport async function streamProxyEndpoint(\n endpoint: string,\n cfg: AppConfig,\n system: string,\n history: ChatMessage[],\n signal: AbortSignal,\n handlers: StreamHandlers,\n context?: ProxyContext,\n): Promise<void> {\n if (!cfg.apiKey) {\n handlers.onError(new Error('Missing API key — open Settings and paste one in.'));\n return;\n }\n\n let acc = '';\n\n try {\n const messages = await buildProxyMessages(endpoint, history, context);\n const resp = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n baseUrl: cfg.baseUrl,\n apiKey: cfg.apiKey,\n model: cfg.model,\n systemPrompt: system,\n messages,\n maxTokens: effectiveMaxTokens(cfg),\n apiVersion: cfg.apiVersion,\n ...(context?.projectId ? { projectId: context.projectId } : {}),\n ...(context?.byokImageModel\n ? { byokImageModel: context.byokImageModel }\n : {}),\n }),\n signal,\n });\n\n if (!resp.ok || !resp.body) {\n const text = await resp.text().catch(() => '');\n handlers.onError(new Error(`proxy ${resp.status}: ${text || 'no body'}`));\n return;\n }\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n let buf = '';\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buf += decoder.decode(value, { stream: true });\n\n while (true) {\n const match = buf.match(/\\r?\\n\\r?\\n/);\n if (!match || match.index === undefined) break;\n const frame = buf.slice(0, match.index);\n buf = buf.slice(match.index + match[0].length);\n\n const parsed = parseSseFrame(frame);\n if (!parsed || parsed.kind !== 'event') continue;\n\n if (parsed.event === 'delta') {\n const text = String(parsed.data.delta ?? parsed.data.text ?? '');\n if (text) {\n acc += text;\n handlers.onDelta(text);\n }\n continue;\n }\n\n if (parsed.event === 'error') {\n handlers.onError(new Error(proxyErrorMessage(parsed.data)));\n return;\n }\n\n if (parsed.event === 'end') {\n handlers.onDone(acc);\n return;\n }\n }\n }\n\n handlers.onDone(acc);\n } catch (err) {\n if ((err as Error).name === 'AbortError') return;\n handlers.onError(err instanceof Error ? err : new Error(String(err)));\n }\n}\n\nexport async function buildProxyMessages(\n endpoint: string,\n history: ChatMessage[],\n context?: ProxyContext,\n): Promise<ProxyMessage[]> {\n if (!usesAnthropicMessagesPayload(endpoint) || !context?.projectId) {\n return history.map((m) => ({ role: m.role, content: m.content }));\n }\n\n const out: ProxyMessage[] = [];\n for (const message of history) {\n out.push({\n role: message.role,\n content: await buildAnthropicMessageContent(message, context.projectId),\n });\n }\n return out;\n}\n\nfunction usesAnthropicMessagesPayload(endpoint: string): boolean {\n return endpoint.includes('/api/proxy/anthropic/');\n}\n\nasync function buildAnthropicMessageContent(\n message: ChatMessage,\n projectId: string,\n): Promise<ProxyMessageContent> {\n const imageAttachments = (message.attachments ?? []).filter(\n (attachment) => attachment.kind === 'image',\n );\n if (message.role !== 'user' || imageAttachments.length === 0) {\n return message.content;\n }\n\n const blocks: Array<ProxyTextContentBlock | ProxyImageContentBlock> = [];\n if (message.content.trim()) {\n blocks.push({ type: 'text', text: message.content });\n }\n\n for (const attachment of imageAttachments) {\n const block = await readAnthropicImageBlock(projectId, attachment.path);\n if (block) {\n blocks.push(block);\n } else if (isAnthropicSupportedImagePath(attachment.path)) {\n blocks.push({\n type: 'text',\n text: `Attached image could not be sent as native image content: path: ${attachment.path} | name: ${attachment.name}`,\n });\n }\n }\n\n return blocks.length > 0 ? blocks : message.content;\n}\n\nasync function readAnthropicImageBlock(\n projectId: string,\n path: string,\n): Promise<ProxyImageContentBlock | null> {\n try {\n const resp = await fetch(projectFileUrl(projectId, path), { cache: 'no-store' });\n if (!resp.ok) return null;\n\n const mediaType = supportedAnthropicImageMediaType(\n resp.headers.get('content-type') ?? '',\n path,\n );\n if (!mediaType) return null;\n\n const bytes = new Uint8Array(await resp.arrayBuffer());\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: mediaType,\n data: bytesToBase64(bytes),\n },\n };\n } catch {\n return null;\n }\n}\n\nfunction supportedAnthropicImageMediaType(\n contentType: string,\n path: string,\n): 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp' | null {\n const normalized = contentType.split(';', 1)[0]?.trim().toLowerCase();\n if (\n normalized === 'image/jpeg' ||\n normalized === 'image/png' ||\n normalized === 'image/gif' ||\n normalized === 'image/webp'\n ) {\n return normalized;\n }\n const lower = path.toLowerCase();\n if (/\\.(jpe?g)$/.test(lower)) return 'image/jpeg';\n if (lower.endsWith('.png')) return 'image/png';\n if (lower.endsWith('.gif')) return 'image/gif';\n if (lower.endsWith('.webp')) return 'image/webp';\n return null;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n let out = '';\n let i = 0;\n for (; i + 2 < bytes.length; i += 3) {\n const n = (bytes[i]! << 16) | (bytes[i + 1]! << 8) | bytes[i + 2]!;\n out += alphabet[(n >> 18) & 63];\n out += alphabet[(n >> 12) & 63];\n out += alphabet[(n >> 6) & 63];\n out += alphabet[n & 63];\n }\n if (i < bytes.length) {\n const a = bytes[i]!;\n const b = i + 1 < bytes.length ? bytes[i + 1]! : 0;\n const n = (a << 16) | (b << 8);\n out += alphabet[(n >> 18) & 63];\n out += alphabet[(n >> 12) & 63];\n out += i + 1 < bytes.length ? alphabet[(n >> 6) & 63] : '=';\n out += '=';\n }\n return out;\n}\n\nfunction proxyErrorMessage(data: Record<string, unknown>): string {\n const nested = data.error;\n if (nested && typeof nested === 'object' && 'message' in nested) {\n const message = (nested as { message?: unknown }).message;\n if (typeof message === 'string' && message) return message;\n }\n return String(data.message ?? 'proxy error');\n}\n","import { isOpenAICompatible } from '../providers/openai-compatible';\nimport type { ApiProtocol, AppConfig } from '../types';\n\nconst API_PROTOCOL_LABELS: Record<ApiProtocol, string> = {\n anthropic: 'Anthropic API',\n openai: 'OpenAI API',\n azure: 'Azure OpenAI',\n google: 'Google Gemini',\n ollama: 'Ollama Cloud API',\n senseaudio: 'SenseAudio API',\n};\n\nconst API_PROTOCOL_AGENT_IDS: Record<ApiProtocol, string> = {\n anthropic: 'anthropic-api',\n openai: 'openai-api',\n azure: 'azure-openai-api',\n google: 'google-gemini-api',\n ollama: 'ollama-cloud-api',\n senseaudio: 'senseaudio-api',\n};\n\nexport function apiProtocolLabel(protocol: ApiProtocol | undefined): string {\n return API_PROTOCOL_LABELS[protocol ?? 'anthropic'];\n}\n\nexport function apiProtocolModelLabel(\n protocol: ApiProtocol | undefined,\n model: string,\n): string {\n const label = apiProtocolLabel(protocol);\n const trimmed = model.trim();\n return trimmed ? `${label} · ${trimmed}` : label;\n}\n\nexport function apiProtocolAgentId(protocol: ApiProtocol | undefined): string {\n return API_PROTOCOL_AGENT_IDS[protocol ?? 'anthropic'];\n}\n\nexport function usesAnthropicProxy(cfg: AppConfig): boolean {\n if (\n cfg.apiProtocol === 'azure' ||\n cfg.apiProtocol === 'ollama' ||\n cfg.apiProtocol === 'google' ||\n cfg.apiProtocol === 'senseaudio' ||\n cfg.apiProtocol === 'openai'\n ) {\n return false;\n }\n if (!cfg.apiProtocol && isOpenAICompatible(cfg.model, cfg.baseUrl)) {\n return false;\n }\n return Boolean(cfg.baseUrl && cfg.baseUrl !== 'https://api.anthropic.com');\n}\n\nexport function isAnthropicSupportedImagePath(path: string): boolean {\n const lower = path.toLowerCase();\n return /\\.(jpe?g|png|gif|webp)$/.test(lower);\n}\n","/**\n * OpenAI-compatible API provider. Works with any service that exposes the\n * /v1/chat/completions endpoint (e.g. MiMo, DeepSeek, Groq, Together, etc.).\n *\n * Routes through the daemon proxy to avoid browser CORS issues.\n * BYOK — the key stays on the user's machine.\n */\nimport type { AppConfig, ChatMessage } from '../types';\nimport type { StreamHandlers } from './anthropic';\nimport { streamProxyEndpoint } from './api-proxy';\n\nexport async function streamMessageOpenAI(\n cfg: AppConfig,\n system: string,\n history: ChatMessage[],\n signal: AbortSignal,\n handlers: StreamHandlers,\n): Promise<void> {\n return streamProxyEndpoint('/api/proxy/openai/stream', cfg, system, history, signal, handlers);\n}\n\n/**\n * Detect whether a model ID / base URL should use the OpenAI-compatible\n * provider rather than the Anthropic SDK.\n */\nexport function isOpenAICompatible(model: string, baseUrl: string): boolean {\n const m = model.toLowerCase();\n const u = baseUrl.toLowerCase();\n const parsed = new URL(u || 'https://api.anthropic.com', 'https://local.invalid');\n const pathSegments = parsed.pathname.split('/').filter(Boolean);\n const isOfficialAnthropic = parsed.hostname === 'api.anthropic.com';\n const isAnthropicEndpoint = pathSegments.at(-1) === 'anthropic' || (\n /^v\\d+$/.test(pathSegments.at(-1) ?? '') && pathSegments.at(-2) === 'anthropic'\n );\n\n // Anthropic endpoint paths should win for providers that expose both\n // protocol shapes on the same host, e.g. /v1/anthropic or /anthropic/v1.\n if (isAnthropicEndpoint) return false;\n\n // Explicit OpenAI-compatible providers/models should win even when a host or\n // unrelated path segment happens to contain the word \"anthropic\".\n if (u.includes('xiaomimimo.com/v1')) return true;\n if (u.includes('api.minimaxi.com/v1')) return true;\n if (u.includes('api.deepseek')) return true;\n if (u.includes('api.groq')) return true;\n if (u.includes('api.together')) return true;\n if (u.includes('openrouter')) return true;\n if (u.includes('openai.com')) return true;\n if (m.startsWith('deepseek')) return true;\n if (m.startsWith('groq') || m.startsWith('llama') || m.startsWith('mixtral')) return true;\n if (m.startsWith('gpt-') || m.startsWith('o1') || m.startsWith('o3') || m.startsWith('o4')) return true;\n\n // MiMo exposes both OpenAI-compatible (/v1) and Anthropic-compatible\n // (/anthropic) endpoints with the same model names, so path shape must break\n // the tie for this provider.\n if (m.startsWith('mimo')) return true;\n\n // If the base URL is custom and not clearly Anthropic-compatible, preserve\n // the existing OpenAI-compatible fallback for third-party providers.\n if (u && !isOfficialAnthropic) return true;\n return false;\n}\n","import type { AppTheme } from '../types';\n\nconst ACCENT_VARS = [\n '--accent',\n '--accent-strong',\n '--accent-soft',\n '--accent-tint',\n '--accent-hover',\n] as const;\n\nexport const DEFAULT_ACCENT_COLOR = '#c96442';\nexport const ACCENT_SWATCHES = [\n DEFAULT_ACCENT_COLOR,\n '#2563eb',\n '#7c3aed',\n '#059669',\n '#dc2626',\n '#d97706',\n '#0891b2',\n '#db2777',\n] as const;\n\nexport function normalizeAccentColor(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim();\n return /^#[0-9a-fA-F]{6}$/.test(trimmed) ? trimmed.toLowerCase() : null;\n}\n\nexport function resolveAccentColor(value: unknown): string {\n return normalizeAccentColor(value) ?? DEFAULT_ACCENT_COLOR;\n}\n\nfunction accentVars(accentColor: string): Record<(typeof ACCENT_VARS)[number], string> {\n return {\n '--accent': accentColor,\n // Keep these mix ratios in sync with the pre-hydration script in app/layout.tsx.\n '--accent-strong': `color-mix(in srgb, ${accentColor} 86%, var(--text-strong))`,\n '--accent-soft': `color-mix(in srgb, ${accentColor} 22%, var(--bg-panel))`,\n '--accent-tint': `color-mix(in srgb, ${accentColor} 12%, var(--bg-panel))`,\n '--accent-hover': `color-mix(in srgb, ${accentColor} 90%, var(--text-strong))`,\n };\n}\n\nexport function applyAppearanceToDocument({\n theme,\n accentColor,\n}: {\n theme?: AppTheme;\n accentColor?: string;\n}): void {\n const root = document.documentElement;\n if (theme === 'light' || theme === 'dark') {\n root.setAttribute('data-theme', theme);\n } else {\n root.removeAttribute('data-theme');\n }\n\n const normalized = resolveAccentColor(accentColor);\n const vars = accentVars(normalized);\n for (const name of ACCENT_VARS) {\n root.style.setProperty(name, vars[name]);\n }\n}\n","import type { Dict } from '../i18n/types';\n\nexport type SoundId = string;\n\nexport interface SoundOption {\n id: SoundId;\n labelKey: keyof Dict;\n}\n\nexport const SUCCESS_SOUNDS: SoundOption[] = [\n { id: 'ding', labelKey: 'settings.notifySoundDing' },\n { id: 'chime', labelKey: 'settings.notifySoundChime' },\n { id: 'two-tone-up', labelKey: 'settings.notifySoundTwoToneUp' },\n { id: 'pluck', labelKey: 'settings.notifySoundPluck' },\n];\n\nexport const FAILURE_SOUNDS: SoundOption[] = [\n { id: 'buzz', labelKey: 'settings.notifySoundBuzz' },\n { id: 'two-tone-down', labelKey: 'settings.notifySoundTwoToneDown' },\n { id: 'thud', labelKey: 'settings.notifySoundThud' },\n];\n\nexport const DEFAULT_SUCCESS_SOUND_ID: SoundId = 'ding';\nexport const DEFAULT_FAILURE_SOUND_ID: SoundId = 'buzz';\n\ntype AudioCtxCtor = typeof AudioContext;\ntype NotificationOptionsWithBrowserExtensions = NotificationOptions & {\n renotify?: boolean;\n};\n\nlet ctx: AudioContext | null = null;\nconst activeNotifications = new Set<Notification>();\nconst SERVICE_WORKER_URL = '/od-notifications-sw.js';\n\nfunction getCtx(): AudioContext | null {\n if (typeof window === 'undefined') return null;\n const Ctor: AudioCtxCtor | undefined =\n window.AudioContext ??\n (window as unknown as { webkitAudioContext?: AudioCtxCtor }).webkitAudioContext;\n if (!Ctor) return null;\n if (!ctx) {\n try {\n ctx = new Ctor();\n } catch {\n return null;\n }\n }\n if (ctx && ctx.state === 'suspended') {\n void ctx.resume().catch(() => {\n // Autoplay policy can refuse — fall through silently. The next\n // user-gesture-driven call will retry.\n });\n }\n return ctx;\n}\n\ninterface ToneSpec {\n freq: number;\n type: OscillatorType;\n start: number;\n duration: number;\n gain?: number;\n // Optional lowpass cutoff applied via a BiquadFilter for plucky textures.\n lowpass?: number;\n}\n\nfunction playTones(c: AudioContext, tones: ToneSpec[]): void {\n const now = c.currentTime;\n for (const tone of tones) {\n const osc = c.createOscillator();\n const gain = c.createGain();\n osc.type = tone.type;\n osc.frequency.value = tone.freq;\n const peak = tone.gain ?? 0.18;\n const startAt = now + tone.start;\n const endAt = startAt + tone.duration;\n // Short attack to avoid clicks; exponential-ish decay via linear ramp\n // to a near-zero value (exponentialRamp can't reach 0).\n gain.gain.setValueAtTime(0.0001, startAt);\n gain.gain.linearRampToValueAtTime(peak, startAt + Math.min(0.005, tone.duration * 0.2));\n gain.gain.exponentialRampToValueAtTime(0.0001, endAt);\n\n let last: AudioNode = osc;\n if (tone.lowpass) {\n const lp = c.createBiquadFilter();\n lp.type = 'lowpass';\n lp.frequency.value = tone.lowpass;\n osc.connect(lp);\n last = lp;\n }\n last.connect(gain);\n gain.connect(c.destination);\n osc.start(startAt);\n osc.stop(endAt + 0.02);\n }\n}\n\nconst SOUND_PLAYERS: Record<SoundId, (c: AudioContext) => void> = {\n ding: (c) => {\n playTones(c, [{ freq: 880, type: 'sine', start: 0, duration: 0.25, gain: 0.22 }]);\n },\n chime: (c) => {\n playTones(c, [\n { freq: 880, type: 'triangle', start: 0, duration: 0.4, gain: 0.18 },\n { freq: 1320, type: 'triangle', start: 0, duration: 0.4, gain: 0.12 },\n ]);\n },\n 'two-tone-up': (c) => {\n playTones(c, [\n { freq: 660, type: 'square', start: 0, duration: 0.08, gain: 0.16 },\n { freq: 990, type: 'square', start: 0.09, duration: 0.08, gain: 0.16 },\n ]);\n },\n pluck: (c) => {\n playTones(c, [\n { freq: 220, type: 'sawtooth', start: 0, duration: 0.15, gain: 0.22, lowpass: 1200 },\n ]);\n },\n buzz: (c) => {\n playTones(c, [\n { freq: 165, type: 'square', start: 0, duration: 0.06, gain: 0.2 },\n { freq: 165, type: 'square', start: 0.1, duration: 0.06, gain: 0.2 },\n { freq: 165, type: 'square', start: 0.2, duration: 0.06, gain: 0.2 },\n ]);\n },\n 'two-tone-down': (c) => {\n playTones(c, [\n { freq: 880, type: 'sine', start: 0, duration: 0.12, gain: 0.2 },\n { freq: 440, type: 'sine', start: 0.13, duration: 0.12, gain: 0.2 },\n ]);\n },\n thud: (c) => {\n playTones(c, [{ freq: 80, type: 'sine', start: 0, duration: 0.12, gain: 0.32 }]);\n },\n};\n\nexport function playSound(id: SoundId): void {\n const c = getCtx();\n if (!c) return;\n const player = SOUND_PLAYERS[id];\n if (!player) return;\n try {\n player(c);\n } catch {\n // A node creation / connection failure should never throw out to UI code.\n }\n}\n\nexport function previewSuccess(id: SoundId): void {\n playSound(id);\n}\n\nexport function previewFailure(id: SoundId): void {\n playSound(id);\n}\n\nexport function notificationPermission(): NotificationPermission | 'unsupported' {\n if (typeof Notification === 'undefined') return 'unsupported';\n return Notification.permission;\n}\n\nexport async function requestNotificationPermission(): Promise<\n NotificationPermission | 'unsupported'\n> {\n if (typeof Notification === 'undefined') return 'unsupported';\n if (Notification.permission === 'granted' || Notification.permission === 'denied') {\n return Notification.permission;\n }\n try {\n return await Notification.requestPermission();\n } catch {\n return 'denied';\n }\n}\n\nexport interface CompletionNotificationOpts {\n status: 'succeeded' | 'failed';\n title: string;\n body: string;\n onClick?: () => void;\n}\n\nexport type CompletionNotificationResult =\n | 'shown'\n | 'unsupported'\n | 'permission-denied'\n | 'failed';\n\nfunction notificationOptionsFor(\n opts: CompletionNotificationOpts,\n): NotificationOptionsWithBrowserExtensions {\n const tag = `od-task-${opts.status}`;\n return {\n body: opts.body,\n tag,\n renotify: true,\n data: {\n status: opts.status,\n url: typeof window === 'undefined' ? '/' : window.location.href,\n },\n };\n}\n\nasync function showViaServiceWorker(\n opts: CompletionNotificationOpts,\n): Promise<CompletionNotificationResult | null> {\n if (typeof navigator === 'undefined' || !('serviceWorker' in navigator)) return null;\n try {\n const registration = await navigator.serviceWorker.register(SERVICE_WORKER_URL);\n const readyRegistration = await navigator.serviceWorker.ready.catch(() => registration);\n if (!readyRegistration.showNotification) return null;\n await readyRegistration.showNotification(opts.title, notificationOptionsFor(opts));\n return 'shown';\n } catch {\n return null;\n }\n}\n\nfunction showViaConstructor(opts: CompletionNotificationOpts): CompletionNotificationResult {\n if (typeof Notification === 'undefined') return 'unsupported';\n if (Notification.permission !== 'granted') return 'permission-denied';\n try {\n const note = new Notification(opts.title, notificationOptionsFor(opts));\n activeNotifications.add(note);\n const release = () => {\n note.onclick = null;\n note.onclose = null;\n note.onerror = null;\n activeNotifications.delete(note);\n };\n note.onclick = () => {\n try {\n if (typeof window !== 'undefined') window.focus();\n } catch {\n /* ignore */\n }\n opts.onClick?.();\n try {\n note.close();\n } catch {\n /* ignore */\n }\n };\n note.onclose = release;\n note.onerror = release;\n return 'shown';\n } catch {\n return 'failed';\n }\n}\n\nexport async function showCompletionNotification(\n opts: CompletionNotificationOpts,\n): Promise<CompletionNotificationResult> {\n if (typeof Notification === 'undefined') return 'unsupported';\n if (Notification.permission !== 'granted') return 'permission-denied';\n return (await showViaServiceWorker(opts)) ?? showViaConstructor(opts);\n}\n","import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { useT } from '../../i18n';\nimport type { PetConfig } from '../../types';\nimport {\n pickAmbientRow,\n preferredRowId,\n resolveActivePet,\n type PetInteraction,\n} from './pets';\nimport { PetSpriteFace } from './PetSpriteFace';\n\ninterface Props {\n pet: PetConfig | undefined;\n taskCenter?: PetTaskCenter;\n onOpenProject?: (projectId: string) => void;\n persistentBubble?: boolean;\n}\n\nconst STORAGE_KEY = 'open-design:pet-position';\n\nexport interface PetTaskSummary {\n projectId: string;\n projectName: string;\n status: 'queued' | 'running';\n count: number;\n}\n\nexport interface PetRecentTaskSummary {\n projectId: string;\n projectName: string;\n status: 'succeeded' | 'failed' | 'canceled';\n updatedAt: number;\n}\n\nexport interface PetTaskCenter {\n running: PetTaskSummary[];\n queued: PetTaskSummary[];\n recent: PetRecentTaskSummary[];\n}\n\nconst EMPTY_TASK_CENTER: PetTaskCenter = {\n running: [],\n queued: [],\n recent: [],\n};\n\ninterface Position {\n // Distances from the right/bottom of the viewport so the overlay\n // sticks to the corner across resizes. Saved in localStorage.\n right: number;\n bottom: number;\n}\n\nconst DEFAULT_POSITION: Position = { right: 24, bottom: 24 };\n\n// How long the pet has to sit untouched before the overlay flips to\n// the \"waiting\" animation row. Sized to sit comfortably past a few\n// ambient beats so the pet clearly feels alive before falling through\n// to the more static \"bored\" cue.\nconst WAITING_AFTER_MS = 45000;\n\n// Ambient idle choreography — while nobody is hovering / dragging, the\n// overlay occasionally swaps the `idle` row for a random non-idle row\n// from the atlas (wave, hop, look around) so the pet visibly has a\n// life of its own instead of breathing in place forever. Each ambient\n// \"beat\" plays for a chunk of time, then the pet returns to idle for\n// a longer rest window before the next beat. Randomising both windows\n// prevents the rhythm from feeling mechanical, and the rest window is\n// intentionally generous so the pet reads as calm rather than fidgety.\nconst AMBIENT_PLAY_MIN_MS = 1400;\nconst AMBIENT_PLAY_VARIANCE_MS = 900;\nconst AMBIENT_REST_MIN_MS = 9000;\nconst AMBIENT_REST_VARIANCE_MS = 9000;\nconst AMBIENT_INITIAL_DELAY_MIN_MS = 4000;\nconst AMBIENT_INITIAL_DELAY_VARIANCE_MS = 3000;\n\n// Filters pointer jitter and accidental nudges before the overlay\n// commits to a directional running animation. Picked to feel\n// responsive without flickering on small mouse wiggles.\nconst DRAG_GESTURE_MIN_PX = 14;\n// Require one axis to clearly dominate before swapping running-* for\n// jumping/waving so diagonal drags don't strobe between rows.\nconst DRAG_AXIS_BIAS = 1.18;\n\nconst IDLE_QUOTE_COUNT = 6;\n\nfunction recentTaskKey(task: PetRecentTaskSummary): string {\n return `${task.projectId}:${task.updatedAt}`;\n}\n\nfunction loadPosition(): Position {\n if (typeof window === 'undefined') return DEFAULT_POSITION;\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return DEFAULT_POSITION;\n const parsed = JSON.parse(raw) as Partial<Position>;\n return {\n right: typeof parsed.right === 'number' ? parsed.right : DEFAULT_POSITION.right,\n bottom: typeof parsed.bottom === 'number' ? parsed.bottom : DEFAULT_POSITION.bottom,\n };\n } catch {\n return DEFAULT_POSITION;\n }\n}\n\nfunction savePosition(p: Position) {\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(p));\n } catch {\n /* ignore */\n }\n}\n\n// Compact floating sprite + speech bubble. Rendered at the document\n// root via App.tsx so it stays put when the user navigates between\n// the entry and project views.\nexport function PetOverlay({\n pet,\n taskCenter = EMPTY_TASK_CENTER,\n onOpenProject,\n persistentBubble = false,\n}: Props) {\n const t = useT();\n const active = useMemo(() => resolveActivePet(pet), [pet]);\n const [bubbleOpen, setBubbleOpen] = useState(persistentBubble);\n const [acknowledgedRecentKeys, setAcknowledgedRecentKeys] = useState<Set<string>>(() => new Set());\n const [viewingRecentKeys, setViewingRecentKeys] = useState<Set<string>>(() => new Set());\n const [ambientIdx, setAmbientIdx] = useState(0);\n const [position, setPosition] = useState<Position>(() => loadPosition());\n // Interaction state drives which atlas row plays. Only meaningful\n // for atlas-backed custom pets — the renderer ignores it for emoji\n // / single-strip pets.\n const [interaction, setInteraction] = useState<PetInteraction>('idle');\n // Ambient row id that temporarily overrides the `idle` row. Null\n // whenever the pet is resting on its baseline row so the user-facing\n // interaction state wins as soon as a gesture fires.\n const [ambientRowId, setAmbientRowId] = useState<string | null>(null);\n const [hovered, setHovered] = useState(false);\n const dragRef = useRef<{\n startX: number;\n startY: number;\n startRight: number;\n startBottom: number;\n moved: boolean;\n // Last classified gesture direction. Kept on the ref so we don't\n // trigger a state update + render on every pointermove tick.\n direction: 'right' | 'left' | 'up' | 'down' | null;\n } | null>(null);\n // Idle timer that flips the pet to the `waiting` row after a few\n // seconds without hover or drag. Reset by every interaction.\n const waitingTimerRef = useRef<number | null>(null);\n\n // Show the greeting briefly the first time the overlay mounts after a\n // wake. Auto-tuck the bubble after 4s so it does not linger forever.\n useEffect(() => {\n if (!active) return;\n setBubbleOpen(true);\n if (persistentBubble) return;\n const id = window.setTimeout(() => setBubbleOpen(false), 4000);\n return () => window.clearTimeout(id);\n }, [active?.id, persistentBubble]);\n\n useEffect(() => {\n savePosition(position);\n }, [position]);\n\n const idleQuotes = useMemo(\n () => [\n {\n text: t('pet.idleQuote.leonardo.text'),\n author: t('pet.idleQuote.leonardo.author'),\n },\n {\n text: t('pet.idleQuote.michelangelo.text'),\n author: t('pet.idleQuote.michelangelo.author'),\n },\n {\n text: t('pet.idleQuote.bernini.text'),\n author: t('pet.idleQuote.bernini.author'),\n },\n {\n text: t('pet.idleQuote.raphael.text'),\n author: t('pet.idleQuote.raphael.author'),\n },\n {\n text: t('pet.idleQuote.caravaggio.text'),\n author: t('pet.idleQuote.caravaggio.author'),\n },\n {\n text: t('pet.idleQuote.rodin.text'),\n author: t('pet.idleQuote.rodin.author'),\n },\n ],\n [t],\n );\n const visibleQuote = idleQuotes[ambientIdx % IDLE_QUOTE_COUNT] ?? idleQuotes[0];\n const activeTasks = [...taskCenter.running, ...taskCenter.queued];\n const unacknowledgedRecentTasks = taskCenter.recent.filter(\n (task) => !acknowledgedRecentKeys.has(recentTaskKey(task)),\n );\n const visibleRecentTasks = bubbleOpen\n ? persistentBubble && viewingRecentKeys.size === 0\n ? unacknowledgedRecentTasks\n : taskCenter.recent.filter((task) => viewingRecentKeys.has(recentTaskKey(task)))\n : unacknowledgedRecentTasks;\n const activeTaskCount = activeTasks.reduce((sum, task) => sum + task.count, 0);\n const recentTaskCount = visibleRecentTasks.length;\n const taskTotal = activeTaskCount + recentTaskCount;\n const badgeTotal = activeTaskCount + unacknowledgedRecentTasks.length;\n const taskSummaryLine =\n activeTaskCount > 0\n ? t(\n activeTaskCount === 1\n ? 'pet.taskSummarySingle'\n : 'pet.taskSummaryMultiple',\n {\n count: activeTaskCount,\n projects: new Set(activeTasks.map((task) => task.projectId)).size,\n },\n )\n : recentTaskCount > 0\n ? t(\n recentTaskCount === 1\n ? 'pet.taskSummaryRecentSingle'\n : 'pet.taskSummaryRecentMultiple',\n { count: recentTaskCount },\n )\n : '';\n const visibleLine = taskSummaryLine || visibleQuote?.text || active?.greeting || '';\n const taskRowId =\n taskTotal > 0 && interaction === 'idle' ? 'waiting' : undefined;\n\n const acknowledgeRecentTasks = useCallback((tasks: PetRecentTaskSummary[]) => {\n if (tasks.length === 0) {\n setViewingRecentKeys(new Set());\n return;\n }\n const keys = tasks.map(recentTaskKey);\n setViewingRecentKeys(new Set(keys));\n setAcknowledgedRecentKeys((prev) => {\n const next = new Set(prev);\n for (const key of keys) next.add(key);\n return next;\n });\n }, []);\n\n // (Re)arms the long-idle waiting timer. Called every time the user\n // interacts so an active session never falls into \"waiting\" mid-drag.\n const armWaitingTimer = useCallback(() => {\n if (waitingTimerRef.current != null) {\n window.clearTimeout(waitingTimerRef.current);\n }\n waitingTimerRef.current = window.setTimeout(() => {\n // Only escalate to `waiting` from a calm `idle` baseline; an\n // active hover / drag should keep their own animation.\n setInteraction((prev) => (prev === 'idle' ? 'waiting' : prev));\n waitingTimerRef.current = null;\n }, WAITING_AFTER_MS);\n }, []);\n\n // Start the idle clock when the pet becomes visible / changes.\n useEffect(() => {\n if (!active) return;\n armWaitingTimer();\n return () => {\n if (waitingTimerRef.current != null) {\n window.clearTimeout(waitingTimerRef.current);\n waitingTimerRef.current = null;\n }\n };\n }, [active?.id, armWaitingTimer]);\n\n // Ambient idle choreography scheduler. Only runs while the pet is in\n // `idle` and has an atlas with ambient-eligible rows; otherwise we\n // bail out and leave the base row alone. The effect is deliberately\n // scoped to `interaction === 'idle'` so any user gesture\n // (hover / drag / pointerdown) cancels the currently playing beat via\n // cleanup and the user-facing state takes over instantly.\n useEffect(() => {\n if (interaction !== 'idle') {\n setAmbientRowId(null);\n return;\n }\n const atlas = active?.atlas;\n if (!atlas || atlas.rowsDef.length === 0) return;\n\n let playTimer: number | undefined;\n let restTimer: number | undefined;\n let lastPlayedId: string | undefined;\n\n const playBeat = () => {\n const def = pickAmbientRow(atlas, lastPlayedId);\n if (!def) return;\n lastPlayedId = def.id;\n setAmbientRowId(def.id);\n const playMs =\n AMBIENT_PLAY_MIN_MS + Math.floor(Math.random() * AMBIENT_PLAY_VARIANCE_MS);\n playTimer = window.setTimeout(() => {\n setAmbientRowId(null);\n const restMs =\n AMBIENT_REST_MIN_MS + Math.floor(Math.random() * AMBIENT_REST_VARIANCE_MS);\n restTimer = window.setTimeout(playBeat, restMs);\n }, playMs);\n };\n\n // Let the pet breathe for a moment before the first beat so a\n // freshly-woken overlay doesn't snap straight into a flourish.\n const initialDelay =\n AMBIENT_INITIAL_DELAY_MIN_MS +\n Math.floor(Math.random() * AMBIENT_INITIAL_DELAY_VARIANCE_MS);\n restTimer = window.setTimeout(playBeat, initialDelay);\n\n return () => {\n if (playTimer != null) window.clearTimeout(playTimer);\n if (restTimer != null) window.clearTimeout(restTimer);\n setAmbientRowId(null);\n };\n }, [interaction, active?.id, active?.atlas]);\n\n if (!active) return null;\n\n const onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) return;\n const target = event.currentTarget;\n target.setPointerCapture(event.pointerId);\n dragRef.current = {\n startX: event.clientX,\n startY: event.clientY,\n startRight: position.right,\n startBottom: position.bottom,\n moved: false,\n direction: null,\n };\n armWaitingTimer();\n };\n\n const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const drag = dragRef.current;\n if (!drag) return;\n const dx = event.clientX - drag.startX;\n const dy = event.clientY - drag.startY;\n if (!drag.moved && Math.abs(dx) + Math.abs(dy) < 4) return;\n drag.moved = true;\n // Convert pointer movement into right/bottom offsets so the sprite\n // tracks the cursor while staying anchored to the corner system.\n // The clamp budget (~120px) keeps the 96px sprite plus its drop\n // shadow on-screen even when dragged toward the opposite edge.\n const nextRight = Math.max(8, Math.min(window.innerWidth - 120, drag.startRight - dx));\n const nextBottom = Math.max(8, Math.min(window.innerHeight - 120, drag.startBottom - dy));\n setPosition({ right: nextRight, bottom: nextBottom });\n\n // Classify the gesture direction once it clears the jitter floor\n // and one axis clearly dominates the other. The animation then\n // sticks until the user reverses past the threshold again.\n const absX = Math.abs(dx);\n const absY = Math.abs(dy);\n if (absX < DRAG_GESTURE_MIN_PX && absY < DRAG_GESTURE_MIN_PX) return;\n let dir: 'right' | 'left' | 'up' | 'down' | null = null;\n if (absX >= absY * DRAG_AXIS_BIAS) {\n dir = dx > 0 ? 'right' : 'left';\n } else if (absY >= absX * DRAG_AXIS_BIAS) {\n dir = dy < 0 ? 'up' : 'down';\n }\n if (dir && dir !== drag.direction) {\n drag.direction = dir;\n setInteraction(\n dir === 'right'\n ? 'drag-right'\n : dir === 'left'\n ? 'drag-left'\n : dir === 'up'\n ? 'drag-up'\n : 'drag-down',\n );\n }\n armWaitingTimer();\n };\n\n const onPointerUp = (event: React.PointerEvent<HTMLDivElement>) => {\n const drag = dragRef.current;\n dragRef.current = null;\n try {\n event.currentTarget.releasePointerCapture(event.pointerId);\n } catch {\n /* ignore */\n }\n // A tap (no drag) toggles the speech bubble and rotates the line.\n if (drag && !drag.moved) {\n if (unacknowledgedRecentTasks.length > 0) {\n setBubbleOpen(true);\n setAmbientIdx((i) => i + 1);\n acknowledgeRecentTasks(unacknowledgedRecentTasks);\n } else {\n setBubbleOpen((open) => {\n const next = !open;\n if (next) {\n setAmbientIdx((i) => i + 1);\n } else {\n setViewingRecentKeys(new Set());\n }\n return next;\n });\n }\n }\n // After the drag ends, fall back to the resting animation so the\n // pet stops \"running\" the moment the user lets go. Hovered state\n // wins so a release-into-hover keeps the wave going.\n setInteraction(hovered ? 'hover' : 'idle');\n armWaitingTimer();\n };\n\n const onPointerEnter = () => {\n setHovered(true);\n // Don't override an active drag direction with the hover wave —\n // the user is mid-gesture and they expect the running cycle to\n // keep playing until they let go.\n if (!dragRef.current) setInteraction('hover');\n armWaitingTimer();\n };\n\n const onPointerLeave = () => {\n setHovered(false);\n if (!dragRef.current) setInteraction('idle');\n armWaitingTimer();\n };\n\n return (\n <div\n className=\"pet-overlay\"\n role=\"complementary\"\n aria-label={t('pet.overlayAria')}\n style={{\n right: position.right,\n bottom: position.bottom,\n // The accent drives the halo, the bubble border, and the focus\n // ring on the action buttons via CSS custom property cascade.\n ['--pet-accent' as string]: active.accent,\n }}\n >\n {bubbleOpen ? (\n <div className=\"pet-bubble\" role=\"status\">\n <div className=\"pet-bubble-name\">{active.name}</div>\n {taskTotal > 0 ? (\n <div className=\"pet-bubble-line\">{visibleLine}</div>\n ) : (\n <figure className=\"pet-idle-quote\">\n <blockquote>{visibleLine}</blockquote>\n {visibleQuote?.author ? <figcaption>{visibleQuote.author}</figcaption> : null}\n </figure>\n )}\n {taskTotal > 0 ? (\n <div className=\"pet-task-list\" aria-label={t('pet.taskListAria')}>\n <TaskGroup\n title={t('pet.taskGroup.running')}\n tasks={taskCenter.running}\n onOpenProject={onOpenProject}\n openTitle={(project) => t('pet.taskOpenProject', { project })}\n />\n <TaskGroup\n title={t('pet.taskGroup.queued')}\n tasks={taskCenter.queued}\n onOpenProject={onOpenProject}\n openTitle={(project) => t('pet.taskOpenProject', { project })}\n />\n <RecentTaskGroup\n title={t('pet.taskGroup.recent')}\n tasks={visibleRecentTasks}\n onOpenProject={onOpenProject}\n openTitle={(project) => t('pet.taskOpenProject', { project })}\n />\n </div>\n ) : null}\n </div>\n ) : null}\n <div\n className=\"pet-sprite\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n title={t('pet.spriteTitle', { name: active.name })}\n aria-label={t('pet.spriteAria', { name: active.name })}\n data-pet-state={interaction}\n data-pet-ambient={ambientRowId ?? undefined}\n style={{\n // For atlas-backed pets the row swap *is* the animation, so\n // we let the sprite element sit still and animate frames\n // inside it. Built-ins / single-strip uploads keep their\n // gentle CSS-named bob via --pet-anim.\n ['--pet-anim' as string]: active.atlas\n ? 'none'\n : `pet-${active.animation}`,\n }}\n >\n <PetSpriteFace\n active={active}\n className=\"pet-sprite-glyph\"\n rowId={ambientRowId ?? taskRowId ?? preferredRowId(interaction)}\n />\n {badgeTotal > 0 ? (\n <span className=\"pet-sprite-status\" aria-label={visibleLine}>\n {badgeTotal}\n </span>\n ) : null}\n <span className=\"pet-sprite-shadow\" aria-hidden />\n </div>\n </div>\n );\n}\n\nfunction TaskItem({\n children,\n clickable,\n onClick,\n title,\n}: {\n children: ReactNode;\n clickable: boolean;\n onClick?: () => void;\n title: string;\n}) {\n if (clickable) {\n return (\n <button\n type=\"button\"\n className=\"pet-task-item\"\n onClick={onClick}\n title={title}\n >\n {children}\n </button>\n );\n }\n return (\n <div className=\"pet-task-item pet-task-item--static\" title={title}>\n {children}\n </div>\n );\n}\n\nfunction TaskGroup({\n title,\n tasks,\n onOpenProject,\n openTitle,\n}: {\n title: string;\n tasks: PetTaskSummary[];\n onOpenProject?: (projectId: string) => void;\n openTitle: (projectName: string) => string;\n}) {\n if (tasks.length === 0) return null;\n return (\n <section className=\"pet-task-group\">\n <div className=\"pet-task-group-title\">{title}</div>\n {tasks.slice(0, 3).map((task) => (\n <TaskItem\n key={task.projectId}\n clickable={Boolean(onOpenProject)}\n onClick={onOpenProject ? () => onOpenProject(task.projectId) : undefined}\n title={openTitle(task.projectName)}\n >\n <span\n className=\"pet-task-dot\"\n data-pet-task-status={task.status}\n aria-hidden\n />\n <span className=\"pet-task-name\">{task.projectName}</span>\n {task.count > 1 ? (\n <span className=\"pet-task-count\">{task.count}</span>\n ) : null}\n </TaskItem>\n ))}\n </section>\n );\n}\n\nfunction RecentTaskGroup({\n title,\n tasks,\n onOpenProject,\n openTitle,\n}: {\n title: string;\n tasks: PetRecentTaskSummary[];\n onOpenProject?: (projectId: string) => void;\n openTitle: (projectName: string) => string;\n}) {\n if (tasks.length === 0) return null;\n return (\n <section className=\"pet-task-group\">\n <div className=\"pet-task-group-title\">{title}</div>\n {tasks.slice(0, 3).map((task) => (\n <TaskItem\n key={`${task.projectId}:${task.updatedAt}`}\n clickable={Boolean(onOpenProject)}\n onClick={onOpenProject ? () => onOpenProject(task.projectId) : undefined}\n title={openTitle(task.projectName)}\n >\n <span\n className=\"pet-task-dot\"\n data-pet-task-status={task.status}\n aria-hidden\n />\n <span className=\"pet-task-name\">{task.projectName}</span>\n </TaskItem>\n ))}\n </section>\n );\n}\n","import type { AppConfig, CodexPetSummary, PetAtlasLayout, PetAtlasRowDef, PetCustom, PetConfig } from '../../types';\nimport {\n codexPetSpritesheetUrl,\n fetchCodexPets,\n} from '../../providers/registry';\nimport { prepareCodexAtlas } from './codexAtlas';\n\n// Built-in pet catalog. Historically this listed a handful of emoji-only\n// pets (Mochi, Pixel, Foxy…), but those felt boring next to the rich\n// hatch-pet sprite atlases bundled under `assets/community-pets/`. The\n// \"Built-in\" tab now sources its pets from those bundled spritesheets at\n// runtime via `/api/codex-pets` (filtered by `bundled: true`), and the\n// emoji-based catalog has been retired.\n//\n// We keep the type and an empty array for backwards compatibility with\n// rail / composer code paths and saved configs whose `petId` still\n// points at a legacy emoji id — those configs fall back to the user's\n// custom slot in `resolveActivePet` so the overlay never renders blank.\nexport interface BuiltInPet {\n id: string;\n name: string;\n glyph: string;\n accent: string;\n greeting: string;\n // Free-form one-liner shown under the pet name in the catalog card\n // — flavor text, not a tooltip. Keep it short.\n flavor: string;\n // CSS animation name applied to the sprite when the overlay is awake.\n // All four are defined in `index.css` under `@keyframes pet-…`.\n animation: 'bounce' | 'sway' | 'float' | 'wiggle';\n}\n\nexport const BUILT_IN_PETS: BuiltInPet[] = [];\n\nexport const CUSTOM_PET_ID = 'custom';\n\nexport interface ResolvedPet {\n id: string;\n name: string;\n glyph: string;\n accent: string;\n greeting: string;\n animation: BuiltInPet['animation'];\n // Optional uploaded image data URL. Present only for custom pets that\n // have an image; built-ins fall back to their emoji glyph.\n imageUrl?: string;\n // Legacy single-row spritesheet config (used when `atlas` is missing).\n // Number of horizontal frames in the imageUrl (1 = static).\n frames?: number;\n // Frames-per-second for the spritesheet step animation.\n fps?: number;\n // Optional sprite atlas layout. When present, `imageUrl` is the full\n // grid and `PetSpriteFace` picks one row to play based on the\n // overlay's interaction state.\n atlas?: PetAtlasLayout;\n}\n\n// Resolve the pet definition currently in use. Returns `null` only when\n// the user has not adopted yet — call sites use that to decide whether\n// to render the floating overlay at all.\nexport function resolveActivePet(pet: PetConfig | undefined): ResolvedPet | null {\n if (!pet?.adopted) return null;\n // Bundled \"Built-in\" pets adopt into the custom slot (the spritesheet\n // and atlas layout are copied there by `adoptCodexPet`), so the\n // custom branch is the rendering path for both user-authored pets\n // and bundled adoptions.\n if (pet.petId === CUSTOM_PET_ID) {\n return resolveCustomPet(pet.custom);\n }\n const found = BUILT_IN_PETS.find((p) => p.id === pet.petId);\n if (found) {\n return {\n id: found.id,\n name: found.name,\n glyph: found.glyph,\n accent: found.accent,\n greeting: found.greeting,\n animation: found.animation,\n };\n }\n // Legacy fallback — older configs may still carry an emoji built-in\n // id (e.g. `mochi`) from before the catalog migrated to bundled\n // spritesheets. Render the user's custom slot instead of crashing or\n // blanking the overlay; the user can re-adopt from Settings to pick\n // a bundled pet.\n return resolveCustomPet(pet.custom);\n}\n\nfunction resolveCustomPet(c: PetCustom): ResolvedPet {\n return {\n id: CUSTOM_PET_ID,\n name: c.name?.trim() || 'Buddy',\n glyph: c.glyph?.trim() || '🦄',\n accent: c.accent?.trim() || '#c96442',\n greeting: c.greeting?.trim() || 'Hi! I am here whenever you need me.',\n // Custom pets get the gentle float animation by default. We could\n // expose this in the editor later; today's UX keeps the picker\n // focused on glyph + name + color.\n animation: 'float',\n imageUrl: c.imageUrl,\n frames: clampFrames(c.frames),\n fps: clampFps(c.fps),\n atlas: sanitizeAtlas(c.atlas),\n };\n}\n\nexport const FRAMES_MIN = 1;\nexport const FRAMES_MAX = 24;\nexport const FPS_MIN = 1;\nexport const FPS_MAX = 30;\n\nfunction clampFrames(value: number | undefined): number {\n if (!Number.isFinite(value as number)) return 1;\n return Math.max(FRAMES_MIN, Math.min(FRAMES_MAX, Math.round(value as number)));\n}\n\nfunction clampFps(value: number | undefined): number {\n if (!Number.isFinite(value as number)) return 6;\n return Math.max(FPS_MIN, Math.min(FPS_MAX, Math.round(value as number)));\n}\n\n// Atlas hardening — strips out malformed entries so the renderer never\n// has to defensively check for NaN cell sizes / negative indices. We\n// keep rows we can validate even if the layout omits a few; missing\n// rows just fall back to `idle` at lookup time.\nfunction sanitizeAtlas(input: PetAtlasLayout | undefined): PetAtlasLayout | undefined {\n if (!input) return undefined;\n const cols = Math.max(1, Math.floor(input.cols));\n const rows = Math.max(1, Math.floor(input.rows));\n if (!Number.isFinite(cols) || !Number.isFinite(rows)) return undefined;\n const seen = new Set<number>();\n const rowsDef: PetAtlasRowDef[] = [];\n for (const row of input.rowsDef ?? []) {\n if (!row || typeof row.id !== 'string' || !row.id.trim()) continue;\n const index = Math.floor(row.index);\n if (!Number.isFinite(index) || index < 0 || index >= rows) continue;\n if (seen.has(index)) continue;\n seen.add(index);\n rowsDef.push({\n index,\n id: row.id.trim(),\n frames: Math.max(1, Math.min(cols, Math.floor(row.frames) || 1)),\n fps: Math.max(FPS_MIN, Math.min(FPS_MAX, Math.floor(row.fps) || 6)),\n });\n }\n if (rowsDef.length === 0) return undefined;\n rowsDef.sort((a, b) => a.index - b.index);\n return { cols, rows, rowsDef };\n}\n\n// Logical interaction states that drive the overlay's animation\n// switching. Kept narrow on purpose so the mapping below stays a\n// declarative table rather than a tangle of conditionals.\nexport type PetInteraction =\n | 'idle'\n | 'hover'\n | 'drag-right'\n | 'drag-left'\n | 'drag-up'\n | 'drag-down'\n | 'waiting';\n\n// Preferred Codex atlas row id for each interaction state. Hover and\n// drag each map to a dedicated action row so the pet visibly reacts to\n// the user — hover plays a wave, drag swaps to a directional run (or\n// hop when the gesture is vertical). Autonomous ambient variety below\n// only fires when the pet is otherwise at rest so rest ↔ interaction\n// reads as two cleanly separated behaviours.\nconst INTERACTION_ROW_ID: Record<PetInteraction, string> = {\n idle: 'idle',\n hover: 'waving',\n 'drag-right': 'running-right',\n 'drag-left': 'running-left',\n 'drag-up': 'jumping',\n 'drag-down': 'waving',\n waiting: 'waiting',\n};\n\nconst ROW_FALLBACK_ORDER: readonly string[] = [\n 'idle',\n 'waiting',\n 'waving',\n 'running',\n 'running-right',\n];\n\nexport function preferredRowId(state: PetInteraction): string {\n return INTERACTION_ROW_ID[state];\n}\n\n// Resolve the atlas row to play given the desired animation id. We try\n// the requested id first, then walk a sensible fallback chain, then\n// return whichever row the atlas does have so playback never blanks\n// out for a partially-populated pet.\nexport function pickAtlasRow(\n layout: PetAtlasLayout | undefined,\n preferred: string,\n): PetAtlasRowDef | undefined {\n if (!layout || layout.rowsDef.length === 0) return undefined;\n const direct = layout.rowsDef.find((r) => r.id === preferred);\n if (direct) return direct;\n for (const id of ROW_FALLBACK_ORDER) {\n const fallback = layout.rowsDef.find((r) => r.id === id);\n if (fallback) return fallback;\n }\n return layout.rowsDef[0];\n}\n\n// Ambient row pool — the overlay dips into these between `idle` cycles\n// so a parked pet doesn't look frozen. Ordered by \"quietness\": waving\n// and review feel calm enough to interject without startling the user,\n// jumping / running* are more energetic and round out the variety when\n// the atlas ships them. `idle`, `waiting`, and `failed` are excluded\n// intentionally: idle is the resting baseline, waiting is reserved for\n// the long-idle cue, and failed reads as a negative micro-narrative.\nconst AMBIENT_ROW_POOL: readonly string[] = [\n 'waving',\n 'review',\n 'jumping',\n 'running',\n 'running-right',\n 'running-left',\n];\n\n// Pick a random ambient row from the atlas, preferring ids in\n// AMBIENT_ROW_POOL and avoiding `avoidId` when possible so the overlay\n// doesn't replay the same micro-animation twice in a row. Returns null\n// when the atlas ships only `idle` / `waiting` rows so the caller can\n// no-op cleanly.\nexport function pickAmbientRow(\n layout: PetAtlasLayout | undefined,\n avoidId?: string,\n): PetAtlasRowDef | null {\n if (!layout || layout.rowsDef.length === 0) return null;\n const pool = layout.rowsDef.filter((r) => AMBIENT_ROW_POOL.includes(r.id));\n if (pool.length === 0) return null;\n const candidates =\n pool.length > 1 && avoidId ? pool.filter((r) => r.id !== avoidId) : pool;\n const choices = candidates.length > 0 ? candidates : pool;\n return choices[Math.floor(Math.random() * choices.length)] ?? null;\n}\n\n// A short pool of \"ambient\" prompts that the overlay rotates through on\n// hover so the speech bubble feels alive after the initial greeting.\n// Keep these brand-neutral and product-relevant to Open Design.\nexport function ambientLines(name: string): string[] {\n return [\n `${name}: nudge me when you want a fresh idea.`,\n `${name}: I will keep you company while it builds.`,\n `${name}: take a breath — the prototype will wait.`,\n `${name}: small tweaks compound. Keep going!`,\n ];\n}\n\nexport function defaultCustomPet(): PetCustom {\n return {\n name: 'Buddy',\n glyph: '🦄',\n accent: '#c96442',\n greeting: 'Hi! I am here whenever you need me.',\n };\n}\n\n// One-shot self-healing migration for pets adopted before the overlay\n// learned how to switch atlas rows.\n//\n// Older versions of `adoptCodexPet` cropped the Codex spritesheet down\n// to the idle row and stored just that horizontal strip on\n// `PetCustom.imageUrl` (strip mode, single row). The overlay is now an\n// atlas-aware renderer that can swap rows per interaction (hover ↔\n// waving, drag ↔ running-*, idle ↔ ambient rotation), but it needs the\n// full 8×9 grid in `PetCustom.atlas` + `imageUrl` to do so.\n//\n// When the persisted config points at a custom pet that has an\n// imageUrl but no atlas, we look up the Codex pet registry, match by\n// the name we stamped on adoption, and silently re-download the\n// full spritesheet. The user sees nothing except their pet going from\n// \"one-state statue\" to fully animated on next launch. The migration\n// bails on any failure — this is best-effort and the strip sprite\n// stays as-is if, say, the daemon is offline.\nexport async function migrateCustomPetAtlas(\n cfg: AppConfig,\n): Promise<PetCustom | null> {\n const pet = cfg.pet;\n if (!pet || !pet.adopted || pet.petId !== CUSTOM_PET_ID) return null;\n const custom = pet.custom;\n if (!custom?.imageUrl || custom.atlas) return null;\n\n const name = custom.name?.trim();\n if (!name) return null;\n\n let registry;\n try {\n registry = await fetchCodexPets();\n } catch {\n return null;\n }\n if (!registry?.pets?.length) return null;\n\n const needle = name.toLowerCase();\n const match = registry.pets.find(\n (p) =>\n (p.displayName?.trim().toLowerCase() ?? '') === needle ||\n p.id.trim().toLowerCase() === needle,\n );\n if (!match) return null;\n\n try {\n const resp = await fetch(codexPetSpritesheetUrl(match));\n if (!resp.ok) return null;\n const blob = await resp.blob();\n const dataUrl = await blobToDataUrl(blob);\n const prepared = await prepareCodexAtlas(dataUrl);\n return {\n ...custom,\n imageUrl: prepared.dataUrl,\n frames: 1,\n fps: prepared.layout.rowsDef[0]?.fps ?? custom.fps ?? 6,\n atlas: prepared.layout,\n };\n } catch {\n return null;\n }\n}\n\nexport async function prepareCodexPetCustom(pet: CodexPetSummary): Promise<PetCustom> {\n const resp = await fetch(codexPetSpritesheetUrl(pet));\n if (!resp.ok) throw new Error('Could not download that pet.');\n const blob = await resp.blob();\n const dataUrl = await blobToDataUrl(blob);\n const prepared = await prepareCodexAtlas(dataUrl);\n return {\n name: pet.displayName || pet.id,\n glyph: '🦄',\n accent: '#c96442',\n greeting: pet.description || `Hi! I am ${pet.displayName || pet.id}.`,\n imageUrl: prepared.dataUrl,\n frames: 1,\n fps: prepared.layout.rowsDef[0]?.fps ?? 6,\n atlas: prepared.layout,\n };\n}\n\nfunction blobToDataUrl(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = () => reject(reader.error ?? new Error('Read failed'));\n reader.onload = () => {\n const result = reader.result;\n if (typeof result !== 'string') {\n reject(new Error('Could not read sprite blob.'));\n return;\n }\n resolve(result);\n };\n reader.readAsDataURL(blob);\n });\n}\n","// Codex hatch-pet atlas helpers.\n//\n// The companion `hatch-pet` skill (vendored under `skills/hatch-pet/`)\n// produces a fixed-shape spritesheet that the Codex app reads directly:\n//\n// - Format: PNG or WebP, transparent background.\n// - Dimensions: 1536 x 1872 px.\n// - Grid: 8 columns x 9 rows of 192 x 208 cells.\n// - Each row encodes one animation state (idle, running-right, …).\n//\n// The pet overlay can render the full atlas and switch the active row\n// based on interaction state (hover, drag direction, idle timeout) —\n// matching the codex-pets-react `PetWidget` behaviour. For users who\n// prefer a single-row loop (or a non-Codex strip) we still expose the\n// `cropAtlasRow` helper, which slices one row into a standalone strip.\n//\n// Source contract:\n// https://github.com/openai/skills/tree/main/skills/.curated/hatch-pet/references\n\nimport type { PetAtlasLayout, PetAtlasRowDef } from '../../types';\n\nexport const CODEX_ATLAS_COLS = 8;\nexport const CODEX_ATLAS_ROWS = 9;\nexport const CODEX_CELL_WIDTH = 192;\nexport const CODEX_CELL_HEIGHT = 208;\nexport const CODEX_ATLAS_WIDTH = CODEX_ATLAS_COLS * CODEX_CELL_WIDTH; // 1536\nexport const CODEX_ATLAS_HEIGHT = CODEX_ATLAS_ROWS * CODEX_CELL_HEIGHT; // 1872\nexport const CODEX_ATLAS_ASPECT = CODEX_ATLAS_WIDTH / CODEX_ATLAS_HEIGHT; // ~0.821\n\nexport interface CodexAtlasRow {\n // Row index in the atlas, top to bottom. Stable ordering matches the\n // `animation-rows.md` reference shipped with the upstream skill.\n index: number;\n // Stable id used for translation lookup and React keys.\n id:\n | 'idle'\n | 'running-right'\n | 'running-left'\n | 'waving'\n | 'jumping'\n | 'failed'\n | 'waiting'\n | 'running'\n | 'review';\n // Number of frames the row uses, per the upstream reference. Frames\n // beyond this index are required to be transparent so we crop them\n // out by default to keep the strip tight.\n frames: number;\n // Recommended fps so the strip plays at roughly the same cadence as\n // the Codex app's own per-frame ms timings. Each row uses different\n // per-frame timings; this is a reasonable rounded average.\n fps: number;\n}\n\n// Mirrors `references/animation-rows.md` from the hatch-pet skill.\nexport const CODEX_ATLAS_ROWS_DEF: CodexAtlasRow[] = [\n { index: 0, id: 'idle', frames: 6, fps: 6 },\n { index: 1, id: 'running-right', frames: 8, fps: 8 },\n { index: 2, id: 'running-left', frames: 8, fps: 8 },\n { index: 3, id: 'waving', frames: 4, fps: 6 },\n { index: 4, id: 'jumping', frames: 5, fps: 7 },\n { index: 5, id: 'failed', frames: 8, fps: 7 },\n { index: 6, id: 'waiting', frames: 6, fps: 6 },\n { index: 7, id: 'running', frames: 6, fps: 8 },\n { index: 8, id: 'review', frames: 6, fps: 6 },\n];\n\n// Canonical layout passed to `PetCustom.atlas` when the user adopts a\n// Codex hatch-pet without freezing it to a single row. The overlay reads\n// this to know how to slice the grid + which rows are populated.\nexport const CODEX_ATLAS_LAYOUT: PetAtlasLayout = {\n cols: CODEX_ATLAS_COLS,\n rows: CODEX_ATLAS_ROWS,\n rowsDef: CODEX_ATLAS_ROWS_DEF.map(\n (row): PetAtlasRowDef => ({\n index: row.index,\n id: row.id,\n frames: row.frames,\n fps: row.fps,\n }),\n ),\n};\n\n// Aspect-only check is enough to handle WebP/PNG atlases that have been\n// resized for transport. We accept anything within ~6% of the canonical\n// 8x9 / 192x208 aspect, which comfortably catches resized variants while\n// rejecting normal screenshots and selfies.\nexport function looksLikeCodexAtlas(width: number, height: number): boolean {\n if (!Number.isFinite(width) || !Number.isFinite(height)) return false;\n if (width <= 0 || height <= 0) return false;\n const aspect = width / height;\n return Math.abs(aspect - CODEX_ATLAS_ASPECT) < 0.06;\n}\n\n// Read a user-picked file into a data URL without re-encoding through a\n// canvas. The Codex atlas import path needs the original full-resolution\n// pixels so the per-row crop stays sharp; the regular pet upload path in\n// `image.ts` would downscale to 384 px on the longest side and destroy\n// the grid alignment.\nexport interface RawAtlasImage {\n dataUrl: string;\n width: number;\n height: number;\n}\n\nconst ACCEPTED_TYPES = new Set([\n 'image/png',\n 'image/webp',\n 'image/jpeg',\n 'image/gif',\n]);\n\nexport async function loadAtlasImageFromFile(file: File): Promise<RawAtlasImage> {\n if (!file.type.startsWith('image/')) {\n throw new Error('Only image files are supported.');\n }\n if (!ACCEPTED_TYPES.has(file.type) && file.type !== 'image/svg+xml') {\n throw new Error('Use a PNG, WebP, JPEG, or GIF spritesheet.');\n }\n const dataUrl = await readFileAsDataUrl(file);\n const dims = await measureImage(dataUrl);\n return { dataUrl, width: dims.width, height: dims.height };\n}\n\nexport interface CropAtlasOptions {\n // Which row to extract. Defaults to row 0 (`idle`).\n rowIndex: number;\n // Override the columns / rows / cell size if the source is a non-Codex\n // atlas. Defaults to the canonical 8x9 / 192x208 layout.\n cols?: number;\n rows?: number;\n // Number of leading frames to keep from the row. Defaults to the\n // upstream-defined \"used columns\" for the chosen row, falling back to\n // `cols` when the row isn't recognised.\n frames?: number;\n // Cap on the cell height of the resulting strip. The pet overlay only\n // renders at ~56-72 px, so 96 px cells stay crisp without bloating\n // the localStorage payload. Set to `null` to skip downscaling.\n maxCellHeight?: number | null;\n}\n\nexport interface CroppedAtlasRow {\n // PNG data URL of the horizontal strip ready to drop into\n // `PetCustom.imageUrl` and animated via `pet-frames` keyframes.\n dataUrl: string;\n // Final strip dimensions after optional downscale.\n width: number;\n height: number;\n // Number of frames packed into the strip.\n frames: number;\n}\n\nconst DEFAULT_MAX_CELL_HEIGHT = 96;\n\nexport async function cropAtlasRow(\n dataUrl: string,\n options: CropAtlasOptions,\n): Promise<CroppedAtlasRow> {\n const cols = Math.max(1, Math.floor(options.cols ?? CODEX_ATLAS_COLS));\n const rows = Math.max(1, Math.floor(options.rows ?? CODEX_ATLAS_ROWS));\n const rowIndex = Math.max(0, Math.min(rows - 1, Math.floor(options.rowIndex)));\n const def = CODEX_ATLAS_ROWS_DEF.find((r) => r.index === rowIndex);\n const requestedFrames =\n options.frames ?? def?.frames ?? cols;\n const frames = Math.max(1, Math.min(cols, Math.floor(requestedFrames)));\n const maxCellHeight =\n options.maxCellHeight === null\n ? null\n : options.maxCellHeight ?? DEFAULT_MAX_CELL_HEIGHT;\n\n const img = await loadImage(dataUrl);\n const cellWidth = Math.floor(img.naturalWidth / cols);\n const cellHeight = Math.floor(img.naturalHeight / rows);\n if (cellWidth <= 0 || cellHeight <= 0) {\n throw new Error('Atlas image is too small to crop.');\n }\n\n const targetCellHeight =\n maxCellHeight && cellHeight > maxCellHeight ? maxCellHeight : cellHeight;\n const scale = targetCellHeight / cellHeight;\n const targetCellWidth = Math.max(1, Math.round(cellWidth * scale));\n const targetWidth = targetCellWidth * frames;\n const targetHeight = targetCellHeight;\n\n const canvas = document.createElement('canvas');\n canvas.width = targetWidth;\n canvas.height = targetHeight;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Canvas is unavailable in this browser.');\n }\n // Pixel-art atlases lose readability under bilinear smoothing, so we\n // explicitly disable it before drawing.\n ctx.imageSmoothingEnabled = false;\n for (let f = 0; f < frames; f++) {\n const sx = f * cellWidth;\n const sy = rowIndex * cellHeight;\n ctx.drawImage(\n img,\n sx,\n sy,\n cellWidth,\n cellHeight,\n f * targetCellWidth,\n 0,\n targetCellWidth,\n targetCellHeight,\n );\n }\n const out = canvas.toDataURL('image/png');\n return {\n dataUrl: out,\n width: targetWidth,\n height: targetHeight,\n frames,\n };\n}\n\n// Same idea as `cropAtlasRow` but keeps every row so the overlay can\n// switch animations on the fly. We downscale to a target cell height\n// (default 80 px → 8x9 grid lands at ~528 KB PNG which fits inside the\n// MAX_DATA_URL_BYTES guard from `image.ts` even for busy spritesheets)\n// while preserving the grid layout 1:1 so background-position math in\n// `PetSpriteFace` stays simple.\nconst DEFAULT_FULL_ATLAS_MAX_CELL = 80;\n\nexport interface PreparedAtlas {\n // PNG data URL of the full atlas, ready to drop into\n // `PetCustom.imageUrl` together with the matching layout.\n dataUrl: string;\n // Final pixel dimensions of the downscaled atlas.\n width: number;\n height: number;\n // Layout metadata describing the grid + per-row playback config.\n layout: PetAtlasLayout;\n}\n\nexport async function prepareCodexAtlas(\n sourceDataUrl: string,\n options?: { maxCellHeight?: number | null },\n): Promise<PreparedAtlas> {\n const maxCellHeight =\n options?.maxCellHeight === null\n ? null\n : options?.maxCellHeight ?? DEFAULT_FULL_ATLAS_MAX_CELL;\n const img = await loadImage(sourceDataUrl);\n const cellWidth = Math.floor(img.naturalWidth / CODEX_ATLAS_COLS);\n const cellHeight = Math.floor(img.naturalHeight / CODEX_ATLAS_ROWS);\n if (cellWidth <= 0 || cellHeight <= 0) {\n throw new Error('Atlas image is too small to slice.');\n }\n const targetCellHeight =\n maxCellHeight && cellHeight > maxCellHeight ? maxCellHeight : cellHeight;\n const scale = targetCellHeight / cellHeight;\n const targetCellWidth = Math.max(1, Math.round(cellWidth * scale));\n const targetWidth = targetCellWidth * CODEX_ATLAS_COLS;\n const targetHeight = targetCellHeight * CODEX_ATLAS_ROWS;\n const canvas = document.createElement('canvas');\n canvas.width = targetWidth;\n canvas.height = targetHeight;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Canvas is unavailable in this browser.');\n }\n ctx.imageSmoothingEnabled = false;\n // Draw cell-by-cell so alignment survives even if the source has a\n // slightly off canvas size (some tools add a 1 px gutter that would\n // otherwise smear into adjacent cells under a single drawImage).\n for (let r = 0; r < CODEX_ATLAS_ROWS; r++) {\n for (let c = 0; c < CODEX_ATLAS_COLS; c++) {\n ctx.drawImage(\n img,\n c * cellWidth,\n r * cellHeight,\n cellWidth,\n cellHeight,\n c * targetCellWidth,\n r * targetCellHeight,\n targetCellWidth,\n targetCellHeight,\n );\n }\n }\n const dataUrl = canvas.toDataURL('image/png');\n return {\n dataUrl,\n width: targetWidth,\n height: targetHeight,\n layout: CODEX_ATLAS_LAYOUT,\n };\n}\n\nfunction readFileAsDataUrl(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = () => reject(reader.error ?? new Error('Read failed'));\n reader.onload = () => {\n const result = reader.result;\n if (typeof result !== 'string') {\n reject(new Error('Could not decode the image.'));\n return;\n }\n resolve(result);\n };\n reader.readAsDataURL(file);\n });\n}\n\nfunction measureImage(\n dataUrl: string,\n): Promise<{ width: number; height: number }> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve({ width: img.naturalWidth, height: img.naturalHeight });\n img.onerror = () => reject(new Error('Could not load that image.'));\n img.src = dataUrl;\n });\n}\n\nfunction loadImage(dataUrl: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error('Could not load that image.'));\n img.src = dataUrl;\n });\n}\n","import { useEffect, useState, type CSSProperties } from 'react';\nimport type { PetAtlasRowDef } from '../../types';\nimport type { ResolvedPet } from './pets';\n\ninterface Props {\n active: ResolvedPet;\n className?: string;\n // Optional explicit pixel size; the overlay leaves it unset and\n // inherits container metrics, while the rail / settings preview\n // pin a concrete size to keep the cell shape consistent.\n size?: number;\n // Atlas-mode only — which row id (e.g. `idle`, `waving`, `running-right`)\n // to play right now. Defaults to `idle` (or the first row, when the\n // atlas does not declare an idle row). Ignored for emoji / strip pets.\n rowId?: string;\n}\n\n// Renders the pet's face. Four cases:\n//\n// 1. No imageUrl — just the emoji glyph (legacy / built-ins).\n// 2. imageUrl + atlas — the full Codex 8x9 sprite atlas. We pick the\n// requested row by index and step through that row's frames at\n// the row's per-second fps. Mirrors the `codex-pets-react`\n// `SpriteAnimator` behaviour so different interactions (idle,\n// waving, running-*) play the right row of the atlas.\n// 3. imageUrl + frames > 1 — legacy horizontal spritesheet (one row\n// cropped out). Walked through with a CSS `steps()` animation.\n// 4. imageUrl + frames === 1 — single static image.\nexport function PetSpriteFace({ active, className, size, rowId }: Props) {\n if (!active.imageUrl) {\n const style: CSSProperties | undefined = size\n ? { fontSize: Math.round(size * 0.85), width: size, height: size, lineHeight: 1 }\n : undefined;\n return (\n <span className={className} aria-hidden style={style}>\n {active.glyph}\n </span>\n );\n }\n\n if (active.atlas && active.atlas.rowsDef.length > 0) {\n return (\n <AtlasSprite\n imageUrl={active.imageUrl}\n cols={Math.max(1, active.atlas.cols)}\n rows={Math.max(1, active.atlas.rows)}\n rowsDef={active.atlas.rowsDef}\n rowId={rowId}\n className={className}\n size={size}\n />\n );\n }\n\n const frames = Math.max(1, active.frames ?? 1);\n const fps = Math.max(1, active.fps ?? 6);\n if (frames === 1) {\n return (\n <span\n className={`${className ?? ''} pet-image static`.trim()}\n aria-hidden\n style={{\n backgroundImage: `url(${active.imageUrl})`,\n width: size,\n height: size,\n }}\n />\n );\n }\n // Strip mode — N frames laid out horizontally. The image is\n // (N × container_width) wide, so the visible frame is selected by\n // sliding background-position-x from 0% to 100% in (N-1) steps.\n // `steps(N, jump-none)` is required because the default jump-end\n // would land on 0/N, 1/N, …, (N-1)/N, which slices each frame mid-cell;\n // jump-none lands on the actual cell boundaries 0/(N-1) … 1.\n const durationMs = Math.round((frames / fps) * 1000);\n return (\n <span\n className={`${className ?? ''} pet-image frames`.trim()}\n aria-hidden\n style={{\n backgroundImage: `url(${active.imageUrl})`,\n backgroundSize: `${frames * 100}% 100%`,\n animation: `pet-frames ${durationMs}ms steps(${frames}, jump-none) infinite`,\n width: size,\n height: size,\n }}\n />\n );\n}\n\ninterface AtlasSpriteProps {\n imageUrl: string;\n cols: number;\n rows: number;\n rowsDef: PetAtlasRowDef[];\n rowId?: string;\n className?: string;\n size?: number;\n}\n\n// Atlas renderer. Drives the frame index from JS instead of a CSS\n// `steps()` animation — sidesteps the jump-end vs jump-none footgun\n// and makes per-row fps trivial to swap when the parent flips the\n// `rowId` prop (idle ↔ waving ↔ running-*).\nfunction AtlasSprite({\n imageUrl,\n cols,\n rows,\n rowsDef,\n rowId,\n className,\n size,\n}: AtlasSpriteProps) {\n const def =\n rowsDef.find((r) => r.id === rowId)\n ?? rowsDef.find((r) => r.id === 'idle')\n ?? rowsDef[0]!;\n const rowFrames = Math.max(1, def.frames);\n const fps = Math.max(1, def.fps);\n\n const [frame, setFrame] = useState(0);\n // Reset to frame 0 on row change so a freshly-triggered animation\n // (e.g. tap → waving) starts cleanly instead of mid-cycle.\n useEffect(() => {\n setFrame(0);\n if (rowFrames <= 1) return;\n const intervalMs = Math.max(16, Math.round(1000 / fps));\n const id = window.setInterval(() => {\n setFrame((f) => (f + 1) % rowFrames);\n }, intervalMs);\n return () => window.clearInterval(id);\n }, [def.id, def.index, rowFrames, fps]);\n\n // Background math:\n // - background-size = (cols × 100%) × (rows × 100%)\n // → each grid cell renders at exactly the container size.\n // - background-position-x = frame / (cols - 1) × 100%\n // → 0% slides to the leftmost cell, 100% to the rightmost,\n // intermediate cells land at frame/(cols-1) of the offset range.\n // - background-position-y = rowIndex / (rows - 1) × 100%\n const xPct = cols > 1 ? (frame / (cols - 1)) * 100 : 0;\n const yPct = rows > 1 ? (def.index / (rows - 1)) * 100 : 0;\n\n return (\n <span\n className={`${className ?? ''} pet-image atlas`.trim()}\n aria-hidden\n style={{\n backgroundImage: `url(${imageUrl})`,\n backgroundSize: `${cols * 100}% ${rows * 100}%`,\n backgroundPosition: `${xPct}% ${yPct}%`,\n width: size,\n height: size,\n }}\n />\n );\n}\n","import type { ChatRunStatusResponse } from '@open-design/contracts';\nimport type { Project } from '../../types';\nimport type { PetRecentTaskSummary, PetTaskCenter, PetTaskSummary } from './PetOverlay';\n\nconst TERMINAL_STATUSES = new Set(['succeeded', 'failed', 'canceled']);\n\nexport function buildPetTaskCenter(\n projects: Project[],\n runs: ChatRunStatusResponse[],\n): PetTaskCenter {\n const projectsById = new Map(projects.map((project) => [project.id, project]));\n const running = new Map<string, PetTaskSummary>();\n const queued = new Map<string, PetTaskSummary>();\n const recentByProject = new Map<string, PetRecentTaskSummary>();\n\n for (const run of runs) {\n if (!run.projectId) continue;\n const project = projectsById.get(run.projectId);\n if (!project) continue;\n if (run.status === 'running') {\n addActiveSummary(running, run.projectId, project.name, 'running');\n continue;\n }\n if (run.status === 'queued') {\n addActiveSummary(queued, run.projectId, project.name, 'queued');\n continue;\n }\n if (TERMINAL_STATUSES.has(run.status)) {\n const prev = recentByProject.get(run.projectId);\n if (prev && prev.updatedAt >= run.updatedAt) continue;\n recentByProject.set(run.projectId, {\n projectId: run.projectId,\n projectName: project.name,\n status: run.status as PetRecentTaskSummary['status'],\n updatedAt: run.updatedAt,\n });\n }\n }\n\n return {\n running: sortActiveSummaries([...running.values()]),\n queued: sortActiveSummaries([...queued.values()]),\n recent: [...recentByProject.values()]\n .filter((task) => !running.has(task.projectId) && !queued.has(task.projectId))\n .sort((a, b) => b.updatedAt - a.updatedAt)\n .slice(0, 3),\n };\n}\n\nfunction addActiveSummary(\n summaries: Map<string, PetTaskSummary>,\n projectId: string,\n projectName: string,\n status: PetTaskSummary['status'],\n) {\n const prev = summaries.get(projectId);\n summaries.set(projectId, {\n projectId,\n projectName,\n status,\n count: (prev?.count ?? 0) + 1,\n });\n}\n\nfunction sortActiveSummaries(summaries: PetTaskSummary[]): PetTaskSummary[] {\n return summaries.sort((a, b) => {\n if (b.count !== a.count) return b.count - a.count;\n return a.projectName.localeCompare(b.projectName);\n });\n}\n"],"names":["MEDIA_PROVIDERS","id","label","hint","integrated","defaultBaseUrl","docsUrl","credentialsRequired","settingsVisible","supportsCustomModel","customModelPlaceholder","IMAGE_MODELS","provider","caps","default","VIDEO_MODELS","AUDIO_MODELS_BY_KIND","music","speech","sfx","MEDIA_ASPECTS","VIDEO_LENGTHS_SEC","AUDIO_DURATIONS_SEC","DEFAULT_IMAGE_MODEL","find","m","DEFAULT_VIDEO_MODEL","DEFAULT_AUDIO_MODEL","findMediaModel","all","findProvider","p","modelIdsBySurface","image","map","video","audio","groupByProvider","models","order","Map","has","push","set","get","list","filter","entry","DEFAULT_DEPLOY_PROVIDER_ID","CLOUDFLARE_PAGES_PROVIDER_ID","DEPLOY_PROVIDER_IDS","isDeployProviderId","value","includes","deployProviderQuery","providerId","encodeURIComponent","fetchAgents","options","resp","fetch","cache","ok","throwOnError","Error","status","json","agents","err","fetchSkills","skills","fetchDesignTemplates","designTemplates","fetchDesignTemplate","fetchCodexPets","pets","rootDir","syncCommunityPets","input","method","headers","body","JSON","stringify","payload","catch","wrote","skipped","failed","total","errors","error","message","codexPetSpritesheetUrl","pet","spritesheetUrl","importSkill","code","updateSkill","fetchSkillFiles","files","deleteSkill","fetchSkill","fetchDesignSystems","result","fetchDesignSystemsResult","designSystems","fetchDesignSystem","parseDesignSystemDetail","fetchDesignSystemFiles","fetchDesignSystemFile","filePath","file","ensureDesignSystemWorkspace","wrapper","designSystem","createDesignSystemDraft","startDesignSystemGenerationJob","job","fetchDesignSystemGenerationJob","fetchProjectDesignSystemPackageAudit","projectId","audit","fetchDesignSystemRevisions","revisions","updateDesignSystemRevisionStatus","revisionId","revision","startDesignSystemRevisionJob","updateDesignSystemDraft","deleteDesignSystemDraft","importLocalDesignSystem","readImportError","importGitHubDesignSystem","fetchPromptTemplates","promptTemplates","fetchPromptTemplate","surface","promptTemplate","daemonIsLive","fetchConnectors","connectors","fetchConnectorStatuses","signal","statuses","connectorDiscoveryCache","connectorDiscoveryPromise","fetchConnectorDiscovery","refresh","promise","params","fetchConnectorDetail","connectorId","URLSearchParams","hydrateTools","toolsLimit","undefined","String","toolsCursor","query","toString","connector","popupBlockedMessage","openExternalUrl","url","opened","window","location","assign","decodeConnectorError","trim","connectConnector","authWindow","useExternalBrowser","open","renderConnectorAuthLoading","title","prepare","prepareConnectorAuthConfig","renderConnectorAuthError","auth","kind","redirectUrl","openConnectorAuthRedirect","renderConnectorAuthInfo","connectorIds","results","renderConnectorAuthRedirect","replace","copy","document","innerHTML","escapeHtmlText","escapeHtmlAttribute","readConnectorApiErrorMessage","char","disconnectConnector","cancelConnectorAuthorization","isAppVersionInfo","candidate","version","channel","packaged","platform","arch","fetchAppVersionInfo","fetchLatestGithubReleaseInfo","tag_name","html_url","tagName","htmlUrl","stale","fetchSkillExample","previewType","unavailable","html","text","fetchDeployConfig","updateDeployConfig","fetchCloudflarePagesZones","fetchProjectDeployments","deployments","deployProjectFile","fileName","cloudflarePages","checkDeploymentLink","deploymentId","fetchProjectFiles","fetchLiveArtifacts","liveArtifacts","artifacts","fetchLiveArtifact","artifactId","liveArtifactDetailUrl","liveArtifact","artifact","LiveArtifactRefreshError","name","refreshLiveArtifact","errorBody","readApiErrorBody","fetchLiveArtifactRefreshes","refreshes","updateLiveArtifact","deleteLiveArtifact","length","liveArtifactPreviewUrl","variant","variantQuery","fetchLiveArtifactCode","projectFileUrl","projectRawUrl","fetchProjectFilePreview","fetchProjectFileText","cacheBustKey","requestUrl","init","console","warn","statusText","fetchPreviewComments","conversationId","comments","upsertPreviewComment","comment","patchPreviewCommentStatus","commentId","deletePreviewComment","writeProjectTextFile","content","writeProjectTextFileDetailed","artifactManifest","writeProjectBase64File","base64","encoding","uploadProjectFile","desiredName","form","FormData","append","PROJECT_UPLOAD_BATCH_SIZE","uploadProjectFiles","uploaded","i","batch","slice","remaining","f","responseFiles","path","originalName","looksLikeImage","size","safePath","split","seg","join","test","deleteProjectFile","renameProjectFile","from","to","openFolderDialog","data","replaceProjectWorkingDir","baseDir","desktopImportToken","fetchHostEditors","openProjectInEditor","editorId","fetchDesignSystemPreview","fetchDesignSystemShowcase","fetchPluginPreviewHtml","fetchPluginExampleHtml","pluginId","stem","fetchPluginAssetText","relpath","encodePluginAssetPath","Boolean","installSkill","uninstallSkill","installDesignSystem","uninstallDesignSystem","listProjects","projects","getProject","project","createProject","importFolderProject","importClaudeDesignZip","listTemplates","templates","getTemplate","template","saveTemplate","deleteTemplate","patchProject","patch","deleteProject","listConversations","conversations","createConversation","conversation","patchConversation","deleteConversation","listMessages","messages","saveMessage","telemetryFinalized","keepalive","loadTabs","tabs","active","saveTabs","state","listPlugins","plugins","includeHidden","isVisiblePlugin","plugin","od","manifest","hidden","installPluginSource","source","log","readErrorMessage","warnings","success","errorMessage","ev","readServerSentEvents","uploadPluginZip","postPluginUpload","uploadPluginFolder","relativePath","getUploadRelativePath","installGeneratedPluginFolder","request","outcome","readPluginInstallOutcome","dispatchEvent","CustomEvent","publishGeneratedPluginToGitHub","postGeneratedPluginShareAction","contributeGeneratedPluginToOpenDesign","startGeneratedPluginShareTask","action","taskId","startedAt","waitGeneratedPluginShareTask","since","timeoutMs","createPluginShareProject","locale","fallbackMessage","upgradePlugin","withRelativePath","webkitRelativePath","uninstallPlugin","listPluginMarketplaces","marketplaces","addPluginMarketplace","readPluginMarketplaceOutcome","refreshPluginMarketplace","removePluginMarketplace","setPluginMarketplaceTrust","trust","successMessage","marketplace","applyPlugin","inputs","grantCaps","details","extractErrorDetails","values","flatMap","Array","isArray","item","reader","getReader","decoder","TextDecoder","buffer","done","read","decode","stream","parts","pop","part","event","parseServerSentEvent","releaseLock","raw","line","startsWith","trimStart","parse","fetchAppliedPluginSnapshot","snapshotId","renderPluginBriefTemplate","full","key","v","resolvePluginQueryFallback","fallbackLocale","isStringMap","candidates","resolved","Object","every","FALLBACK_MAX_TOKENS","MIN_MAX_TOKENS","MAX_MAX_TOKENS","LITELLM_MODELS","OVERRIDES","modelMaxTokensDefault","model","isValidOverride","Number","isInteger","effectiveMaxTokens","cfg","maxTokens","API_PROTOCOL_LABELS","anthropic","openai","azure","google","ollama","senseaudio","API_PROTOCOL_AGENT_IDS","apiProtocolLabel","protocol","apiProtocolModelLabel","trimmed","apiProtocolAgentId","usesAnthropicProxy","apiProtocol","isOpenAICompatible","baseUrl","isAnthropicSupportedImagePath","lower","toLowerCase","CODEX_ATLAS_COLS","CODEX_ATLAS_ROWS","CODEX_CELL_WIDTH","CODEX_CELL_HEIGHT","CODEX_ATLAS_WIDTH","CODEX_ATLAS_HEIGHT","CODEX_ATLAS_ASPECT","CODEX_ATLAS_ROWS_DEF","index","frames","fps","CODEX_ATLAS_LAYOUT","cols","rows","rowsDef","row","looksLikeCodexAtlas","width","height","isFinite","aspect","Math","abs","ACCEPTED_TYPES","Set","loadAtlasImageFromFile","type","dataUrl","readFileAsDataUrl","dims","measureImage","DEFAULT_MAX_CELL_HEIGHT","cropAtlasRow","max","floor","rowIndex","min","def","r","requestedFrames","maxCellHeight","img","loadImage","cellWidth","naturalWidth","cellHeight","naturalHeight","targetCellHeight","scale","targetCellWidth","round","targetWidth","targetHeight","canvas","createElement","ctx","getContext","imageSmoothingEnabled","sx","sy","drawImage","out","toDataURL","DEFAULT_FULL_ATLAS_MAX_CELL","prepareCodexAtlas","sourceDataUrl","c","layout","Promise","resolve","reject","FileReader","onerror","onload","readAsDataURL","Image","src"],"mappings":"uIAoFO,IAAMA,EAAmC,CAC9C,CACEC,GAAI,SACJC,MAAO,SACPC,KAAM,yBACNC,YAAY,EACZC,eAAgB,4BAChBC,QAAS,sCACX,EACA,CACEL,GAAI,aACJC,MAAO,0BACPC,KAAM,0BACNC,YAAY,EACZC,eAAgB,2CAChBC,QAAS,oCACX,EACA,CACEL,GAAI,OACJC,MAAO,mBACPC,KAAM,iDACNC,YAAY,EACZC,eAAgB,sBAChBC,QAAS,kEACX,EACA,CACEL,GAAI,cACJC,MAAO,cACPC,KAAM,6BACNC,YAAY,EACZG,qBAAqB,EACrBC,iBAAiB,EACjBF,QAAS,gCACX,EACA,CACEL,GAAI,aACJC,MAAO,cACPC,KAAM,0DACNC,YAAY,EACZC,eAAgB,4CAChBC,QAAS,gDACTG,qBAAqB,CACvB,EACA,CACER,GAAI,cACJC,MAAO,cACPC,KAAM,0CACNC,YAAY,EACZC,eAAgB,uCAChBC,QAAS,8DACTG,qBAAqB,EACrBC,uBAAwB,8CAC1B,EACA,CACET,GAAI,aACJC,MAAO,aACPC,KAAM,2CACNC,YAAY,EACZG,qBAAqB,EACrBC,iBAAiB,EACjBH,eAAgB,+BAChBC,QAAS,qCACX,EACA,CACEL,GAAI,eACJC,MAAO,mBACPC,KAAM,uEACNC,YAAY,EACZE,QAAS,wDACTG,oBAAqB,GACrBC,uBAAwB,gBAC1B,EACA,CACET,GAAI,UACJC,MAAO,UACPC,KAAM,+CACNC,YAAY,EACZC,eAAgB,wBAChBC,QAAS,2DACX,EACA,CACEL,GAAI,MACJC,MAAO,oBACPC,KAAM,gCACNC,YAAY,EACZC,eAAgB,qBAChBC,QAAS,gDACX,EACA,CACEL,GAAI,MACJC,MAAO,SACPC,KAAM,sEACNC,WAAY,GACZC,eAAgB,kBAChBC,QAAS,gCACTG,qBAAqB,CACvB,EACA,CACER,GAAI,WACJC,MAAO,cACPC,KAAM,2BACNC,YAAY,EACZG,qBAAqB,EACrBC,iBAAiB,EACjBH,eAAgB,wCAChBC,QAAS,iDACX,EACA,CACEL,GAAI,YACJC,MAAO,YACPC,KAAM,yBACNC,WAAY,GACZC,eAAgB,+BAChBC,QAAS,0CACX,EACA,CACEL,GAAI,SACJC,MAAO,qBACPC,KAAM,2BACNC,YAAY,EACZE,QAAS,+CACX,EACA,CACEL,GAAI,QACJC,MAAO,iBACPC,KAAM,wBACNC,YAAY,EACZE,QAAS,gCACX,EACA,CACEL,GAAI,aACJC,MAAO,qBACPC,KAAM,gBACNC,YAAY,CACd,EACA,CACEH,GAAI,UACJC,MAAO,UACPC,KAAM,iBACNC,YAAY,EACZC,eAAgB,+BAChBC,QAAS,+BACX,EACA,CACEL,GAAI,OACJC,MAAO,OACPC,KAAM,mBACNC,YAAY,CACd,EACA,CACEH,GAAI,OACJC,MAAO,OACPC,KAAM,mBACNC,YAAY,CACd,EACA,CACEH,GAAI,aACJC,MAAO,aACPC,KAAM,cACNC,YAAY,EACZC,eAAgB,4BAChBC,QAAS,6CACX,EACA,CACEL,GAAI,YACJC,MAAO,YACPC,KAAM,uBACNC,YAAY,EACZC,eAAgB,yBAChBC,QAAS,oBACX,EACA,CACEL,GAAI,aACJC,MAAO,aACPC,KAAM,GACNC,YAAY,EACZC,eAAgB,4BAChBC,QAAS,4BACX,EACA,CACEL,GAAI,SACJC,MAAO,gBACPC,KAAM,8BACNC,WAAY,GACZC,eAAgB,yBAChBC,QAAS,6BACX,EACA,CACEL,GAAI,eACJC,MAAO,eACPC,KAAM,wCACNC,YAAY,EACZG,qBAAqB,EACrBF,eAAgB,gCAClB,EACA,CACEJ,GAAI,OACJC,MAAO,qBACPC,KAAM,wCACNC,YAAY,EAKZI,iBAAiB,CACnB,EACD,CAwBYG,EAA6B,CAExC,CACEV,GAAI,cACJC,MAAO,cACPC,KAAM,iCACNS,SAAU,SACVC,KAAM,CAAC,MAAO,MAAO,UAAU,CAC/BC,QAAS,EACX,EACA,CACEb,GAAI,gBACJC,MAAO,gBACPC,KAAM,sCACNS,SAAU,SACVC,KAAM,CAAC,MAAO,MAAO,UAAU,AACjC,EACA,CACEZ,GAAI,cACJC,MAAO,cACPC,KAAM,0BACNS,SAAU,SACVC,KAAM,CAAC,MAAO,MAAO,UAAU,AACjC,EACA,CACEZ,GAAI,mBACJC,MAAO,m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,aACP,SAAU,SACV,QAAS,+BACT,MAAO,8BACP,OAAQ,CACN,8BACA,8BACA,0BACA,wBACA,gBACA,iBACA,yBACA,uBACD,AACH,EACA,CACE,MAAO,eACP,SAAU,QACV,QAAS,GACT,MAAO,GACP,OAAQ,EAAE,AACZ,EACA,CACE,MAAO,gBACP,SAAU,SACV,QAAS,4CACT,MAAO,mBACP,OAAQ,CAAC,mBAAoB,wBAAyB,iBAAkB,mBAAmB,AAC7F,EACA,CACE,MAAO,oBACP,SAAU,SACV,QAAS,2BACT,MAAO,gBACP,OAAQ,CACN,gBACA,oBACA,oBACA,kBAEJ,AADG,EAEH,CACE,MAAO,mBACP,SAAU,SACV,QAAS,8BACT,MAAO,yBACP,OAAQ,CACN,yBACA,eACA,yBACA,eACA,yBACA,eACA,aACD,AACH,EACA,CACE,MAAO,yBACP,SAAU,SACV,QAAS,0CACT,MAAO,gBACP,OAAQ,CAAC,gBAAgB,AAC3B,EACA,CACE,MAAO,yBACP,SAAU,SACV,QAAS,qBACT,MAAO,eACP,OAAQ,CACN,kBACA,qBACA,gBACA,oBACA,kBACA,kBACA,uBACA,yBACA,YACA,aACA,aACA,aACA,UACA,UACA,QACA,UACA,cACA,eACA,aACA,mBACA,YACA,YACA,aACA,eACA,eACA,eACA,iBACA,iBACA,kBACA,uBACA,sBACA,mBACA,mBACA,mBACA,iBACA,gBACA,yBACA,eACA,WACD,AACH,EACA,CACE,MAAO,6BACP,SAAU,SACV,QAAS,yBACT,MAAO,YACP,OAAQ,CAAC,YAAa,aAAc,aAAc,cAAc,CAChE,gBAAgB,CAClB,EACA,CACE,MAAO,4BACP,SAAU,YACV,QAAS,iDACT,MAAO,gBACP,OAAQ,CAAC,gBAAgB,AAC3B,EACA,CACE,MAAO,aACP,SAAU,aACV,QAAS,4BACT,MAAO,gBACP,OAAQ,CACN,gBACA,sBACA,oBACA,kBACA,UACA,YACA,yBACA,eACD,AACH,EACD,CAED,SAAS,EAAa,CAAqC,SACzD,AAAK,EAGE,CACL,CAJE,EAIC,CAJO,AAII,CACd,GAAG,CAAK,CACR,OAAQ,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"}
|