SPB Git forge

spb/polyllm

Public
15commits 1branches 0releases
2.2 MBsize
maindefault branch
13 days agolast push
TypeScript 97.4% SQL 1% JavaScript 0.9% CSS 0.6%

PolyLLM v0.1.0 — multi-provider BYOK AI workspace (OpenAI, Anthropic, Gemini, xAI)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed 16 days ago (Sep 8, 2026)

44 changed files +20,001 −0

added .env.example +35 −0
@@ -0,0 +1,35 @@
1 +# --- Runtime -------------------------------------------------------------
2 +NODE_ENV=production
3 +PORT=3000
4 +# Public origin used in emails, auth callbacks and canonical links. No trailing slash.
5 +PUBLIC_APP_URL=https://www.polyllm.io
6 +
7 +# --- Database ------------------------------------------------------------
8 +DATABASE_URL=postgres://localhost:5432/polyllm
9 +DB_POOL_MAX=10
10 +
11 +# --- Auth ----------------------------------------------------------------
12 +# 32+ random bytes, hex or base64. `openssl rand -hex 32`
13 +AUTH_SECRET=
14 +
15 +# --- Email (Resend) ------------------------------------------------------
16 +RESEND_API_KEY=
17 +RESEND_FROM_EMAIL="PolyLLM <mail@spboucher.ai>"
18 +# Set to 1 to log emails instead of sending (development).
19 +EMAIL_DRY_RUN=0
20 +
21 +# --- Encryption of user provider keys (AES-256-GCM, server-side only) ----
22 +# 32+ random bytes. Rotating this secret invalidates every stored key.
23 +API_KEY_ENCRYPTION_SECRET=
24 +
25 +# --- Owner / development provider keys (TEST ONLY — never used for users) -
26 +OPENAI_API_KEY=
27 +ANTHROPIC_API_KEY=
28 +GOOGLE_GEMINI_API_KEY=
29 +XAI_API_KEY=
30 +
31 +# --- Admin ---------------------------------------------------------------
32 +# Comma-separated emails with access to /admin.
33 +ADMIN_EMAILS=
34 +# Model catalog refresh interval (minutes). 0 disables the scheduler.
35 +MODEL_SYNC_INTERVAL_MINUTES=360
added .gitignore +33 −0
@@ -0,0 +1,33 @@
1 +# dependencies
2 +node_modules/
3 +.pnpm-store/
4 +
5 +# next
6 +.next/
7 +out/
8 +next-env.d.ts
9 +*.tsbuildinfo
10 +
11 +# env & secrets — never commit
12 +.env
13 +.env.*
14 +!.env.example
15 +deploy/*.mld.json
16 +
17 +# research scratch (installed SDKs, probe outputs)
18 +research/*/node_modules/
19 +research/*/out/
20 +research/*/*.log
21 +
22 +# tests
23 +coverage/
24 +playwright-report/
25 +test-results/
26 +qa/out/
27 +
28 +# misc
29 +.DS_Store
30 +logs/
31 +tmp/
32 +.turbo/
33 +.claude/
added CLAUDE.md +38 −0
@@ -0,0 +1,38 @@
1 +# PolyLLM — repository guide
2 +
3 +PolyLLM (www.polyllm.io) is a BYOK multi-provider AI workspace: OpenAI, Anthropic, Gemini, xAI behind one normalized
4 +adapter layer, real streaming, capability-driven configuration, Arena comparisons, usage/cost tracking.
5 +The original product brief lives in `docs/SPEC-original.md`; the UI conventions in `docs/UI-BRIEF.md`.
6 +
7 +## Non-negotiables
8 +- **Research before provider changes.** Read `docs/provider-research/<provider>.md`, re-fetch the official docs, probe the
9 + real API (`pnpm providers:matrix`), then update `src/lib/ai/providers/<provider>/catalog*.ts`. Never assume model ids,
10 + parameters, event names or limits from memory. Bump `Last documentation audit`.
11 +- **Provider quirks stay inside `src/lib/ai/providers/*`.** UI and services only see `PolyModel`, `UnifiedChatRequest`,
12 + `UnifiedStreamEvent`, `PolyProviderError`.
13 +- **Capabilities drive the UI.** Never branch on a model id in components; use `model.capabilities` / `model.parameters`.
14 + Never send a parameter the model does not accept (`filterSettings()` + adapter translation).
15 +- **Keys.** User keys are encrypted (`src/lib/crypto/keys.ts`) and decrypted only in `getDecryptedKey()` right before a
16 + request. Never log, return or serialize them; `PublicConnection` exposes `keyHint` only. Owner keys in `.env` are for the
17 + registry sync, admin diagnostics and tests — never for user requests.
18 +- **No fake integrations.** A capability is ✅ only after a real request passed (`docs/provider-test-matrix.md`).
19 +- Secrets only in `.env` (gitignored) and the mld manifest on M1M32; `.env.example` documents the variables.
20 +
21 +## Commands
22 +`pnpm dev` · `pnpm typecheck` · `pnpm lint` · `pnpm test` (vitest) · `pnpm test:e2e` (Playwright; dev server with
23 +`EMAIL_DRY_RUN=1 EMAIL_DRY_RUN_PRINT=1`) · `pnpm db:generate` / `pnpm db:migrate` · `pnpm models:sync [provider]` ·
24 +`pnpm providers:matrix [provider]`.
25 +
26 +## Deploy
27 +`mld` from the laptop (see `docs/deployment-cluster.md`): `mld stage . polyllm && mld deploy polyllm --node M3U96a`.
28 +Manifest with secrets: `M1M32:~/dispatch/apps/polyllm.json` (local gitignored copy `deploy/polyllm.mld.json`).
29 +
30 +## Gotchas
31 +- React Compiler lint: no `Date.now()`/impure calls in render, no setState synchronously in effects without an explicit
32 + eslint-disable, memoize derived lists.
33 +- `import "server-only"` modules are used by CLI scripts through `scripts/hooks.mjs` (tsx `--import`) and by vitest via an alias.
34 +- Anthropic: adaptive thinking may legitimately produce zero thinking tokens on easy prompts; Haiku 4.5 needs `budget_tokens`.
35 +- Gemini: free-tier keys have tiny per-model daily quotas (429 `limit: 20`) and some models are paid-tier only (429 `limit: 0`);
36 + thought signatures must be replayed on function-call parts.
37 +- xAI: bad keys return HTTP **400** (`Incorrect API key`), `frequency/presence_penalty` always 400, web search only via `/v1/responses`.
38 +- OpenAI: Responses API has no `seed`/`stop`; sampling params only when `reasoning.effort === "none"` on reasoning models.
added README.md +46 −0
@@ -0,0 +1,46 @@
1 +# PolyLLM
2 +
3 +**One interface. Every model. Bring your own keys.** — https://www.polyllm.io
4 +
5 +PolyLLM is a universal control center for AI models: connect your own OpenAI, Anthropic, Google Gemini and xAI API keys,
6 +discover the models your keys can reach, configure each one with only the parameters it supports, chat with real
7 +token-by-token streaming, compare up to four models side by side in the Arena, and track tokens, latency and estimated
8 +cost. Keys are encrypted at rest (AES-256-GCM, HKDF-derived data key, AAD-bound to the user) and only decrypted on the
9 +server immediately before a provider request.
10 +
11 +## Stack
12 +Next.js 16 (App Router, Route Handlers with SSE streaming) · React 19 · TypeScript · Tailwind v4 · PostgreSQL 17 + Drizzle ·
13 +Better Auth 1.7 (Argon2id, email verification, sessions, reset, change email, delete account) · Resend · Zod ·
14 +official provider SDKs (`openai`, `@anthropic-ai/sdk`, `@google/genai`; xAI through the OpenAI SDK at `api.x.ai`).
15 +
16 +## Layout
17 +```
18 +src/app routes: (marketing) landing/legal · (auth) login/signup/verify/reset · app/* workspace · admin/* · share/[id] · api/*
19 +src/lib/ai/core provider-neutral contract: PolyModel, UnifiedChatRequest, UnifiedStreamEvent, errors, retry, pricing, normalization
20 +src/lib/ai/providers adapters (openai, anthropic, gemini, xai) + catalogs — provider quirks live ONLY here
21 +src/lib/ai/registry model registry: live listing → catalog merge → Postgres; scheduled + manual sync
22 +src/lib/chat turn orchestration (edit/regenerate/continue/branch), built-in tools loop, SSE
23 +src/lib/providers encrypted key storage & validation
24 +src/components ui kit · app shell · chat · arena · settings · marketing
25 +docs/ provider-research (per provider, dated), provider-test-matrix (generated), deployment-cluster, final-audit, UI brief
26 +scripts/ sync-models, provider-matrix (real-API tests)
27 +e2e/, tests/ Playwright workflows, vitest unit tests
28 +```
29 +
30 +## Development
31 +```bash
32 +cp .env.example .env # fill AUTH_SECRET, API_KEY_ENCRYPTION_SECRET, RESEND_API_KEY, owner provider keys (optional)
33 +createdb polyllm && pnpm install && pnpm db:migrate
34 +pnpm models:sync # populate the registry with the owner keys
35 +pnpm dev # http://localhost:3000
36 +pnpm typecheck && pnpm lint && pnpm test
37 +pnpm providers:matrix # real-API capability matrix → docs/provider-test-matrix.md
38 +EMAIL_DRY_RUN=1 EMAIL_DRY_RUN_PRINT=1 pnpm dev && pnpm test:e2e # full browser workflow (links read from the dev log)
39 +```
40 +
41 +## Deployment
42 +Runs on the private MacLustr cluster behind ngrok — see `docs/deployment-cluster.md`.
43 +
44 +## Security notes
45 +No provider key ever reaches the browser, logs or analytics (structured logger redacts key-shaped strings and sensitive
46 +field names). CSP, HSTS, HttpOnly/SameSite cookies, rate limits on auth and provider endpoints, per-user audit log.
added deploy/backup/install.sh +28 −0
@@ -0,0 +1,28 @@
1 +#!/bin/bash
2 +# Installs the daily PostgreSQL backup for PolyLLM on the deployment node (run ON the node).
3 +set -euo pipefail
4 +mkdir -p ~/backups/polyllm ~/Library/LaunchAgents
5 +cat > ~/backups/polyllm/backup.sh <<'SH'
6 +#!/bin/bash
7 +set -euo pipefail
8 +export PATH="/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/bin:$PATH"
9 +out=~/backups/polyllm/polyllm-$(date +%Y%m%d).sql.gz
10 +pg_dump polyllm | gzip -9 > "$out.tmp" && mv "$out.tmp" "$out"
11 +find ~/backups/polyllm -name 'polyllm-*.sql.gz' -mtime +14 -delete
12 +echo "$(date -Iseconds) ok $(du -h "$out" | cut -f1)" >> ~/backups/polyllm/backup.log
13 +SH
14 +chmod +x ~/backups/polyllm/backup.sh
15 +cat > ~/Library/LaunchAgents/dev.polyllm.backup.plist <<PLIST
16 +<?xml version="1.0" encoding="UTF-8"?>
17 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
18 +<plist version="1.0"><dict>
19 + <key>Label</key><string>dev.polyllm.backup</string>
20 + <key>ProgramArguments</key><array><string>/bin/bash</string><string>$HOME/backups/polyllm/backup.sh</string></array>
21 + <key>StartCalendarInterval</key><dict><key>Hour</key><integer>3</integer><key>Minute</key><integer>45</integer></dict>
22 + <key>StandardOutPath</key><string>$HOME/backups/polyllm/launchd.log</string>
23 + <key>StandardErrorPath</key><string>$HOME/backups/polyllm/launchd.log</string>
24 +</dict></plist>
25 +PLIST
26 +launchctl bootout gui/$(id -u)/dev.polyllm.backup 2>/dev/null || true
27 +launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/dev.polyllm.backup.plist
28 +~/backups/polyllm/backup.sh && echo "backup installed + first dump done"
added docs/SPEC-original.md +3 −0
@@ -0,0 +1,3 @@
1 +# PolyLLM — original product brief (CLAUDE.md provided by the owner, 2026-09-08)
2 +
3 +The full brief was supplied in the build session; its normative rules are reproduced in the repository `CLAUDE.md` and `docs/UI-BRIEF.md`. Key sections: research-before-implementation, live model catalog, adapter architecture, mandatory email verification, encrypted BYOK keys, unified streaming events, capability-driven configuration, Arena, usage/cost tracking, security/privacy/logging rules, cluster deployment through ngrok at https://www.polyllm.io, real-API test matrix, final audit.
added docs/UI-BRIEF.md +64 −0
@@ -0,0 +1,64 @@
1 +# PolyLLM — UI brief for contributors (humans and agents)
2 +
3 +PolyLLM (www.polyllm.io) is a **universal control center for AI models**: users bring their own API keys
4 +(OpenAI, Anthropic, Gemini, xAI), discover current models, configure them precisely, chat with real streaming,
5 +compare models in the Arena and track usage/costs. Tagline: **"Your models. Your keys. One workspace."**
6 +
7 +## Stack & conventions
8 +- Next.js 16 App Router, React 19, TypeScript strict, Tailwind v4 (tokens in `src/app/globals.css`), shadcn-style
9 + primitives in `src/components/ui/*` (button, input/textarea/label/field, badge, dialog, dropdown-menu, popover,
10 + select, slider, switch, tabs, tooltip, toast (`toast.success/error/info`), misc: Card/CardHeader/CardBody, Stat,
11 + PageHeader, EmptyState, Skeleton, CopyButton, Kbd, Spinner, Divider). Icons: `lucide-react`. Motion: `motion/react` (sparingly).
12 +- Client data: `useApi<T>(url)` (SWR) and `api<T>(url, { method, json })` from `src/lib/client/api.ts`;
13 + `streamEvents(url, body, onEvent, signal)` for SSE. Types: `src/lib/client/types.ts`. Provider metadata:
14 + `src/lib/client/providers.ts` (`PROVIDERS`, `PROVIDER_ORDER`, `providerName`). Brand: `src/components/brand/logo.tsx`
15 + (`Logo`, `LogoMark`), `src/components/brand/provider-icon.tsx` (`ProviderIcon`).
16 +- App state: `useApp()` from `src/components/app/store.tsx` → `{ user, preferences, updatePreferences, models, modelsByKey,
17 + favorites, recents, connectedProviders, connections, folders, toggleFavorite, refreshModels, refreshConnections,
18 + selectedModelKey, setSelectedModelKey, setPaletteOpen }`. Everything under `/app/*` is wrapped by the shell
19 + (sidebar + command palette) in `src/app/app/layout.tsx`; pages render inside `<div className="relative flex min-w-0 flex-1 flex-col">`.
20 + A page should typically be `<main className="min-h-0 flex-1 overflow-y-auto scrollbar-thin"><div className="mx-auto w-full max-w-5xl px-4 py-6 sm:px-6 lg:px-8">…</div></main>`.
21 +- Auth client: `authClient`, `signIn`, `signUp`, `signOut`, `useSession` from `src/lib/auth-client.ts` (Better Auth 1.7).
22 + Server: `requireUser()` / `getSession()` in `src/lib/session.ts`.
23 +- Formatting helpers: `formatUsd`, `formatTokens`, `formatMs`, `formatRelative`, `formatNumber`, `cn` in `src/lib/utils.ts`.
24 +- Never render key material. Connections only expose `keyHint` like `sk-••••••••9A2K`.
25 +- React Compiler lint rules apply: no setState synchronously in effects without the eslint-disable, no components defined
26 + inside render, derive state with useMemo. Run `pnpm lint` and `pnpm typecheck`.
27 +
28 +## Design language (must feel premium, unique, not a template)
29 +- Minimal, dense-when-useful, excellent typography (Geist Sans/Mono via `font-sans`/`font-mono`), subtle borders
30 + (`border-border`), surfaces `bg-bg / bg-bg-subtle / bg-bg-muted / bg-bg-elevated`, text `text-fg / text-fg-muted / text-fg-subtle`,
31 + accent `text-accent / bg-accent / bg-accent-soft`, semantic `success/warning/danger/info` (+ `-soft`). Radii `rounded-md/lg/xl`.
32 + Provider colors: `text-openai`, `text-anthropic`, `text-gemini`, `text-xai` or `style={{color: PROVIDERS[p].colorVar}}`.
33 +- Dark and light must both look great. No cheap gradients, no childish AI imagery, no huge empty whitespace, no boxed-card overload.
34 + A single restrained gradient (`.text-gradient`) is allowed for hero words. Use `.dot-grid` / `.glass` utilities sparingly.
35 +- Mobile first: no horizontal overflow, 16px inputs on mobile (`text-[15px] sm:text-sm` is already in Input), safe-area aware.
36 +- Keyboard-first: ⌘K palette, ⌘N new chat, ⌘Enter send, Esc stop, ⌘/ model selector, ⌘B sidebar.
37 +- Accessibility: semantic HTML, labels, visible focus, aria on icon buttons, reduced motion respected.
38 +
39 +## API routes (all JSON unless noted; all under a verified session)
40 +- `GET /api/models` → `{ models: PolyModel[], favorites: string[], recents: string[], connectedProviders }`;
41 + `POST /api/models {action:"toggle-favorite", modelKey}`; `POST /api/models/sync {provider?}` → `{results: SyncResult[]}`.
42 +- `GET /api/providers` → `{connections: PublicConnection[]}`; `PUT /api/providers {provider, apiKey}` → `{ok, error?, modelsAvailable?, connections}`;
43 + `POST /api/providers {action:"validate", provider}`; `DELETE /api/providers?provider=`.
44 +- `GET /api/conversations?q&provider&model&folder&archived=1&pinned=1&since&until&limit&cursor`; `POST /api/conversations`;
45 + `GET|PATCH|DELETE /api/conversations/:id`; `POST /api/conversations/:id/actions {action: duplicate|branch|export|share|unshare|share-status|delete-message}`.
46 +- `POST /api/chat` (SSE) body `ChatRequestInput` → events `ChatStreamEvent` (see `src/lib/client/types.ts`).
47 +- `GET /api/folders`, `POST {name,color}`, `PATCH {id,…}`, `DELETE ?id=`.
48 +- `POST /api/attachments` (multipart `file`) → `{attachment}`; `GET /api/attachments?id=` streams the file.
49 +- `GET /api/usage?range=today|7d|30d|all` → `{ totals, series[{bucket,requests,inputTokens,outputTokens,costUsd}], byProvider[], byModel[], recent[] }`.
50 +- `GET /api/presets` → `{modelPresets, promptPresets}`; `POST /api/presets?kind=model|prompt`; `PATCH ?kind&id`; `DELETE ?kind&id`.
51 +- `GET /api/preferences` / `PATCH /api/preferences` (theme, defaultModelKey, defaultSystemPrompt, enterToSend, streaming, codeWrap, showReasoning, showCosts, autoTitle, onboardingCompleted).
52 +- `GET /api/arena` → `{sessions}`; `POST /api/arena {prompt, systemPrompt?, modelKeys[1..4], settings?, attachmentIds?}` → `{session}`;
53 + `POST /api/arena/stream {sessionId, modelKey}` (SSE: meta → text-delta/reasoning-delta/citation → done|error); `PATCH /api/arena {responseId, ratings}`.
54 +- `GET /api/account` → `{audit}`; `GET /api/account?export=1` downloads the full account export.
55 +- `GET /api/search?q=`.
56 +- Admin: `GET /api/admin/providers`, `POST /api/admin/providers {action:"sync", provider?}` (owner only, `user.isAdmin`).
57 +- Better Auth: `/api/auth/*` (client SDK). Email verification is mandatory: unverified users are redirected to `/verify-email`.
58 +
59 +## Model capability sheet (drives every configuration UI)
60 +`PolyModel.capabilities` {text, vision, audioInput, audioOutput, imageGeneration, video, reasoning, tools, structuredOutput,
61 +streaming, files, webSearch}; `parameters` {temperature, topP, topK, maxTokens, reasoningEffort, reasoningEffortLevels[],
62 +thinkingBudget, thinkingBudgetRange, stop, seed, frequencyPenalty, presencePenalty, verbosity, temperatureRange};
63 +`limits` {contextTokens, maxOutputTokens}; `pricing` {inputPerMillion, cachedInputPerMillion, outputPerMillion};
64 +`status` active|preview|deprecated|unknown; `metadata.shutdownDate`, `metadata.aliases`, etc. **Never show a control the model does not support.**
added docs/deployment-cluster.md +91 −0
@@ -0,0 +1,91 @@
1 +# PolyLLM — cluster deployment (MacLustr)
2 +
3 +Production runs on the owner's private Apple Silicon cluster and is exposed through ngrok at
4 +**https://www.polyllm.io**. Everything is orchestrated by `mld` (maclustr-dispatch) from the gateway node M1M32.
5 +
6 +```
7 +Internet → www.polyllm.io (CNAME → ngrok) → ngrok agent (PM2 polyllm-ngrok) → Next.js `next start` 0.0.0.0:8240 → PostgreSQL 17 (localhost)
8 +```
9 +
10 +| Item | Value |
11 +| --- | --- |
12 +| Node | M3U96a (pinned: local PostgreSQL 17, same host as fetcha / spinza / rareindex) |
13 +| Directory | `~/apps/polyllm` (rsync'd by mld from the laptop staging area) |
14 +| Processes | PM2 `polyllm-web` (Next 16, port 8240, binds 0.0.0.0), PM2 `polyllm-ngrok` (`--domain www.polyllm.io`) |
15 +| Database | `postgres://localhost:5432/polyllm` (created by the post-sync hook if missing) |
16 +| Manifest | `M1M32:~/dispatch/apps/polyllm.json` — **the only place secrets live** (gitignored copy `deploy/polyllm.mld.json`) |
17 +| Health | `GET /api/health` (liveness), `GET /api/health/ready` (DB ping; used by mld) |
18 +| Registry | `mld status` / `mld status --live` |
19 +
20 +## Environment variables (production)
21 +
22 +See `.env.example`. Required: `NODE_ENV=production`, `PORT=8240`, `PUBLIC_APP_URL=https://www.polyllm.io`,
23 +`DATABASE_URL`, `AUTH_SECRET` (32+ bytes), `API_KEY_ENCRYPTION_SECRET` (32+ bytes — **rotating it invalidates every
24 +stored user key**), `RESEND_API_KEY`, `RESEND_FROM_EMAIL`, `ADMIN_EMAILS`. Optional owner keys
25 +(`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GOOGLE_GEMINI_API_KEY`, `XAI_API_KEY`) are used **only** for the scheduled
26 +model-registry refresh and the admin diagnostics; user requests always use the user's own encrypted key.
27 +
28 +## Build & deploy
29 +
30 +```bash
31 +# laptop
32 +cd ~/Desktop/Projets/apps-web/polyllm
33 +pnpm typecheck && pnpm lint && pnpm test # gates
34 +scp deploy/polyllm.mld.json M1M32:~/dispatch/apps/polyllm.json # first time / when secrets change
35 +~/Desktop/cluster-skill/mld stage . polyllm # laptop → M1M32 staging
36 +~/Desktop/cluster-skill/mld deploy polyllm --node M3U96a
37 +```
38 +
39 +`mld deploy` runs the manifest hooks on the node: `pnpm install --frozen-lockfile` → `createdb polyllm` (if needed) +
40 +`pnpm db:migrate` (Drizzle migrations in `drizzle/`, version-controlled) → `pnpm build` → PM2 start/reload of
41 +`polyllm-web` and `polyllm-ngrok` → local health check (`/api/health/ready`) → public health check (`https://www.polyllm.io/api/health/ready`) → registry update.
42 +
43 +Restart / logs on the node:
44 +
45 +```bash
46 +ssh M3U96a 'pm2 restart polyllm-web; pm2 logs polyllm-web --lines 100 --nostream'
47 +ssh M3U96a 'pm2 logs polyllm-ngrok --lines 30 --nostream'
48 +```
49 +
50 +Migrations are applied by the hook before the new build starts; they must stay backward compatible with the running
51 +version (add columns, never drop in the same release).
52 +
53 +## ngrok / domain / TLS
54 +
55 +- DNS (GoDaddy): `www.polyllm.io` CNAME → the ngrok-cname target shown in the ngrok dashboard for the reserved domain.
56 + The apex `polyllm.io` should redirect to `https://www.polyllm.io` (GoDaddy forwarding).
57 +- TLS terminates at ngrok (automatic certificate for the reserved domain). The app sees `X-Forwarded-For` /
58 + `X-Forwarded-Proto`; Better Auth is configured with `baseURL = PUBLIC_APP_URL` and secure cookies in production.
59 +- The PM2 process `polyllm-ngrok` runs `ngrok http 8240 --domain www.polyllm.io`. Only port 8240 is exposed; no admin port.
60 +- Streaming: SSE responses send a `: ping` heartbeat every 15 s so ngrok never closes idle long reasoning turns.
61 +
62 +## Process management
63 +
64 +PM2 with `pm2 startup` (LaunchAgent) on the node → processes survive terminal closure and reboots; `autorestart: true`,
65 +`max_memory_restart: 2G`. The model-registry scheduler runs inside the web process (`src/instrumentation.ts`, every
66 +`MODEL_SYNC_INTERVAL_MINUTES`, default 360) plus a startup sync.
67 +
68 +## Backups
69 +
70 +- Daily `pg_dump` at 03:45 via launchd `dev.polyllm.backup` on M3U96a → `~/backups/polyllm/polyllm-YYYYMMDD.sql.gz`,
71 + 14-day retention (`find -mtime +14 -delete`). Install with `deploy/backup/install.sh` (see that file).
72 +- Restore: `gunzip -c ~/backups/polyllm/polyllm-YYYYMMDD.sql.gz | psql polyllm_restore` after `createdb polyllm_restore`;
73 + swap with `ALTER DATABASE … RENAME` during a maintenance window. Test restore on the 1st of each month into a scratch DB
74 + and run `select count(*) from users;` to validate.
75 +- Encrypted user keys are only decryptable with the same `API_KEY_ENCRYPTION_SECRET`: back up the manifest too
76 + (`M1M32:~/dispatch/apps/polyllm.json` is included in the spbgit gateway backup).
77 +
78 +## Rollback
79 +
80 +```bash
81 +ssh M3U96a 'cd ~/apps/polyllm && git log --oneline -5' # deployed commit
82 +# redeploy the previous tag from the laptop:
83 +git checkout <previous-tag> && ~/Desktop/cluster-skill/mld stage . polyllm && ~/Desktop/cluster-skill/mld deploy polyllm --node M3U96a
84 +```
85 +
86 +If a migration must be reverted, restore last night's dump (see Backups) — Drizzle migrations are forward-only.
87 +
88 +## Moving to another node
89 +
90 +`mld move polyllm --to <node>` handles rsync, PM2 and ngrok, but the database is local: dump on M3U96a, restore on the
91 +target (PostgreSQL 17 via Homebrew), then update `DATABASE_URL` in the manifest before the move.
added docs/provider-research.md +30 −0
@@ -0,0 +1,30 @@
1 +# Provider research — index
2 +
3 +**Last documentation audit: 2026-09-08**
4 +
5 +PolyLLM never relies on remembered API shapes. Before each adapter was written, the CURRENT official
6 +documentation was fetched and every claim that matters for the adapter was **probed against the real API**
7 +with the owner's keys. The per-provider reports below contain the base URLs, auth, SDKs and versions, streaming
8 +protocols and event names, tool/structured-output formats, reasoning controls, modalities, limits, parameter
9 +support matrices with exact rejection strings, error schemas, rate limits, pricing, lifecycle, and the probe
10 +scripts that produced the evidence.
11 +
12 +| Provider | Report | Model data | SDK used | Primary API | Probe scripts |
13 +| --- | --- | --- | --- | --- | --- |
14 +| OpenAI | [openai.md](provider-research/openai.md) | [openai.models.json](provider-research/openai.models.json) (84) | `openai` 7.10 | Responses API (`store:false`, encrypted reasoning replay) | `research/openai/` |
15 +| Anthropic | [anthropic.md](provider-research/anthropic.md) | Models API (live capabilities) + `src/lib/ai/providers/anthropic/catalog.ts` (pricing) | `@anthropic-ai/sdk` 0.124 | Messages API (adaptive thinking, `output_config`) | `scripts/provider-matrix.ts` |
16 +| Google Gemini | [gemini.md](provider-research/gemini.md) | [gemini.models.json](provider-research/gemini.models.json) (19) | `@google/genai` 2.21 | `generateContentStream` (thinkingLevel/budget per family, thought signatures) | `research/gemini/` |
17 +| xAI | [xai.md](provider-research/xai.md) | [xai.models.json](provider-research/xai.models.json) (7) | `openai` 7.10 with `baseURL https://api.x.ai/v1` | Chat Completions (+ `/v1/responses` for server-side web search) | `research/xai/` |
18 +
19 +The verified behaviour is encoded in code, not prose:
20 +
21 +- `src/lib/ai/providers/<provider>/catalog*.ts` — capability sheets, parameter support, pricing, lifecycle.
22 +- `src/lib/ai/providers/<provider>/index.ts` — request translation that only sends what the model accepts.
23 +- `docs/provider-test-matrix.md` — generated by `pnpm providers:matrix` from live requests.
24 +
25 +## Re-audit procedure (before every release)
26 +
27 +1. `pnpm models:sync` — refresh the registry from the live listing endpoints; check `model_sync_runs` for removed/added ids.
28 +2. Re-fetch the docs pages linked at the bottom of each report; update the catalog data when parameters, limits or prices moved.
29 +3. `pnpm providers:matrix` — must be all ✅; investigate any ❌ before shipping.
30 +4. Bump `Last documentation audit` in this file and in each report.
added docs/provider-research/anthropic.md +41 −0
@@ -0,0 +1,41 @@
1 +# Anthropic — provider research
2 +
3 +**Last documentation audit: 2026-09-08** — sources: Claude Platform docs (Messages API, Models API, extended thinking,
4 +structured outputs, tool use, prompt caching, pricing, errors), the bundled `claude-api` reference (models table cached
5 +2026-06-24), SDK type definitions of `@anthropic-ai/sdk` 0.124.0, and live probes with the owner key (`scripts/provider-matrix.ts`
6 +and `GET /v1/models`).
7 +
8 +## Endpoint, auth, SDK
9 +- Base URL `https://api.anthropic.com`; headers `x-api-key`, `anthropic-version: 2023-06-01`. Invalid key → **401** `authentication_error`.
10 +- SDK `@anthropic-ai/sdk` 0.124.0 (`client.messages.create({stream:true})` returns an async iterable of raw events; `client.models.list()` auto-paginates; `client.messages.countTokens`).
11 +- Timeouts: SDK default 10 min; PolyLLM uses 10 min for chats, 20 s for validation/listing; SDK retries 1 (PolyLLM never retries mid-stream).
12 +
13 +## Models API (live capability metadata — verified)
14 +`GET /v1/models` returns `id, display_name, created_at, max_input_tokens, max_tokens, capabilities` with
15 +`thinking.types.{adaptive,enabled}`, `effort.{low,medium,high,xhigh,max}`, `image_input`, `pdf_input`, `structured_outputs`,
16 +`code_execution`, `citations`, `batch`, `context_management`. 11 models for this key: `claude-fable-5-1`, `claude-opus-5`,
17 +`claude-sonnet-5`, `claude-fable-5`, `claude-opus-4-8`, `claude-opus-4-7`, `claude-sonnet-4-6`, `claude-opus-4-6`,
18 +`claude-opus-4-5-20251101`, `claude-haiku-4-5-20251001`, `claude-sonnet-4-5-20250929`. Aliases (`claude-haiku-4-5`) resolve to dated snapshots.
19 +All current models: 1M context (Haiku 4.5: 200k), 128k max output (Haiku 4.5: 64k).
20 +
21 +## Verified rules encoded in the adapter
22 +- **Adaptive-only generations** (`thinking.types.enabled.supported === false`: Fable 5/5.1, Opus 5/4.8/4.7, Sonnet 5) reject
23 + `temperature`/`top_p`/`top_k` (400) and `budget_tokens`; the adapter exposes none of them. Effort via `output_config.effort`.
24 + Sending `thinking:{type:"adaptive"}` to Haiku 4.5 → 400 `adaptive thinking is not supported on this model` (probed) → Haiku uses `{type:"enabled", budget_tokens}` (≥1024, < max_tokens).
25 +- Fable 5.x: thinking always on, `{type:"disabled"}` → 400; forced `tool_choice` `any`/`tool` → 400 on Fable 5.1 (adapter downgrades to `auto`).
26 +- Adaptive thinking decides when to think: trivial prompts produce **no thinking block and 0 thinking tokens** even at effort `high` (probed on Sonnet 5); a harder prompt produced 3.5k thinking tokens with `display:"summarized"`.
27 +- Streaming events: `message_start` (input usage incl. cache), `content_block_start/delta/stop` with `text_delta`, `thinking_delta`,
28 + `signature_delta`, `input_json_delta`, `citations_delta`; `message_delta` carries `stop_reason` (`end_turn|max_tokens|stop_sequence|tool_use|pause_turn|refusal|model_context_window_exceeded`),
29 + `usage.output_tokens` and `usage.output_tokens_details.thinking_tokens`; `stop_details` on refusal.
30 +- Tools: `tools[{name, description, input_schema, strict}]`; tool results as `tool_result` blocks in a **user** turn; thinking blocks replayed with signature only on the same model.
31 +- Server tools: `web_search_20260209` (Opus 5/4.8/4.7/4.6, Sonnet 5/4.6; not combinable with `code_execution_20260521`), `web_search_20250305` for older models.
32 +- Structured output: `output_config.format = { type: "json_schema", schema }` (Opus 4.7+, Sonnet 5, Fable — `structured_outputs.supported`).
33 +- Files: PDF as `document` (base64), text files as `document` with `text/plain` source; images base64 `image` blocks.
34 +- Errors: `{type:"error", error:{type, message}}`: `authentication_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `overloaded_error` (529, retryable), `billing_error`, `request_too_large`, `invalid_request_error`.
35 +- Pricing (USD/M, first-party): Fable 5.1 10/50 (cache read 0.25), Opus 5 5/25, Sonnet 5 2/10, Sonnet 4.6 3/15, Haiku 4.5 1/5 — see `catalog.ts`; cache reads 10 % of input.
36 +- Prompt caching: `cache_control` (not used by PolyLLM v0.1; usage reports `cache_read_input_tokens`, folded into cached tokens).
37 +
38 +## Probe results (2026-09-08, `pnpm providers:matrix`)
39 +Auth ✅ · Model list ✅ (11) · Text ✅ · Streaming ✅ · System ✅ · Vision ✅ (64×64 PNG → "Red") · Tools ✅ (streamed `input_json_delta`, args rebuilt) ·
40 +Structured output ✅ · Reasoning ✅ (Sonnet 5, effort high, 3 558 thinking tokens, summary streamed) · Token usage ✅ · Invalid key ✅ (401) ·
41 +Error normalization ✅ (unknown model → `not_found_error` → MODEL_NOT_FOUND) · Long response ✅ (407 words).
added docs/provider-research/gemini.md +302 −0
@@ -0,0 +1,302 @@
1 +# Google Gemini (Gemini Developer API) — provider research for PolyLLM
2 +
3 +Last documentation audit: **2026-09-08**. SDK probed: `@google/genai` **2.21.0** (Node 25.9, tsx 4.23). Probe scripts and raw outputs: `research/gemini/*.ts`, `research/gemini/out/*.json` (keys redacted). Key used: free-tier `AQ.`-style ("auth") key.
4 +
5 +> Headline for the adapter: `generateContent` / `streamGenerateContent` remain **fully supported** but Google now labels them legacy and documents everything on the new **Interactions API** (`ai.interactions.create`, GA June 2026, "recommended for all new projects", all new features land there first). This audit targets `generateContent` (what the SDK's `ai.models.*` uses) and notes Interactions where relevant.
6 +
7 +---
8 +
9 +## 1. Endpoint, auth, headers
10 +
11 +| Item | Value (verified by probe unless marked docs) |
12 +|---|---|
13 +| Base URL | `https://generativelanguage.googleapis.com` |
14 +| API version | `v1beta` (SDK default; needed for computer use / MCP / preview features). `v1` also works: probed `gemini-3.8-flash` + `thinkingLevel` on `v1` -> OK. Select via `new GoogleGenAI({ apiKey, httpOptions: { apiVersion: "v1" } })`. |
15 +| Auth header | `x-goog-api-key: <key>` (works with `AQ.` keys). `?key=` query param also works (200). **`Authorization: Bearer <api key>` does NOT work**: 401 `UNAUTHENTICATED`, reason `ACCESS_TOKEN_TYPE_UNSUPPORTED` (Bearer is only for the OpenAI-compat endpoint). |
16 +| Other headers | `Content-Type: application/json`. No rate-limit headers are returned (only `server-timing`, `vary`, `alt-svc`). |
17 +| Key formats | New keys created in AI Studio are "auth keys" bound to a service account (`AQ.` prefix). Docs: **standard (legacy) keys will be rejected after September 2026** — expect BYOK users with old keys to break. Leaked keys: `"Your API key was reported as leaked. Please use another API key."` |
18 +| SDK env vars | `GEMINI_API_KEY` or `GOOGLE_API_KEY` (`GOOGLE_API_KEY` wins if both). Pass `apiKey` explicitly in a BYOK app. |
19 +| OpenAI-compat | `https://generativelanguage.googleapis.com/v1beta/openai/` with `Authorization: Bearer <key>`; `reasoning_effort` maps to thinking levels (3.x) or budgets 1024/8192/24576 (2.5); Gemini extras via `extra_body.google.*`. Beta. Not probed. |
20 +
21 +Docs: https://ai.google.dev/gemini-api/docs/api-key , https://ai.google.dev/gemini-api/docs/api-versions , https://ai.google.dev/gemini-api/docs/openai
22 +
23 +## 2. SDK
24 +
25 +```bash
26 +pnpm add @google/genai@latest # 2.21.0 on 2026-09-08; Node >= 20 (3.x will require Node 22+)
27 +```
28 +```ts
29 +import { GoogleGenAI } from "@google/genai";
30 +const ai = new GoogleGenAI({ apiKey, httpOptions: { timeout: 120_000 /* ms */, apiVersion: "v1beta" } });
31 +```
32 +- `ai.models.generateContent / generateContentStream / countTokens / list / get`, `ai.chats.create` (client-side history helper), `ai.caches`, `ai.files`, `ai.batches`, `ai.live`, `ai.interactions` (new), `mcpToTool()`.
33 +- Errors: `ApiError { name: "ApiError", status: <http>, message: <JSON string of the body> }` — message is the raw `{"error":{code,message,status,details}}` JSON; parse it. Retries: `httpOptions.retryOptions` exists (defaults not documented for JS).
34 +- `config.abortSignal` supported on generate calls.
35 +- Legacy `@google/generative-ai` is deprecated (since 2025-11-30) — do not use.
36 +- SDK-side guard: `toolConfig.functionCallingConfig.streamFunctionCallArguments` throws `"streamFunctionCallArguments parameter is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."` (no partial-args streaming on the Developer API).
37 +
38 +Docs: https://github.com/googleapis/js-genai , https://ai.google.dev/gemini-api/docs/libraries
39 +
40 +## 3. generateContent / streamGenerateContent
41 +
42 +REST: `POST /v1beta/models/{model}:generateContent` and `POST /v1beta/models/{model}:streamGenerateContent?alt=sse`.
43 +
44 +Request body: `contents[]` (`{role:"user"|"model", parts:[...]}`), `systemInstruction` (`{parts:[{text}]}`), `tools[]`, `toolConfig`, `safetySettings[]`, `generationConfig`, `cachedContent`, `serviceTier`, `store`.
45 +Response: `candidates[0].content.parts[]`, `candidates[0].finishReason`, `usageMetadata`, `modelVersion`, `responseId`, `promptFeedback`, `modelStatus`.
46 +
47 +Part fields seen in probes: `text`, `thought: true` (thought summary), `thoughtSignature` (base64 string, 300–700 chars), `functionCall {name, args, id}`, `functionResponse`, `inlineData {mimeType, data}`, `fileData {fileUri, mimeType}`, `executableCode {language:"PYTHON", code, id}`, `codeExecutionResult {outcome:"OUTCOME_OK", output, id}`.
48 +
49 +FinishReason enum (SDK 2.21): `STOP, MAX_TOKENS, SAFETY, RECITATION, LANGUAGE, OTHER, BLOCKLIST, PROHIBITED_CONTENT, SPII, MALFORMED_FUNCTION_CALL, IMAGE_SAFETY, UNEXPECTED_TOOL_CALL, TOO_MANY_TOOL_CALLS, IMAGE_PROHIBITED_CONTENT, NO_IMAGE, IMAGE_RECITATION, IMAGE_OTHER`.
50 +
51 +Docs: https://ai.google.dev/api/generate-content , https://ai.google.dev/gemini-api/docs/text-generation
52 +
53 +### 3.1 Streaming protocol (verified)
54 +
55 +- REST with `alt=sse`: `Content-Type: text/event-stream`; each event is `data: {GenerateContentResponse JSON}` terminated by **CRLF CRLF** (`\r\n\r\n`); no `event:` lines, no `[DONE]` sentinel — the stream simply ends. Errors before the first token come back as a normal HTTP error status (400 etc.) but still with `text/event-stream` content type and a JSON `{error}` body — check `res.ok` before parsing SSE.
56 +- REST without `alt=sse`: `application/json` **JSON array** of responses (`[{...},{...}]`) streamed incrementally — avoid.
57 +- SDK: `for await (const chunk of await ai.models.generateContentStream({...}))`, each chunk is a full `GenerateContentResponse` (`chunk.text` getter concatenates non-thought text).
58 +- Chunk shape observed (Gemini 3.x Flash): 2–4 chunks for short answers. With `includeThoughts: true` the **first chunk** carries `parts:[{text:"…", thought:true}]`; then text chunks; the **last chunk** has `finishReason` and typically an **empty text part carrying `thoughtSignature`** (`{text:"", thoughtSignature:"…"}`) — do not render it as text, but keep it if you replay history.
59 +- `usageMetadata` is present on **every** chunk. On 3.5/3.6 Flash the first chunk has only `promptTokenCount/totalTokenCount/promptTokensDetails/serviceTier`; subsequent chunks have the full set (`candidatesTokenCount`, `thoughtsTokenCount`). On 3.7 Flash all chunks were full. Rule: **take usage from the last chunk**.
60 +- Function calls stream as a single chunk: `parts:[{functionCall:{name,args,id:"call_…"}, thoughtSignature:"…"}]`, followed by a final chunk with an empty `text` part and `finishReason:"STOP"` (not `FUNCTION_CALL`). Args are complete (never partial).
61 +
62 +### 3.2 usageMetadata fields
63 +`promptTokenCount`, `candidatesTokenCount`, `thoughtsTokenCount` (absent when 0), `cachedContentTokenCount` (absent when 0), `toolUsePromptTokenCount`, `totalTokenCount` (= prompt + candidates + thoughts), `promptTokensDetails[{modality:"TEXT"|"IMAGE"|…, tokenCount}]`, `cacheTokensDetails[]`, `candidatesTokensDetails[]`, `serviceTier:"standard"`. Thinking tokens are billed as output.
64 +
65 +### 3.3 Exact SDK code that worked
66 +
67 +```ts
68 +const stream = await ai.models.generateContentStream({
69 + model: "gemini-3.5-flash-lite",
70 + contents: [{ role: "user", parts: [{ text: "Count from 1 to 12, then say DONE." }] }],
71 + config: {
72 + systemInstruction: "You are terse.",
73 + maxOutputTokens: 2000, // includes thinking tokens!
74 + thinkingConfig: { includeThoughts: true, thinkingLevel: "LOW" }, // never combine with thinkingBudget
75 + },
76 +});
77 +let usage;
78 +for await (const chunk of stream) {
79 + for (const part of chunk.candidates?.[0]?.content?.parts ?? []) {
80 + if (part.thought) emitReasoning(part.text);
81 + else if (part.text) emitText(part.text); // may be "" on the final signature-only part
82 + if (part.functionCall) emitToolCall(part.functionCall.id, part.functionCall.name, part.functionCall.args, part.thoughtSignature);
83 + }
84 + if (chunk.candidates?.[0]?.finishReason) finish = chunk.candidates[0].finishReason;
85 + usage = chunk.usageMetadata ?? usage; // last chunk wins
86 +}
87 +```
88 +
89 +## 4. generationConfig parameter support (probed matrix)
90 +
91 +Probed with `maxOutputTokens: 1500` on the models the free-tier key can call. Legend: OK / 400 "…" = exact server message / — = not probed (quota).
92 +
93 +| param | 3.8-flash | 3.5-flash | 3.5-flash-lite | 3.1-flash-lite | 3-flash-preview | gemma-4-31b-it |
94 +|---|---|---|---|---|---|---|
95 +| temperature 0 / 1.5 / 2 | OK | OK | OK | OK | OK | 2 OK; 0,1.5 → 500 INTERNAL (flaky) |
96 +| temperature 2.5 | 400 `* GenerateContentRequest.generation_config.temperature: temperature must be in the range [0.0, 2.0].` | same | same | same | same | same |
97 +| topP 0.9 | OK | OK | OK | OK | OK | 500 INTERNAL (flaky) |
98 +| topK 40 | — | OK | OK | OK | OK | OK |
99 +| seed 42 | — | OK | OK | OK | OK | OK |
100 +| stopSequences ["DONE"] | — | OK (stopped before DONE) | OK | OK | OK | 500 INTERNAL (flaky) |
101 +| frequencyPenalty 0.5 | — | 400 `Penalty is not enabled for this model` | same | same | same | same |
102 +| presencePenalty 0.5 | — | 400 `Penalty is not enabled for this model` | same | same | same | same |
103 +| candidateCount 2 | 400 `Multiple candidates is not enabled for this model` | same | same | same | same | same |
104 +| responseMimeType application/json | — | OK | OK | OK | OK | 500 (flaky) |
105 +| responseSchema (OpenAPI, `OBJECT/STRING`) | — | OK | OK | OK | OK | OK |
106 +| responseJsonSchema (JSON Schema) | — | OK | OK | OK | OK | OK |
107 +| responseMimeType text/x.enum + enum schema | — | OK (`blue`) | OK | OK | OK | OK |
108 +| thinkingConfig.thinkingBudget 0 | — | OK (0 thoughts) | 400 `Request contains an invalid argument.` | OK | OK | 400 `Thinking budget is not supported for this model.` |
109 +| thinkingBudget 1024 / -1 | — | — | OK / OK | OK / OK | OK / OK (-1 → 1436 thought tokens) | 400 same |
110 +| includeThoughts true | — | OK (thought parts) | OK | OK | OK | 500 (flaky) |
111 +| thinkingLevel MINIMAL | docs: **error** | — | OK (0 thoughts) | OK (0) | OK (0) | 500 (flaky) |
112 +| thinkingLevel LOW / MEDIUM / HIGH | — | — | OK | OK | HIGH, MEDIUM OK; LOW — | 400 `Thinking level is not supported for this model.` (HIGH → 500) |
113 +| thinkingLevel + thinkingBudget | — | — | 400 `You can only set only one of thinking budget and thinking level.` | same | same | same |
114 +| responseLogprobs/logprobs | 400 `Logprobs is not enabled for this model` | — | same | same | — | same |
115 +
116 +Notes:
117 +- **Sampling deprecation**: changelog 2026-07-21 — "The sampling parameters `temperature`, `top_p` and `top_k` are now deprecated" (for 3.6 Flash / 3.5 Flash-Lite onward; the 3.8 guide says "Strip `temperature`, `top_p`, and `top_k` from generation configs"). They are still **accepted** by `generateContent` (probed) but Google recommends not sending them; Gemini 3 guide: "strongly recommend keeping the temperature parameter at its default value of 1.0" (lower values can cause looping). Adapter: default to not sending temperature/topP/topK for Gemini 3.x unless the user overrides.
118 +- Default temperature/topP/topK reported by the models endpoint: 1 / 0.95 / 64 (maxTemperature 2) for all Gemini text models.
119 +- `maxOutputTokens` **includes thinking tokens**: `gemini-3.8-flash` with `maxOutputTokens: 100` returned empty text, `finishReason: MAX_TOKENS`, `thoughtsTokenCount: 97`. Give thinking models a generous budget (>= 1024 + expected answer) or disable thinking.
120 +- `stopSequences` are honoured but the stop string itself is stripped.
121 +
122 +## 5. Reasoning controls per family
123 +
124 +| Family | Default | Controls | Probe evidence |
125 +|---|---|---|---|
126 +| Gemini 3.8 / 3.7 Flash | `thinkingLevel` **medium** | `low, medium, high`; `minimal` → error (docs). `thinkingBudget` still accepted "for backward compatibility" per Gemini 3 guide but 3.8 guide says replace it. Cannot be disabled. | 3.8: thoughts 199–330 on trivial prompts. |
127 +| Gemini 3.6 Flash | medium | `minimal, low, medium, high` | stream has thought part first. |
128 +| Gemini 3.5 Flash | medium (docs) | all four levels (docs); `thinkingBudget: 0` **does** disable (probed). | thoughts 136–515 by default. |
129 +| Gemini 3.5 Flash-Lite / 3.1 Flash-Lite | **minimal (off)** | all four levels; `thinkingBudget` 1024 / -1 OK; `thinkingBudget: 0` rejected on 3.5-lite (use MINIMAL) but OK on 3.1-lite. | thoughts 0 unless requested. |
130 +| Gemini 3 Flash Preview / 3.1 Pro Preview | high (dynamic) | `minimal, low, medium, high`; budgets 0/1024/-1 OK on 3-flash-preview. | |
131 +| Gemini 2.5 Pro / Flash / Flash-Lite | on / on / off | `thinkingBudget` (Pro 128–32768 cannot disable; Flash 0–24576; Lite 512–24576; -1 dynamic) + `thinkingLevel` low/medium/high (docs). | **Not callable with new keys (404)** — docs only. |
132 +| Gemma 4 | thinks by default | **no control**: both `thinkingBudget` and `thinkingLevel` → 400. | thoughts 47–430. |
133 +
134 +- `includeThoughts: true` → thought **summaries** as parts with `thought: true` (streamed first). Raw reasoning is never returned.
135 +- Thinking tokens: `usageMetadata.thoughtsTokenCount`, billed at the output rate.
136 +- SDK enum: `ThinkingLevel.MINIMAL|LOW|MEDIUM|HIGH` (strings `"MINIMAL"`… accepted; Interactions API uses lowercase).
137 +
138 +Docs: https://ai.google.dev/gemini-api/docs/thinking , https://ai.google.dev/gemini-api/docs/gemini-3 , https://ai.google.dev/gemini-api/docs/latest-model
139 +
140 +### 5.1 Thought signatures (critical for tool calling)
141 +- Gemini 3.x attaches `thoughtSignature` to the **functionCall part** (and to the last text/empty part of a text answer, and to `executableCode` parts).
142 +- **Function calling is strict**: replaying the model turn without the signature → 400 `INVALID_ARGUMENT`: `Function call is missing a thought_signature in functionCall parts. This is required for tools to work correctly, and missing thought_signature may lead to degraded model performance. Additional data, function call `default_api:get_weather` , position 2. Please refer to https://ai.google.dev/gemini-api/docs/thought-signatures for more details.` (probed on gemini-3.7-flash).
143 +- Echoing the real signature → OK. The documented escape hatch `thoughtSignature: "skip_thought_signature_validator"` on the functionCall part → accepted (probed) — useful when importing history from another provider.
144 +- Text-only multi-turn **without** signatures works (probed): signatures on text parts are optional.
145 +- Adapter rule: persist `thoughtSignature` alongside each tool call (and ideally each assistant part) in the conversation store and replay it verbatim in `contents`.
146 +
147 +## 6. Tool calling (function declarations)
148 +
149 +```ts
150 +const tools = [{ functionDeclarations: [{
151 + name: "get_weather", description: "Get weather for a city.",
152 + parametersJsonSchema: { type: "object", properties: { city: { type: "string" } }, required: ["city"] }, // JSON Schema (lowercase types)
153 + // or legacy: parameters: { type: "OBJECT", properties: { city: { type: "STRING" } }, required: ["city"] }
154 +}]}];
155 +// model turn → parts: [{ functionCall: { name, args, id: "call_88210" }, thoughtSignature }]
156 +// reply:
157 +contents.push({ role: "model", parts: modelPartsVerbatim }); // keep thoughtSignature!
158 +contents.push({ role: "user", parts: [{ functionResponse: { name, id, response: { /* any JSON object */ } } }] });
159 +```
160 +- `toolConfig.functionCallingConfig`: `mode: AUTO | ANY | NONE | VALIDATED`, `allowedFunctionNames[]`. `ANY` + `allowedFunctionNames` probed OK on 3.6 Flash (forced call).
161 +- Parallel calls arrive as multiple `functionCall` parts in one turn; send all `functionResponse` parts in one user turn (same order).
162 +- `functionCall.id` is present on 3.x (`call_NNNNN`); echo it in `functionResponse.id`.
163 +- Built-in tools **can be combined with function declarations on Gemini 3** (not on 2.5). Structured output + tools also allowed on Gemini 3.
164 +- SDK automatic function calling exists (`config.automaticFunctionCalling`) — disable it in a UI adapter (`{ disable: true }`) to keep control of the loop.
165 +- MCP: `mcpToTool(client)` in the SDK (experimental) and server-side `tools:[{ mcpServers: [...] }]` (v1beta, docs: HTTP transport only).
166 +
167 +Docs: https://ai.google.dev/gemini-api/docs/function-calling (now Interactions-only; legacy shapes verified by probe and SDK types)
168 +
169 +## 7. Structured output / JSON schema
170 +- `responseMimeType: "application/json"` alone → valid JSON of free shape (one model returned an array).
171 +- `responseJsonSchema` (standard JSON Schema: lowercase types, `additionalProperties`, `anyOf`, `$ref:"#"`, `enum`, `format` date/time, `minimum/maximum`, `items/prefixItems/minItems/maxItems`) → **preferred**; probed OK on all callable models incl. Gemma 4.
172 +- `responseSchema` (legacy OpenAPI `Schema` with uppercase `TYPE`s, `propertyOrdering`) → still OK. Don't send both.
173 +- `responseMimeType: "text/x.enum"` + `{type:"STRING", enum:[…]}` → bare enum value (probed).
174 +- Works together with thinking (JSON is in non-thought parts) and, on Gemini 3, with tools.
175 +
176 +Docs: https://ai.google.dev/gemini-api/docs/structured-output
177 +
178 +## 8. Modalities
179 +| Modality | How | Limits / notes |
180 +|---|---|---|
181 +| Image in | `inlineData {mimeType, data(base64)}` or `fileData {fileUri}`; PNG/JPEG/WebP/HEIC/HEIF; inline request total <= 20 MB; up to 3,600 images | Probed 2x2 PNG → `promptTokensDetails IMAGE 1089` tokens on 3.8/3.5 Flash (Gemini 3 default media resolution is high; docs' "258 tokens" applies to older models / low res). Use `mediaResolution` to cut cost. |
182 +| PDF | `inlineData application/pdf` or Files API; <= 50 MB, <= 1000 pages, ~258 tokens/page | Not probed. |
183 +| Audio in | wav/mp3/aiff/aac/ogg/flac/m4a/opus/webm…; 32 tokens/s; <= 9.5 h/prompt; >20 MB via Files API | Not probed. |
184 +| Video in | inline <100 MB, Files API up to 2 GB (free) / 20 GB (paid), YouTube URLs via `fileData.fileUri`; ~100 tok/s low / 300 tok/s high res; 3.5+ have "agentic" video mode | Not probed. |
185 +| Audio out | **Not via chat models.** TTS models (`gemini-3.1-flash-tts-preview`, `gemini-2.5-*-preview-tts`) with `responseModalities:["AUDIO"]` + `speechConfig` → `inlineData audio/L16 24 kHz PCM`; 32k context; Live API (`bidiGenerateContent`, WebSocket) for realtime voice. | Not probed. |
186 +| Image out | Image models only (`gemini-3.1-flash-image`, `gemini-3.1-flash-lite-image`, `gemini-3-pro-image`, `gemini-2.5-flash-image`), `responseModalities:["TEXT","IMAGE"]`, `imageConfig {aspectRatio, imageSize "512px"/"1K"/"2K"/"4K"}` → `inlineData image/png`; SynthID watermark; priced per image (~$0.045–0.151). | Not probed. |
187 +| Video out | `gemini-omni-1.1-flash` / `gemini-omni-flash-preview` (paid tier only), Veo 3.1 via `predictLongRunning`. | Not chat models. |
188 +
189 +Docs: image-understanding, document-processing, audio, video-understanding, speech-generation, image-generation, files pages under https://ai.google.dev/gemini-api/docs/
190 +
191 +## 9. Files API
192 +`ai.files.upload({file, config:{mimeType}})` → `{uri, mimeType, state}`; poll until `ACTIVE`; reference with `fileData:{fileUri, mimeType}`. 48 h retention, 2 GB/file, 20 GB/project. Use when the request exceeds 20 MB (100 MB for video per newer docs). Not probed.
193 +
194 +## 10. System instruction
195 +`config.systemInstruction` (string or `Content`) — probed OK on 3.5/3.6/3.7/3.8 Flash ("BLUE" uppercase obeyed). Not probed on Gemma 4 (historically Gemma rejected developer instructions on this API; Gemma 4 docs say the system role is now supported — verify before enabling).
196 +
197 +## 11. Conversation state
198 +- `generateContent` is **stateless**: send the full `contents` history each turn (`ai.chats` is a client-side helper only).
199 +- Server-side state exists only in the **Interactions API** (`previous_interaction_id`, `store` default true; paid tier retains 55 days, free 1 day). Probed `ai.interactions.create({model, input, generation_config:{thinking_level:"low"}, store:false})` → works with this key; response has `steps[]`, `output_text`, `usage{total_input_tokens,total_output_tokens,total_thought_tokens,total_cached_tokens,total_tool_use_tokens}`. Consider it for a later "Gemini v2" adapter; it lacks Batch, explicit caching and custom safety settings today.
200 +
201 +## 12. Context caching
202 +- **Implicit** caching is on by default for 2.5+ (min 4,096 tokens on 3.x Flash / 3.1 Pro, 2,048 on 2.5); savings show as `usageMetadata.cachedContentTokenCount`; cached input billed at ~10 % (e.g. 3.8 Flash $0.075/M). Put static content first.
203 +- **Explicit**: `ai.caches.create({model, config:{contents, systemInstruction, tools, ttl:"300s"|expireTime, displayName}})` → pass `config.cachedContent = cache.name`. Models with `createCachedContent` in `supportedGenerationMethods` (all Gemini text models; not Gemma/omni). Storage $0.50–4.50 /M tokens/hour. Probe on 2.5-flash hit the 404 (model gone); not re-probed.
204 +
205 +Docs: https://ai.google.dev/gemini-api/docs/caching , https://ai.google.dev/api/caching
206 +
207 +## 13. Built-in tools
208 +- **Google Search grounding**: `tools:[{googleSearch:{}}]`. Response `candidates[0].groundingMetadata { webSearchQueries[], searchEntryPoint{renderedContent: HTML chip — must be displayed per ToS}, groundingChunks[{web:{uri,title}}], groundingSupports[{segment{startIndex,endIndex,text}, groundingChunkIndices[], confidenceScores[]}] }` (docs + SDK types; probe hit 429 on both attempts — **unverified**). Pricing: 3.x — 5,000 free requests/month shared, then $14/1,000; 2.5 — 1,500 free RPD then $35/1,000. Legacy `googleSearchRetrieval` only for 1.5.
209 +- **URL context**: `tools:[{urlContext:{}}]`, <= 20 URLs, 34 MB each, `candidates[0].urlContextMetadata`; billed as input tokens.
210 +- **Code execution**: `tools:[{codeExecution:{}}]` probed OK on 3.6 Flash → parts `executableCode{language:"PYTHON", code, id}` + `codeExecutionResult{outcome:"OUTCOME_OK", output, id}` (both also carry `thoughtSignature`), then text. 30 s runtime, matplotlib only for plots, billed as tokens.
211 +- **File Search** (RAG): stores + `tools:[{fileSearch:{fileSearchStoreNames:[…]}}]`, citations with `media_id`/page numbers; indexing $0.15/M embedding tokens, storage free. Not probed.
212 +- **Computer use**: `tools:[{computerUse:{environment:"browser"|"mobile"|"desktop"}}]` on 3.8/3.7/3.5 Flash(-Lite) (preview, documented for Interactions). Not probed.
213 +- **Google Maps grounding**, **MCP servers** tool: v1beta. Not probed.
214 +
215 +## 14. Safety settings
216 +`safetySettings:[{category, threshold}]`; categories `HARM_CATEGORY_HARASSMENT | HATE_SPEECH | SEXUALLY_EXPLICIT | DANGEROUS_CONTENT` (+ `CIVIC_INTEGRITY` in SDK enum); thresholds `OFF | BLOCK_NONE | BLOCK_ONLY_HIGH | BLOCK_MEDIUM_AND_ABOVE | BLOCK_LOW_AND_ABOVE`. Default for 2.5/3 models is **OFF**. Blocked prompt → `promptFeedback.blockReason` (`SAFETY|OTHER|BLOCKLIST|PROHIBITED_CONTENT|IMAGE_SAFETY`) with no candidates; blocked answer → `finishReason: SAFETY` + `safetyRatings`. Probe was routed to 2.5-flash-lite (404) — not re-probed. Not supported on the Interactions API.
217 +
218 +## 15. Rate limits and tiers
219 +- Tiers: Free, Tier 1 (billing linked), Tier 2 ($100 spent + 3 days), Tier 3 ($1,000 + 30 days). Dimensions: RPM, TPM (input), RPD (resets midnight Pacific) + rolling 10-minute spend caps ($10/$50/$200). Per-model tables are only shown in AI Studio (`https://aistudio.google.com/rate-limit`), not in docs.
220 +- Observed free-tier quotas (from 429 `google.rpc.QuotaFailure` details): `GenerateRequestsPerDayPerProjectPerModel-FreeTier` **quotaValue 20** for `gemini-3.8-flash`; per-minute quota trips after ~5–10 requests; `gemini-3.1-pro*`, `gemini-pro-latest`, `gemini-omni-*` → **limit 0** (paid only). Quotas are **per model**, so parallelising across models is fine.
221 +- 429 body includes `details[]`: `google.rpc.Help`, `google.rpc.QuotaFailure{violations[{quotaMetric, quotaId, quotaDimensions{model,location}, quotaValue}]}`, `google.rpc.RetryInfo{retryDelay:"24s"}` → honour `retryDelay`.
222 +- 503 `UNAVAILABLE` "This model is currently experiencing high demand…" was frequent on 3.8-flash and gemini-flash-latest (transient; retry with backoff). Gemma 4 returned 500 `INTERNAL` on ~50 % of calls (retry).
223 +
224 +Docs: https://ai.google.dev/gemini-api/docs/rate-limits
225 +
226 +## 16. Errors
227 +Body: `{"error":{"code":<http>,"message":"…","status":"<grpc status>","details":[…]}}`. Seen:
228 +
229 +| HTTP | status | Example |
230 +|---|---|---|
231 +| 400 | INVALID_ARGUMENT | temperature range, `Penalty is not enabled for this model`, `Multiple candidates is not enabled for this model`, `Logprobs is not enabled for this model`, `You can only set only one of thinking budget and thinking level.`, missing thought_signature, `Request contains an invalid argument.` |
232 +| 401 | UNAUTHENTICATED | invalid key: `Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential…`, `details[0].reason: "ACCESS_TOKEN_TYPE_UNSUPPORTED"`. (Docs list 400 `API_KEY_INVALID` for malformed keys — with `AQ.`-style bogus key we got 401.) |
233 +| 403 | PERMISSION_DENIED | key lacks permission / wrong project (docs) |
234 +| 404 | NOT_FOUND | unknown model: `models/gemini-9-ultra is not found for API version v1beta, or is not supported for generateContent. Call ModelService.ListModels…`; **retired-for-new-users**: `This model models/gemini-2.5-flash is no longer available to new users. Please update your code to use models/gemini-3.6-flash for the latest features and improvements. We recommend you to use the Interactions API.` |
235 +| 429 | RESOURCE_EXHAUSTED | quota (see §15) |
236 +| 500 | INTERNAL | `Internal error encountered.` (Gemma 4, transient) |
237 +| 503 | UNAVAILABLE | high demand |
238 +| 504 | DEADLINE_EXCEEDED | docs |
239 +
240 +Retry: exponential backoff with jitter on 429/500/503/504 (and network), honour `RetryInfo.retryDelay`; never retry 400/401/403/404. Streaming errors mid-stream: SDK throws from the iterator. Timeouts: set `httpOptions.timeout` (ms); long outputs with thinking can take >60 s — use 120 s+ for streaming.
241 +
242 +Docs: https://ai.google.dev/gemini-api/docs/troubleshooting , https://ai.google.dev/gemini-api/docs/api-errors (now describes Interactions snake_case codes)
243 +
244 +## 17. Token counting
245 +`ai.models.countTokens({model, contents})` → `{totalTokens}` (free, no quota cost documented). REST `:countTokens` with `generateContentRequest{contents, systemInstruction, tools}` counts everything (probed: 11 tokens text-only → 51 with system + tool) and returns `promptTokensDetails`. Rules of thumb: ~4 chars/token; image 258 tokens (<=384 px) or per 768 px tile — but Gemini 3 high res gave 1,089 for a tiny PNG; audio 32 tok/s; video ~100–300 tok/s.
246 +
247 +## 18. Model listing
248 +`GET /v1beta/models?pageSize=1000` (paginated via `nextPageToken`; SDK `ai.models.list()` / `ai.models.get({model})`). 54 models on 2026-09-08. Fields: `name`, `version`, `displayName`, `description`, `inputTokenLimit`, `outputTokenLimit`, `supportedGenerationMethods[]` (SDK renames to `supportedActions`), `temperature`, `maxTemperature`, `topP`, `topK`, `thinking` (boolean). Filter chat models with `supportedGenerationMethods.includes("generateContent")` and exclude by name pattern (`-image`, `-tts`, `lyria`, `veo`, `transcribe`, `live`, `native-audio`, `robotics`, `computer-use`, `deep-research`, `antigravity`, `embedding`, `aqa`). **The list includes models the key cannot call** (2.5 family → 404 for new users; paid-only → 429 limit 0), so the picker must tolerate per-model failures.
249 +
250 +## 19. Pricing (paid tier, USD per 1M tokens; pricing page 2026-09-08)
251 +| Model | Input | Cached | Output (incl. thinking) |
252 +|---|---|---|---|
253 +| 3.8 / 3.7 / 3.6 Flash | 0.75 (1.50 from 2027-01-01) | 0.075 (0.15) | 3.75 (7.50) |
254 +| 3.5 Flash | 1.50 | 0.15 | 9.00 |
255 +| 3.5 Flash-Lite | 0.30 | 0.03 | 2.50 |
256 +| 3.1 Flash-Lite | 0.25 (audio 0.50) | n/a | 1.50 |
257 +| 3 Flash Preview | 0.50 (audio 1.00) | n/a | 3.00 |
258 +| 3.1 Pro Preview | 2.00 / 4.00 (>200k) | 0.20 / 0.40 | 12.00 / 18.00 |
259 +| 2.5 Pro | 1.25 / 2.50 | 0.125 / 0.25 | 10.00 / 15.00 |
260 +| 2.5 Flash | 0.30 (audio 1.00) | 0.03 | 2.50 |
261 +| 2.5 Flash-Lite | 0.10 (audio 0.30) | 0.01 | 0.40 |
262 +| Omni Flash | 1.50 | n/a | 9.00 text / 17.50 video |
263 +| Gemma 4 | free (free tier only; "Not available" on paid) | | |
264 +Batch = 50 % off; priority tier = 1.8x; cache storage $0.50–4.50 /M/h; Search grounding see §13. Free tier: prompts may be used for product improvement.
265 +
266 +Docs: https://ai.google.dev/gemini-api/docs/pricing
267 +
268 +## 20. Lifecycle, aliases, deprecations
269 +- Stable ids don't change (`gemini-3.6-flash`); previews get >= 2 weeks' notice; `-latest` aliases are hot-swapped with a 2-week email notice: `gemini-flash-latest` → 3.5 Flash (changelog), `gemini-flash-lite-latest` → 3.5 Flash-Lite (probed), `gemini-pro-latest` → 3.1 Pro (quota dimension).
270 +- Shut down: all `gemini-2.0-*` (2026-06-01), `gemini-3.1-flash-lite-preview` (2026-05-25; the id still answers as 3.1-flash-lite), 2.5 previews. **Gemini 2.5 Pro/Flash/Flash-Lite are closed to new users** (404) though still listed and priced.
271 +- Preview shutdown windows are 3–9 months. Legacy JS SDK deprecated 2025-11-30. Standard API keys rejected after Sept 2026.
272 +
273 +Docs: https://ai.google.dev/gemini-api/docs/deprecations , https://ai.google.dev/gemini-api/docs/changelog , https://ai.google.dev/gemini-api/docs/models
274 +
275 +## 21. Probe results summary
276 +
277 +| Probe | 3.8-flash | 3.7-flash | 3.6-flash | 3.5-flash | 3.5-flash-lite | 3.1-flash-lite | 3-flash-preview | gemma-4-31b-it | 3.1-pro-preview | 2.5-flash / 2.5-pro | omni-1.1-flash |
278 +|---|---|---|---|---|---|---|---|---|---|---|---|
279 +| generateContent + systemInstruction | OK | OK | OK | OK | OK (no sysinstr) | OK (no sysinstr) | OK (no sysinstr) | OK (no sysinstr) | 429 limit 0 | 404 gone | 429 limit 0 |
280 +| stream (chunk shape, usage) | 503 then quota | OK 3 chunks, usage full each | OK 4 chunks | OK 3 chunks | — | — | — | — | — | 404 | — |
281 +| params matrix | partial (RPD 20) | — | — | most | full | full | most | full (flaky 500s) | — | 404 | — |
282 +| function call stream + round trip | 503/429 | OK (+signature tests) | OK | OK | OK | OK | — | — | — | 404 | — |
283 +| responseJsonSchema | — | — | OK | OK | OK | OK | OK | OK | — | 404 | — |
284 +| vision (inline PNG) | OK 1089 img tokens | — | — | OK | — | — | — | — | 429 | 404 | 429 |
285 +| googleSearch grounding | 429 | — | 429 | — | — | — | — | — | — | 404 | — |
286 +| codeExecution | 429 | — | OK | — | — | — | — | — | — | — | — |
287 +| invalid key | 401 UNAUTHENTICATED (REST + SDK) | | | | | | | | | | |
288 +| countTokens / models.get / v1 apiVersion / interactions.create | OK / OK / OK / OK | | | | | | | | | | |
289 +
290 +Not probed (docs only): audio/video/PDF input, Files API, explicit caching, safety settings behaviour, TTS/image output, Live API, File Search, computer use, MCP, Batch, 3.1 Pro & omni anything (paid tier), 2.5 anything (closed to new users).
291 +
292 +## 22. Gotchas for the adapter (checklist)
293 +1. Use `x-goog-api-key`, never Bearer. Expect 401 (not 400/403) for bad keys.
294 +2. Filter the model list by `generateContent` + name patterns, and **probe-or-handle 404 "no longer available to new users"** (2.5 family) and 429 "limit: 0" (paid-only) gracefully — hide or badge those models.
295 +3. Gemini 3.x: prefer `thinkingLevel` (uppercase enum in SDK), never send both level and budget, `MINIMAL` errors on 3.7/3.8, Gemma rejects both. Map PolyLLM "reasoning effort" → level; "off" → `MINIMAL` on lite/3.5-flash-lite, `thinkingBudget: 0` on 3.5 Flash / 3.1-lite / 3-flash-preview, and "not disableable" on 3.6+/Pro.
296 +4. `maxOutputTokens` includes thoughts — floor it (e.g. >= 2048) when thinking is on, or you get empty text with `MAX_TOKENS`.
297 +5. Store and replay `thoughtSignature` on tool-call parts (400 otherwise); `skip_thought_signature_validator` is the documented escape hatch. Strip empty signature-only text parts from the UI but keep them in history.
298 +6. Usage: read `usageMetadata` from the last chunk; thoughts = `thoughtsTokenCount`, cache hits = `cachedContentTokenCount`.
299 +7. Penalties, `candidateCount > 1`, logprobs → 400 on every model: don't expose them for Gemini. Temperature/topP/topK are accepted but deprecated for 3.6+; don't send by default.
300 +8. SSE events are CRLF-delimited `data:` lines with no terminator; HTTP error status can arrive with `text/event-stream` content type.
301 +9. Quotas are per model; free tier is tiny (20 RPD on 3.8-flash) — surface `RetryInfo.retryDelay` to the user.
302 +10. Consider a future switch to the Interactions API (server-side state, unified steps); today `generateContent` is stable and complete for chat.
added docs/provider-research/gemini.models.json +231 −0
@@ -0,0 +1,231 @@
1 +[
2 + {
3 + "id": "gemini-3.8-flash",
4 + "displayName": "Gemini 3.8 Flash",
5 + "family": "gemini-3.x-flash",
6 + "contextTokens": 1048576,
7 + "maxOutputTokens": 65536,
8 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
9 + "parameters": { "temperature": "0-2 (accepted; Google recommends leaving 1.0; deprecated for 3.6+ per changelog 2026-07-21)", "topP": true, "topK": true, "maxTokens": true, "reasoningEffort": ["low", "medium", "high"], "thinkingBudget": "docs: legacy, replace with thinkingLevel; not probed (free-tier RPD=20 exhausted)", "stop": true, "seed": true, "frequencyPenalty": false, "presencePenalty": false },
10 + "pricing": { "inputPerMillion": 0.75, "cachedInputPerMillion": 0.075, "outputPerMillion": 3.75, "note": "introductory through 2026-12-31; from 2027-01-01: 1.50 / 0.15 / 7.50. >200k-token prompts not tiered." },
11 + "status": "active",
12 + "notes": "Stable, released 2026-09-02. Probed: generateContent+systemInstruction OK, vision OK (2x2 PNG = 1089 image tokens), temperature 0/1.5/2 OK, candidateCount=2 -> 400, logprobs -> 400. Default thinkingLevel medium; 'minimal' returns an error (docs). Free tier: 20 requests/day (quotaValue=20 seen in 429). Thinking tokens count against maxOutputTokens (maxOutputTokens=100 gave empty text, finishReason MAX_TOKENS, 97 thought tokens)."
13 + },
14 + {
15 + "id": "gemini-3.7-flash",
16 + "displayName": "Gemini 3.7 Flash",
17 + "family": "gemini-3.x-flash",
18 + "contextTokens": 1048576,
19 + "maxOutputTokens": 65536,
20 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
21 + "parameters": { "temperature": "0-2 (deprecated, keep 1.0)", "topP": true, "topK": true, "maxTokens": true, "reasoningEffort": ["low", "medium", "high"], "thinkingBudget": "docs-only: legacy", "stop": "docs-only", "seed": "docs-only", "frequencyPenalty": false, "presencePenalty": false },
22 + "pricing": { "inputPerMillion": 0.75, "cachedInputPerMillion": 0.075, "outputPerMillion": 3.75, "note": "same as 3.8 Flash: introductory through 2026-12-31, then 1.50 / 0.15 / 7.50" },
23 + "status": "active",
24 + "notes": "Stable, Aug 2026. Probed: generateContent+systemInstruction OK; stream 3 chunks with full usageMetadata on every chunk; function call round trip OK; thought signature on functionCall part is MANDATORY (400 'Function call is missing a thought_signature in functionCall parts...' when omitted; dummy 'skip_thought_signature_validator' accepted); text-only multi-turn without signatures OK. Param matrix not probed (family assumed = 3.8)."
25 + },
26 + {
27 + "id": "gemini-3.6-flash",
28 + "displayName": "Gemini 3.6 Flash",
29 + "family": "gemini-3.x-flash",
30 + "contextTokens": 1048576,
31 + "maxOutputTokens": 65536,
32 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
33 + "parameters": { "temperature": "0-2 (deprecated per changelog 2026-07-21, keep 1.0)", "topP": "deprecated", "topK": "deprecated", "maxTokens": true, "reasoningEffort": ["minimal", "low", "medium", "high"], "thinkingBudget": "docs-only: legacy", "stop": "docs-only", "seed": "docs-only", "frequencyPenalty": false, "presencePenalty": false },
34 + "pricing": { "inputPerMillion": 0.75, "cachedInputPerMillion": 0.075, "outputPerMillion": 3.75, "note": "same as 3.8 Flash: introductory through 2026-12-31, then 1.50 / 0.15 / 7.50" },
35 + "status": "active",
36 + "status_note": "Google's recommended replacement for gemini-2.5-flash (404 message).",
37 + "notes": "Stable, July 2026. Probed: generateContent OK; stream 4 chunks (thought summary chunk first when includeThoughts, last chunk = empty text part carrying thoughtSignature + finishReason STOP); function call streaming (1 chunk with functionCall+thoughtSignature+id, then final empty chunk) and round trip OK; responseJsonSchema OK; codeExecution tool OK (executableCode{language:'PYTHON',code,id} + codeExecutionResult{outcome:'OUTCOME_OK',output,id}); googleSearch probe hit 429 (unverified). Param matrix not probed."
38 + },
39 + {
40 + "id": "gemini-3.5-flash",
41 + "displayName": "Gemini 3.5 Flash",
42 + "family": "gemini-3.x-flash",
43 + "contextTokens": 1048576,
44 + "maxOutputTokens": 65536,
45 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
46 + "parameters": { "temperature": "0-2 probed OK (2.5 -> 400)", "topP": true, "topK": true, "maxTokens": true, "reasoningEffort": "docs: minimal/low/medium/high (default medium); levels not probed (429)", "thinkingBudget": "0 probed OK (disables thinking); 1024/-1 not probed (429)", "stop": true, "seed": true, "frequencyPenalty": false, "presencePenalty": false },
47 + "pricing": { "inputPerMillion": 1.5, "cachedInputPerMillion": 0.15, "outputPerMillion": 9.0 },
48 + "status": "active",
49 + "notes": "GA May 2026; current target of gemini-flash-latest per changelog. Probed: systemInstruction OK, stream 3 chunks (first chunk usage has only promptTokenCount; later chunks full), includeThoughts -> parts with thought:true, function call streaming + round trip OK (functionCall has id 'call_...'), responseMimeType json / responseSchema / responseJsonSchema / text/x.enum OK, penalties -> 400 'Penalty is not enabled for this model', candidateCount=2 -> 400, vision OK. Free tier RPD low (~20)."
50 + },
51 + {
52 + "id": "gemini-3.5-flash-lite",
53 + "displayName": "Gemini 3.5 Flash-Lite",
54 + "family": "gemini-3.x-flash-lite",
55 + "contextTokens": 1048576,
56 + "maxOutputTokens": 65536,
57 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
58 + "parameters": { "temperature": "0-2 probed OK (deprecated per changelog 2026-07-21)", "topP": true, "topK": true, "maxTokens": true, "reasoningEffort": ["minimal", "low", "medium", "high"], "thinkingBudget": "1024 and -1 OK; 0 -> 400 'Request contains an invalid argument.' (use thinkingLevel MINIMAL to disable)", "stop": true, "seed": true, "frequencyPenalty": false, "presencePenalty": false },
59 + "pricing": { "inputPerMillion": 0.3, "cachedInputPerMillion": 0.03, "outputPerMillion": 2.5 },
60 + "status": "active",
61 + "notes": "Stable, July 2026; default thinking OFF (thoughtsTokenCount 0 unless thinkingLevel/thinkingBudget set). Full param matrix probed: all thinkingLevel values OK (minimal=0 thoughts), thinkingLevel+thinkingBudget together -> 400 'You can only set only one of thinking budget and thinking level.', penalties/candidateCount/logprobs -> 400. Function calling + responseJsonSchema OK. gemini-flash-lite-latest currently resolves here (modelVersion)."
62 + },
63 + {
64 + "id": "gemini-3.1-flash-lite",
65 + "displayName": "Gemini 3.1 Flash-Lite",
66 + "family": "gemini-3.x-flash-lite",
67 + "contextTokens": 1048576,
68 + "maxOutputTokens": 65536,
69 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
70 + "parameters": { "temperature": "0-2 probed OK", "topP": true, "topK": true, "maxTokens": true, "reasoningEffort": ["minimal", "low", "medium", "high"], "thinkingBudget": "0 / 1024 / -1 all OK", "stop": true, "seed": true, "frequencyPenalty": false, "presencePenalty": false },
71 + "pricing": { "inputPerMillion": 0.25, "cachedInputPerMillion": null, "outputPerMillion": 1.5, "note": "audio input 0.50/M; cached price not listed on pricing page" },
72 + "status": "active",
73 + "notes": "GA May 2026; default thinkingLevel minimal (thinking off). Full param matrix probed: same acceptance pattern as 3.5-flash-lite except thinkingBudget 0 is accepted. Function calling + responseJsonSchema OK. gemini-3.1-flash-lite-preview alias still answers and reports modelVersion gemini-3.1-flash-lite (changelog says preview shut down 2026-05-25)."
74 + },
75 + {
76 + "id": "gemini-3-flash-preview",
77 + "displayName": "Gemini 3 Flash Preview",
78 + "family": "gemini-3.x-flash",
79 + "contextTokens": 1048576,
80 + "maxOutputTokens": 65536,
81 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
82 + "parameters": { "temperature": "0-2 probed OK", "topP": true, "topK": true, "maxTokens": true, "reasoningEffort": ["minimal", "low", "medium", "high"], "thinkingBudget": "0 / 1024 / -1 all OK (-1 produced 1436 thought tokens)", "stop": true, "seed": true, "frequencyPenalty": false, "presencePenalty": false },
83 + "pricing": { "inputPerMillion": 0.5, "cachedInputPerMillion": null, "outputPerMillion": 3.0, "note": "audio input 1.00/M" },
84 + "status": "preview",
85 + "notes": "Dec 2025 preview; superseded by gemini-3.5-flash (stable). Default thinking high (dynamic). Param matrix probed except thinkingLevel low / logprobs (429). No shutdown date published."
86 + },
87 + {
88 + "id": "gemini-3.1-pro-preview",
89 + "displayName": "Gemini 3.1 Pro Preview",
90 + "family": "gemini-3.x-pro",
91 + "contextTokens": 1048576,
92 + "maxOutputTokens": 65536,
93 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
94 + "parameters": { "temperature": "0-2 (2.5 -> 400 probed; keep 1.0)", "topP": "docs-only", "topK": "docs-only", "maxTokens": true, "reasoningEffort": ["minimal", "low", "medium", "high"], "thinkingBudget": "docs-only: legacy", "stop": "docs-only", "seed": "docs-only", "frequencyPenalty": "docs-only (family pattern: rejected)", "presencePenalty": "docs-only (family pattern: rejected)" },
95 + "pricing": { "inputPerMillion": 2.0, "cachedInputPerMillion": 0.2, "outputPerMillion": 12.0, "note": ">200k prompt: 4.00 in / 0.40 cached / 18.00 out; storage 4.50/M/hr" },
96 + "status": "preview",
97 + "notes": "PAID TIER ONLY: free-tier quota is 0 (429 RESOURCE_EXHAUSTED 'limit: 0', quotaId GenerateRequestsPerDayPerProjectPerModel-FreeTier). Not probed beyond that. Default thinkingLevel high. gemini-pro-latest currently resolves here (also 429 limit 0 on free tier). Google's recommended replacement for gemini-2.5-pro."
98 + },
99 + {
100 + "id": "gemini-3.1-pro-preview-customtools",
101 + "displayName": "Gemini 3.1 Pro Preview (custom tools)",
102 + "family": "gemini-3.x-pro",
103 + "contextTokens": 1048576,
104 + "maxOutputTokens": 65536,
105 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
106 + "parameters": { "temperature": "0-2", "topP": "docs-only", "topK": "docs-only", "maxTokens": true, "reasoningEffort": ["low", "medium", "high"], "thinkingBudget": "docs-only", "stop": "docs-only", "seed": "docs-only", "frequencyPenalty": false, "presencePenalty": false },
107 + "pricing": { "inputPerMillion": 2.0, "cachedInputPerMillion": 0.2, "outputPerMillion": 12.0, "note": "assumed same as gemini-3.1-pro-preview (not separately listed)" },
108 + "status": "preview",
109 + "notes": "Variant that prioritises custom (function) tools over built-ins in agentic/bash workflows; 'may see quality fluctuations'. Paid tier only (429 limit 0 on free tier). Not probed."
110 + },
111 + {
112 + "id": "gemini-2.5-pro",
113 + "displayName": "Gemini 2.5 Pro",
114 + "family": "gemini-2.5",
115 + "contextTokens": 1048576,
116 + "maxOutputTokens": 65536,
117 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
118 + "parameters": { "temperature": "0-2 (2.5 -> 400 probed)", "topP": "docs-only", "topK": "docs-only", "maxTokens": true, "reasoningEffort": "docs: thinkingLevel low/medium/high accepted; OpenAI-compat maps minimal/low=1024, medium=8192, high=24576 budget", "thinkingBudget": "docs-only: 128-32768, cannot be disabled (-1 dynamic)", "stop": "docs-only", "seed": "docs-only", "frequencyPenalty": "docs-only", "presencePenalty": "docs-only" },
119 + "pricing": { "inputPerMillion": 1.25, "cachedInputPerMillion": 0.125, "outputPerMillion": 10.0, "note": ">200k prompt: 2.50 / 0.25 / 15.00; paid tier only" },
120 + "status": "deprecated",
121 + "notes": "LISTED by /v1beta/models but generateContent returns 404 NOT_FOUND: 'This model models/gemini-2.5-pro is no longer available to new users. Please update your code to use models/gemini-3.1-pro-preview ... We recommend you to use the Interactions API.' Only pre-existing users can call it. Knowledge cutoff Jan 2025. Treat as legacy/hidden in a BYOK app unless the user's key is grandfathered (detect via 404 message)."
122 + },
123 + {
124 + "id": "gemini-2.5-flash",
125 + "displayName": "Gemini 2.5 Flash",
126 + "family": "gemini-2.5",
127 + "contextTokens": 1048576,
128 + "maxOutputTokens": 65536,
129 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
130 + "parameters": { "temperature": "0-2 (2.5 -> 400 probed)", "topP": "docs-only", "topK": "docs-only", "maxTokens": true, "reasoningEffort": "docs: low/medium/high", "thinkingBudget": "docs-only: 0 (off) to 24576, -1 dynamic", "stop": "docs-only", "seed": "docs-only", "frequencyPenalty": "docs-only", "presencePenalty": "docs-only" },
131 + "pricing": { "inputPerMillion": 0.3, "cachedInputPerMillion": 0.03, "outputPerMillion": 2.5, "note": "audio input 1.00/M, cached audio 0.10/M" },
132 + "status": "deprecated",
133 + "notes": "LISTED by /v1beta/models but generateContent, streamGenerateContent, cachedContents.create all return 404 'no longer available to new users' -> use gemini-3.6-flash. Only grandfathered keys can use it. Knowledge cutoff Jan 2025."
134 + },
135 + {
136 + "id": "gemini-2.5-flash-lite",
137 + "displayName": "Gemini 2.5 Flash-Lite",
138 + "family": "gemini-2.5",
139 + "contextTokens": 1048576,
140 + "maxOutputTokens": 65536,
141 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
142 + "parameters": { "temperature": "0-2", "topP": "docs-only", "topK": "docs-only", "maxTokens": true, "reasoningEffort": "docs: low/medium/high (default off)", "thinkingBudget": "docs-only: 512-24576, 0 off", "stop": "docs-only", "seed": "docs-only", "frequencyPenalty": "docs-only", "presencePenalty": "docs-only" },
143 + "pricing": { "inputPerMillion": 0.1, "cachedInputPerMillion": 0.01, "outputPerMillion": 0.4, "note": "audio input 0.30/M" },
144 + "status": "deprecated",
145 + "notes": "LISTED but 404 'no longer available to new users' -> use gemini-3.5-flash-lite (probed via chats + safetySettings probes)."
146 + },
147 + {
148 + "id": "gemini-flash-latest",
149 + "displayName": "Gemini Flash (latest alias)",
150 + "family": "alias",
151 + "contextTokens": 1048576,
152 + "maxOutputTokens": 65536,
153 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
154 + "parameters": { "temperature": "0-2", "topP": true, "topK": true, "maxTokens": true, "reasoningEffort": ["minimal", "low", "medium", "high"], "thinkingBudget": "legacy", "stop": true, "seed": true, "frequencyPenalty": false, "presencePenalty": false },
155 + "pricing": { "inputPerMillion": 1.5, "cachedInputPerMillion": 0.15, "outputPerMillion": 9.0, "note": "billed as the model it resolves to (currently gemini-3.5-flash per changelog May 2026); not listed on pricing page" },
156 + "status": "active",
157 + "notes": "Hot-swapped alias; Google gives 2 weeks' email notice before re-pointing. Probe returned 503 'high demand' (transient) so resolution not confirmed live; changelog says gemini-3.5-flash. Avoid as default in a registry: pin explicit ids and show alias as convenience."
158 + },
159 + {
160 + "id": "gemini-flash-lite-latest",
161 + "displayName": "Gemini Flash-Lite (latest alias)",
162 + "family": "alias",
163 + "contextTokens": 1048576,
164 + "maxOutputTokens": 65536,
165 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
166 + "parameters": { "temperature": "0-2", "topP": true, "topK": true, "maxTokens": true, "reasoningEffort": ["minimal", "low", "medium", "high"], "thinkingBudget": "1024/-1 OK, 0 rejected (as 3.5-flash-lite)", "stop": true, "seed": true, "frequencyPenalty": false, "presencePenalty": false },
167 + "pricing": { "inputPerMillion": 0.3, "cachedInputPerMillion": 0.03, "outputPerMillion": 2.5, "note": "billed as gemini-3.5-flash-lite (probe modelVersion = gemini-3.5-flash-lite)" },
168 + "status": "active",
169 + "notes": "Probed: resolves to gemini-3.5-flash-lite (modelVersion). Used for the raw REST SSE probe (works)."
170 + },
171 + {
172 + "id": "gemini-pro-latest",
173 + "displayName": "Gemini Pro (latest alias)",
174 + "family": "alias",
175 + "contextTokens": 1048576,
176 + "maxOutputTokens": 65536,
177 + "capabilities": { "text": true, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": true, "structuredOutput": true, "streaming": true, "files": true, "webSearch": true },
178 + "parameters": { "temperature": "0-2", "topP": "docs-only", "topK": "docs-only", "maxTokens": true, "reasoningEffort": ["low", "medium", "high"], "thinkingBudget": "legacy", "stop": "docs-only", "seed": "docs-only", "frequencyPenalty": false, "presencePenalty": false },
179 + "pricing": { "inputPerMillion": 2.0, "cachedInputPerMillion": 0.2, "outputPerMillion": 12.0, "note": "billed as the resolved model (429 quota dimension showed model=gemini-3.1-pro -> resolves to 3.1 Pro preview)" },
180 + "status": "active",
181 + "notes": "Paid tier only (free-tier 429 limit 0, quota dimension model=gemini-3.1-pro)."
182 + },
183 + {
184 + "id": "gemma-4-31b-it",
185 + "displayName": "Gemma 4 31B (instruction-tuned)",
186 + "family": "gemma-4",
187 + "contextTokens": 262144,
188 + "maxOutputTokens": 32768,
189 + "capabilities": { "text": true, "vision": "docs: image/video/audio input supported by Gemma 4; not probed on the API", "audioInput": null, "audioOutput": false, "imageGeneration": false, "video": null, "reasoning": true, "tools": "docs: yes; not probed", "structuredOutput": true, "streaming": true, "files": null, "webSearch": false },
190 + "parameters": { "temperature": "0-2 accepted (2 probed OK; 0/1.5 hit transient 500s)", "topP": "probed: 500 INTERNAL x2 (transient?)", "topK": true, "maxTokens": true, "reasoningEffort": false, "thinkingBudget": false, "stop": "probed: 500 INTERNAL x2 (transient?)", "seed": true, "frequencyPenalty": false, "presencePenalty": false },
191 + "pricing": { "inputPerMillion": 0, "cachedInputPerMillion": null, "outputPerMillion": 0, "note": "Free tier: 'Free of charge' (data used for product improvement). Paid tier: 'Not available'." },
192 + "status": "active",
193 + "notes": "Open model served on Gemini API. Thinks by default (thoughtsTokenCount 47-430) but thinkingConfig is rejected: thinkingBudget -> 400 'Thinking budget is not supported for this model.'; thinkingLevel -> 400 'Thinking level is not supported for this model.' responseSchema / responseJsonSchema / text/x.enum OK. ~50% of probe requests returned 500 INTERNAL 'Internal error encountered.' (flaky; retry). systemInstruction not probed. No createCachedContent / batch support (supportedGenerationMethods = generateContent, countTokens)."
194 + },
195 + {
196 + "id": "gemma-4-26b-a4b-it",
197 + "displayName": "Gemma 4 26B A4B (MoE, instruction-tuned)",
198 + "family": "gemma-4",
199 + "contextTokens": 262144,
200 + "maxOutputTokens": 32768,
201 + "capabilities": { "text": true, "vision": null, "audioInput": null, "audioOutput": false, "imageGeneration": false, "video": null, "reasoning": true, "tools": null, "structuredOutput": null, "streaming": true, "files": null, "webSearch": false },
202 + "parameters": { "temperature": "0-2", "topP": null, "topK": null, "maxTokens": true, "reasoningEffort": false, "thinkingBudget": false, "stop": null, "seed": null, "frequencyPenalty": false, "presencePenalty": false },
203 + "pricing": { "inputPerMillion": 0, "cachedInputPerMillion": null, "outputPerMillion": 0, "note": "free tier only" },
204 + "status": "active",
205 + "notes": "Probed once: 'pong' OK with 58 thought tokens. Assume same behaviour as gemma-4-31b-it (unknowns = null)."
206 + },
207 + {
208 + "id": "gemini-omni-1.1-flash",
209 + "displayName": "Gemini Omni 1.1 Flash",
210 + "family": "gemini-omni",
211 + "contextTokens": 131072,
212 + "maxOutputTokens": 65536,
213 + "capabilities": { "text": "docs: text output priced (9.00/M) but model card says output = video only", "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": null, "structuredOutput": null, "streaming": null, "files": null, "webSearch": false },
214 + "parameters": { "temperature": "0-2 (2.5 -> 400 probed)", "topP": null, "topK": null, "maxTokens": true, "reasoningEffort": null, "thinkingBudget": null, "stop": null, "seed": null, "frequencyPenalty": null, "presencePenalty": null },
215 + "pricing": { "inputPerMillion": 1.5, "cachedInputPerMillion": null, "outputPerMillion": 9.0, "note": "video output 17.50/M (~0.10/s); paid tier only" },
216 + "status": "active",
217 + "notes": "Video-generation model (GA Aug 2026; 3-10 s clips, 360p-4K). Models endpoint says inputTokenLimit 131072 (model card says 1,048,576 — endpoint value preferred). PAID TIER ONLY: free tier 429 'limit: 0'. Not usable for chat; exclude from the chat model picker or gate behind paid-tier detection."
218 + },
219 + {
220 + "id": "gemini-omni-flash-preview",
221 + "displayName": "Gemini Omni Flash Preview",
222 + "family": "gemini-omni",
223 + "contextTokens": 131072,
224 + "maxOutputTokens": 65536,
225 + "capabilities": { "text": null, "vision": true, "audioInput": true, "audioOutput": false, "imageGeneration": false, "video": true, "reasoning": true, "tools": null, "structuredOutput": null, "streaming": null, "files": null, "webSearch": false },
226 + "parameters": { "temperature": "0-2", "topP": null, "topK": null, "maxTokens": true, "reasoningEffort": null, "thinkingBudget": null, "stop": null, "seed": null, "frequencyPenalty": null, "presencePenalty": null },
227 + "pricing": { "inputPerMillion": 1.5, "cachedInputPerMillion": null, "outputPerMillion": 9.0, "note": "video output 17.50/M; paid tier only" },
228 + "status": "preview",
229 + "notes": "Preview predecessor of gemini-omni-1.1-flash (June 2026). Free tier 429 'limit: 0'. Not a chat model."
230 + }
231 +]
added docs/provider-research/openai.md +390 −0
@@ -0,0 +1,390 @@
1 +# OpenAI provider audit for PolyLLM
2 +
3 +Last documentation audit: 2026-09-08
4 +SDK probed: `openai@7.10.0` (npm), Node 25.9.0, `tsx` 4.23.13. Probe scripts and raw results: `research/openai/` (`results/*.json`, no secrets).
5 +Model registry produced from this audit: `docs/provider-research/openai.models.json` (84 entries).
6 +
7 +> Docs moved: every `platform.openai.com/docs/...` URL now 301-redirects to `https://developers.openai.com/api/docs/...`. The API reference pages there render only partially through a headless fetch (the "create response" and "streaming events" pages surfaced only the cancel endpoint), so event names, enums and parameter lists below were cross-checked against the SDK type definitions (`node_modules/openai/resources/responses/responses.d.ts`, `shared.d.ts`) and against live probes. Where docs and probes disagree, the probe wins and the disagreement is called out.
8 +
9 +---
10 +
11 +## 1. Endpoint, auth, headers
12 +
13 +| Item | Value |
14 +|---|---|
15 +| Base URL | `https://api.openai.com/v1/` (docs also mention data-residency endpoints in the SDK 7.6 release notes; not needed for BYOK) |
16 +| Auth | `Authorization: Bearer <OPENAI_API_KEY>` |
17 +| Optional headers | `OpenAI-Organization: org_...`, `OpenAI-Project: proj_...` (billing scope), `X-Client-Request-Id` (ASCII, <= 512 chars), `OpenAI-Safety-Identifier` (Realtime only; for HTTP use the `safety_identifier` body param) |
18 +| Response headers seen | `x-request-id`, `openai-processing-ms`, `openai-version: 2020-10-01`, `openai-organization`, `openai-project`, `x-ratelimit-*` (see section 13) |
19 +| Header size limits | total < 64 KiB, single custom header value < 60 KiB |
20 +| `OpenAI-Beta` | Not required for Responses, Chat Completions, tools or structured outputs (none sent by SDK 7.x for these). |
21 +
22 +Source: https://developers.openai.com/api/docs/api-reference/introduction
23 +
24 +## 2. Which API: Responses vs Chat Completions
25 +
26 +- **Use the Responses API (`POST /v1/responses`) as the primary adapter.** Docs: "While Chat Completions remains supported, Responses is recommended for all new projects." Chat Completions is *not* labelled legacy/deprecated and has no shutdown date, but:
27 + - Pro models (`gpt-5.5-pro`, `gpt-5.4-pro`, `gpt-5.2-pro`, `gpt-5-pro`, `o3-pro`, `o1-pro`), `gpt-5.3-codex` and `gpt-5.6-cyber` are **Responses-only**.
28 + - Built-in tools (web_search, file_search, code_interpreter, MCP, image_generation, computer use) exist only in Responses (Chat Completions has only `web_search_options` on the `*-search-*` models).
29 + - Reasoning docs: "Reasoning models work better with the Responses API"; GPT-6 Astra page: "Requires Responses API for tool calling (Chat Completions available but limited)".
30 + - Reasoning summaries, encrypted reasoning, `previous_response_id`, `conversation`, background mode, `reasoning.context` are Responses-only.
31 +- Chat Completions still works (verified 2026-09-08 on gpt-4.1-mini, gpt-5.5, o4-mini): chunk shape `chat.completion.chunk` with `choices[0].delta`, `usage` only in the final chunk when `stream_options.include_usage: true`; usage fields `prompt_tokens`/`completion_tokens`/`prompt_tokens_details.cached_tokens`/`completion_tokens_details.reasoning_tokens`. `max_tokens` is rejected on new models (`gpt-6-astra`: `400 unsupported_parameter "'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead."`).
32 +- The Chat-Completions-only web search models (`gpt-5-search-api`, `gpt-4o-search-preview`, `gpt-4o-mini-search-preview`) return `400 model_not_found "The requested model 'gpt-5-search-api' is not supported with the Responses API."` on Responses. Do not expose them; use the `web_search` tool on a normal model.
33 +- Assistants API shut down 2026-08-26 (replaced by Responses + Conversations). `v1/prompts` (reusable prompts), Evals, Agent Builder shut down 2026-11-30.
34 +
35 +Sources: https://developers.openai.com/api/docs/api-reference/chat , https://developers.openai.com/api/docs/guides/migrate-to-responses , https://developers.openai.com/api/docs/deprecations
36 +
37 +### Chat Completions -> Responses mapping (for the adapter)
38 +
39 +| Chat Completions | Responses |
40 +|---|---|
41 +| `messages` | `input` (string, or array of items: messages `{role, content}` / `function_call` / `function_call_output` / `reasoning` ...) |
42 +| `system` message | `instructions` (top-level) or a `developer` (or `system`) role message; all three verified to work |
43 +| `max_tokens` / `max_completion_tokens` | `max_output_tokens` (min 16; includes reasoning tokens) |
44 +| `response_format` | `text.format` (`{type:"text"}` / `{type:"json_schema", name, schema, strict}` / `{type:"json_object"}`) |
45 +| `tools[].function.{name,parameters}` | flattened `tools[] = {type:"function", name, description, parameters, strict}` |
46 +| `tool_calls[]` in message | separate `function_call` output items (`call_id`, `name`, `arguments`) |
47 +| `role:"tool"` message | `{type:"function_call_output", call_id, output}` input item |
48 +| `reasoning_effort`, `verbosity` | `reasoning.effort`, `text.verbosity` |
49 +| `usage.prompt_tokens` / `completion_tokens` | `usage.input_tokens` / `output_tokens` (+ `input_tokens_details.cached_tokens`, `cache_write_tokens`, `output_tokens_details.reasoning_tokens`, `total_tokens`) |
50 +| `n`, `seed`, `stop`, `logprobs` (bool) | `n` removed; **`seed` and `stop` do not exist** (`400 unknown_parameter`); logprobs via `top_logprobs` + `include:["message.output_text.logprobs"]` |
51 +| `stream_options.include_usage` | not needed: `response.completed` carries the full `response.usage` |
52 +
53 +## 3. Request shape (Responses) - parameters that matter
54 +
55 +From SDK `ResponseCreateParams` (7.10.0) and probes:
56 +
57 +`model`, `input`, `instructions`, `max_output_tokens` (>= 16), `reasoning {effort, summary, mode, context}`, `text {format, verbosity}`, `tools`, `tool_choice` (`"auto"|"none"|"required"|{type:"function",name}|{type:"allowed_tools",...}`), `parallel_tool_calls`, `temperature`, `top_p`, `top_logprobs`, `include[]`, `store` (default **true**), `previous_response_id`, `conversation`, `stream`, `stream_options {include_obfuscation}`, `background`, `truncation` (`"auto"|"disabled"`, default disabled), `metadata`, `service_tier` (`auto|default|flex|priority|fast`), `prompt_cache_key`, `prompt_cache_retention` (`in_memory|24h`, pre-5.6), `prompt_cache_options {mode, ttl:"30m"}` (5.6+), `safety_identifier`, `user`, `context_management` (compaction), `moderation`, `prompt`.
58 +
59 +`include` values: `file_search_call.results`, `web_search_call.results`, `web_search_call.action.sources`, `message.input_image.image_url`, `computer_call_output.output.image_url`, `code_interpreter_call.outputs`, `reasoning.encrypted_content`, `message.output_text.logprobs`.
60 +
61 +Response object: `id` (`resp_...`), `object:"response"`, `status` (`completed|failed|in_progress|cancelled|queued|incomplete`), `incomplete_details.reason` (`max_output_tokens|max_messages|content_filter|steered`), `error`, `model` (resolved snapshot, e.g. `gpt-5.5-2026-04-23`), `output[]` items, `usage`, plus echoes of `reasoning`, `text`, `temperature`, `top_p`, `truncation`, `store`, `service_tier`, `previous_response_id`, `tools`. The SDK adds a convenience `output_text` getter **only on non-streaming `create()` results** (the `response` object inside a `response.completed` event does not have it - accumulate deltas or read `output[].content[].text`).
62 +
63 +## 4. Streaming protocol
64 +
65 +SSE; every event is JSON with `type` and a monotonically increasing `sequence_number` (verified: strictly +1 per event). Text deltas also carry an `obfuscation` padding string (disable via `stream_options.include_obfuscation:false`).
66 +
67 +Event names observed in probes (exact strings):
68 +
69 +```
70 +response.created > response.in_progress
71 + > response.output_item.added {item:{type:"reasoning"...}} (reasoning models, effort >= low)
72 + > response.reasoning_summary_part.added
73 + > response.reasoning_summary_text.delta {delta} (x N) (only when reasoning.summary is set AND the model emits one)
74 + > response.reasoning_summary_text.done {text}
75 + > response.reasoning_summary_part.done
76 + > response.output_item.done
77 + > response.output_item.added {item:{type:"message", role:"assistant"}}
78 + > response.content_part.added {part:{type:"output_text", text:"", annotations:[]}}
79 + > response.output_text.delta {delta, item_id, output_index, content_index, logprobs, obfuscation} (x N)
80 + > response.output_text.annotation.added {annotation:{type:"url_citation",...}, annotation_index} (web search)
81 + > response.output_text.done {text}
82 + > response.content_part.done
83 + > response.output_item.done
84 +> response.completed {response:{...usage}} | response.incomplete | response.failed | error
85 +```
86 +
87 +Function calls (verified on all six models):
88 +
89 +```
90 +response.output_item.added {item:{type:"function_call", id:"fc_...", call_id:"call_...", name, arguments:"", status:"in_progress"}, output_index}
91 +response.function_call_arguments.delta {delta, item_id, output_index}
92 +response.function_call_arguments.done {arguments:"{...}", item_id}
93 +response.output_item.done {item:{type:"function_call", ..., arguments:"{...}", status:"completed"}}
94 +response.completed
95 +```
96 +
97 +Web search: `response.web_search_call.in_progress` > `.searching` > `.completed` (item type `web_search_call`).
98 +
99 +Full list of event types in the SDK (for exhaustive switch statements): `response.created, response.in_progress, response.queued, response.completed, response.incomplete, response.failed, error, response.output_item.added/done, response.content_part.added/done, response.output_text.delta/done, response.output_text.annotation.added, response.refusal.delta/done, response.reasoning_text.delta/done, response.reasoning_summary_part.added/done, response.reasoning_summary_text.delta/done, response.function_call_arguments.delta/done, response.custom_tool_call_input.delta/done, response.web_search_call.in_progress/searching/completed, response.file_search_call.in_progress/searching/completed, response.code_interpreter_call.in_progress/interpreting/completed, response.code_interpreter_call_code.delta/done, response.image_generation_call.in_progress/generating/partial_image/completed, response.mcp_call.in_progress/completed/failed, response.mcp_call_arguments.delta/done, response.mcp_list_tools.in_progress/completed/failed, response.shell_call_command.added/delta/done, response.shell_call_output_content.delta/done, response.audio.delta/done, response.audio.transcript.delta/done, response.steer.*`.
100 +
101 +Resumable streams: with `background:true, stream:true`, reconnect with `GET /v1/responses/{id}?stream=true&starting_after={sequence_number}`.
102 +
103 +Sources: https://developers.openai.com/api/docs/guides/streaming-responses , https://developers.openai.com/api/docs/guides/background , SDK types.
104 +
105 +### Exact SDK streaming code that worked (research/openai/03-stream.ts, 05-tools-stream.ts)
106 +
107 +```ts
108 +import OpenAI from "openai";
109 +const client = new OpenAI({ maxRetries: 1, timeout: 180_000 }); // key from OPENAI_API_KEY
110 +
111 +const stream = await client.responses.create({
112 + model: "gpt-5.5",
113 + input: [{ role: "user", content: "Say hello in five words." }],
114 + reasoning: { effort: "low", summary: "auto" },
115 + max_output_tokens: 200,
116 + stream: true,
117 +});
118 +let text = "", final: OpenAI.Responses.Response | null = null;
119 +for await (const ev of stream) {
120 + switch (ev.type) {
121 + case "response.output_text.delta": text += ev.delta; break;
122 + case "response.reasoning_summary_text.delta": /* show thinking */ break;
123 + case "response.function_call_arguments.delta": /* accumulate by ev.item_id */ break;
124 + case "response.output_item.done": if (ev.item.type === "function_call") { /* ev.item.call_id, name, arguments */ } break;
125 + case "response.completed": case "response.incomplete": final = ev.response; break; // final.usage, final.output
126 + case "error": throw new Error(ev.message);
127 + }
128 +}
129 +```
130 +
131 +Tool round trip (stateless): replay `[...previousInput, ...final.output, { type: "function_call_output", call_id, output: JSON.stringify(result) }]`. Replaying the *entire* `output` array (including `reasoning` items) is what the docs require for reasoning models; verified on gpt-5.5, gpt-5.4-mini, gpt-5.6-sol, gpt-6-astra, gpt-4.1-mini. Stateful alternative verified on gpt-5.4-mini: `previous_response_id: final.id, input: [function_call_output]`.
132 +
133 +## 5. Tool calling format
134 +
135 +- Definition: `{ type: "function", name, description, parameters: <JSON Schema>, strict: true }` (flattened; `strict` recommended; strict requires `additionalProperties:false` and all properties in `required`).
136 +- Output item: `{ id: "fc_...", type: "function_call", status: "completed", call_id: "call_...", name, arguments: "<json string>" }` (verified shape). `call_id` is what you echo back; `id` is the item id.
137 +- Result item: `{ type: "function_call_output", call_id, output: string | [content parts for images/files] }` (SDK 7.7 made the `id` optional).
138 +- `tool_choice`: `"auto"` (default) | `"none"` | `"required"` | `{type:"function", name}` | `{type:"allowed_tools", mode:"auto"|"required", tools:[...]}`.
139 +- `parallel_tool_calls` default true.
140 +- Other tool types accepted in `tools[]`: `web_search` (and legacy `web_search_preview`), `file_search`, `code_interpreter`, `image_generation`, `mcp`, `computer` / `computer_use_preview`, `shell`, `local_shell`, `apply_patch`, `custom` (free-form text tool), `namespace` (grouping, `defer_loading`), `tool_search`, `programmatic_tool_calling`.
141 +
142 +Sources: https://developers.openai.com/api/docs/guides/function-calling , https://developers.openai.com/api/docs/guides/tools
143 +
144 +## 6. Structured output / JSON schema
145 +
146 +- `text: { format: { type: "json_schema", name, schema, strict: true } }` - verified on gpt-5.5, gpt-5.4-mini, gpt-5.6-sol, gpt-6-astra, gpt-4.1-mini (parsed `{name:"Marie Curie",age:66,city:"Paris"}`); o4-mini accepted it but ran out of the 200-token budget on reasoning.
147 +- Schema subset: root must be `object`; every property in `required`; `additionalProperties:false`; optional fields via `type:["string","null"]`; supports `enum`, `anyOf`, `$ref`/`$defs`, recursion; no `minLength`/`pattern`/`format` etc. Numeric limits (depth/property count/enum size) exist but the page did not expose them - keep schemas modest.
148 +- Refusals arrive as a `refusal` content part (`response.refusal.delta/done`) instead of JSON.
149 +- `{type:"json_object"}` (JSON mode) is the fallback for gpt-4 / gpt-3.5-turbo which lack structured outputs.
150 +- SDK helpers: `zodTextFormat(schema, "name")` + `client.responses.parse(...)` -> `response.output_parsed`.
151 +
152 +Source: https://developers.openai.com/api/docs/guides/structured-outputs
153 +
154 +## 7. Reasoning controls
155 +
156 +- `reasoning.effort` values in the SDK enum: `none | minimal | low | medium | high | xhigh | max`. **Per-model acceptance (verified, exact error strings in section 20):**
157 + - gpt-6-astra: `low, medium, high, xhigh, max` (default `medium`; `none`/`minimal` -> 400)
158 + - gpt-5.6-sol/terra/luna: `none, low, medium, high, xhigh, max` (default `medium`)
159 + - gpt-5.5: `none, low, medium, high, xhigh` (default `medium`)
160 + - gpt-5.4 / 5.4-mini / 5.4-nano, gpt-5.2: `none, low, medium, high, xhigh` (default **`none`** - verified echo)
161 + - gpt-5.1: `none, low, medium, high` (default `none`)
162 + - gpt-5 / 5-mini / 5-nano: `minimal, low, medium, high` (default `medium`; no `none`)
163 + - o3, o4-mini, o3-mini, o1: `low, medium, high` (default `medium`)
164 + - pro models: 5.5-pro `medium|high|xhigh` (default high), 5.4-pro / 5.2-pro `medium|high|xhigh`, gpt-5-pro `high` only
165 + - gpt-4.1 / gpt-4o / chat-latest: `reasoning.effort` -> `400 unsupported_parameter`
166 +- `reasoning.summary`: `auto | concise | detailed` (server echoes `detailed` for `auto`). Summary text arrives in `reasoning` items' `summary[]` and via `response.reasoning_summary_*` events; gpt-5.5 and gpt-6-astra returned no summary on a trivial prompt while gpt-5.6-sol and o4-mini did. Never assume a summary will exist. Non-reasoning models silently ignore `summary`.
167 +- `reasoning.mode`: `standard | pro` (GPT-5.6; pro replaces the `*-pro` models). Not probed (cost).
168 +- `reasoning.context`: `current_turn | all_turns` (`all_turns` is the default on 5.6 and 6; earlier models default `current_turn`). Reasoning persists only within a family.
169 +- Reasoning tokens are billed as output and count against `max_output_tokens`; `usage.output_tokens_details.reasoning_tokens` reports them. Docs recommend reserving >= 25k tokens; with tiny caps, o4-mini / gpt-5-nano return `status:"incomplete", incomplete_details.reason:"max_output_tokens"` with an empty message (verified). **Adapter rule: never cap reasoning models below ~1-2k output tokens; treat `incomplete` + empty text as "reasoning exhausted the budget".**
170 +- Encrypted reasoning for stateless (store:false) multi-turn: `store:false, include:["reasoning.encrypted_content"]` -> `reasoning` items carry `encrypted_content` (~1.2 kB for a trivial turn); replaying them in the next `input` works (verified on gpt-5.5). `previous_response_id` on a `store:false` response fails: `400 previous_response_not_found`.
171 +- GPT-6 Astra: mid-conversation `configuration_update` items to change effort; async tool calling (`async:true`); no `none` effort.
172 +
173 +Sources: https://developers.openai.com/api/docs/guides/reasoning , https://developers.openai.com/api/docs/guides/latest-model
174 +
175 +## 8. Sampling parameter support matrix (Responses API, verified 2026-09-08)
176 +
177 +| Param | gpt-6-astra | gpt-5.6-sol | gpt-5.5 | gpt-5.4-mini (default effort none) | gpt-4.1-mini | o4-mini |
178 +|---|---|---|---|---|---|---|
179 +| `temperature` | rejected | rejected unless `effort:"none"` (then accepted) | rejected unless `effort:"none"` | accepted | accepted | rejected |
180 +| `top_p` | rejected | same as temperature | same | accepted | accepted | rejected |
181 +| `frequency_penalty` | rejected | rejected (effort medium) | rejected | accepted | accepted | rejected |
182 +| `presence_penalty` | rejected | rejected | rejected | accepted | accepted | rejected |
183 +| `seed` | `unknown_parameter` on every model (does not exist in Responses) | | | | | |
184 +| `stop` | `unknown_parameter` on every model ("Did you mean 'store'?") | | | | | |
185 +| logprobs (`top_logprobs`+include) | rejected (reasoning) | rejected | rejected | accepted (`logprobs[]` on content part) | accepted | rejected |
186 +| `reasoning.effort` | low..max | none..max | none..xhigh | none..xhigh | rejected | low..high |
187 +| `reasoning.summary` | accepted | accepted | accepted | accepted | ignored (no error) | accepted |
188 +| `text.verbosity: "low"` | accepted | accepted | accepted | accepted | rejected (`Supported values are: 'medium'`) | rejected |
189 +| `max_output_tokens` | min 16 on all (`integer_below_min_value`) | | | | | |
190 +| `truncation:"auto"` | accepted on all | | | | | |
191 +| `store:false` + `include:["reasoning.encrypted_content"]` | accepted on all (non-reasoning models just have no reasoning item) | | | | | |
192 +| `prompt_cache_key` | accepted on all | | | | | |
193 +
194 +Default `top_p` echoed by GPT-5.x/6 is `0.98`, by GPT-4.1 `1`. `temperature` default 1. `top_k` does not exist. There is no thinking *budget* parameter (effort only). Chat Completions on gpt-5.5: `temperature:0.3` -> `400 unsupported_value "'temperature' does not support 0.3 with this model. Only the default (1) value is supported."`
195 +
196 +Practical rule for the adapter: send sampling params only when (model is non-reasoning) or (reasoning-capable model with `reasoning.effort === "none"`); otherwise drop them client-side and show "not supported" in the UI. Never send `seed`/`stop` to Responses.
197 +
198 +## 9. Roles and instructions
199 +
200 +Input roles accepted: `user`, `assistant`, `developer`, `system` (both `system` and `developer` verified on gpt-5.5 and gpt-4.1-mini; docs describe `developer` as the canonical name and treat `instructions` as equivalent to a developer message). `instructions` is not inherited through `previous_response_id`; resend it each call. Content parts: `input_text`, `input_image`, `input_file`, (`input_audio` rejected, see 10); assistant output parts: `output_text`, `refusal`.
201 +
202 +Source: https://developers.openai.com/api/docs/guides/text
203 +
204 +## 10. Modalities
205 +
206 +| Modality | Responses API support | Notes |
207 +|---|---|---|
208 +| Text in/out | yes | |
209 +| Image in | yes on every current model except `o3-mini`, `gpt-4`, `gpt-3.5-turbo` | `{type:"input_image", image_url:"data:image/png;base64,..." \| https URL \| file_id, detail:"low"\|"high"\|"auto"\|"original"}`. PNG/JPEG/WEBP/non-animated GIF; <= 512 MB per request, <= 1,500 images, <= 30,000 patches after resize. Tokens ~ `ceil(w/32)*ceil(h/32)` x model multiplier (1.2-2.46). Verified with a 2x2 PNG on all six probe models (31-33 input tokens). |
210 +| PDF / file in | yes (vision models) | `{type:"input_file", filename, file_data:"data:application/pdf;base64,..." \| file_id \| file_url}`; <= 50 MB per file and per request; both text and page images are sent (costly). Verified on gpt-5.4-mini (answered `42` from the PDF). |
211 +| Image out | via tool only | `tools:[{type:"image_generation"}]` uses `gpt-image-2`; returns base64 in an `image_generation_call` item; events `response.image_generation_call.partial_image`. Not probed. Older gpt-image-1* shut down 2026-10-23 / 2026-12-01. |
212 +| Audio in/out | **no** in Responses | probe: `400 invalid_request_error param=input "Audio input is not available."`. Audio chat = Chat Completions with `gpt-audio-1.5` (`input_audio` parts, `modalities:["text","audio"]`) or Realtime (`gpt-realtime-2.1`). TTS: `gpt-4o-mini-tts`; STT: `gpt-transcribe`, `gpt-live-transcribe` (whisper-1/gpt-4o-transcribe shut down 2027-02-26). |
213 +| Video | no | Sora 2 / Videos API shut down 2026-09-24. |
214 +
215 +Sources: https://developers.openai.com/api/docs/guides/images-vision , https://developers.openai.com/api/docs/guides/pdf-files , https://developers.openai.com/api/docs/guides/audio
216 +
217 +## 11. Context windows, max output, pricing (per 1M tokens, USD, standard tier)
218 +
219 +| Model | Context | Max output | Input | Cached | Output | Notes |
220 +|---|---|---|---|---|---|---|
221 +| gpt-6-astra | 1,050,000 | 128,000 | 10 | 1 | 50 | cache write 12.50; >272K input: 2x in / 1.5x out |
222 +| gpt-5.6-sol (`gpt-5.6`) | 1,050,000 | 128,000 | 4 | 0.40 | 20 | |
223 +| gpt-5.6-terra | 1,050,000 (922K input) | 128,000 | 2 | 0.20 | 12 | |
224 +| gpt-5.6-luna | 1,050,000 | 128,000 | 0.20 | 0.02 | 1.20 | |
225 +| gpt-5.5 | 1,050,000 | 128,000 | 5 | 0.50 | 30 | >272K: 2x/1.5x |
226 +| gpt-5.5-pro | 1,050,000 | 128,000 | 30 | - | 180 | Responses only |
227 +| gpt-5.4 | 1,050,000 | 128,000 | 2.50 | 0.25 | 15 | |
228 +| gpt-5.4-mini | 400,000 | 128,000 | 0.75 | 0.075 | 4.50 | |
229 +| gpt-5.4-nano | 400,000 | 128,000 | 0.20 | 0.02 | 1.25 | |
230 +| gpt-5.4-pro | 1,050,000 | 128,000 | 30 | - | 180 | Responses only |
231 +| gpt-5.3-codex | 400,000 | 128,000 | 1.75 | 0.175 | 14 | Responses only, coding |
232 +| gpt-5.2 | 400,000 | 128,000 | 1.75 | 0.175 | 14 | |
233 +| gpt-5.2-pro | 400,000 | 128,000 | 21 | - | 168 | Responses only |
234 +| gpt-5.1 | 400,000 | 128,000 | 1.25 | 0.125 | 10 | |
235 +| gpt-5 | 400,000 | 128,000 | 1.25 | 0.125 | 10 | snapshot shuts down 2026-12-11 |
236 +| gpt-5-mini | 400,000 | 128,000 | 0.25 | 0.025 | 2 | snapshot shuts down 2026-12-11 |
237 +| gpt-5-nano | 400,000 | 128,000 | 0.05 | 0.005 | 0.40 | snapshot shuts down 2026-12-11 |
238 +| gpt-5-pro | 400,000 | 272,000 | 15 | - | 120 | Responses only |
239 +| chat-latest | 400,000 (272K input) | 128,000 | 5 | 0.50 | 30 | ChatGPT Instant, non-reasoning |
240 +| gpt-4.1 | 1,047,576 | 32,768 | 2 | 0.50 | 8 | |
241 +| gpt-4.1-mini | 1,047,576 | 32,768 | 0.40 | 0.10 | 1.60 | |
242 +| gpt-4.1-nano | 1,047,576 | 32,768 | 0.10 | 0.025 | 0.40 | shuts down 2026-10-23 |
243 +| gpt-4o | 128,000 | 16,384 | 2.50 | 1.25 | 10 | alias -> 2024-08-06 |
244 +| gpt-4o-mini | 128,000 | 16,384 | 0.15 | 0.075 | 0.60 | |
245 +| o3 | 200,000 | 100,000 | 2 | 0.50 | 8 | snapshot shuts down 2026-12-11 |
246 +| o3-pro | 200,000 | 100,000 | 20 | - | 80 | Responses only |
247 +| o4-mini | 200,000 | 100,000 | 1.10 | 0.275 | 4.40 | shuts down 2026-10-23 |
248 +| o3-mini | 200,000 | 100,000 | 1.10 | 0.55 | 4.40 | text only; shuts down 2026-10-23 |
249 +| o1 | 200,000 | 100,000 | 15 | 7.50 | 60 | shuts down 2026-10-23 |
250 +| o1-pro | 200,000 | 100,000 | 150 | - | 600 | shuts down 2026-10-23 |
251 +| gpt-4-turbo | 128,000 | 4,096 | 10 | - | 30 | shuts down 2026-10-23 |
252 +| gpt-4 | 8,192 | 8,192 | 30 | - | 60 | shuts down 2026-10-23 |
253 +| gpt-3.5-turbo | 16,385 | 4,096 | 0.50 | - | 1.50 | shuts down 2026-10-23 |
254 +
255 +Tiers: Batch and Flex = ~50% of standard; Priority higher; Fast = 2x (not for gpt-6-astra with EU residency). Regional data residency +10% for models released after 2026-03-05. Tools: web search $10 / 1k calls (+ tokens), file search $2.50 / 1k calls + $0.10/GB/day storage (1 GB free), code interpreter $0.03-$1.92 per 20-min session by memory tier, MCP = tokens only. Unknown for this key: `gpt-5-search-api`, `gpt-4o-mini-search-preview`, the dead codex snapshots (set to `null` in the JSON).
256 +
257 +Sources: per-model pages under https://developers.openai.com/api/docs/models/<id> , https://developers.openai.com/api/docs/pricing
258 +
259 +## 12. Prompt caching
260 +
261 +Automatic prefix caching; minimum cacheable prefix 1,024 tokens (GPT-5.6+) / 2,048 (earlier). Reads at the "cached" price (0.1x on 5.6+, 0.5x on gpt-4o/o3-mini/o1); GPT-5.6+ also bill **cache writes at 1.25x** (reported in `usage.input_tokens_details.cache_write_tokens`, present in every usage object we saw). `prompt_cache_key` (routing hint, accepted on every model) ; `prompt_cache_retention: "in_memory" | "24h"` for pre-5.6 models (accepted on gpt-5.5 and even gpt-6-astra, but docs say it is deprecated for 6 -> use `prompt_cache_options: { ttl: "30m" }`, verified accepted on gpt-5.6-sol, echoed `{mode:"implicit", ttl:"30m"}`). `cached_tokens` is exact on 5.6+, rounded to 128 earlier. Cache lifetime 5-10 min (up to 1 h) or 24 h; not shared across orgs.
262 +
263 +Source: https://developers.openai.com/api/docs/guides/prompt-caching
264 +
265 +## 13. Rate limits, headers, retries, timeouts
266 +
267 +- Dimensions: RPM, TPM, RPD, TPD, IPM (+ audio minutes). Tiers Free..Tier 5 by cumulative spend; this key is Tier 5 (headers show 15,000 RPM / 40M TPM on gpt-5.5, 30,000 RPM / 150M TPM on gpt-4.1-mini).
268 +- Headers (verified on every 200): `x-ratelimit-limit-requests`, `x-ratelimit-remaining-requests`, `x-ratelimit-reset-requests` (e.g. `4ms`, `6m0s`), `x-ratelimit-limit-tokens`, `x-ratelimit-remaining-tokens`, `x-ratelimit-reset-tokens`; docs also list `x-ratelimit-limit-project-tokens` / `x-ratelimit-remaining-project-tokens` and `Retry-After` (seconds) on 429/503. Also `x-request-id` and `openai-processing-ms`.
269 +- 429 codes: `rate_limit_exceeded`, `slow_down` (traffic ramped too fast), `insufficient_quota` / `credit_balance_exhausted`, `organization_spend_limit_exceeded`, `project_spend_limit_exceeded`, `organization_usage_limit_exceeded`. 503 `server_is_overloaded`. Billing/quota 429s must **not** be retried.
270 +- Retry guidance: honour `Retry-After` when present, else exponential backoff with jitter; ramp traffic <= +50% per 15 min above 1M TPM. SDK default: `maxRetries: 2`, retries 408/409/429/>=500 and any response with `x-should-retry: true`, honours `retry-after-ms` / `retry-after`, backoff 0.5 s x 2^n capped at 8 s with up to 25% jitter. For a BYOK chat UI use `maxRetries: 1-2` for non-streaming, and do not retry once streaming has begun.
271 +- Timeouts: SDK default 10 minutes (`OpenAI.DEFAULT_TIMEOUT = 600000`). Recommend: 60 s connect/first-byte for chat, overall 5-10 min for high/xhigh/max effort, and `background: true` (+ polling / resumable stream) for pro models and anything expected to run > 1-2 min. Docs: streaming is "the single most effective approach" to perceived latency; `service_tier: "priority" | "fast"` buys lower latency at higher price (`flex` accepted on gpt-5.4-mini: slower, cheaper).
272 +
273 +Sources: https://developers.openai.com/api/docs/guides/rate-limits , https://developers.openai.com/api/docs/guides/error-codes , https://developers.openai.com/api/docs/guides/latency-optimization , SDK `client.js`
274 +
275 +## 14. Error schema
276 +
277 +HTTP body: `{ "error": { "message", "type", "param", "code" } }` (raw fetch with a bad key also returned a top-level `"status": 401`). SDK maps to `BadRequestError` (400), `AuthenticationError` (401), `PermissionDeniedError` (403), `NotFoundError` (404), `RateLimitError` (429), `InternalServerError` (>=500), `APIConnectionError`, `APITimeoutError`; each exposes `.status`, `.code`, `.type`, `.param`, `.requestID`, `.headers`, `.error` (raw body).
278 +
279 +Verified examples:
280 +
281 +| Case | Status | `type` | `code` | `param` | `message` |
282 +|---|---|---|---|---|---|
283 +| invalid key | 401 | invalid_request_error | `invalid_api_key` | null | `Incorrect API key provided: sk-inva*****key. You can find your API key at https://platform.openai.com/account/api-keys.` |
284 +| unknown model | 404 | invalid_request_error | `model_not_found` | null | ``The model `gpt-does-not-exist` does not exist or you do not have access to it.`` |
285 +| CC-only model on Responses | 400 | invalid_request_error | `model_not_found` | model | `The requested model 'gpt-5-search-api' is not supported with the Responses API.` |
286 +| wrong type | 400 | invalid_request_error | `invalid_type` | max_output_tokens | `Invalid type for 'max_output_tokens': expected an integer, but got a string instead.` |
287 +| below min | 400 | invalid_request_error | `integer_below_min_value` | max_output_tokens | `Invalid 'max_output_tokens': integer below minimum value. Expected a value >= 16, but got 5 instead.` |
288 +| unsupported param | 400 | invalid_request_error | **null** | temperature | `Unsupported parameter: 'temperature' is not supported with this model.` |
289 +| unsupported param | 400 | invalid_request_error | `unsupported_parameter` | reasoning.effort | `Unsupported parameter: 'reasoning.effort' is not supported with this model.` |
290 +| unsupported value | 400 | invalid_request_error | `unsupported_value` | reasoning.effort | `Unsupported value: 'minimal' is not supported with the 'gpt-5.5' model. Supported values are: 'none', 'low', 'medium', 'high', and 'xhigh'.` |
291 +| unknown param | 400 | invalid_request_error | `unknown_parameter` | stop | `Unknown parameter: 'stop'. Did you mean 'store'?` |
292 +| logprobs on reasoning | 400 | invalid_request_error | `unsupported_parameter` | - | `logprobs are not supported with reasoning models.` |
293 +| prev response gone | 400 | invalid_request_error | `previous_response_not_found` | previous_response_id | `Previous response with id 'resp_...' not found.` |
294 +| audio in Responses | 400 | invalid_request_error | null | input | `Audio input is not available.` |
295 +
296 +Note `code` is sometimes null for "Unsupported parameter" errors; match on `param` + message prefix as well. Other documented codes: `context_length_exceeded`, `invalid_service_tier`, `insufficient_quota`, `rate_limit_exceeded`, `slow_down`, `server_is_overloaded`.
297 +
298 +## 15. Usage reporting and token counting
299 +
300 +- Every response (and `response.completed`) has `usage: { input_tokens, input_tokens_details: { cached_tokens, cache_write_tokens }, output_tokens, output_tokens_details: { reasoning_tokens }, total_tokens }`. Web search inflates `input_tokens` heavily (4.7k-8.8k for a one-line question) because search results are injected as context and billed as input.
301 +- Chat Completions usage: `prompt_tokens`, `completion_tokens`, `total_tokens`, `prompt_tokens_details {cached_tokens, audio_tokens}`, `completion_tokens_details {reasoning_tokens, audio_tokens, accepted_prediction_tokens, rejected_prediction_tokens}`; streaming needs `stream_options: {include_usage: true}` (usage arrives in a final chunk with empty `choices`).
302 +- Pre-flight counting: `POST /v1/responses/input_tokens` (`{model, input, instructions?, tools?, conversation?, previous_response_id?}` -> `{object:"response.input_tokens", input_tokens}`); SDK: `client.responses.inputTokens.count(...)`. Client-side: `tiktoken` / `js-tiktoken` with `o200k_base` for gpt-4o and newer (approximation only for images/PDF). Rule of thumb 1 token ~ 4 chars English.
303 +- SDK 7.8 added `compute_units` tracking on usage for some tiers (not observed in our responses).
304 +
305 +Source: https://developers.openai.com/api/docs/api-reference/responses/input-tokens
306 +
307 +## 16. Model listing
308 +
309 +`GET /v1/models` (SDK `client.models.list()` auto-paginates) returns `{id, object:"model", created, owned_by, shutdown_date}`. **`shutdown_date` is the only lifecycle signal** (ISO date or null; documented as "The date when the model will shut down, or null if not announced"). No capability, context or pricing metadata is exposed, so a static registry is mandatory (`openai.models.json`). 131 ids were returned for this key on 2026-09-08; 55 carried a `shutdown_date`, several already in the past (see 18). Filtering heuristics for chat models: exclude ids matching `babbage|davinci|instruct|transcribe|tts|whisper|audio|realtime|image|sora|embedding|moderation|search-preview|search-api|deep-research|codex` and anything whose `shutdown_date < today`; keep the rest and look it up in the registry (unknown ids -> show as "unverified").
310 +
311 +Source: https://developers.openai.com/api/docs/api-reference/models
312 +
313 +## 17. Aliases
314 +
315 +- `gpt-5.6` -> `gpt-5.6-sol` (documented; verified `response.model === "gpt-5.6-sol"`; **not** itself listed by `/v1/models`).
316 +- `gpt-5.5` -> `gpt-5.5-2026-04-23`; `gpt-5.4` -> `-2026-03-05`; `gpt-5.4-mini`/`-nano` -> `-2026-03-17`; `gpt-5.2` -> `-2025-12-11`; `gpt-5.1` -> `-2025-11-13`; `gpt-5*` -> `-2025-08-07`; `gpt-4.1*` -> `-2025-04-14`; `gpt-4o` -> `-2024-08-06` (not the newest 11-20 snapshot); `gpt-4o-mini` -> `-2024-07-18`; `o3` -> `-2025-04-16`; `o4-mini` -> `-2025-04-16`; `o3-mini` -> `-2025-01-31`; `gpt-4-turbo` -> `-2024-04-09`; `gpt-3.5-turbo` -> `-0125`. `gpt-6-astra`, `gpt-5.6-*`, `gpt-5.3-codex`, `chat-latest` have no dated snapshot (echoed as-is).
317 +- `*-chat-latest` aliases (gpt-5 / 5.1 / 5.2 / 5.3) are **dead** (404) although still listed; `chat-latest` is the live ChatGPT-Instant alias.
318 +
319 +## 18. Lifecycle / deprecations relevant to a chat app
320 +
321 +| Shutdown | Models | Replacement |
322 +|---|---|---|
323 +| 2026-07-23 (passed; 404 today) | gpt-5-chat-latest, gpt-5.1-chat-latest, gpt-5-codex, gpt-5.1-codex(-max/-mini), gpt-5.2-codex, o3-deep-research, o4-mini-deep-research, *-search-preview-2025-03-11 snapshots | gpt-6-astra / gpt-5.3-codex |
324 +| 2026-08-10 (passed; 404) | gpt-5.2-chat-latest, gpt-5.3-chat-latest | chat-latest / gpt-6-astra |
325 +| 2026-08-26 | Assistants API | Responses + Conversations |
326 +| 2026-09-24 | sora-2, sora-2-pro, Videos API | - |
327 +| 2026-09-28 | gpt-3.5-turbo-1106, gpt-3.5-turbo-instruct, babbage-002, davinci-002 | gpt-5.6-terra |
328 +| 2026-10-23 | gpt-3.5-turbo(-0125), gpt-4(-0613), gpt-4-turbo, gpt-4.1-nano, gpt-4o-2024-05-13, gpt-image-1, o1, o1-pro, o3-mini, o4-mini | gpt-5.6-sol / terra / luna (o1-pro -> 5.6-sol `reasoning.mode: pro`) |
329 +| 2026-11-30 | v1/prompts, Evals, Agent Builder | - |
330 +| 2026-12-01 | gpt-image-1-mini, gpt-image-1.5, chatgpt-image-latest | gpt-image-2 |
331 +| 2026-12-11 | gpt-5-2025-08-07, gpt-5-mini-2025-08-07, gpt-5-nano-2025-08-07, gpt-5-pro-2025-10-06, o3-2025-04-16, o3-pro-2025-06-10 (the bare aliases `gpt-5`, `o3` currently have `shutdown_date: null`) | gpt-5.6-sol / terra / luna |
332 +| 2027-01-20 / 2027-02-26 | legacy audio/realtime/transcribe models | gpt-audio-1.5, gpt-realtime-2.1, gpt-transcribe |
333 +
334 +Fine-tuning: closed to new orgs since 2026-05-07; no new jobs at all after 2027-01-06.
335 +
336 +Source: https://developers.openai.com/api/docs/deprecations + `shutdown_date` from `/v1/models`
337 +
338 +## 19. Built-in tools, state, safety
339 +
340 +- **Conversation state**: `store` defaults to **true** (30-day retention, visible in dashboard logs) - set `store:false` for privacy-minded BYOK usage and manage history client-side; then use `include:["reasoning.encrypted_content"]` and replay all output items. `previous_response_id` (verified) and `conversation` (Conversations API, `conv_...`, not subject to 30-day TTL) require `store:true`. Server-side compaction: `context_management:[{type:"compaction", compact_threshold}]`.
341 +- **Web search**: `{type:"web_search", search_context_size?:"low"|"medium"|"high", user_location?:{type:"approximate", country, city, region, timezone}, filters?:{allowed_domains[] | blocked_domains[]} (<=100), external_web_access?, search_content_types?:["text","image"], return_token_budget?}` (legacy `web_search_preview` still accepted). Output: `web_search_call` items (`action: {type:"search", queries[], query} | {type:"open_page", url} | {type:"find_in_page"}`) then a `message` whose `output_text` part has `annotations: [{type:"url_citation", start_index, end_index, url, title}]` and inline markdown links with `?utm_source=openai`. Events: `response.web_search_call.{in_progress,searching,completed}`, `response.output_text.annotation.added`. Verified on gpt-4.1-mini and gpt-5.5 (effort low); the gpt-5.5 default-effort attempt at 200 tokens ended with three searches and no message - budget again. Search context capped at 128k. Supported per docs on gpt-6, 5.6, 5.5, 5.4 family, 5.2, 5.1, 5(-mini/-nano), 4.1(-mini), 4o(-mini), o3, o4-mini, chat-latest; not on gpt-4.1-nano, o3-mini, o1, gpt-4, gpt-3.5.
342 +- **Code execution**: `{type:"code_interpreter", container: {type:"auto", memory_limit?:"1g"|"4g"|"16g"|"64g", file_ids?} | "cntr_..."}` -> `code_interpreter_call {code, outputs, container_id}`; generated files as `container_file_citation` annotations; 100 RPM/org; events `response.code_interpreter_call*`. Also `shell` (hosted shell), `local_shell`, `apply_patch`, skills.
343 +- **File search**: `{type:"file_search", vector_store_ids[], max_num_results?, filters?, ranking_options?}` -> `file_search_call` + `file_citation {file_id, filename, index}` annotations; `include:["file_search_call.results"]`.
344 +- **Computer use**: `{type:"computer"}` (new) or `computer_use_preview {display_width, display_height, environment}`; `computer_call` -> reply with `computer_call_output {call_id, output:{type:"computer_screenshot", image_url}}`; docs recommend GPT-6 Astra with code execution instead. Not relevant for PolyLLM v1.
345 +- **MCP**: `{type:"mcp", server_label, server_url | connector_id, server_description?, authorization?, headers?, allowed_tools?, require_approval:"never"|"always"|{...}, defer_loading?}` -> `mcp_list_tools`, `mcp_call`, `mcp_approval_request` (answer with `mcp_approval_response {approval_request_id, approve}`); events `response.mcp_call*`, `response.mcp_list_tools*`. Billing = tokens only. 8 first-party connectors (Gmail, Drive, Calendar, Dropbox, Teams, Outlook x2, SharePoint).
346 +- **Citations/annotations**: `url_citation`, `file_citation`, `container_file_citation`, `file_path` types on `output_text.annotations[]`; streamed through `response.output_text.annotation.added`.
347 +- **Safety**: send `safety_identifier` (hashed user id) on every request; `incomplete_details.reason:"content_filter"` and `refusal` parts must be surfaced; free Moderation API (`omni-moderation-latest`) available; revoke leaked keys immediately. `moderation` request param exists in the SDK types.
348 +
349 +Sources: https://developers.openai.com/api/docs/guides/conversation-state , https://developers.openai.com/api/docs/guides/tools-web-search , https://developers.openai.com/api/docs/guides/tools-code-interpreter , https://developers.openai.com/api/docs/guides/tools-file-search , https://developers.openai.com/api/docs/guides/tools-computer-use , https://developers.openai.com/api/docs/guides/tools-remote-mcp , https://developers.openai.com/api/docs/guides/safety-best-practices
350 +
351 +## 20. Probe results (2026-09-08, key = Tier 5 project key)
352 +
353 +Legend: OK = completed with expected output; INC = accepted but `status:"incomplete"` (reasoning consumed the <= 200-token cap); 4xx = rejected with the quoted message.
354 +
355 +| Probe | gpt-5.5 | gpt-5.4-mini | gpt-5.6-sol | gpt-6-astra | gpt-4.1-mini | o4-mini |
356 +|---|---|---|---|---|---|---|
357 +| (a) basic Responses, 200 tok | OK (`gpt-5.5-2026-04-23`, 12 reasoning tok) | OK (0 reasoning) | OK (0 reasoning) | OK (0 reasoning) | OK | OK (64 reasoning) |
358 +| (b) streaming events | OK, reasoning item but no summary events | OK | OK, `reasoning_summary_*` events seen | OK, no summary events | OK | INC: summary events, then `response.incomplete` |
359 +| (c) temperature / top_p | 400 `Unsupported parameter: 'temperature' is not supported with this model.` (OK with `effort:"none"`) | OK (echo 0.5) | 400 same (OK with `effort:"none"`) | 400 same; `effort:"none"` itself rejected | OK | 400 same |
360 +| (c) frequency/presence_penalty | 400 `Unsupported parameter: 'frequency_penalty' is not supported with this model.` | OK | 400 | 400 | OK | 400 |
361 +| (c) seed | 400 `unknown_parameter` `Unknown parameter: 'seed'.` (all models) | | | | | |
362 +| (c) stop | 400 `unknown_parameter` `Unknown parameter: 'stop'. Did you mean 'store'?` (all models) | | | | | |
363 +| (c) logprobs | 400 `logprobs are not supported with reasoning models.` | OK | 400 | 400 | OK | 400 |
364 +| (c) effort none | OK | OK | OK | 400 `Unsupported value: 'none' is not supported with the 'gpt-6-astra' model. Supported values are: 'low', 'medium', 'high', 'xhigh', and 'max'.` | 400 `Unsupported parameter: 'reasoning.effort' is not supported with this model.` | 400 `Supported values are: 'low', 'medium', and 'high'.` |
365 +| (c) effort minimal | 400 `... Supported values are: 'none', 'low', 'medium', 'high', and 'xhigh'.` | 400 same | 400 `... 'none', 'low', 'medium', 'high', 'xhigh', and 'max'.` | 400 | 400 | 400 |
366 +| (c) effort low/medium/high | OK | OK | OK | OK | 400 | OK |
367 +| (c) effort xhigh | OK | OK | OK | OK | 400 | 400 |
368 +| (c) effort max | 400 | 400 | OK | OK | 400 | 400 |
369 +| (c) reasoning.summary auto | OK (echo `detailed`) | OK | OK | OK | OK (ignored) | OK |
370 +| (c) text.verbosity low | OK | OK | OK | OK | 400 `Unsupported value: 'low' is not supported with the 'gpt-4.1-mini' model. Supported values are: 'medium'.` | 400 same wording |
371 +| (c) max_output_tokens 5 | 400 `integer_below_min_value` `Expected a value >= 16, but got 5 instead.` (all) | | | | | |
372 +| (c) truncation auto, prompt_cache_key, store:false+encrypted | OK on all six | | | | | |
373 +| (d) function call, streaming | OK: `function_call` item, args `{"city":"Paris","unit":"c"}`, round trip -> "18°C and cloudy" | OK (+ `previous_response_id` variant OK) | OK | OK | OK | INC (192 reasoning tokens, no call) |
374 +| (e) json_schema strict | OK parsed | OK | OK | OK | OK | INC |
375 +| (f) vision 2x2 PNG | INC at default effort; OK with `effort:"none"` | OK | INC default; OK with `effort:"none"` | OK (`effort:"low"`, detail high) | OK | INC (even at `effort:"low"`) |
376 +| (h) web_search tool | OK with `effort:"low"`: `web_search_call` + `url_citation` annotation; default effort at 200 tok: 3 searches, no message | OK (3 searches + message, no citation) | not probed | not probed | OK with citation | not probed |
377 +| (i) Chat Completions | `temperature:0.3` -> 400 `Only the default (1) value is supported`; `reasoning_effort`+`verbosity` OK | - | - | `max_tokens` -> 400 `Use 'max_completion_tokens' instead.` | OK streaming, usage in last chunk | OK streaming |
378 +| (g) invalid key | 401 `invalid_api_key` (`AuthenticationError`) - see section 14 | | | | | |
379 +
380 +Other probes: `gpt-5.6` alias OK; 26-model sweep OK except `gpt-5.3-chat-latest` (404); `gpt-5-nano` INC at default effort; `o1` INC at 32 tokens; `gpt-5.5-pro` OK (7.3 s, "pong"); `gpt-4.1-nano`, `gpt-4-turbo`, `gpt-3.5-turbo`, `o3-mini` still answer despite announced shutdowns; `gpt-5-search-api` works only via `chat.completions`; PDF input OK on gpt-5.4-mini; `previous_response_id` OK (remembered "7"); `service_tier:"flex"` OK; `input_audio` -> 400 `Audio input is not available.`; `prompt_cache_options.ttl:"30m"` OK on gpt-5.6-sol.
381 +
382 +## 21. Adapter recommendations (summary)
383 +
384 +1. Responses API only; Chat Completions merely as an optional legacy toggle (needed for `gpt-audio-*`, `*-search-*`).
385 +2. Registry-driven parameter gating: sampling params allowed iff model is non-reasoning or `effort === "none"`; never send `seed`/`stop`; `max_output_tokens >= 16` and default it high (>= 4k) for reasoning models; effort dropdown filtered per model (`reasoningEfforts` in the JSON).
386 +3. Stream handler keyed on `event.type`; treat `response.incomplete` as a normal terminal event (show partial text + "reasoning exhausted budget" hint when `reason === "max_output_tokens"` and no text).
387 +4. Default `store:false` + `include:["reasoning.encrypted_content"]`, replay full `output` items each turn; offer `previous_response_id` mode only when the user opts into server-side storage.
388 +5. Persist `usage` (incl. `cached_tokens`, `cache_write_tokens`, `reasoning_tokens`) per message and price with the registry table; web-search turns cost 5-9k input tokens.
389 +6. Model list = `GET /v1/models` filtered by regex + `shutdown_date`, then joined with `openai.models.json`; show shutdown badges for dates < 90 days away.
390 +7. Errors: map on `status` + `code` + `param`; `code` can be null for "Unsupported parameter" - fall back to message prefix; never retry 401/400/quota-429.
added docs/provider-research/openai.models.json +4472 −0
@@ -0,0 +1,4472 @@
1 +[
2 + {
3 + "id": "chat-latest",
4 + "displayName": "ChatGPT Instant (chat-latest)",
5 + "family": "chat-latest",
6 + "contextTokens": 400000,
7 + "maxOutputTokens": 128000,
8 + "capabilities": {
9 + "text": true,
10 + "vision": true,
11 + "audioInput": false,
12 + "audioOutput": false,
13 + "imageGeneration": true,
14 + "video": false,
15 + "reasoning": false,
16 + "tools": true,
17 + "structuredOutput": true,
18 + "streaming": true,
19 + "files": true,
20 + "webSearch": true
21 + },
22 + "parameters": {
23 + "temperature": null,
24 + "topP": null,
25 + "topK": "unsupported",
26 + "maxTokens": "supported",
27 + "reasoningEffort": "unsupported",
28 + "thinkingBudget": "unsupported",
29 + "stop": "conditional",
30 + "seed": "conditional",
31 + "frequencyPenalty": null,
32 + "presencePenalty": null,
33 + "verbosity": "supported"
34 + },
35 + "pricing": {
36 + "inputPerMillion": 5,
37 + "cachedInputPerMillion": 0.5,
38 + "outputPerMillion": 30
39 + },
40 + "status": "active",
41 + "notes": "Latest ChatGPT Instant model; non-reasoning (probe echoed reasoning.effort medium but 0 reasoning tokens). Max input 272,000. No Batch. Docs recommend GPT-6 Astra for production. Sampling params not probed. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
42 + "reasoningEfforts": null,
43 + "defaultReasoningEffort": null,
44 + "apis": [
45 + "responses",
46 + "chat"
47 + ],
48 + "knowledgeCutoff": "2025-08-31",
49 + "shutdownDate": null,
50 + "snapshotOf": null
51 + },
52 + {
53 + "id": "gpt-3.5-turbo",
54 + "displayName": "GPT-3.5 Turbo",
55 + "family": "gpt-3.5",
56 + "contextTokens": 16385,
57 + "maxOutputTokens": 4096,
58 + "capabilities": {
59 + "text": true,
60 + "vision": false,
61 + "audioInput": false,
62 + "audioOutput": false,
63 + "imageGeneration": false,
64 + "video": false,
65 + "reasoning": false,
66 + "tools": true,
67 + "structuredOutput": false,
68 + "streaming": true,
69 + "files": false,
70 + "webSearch": false
71 + },
72 + "parameters": {
73 + "temperature": "supported",
74 + "topP": "supported",
75 + "topK": "unsupported",
76 + "maxTokens": "supported",
77 + "reasoningEffort": "unsupported",
78 + "thinkingBudget": "unsupported",
79 + "stop": "conditional",
80 + "seed": "conditional",
81 + "frequencyPenalty": "supported",
82 + "presencePenalty": "supported",
83 + "verbosity": "unsupported"
84 + },
85 + "pricing": {
86 + "inputPerMillion": 0.5,
87 + "cachedInputPerMillion": null,
88 + "outputPerMillion": 1.5
89 + },
90 + "status": "deprecated",
91 + "notes": "Alias; currently resolves to gpt-3.5-turbo-0125. shutdown_date (from GET /v1/models): 2026-10-23. Alias -> gpt-3.5-turbo-0125 (verified). shutdown_date 2026-10-23 (-1106 and -instruct: 2026-09-28) -> gpt-5.6-terra. Text only, JSON mode only. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
92 + "reasoningEfforts": null,
93 + "defaultReasoningEffort": null,
94 + "apis": [
95 + "responses",
96 + "chat",
97 + "batch",
98 + "fine-tuning"
99 + ],
100 + "knowledgeCutoff": null,
101 + "shutdownDate": "2026-10-23",
102 + "snapshotOf": null
103 + },
104 + {
105 + "id": "gpt-3.5-turbo-0125",
106 + "displayName": "GPT-3.5 Turbo (0125)",
107 + "family": "gpt-3.5",
108 + "contextTokens": 16385,
109 + "maxOutputTokens": 4096,
110 + "capabilities": {
111 + "text": true,
112 + "vision": false,
113 + "audioInput": false,
114 + "audioOutput": false,
115 + "imageGeneration": false,
116 + "video": false,
117 + "reasoning": false,
118 + "tools": true,
119 + "structuredOutput": false,
120 + "streaming": true,
121 + "files": false,
122 + "webSearch": false
123 + },
124 + "parameters": {
125 + "temperature": "supported",
126 + "topP": "supported",
127 + "topK": "unsupported",
128 + "maxTokens": "supported",
129 + "reasoningEffort": "unsupported",
130 + "thinkingBudget": "unsupported",
131 + "stop": "conditional",
132 + "seed": "conditional",
133 + "frequencyPenalty": "supported",
134 + "presencePenalty": "supported",
135 + "verbosity": "unsupported"
136 + },
137 + "pricing": {
138 + "inputPerMillion": 0.5,
139 + "cachedInputPerMillion": null,
140 + "outputPerMillion": 1.5
141 + },
142 + "status": "deprecated",
143 + "notes": "Dated snapshot of gpt-3.5-turbo. shutdown_date (from GET /v1/models): 2026-10-23. Alias -> gpt-3.5-turbo-0125 (verified). shutdown_date 2026-10-23 (-1106 and -instruct: 2026-09-28) -> gpt-5.6-terra. Text only, JSON mode only. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
144 + "reasoningEfforts": null,
145 + "defaultReasoningEffort": null,
146 + "apis": [
147 + "responses",
148 + "chat",
149 + "batch",
150 + "fine-tuning"
151 + ],
152 + "knowledgeCutoff": null,
153 + "shutdownDate": "2026-10-23",
154 + "snapshotOf": "gpt-3.5-turbo"
155 + },
156 + {
157 + "id": "gpt-3.5-turbo-1106",
158 + "displayName": "GPT-3.5 Turbo (1106)",
159 + "family": "gpt-3.5",
160 + "contextTokens": 16385,
161 + "maxOutputTokens": 4096,
162 + "capabilities": {
163 + "text": true,
164 + "vision": false,
165 + "audioInput": false,
166 + "audioOutput": false,
167 + "imageGeneration": false,
168 + "video": false,
169 + "reasoning": false,
170 + "tools": true,
171 + "structuredOutput": false,
172 + "streaming": true,
173 + "files": false,
174 + "webSearch": false
175 + },
176 + "parameters": {
177 + "temperature": "supported",
178 + "topP": "supported",
179 + "topK": "unsupported",
180 + "maxTokens": "supported",
181 + "reasoningEffort": "unsupported",
182 + "thinkingBudget": "unsupported",
183 + "stop": "conditional",
184 + "seed": "conditional",
185 + "frequencyPenalty": "supported",
186 + "presencePenalty": "supported",
187 + "verbosity": "unsupported"
188 + },
189 + "pricing": {
190 + "inputPerMillion": 0.5,
191 + "cachedInputPerMillion": null,
192 + "outputPerMillion": 1.5
193 + },
194 + "status": "deprecated",
195 + "notes": "Dated snapshot of gpt-3.5-turbo. shutdown_date (from GET /v1/models): 2026-09-28. Alias -> gpt-3.5-turbo-0125 (verified). shutdown_date 2026-10-23 (-1106 and -instruct: 2026-09-28) -> gpt-5.6-terra. Text only, JSON mode only. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
196 + "reasoningEfforts": null,
197 + "defaultReasoningEffort": null,
198 + "apis": [
199 + "responses",
200 + "chat",
201 + "batch",
202 + "fine-tuning"
203 + ],
204 + "knowledgeCutoff": null,
205 + "shutdownDate": "2026-09-28",
206 + "snapshotOf": "gpt-3.5-turbo"
207 + },
208 + {
209 + "id": "gpt-3.5-turbo-16k",
210 + "displayName": "GPT-3.5 Turbo (16k)",
211 + "family": "gpt-3.5",
212 + "contextTokens": 16385,
213 + "maxOutputTokens": 4096,
214 + "capabilities": {
215 + "text": true,
216 + "vision": false,
217 + "audioInput": false,
218 + "audioOutput": false,
219 + "imageGeneration": false,
220 + "video": false,
221 + "reasoning": false,
222 + "tools": true,
223 + "structuredOutput": false,
224 + "streaming": true,
225 + "files": false,
226 + "webSearch": false
227 + },
228 + "parameters": {
229 + "temperature": "supported",
230 + "topP": "supported",
231 + "topK": "unsupported",
232 + "maxTokens": "supported",
233 + "reasoningEffort": "unsupported",
234 + "thinkingBudget": "unsupported",
235 + "stop": "conditional",
236 + "seed": "conditional",
237 + "frequencyPenalty": "supported",
238 + "presencePenalty": "supported",
239 + "verbosity": "unsupported"
240 + },
241 + "pricing": {
242 + "inputPerMillion": 0.5,
243 + "cachedInputPerMillion": null,
244 + "outputPerMillion": 1.5
245 + },
246 + "status": "deprecated",
247 + "notes": "Dated snapshot of gpt-3.5-turbo. Alias -> gpt-3.5-turbo-0125 (verified). shutdown_date 2026-10-23 (-1106 and -instruct: 2026-09-28) -> gpt-5.6-terra. Text only, JSON mode only. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
248 + "reasoningEfforts": null,
249 + "defaultReasoningEffort": null,
250 + "apis": [
251 + "responses",
252 + "chat",
253 + "batch",
254 + "fine-tuning"
255 + ],
256 + "knowledgeCutoff": null,
257 + "shutdownDate": null,
258 + "snapshotOf": "gpt-3.5-turbo"
259 + },
260 + {
261 + "id": "gpt-4",
262 + "displayName": "GPT-4",
263 + "family": "gpt-4",
264 + "contextTokens": 8192,
265 + "maxOutputTokens": 8192,
266 + "capabilities": {
267 + "text": true,
268 + "vision": false,
269 + "audioInput": false,
270 + "audioOutput": false,
271 + "imageGeneration": false,
272 + "video": false,
273 + "reasoning": false,
274 + "tools": true,
275 + "structuredOutput": false,
276 + "streaming": true,
277 + "files": false,
278 + "webSearch": false
279 + },
280 + "parameters": {
281 + "temperature": "supported",
282 + "topP": "supported",
283 + "topK": "unsupported",
284 + "maxTokens": "supported",
285 + "reasoningEffort": "unsupported",
286 + "thinkingBudget": "unsupported",
287 + "stop": "conditional",
288 + "seed": "conditional",
289 + "frequencyPenalty": "supported",
290 + "presencePenalty": "supported",
291 + "verbosity": "unsupported"
292 + },
293 + "pricing": {
294 + "inputPerMillion": 30,
295 + "cachedInputPerMillion": null,
296 + "outputPerMillion": 60
297 + },
298 + "status": "deprecated",
299 + "notes": "shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-sol. Text only, no structured outputs (JSON mode only). Not probed. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
300 + "reasoningEfforts": null,
301 + "defaultReasoningEffort": null,
302 + "apis": [
303 + "responses",
304 + "chat",
305 + "batch",
306 + "assistants",
307 + "fine-tuning"
308 + ],
309 + "knowledgeCutoff": "2023-12-01",
310 + "shutdownDate": "2026-10-23",
311 + "snapshotOf": null
312 + },
313 + {
314 + "id": "gpt-4-0613",
315 + "displayName": "GPT-4 (0613)",
316 + "family": "gpt-4",
317 + "contextTokens": 8192,
318 + "maxOutputTokens": 8192,
319 + "capabilities": {
320 + "text": true,
321 + "vision": false,
322 + "audioInput": false,
323 + "audioOutput": false,
324 + "imageGeneration": false,
325 + "video": false,
326 + "reasoning": false,
327 + "tools": true,
328 + "structuredOutput": false,
329 + "streaming": true,
330 + "files": false,
331 + "webSearch": false
332 + },
333 + "parameters": {
334 + "temperature": "supported",
335 + "topP": "supported",
336 + "topK": "unsupported",
337 + "maxTokens": "supported",
338 + "reasoningEffort": "unsupported",
339 + "thinkingBudget": "unsupported",
340 + "stop": "conditional",
341 + "seed": "conditional",
342 + "frequencyPenalty": "supported",
343 + "presencePenalty": "supported",
344 + "verbosity": "unsupported"
345 + },
346 + "pricing": {
347 + "inputPerMillion": 30,
348 + "cachedInputPerMillion": null,
349 + "outputPerMillion": 60
350 + },
351 + "status": "deprecated",
352 + "notes": "Dated snapshot of gpt-4. shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-sol. Text only, no structured outputs (JSON mode only). Not probed. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
353 + "reasoningEfforts": null,
354 + "defaultReasoningEffort": null,
355 + "apis": [
356 + "responses",
357 + "chat",
358 + "batch",
359 + "assistants",
360 + "fine-tuning"
361 + ],
362 + "knowledgeCutoff": "2023-12-01",
363 + "shutdownDate": "2026-10-23",
364 + "snapshotOf": "gpt-4"
365 + },
366 + {
367 + "id": "gpt-4-turbo",
368 + "displayName": "GPT-4 Turbo",
369 + "family": "gpt-4",
370 + "contextTokens": 128000,
371 + "maxOutputTokens": 4096,
372 + "capabilities": {
373 + "text": true,
374 + "vision": true,
375 + "audioInput": false,
376 + "audioOutput": false,
377 + "imageGeneration": false,
378 + "video": false,
379 + "reasoning": false,
380 + "tools": true,
381 + "structuredOutput": true,
382 + "streaming": true,
383 + "files": null,
384 + "webSearch": false
385 + },
386 + "parameters": {
387 + "temperature": "supported",
388 + "topP": "supported",
389 + "topK": "unsupported",
390 + "maxTokens": "supported",
391 + "reasoningEffort": "unsupported",
392 + "thinkingBudget": "unsupported",
393 + "stop": "conditional",
394 + "seed": "conditional",
395 + "frequencyPenalty": "supported",
396 + "presencePenalty": "supported",
397 + "verbosity": "unsupported"
398 + },
399 + "pricing": {
400 + "inputPerMillion": 10,
401 + "cachedInputPerMillion": null,
402 + "outputPerMillion": 30
403 + },
404 + "status": "deprecated",
405 + "notes": "shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-sol. Still answers (verified). No prompt caching. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
406 + "reasoningEfforts": null,
407 + "defaultReasoningEffort": null,
408 + "apis": [
409 + "responses",
410 + "chat",
411 + "batch",
412 + "assistants"
413 + ],
414 + "knowledgeCutoff": "2023-12-01",
415 + "shutdownDate": "2026-10-23",
416 + "snapshotOf": null
417 + },
418 + {
419 + "id": "gpt-4-turbo-2024-04-09",
420 + "displayName": "GPT-4 Turbo (2024-04-09)",
421 + "family": "gpt-4",
422 + "contextTokens": 128000,
423 + "maxOutputTokens": 4096,
424 + "capabilities": {
425 + "text": true,
426 + "vision": true,
427 + "audioInput": false,
428 + "audioOutput": false,
429 + "imageGeneration": false,
430 + "video": false,
431 + "reasoning": false,
432 + "tools": true,
433 + "structuredOutput": true,
434 + "streaming": true,
435 + "files": null,
436 + "webSearch": false
437 + },
438 + "parameters": {
439 + "temperature": "supported",
440 + "topP": "supported",
441 + "topK": "unsupported",
442 + "maxTokens": "supported",
443 + "reasoningEffort": "unsupported",
444 + "thinkingBudget": "unsupported",
445 + "stop": "conditional",
446 + "seed": "conditional",
447 + "frequencyPenalty": "supported",
448 + "presencePenalty": "supported",
449 + "verbosity": "unsupported"
450 + },
451 + "pricing": {
452 + "inputPerMillion": 10,
453 + "cachedInputPerMillion": null,
454 + "outputPerMillion": 30
455 + },
456 + "status": "deprecated",
457 + "notes": "Dated snapshot of gpt-4-turbo. shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-sol. Still answers (verified). No prompt caching. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
458 + "reasoningEfforts": null,
459 + "defaultReasoningEffort": null,
460 + "apis": [
461 + "responses",
462 + "chat",
463 + "batch",
464 + "assistants"
465 + ],
466 + "knowledgeCutoff": "2023-12-01",
467 + "shutdownDate": "2026-10-23",
468 + "snapshotOf": "gpt-4-turbo"
469 + },
470 + {
471 + "id": "gpt-4.1",
472 + "displayName": "GPT-4.1",
473 + "family": "gpt-4.1",
474 + "contextTokens": 1047576,
475 + "maxOutputTokens": 32768,
476 + "capabilities": {
477 + "text": true,
478 + "vision": true,
479 + "audioInput": false,
480 + "audioOutput": false,
481 + "imageGeneration": true,
482 + "video": false,
483 + "reasoning": false,
484 + "tools": true,
485 + "structuredOutput": true,
486 + "streaming": true,
487 + "files": true,
488 + "webSearch": true
489 + },
490 + "parameters": {
491 + "temperature": "supported",
492 + "topP": "supported",
493 + "topK": "unsupported",
494 + "maxTokens": "supported",
495 + "reasoningEffort": "unsupported",
496 + "thinkingBudget": "unsupported",
497 + "stop": "conditional",
498 + "seed": "conditional",
499 + "frequencyPenalty": "supported",
500 + "presencePenalty": "supported",
501 + "verbosity": "unsupported"
502 + },
503 + "pricing": {
504 + "inputPerMillion": 2,
505 + "cachedInputPerMillion": 0.5,
506 + "outputPerMillion": 8
507 + },
508 + "status": "active",
509 + "notes": "Snapshot gpt-4.1-2025-04-14. Non-reasoning; classic sampling params; text.verbosity only 'medium'. Web search supported. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
510 + "reasoningEfforts": null,
511 + "defaultReasoningEffort": null,
512 + "apis": [
513 + "responses",
514 + "chat",
515 + "batch",
516 + "assistants",
517 + "fine-tuning"
518 + ],
519 + "knowledgeCutoff": "2024-06-01",
520 + "shutdownDate": null,
521 + "snapshotOf": null
522 + },
523 + {
524 + "id": "gpt-4.1-2025-04-14",
525 + "displayName": "GPT-4.1 (2025-04-14)",
526 + "family": "gpt-4.1",
527 + "contextTokens": 1047576,
528 + "maxOutputTokens": 32768,
529 + "capabilities": {
530 + "text": true,
531 + "vision": true,
532 + "audioInput": false,
533 + "audioOutput": false,
534 + "imageGeneration": true,
535 + "video": false,
536 + "reasoning": false,
537 + "tools": true,
538 + "structuredOutput": true,
539 + "streaming": true,
540 + "files": true,
541 + "webSearch": true
542 + },
543 + "parameters": {
544 + "temperature": "supported",
545 + "topP": "supported",
546 + "topK": "unsupported",
547 + "maxTokens": "supported",
548 + "reasoningEffort": "unsupported",
549 + "thinkingBudget": "unsupported",
550 + "stop": "conditional",
551 + "seed": "conditional",
552 + "frequencyPenalty": "supported",
553 + "presencePenalty": "supported",
554 + "verbosity": "unsupported"
555 + },
556 + "pricing": {
557 + "inputPerMillion": 2,
558 + "cachedInputPerMillion": 0.5,
559 + "outputPerMillion": 8
560 + },
561 + "status": "active",
562 + "notes": "Dated snapshot of gpt-4.1. Snapshot gpt-4.1-2025-04-14. Non-reasoning; classic sampling params; text.verbosity only 'medium'. Web search supported. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
563 + "reasoningEfforts": null,
564 + "defaultReasoningEffort": null,
565 + "apis": [
566 + "responses",
567 + "chat",
568 + "batch",
569 + "assistants",
570 + "fine-tuning"
571 + ],
572 + "knowledgeCutoff": "2024-06-01",
573 + "shutdownDate": null,
574 + "snapshotOf": "gpt-4.1"
575 + },
576 + {
577 + "id": "gpt-4.1-mini",
578 + "displayName": "GPT-4.1 mini",
579 + "family": "gpt-4.1",
580 + "contextTokens": 1047576,
581 + "maxOutputTokens": 32768,
582 + "capabilities": {
583 + "text": true,
584 + "vision": true,
585 + "audioInput": false,
586 + "audioOutput": false,
587 + "imageGeneration": true,
588 + "video": false,
589 + "reasoning": false,
590 + "tools": true,
591 + "structuredOutput": true,
592 + "streaming": true,
593 + "files": true,
594 + "webSearch": true
595 + },
596 + "parameters": {
597 + "temperature": "supported",
598 + "topP": "supported",
599 + "topK": "unsupported",
600 + "maxTokens": "supported",
601 + "reasoningEffort": "unsupported",
602 + "thinkingBudget": "unsupported",
603 + "stop": "conditional",
604 + "seed": "conditional",
605 + "frequencyPenalty": "supported",
606 + "presencePenalty": "supported",
607 + "verbosity": "unsupported"
608 + },
609 + "pricing": {
610 + "inputPerMillion": 0.4,
611 + "cachedInputPerMillion": 0.1,
612 + "outputPerMillion": 1.6
613 + },
614 + "status": "active",
615 + "notes": "temperature/top_p/frequency_penalty/presence_penalty/logprobs accepted; reasoning.effort rejected ('Unsupported parameter'); text.verbosity 'low' rejected ('Supported values are: medium'); seed/stop unknown_parameter in Responses (available in Chat Completions). web_search verified with url_citation annotations. Verified by probe: basic, stream, params, tools, structured, vision, web_search, chat completions. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
616 + "reasoningEfforts": null,
617 + "defaultReasoningEffort": null,
618 + "apis": [
619 + "responses",
620 + "chat",
621 + "batch",
622 + "assistants",
623 + "fine-tuning"
624 + ],
625 + "knowledgeCutoff": "2024-06-01",
626 + "shutdownDate": null,
627 + "snapshotOf": null
628 + },
629 + {
630 + "id": "gpt-4.1-mini-2025-04-14",
631 + "displayName": "GPT-4.1 mini (2025-04-14)",
632 + "family": "gpt-4.1",
633 + "contextTokens": 1047576,
634 + "maxOutputTokens": 32768,
635 + "capabilities": {
636 + "text": true,
637 + "vision": true,
638 + "audioInput": false,
639 + "audioOutput": false,
640 + "imageGeneration": true,
641 + "video": false,
642 + "reasoning": false,
643 + "tools": true,
644 + "structuredOutput": true,
645 + "streaming": true,
646 + "files": true,
647 + "webSearch": true
648 + },
649 + "parameters": {
650 + "temperature": "supported",
651 + "topP": "supported",
652 + "topK": "unsupported",
653 + "maxTokens": "supported",
654 + "reasoningEffort": "unsupported",
655 + "thinkingBudget": "unsupported",
656 + "stop": "conditional",
657 + "seed": "conditional",
658 + "frequencyPenalty": "supported",
659 + "presencePenalty": "supported",
660 + "verbosity": "unsupported"
661 + },
662 + "pricing": {
663 + "inputPerMillion": 0.4,
664 + "cachedInputPerMillion": 0.1,
665 + "outputPerMillion": 1.6
666 + },
667 + "status": "active",
668 + "notes": "Dated snapshot of gpt-4.1-mini. temperature/top_p/frequency_penalty/presence_penalty/logprobs accepted; reasoning.effort rejected ('Unsupported parameter'); text.verbosity 'low' rejected ('Supported values are: medium'); seed/stop unknown_parameter in Responses (available in Chat Completions). web_search verified with url_citation annotations. Verified by probe: basic, stream, params, tools, structured, vision, web_search, chat completions. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
669 + "reasoningEfforts": null,
670 + "defaultReasoningEffort": null,
671 + "apis": [
672 + "responses",
673 + "chat",
674 + "batch",
675 + "assistants",
676 + "fine-tuning"
677 + ],
678 + "knowledgeCutoff": "2024-06-01",
679 + "shutdownDate": null,
680 + "snapshotOf": "gpt-4.1-mini"
681 + },
682 + {
683 + "id": "gpt-4.1-nano",
684 + "displayName": "GPT-4.1 nano",
685 + "family": "gpt-4.1",
686 + "contextTokens": 1047576,
687 + "maxOutputTokens": 32768,
688 + "capabilities": {
689 + "text": true,
690 + "vision": true,
691 + "audioInput": false,
692 + "audioOutput": false,
693 + "imageGeneration": true,
694 + "video": false,
695 + "reasoning": false,
696 + "tools": true,
697 + "structuredOutput": true,
698 + "streaming": true,
699 + "files": true,
700 + "webSearch": false
701 + },
702 + "parameters": {
703 + "temperature": "supported",
704 + "topP": "supported",
705 + "topK": "unsupported",
706 + "maxTokens": "supported",
707 + "reasoningEffort": "unsupported",
708 + "thinkingBudget": "unsupported",
709 + "stop": "conditional",
710 + "seed": "conditional",
711 + "frequencyPenalty": "supported",
712 + "presencePenalty": "supported",
713 + "verbosity": "unsupported"
714 + },
715 + "pricing": {
716 + "inputPerMillion": 0.1,
717 + "cachedInputPerMillion": 0.025,
718 + "outputPerMillion": 0.4
719 + },
720 + "status": "deprecated",
721 + "notes": "shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 (still answers, verified) -> replacement gpt-5.6-luna. No web_search tool. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
722 + "reasoningEfforts": null,
723 + "defaultReasoningEffort": null,
724 + "apis": [
725 + "responses",
726 + "chat",
727 + "batch",
728 + "assistants",
729 + "fine-tuning"
730 + ],
731 + "knowledgeCutoff": "2024-06-01",
732 + "shutdownDate": "2026-10-23",
733 + "snapshotOf": null
734 + },
735 + {
736 + "id": "gpt-4.1-nano-2025-04-14",
737 + "displayName": "GPT-4.1 nano (2025-04-14)",
738 + "family": "gpt-4.1",
739 + "contextTokens": 1047576,
740 + "maxOutputTokens": 32768,
741 + "capabilities": {
742 + "text": true,
743 + "vision": true,
744 + "audioInput": false,
745 + "audioOutput": false,
746 + "imageGeneration": true,
747 + "video": false,
748 + "reasoning": false,
749 + "tools": true,
750 + "structuredOutput": true,
751 + "streaming": true,
752 + "files": true,
753 + "webSearch": false
754 + },
755 + "parameters": {
756 + "temperature": "supported",
757 + "topP": "supported",
758 + "topK": "unsupported",
759 + "maxTokens": "supported",
760 + "reasoningEffort": "unsupported",
761 + "thinkingBudget": "unsupported",
762 + "stop": "conditional",
763 + "seed": "conditional",
764 + "frequencyPenalty": "supported",
765 + "presencePenalty": "supported",
766 + "verbosity": "unsupported"
767 + },
768 + "pricing": {
769 + "inputPerMillion": 0.1,
770 + "cachedInputPerMillion": 0.025,
771 + "outputPerMillion": 0.4
772 + },
773 + "status": "deprecated",
774 + "notes": "Dated snapshot of gpt-4.1-nano. shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 (still answers, verified) -> replacement gpt-5.6-luna. No web_search tool. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
775 + "reasoningEfforts": null,
776 + "defaultReasoningEffort": null,
777 + "apis": [
778 + "responses",
779 + "chat",
780 + "batch",
781 + "assistants",
782 + "fine-tuning"
783 + ],
784 + "knowledgeCutoff": "2024-06-01",
785 + "shutdownDate": "2026-10-23",
786 + "snapshotOf": "gpt-4.1-nano"
787 + },
788 + {
789 + "id": "gpt-4o",
790 + "displayName": "GPT-4o",
791 + "family": "gpt-4o",
792 + "contextTokens": 128000,
793 + "maxOutputTokens": 16384,
794 + "capabilities": {
795 + "text": true,
796 + "vision": true,
797 + "audioInput": false,
798 + "audioOutput": false,
799 + "imageGeneration": true,
800 + "video": false,
801 + "reasoning": false,
802 + "tools": true,
803 + "structuredOutput": true,
804 + "streaming": true,
805 + "files": true,
806 + "webSearch": true
807 + },
808 + "parameters": {
809 + "temperature": "supported",
810 + "topP": "supported",
811 + "topK": "unsupported",
812 + "maxTokens": "supported",
813 + "reasoningEffort": "unsupported",
814 + "thinkingBudget": "unsupported",
815 + "stop": "conditional",
816 + "seed": "conditional",
817 + "frequencyPenalty": "supported",
818 + "presencePenalty": "supported",
819 + "verbosity": "unsupported"
820 + },
821 + "pricing": {
822 + "inputPerMillion": 2.5,
823 + "cachedInputPerMillion": 1.25,
824 + "outputPerMillion": 10
825 + },
826 + "status": "active",
827 + "notes": "Alias; currently resolves to gpt-4o-2024-08-06. Alias resolves to gpt-4o-2024-08-06 (verified). Snapshot 2024-05-13 shuts down 2026-10-23 -> gpt-5.6-sol. Cached input is only 50% (older cache pricing). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
828 + "reasoningEfforts": null,
829 + "defaultReasoningEffort": null,
830 + "apis": [
831 + "responses",
832 + "chat",
833 + "batch",
834 + "assistants",
835 + "fine-tuning"
836 + ],
837 + "knowledgeCutoff": "2023-10-01",
838 + "shutdownDate": null,
839 + "snapshotOf": null
840 + },
841 + {
842 + "id": "gpt-4o-2024-05-13",
843 + "displayName": "GPT-4o (2024-05-13)",
844 + "family": "gpt-4o",
845 + "contextTokens": 128000,
846 + "maxOutputTokens": 16384,
847 + "capabilities": {
848 + "text": true,
849 + "vision": true,
850 + "audioInput": false,
851 + "audioOutput": false,
852 + "imageGeneration": true,
853 + "video": false,
854 + "reasoning": false,
855 + "tools": true,
856 + "structuredOutput": true,
857 + "streaming": true,
858 + "files": true,
859 + "webSearch": true
860 + },
861 + "parameters": {
862 + "temperature": "supported",
863 + "topP": "supported",
864 + "topK": "unsupported",
865 + "maxTokens": "supported",
866 + "reasoningEffort": "unsupported",
867 + "thinkingBudget": "unsupported",
868 + "stop": "conditional",
869 + "seed": "conditional",
870 + "frequencyPenalty": "supported",
871 + "presencePenalty": "supported",
872 + "verbosity": "unsupported"
873 + },
874 + "pricing": {
875 + "inputPerMillion": 2.5,
876 + "cachedInputPerMillion": 1.25,
877 + "outputPerMillion": 10
878 + },
879 + "status": "deprecated",
880 + "notes": "Dated snapshot of gpt-4o. shutdown_date (from GET /v1/models): 2026-10-23. Alias resolves to gpt-4o-2024-08-06 (verified). Snapshot 2024-05-13 shuts down 2026-10-23 -> gpt-5.6-sol. Cached input is only 50% (older cache pricing). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
881 + "reasoningEfforts": null,
882 + "defaultReasoningEffort": null,
883 + "apis": [
884 + "responses",
885 + "chat",
886 + "batch",
887 + "assistants",
888 + "fine-tuning"
889 + ],
890 + "knowledgeCutoff": "2023-10-01",
891 + "shutdownDate": "2026-10-23",
892 + "snapshotOf": "gpt-4o"
893 + },
894 + {
895 + "id": "gpt-4o-2024-08-06",
896 + "displayName": "GPT-4o (2024-08-06)",
897 + "family": "gpt-4o",
898 + "contextTokens": 128000,
899 + "maxOutputTokens": 16384,
900 + "capabilities": {
901 + "text": true,
902 + "vision": true,
903 + "audioInput": false,
904 + "audioOutput": false,
905 + "imageGeneration": true,
906 + "video": false,
907 + "reasoning": false,
908 + "tools": true,
909 + "structuredOutput": true,
910 + "streaming": true,
911 + "files": true,
912 + "webSearch": true
913 + },
914 + "parameters": {
915 + "temperature": "supported",
916 + "topP": "supported",
917 + "topK": "unsupported",
918 + "maxTokens": "supported",
919 + "reasoningEffort": "unsupported",
920 + "thinkingBudget": "unsupported",
921 + "stop": "conditional",
922 + "seed": "conditional",
923 + "frequencyPenalty": "supported",
924 + "presencePenalty": "supported",
925 + "verbosity": "unsupported"
926 + },
927 + "pricing": {
928 + "inputPerMillion": 2.5,
929 + "cachedInputPerMillion": 1.25,
930 + "outputPerMillion": 10
931 + },
932 + "status": "active",
933 + "notes": "Dated snapshot of gpt-4o. Alias resolves to gpt-4o-2024-08-06 (verified). Snapshot 2024-05-13 shuts down 2026-10-23 -> gpt-5.6-sol. Cached input is only 50% (older cache pricing). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
934 + "reasoningEfforts": null,
935 + "defaultReasoningEffort": null,
936 + "apis": [
937 + "responses",
938 + "chat",
939 + "batch",
940 + "assistants",
941 + "fine-tuning"
942 + ],
943 + "knowledgeCutoff": "2023-10-01",
944 + "shutdownDate": null,
945 + "snapshotOf": "gpt-4o"
946 + },
947 + {
948 + "id": "gpt-4o-2024-11-20",
949 + "displayName": "GPT-4o (2024-11-20)",
950 + "family": "gpt-4o",
951 + "contextTokens": 128000,
952 + "maxOutputTokens": 16384,
953 + "capabilities": {
954 + "text": true,
955 + "vision": true,
956 + "audioInput": false,
957 + "audioOutput": false,
958 + "imageGeneration": true,
959 + "video": false,
960 + "reasoning": false,
961 + "tools": true,
962 + "structuredOutput": true,
963 + "streaming": true,
964 + "files": true,
965 + "webSearch": true
966 + },
967 + "parameters": {
968 + "temperature": "supported",
969 + "topP": "supported",
970 + "topK": "unsupported",
971 + "maxTokens": "supported",
972 + "reasoningEffort": "unsupported",
973 + "thinkingBudget": "unsupported",
974 + "stop": "conditional",
975 + "seed": "conditional",
976 + "frequencyPenalty": "supported",
977 + "presencePenalty": "supported",
978 + "verbosity": "unsupported"
979 + },
980 + "pricing": {
981 + "inputPerMillion": 2.5,
982 + "cachedInputPerMillion": 1.25,
983 + "outputPerMillion": 10
984 + },
985 + "status": "active",
986 + "notes": "Dated snapshot of gpt-4o. Alias resolves to gpt-4o-2024-08-06 (verified). Snapshot 2024-05-13 shuts down 2026-10-23 -> gpt-5.6-sol. Cached input is only 50% (older cache pricing). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
987 + "reasoningEfforts": null,
988 + "defaultReasoningEffort": null,
989 + "apis": [
990 + "responses",
991 + "chat",
992 + "batch",
993 + "assistants",
994 + "fine-tuning"
995 + ],
996 + "knowledgeCutoff": "2023-10-01",
997 + "shutdownDate": null,
998 + "snapshotOf": "gpt-4o"
999 + },
1000 + {
1001 + "id": "gpt-4o-mini",
1002 + "displayName": "GPT-4o mini",
1003 + "family": "gpt-4o",
1004 + "contextTokens": 128000,
1005 + "maxOutputTokens": 16384,
1006 + "capabilities": {
1007 + "text": true,
1008 + "vision": true,
1009 + "audioInput": false,
1010 + "audioOutput": false,
1011 + "imageGeneration": true,
1012 + "video": false,
1013 + "reasoning": false,
1014 + "tools": true,
1015 + "structuredOutput": true,
1016 + "streaming": true,
1017 + "files": true,
1018 + "webSearch": true
1019 + },
1020 + "parameters": {
1021 + "temperature": "supported",
1022 + "topP": "supported",
1023 + "topK": "unsupported",
1024 + "maxTokens": "supported",
1025 + "reasoningEffort": "unsupported",
1026 + "thinkingBudget": "unsupported",
1027 + "stop": "conditional",
1028 + "seed": "conditional",
1029 + "frequencyPenalty": "supported",
1030 + "presencePenalty": "supported",
1031 + "verbosity": "unsupported"
1032 + },
1033 + "pricing": {
1034 + "inputPerMillion": 0.15,
1035 + "cachedInputPerMillion": 0.075,
1036 + "outputPerMillion": 0.6
1037 + },
1038 + "status": "active",
1039 + "notes": "Snapshot gpt-4o-mini-2024-07-18. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1040 + "reasoningEfforts": null,
1041 + "defaultReasoningEffort": null,
1042 + "apis": [
1043 + "responses",
1044 + "chat",
1045 + "batch",
1046 + "assistants",
1047 + "fine-tuning"
1048 + ],
1049 + "knowledgeCutoff": "2023-10-01",
1050 + "shutdownDate": null,
1051 + "snapshotOf": null
1052 + },
1053 + {
1054 + "id": "gpt-4o-mini-2024-07-18",
1055 + "displayName": "GPT-4o mini (2024-07-18)",
1056 + "family": "gpt-4o",
1057 + "contextTokens": 128000,
1058 + "maxOutputTokens": 16384,
1059 + "capabilities": {
1060 + "text": true,
1061 + "vision": true,
1062 + "audioInput": false,
1063 + "audioOutput": false,
1064 + "imageGeneration": true,
1065 + "video": false,
1066 + "reasoning": false,
1067 + "tools": true,
1068 + "structuredOutput": true,
1069 + "streaming": true,
1070 + "files": true,
1071 + "webSearch": true
1072 + },
1073 + "parameters": {
1074 + "temperature": "supported",
1075 + "topP": "supported",
1076 + "topK": "unsupported",
1077 + "maxTokens": "supported",
1078 + "reasoningEffort": "unsupported",
1079 + "thinkingBudget": "unsupported",
1080 + "stop": "conditional",
1081 + "seed": "conditional",
1082 + "frequencyPenalty": "supported",
1083 + "presencePenalty": "supported",
1084 + "verbosity": "unsupported"
1085 + },
1086 + "pricing": {
1087 + "inputPerMillion": 0.15,
1088 + "cachedInputPerMillion": 0.075,
1089 + "outputPerMillion": 0.6
1090 + },
1091 + "status": "active",
1092 + "notes": "Dated snapshot of gpt-4o-mini. Snapshot gpt-4o-mini-2024-07-18. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1093 + "reasoningEfforts": null,
1094 + "defaultReasoningEffort": null,
1095 + "apis": [
1096 + "responses",
1097 + "chat",
1098 + "batch",
1099 + "assistants",
1100 + "fine-tuning"
1101 + ],
1102 + "knowledgeCutoff": "2023-10-01",
1103 + "shutdownDate": null,
1104 + "snapshotOf": "gpt-4o-mini"
1105 + },
1106 + {
1107 + "id": "gpt-4o-mini-search-preview",
1108 + "displayName": "GPT-4o mini Search Preview",
1109 + "family": "gpt-4o",
1110 + "contextTokens": 128000,
1111 + "maxOutputTokens": 16384,
1112 + "capabilities": {
1113 + "text": true,
1114 + "vision": true,
1115 + "audioInput": false,
1116 + "audioOutput": false,
1117 + "imageGeneration": false,
1118 + "video": false,
1119 + "reasoning": false,
1120 + "tools": true,
1121 + "structuredOutput": true,
1122 + "streaming": true,
1123 + "files": true,
1124 + "webSearch": true
1125 + },
1126 + "parameters": {
1127 + "temperature": "supported",
1128 + "topP": "supported",
1129 + "topK": "unsupported",
1130 + "maxTokens": "supported",
1131 + "reasoningEffort": "unsupported",
1132 + "thinkingBudget": "unsupported",
1133 + "stop": "conditional",
1134 + "seed": "conditional",
1135 + "frequencyPenalty": "supported",
1136 + "presencePenalty": "supported",
1137 + "verbosity": "unsupported"
1138 + },
1139 + "pricing": {
1140 + "inputPerMillion": null,
1141 + "cachedInputPerMillion": null,
1142 + "outputPerMillion": null
1143 + },
1144 + "status": "preview",
1145 + "notes": "Chat Completions only (by analogy with gpt-4o-search-preview; not probed). Snapshot shutdown_date 2026-07-23. Pricing page not fetched -> null. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1146 + "reasoningEfforts": null,
1147 + "defaultReasoningEffort": null,
1148 + "apis": [
1149 + "chat"
1150 + ],
1151 + "knowledgeCutoff": null,
1152 + "shutdownDate": null,
1153 + "snapshotOf": null
1154 + },
1155 + {
1156 + "id": "gpt-4o-mini-search-preview-2025-03-11",
1157 + "displayName": "GPT-4o mini Search Preview (2025-03-11)",
1158 + "family": "gpt-4o",
1159 + "contextTokens": 128000,
1160 + "maxOutputTokens": 16384,
1161 + "capabilities": {
1162 + "text": true,
1163 + "vision": true,
1164 + "audioInput": false,
1165 + "audioOutput": false,
1166 + "imageGeneration": false,
1167 + "video": false,
1168 + "reasoning": false,
1169 + "tools": true,
1170 + "structuredOutput": true,
1171 + "streaming": true,
1172 + "files": true,
1173 + "webSearch": true
1174 + },
1175 + "parameters": {
1176 + "temperature": "supported",
1177 + "topP": "supported",
1178 + "topK": "unsupported",
1179 + "maxTokens": "supported",
1180 + "reasoningEffort": "unsupported",
1181 + "thinkingBudget": "unsupported",
1182 + "stop": "conditional",
1183 + "seed": "conditional",
1184 + "frequencyPenalty": "supported",
1185 + "presencePenalty": "supported",
1186 + "verbosity": "unsupported"
1187 + },
1188 + "pricing": {
1189 + "inputPerMillion": null,
1190 + "cachedInputPerMillion": null,
1191 + "outputPerMillion": null
1192 + },
1193 + "status": "deprecated",
1194 + "notes": "Dated snapshot of gpt-4o-mini-search-preview. shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. Chat Completions only (by analogy with gpt-4o-search-preview; not probed). Snapshot shutdown_date 2026-07-23. Pricing page not fetched -> null. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1195 + "reasoningEfforts": null,
1196 + "defaultReasoningEffort": null,
1197 + "apis": [
1198 + "chat"
1199 + ],
1200 + "knowledgeCutoff": null,
1201 + "shutdownDate": "2026-07-23",
1202 + "snapshotOf": "gpt-4o-mini-search-preview"
1203 + },
1204 + {
1205 + "id": "gpt-4o-search-preview",
1206 + "displayName": "GPT-4o Search Preview",
1207 + "family": "gpt-4o",
1208 + "contextTokens": 128000,
1209 + "maxOutputTokens": 16384,
1210 + "capabilities": {
1211 + "text": true,
1212 + "vision": true,
1213 + "audioInput": false,
1214 + "audioOutput": false,
1215 + "imageGeneration": false,
1216 + "video": false,
1217 + "reasoning": false,
1218 + "tools": true,
1219 + "structuredOutput": true,
1220 + "streaming": true,
1221 + "files": true,
1222 + "webSearch": true
1223 + },
1224 + "parameters": {
1225 + "temperature": "supported",
1226 + "topP": "supported",
1227 + "topK": "unsupported",
1228 + "maxTokens": "supported",
1229 + "reasoningEffort": "unsupported",
1230 + "thinkingBudget": "unsupported",
1231 + "stop": "conditional",
1232 + "seed": "conditional",
1233 + "frequencyPenalty": "supported",
1234 + "presencePenalty": "supported",
1235 + "verbosity": "unsupported"
1236 + },
1237 + "pricing": {
1238 + "inputPerMillion": 2.5,
1239 + "cachedInputPerMillion": null,
1240 + "outputPerMillion": 10
1241 + },
1242 + "status": "preview",
1243 + "notes": "Chat Completions only (Responses -> 400 'not supported with the Responses API', verified). Snapshot 2025-03-11 has shutdown_date 2026-07-23. Legacy; use web_search tool instead. Verified by probe: responses -> 400. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1244 + "reasoningEfforts": null,
1245 + "defaultReasoningEffort": null,
1246 + "apis": [
1247 + "chat"
1248 + ],
1249 + "knowledgeCutoff": null,
1250 + "shutdownDate": null,
1251 + "snapshotOf": null
1252 + },
1253 + {
1254 + "id": "gpt-4o-search-preview-2025-03-11",
1255 + "displayName": "GPT-4o Search Preview (2025-03-11)",
1256 + "family": "gpt-4o",
1257 + "contextTokens": 128000,
1258 + "maxOutputTokens": 16384,
1259 + "capabilities": {
1260 + "text": true,
1261 + "vision": true,
1262 + "audioInput": false,
1263 + "audioOutput": false,
1264 + "imageGeneration": false,
1265 + "video": false,
1266 + "reasoning": false,
1267 + "tools": true,
1268 + "structuredOutput": true,
1269 + "streaming": true,
1270 + "files": true,
1271 + "webSearch": true
1272 + },
1273 + "parameters": {
1274 + "temperature": "supported",
1275 + "topP": "supported",
1276 + "topK": "unsupported",
1277 + "maxTokens": "supported",
1278 + "reasoningEffort": "unsupported",
1279 + "thinkingBudget": "unsupported",
1280 + "stop": "conditional",
1281 + "seed": "conditional",
1282 + "frequencyPenalty": "supported",
1283 + "presencePenalty": "supported",
1284 + "verbosity": "unsupported"
1285 + },
1286 + "pricing": {
1287 + "inputPerMillion": 2.5,
1288 + "cachedInputPerMillion": null,
1289 + "outputPerMillion": 10
1290 + },
1291 + "status": "deprecated",
1292 + "notes": "Dated snapshot of gpt-4o-search-preview. shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. Chat Completions only (Responses -> 400 'not supported with the Responses API', verified). Snapshot 2025-03-11 has shutdown_date 2026-07-23. Legacy; use web_search tool instead. Verified by probe: responses -> 400. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1293 + "reasoningEfforts": null,
1294 + "defaultReasoningEffort": null,
1295 + "apis": [
1296 + "chat"
1297 + ],
1298 + "knowledgeCutoff": null,
1299 + "shutdownDate": "2026-07-23",
1300 + "snapshotOf": "gpt-4o-search-preview"
1301 + },
1302 + {
1303 + "id": "gpt-5",
1304 + "displayName": "GPT-5",
1305 + "family": "gpt-5",
1306 + "contextTokens": 400000,
1307 + "maxOutputTokens": 128000,
1308 + "capabilities": {
1309 + "text": true,
1310 + "vision": true,
1311 + "audioInput": false,
1312 + "audioOutput": false,
1313 + "imageGeneration": true,
1314 + "video": false,
1315 + "reasoning": true,
1316 + "tools": true,
1317 + "structuredOutput": true,
1318 + "streaming": true,
1319 + "files": true,
1320 + "webSearch": true
1321 + },
1322 + "parameters": {
1323 + "temperature": "unsupported",
1324 + "topP": "unsupported",
1325 + "topK": "unsupported",
1326 + "maxTokens": "supported",
1327 + "reasoningEffort": "supported",
1328 + "thinkingBudget": "unsupported",
1329 + "stop": "unsupported",
1330 + "seed": "unsupported",
1331 + "frequencyPenalty": "unsupported",
1332 + "presencePenalty": "unsupported",
1333 + "verbosity": "supported"
1334 + },
1335 + "pricing": {
1336 + "inputPerMillion": 1.25,
1337 + "cachedInputPerMillion": 0.125,
1338 + "outputPerMillion": 10
1339 + },
1340 + "status": "active",
1341 + "notes": "Alias still active but snapshot gpt-5-2025-08-07 has shutdown_date 2026-12-11 -> replacement gpt-5.6-sol. Uses 'minimal' (not 'none'); temperature not supported at any effort (docs). Reasoning items appear in output by default. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1342 + "reasoningEfforts": [
1343 + "minimal",
1344 + "low",
1345 + "medium",
1346 + "high"
1347 + ],
1348 + "defaultReasoningEffort": "medium",
1349 + "apis": [
1350 + "responses",
1351 + "chat",
1352 + "batch"
1353 + ],
1354 + "knowledgeCutoff": "2024-09-30",
1355 + "shutdownDate": null,
1356 + "snapshotOf": null
1357 + },
1358 + {
1359 + "id": "gpt-5-2025-08-07",
1360 + "displayName": "GPT-5 (2025-08-07)",
1361 + "family": "gpt-5",
1362 + "contextTokens": 400000,
1363 + "maxOutputTokens": 128000,
1364 + "capabilities": {
1365 + "text": true,
1366 + "vision": true,
1367 + "audioInput": false,
1368 + "audioOutput": false,
1369 + "imageGeneration": true,
1370 + "video": false,
1371 + "reasoning": true,
1372 + "tools": true,
1373 + "structuredOutput": true,
1374 + "streaming": true,
1375 + "files": true,
1376 + "webSearch": true
1377 + },
1378 + "parameters": {
1379 + "temperature": "unsupported",
1380 + "topP": "unsupported",
1381 + "topK": "unsupported",
1382 + "maxTokens": "supported",
1383 + "reasoningEffort": "supported",
1384 + "thinkingBudget": "unsupported",
1385 + "stop": "unsupported",
1386 + "seed": "unsupported",
1387 + "frequencyPenalty": "unsupported",
1388 + "presencePenalty": "unsupported",
1389 + "verbosity": "supported"
1390 + },
1391 + "pricing": {
1392 + "inputPerMillion": 1.25,
1393 + "cachedInputPerMillion": 0.125,
1394 + "outputPerMillion": 10
1395 + },
1396 + "status": "deprecated",
1397 + "notes": "Dated snapshot of gpt-5. shutdown_date (from GET /v1/models): 2026-12-11. Alias still active but snapshot gpt-5-2025-08-07 has shutdown_date 2026-12-11 -> replacement gpt-5.6-sol. Uses 'minimal' (not 'none'); temperature not supported at any effort (docs). Reasoning items appear in output by default. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1398 + "reasoningEfforts": [
1399 + "minimal",
1400 + "low",
1401 + "medium",
1402 + "high"
1403 + ],
1404 + "defaultReasoningEffort": "medium",
1405 + "apis": [
1406 + "responses",
1407 + "chat",
1408 + "batch"
1409 + ],
1410 + "knowledgeCutoff": "2024-09-30",
1411 + "shutdownDate": "2026-12-11",
1412 + "snapshotOf": "gpt-5"
1413 + },
1414 + {
1415 + "id": "gpt-5-chat-latest",
1416 + "displayName": "GPT-5 Chat",
1417 + "family": "gpt-5",
1418 + "contextTokens": 128000,
1419 + "maxOutputTokens": 16384,
1420 + "capabilities": {
1421 + "text": true,
1422 + "vision": true,
1423 + "audioInput": false,
1424 + "audioOutput": false,
1425 + "imageGeneration": true,
1426 + "video": false,
1427 + "reasoning": false,
1428 + "tools": true,
1429 + "structuredOutput": true,
1430 + "streaming": true,
1431 + "files": true,
1432 + "webSearch": true
1433 + },
1434 + "parameters": {
1435 + "temperature": "supported",
1436 + "topP": "supported",
1437 + "topK": "unsupported",
1438 + "maxTokens": "supported",
1439 + "reasoningEffort": "unsupported",
1440 + "thinkingBudget": "unsupported",
1441 + "stop": "conditional",
1442 + "seed": "conditional",
1443 + "frequencyPenalty": "supported",
1444 + "presencePenalty": "supported",
1445 + "verbosity": "unsupported"
1446 + },
1447 + "pricing": {
1448 + "inputPerMillion": 1.25,
1449 + "cachedInputPerMillion": 0.125,
1450 + "outputPerMillion": 10
1451 + },
1452 + "status": "deprecated",
1453 + "notes": "shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23; 404 model_not_found (verified). Verified by probe: basic -> 404. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1454 + "reasoningEfforts": null,
1455 + "defaultReasoningEffort": null,
1456 + "apis": [
1457 + "responses",
1458 + "chat"
1459 + ],
1460 + "knowledgeCutoff": null,
1461 + "shutdownDate": "2026-07-23",
1462 + "snapshotOf": null
1463 + },
1464 + {
1465 + "id": "gpt-5-codex",
1466 + "displayName": "GPT-5 Codex",
1467 + "family": "gpt-5",
1468 + "contextTokens": 400000,
1469 + "maxOutputTokens": 128000,
1470 + "capabilities": {
1471 + "text": true,
1472 + "vision": true,
1473 + "audioInput": false,
1474 + "audioOutput": false,
1475 + "imageGeneration": true,
1476 + "video": false,
1477 + "reasoning": true,
1478 + "tools": true,
1479 + "structuredOutput": true,
1480 + "streaming": true,
1481 + "files": true,
1482 + "webSearch": true
1483 + },
1484 + "parameters": {
1485 + "temperature": "unsupported",
1486 + "topP": "unsupported",
1487 + "topK": "unsupported",
1488 + "maxTokens": "supported",
1489 + "reasoningEffort": "supported",
1490 + "thinkingBudget": "unsupported",
1491 + "stop": "unsupported",
1492 + "seed": "unsupported",
1493 + "frequencyPenalty": "unsupported",
1494 + "presencePenalty": "unsupported",
1495 + "verbosity": "supported"
1496 + },
1497 + "pricing": {
1498 + "inputPerMillion": null,
1499 + "cachedInputPerMillion": null,
1500 + "outputPerMillion": null
1501 + },
1502 + "status": "deprecated",
1503 + "notes": "shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23; 404 model_not_found (verified). Verified by probe: basic -> 404. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1504 + "reasoningEfforts": null,
1505 + "defaultReasoningEffort": null,
1506 + "apis": [
1507 + "responses"
1508 + ],
1509 + "knowledgeCutoff": null,
1510 + "shutdownDate": "2026-07-23",
1511 + "snapshotOf": null
1512 + },
1513 + {
1514 + "id": "gpt-5-mini",
1515 + "displayName": "GPT-5 mini",
1516 + "family": "gpt-5",
1517 + "contextTokens": 400000,
1518 + "maxOutputTokens": 128000,
1519 + "capabilities": {
1520 + "text": true,
1521 + "vision": true,
1522 + "audioInput": false,
1523 + "audioOutput": false,
1524 + "imageGeneration": true,
1525 + "video": false,
1526 + "reasoning": true,
1527 + "tools": true,
1528 + "structuredOutput": true,
1529 + "streaming": true,
1530 + "files": true,
1531 + "webSearch": true
1532 + },
1533 + "parameters": {
1534 + "temperature": "unsupported",
1535 + "topP": "unsupported",
1536 + "topK": "unsupported",
1537 + "maxTokens": "supported",
1538 + "reasoningEffort": "supported",
1539 + "thinkingBudget": "unsupported",
1540 + "stop": "unsupported",
1541 + "seed": "unsupported",
1542 + "frequencyPenalty": "unsupported",
1543 + "presencePenalty": "unsupported",
1544 + "verbosity": "supported"
1545 + },
1546 + "pricing": {
1547 + "inputPerMillion": 0.25,
1548 + "cachedInputPerMillion": 0.025,
1549 + "outputPerMillion": 2
1550 + },
1551 + "status": "active",
1552 + "notes": "Snapshot gpt-5-mini-2025-08-07 shuts down 2026-12-11 -> gpt-5.6-terra. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1553 + "reasoningEfforts": [
1554 + "minimal",
1555 + "low",
1556 + "medium",
1557 + "high"
1558 + ],
1559 + "defaultReasoningEffort": "medium",
1560 + "apis": [
1561 + "responses",
1562 + "chat",
1563 + "batch"
1564 + ],
1565 + "knowledgeCutoff": "2024-05-31",
1566 + "shutdownDate": null,
1567 + "snapshotOf": null
1568 + },
1569 + {
1570 + "id": "gpt-5-mini-2025-08-07",
1571 + "displayName": "GPT-5 mini (2025-08-07)",
1572 + "family": "gpt-5",
1573 + "contextTokens": 400000,
1574 + "maxOutputTokens": 128000,
1575 + "capabilities": {
1576 + "text": true,
1577 + "vision": true,
1578 + "audioInput": false,
1579 + "audioOutput": false,
1580 + "imageGeneration": true,
1581 + "video": false,
1582 + "reasoning": true,
1583 + "tools": true,
1584 + "structuredOutput": true,
1585 + "streaming": true,
1586 + "files": true,
1587 + "webSearch": true
1588 + },
1589 + "parameters": {
1590 + "temperature": "unsupported",
1591 + "topP": "unsupported",
1592 + "topK": "unsupported",
1593 + "maxTokens": "supported",
1594 + "reasoningEffort": "supported",
1595 + "thinkingBudget": "unsupported",
1596 + "stop": "unsupported",
1597 + "seed": "unsupported",
1598 + "frequencyPenalty": "unsupported",
1599 + "presencePenalty": "unsupported",
1600 + "verbosity": "supported"
1601 + },
1602 + "pricing": {
1603 + "inputPerMillion": 0.25,
1604 + "cachedInputPerMillion": 0.025,
1605 + "outputPerMillion": 2
1606 + },
1607 + "status": "deprecated",
1608 + "notes": "Dated snapshot of gpt-5-mini. shutdown_date (from GET /v1/models): 2026-12-11. Snapshot gpt-5-mini-2025-08-07 shuts down 2026-12-11 -> gpt-5.6-terra. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1609 + "reasoningEfforts": [
1610 + "minimal",
1611 + "low",
1612 + "medium",
1613 + "high"
1614 + ],
1615 + "defaultReasoningEffort": "medium",
1616 + "apis": [
1617 + "responses",
1618 + "chat",
1619 + "batch"
1620 + ],
1621 + "knowledgeCutoff": "2024-05-31",
1622 + "shutdownDate": "2026-12-11",
1623 + "snapshotOf": "gpt-5-mini"
1624 + },
1625 + {
1626 + "id": "gpt-5-nano",
1627 + "displayName": "GPT-5 nano",
1628 + "family": "gpt-5",
1629 + "contextTokens": 400000,
1630 + "maxOutputTokens": 128000,
1631 + "capabilities": {
1632 + "text": true,
1633 + "vision": true,
1634 + "audioInput": false,
1635 + "audioOutput": false,
1636 + "imageGeneration": true,
1637 + "video": false,
1638 + "reasoning": true,
1639 + "tools": true,
1640 + "structuredOutput": true,
1641 + "streaming": true,
1642 + "files": true,
1643 + "webSearch": true
1644 + },
1645 + "parameters": {
1646 + "temperature": "unsupported",
1647 + "topP": "unsupported",
1648 + "topK": "unsupported",
1649 + "maxTokens": "supported",
1650 + "reasoningEffort": "supported",
1651 + "thinkingBudget": "unsupported",
1652 + "stop": "unsupported",
1653 + "seed": "unsupported",
1654 + "frequencyPenalty": "unsupported",
1655 + "presencePenalty": "unsupported",
1656 + "verbosity": "supported"
1657 + },
1658 + "pricing": {
1659 + "inputPerMillion": 0.05,
1660 + "cachedInputPerMillion": 0.005,
1661 + "outputPerMillion": 0.4
1662 + },
1663 + "status": "active",
1664 + "notes": "Snapshot gpt-5-nano-2025-08-07 shuts down 2026-12-11 -> gpt-5.6-luna. Probe at default effort burned all 200 output tokens on reasoning (status incomplete) -> set effort minimal/low for short answers. Verified by probe: basic (incomplete at 200 tokens). Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1665 + "reasoningEfforts": [
1666 + "minimal",
1667 + "low",
1668 + "medium",
1669 + "high"
1670 + ],
1671 + "defaultReasoningEffort": "medium",
1672 + "apis": [
1673 + "responses",
1674 + "chat",
1675 + "batch"
1676 + ],
1677 + "knowledgeCutoff": "2024-05-31",
1678 + "shutdownDate": null,
1679 + "snapshotOf": null
1680 + },
1681 + {
1682 + "id": "gpt-5-nano-2025-08-07",
1683 + "displayName": "GPT-5 nano (2025-08-07)",
1684 + "family": "gpt-5",
1685 + "contextTokens": 400000,
1686 + "maxOutputTokens": 128000,
1687 + "capabilities": {
1688 + "text": true,
1689 + "vision": true,
1690 + "audioInput": false,
1691 + "audioOutput": false,
1692 + "imageGeneration": true,
1693 + "video": false,
1694 + "reasoning": true,
1695 + "tools": true,
1696 + "structuredOutput": true,
1697 + "streaming": true,
1698 + "files": true,
1699 + "webSearch": true
1700 + },
1701 + "parameters": {
1702 + "temperature": "unsupported",
1703 + "topP": "unsupported",
1704 + "topK": "unsupported",
1705 + "maxTokens": "supported",
1706 + "reasoningEffort": "supported",
1707 + "thinkingBudget": "unsupported",
1708 + "stop": "unsupported",
1709 + "seed": "unsupported",
1710 + "frequencyPenalty": "unsupported",
1711 + "presencePenalty": "unsupported",
1712 + "verbosity": "supported"
1713 + },
1714 + "pricing": {
1715 + "inputPerMillion": 0.05,
1716 + "cachedInputPerMillion": 0.005,
1717 + "outputPerMillion": 0.4
1718 + },
1719 + "status": "deprecated",
1720 + "notes": "Dated snapshot of gpt-5-nano. shutdown_date (from GET /v1/models): 2026-12-11. Snapshot gpt-5-nano-2025-08-07 shuts down 2026-12-11 -> gpt-5.6-luna. Probe at default effort burned all 200 output tokens on reasoning (status incomplete) -> set effort minimal/low for short answers. Verified by probe: basic (incomplete at 200 tokens). Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1721 + "reasoningEfforts": [
1722 + "minimal",
1723 + "low",
1724 + "medium",
1725 + "high"
1726 + ],
1727 + "defaultReasoningEffort": "medium",
1728 + "apis": [
1729 + "responses",
1730 + "chat",
1731 + "batch"
1732 + ],
1733 + "knowledgeCutoff": "2024-05-31",
1734 + "shutdownDate": "2026-12-11",
1735 + "snapshotOf": "gpt-5-nano"
1736 + },
1737 + {
1738 + "id": "gpt-5-pro",
1739 + "displayName": "GPT-5 Pro",
1740 + "family": "gpt-5",
1741 + "contextTokens": 400000,
1742 + "maxOutputTokens": 272000,
1743 + "capabilities": {
1744 + "text": true,
1745 + "vision": true,
1746 + "audioInput": false,
1747 + "audioOutput": false,
1748 + "imageGeneration": true,
1749 + "video": false,
1750 + "reasoning": true,
1751 + "tools": true,
1752 + "structuredOutput": true,
1753 + "streaming": true,
1754 + "files": true,
1755 + "webSearch": true
1756 + },
1757 + "parameters": {
1758 + "temperature": "unsupported",
1759 + "topP": "unsupported",
1760 + "topK": "unsupported",
1761 + "maxTokens": "supported",
1762 + "reasoningEffort": "supported",
1763 + "thinkingBudget": "unsupported",
1764 + "stop": "unsupported",
1765 + "seed": "unsupported",
1766 + "frequencyPenalty": "unsupported",
1767 + "presencePenalty": "unsupported",
1768 + "verbosity": null
1769 + },
1770 + "pricing": {
1771 + "inputPerMillion": 15,
1772 + "cachedInputPerMillion": null,
1773 + "outputPerMillion": 120
1774 + },
1775 + "status": "active",
1776 + "notes": "Only reasoning.effort high. Snapshot gpt-5-pro-2025-10-06 shuts down 2026-12-11 -> gpt-5.6-sol with reasoning.mode pro. Not probed. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1777 + "reasoningEfforts": [
1778 + "high"
1779 + ],
1780 + "defaultReasoningEffort": "high",
1781 + "apis": [
1782 + "responses",
1783 + "batch"
1784 + ],
1785 + "knowledgeCutoff": "2024-09-30",
1786 + "shutdownDate": null,
1787 + "snapshotOf": null
1788 + },
1789 + {
1790 + "id": "gpt-5-pro-2025-10-06",
1791 + "displayName": "GPT-5 Pro (2025-10-06)",
1792 + "family": "gpt-5",
1793 + "contextTokens": 400000,
1794 + "maxOutputTokens": 272000,
1795 + "capabilities": {
1796 + "text": true,
1797 + "vision": true,
1798 + "audioInput": false,
1799 + "audioOutput": false,
1800 + "imageGeneration": true,
1801 + "video": false,
1802 + "reasoning": true,
1803 + "tools": true,
1804 + "structuredOutput": true,
1805 + "streaming": true,
1806 + "files": true,
1807 + "webSearch": true
1808 + },
1809 + "parameters": {
1810 + "temperature": "unsupported",
1811 + "topP": "unsupported",
1812 + "topK": "unsupported",
1813 + "maxTokens": "supported",
1814 + "reasoningEffort": "supported",
1815 + "thinkingBudget": "unsupported",
1816 + "stop": "unsupported",
1817 + "seed": "unsupported",
1818 + "frequencyPenalty": "unsupported",
1819 + "presencePenalty": "unsupported",
1820 + "verbosity": null
1821 + },
1822 + "pricing": {
1823 + "inputPerMillion": 15,
1824 + "cachedInputPerMillion": null,
1825 + "outputPerMillion": 120
1826 + },
1827 + "status": "deprecated",
1828 + "notes": "Dated snapshot of gpt-5-pro. shutdown_date (from GET /v1/models): 2026-12-11. Only reasoning.effort high. Snapshot gpt-5-pro-2025-10-06 shuts down 2026-12-11 -> gpt-5.6-sol with reasoning.mode pro. Not probed. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1829 + "reasoningEfforts": [
1830 + "high"
1831 + ],
1832 + "defaultReasoningEffort": "high",
1833 + "apis": [
1834 + "responses",
1835 + "batch"
1836 + ],
1837 + "knowledgeCutoff": "2024-09-30",
1838 + "shutdownDate": "2026-12-11",
1839 + "snapshotOf": "gpt-5-pro"
1840 + },
1841 + {
1842 + "id": "gpt-5-search-api",
1843 + "displayName": "GPT-5 Search API (Chat Completions web search)",
1844 + "family": "gpt-5",
1845 + "contextTokens": null,
1846 + "maxOutputTokens": null,
1847 + "capabilities": {
1848 + "text": true,
1849 + "vision": true,
1850 + "audioInput": false,
1851 + "audioOutput": false,
1852 + "imageGeneration": false,
1853 + "video": false,
1854 + "reasoning": false,
1855 + "tools": true,
1856 + "structuredOutput": true,
1857 + "streaming": true,
1858 + "files": true,
1859 + "webSearch": true
1860 + },
1861 + "parameters": {
1862 + "temperature": "supported",
1863 + "topP": "supported",
1864 + "topK": "unsupported",
1865 + "maxTokens": "supported",
1866 + "reasoningEffort": "unsupported",
1867 + "thinkingBudget": "unsupported",
1868 + "stop": "conditional",
1869 + "seed": "conditional",
1870 + "frequencyPenalty": "supported",
1871 + "presencePenalty": "supported",
1872 + "verbosity": "unsupported"
1873 + },
1874 + "pricing": {
1875 + "inputPerMillion": null,
1876 + "cachedInputPerMillion": null,
1877 + "outputPerMillion": null
1878 + },
1879 + "status": "preview",
1880 + "notes": "Chat Completions ONLY: Responses returns 400 model_not_found 'not supported with the Responses API' (verified); chat.completions works (verified, resolves gpt-5-search-api-2025-10-14). Model page 404 -> context/pricing unknown. Prefer web_search tool on a normal model. Verified by probe: chat only. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1881 + "reasoningEfforts": null,
1882 + "defaultReasoningEffort": null,
1883 + "apis": [
1884 + "chat"
1885 + ],
1886 + "knowledgeCutoff": null,
1887 + "shutdownDate": null,
1888 + "snapshotOf": null
1889 + },
1890 + {
1891 + "id": "gpt-5-search-api-2025-10-14",
1892 + "displayName": "GPT-5 Search API (Chat Completions web search) (2025-10-14)",
1893 + "family": "gpt-5",
1894 + "contextTokens": null,
1895 + "maxOutputTokens": null,
1896 + "capabilities": {
1897 + "text": true,
1898 + "vision": true,
1899 + "audioInput": false,
1900 + "audioOutput": false,
1901 + "imageGeneration": false,
1902 + "video": false,
1903 + "reasoning": false,
1904 + "tools": true,
1905 + "structuredOutput": true,
1906 + "streaming": true,
1907 + "files": true,
1908 + "webSearch": true
1909 + },
1910 + "parameters": {
1911 + "temperature": "supported",
1912 + "topP": "supported",
1913 + "topK": "unsupported",
1914 + "maxTokens": "supported",
1915 + "reasoningEffort": "unsupported",
1916 + "thinkingBudget": "unsupported",
1917 + "stop": "conditional",
1918 + "seed": "conditional",
1919 + "frequencyPenalty": "supported",
1920 + "presencePenalty": "supported",
1921 + "verbosity": "unsupported"
1922 + },
1923 + "pricing": {
1924 + "inputPerMillion": null,
1925 + "cachedInputPerMillion": null,
1926 + "outputPerMillion": null
1927 + },
1928 + "status": "preview",
1929 + "notes": "Dated snapshot of gpt-5-search-api. Chat Completions ONLY: Responses returns 400 model_not_found 'not supported with the Responses API' (verified); chat.completions works (verified, resolves gpt-5-search-api-2025-10-14). Model page 404 -> context/pricing unknown. Prefer web_search tool on a normal model. Verified by probe: chat only. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1930 + "reasoningEfforts": null,
1931 + "defaultReasoningEffort": null,
1932 + "apis": [
1933 + "chat"
1934 + ],
1935 + "knowledgeCutoff": null,
1936 + "shutdownDate": null,
1937 + "snapshotOf": "gpt-5-search-api"
1938 + },
1939 + {
1940 + "id": "gpt-5.1",
1941 + "displayName": "GPT-5.1",
1942 + "family": "gpt-5.1",
1943 + "contextTokens": 400000,
1944 + "maxOutputTokens": 128000,
1945 + "capabilities": {
1946 + "text": true,
1947 + "vision": true,
1948 + "audioInput": false,
1949 + "audioOutput": false,
1950 + "imageGeneration": true,
1951 + "video": false,
1952 + "reasoning": true,
1953 + "tools": true,
1954 + "structuredOutput": true,
1955 + "streaming": true,
1956 + "files": true,
1957 + "webSearch": true
1958 + },
1959 + "parameters": {
1960 + "temperature": "conditional",
1961 + "topP": "conditional",
1962 + "topK": "unsupported",
1963 + "maxTokens": "supported",
1964 + "reasoningEffort": "supported",
1965 + "thinkingBudget": "unsupported",
1966 + "stop": "unsupported",
1967 + "seed": "unsupported",
1968 + "frequencyPenalty": "conditional",
1969 + "presencePenalty": "conditional",
1970 + "verbosity": "supported"
1971 + },
1972 + "pricing": {
1973 + "inputPerMillion": 1.25,
1974 + "cachedInputPerMillion": 0.125,
1975 + "outputPerMillion": 10
1976 + },
1977 + "status": "active",
1978 + "notes": "Snapshot gpt-5.1-2025-11-13. No xhigh. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
1979 + "reasoningEfforts": [
1980 + "none",
1981 + "low",
1982 + "medium",
1983 + "high"
1984 + ],
1985 + "defaultReasoningEffort": "none",
1986 + "apis": [
1987 + "responses",
1988 + "chat",
1989 + "batch"
1990 + ],
1991 + "knowledgeCutoff": "2024-09-30",
1992 + "shutdownDate": null,
1993 + "snapshotOf": null
1994 + },
1995 + {
1996 + "id": "gpt-5.1-2025-11-13",
1997 + "displayName": "GPT-5.1 (2025-11-13)",
1998 + "family": "gpt-5.1",
1999 + "contextTokens": 400000,
2000 + "maxOutputTokens": 128000,
2001 + "capabilities": {
2002 + "text": true,
2003 + "vision": true,
2004 + "audioInput": false,
2005 + "audioOutput": false,
2006 + "imageGeneration": true,
2007 + "video": false,
2008 + "reasoning": true,
2009 + "tools": true,
2010 + "structuredOutput": true,
2011 + "streaming": true,
2012 + "files": true,
2013 + "webSearch": true
2014 + },
2015 + "parameters": {
2016 + "temperature": "conditional",
2017 + "topP": "conditional",
2018 + "topK": "unsupported",
2019 + "maxTokens": "supported",
2020 + "reasoningEffort": "supported",
2021 + "thinkingBudget": "unsupported",
2022 + "stop": "unsupported",
2023 + "seed": "unsupported",
2024 + "frequencyPenalty": "conditional",
2025 + "presencePenalty": "conditional",
2026 + "verbosity": "supported"
2027 + },
2028 + "pricing": {
2029 + "inputPerMillion": 1.25,
2030 + "cachedInputPerMillion": 0.125,
2031 + "outputPerMillion": 10
2032 + },
2033 + "status": "active",
2034 + "notes": "Dated snapshot of gpt-5.1. Snapshot gpt-5.1-2025-11-13. No xhigh. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2035 + "reasoningEfforts": [
2036 + "none",
2037 + "low",
2038 + "medium",
2039 + "high"
2040 + ],
2041 + "defaultReasoningEffort": "none",
2042 + "apis": [
2043 + "responses",
2044 + "chat",
2045 + "batch"
2046 + ],
2047 + "knowledgeCutoff": "2024-09-30",
2048 + "shutdownDate": null,
2049 + "snapshotOf": "gpt-5.1"
2050 + },
2051 + {
2052 + "id": "gpt-5.1-chat-latest",
2053 + "displayName": "GPT-5.1 Chat",
2054 + "family": "gpt-5.1",
2055 + "contextTokens": 128000,
2056 + "maxOutputTokens": 16384,
2057 + "capabilities": {
2058 + "text": true,
2059 + "vision": true,
2060 + "audioInput": false,
2061 + "audioOutput": false,
2062 + "imageGeneration": true,
2063 + "video": false,
2064 + "reasoning": false,
2065 + "tools": true,
2066 + "structuredOutput": true,
2067 + "streaming": true,
2068 + "files": true,
2069 + "webSearch": true
2070 + },
2071 + "parameters": {
2072 + "temperature": "supported",
2073 + "topP": "supported",
2074 + "topK": "unsupported",
2075 + "maxTokens": "supported",
2076 + "reasoningEffort": "unsupported",
2077 + "thinkingBudget": "unsupported",
2078 + "stop": "conditional",
2079 + "seed": "conditional",
2080 + "frequencyPenalty": "supported",
2081 + "presencePenalty": "supported",
2082 + "verbosity": "unsupported"
2083 + },
2084 + "pricing": {
2085 + "inputPerMillion": 1.25,
2086 + "cachedInputPerMillion": 0.125,
2087 + "outputPerMillion": 10
2088 + },
2089 + "status": "deprecated",
2090 + "notes": "shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23; requests return 404 model_not_found (verified). Verified by probe: basic -> 404. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2091 + "reasoningEfforts": null,
2092 + "defaultReasoningEffort": null,
2093 + "apis": [
2094 + "responses",
2095 + "chat"
2096 + ],
2097 + "knowledgeCutoff": null,
2098 + "shutdownDate": "2026-07-23",
2099 + "snapshotOf": null
2100 + },
2101 + {
2102 + "id": "gpt-5.1-codex",
2103 + "displayName": "GPT-5.1 Codex",
2104 + "family": "gpt-5.1",
2105 + "contextTokens": 400000,
2106 + "maxOutputTokens": 128000,
2107 + "capabilities": {
2108 + "text": true,
2109 + "vision": true,
2110 + "audioInput": false,
2111 + "audioOutput": false,
2112 + "imageGeneration": true,
2113 + "video": false,
2114 + "reasoning": true,
2115 + "tools": true,
2116 + "structuredOutput": true,
2117 + "streaming": true,
2118 + "files": true,
2119 + "webSearch": true
2120 + },
2121 + "parameters": {
2122 + "temperature": "unsupported",
2123 + "topP": "unsupported",
2124 + "topK": "unsupported",
2125 + "maxTokens": "supported",
2126 + "reasoningEffort": "supported",
2127 + "thinkingBudget": "unsupported",
2128 + "stop": "unsupported",
2129 + "seed": "unsupported",
2130 + "frequencyPenalty": "unsupported",
2131 + "presencePenalty": "unsupported",
2132 + "verbosity": "supported"
2133 + },
2134 + "pricing": {
2135 + "inputPerMillion": null,
2136 + "cachedInputPerMillion": null,
2137 + "outputPerMillion": null
2138 + },
2139 + "status": "deprecated",
2140 + "notes": "shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23; 404 model_not_found (verified). Pricing unknown. Verified by probe: basic -> 404. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2141 + "reasoningEfforts": null,
2142 + "defaultReasoningEffort": null,
2143 + "apis": [
2144 + "responses"
2145 + ],
2146 + "knowledgeCutoff": null,
2147 + "shutdownDate": "2026-07-23",
2148 + "snapshotOf": null
2149 + },
2150 + {
2151 + "id": "gpt-5.1-codex-max",
2152 + "displayName": "GPT-5.1 Codex Max",
2153 + "family": "gpt-5.1",
2154 + "contextTokens": null,
2155 + "maxOutputTokens": null,
2156 + "capabilities": {
2157 + "text": true,
2158 + "vision": true,
2159 + "audioInput": false,
2160 + "audioOutput": false,
2161 + "imageGeneration": true,
2162 + "video": false,
2163 + "reasoning": true,
2164 + "tools": true,
2165 + "structuredOutput": true,
2166 + "streaming": true,
2167 + "files": true,
2168 + "webSearch": true
2169 + },
2170 + "parameters": {
2171 + "temperature": "unsupported",
2172 + "topP": "unsupported",
2173 + "topK": "unsupported",
2174 + "maxTokens": "supported",
2175 + "reasoningEffort": "supported",
2176 + "thinkingBudget": "unsupported",
2177 + "stop": "unsupported",
2178 + "seed": "unsupported",
2179 + "frequencyPenalty": "unsupported",
2180 + "presencePenalty": "unsupported",
2181 + "verbosity": "supported"
2182 + },
2183 + "pricing": {
2184 + "inputPerMillion": null,
2185 + "cachedInputPerMillion": null,
2186 + "outputPerMillion": null
2187 + },
2188 + "status": "deprecated",
2189 + "notes": "shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23 (passed). Not probed; context/pricing unknown. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2190 + "reasoningEfforts": null,
2191 + "defaultReasoningEffort": null,
2192 + "apis": [
2193 + "responses"
2194 + ],
2195 + "knowledgeCutoff": null,
2196 + "shutdownDate": "2026-07-23",
2197 + "snapshotOf": null
2198 + },
2199 + {
2200 + "id": "gpt-5.1-codex-mini",
2201 + "displayName": "GPT-5.1 Codex Mini",
2202 + "family": "gpt-5.1",
2203 + "contextTokens": null,
2204 + "maxOutputTokens": null,
2205 + "capabilities": {
2206 + "text": true,
2207 + "vision": true,
2208 + "audioInput": false,
2209 + "audioOutput": false,
2210 + "imageGeneration": true,
2211 + "video": false,
2212 + "reasoning": true,
2213 + "tools": true,
2214 + "structuredOutput": true,
2215 + "streaming": true,
2216 + "files": true,
2217 + "webSearch": true
2218 + },
2219 + "parameters": {
2220 + "temperature": "unsupported",
2221 + "topP": "unsupported",
2222 + "topK": "unsupported",
2223 + "maxTokens": "supported",
2224 + "reasoningEffort": "supported",
2225 + "thinkingBudget": "unsupported",
2226 + "stop": "unsupported",
2227 + "seed": "unsupported",
2228 + "frequencyPenalty": "unsupported",
2229 + "presencePenalty": "unsupported",
2230 + "verbosity": "supported"
2231 + },
2232 + "pricing": {
2233 + "inputPerMillion": null,
2234 + "cachedInputPerMillion": null,
2235 + "outputPerMillion": null
2236 + },
2237 + "status": "deprecated",
2238 + "notes": "shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23 (passed). Not probed; context/pricing unknown. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2239 + "reasoningEfforts": null,
2240 + "defaultReasoningEffort": null,
2241 + "apis": [
2242 + "responses"
2243 + ],
2244 + "knowledgeCutoff": null,
2245 + "shutdownDate": "2026-07-23",
2246 + "snapshotOf": null
2247 + },
2248 + {
2249 + "id": "gpt-5.2",
2250 + "displayName": "GPT-5.2",
2251 + "family": "gpt-5.2",
2252 + "contextTokens": 400000,
2253 + "maxOutputTokens": 128000,
2254 + "capabilities": {
2255 + "text": true,
2256 + "vision": true,
2257 + "audioInput": false,
2258 + "audioOutput": false,
2259 + "imageGeneration": true,
2260 + "video": false,
2261 + "reasoning": true,
2262 + "tools": true,
2263 + "structuredOutput": true,
2264 + "streaming": true,
2265 + "files": true,
2266 + "webSearch": true
2267 + },
2268 + "parameters": {
2269 + "temperature": "conditional",
2270 + "topP": "conditional",
2271 + "topK": "unsupported",
2272 + "maxTokens": "supported",
2273 + "reasoningEffort": "supported",
2274 + "thinkingBudget": "unsupported",
2275 + "stop": "unsupported",
2276 + "seed": "unsupported",
2277 + "frequencyPenalty": "conditional",
2278 + "presencePenalty": "conditional",
2279 + "verbosity": "supported"
2280 + },
2281 + "pricing": {
2282 + "inputPerMillion": 1.75,
2283 + "cachedInputPerMillion": 0.175,
2284 + "outputPerMillion": 14
2285 + },
2286 + "status": "active",
2287 + "notes": "Snapshot gpt-5.2-2025-12-11. Docs recommend GPT-6 Astra instead. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2288 + "reasoningEfforts": [
2289 + "none",
2290 + "low",
2291 + "medium",
2292 + "high",
2293 + "xhigh"
2294 + ],
2295 + "defaultReasoningEffort": "none",
2296 + "apis": [
2297 + "responses",
2298 + "chat",
2299 + "batch"
2300 + ],
2301 + "knowledgeCutoff": "2025-08-31",
2302 + "shutdownDate": null,
2303 + "snapshotOf": null
2304 + },
2305 + {
2306 + "id": "gpt-5.2-2025-12-11",
2307 + "displayName": "GPT-5.2 (2025-12-11)",
2308 + "family": "gpt-5.2",
2309 + "contextTokens": 400000,
2310 + "maxOutputTokens": 128000,
2311 + "capabilities": {
2312 + "text": true,
2313 + "vision": true,
2314 + "audioInput": false,
2315 + "audioOutput": false,
2316 + "imageGeneration": true,
2317 + "video": false,
2318 + "reasoning": true,
2319 + "tools": true,
2320 + "structuredOutput": true,
2321 + "streaming": true,
2322 + "files": true,
2323 + "webSearch": true
2324 + },
2325 + "parameters": {
2326 + "temperature": "conditional",
2327 + "topP": "conditional",
2328 + "topK": "unsupported",
2329 + "maxTokens": "supported",
2330 + "reasoningEffort": "supported",
2331 + "thinkingBudget": "unsupported",
2332 + "stop": "unsupported",
2333 + "seed": "unsupported",
2334 + "frequencyPenalty": "conditional",
2335 + "presencePenalty": "conditional",
2336 + "verbosity": "supported"
2337 + },
2338 + "pricing": {
2339 + "inputPerMillion": 1.75,
2340 + "cachedInputPerMillion": 0.175,
2341 + "outputPerMillion": 14
2342 + },
2343 + "status": "active",
2344 + "notes": "Dated snapshot of gpt-5.2. Snapshot gpt-5.2-2025-12-11. Docs recommend GPT-6 Astra instead. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2345 + "reasoningEfforts": [
2346 + "none",
2347 + "low",
2348 + "medium",
2349 + "high",
2350 + "xhigh"
2351 + ],
2352 + "defaultReasoningEffort": "none",
2353 + "apis": [
2354 + "responses",
2355 + "chat",
2356 + "batch"
2357 + ],
2358 + "knowledgeCutoff": "2025-08-31",
2359 + "shutdownDate": null,
2360 + "snapshotOf": "gpt-5.2"
2361 + },
2362 + {
2363 + "id": "gpt-5.2-chat-latest",
2364 + "displayName": "GPT-5.2 Chat",
2365 + "family": "gpt-5.2",
2366 + "contextTokens": 128000,
2367 + "maxOutputTokens": 16384,
2368 + "capabilities": {
2369 + "text": true,
2370 + "vision": true,
2371 + "audioInput": false,
2372 + "audioOutput": false,
2373 + "imageGeneration": true,
2374 + "video": false,
2375 + "reasoning": false,
2376 + "tools": true,
2377 + "structuredOutput": true,
2378 + "streaming": true,
2379 + "files": true,
2380 + "webSearch": true
2381 + },
2382 + "parameters": {
2383 + "temperature": "supported",
2384 + "topP": "supported",
2385 + "topK": "unsupported",
2386 + "maxTokens": "supported",
2387 + "reasoningEffort": "unsupported",
2388 + "thinkingBudget": "unsupported",
2389 + "stop": "conditional",
2390 + "seed": "conditional",
2391 + "frequencyPenalty": "supported",
2392 + "presencePenalty": "supported",
2393 + "verbosity": "unsupported"
2394 + },
2395 + "pricing": {
2396 + "inputPerMillion": 1.75,
2397 + "cachedInputPerMillion": 0.175,
2398 + "outputPerMillion": 14
2399 + },
2400 + "status": "deprecated",
2401 + "notes": "shutdown_date (from GET /v1/models): 2026-08-10 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-08-10; requests return 404 model_not_found (verified). Verified by probe: basic -> 404. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2402 + "reasoningEfforts": null,
2403 + "defaultReasoningEffort": null,
2404 + "apis": [
2405 + "responses",
2406 + "chat"
2407 + ],
2408 + "knowledgeCutoff": "2025-08-31",
2409 + "shutdownDate": "2026-08-10",
2410 + "snapshotOf": null
2411 + },
2412 + {
2413 + "id": "gpt-5.2-codex",
2414 + "displayName": "GPT-5.2 Codex",
2415 + "family": "gpt-5.2",
2416 + "contextTokens": 400000,
2417 + "maxOutputTokens": 128000,
2418 + "capabilities": {
2419 + "text": true,
2420 + "vision": true,
2421 + "audioInput": false,
2422 + "audioOutput": false,
2423 + "imageGeneration": true,
2424 + "video": false,
2425 + "reasoning": true,
2426 + "tools": true,
2427 + "structuredOutput": true,
2428 + "streaming": true,
2429 + "files": true,
2430 + "webSearch": true
2431 + },
2432 + "parameters": {
2433 + "temperature": "unsupported",
2434 + "topP": "unsupported",
2435 + "topK": "unsupported",
2436 + "maxTokens": "supported",
2437 + "reasoningEffort": "supported",
2438 + "thinkingBudget": "unsupported",
2439 + "stop": "unsupported",
2440 + "seed": "unsupported",
2441 + "frequencyPenalty": "unsupported",
2442 + "presencePenalty": "unsupported",
2443 + "verbosity": "supported"
2444 + },
2445 + "pricing": {
2446 + "inputPerMillion": null,
2447 + "cachedInputPerMillion": null,
2448 + "outputPerMillion": null
2449 + },
2450 + "status": "deprecated",
2451 + "notes": "shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23 (passed). Not probed; siblings gpt-5-codex/gpt-5.1-codex return 404. Pricing unknown (page not fetched). Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2452 + "reasoningEfforts": null,
2453 + "defaultReasoningEffort": null,
2454 + "apis": [
2455 + "responses"
2456 + ],
2457 + "knowledgeCutoff": null,
2458 + "shutdownDate": "2026-07-23",
2459 + "snapshotOf": null
2460 + },
2461 + {
2462 + "id": "gpt-5.2-pro",
2463 + "displayName": "GPT-5.2 Pro",
2464 + "family": "gpt-5.2",
2465 + "contextTokens": 400000,
2466 + "maxOutputTokens": 128000,
2467 + "capabilities": {
2468 + "text": true,
2469 + "vision": true,
2470 + "audioInput": false,
2471 + "audioOutput": false,
2472 + "imageGeneration": true,
2473 + "video": false,
2474 + "reasoning": true,
2475 + "tools": true,
2476 + "structuredOutput": null,
2477 + "streaming": true,
2478 + "files": true,
2479 + "webSearch": true
2480 + },
2481 + "parameters": {
2482 + "temperature": "unsupported",
2483 + "topP": "unsupported",
2484 + "topK": "unsupported",
2485 + "maxTokens": "supported",
2486 + "reasoningEffort": "supported",
2487 + "thinkingBudget": "unsupported",
2488 + "stop": "unsupported",
2489 + "seed": "unsupported",
2490 + "frequencyPenalty": "unsupported",
2491 + "presencePenalty": "unsupported",
2492 + "verbosity": "supported"
2493 + },
2494 + "pricing": {
2495 + "inputPerMillion": 21,
2496 + "cachedInputPerMillion": null,
2497 + "outputPerMillion": 168
2498 + },
2499 + "status": "active",
2500 + "notes": "Responses API only; docs recommend GPT-5.5 Pro. Not probed. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2501 + "reasoningEfforts": [
2502 + "medium",
2503 + "high",
2504 + "xhigh"
2505 + ],
2506 + "defaultReasoningEffort": "medium",
2507 + "apis": [
2508 + "responses"
2509 + ],
2510 + "knowledgeCutoff": "2025-08-31",
2511 + "shutdownDate": null,
2512 + "snapshotOf": null
2513 + },
2514 + {
2515 + "id": "gpt-5.2-pro-2025-12-11",
2516 + "displayName": "GPT-5.2 Pro (2025-12-11)",
2517 + "family": "gpt-5.2",
2518 + "contextTokens": 400000,
2519 + "maxOutputTokens": 128000,
2520 + "capabilities": {
2521 + "text": true,
2522 + "vision": true,
2523 + "audioInput": false,
2524 + "audioOutput": false,
2525 + "imageGeneration": true,
2526 + "video": false,
2527 + "reasoning": true,
2528 + "tools": true,
2529 + "structuredOutput": null,
2530 + "streaming": true,
2531 + "files": true,
2532 + "webSearch": true
2533 + },
2534 + "parameters": {
2535 + "temperature": "unsupported",
2536 + "topP": "unsupported",
2537 + "topK": "unsupported",
2538 + "maxTokens": "supported",
2539 + "reasoningEffort": "supported",
2540 + "thinkingBudget": "unsupported",
2541 + "stop": "unsupported",
2542 + "seed": "unsupported",
2543 + "frequencyPenalty": "unsupported",
2544 + "presencePenalty": "unsupported",
2545 + "verbosity": "supported"
2546 + },
2547 + "pricing": {
2548 + "inputPerMillion": 21,
2549 + "cachedInputPerMillion": null,
2550 + "outputPerMillion": 168
2551 + },
2552 + "status": "active",
2553 + "notes": "Dated snapshot of gpt-5.2-pro. Responses API only; docs recommend GPT-5.5 Pro. Not probed. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2554 + "reasoningEfforts": [
2555 + "medium",
2556 + "high",
2557 + "xhigh"
2558 + ],
2559 + "defaultReasoningEffort": "medium",
2560 + "apis": [
2561 + "responses"
2562 + ],
2563 + "knowledgeCutoff": "2025-08-31",
2564 + "shutdownDate": null,
2565 + "snapshotOf": "gpt-5.2-pro"
2566 + },
2567 + {
2568 + "id": "gpt-5.3-chat-latest",
2569 + "displayName": "GPT-5.3 Chat (ChatGPT Instant)",
2570 + "family": "gpt-5.3",
2571 + "contextTokens": 128000,
2572 + "maxOutputTokens": 16384,
2573 + "capabilities": {
2574 + "text": true,
2575 + "vision": true,
2576 + "audioInput": false,
2577 + "audioOutput": false,
2578 + "imageGeneration": true,
2579 + "video": false,
2580 + "reasoning": false,
2581 + "tools": true,
2582 + "structuredOutput": true,
2583 + "streaming": true,
2584 + "files": true,
2585 + "webSearch": true
2586 + },
2587 + "parameters": {
2588 + "temperature": null,
2589 + "topP": null,
2590 + "topK": "unsupported",
2591 + "maxTokens": "supported",
2592 + "reasoningEffort": "unsupported",
2593 + "thinkingBudget": "unsupported",
2594 + "stop": "conditional",
2595 + "seed": "conditional",
2596 + "frequencyPenalty": null,
2597 + "presencePenalty": null,
2598 + "verbosity": null
2599 + },
2600 + "pricing": {
2601 + "inputPerMillion": 1.75,
2602 + "cachedInputPerMillion": 0.175,
2603 + "outputPerMillion": 14
2604 + },
2605 + "status": "deprecated",
2606 + "notes": "shutdown_date (from GET /v1/models): 2026-08-10 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. Listed by GET /v1/models with shutdown_date 2026-08-10 but requests return 404 model_not_found (verified). Docs: 'This model has been deprecated. We recommend GPT-6 Astra'. Use chat-latest instead. Verified by probe: basic -> 404. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2607 + "reasoningEfforts": null,
2608 + "defaultReasoningEffort": null,
2609 + "apis": [
2610 + "responses",
2611 + "chat"
2612 + ],
2613 + "knowledgeCutoff": "2025-08-31",
2614 + "shutdownDate": "2026-08-10",
2615 + "snapshotOf": null
2616 + },
2617 + {
2618 + "id": "gpt-5.3-codex",
2619 + "displayName": "GPT-5.3 Codex",
2620 + "family": "gpt-5.3",
2621 + "contextTokens": 400000,
2622 + "maxOutputTokens": 128000,
2623 + "capabilities": {
2624 + "text": true,
2625 + "vision": true,
2626 + "audioInput": false,
2627 + "audioOutput": false,
2628 + "imageGeneration": true,
2629 + "video": false,
2630 + "reasoning": true,
2631 + "tools": true,
2632 + "structuredOutput": true,
2633 + "streaming": true,
2634 + "files": true,
2635 + "webSearch": true
2636 + },
2637 + "parameters": {
2638 + "temperature": null,
2639 + "topP": null,
2640 + "topK": "unsupported",
2641 + "maxTokens": "supported",
2642 + "reasoningEffort": "supported",
2643 + "thinkingBudget": "unsupported",
2644 + "stop": "unsupported",
2645 + "seed": "unsupported",
2646 + "frequencyPenalty": null,
2647 + "presencePenalty": null,
2648 + "verbosity": "supported"
2649 + },
2650 + "pricing": {
2651 + "inputPerMillion": 1.75,
2652 + "cachedInputPerMillion": 0.175,
2653 + "outputPerMillion": 14
2654 + },
2655 + "status": "active",
2656 + "notes": "Agentic-coding model, Responses API only. Probe echoed reasoning.effort 'none' as default although docs list low..xhigh. Not a general chat model. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2657 + "reasoningEfforts": [
2658 + "low",
2659 + "medium",
2660 + "high",
2661 + "xhigh"
2662 + ],
2663 + "defaultReasoningEffort": "none",
2664 + "apis": [
2665 + "responses"
2666 + ],
2667 + "knowledgeCutoff": "2025-08-31",
2668 + "shutdownDate": null,
2669 + "snapshotOf": null
2670 + },
2671 + {
2672 + "id": "gpt-5.4",
2673 + "displayName": "GPT-5.4",
2674 + "family": "gpt-5.4",
2675 + "contextTokens": 1050000,
2676 + "maxOutputTokens": 128000,
2677 + "capabilities": {
2678 + "text": true,
2679 + "vision": true,
2680 + "audioInput": false,
2681 + "audioOutput": false,
2682 + "imageGeneration": true,
2683 + "video": false,
2684 + "reasoning": true,
2685 + "tools": true,
2686 + "structuredOutput": true,
2687 + "streaming": true,
2688 + "files": true,
2689 + "webSearch": true
2690 + },
2691 + "parameters": {
2692 + "temperature": "conditional",
2693 + "topP": "conditional",
2694 + "topK": "unsupported",
2695 + "maxTokens": "supported",
2696 + "reasoningEffort": "supported",
2697 + "thinkingBudget": "unsupported",
2698 + "stop": "unsupported",
2699 + "seed": "unsupported",
2700 + "frequencyPenalty": "conditional",
2701 + "presencePenalty": "conditional",
2702 + "verbosity": "supported"
2703 + },
2704 + "pricing": {
2705 + "inputPerMillion": 2.5,
2706 + "cachedInputPerMillion": 0.25,
2707 + "outputPerMillion": 15
2708 + },
2709 + "status": "active",
2710 + "notes": "Snapshot gpt-5.4-2026-03-05. Default effort 'none' (verified echo) so sampling params work by default; assumed rejected once effort >= low (pattern verified on gpt-5.5/5.6). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2711 + "reasoningEfforts": [
2712 + "none",
2713 + "low",
2714 + "medium",
2715 + "high",
2716 + "xhigh"
2717 + ],
2718 + "defaultReasoningEffort": "none",
2719 + "apis": [
2720 + "responses",
2721 + "chat",
2722 + "batch"
2723 + ],
2724 + "knowledgeCutoff": "2025-08-31",
2725 + "shutdownDate": null,
2726 + "snapshotOf": null
2727 + },
2728 + {
2729 + "id": "gpt-5.4-2026-03-05",
2730 + "displayName": "GPT-5.4 (2026-03-05)",
2731 + "family": "gpt-5.4",
2732 + "contextTokens": 1050000,
2733 + "maxOutputTokens": 128000,
2734 + "capabilities": {
2735 + "text": true,
2736 + "vision": true,
2737 + "audioInput": false,
2738 + "audioOutput": false,
2739 + "imageGeneration": true,
2740 + "video": false,
2741 + "reasoning": true,
2742 + "tools": true,
2743 + "structuredOutput": true,
2744 + "streaming": true,
2745 + "files": true,
2746 + "webSearch": true
2747 + },
2748 + "parameters": {
2749 + "temperature": "conditional",
2750 + "topP": "conditional",
2751 + "topK": "unsupported",
2752 + "maxTokens": "supported",
2753 + "reasoningEffort": "supported",
2754 + "thinkingBudget": "unsupported",
2755 + "stop": "unsupported",
2756 + "seed": "unsupported",
2757 + "frequencyPenalty": "conditional",
2758 + "presencePenalty": "conditional",
2759 + "verbosity": "supported"
2760 + },
2761 + "pricing": {
2762 + "inputPerMillion": 2.5,
2763 + "cachedInputPerMillion": 0.25,
2764 + "outputPerMillion": 15
2765 + },
2766 + "status": "active",
2767 + "notes": "Dated snapshot of gpt-5.4. Snapshot gpt-5.4-2026-03-05. Default effort 'none' (verified echo) so sampling params work by default; assumed rejected once effort >= low (pattern verified on gpt-5.5/5.6). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2768 + "reasoningEfforts": [
2769 + "none",
2770 + "low",
2771 + "medium",
2772 + "high",
2773 + "xhigh"
2774 + ],
2775 + "defaultReasoningEffort": "none",
2776 + "apis": [
2777 + "responses",
2778 + "chat",
2779 + "batch"
2780 + ],
2781 + "knowledgeCutoff": "2025-08-31",
2782 + "shutdownDate": null,
2783 + "snapshotOf": "gpt-5.4"
2784 + },
2785 + {
2786 + "id": "gpt-5.4-mini",
2787 + "displayName": "GPT-5.4 mini",
2788 + "family": "gpt-5.4",
2789 + "contextTokens": 400000,
2790 + "maxOutputTokens": 128000,
2791 + "capabilities": {
2792 + "text": true,
2793 + "vision": true,
2794 + "audioInput": false,
2795 + "audioOutput": false,
2796 + "imageGeneration": true,
2797 + "video": false,
2798 + "reasoning": true,
2799 + "tools": true,
2800 + "structuredOutput": true,
2801 + "streaming": true,
2802 + "files": true,
2803 + "webSearch": true
2804 + },
2805 + "parameters": {
2806 + "temperature": "conditional",
2807 + "topP": "conditional",
2808 + "topK": "unsupported",
2809 + "maxTokens": "supported",
2810 + "reasoningEffort": "supported",
2811 + "thinkingBudget": "unsupported",
2812 + "stop": "unsupported",
2813 + "seed": "unsupported",
2814 + "frequencyPenalty": "conditional",
2815 + "presencePenalty": "conditional",
2816 + "verbosity": "supported"
2817 + },
2818 + "pricing": {
2819 + "inputPerMillion": 0.75,
2820 + "cachedInputPerMillion": 0.075,
2821 + "outputPerMillion": 4.5
2822 + },
2823 + "status": "active",
2824 + "notes": "Snapshot gpt-5.4-mini-2026-03-17. Default effort 'none': temperature, top_p, frequency_penalty, presence_penalty, logprobs all ACCEPTED at default (verified). 'minimal'/'max' rejected. PDF input (input_file file_data) verified. previous_response_id verified. service_tier 'flex' accepted. Verified by probe: basic, stream, params, tools(+previous_response_id), structured, vision, web_search, pdf, flex. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2825 + "reasoningEfforts": [
2826 + "none",
2827 + "low",
2828 + "medium",
2829 + "high",
2830 + "xhigh"
2831 + ],
2832 + "defaultReasoningEffort": "none",
2833 + "apis": [
2834 + "responses",
2835 + "chat",
2836 + "batch"
2837 + ],
2838 + "knowledgeCutoff": "2025-08-31",
2839 + "shutdownDate": null,
2840 + "snapshotOf": null
2841 + },
2842 + {
2843 + "id": "gpt-5.4-mini-2026-03-17",
2844 + "displayName": "GPT-5.4 mini (2026-03-17)",
2845 + "family": "gpt-5.4",
2846 + "contextTokens": 400000,
2847 + "maxOutputTokens": 128000,
2848 + "capabilities": {
2849 + "text": true,
2850 + "vision": true,
2851 + "audioInput": false,
2852 + "audioOutput": false,
2853 + "imageGeneration": true,
2854 + "video": false,
2855 + "reasoning": true,
2856 + "tools": true,
2857 + "structuredOutput": true,
2858 + "streaming": true,
2859 + "files": true,
2860 + "webSearch": true
2861 + },
2862 + "parameters": {
2863 + "temperature": "conditional",
2864 + "topP": "conditional",
2865 + "topK": "unsupported",
2866 + "maxTokens": "supported",
2867 + "reasoningEffort": "supported",
2868 + "thinkingBudget": "unsupported",
2869 + "stop": "unsupported",
2870 + "seed": "unsupported",
2871 + "frequencyPenalty": "conditional",
2872 + "presencePenalty": "conditional",
2873 + "verbosity": "supported"
2874 + },
2875 + "pricing": {
2876 + "inputPerMillion": 0.75,
2877 + "cachedInputPerMillion": 0.075,
2878 + "outputPerMillion": 4.5
2879 + },
2880 + "status": "active",
2881 + "notes": "Dated snapshot of gpt-5.4-mini. Snapshot gpt-5.4-mini-2026-03-17. Default effort 'none': temperature, top_p, frequency_penalty, presence_penalty, logprobs all ACCEPTED at default (verified). 'minimal'/'max' rejected. PDF input (input_file file_data) verified. previous_response_id verified. service_tier 'flex' accepted. Verified by probe: basic, stream, params, tools(+previous_response_id), structured, vision, web_search, pdf, flex. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2882 + "reasoningEfforts": [
2883 + "none",
2884 + "low",
2885 + "medium",
2886 + "high",
2887 + "xhigh"
2888 + ],
2889 + "defaultReasoningEffort": "none",
2890 + "apis": [
2891 + "responses",
2892 + "chat",
2893 + "batch"
2894 + ],
2895 + "knowledgeCutoff": "2025-08-31",
2896 + "shutdownDate": null,
2897 + "snapshotOf": "gpt-5.4-mini"
2898 + },
2899 + {
2900 + "id": "gpt-5.4-nano",
2901 + "displayName": "GPT-5.4 nano",
2902 + "family": "gpt-5.4",
2903 + "contextTokens": 400000,
2904 + "maxOutputTokens": 128000,
2905 + "capabilities": {
2906 + "text": true,
2907 + "vision": true,
2908 + "audioInput": false,
2909 + "audioOutput": false,
2910 + "imageGeneration": true,
2911 + "video": false,
2912 + "reasoning": true,
2913 + "tools": true,
2914 + "structuredOutput": true,
2915 + "streaming": true,
2916 + "files": true,
2917 + "webSearch": true
2918 + },
2919 + "parameters": {
2920 + "temperature": "conditional",
2921 + "topP": "conditional",
2922 + "topK": "unsupported",
2923 + "maxTokens": "supported",
2924 + "reasoningEffort": "supported",
2925 + "thinkingBudget": "unsupported",
2926 + "stop": "unsupported",
2927 + "seed": "unsupported",
2928 + "frequencyPenalty": "conditional",
2929 + "presencePenalty": "conditional",
2930 + "verbosity": "supported"
2931 + },
2932 + "pricing": {
2933 + "inputPerMillion": 0.2,
2934 + "cachedInputPerMillion": 0.02,
2935 + "outputPerMillion": 1.25
2936 + },
2937 + "status": "active",
2938 + "notes": "Snapshot gpt-5.4-nano-2026-03-17. Model page lists web_search among tools but computer use/tool_search absent. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2939 + "reasoningEfforts": [
2940 + "none",
2941 + "low",
2942 + "medium",
2943 + "high",
2944 + "xhigh"
2945 + ],
2946 + "defaultReasoningEffort": "none",
2947 + "apis": [
2948 + "responses",
2949 + "chat",
2950 + "batch"
2951 + ],
2952 + "knowledgeCutoff": "2025-08-31",
2953 + "shutdownDate": null,
2954 + "snapshotOf": null
2955 + },
2956 + {
2957 + "id": "gpt-5.4-nano-2026-03-17",
2958 + "displayName": "GPT-5.4 nano (2026-03-17)",
2959 + "family": "gpt-5.4",
2960 + "contextTokens": 400000,
2961 + "maxOutputTokens": 128000,
2962 + "capabilities": {
2963 + "text": true,
2964 + "vision": true,
2965 + "audioInput": false,
2966 + "audioOutput": false,
2967 + "imageGeneration": true,
2968 + "video": false,
2969 + "reasoning": true,
2970 + "tools": true,
2971 + "structuredOutput": true,
2972 + "streaming": true,
2973 + "files": true,
2974 + "webSearch": true
2975 + },
2976 + "parameters": {
2977 + "temperature": "conditional",
2978 + "topP": "conditional",
2979 + "topK": "unsupported",
2980 + "maxTokens": "supported",
2981 + "reasoningEffort": "supported",
2982 + "thinkingBudget": "unsupported",
2983 + "stop": "unsupported",
2984 + "seed": "unsupported",
2985 + "frequencyPenalty": "conditional",
2986 + "presencePenalty": "conditional",
2987 + "verbosity": "supported"
2988 + },
2989 + "pricing": {
2990 + "inputPerMillion": 0.2,
2991 + "cachedInputPerMillion": 0.02,
2992 + "outputPerMillion": 1.25
2993 + },
2994 + "status": "active",
2995 + "notes": "Dated snapshot of gpt-5.4-nano. Snapshot gpt-5.4-nano-2026-03-17. Model page lists web_search among tools but computer use/tool_search absent. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
2996 + "reasoningEfforts": [
2997 + "none",
2998 + "low",
2999 + "medium",
3000 + "high",
3001 + "xhigh"
3002 + ],
3003 + "defaultReasoningEffort": "none",
3004 + "apis": [
3005 + "responses",
3006 + "chat",
3007 + "batch"
3008 + ],
3009 + "knowledgeCutoff": "2025-08-31",
3010 + "shutdownDate": null,
3011 + "snapshotOf": "gpt-5.4-nano"
3012 + },
3013 + {
3014 + "id": "gpt-5.4-pro",
3015 + "displayName": "GPT-5.4 Pro",
3016 + "family": "gpt-5.4",
3017 + "contextTokens": 1050000,
3018 + "maxOutputTokens": 128000,
3019 + "capabilities": {
3020 + "text": true,
3021 + "vision": true,
3022 + "audioInput": false,
3023 + "audioOutput": false,
3024 + "imageGeneration": true,
3025 + "video": false,
3026 + "reasoning": true,
3027 + "tools": true,
3028 + "structuredOutput": null,
3029 + "streaming": true,
3030 + "files": true,
3031 + "webSearch": true
3032 + },
3033 + "parameters": {
3034 + "temperature": "unsupported",
3035 + "topP": "unsupported",
3036 + "topK": "unsupported",
3037 + "maxTokens": "supported",
3038 + "reasoningEffort": "supported",
3039 + "thinkingBudget": "unsupported",
3040 + "stop": "unsupported",
3041 + "seed": "unsupported",
3042 + "frequencyPenalty": "unsupported",
3043 + "presencePenalty": "unsupported",
3044 + "verbosity": "supported"
3045 + },
3046 + "pricing": {
3047 + "inputPerMillion": 30,
3048 + "cachedInputPerMillion": null,
3049 + "outputPerMillion": 180
3050 + },
3051 + "status": "active",
3052 + "notes": "Responses API only. Not probed (cost). Docs: no structured outputs listed for pro variants of 5.4? (page lists function calling, web search, MCP; structured outputs not listed) -> structuredOutput null. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3053 + "reasoningEfforts": [
3054 + "medium",
3055 + "high",
3056 + "xhigh"
3057 + ],
3058 + "defaultReasoningEffort": "medium",
3059 + "apis": [
3060 + "responses"
3061 + ],
3062 + "knowledgeCutoff": "2025-08-31",
3063 + "shutdownDate": null,
3064 + "snapshotOf": null
3065 + },
3066 + {
3067 + "id": "gpt-5.4-pro-2026-03-05",
3068 + "displayName": "GPT-5.4 Pro (2026-03-05)",
3069 + "family": "gpt-5.4",
3070 + "contextTokens": 1050000,
3071 + "maxOutputTokens": 128000,
3072 + "capabilities": {
3073 + "text": true,
3074 + "vision": true,
3075 + "audioInput": false,
3076 + "audioOutput": false,
3077 + "imageGeneration": true,
3078 + "video": false,
3079 + "reasoning": true,
3080 + "tools": true,
3081 + "structuredOutput": null,
3082 + "streaming": true,
3083 + "files": true,
3084 + "webSearch": true
3085 + },
3086 + "parameters": {
3087 + "temperature": "unsupported",
3088 + "topP": "unsupported",
3089 + "topK": "unsupported",
3090 + "maxTokens": "supported",
3091 + "reasoningEffort": "supported",
3092 + "thinkingBudget": "unsupported",
3093 + "stop": "unsupported",
3094 + "seed": "unsupported",
3095 + "frequencyPenalty": "unsupported",
3096 + "presencePenalty": "unsupported",
3097 + "verbosity": "supported"
3098 + },
3099 + "pricing": {
3100 + "inputPerMillion": 30,
3101 + "cachedInputPerMillion": null,
3102 + "outputPerMillion": 180
3103 + },
3104 + "status": "active",
3105 + "notes": "Dated snapshot of gpt-5.4-pro. Responses API only. Not probed (cost). Docs: no structured outputs listed for pro variants of 5.4? (page lists function calling, web search, MCP; structured outputs not listed) -> structuredOutput null. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3106 + "reasoningEfforts": [
3107 + "medium",
3108 + "high",
3109 + "xhigh"
3110 + ],
3111 + "defaultReasoningEffort": "medium",
3112 + "apis": [
3113 + "responses"
3114 + ],
3115 + "knowledgeCutoff": "2025-08-31",
3116 + "shutdownDate": null,
3117 + "snapshotOf": "gpt-5.4-pro"
3118 + },
3119 + {
3120 + "id": "gpt-5.5",
3121 + "displayName": "GPT-5.5",
3122 + "family": "gpt-5.5",
3123 + "contextTokens": 1050000,
3124 + "maxOutputTokens": 128000,
3125 + "capabilities": {
3126 + "text": true,
3127 + "vision": true,
3128 + "audioInput": false,
3129 + "audioOutput": false,
3130 + "imageGeneration": true,
3131 + "video": false,
3132 + "reasoning": true,
3133 + "tools": true,
3134 + "structuredOutput": true,
3135 + "streaming": true,
3136 + "files": true,
3137 + "webSearch": true
3138 + },
3139 + "parameters": {
3140 + "temperature": "conditional",
3141 + "topP": "conditional",
3142 + "topK": "unsupported",
3143 + "maxTokens": "supported",
3144 + "reasoningEffort": "supported",
3145 + "thinkingBudget": "unsupported",
3146 + "stop": "unsupported",
3147 + "seed": "unsupported",
3148 + "frequencyPenalty": "conditional",
3149 + "presencePenalty": "conditional",
3150 + "verbosity": "supported"
3151 + },
3152 + "pricing": {
3153 + "inputPerMillion": 5,
3154 + "cachedInputPerMillion": 0.5,
3155 + "outputPerMillion": 30
3156 + },
3157 + "status": "active",
3158 + "notes": "Snapshot gpt-5.5-2026-04-23. 'minimal' and 'max' efforts rejected (400 unsupported_value). temperature/top_p/penalties rejected unless reasoning.effort='none' (verified both ways). >272K input tokens billed 2x/1.5x. Default top_p echoed as 0.98. Chat Completions: temperature other than 1 rejected ('Only the default (1) value is supported'). Verified by probe: basic, stream, params, tools(+round trip), structured, vision(effort none), web_search (url_citation annotations), encrypted reasoning round trip, chat completions. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3159 + "reasoningEfforts": [
3160 + "none",
3161 + "low",
3162 + "medium",
3163 + "high",
3164 + "xhigh"
3165 + ],
3166 + "defaultReasoningEffort": "medium",
3167 + "apis": [
3168 + "responses",
3169 + "chat",
3170 + "batch"
3171 + ],
3172 + "knowledgeCutoff": "2025-12-01",
3173 + "shutdownDate": null,
3174 + "snapshotOf": null
3175 + },
3176 + {
3177 + "id": "gpt-5.5-2026-04-23",
3178 + "displayName": "GPT-5.5 (2026-04-23)",
3179 + "family": "gpt-5.5",
3180 + "contextTokens": 1050000,
3181 + "maxOutputTokens": 128000,
3182 + "capabilities": {
3183 + "text": true,
3184 + "vision": true,
3185 + "audioInput": false,
3186 + "audioOutput": false,
3187 + "imageGeneration": true,
3188 + "video": false,
3189 + "reasoning": true,
3190 + "tools": true,
3191 + "structuredOutput": true,
3192 + "streaming": true,
3193 + "files": true,
3194 + "webSearch": true
3195 + },
3196 + "parameters": {
3197 + "temperature": "conditional",
3198 + "topP": "conditional",
3199 + "topK": "unsupported",
3200 + "maxTokens": "supported",
3201 + "reasoningEffort": "supported",
3202 + "thinkingBudget": "unsupported",
3203 + "stop": "unsupported",
3204 + "seed": "unsupported",
3205 + "frequencyPenalty": "conditional",
3206 + "presencePenalty": "conditional",
3207 + "verbosity": "supported"
3208 + },
3209 + "pricing": {
3210 + "inputPerMillion": 5,
3211 + "cachedInputPerMillion": 0.5,
3212 + "outputPerMillion": 30
3213 + },
3214 + "status": "active",
3215 + "notes": "Dated snapshot of gpt-5.5. Snapshot gpt-5.5-2026-04-23. 'minimal' and 'max' efforts rejected (400 unsupported_value). temperature/top_p/penalties rejected unless reasoning.effort='none' (verified both ways). >272K input tokens billed 2x/1.5x. Default top_p echoed as 0.98. Chat Completions: temperature other than 1 rejected ('Only the default (1) value is supported'). Verified by probe: basic, stream, params, tools(+round trip), structured, vision(effort none), web_search (url_citation annotations), encrypted reasoning round trip, chat completions. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3216 + "reasoningEfforts": [
3217 + "none",
3218 + "low",
3219 + "medium",
3220 + "high",
3221 + "xhigh"
3222 + ],
3223 + "defaultReasoningEffort": "medium",
3224 + "apis": [
3225 + "responses",
3226 + "chat",
3227 + "batch"
3228 + ],
3229 + "knowledgeCutoff": "2025-12-01",
3230 + "shutdownDate": null,
3231 + "snapshotOf": "gpt-5.5"
3232 + },
3233 + {
3234 + "id": "gpt-5.5-pro",
3235 + "displayName": "GPT-5.5 Pro",
3236 + "family": "gpt-5.5",
3237 + "contextTokens": 1050000,
3238 + "maxOutputTokens": 128000,
3239 + "capabilities": {
3240 + "text": true,
3241 + "vision": true,
3242 + "audioInput": false,
3243 + "audioOutput": false,
3244 + "imageGeneration": true,
3245 + "video": false,
3246 + "reasoning": true,
3247 + "tools": true,
3248 + "structuredOutput": true,
3249 + "streaming": true,
3250 + "files": true,
3251 + "webSearch": true
3252 + },
3253 + "parameters": {
3254 + "temperature": "unsupported",
3255 + "topP": "unsupported",
3256 + "topK": "unsupported",
3257 + "maxTokens": "supported",
3258 + "reasoningEffort": "supported",
3259 + "thinkingBudget": "unsupported",
3260 + "stop": "unsupported",
3261 + "seed": "unsupported",
3262 + "frequencyPenalty": "unsupported",
3263 + "presencePenalty": "unsupported",
3264 + "verbosity": "supported"
3265 + },
3266 + "pricing": {
3267 + "inputPerMillion": 30,
3268 + "cachedInputPerMillion": null,
3269 + "outputPerMillion": 180
3270 + },
3271 + "status": "active",
3272 + "notes": "Responses API only (no Chat Completions). No cached-input price. Slow: docs recommend background:true. One tiny probe answered in 7.3 s. Docs: streaming listed but not verified. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3273 + "reasoningEfforts": [
3274 + "medium",
3275 + "high",
3276 + "xhigh"
3277 + ],
3278 + "defaultReasoningEffort": "high",
3279 + "apis": [
3280 + "responses",
3281 + "batch"
3282 + ],
3283 + "knowledgeCutoff": "2025-12-01",
3284 + "shutdownDate": null,
3285 + "snapshotOf": null
3286 + },
3287 + {
3288 + "id": "gpt-5.5-pro-2026-04-23",
3289 + "displayName": "GPT-5.5 Pro (2026-04-23)",
3290 + "family": "gpt-5.5",
3291 + "contextTokens": 1050000,
3292 + "maxOutputTokens": 128000,
3293 + "capabilities": {
3294 + "text": true,
3295 + "vision": true,
3296 + "audioInput": false,
3297 + "audioOutput": false,
3298 + "imageGeneration": true,
3299 + "video": false,
3300 + "reasoning": true,
3301 + "tools": true,
3302 + "structuredOutput": true,
3303 + "streaming": true,
3304 + "files": true,
3305 + "webSearch": true
3306 + },
3307 + "parameters": {
3308 + "temperature": "unsupported",
3309 + "topP": "unsupported",
3310 + "topK": "unsupported",
3311 + "maxTokens": "supported",
3312 + "reasoningEffort": "supported",
3313 + "thinkingBudget": "unsupported",
3314 + "stop": "unsupported",
3315 + "seed": "unsupported",
3316 + "frequencyPenalty": "unsupported",
3317 + "presencePenalty": "unsupported",
3318 + "verbosity": "supported"
3319 + },
3320 + "pricing": {
3321 + "inputPerMillion": 30,
3322 + "cachedInputPerMillion": null,
3323 + "outputPerMillion": 180
3324 + },
3325 + "status": "active",
3326 + "notes": "Dated snapshot of gpt-5.5-pro. Responses API only (no Chat Completions). No cached-input price. Slow: docs recommend background:true. One tiny probe answered in 7.3 s. Docs: streaming listed but not verified. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3327 + "reasoningEfforts": [
3328 + "medium",
3329 + "high",
3330 + "xhigh"
3331 + ],
3332 + "defaultReasoningEffort": "high",
3333 + "apis": [
3334 + "responses",
3335 + "batch"
3336 + ],
3337 + "knowledgeCutoff": "2025-12-01",
3338 + "shutdownDate": null,
3339 + "snapshotOf": "gpt-5.5-pro"
3340 + },
3341 + {
3342 + "id": "gpt-5.6-luna",
3343 + "displayName": "GPT-5.6 Luna",
3344 + "family": "gpt-5.6",
3345 + "contextTokens": 1050000,
3346 + "maxOutputTokens": 128000,
3347 + "capabilities": {
3348 + "text": true,
3349 + "vision": true,
3350 + "audioInput": false,
3351 + "audioOutput": false,
3352 + "imageGeneration": true,
3353 + "video": false,
3354 + "reasoning": true,
3355 + "tools": true,
3356 + "structuredOutput": true,
3357 + "streaming": true,
3358 + "files": true,
3359 + "webSearch": true
3360 + },
3361 + "parameters": {
3362 + "temperature": "conditional",
3363 + "topP": "conditional",
3364 + "topK": "unsupported",
3365 + "maxTokens": "supported",
3366 + "reasoningEffort": "supported",
3367 + "thinkingBudget": "unsupported",
3368 + "stop": "unsupported",
3369 + "seed": "unsupported",
3370 + "frequencyPenalty": "conditional",
3371 + "presencePenalty": "conditional",
3372 + "verbosity": "supported"
3373 + },
3374 + "pricing": {
3375 + "inputPerMillion": 0.2,
3376 + "cachedInputPerMillion": 0.02,
3377 + "outputPerMillion": 1.2
3378 + },
3379 + "status": "active",
3380 + "notes": "Cheapest 5.6. Recommended replacement for gpt-5-nano and gpt-4.1-nano. Param matrix assumed identical to gpt-5.6-sol (not individually probed). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3381 + "reasoningEfforts": [
3382 + "none",
3383 + "low",
3384 + "medium",
3385 + "high",
3386 + "xhigh",
3387 + "max"
3388 + ],
3389 + "defaultReasoningEffort": "medium",
3390 + "apis": [
3391 + "responses",
3392 + "chat",
3393 + "batch"
3394 + ],
3395 + "knowledgeCutoff": "2026-02-16",
3396 + "shutdownDate": null,
3397 + "snapshotOf": null
3398 + },
3399 + {
3400 + "id": "gpt-5.6-sol",
3401 + "displayName": "GPT-5.6 Sol",
3402 + "family": "gpt-5.6",
3403 + "contextTokens": 1050000,
3404 + "maxOutputTokens": 128000,
3405 + "capabilities": {
3406 + "text": true,
3407 + "vision": true,
3408 + "audioInput": false,
3409 + "audioOutput": false,
3410 + "imageGeneration": true,
3411 + "video": false,
3412 + "reasoning": true,
3413 + "tools": true,
3414 + "structuredOutput": true,
3415 + "streaming": true,
3416 + "files": true,
3417 + "webSearch": true
3418 + },
3419 + "parameters": {
3420 + "temperature": "conditional",
3421 + "topP": "conditional",
3422 + "topK": "unsupported",
3423 + "maxTokens": "supported",
3424 + "reasoningEffort": "supported",
3425 + "thinkingBudget": "unsupported",
3426 + "stop": "unsupported",
3427 + "seed": "unsupported",
3428 + "frequencyPenalty": "conditional",
3429 + "presencePenalty": "conditional",
3430 + "verbosity": "supported"
3431 + },
3432 + "pricing": {
3433 + "inputPerMillion": 4,
3434 + "cachedInputPerMillion": 0.4,
3435 + "outputPerMillion": 20
3436 + },
3437 + "status": "active",
3438 + "notes": "Alias 'gpt-5.6' resolves here (verified: response.model = gpt-5.6-sol). temperature/top_p/penalties rejected unless reasoning.effort='none' (verified). Supports reasoning.mode 'standard'|'pro' (pro = replacement for *-pro models, not probed), reasoning.context all_turns (default), prompt_cache_options.ttl '30m', explicit cache breakpoints. Recommended replacement for gpt-5, o3, gpt-4o, o1, gpt-4-turbo. Verified by probe: basic, stream (reasoning_summary events seen), params, tools, structured, vision(effort none). Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3439 + "reasoningEfforts": [
3440 + "none",
3441 + "low",
3442 + "medium",
3443 + "high",
3444 + "xhigh",
3445 + "max"
3446 + ],
3447 + "defaultReasoningEffort": "medium",
3448 + "apis": [
3449 + "responses",
3450 + "chat",
3451 + "batch"
3452 + ],
3453 + "knowledgeCutoff": "2026-02-16",
3454 + "shutdownDate": null,
3455 + "snapshotOf": null
3456 + },
3457 + {
3458 + "id": "gpt-5.6-terra",
3459 + "displayName": "GPT-5.6 Terra",
3460 + "family": "gpt-5.6",
3461 + "contextTokens": 1050000,
3462 + "maxOutputTokens": 128000,
3463 + "capabilities": {
3464 + "text": true,
3465 + "vision": true,
3466 + "audioInput": false,
3467 + "audioOutput": false,
3468 + "imageGeneration": true,
3469 + "video": false,
3470 + "reasoning": true,
3471 + "tools": true,
3472 + "structuredOutput": true,
3473 + "streaming": true,
3474 + "files": true,
3475 + "webSearch": true
3476 + },
3477 + "parameters": {
3478 + "temperature": "conditional",
3479 + "topP": "conditional",
3480 + "topK": "unsupported",
3481 + "maxTokens": "supported",
3482 + "reasoningEffort": "supported",
3483 + "thinkingBudget": "unsupported",
3484 + "stop": "unsupported",
3485 + "seed": "unsupported",
3486 + "frequencyPenalty": "conditional",
3487 + "presencePenalty": "conditional",
3488 + "verbosity": "supported"
3489 + },
3490 + "pricing": {
3491 + "inputPerMillion": 2,
3492 + "cachedInputPerMillion": 0.2,
3493 + "outputPerMillion": 12
3494 + },
3495 + "status": "active",
3496 + "notes": "Max input 922,000 tokens. Recommended replacement for gpt-5-mini, o4-mini, gpt-3.5-turbo. Param matrix assumed identical to gpt-5.6-sol (not individually probed). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3497 + "reasoningEfforts": [
3498 + "none",
3499 + "low",
3500 + "medium",
3501 + "high",
3502 + "xhigh",
3503 + "max"
3504 + ],
3505 + "defaultReasoningEffort": "medium",
3506 + "apis": [
3507 + "responses",
3508 + "chat",
3509 + "batch"
3510 + ],
3511 + "knowledgeCutoff": "2026-02-16",
3512 + "shutdownDate": null,
3513 + "snapshotOf": null
3514 + },
3515 + {
3516 + "id": "gpt-6-astra",
3517 + "displayName": "GPT-6 Astra",
3518 + "family": "gpt-6",
3519 + "contextTokens": 1050000,
3520 + "maxOutputTokens": 128000,
3521 + "capabilities": {
3522 + "text": true,
3523 + "vision": true,
3524 + "audioInput": false,
3525 + "audioOutput": false,
3526 + "imageGeneration": true,
3527 + "video": false,
3528 + "reasoning": true,
3529 + "tools": true,
3530 + "structuredOutput": true,
3531 + "streaming": true,
3532 + "files": true,
3533 + "webSearch": true
3534 + },
3535 + "parameters": {
3536 + "temperature": "unsupported",
3537 + "topP": "unsupported",
3538 + "topK": "unsupported",
3539 + "maxTokens": "supported",
3540 + "reasoningEffort": "supported",
3541 + "thinkingBudget": "unsupported",
3542 + "stop": "unsupported",
3543 + "seed": "unsupported",
3544 + "frequencyPenalty": "unsupported",
3545 + "presencePenalty": "unsupported",
3546 + "verbosity": "supported"
3547 + },
3548 + "pricing": {
3549 + "inputPerMillion": 10,
3550 + "cachedInputPerMillion": 1,
3551 + "outputPerMillion": 50
3552 + },
3553 + "status": "active",
3554 + "notes": "Flagship. reasoning.effort 'none'/'minimal' rejected (400 unsupported_value). temperature/top_p/frequency_penalty/presence_penalty rejected ('Unsupported parameter ... is not supported with this model'); logprobs rejected. Cache write $12.50/M; >272K input tokens billed 2x input / 1.5x output. reasoning.context defaults to all_turns. prompt_cache_retention accepted but docs say use prompt_cache_options.ttl='30m'. Verified by probe: basic, stream, params, tools, structured, vision(detail high, effort low), chat completions. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3555 + "reasoningEfforts": [
3556 + "low",
3557 + "medium",
3558 + "high",
3559 + "xhigh",
3560 + "max"
3561 + ],
3562 + "defaultReasoningEffort": "medium",
3563 + "apis": [
3564 + "responses",
3565 + "chat",
3566 + "batch"
3567 + ],
3568 + "knowledgeCutoff": "2026-04-30",
3569 + "shutdownDate": null,
3570 + "snapshotOf": null
3571 + },
3572 + {
3573 + "id": "o1",
3574 + "displayName": "o1",
3575 + "family": "o-series",
3576 + "contextTokens": 200000,
3577 + "maxOutputTokens": 100000,
3578 + "capabilities": {
3579 + "text": true,
3580 + "vision": true,
3581 + "audioInput": false,
3582 + "audioOutput": false,
3583 + "imageGeneration": false,
3584 + "video": false,
3585 + "reasoning": true,
3586 + "tools": true,
3587 + "structuredOutput": true,
3588 + "streaming": true,
3589 + "files": true,
3590 + "webSearch": false
3591 + },
3592 + "parameters": {
3593 + "temperature": "unsupported",
3594 + "topP": "unsupported",
3595 + "topK": "unsupported",
3596 + "maxTokens": "supported",
3597 + "reasoningEffort": "supported",
3598 + "thinkingBudget": "unsupported",
3599 + "stop": "unsupported",
3600 + "seed": "unsupported",
3601 + "frequencyPenalty": "unsupported",
3602 + "presencePenalty": "unsupported",
3603 + "verbosity": "unsupported"
3604 + },
3605 + "pricing": {
3606 + "inputPerMillion": 15,
3607 + "cachedInputPerMillion": 7.5,
3608 + "outputPerMillion": 60
3609 + },
3610 + "status": "deprecated",
3611 + "notes": "shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-sol. Still answers (verified; 32-token probe came back incomplete because of reasoning). Verified by probe: basic (incomplete). Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3612 + "reasoningEfforts": [
3613 + "low",
3614 + "medium",
3615 + "high"
3616 + ],
3617 + "defaultReasoningEffort": "medium",
3618 + "apis": [
3619 + "responses",
3620 + "chat",
3621 + "batch",
3622 + "assistants"
3623 + ],
3624 + "knowledgeCutoff": "2023-10-01",
3625 + "shutdownDate": "2026-10-23",
3626 + "snapshotOf": null
3627 + },
3628 + {
3629 + "id": "o1-2024-12-17",
3630 + "displayName": "o1 (2024-12-17)",
3631 + "family": "o-series",
3632 + "contextTokens": 200000,
3633 + "maxOutputTokens": 100000,
3634 + "capabilities": {
3635 + "text": true,
3636 + "vision": true,
3637 + "audioInput": false,
3638 + "audioOutput": false,
3639 + "imageGeneration": false,
3640 + "video": false,
3641 + "reasoning": true,
3642 + "tools": true,
3643 + "structuredOutput": true,
3644 + "streaming": true,
3645 + "files": true,
3646 + "webSearch": false
3647 + },
3648 + "parameters": {
3649 + "temperature": "unsupported",
3650 + "topP": "unsupported",
3651 + "topK": "unsupported",
3652 + "maxTokens": "supported",
3653 + "reasoningEffort": "supported",
3654 + "thinkingBudget": "unsupported",
3655 + "stop": "unsupported",
3656 + "seed": "unsupported",
3657 + "frequencyPenalty": "unsupported",
3658 + "presencePenalty": "unsupported",
3659 + "verbosity": "unsupported"
3660 + },
3661 + "pricing": {
3662 + "inputPerMillion": 15,
3663 + "cachedInputPerMillion": 7.5,
3664 + "outputPerMillion": 60
3665 + },
3666 + "status": "deprecated",
3667 + "notes": "Dated snapshot of o1. shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-sol. Still answers (verified; 32-token probe came back incomplete because of reasoning). Verified by probe: basic (incomplete). Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3668 + "reasoningEfforts": [
3669 + "low",
3670 + "medium",
3671 + "high"
3672 + ],
3673 + "defaultReasoningEffort": "medium",
3674 + "apis": [
3675 + "responses",
3676 + "chat",
3677 + "batch",
3678 + "assistants"
3679 + ],
3680 + "knowledgeCutoff": "2023-10-01",
3681 + "shutdownDate": "2026-10-23",
3682 + "snapshotOf": "o1"
3683 + },
3684 + {
3685 + "id": "o1-pro",
3686 + "displayName": "o1-pro",
3687 + "family": "o-series",
3688 + "contextTokens": 200000,
3689 + "maxOutputTokens": 100000,
3690 + "capabilities": {
3691 + "text": true,
3692 + "vision": true,
3693 + "audioInput": false,
3694 + "audioOutput": false,
3695 + "imageGeneration": false,
3696 + "video": false,
3697 + "reasoning": true,
3698 + "tools": true,
3699 + "structuredOutput": true,
3700 + "streaming": true,
3701 + "files": true,
3702 + "webSearch": false
3703 + },
3704 + "parameters": {
3705 + "temperature": "unsupported",
3706 + "topP": "unsupported",
3707 + "topK": "unsupported",
3708 + "maxTokens": "supported",
3709 + "reasoningEffort": "supported",
3710 + "thinkingBudget": "unsupported",
3711 + "stop": "unsupported",
3712 + "seed": "unsupported",
3713 + "frequencyPenalty": "unsupported",
3714 + "presencePenalty": "unsupported",
3715 + "verbosity": "unsupported"
3716 + },
3717 + "pricing": {
3718 + "inputPerMillion": 150,
3719 + "cachedInputPerMillion": null,
3720 + "outputPerMillion": 600
3721 + },
3722 + "status": "deprecated",
3723 + "notes": "shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-sol with reasoning.mode pro. Responses only. Not probed (cost). Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3724 + "reasoningEfforts": null,
3725 + "defaultReasoningEffort": null,
3726 + "apis": [
3727 + "responses",
3728 + "batch"
3729 + ],
3730 + "knowledgeCutoff": null,
3731 + "shutdownDate": "2026-10-23",
3732 + "snapshotOf": null
3733 + },
3734 + {
3735 + "id": "o1-pro-2025-03-19",
3736 + "displayName": "o1-pro (2025-03-19)",
3737 + "family": "o-series",
3738 + "contextTokens": 200000,
3739 + "maxOutputTokens": 100000,
3740 + "capabilities": {
3741 + "text": true,
3742 + "vision": true,
3743 + "audioInput": false,
3744 + "audioOutput": false,
3745 + "imageGeneration": false,
3746 + "video": false,
3747 + "reasoning": true,
3748 + "tools": true,
3749 + "structuredOutput": true,
3750 + "streaming": true,
3751 + "files": true,
3752 + "webSearch": false
3753 + },
3754 + "parameters": {
3755 + "temperature": "unsupported",
3756 + "topP": "unsupported",
3757 + "topK": "unsupported",
3758 + "maxTokens": "supported",
3759 + "reasoningEffort": "supported",
3760 + "thinkingBudget": "unsupported",
3761 + "stop": "unsupported",
3762 + "seed": "unsupported",
3763 + "frequencyPenalty": "unsupported",
3764 + "presencePenalty": "unsupported",
3765 + "verbosity": "unsupported"
3766 + },
3767 + "pricing": {
3768 + "inputPerMillion": 150,
3769 + "cachedInputPerMillion": null,
3770 + "outputPerMillion": 600
3771 + },
3772 + "status": "deprecated",
3773 + "notes": "Dated snapshot of o1-pro. shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-sol with reasoning.mode pro. Responses only. Not probed (cost). Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3774 + "reasoningEfforts": null,
3775 + "defaultReasoningEffort": null,
3776 + "apis": [
3777 + "responses",
3778 + "batch"
3779 + ],
3780 + "knowledgeCutoff": null,
3781 + "shutdownDate": "2026-10-23",
3782 + "snapshotOf": "o1-pro"
3783 + },
3784 + {
3785 + "id": "o3",
3786 + "displayName": "o3",
3787 + "family": "o-series",
3788 + "contextTokens": 200000,
3789 + "maxOutputTokens": 100000,
3790 + "capabilities": {
3791 + "text": true,
3792 + "vision": true,
3793 + "audioInput": false,
3794 + "audioOutput": false,
3795 + "imageGeneration": true,
3796 + "video": false,
3797 + "reasoning": true,
3798 + "tools": true,
3799 + "structuredOutput": true,
3800 + "streaming": true,
3801 + "files": true,
3802 + "webSearch": true
3803 + },
3804 + "parameters": {
3805 + "temperature": "unsupported",
3806 + "topP": "unsupported",
3807 + "topK": "unsupported",
3808 + "maxTokens": "supported",
3809 + "reasoningEffort": "supported",
3810 + "thinkingBudget": "unsupported",
3811 + "stop": "unsupported",
3812 + "seed": "unsupported",
3813 + "frequencyPenalty": "unsupported",
3814 + "presencePenalty": "unsupported",
3815 + "verbosity": "unsupported"
3816 + },
3817 + "pricing": {
3818 + "inputPerMillion": 2,
3819 + "cachedInputPerMillion": 0.5,
3820 + "outputPerMillion": 8
3821 + },
3822 + "status": "active",
3823 + "notes": "Alias active; snapshot o3-2025-04-16 shuts down 2026-12-11 -> gpt-5.6-sol. Docs: 'o3 is succeeded by GPT-5'. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3824 + "reasoningEfforts": [
3825 + "low",
3826 + "medium",
3827 + "high"
3828 + ],
3829 + "defaultReasoningEffort": "medium",
3830 + "apis": [
3831 + "responses",
3832 + "chat",
3833 + "batch"
3834 + ],
3835 + "knowledgeCutoff": "2024-06-01",
3836 + "shutdownDate": null,
3837 + "snapshotOf": null
3838 + },
3839 + {
3840 + "id": "o3-2025-04-16",
3841 + "displayName": "o3 (2025-04-16)",
3842 + "family": "o-series",
3843 + "contextTokens": 200000,
3844 + "maxOutputTokens": 100000,
3845 + "capabilities": {
3846 + "text": true,
3847 + "vision": true,
3848 + "audioInput": false,
3849 + "audioOutput": false,
3850 + "imageGeneration": true,
3851 + "video": false,
3852 + "reasoning": true,
3853 + "tools": true,
3854 + "structuredOutput": true,
3855 + "streaming": true,
3856 + "files": true,
3857 + "webSearch": true
3858 + },
3859 + "parameters": {
3860 + "temperature": "unsupported",
3861 + "topP": "unsupported",
3862 + "topK": "unsupported",
3863 + "maxTokens": "supported",
3864 + "reasoningEffort": "supported",
3865 + "thinkingBudget": "unsupported",
3866 + "stop": "unsupported",
3867 + "seed": "unsupported",
3868 + "frequencyPenalty": "unsupported",
3869 + "presencePenalty": "unsupported",
3870 + "verbosity": "unsupported"
3871 + },
3872 + "pricing": {
3873 + "inputPerMillion": 2,
3874 + "cachedInputPerMillion": 0.5,
3875 + "outputPerMillion": 8
3876 + },
3877 + "status": "deprecated",
3878 + "notes": "Dated snapshot of o3. shutdown_date (from GET /v1/models): 2026-12-11. Alias active; snapshot o3-2025-04-16 shuts down 2026-12-11 -> gpt-5.6-sol. Docs: 'o3 is succeeded by GPT-5'. Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3879 + "reasoningEfforts": [
3880 + "low",
3881 + "medium",
3882 + "high"
3883 + ],
3884 + "defaultReasoningEffort": "medium",
3885 + "apis": [
3886 + "responses",
3887 + "chat",
3888 + "batch"
3889 + ],
3890 + "knowledgeCutoff": "2024-06-01",
3891 + "shutdownDate": "2026-12-11",
3892 + "snapshotOf": "o3"
3893 + },
3894 + {
3895 + "id": "o3-deep-research",
3896 + "displayName": "o3 Deep Research",
3897 + "family": "o-series",
3898 + "contextTokens": 200000,
3899 + "maxOutputTokens": 100000,
3900 + "capabilities": {
3901 + "text": true,
3902 + "vision": true,
3903 + "audioInput": false,
3904 + "audioOutput": false,
3905 + "imageGeneration": false,
3906 + "video": false,
3907 + "reasoning": true,
3908 + "tools": true,
3909 + "structuredOutput": true,
3910 + "streaming": true,
3911 + "files": true,
3912 + "webSearch": true
3913 + },
3914 + "parameters": {
3915 + "temperature": "unsupported",
3916 + "topP": "unsupported",
3917 + "topK": "unsupported",
3918 + "maxTokens": "supported",
3919 + "reasoningEffort": "supported",
3920 + "thinkingBudget": "unsupported",
3921 + "stop": "unsupported",
3922 + "seed": "unsupported",
3923 + "frequencyPenalty": "unsupported",
3924 + "presencePenalty": "unsupported",
3925 + "verbosity": "supported"
3926 + },
3927 + "pricing": {
3928 + "inputPerMillion": null,
3929 + "cachedInputPerMillion": null,
3930 + "outputPerMillion": null
3931 + },
3932 + "status": "deprecated",
3933 + "notes": "shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23; 404 model_not_found (verified). Agentic research model, not a chat model. Verified by probe: basic -> 404. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3934 + "reasoningEfforts": null,
3935 + "defaultReasoningEffort": null,
3936 + "apis": [
3937 + "responses"
3938 + ],
3939 + "knowledgeCutoff": null,
3940 + "shutdownDate": "2026-07-23",
3941 + "snapshotOf": null
3942 + },
3943 + {
3944 + "id": "o3-deep-research-2025-06-26",
3945 + "displayName": "o3 Deep Research (2025-06-26)",
3946 + "family": "o-series",
3947 + "contextTokens": 200000,
3948 + "maxOutputTokens": 100000,
3949 + "capabilities": {
3950 + "text": true,
3951 + "vision": true,
3952 + "audioInput": false,
3953 + "audioOutput": false,
3954 + "imageGeneration": false,
3955 + "video": false,
3956 + "reasoning": true,
3957 + "tools": true,
3958 + "structuredOutput": true,
3959 + "streaming": true,
3960 + "files": true,
3961 + "webSearch": true
3962 + },
3963 + "parameters": {
3964 + "temperature": "unsupported",
3965 + "topP": "unsupported",
3966 + "topK": "unsupported",
3967 + "maxTokens": "supported",
3968 + "reasoningEffort": "supported",
3969 + "thinkingBudget": "unsupported",
3970 + "stop": "unsupported",
3971 + "seed": "unsupported",
3972 + "frequencyPenalty": "unsupported",
3973 + "presencePenalty": "unsupported",
3974 + "verbosity": "supported"
3975 + },
3976 + "pricing": {
3977 + "inputPerMillion": null,
3978 + "cachedInputPerMillion": null,
3979 + "outputPerMillion": null
3980 + },
3981 + "status": "deprecated",
3982 + "notes": "Dated snapshot of o3-deep-research. shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23; 404 model_not_found (verified). Agentic research model, not a chat model. Verified by probe: basic -> 404. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
3983 + "reasoningEfforts": null,
3984 + "defaultReasoningEffort": null,
3985 + "apis": [
3986 + "responses"
3987 + ],
3988 + "knowledgeCutoff": null,
3989 + "shutdownDate": "2026-07-23",
3990 + "snapshotOf": "o3-deep-research"
3991 + },
3992 + {
3993 + "id": "o3-mini",
3994 + "displayName": "o3-mini",
3995 + "family": "o-series",
3996 + "contextTokens": 200000,
3997 + "maxOutputTokens": 100000,
3998 + "capabilities": {
3999 + "text": true,
4000 + "vision": false,
4001 + "audioInput": false,
4002 + "audioOutput": false,
4003 + "imageGeneration": false,
4004 + "video": false,
4005 + "reasoning": true,
4006 + "tools": true,
4007 + "structuredOutput": true,
4008 + "streaming": true,
4009 + "files": false,
4010 + "webSearch": false
4011 + },
4012 + "parameters": {
4013 + "temperature": "unsupported",
4014 + "topP": "unsupported",
4015 + "topK": "unsupported",
4016 + "maxTokens": "supported",
4017 + "reasoningEffort": "supported",
4018 + "thinkingBudget": "unsupported",
4019 + "stop": "unsupported",
4020 + "seed": "unsupported",
4021 + "frequencyPenalty": "unsupported",
4022 + "presencePenalty": "unsupported",
4023 + "verbosity": "unsupported"
4024 + },
4025 + "pricing": {
4026 + "inputPerMillion": 1.1,
4027 + "cachedInputPerMillion": 0.55,
4028 + "outputPerMillion": 4.4
4029 + },
4030 + "status": "deprecated",
4031 + "notes": "shutdown_date (from GET /v1/models): 2026-10-23. TEXT ONLY (no image input). shutdown_date 2026-10-23 -> gpt-5.6-sol. Still answers (verified). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
4032 + "reasoningEfforts": [
4033 + "low",
4034 + "medium",
4035 + "high"
4036 + ],
4037 + "defaultReasoningEffort": "medium",
4038 + "apis": [
4039 + "responses",
4040 + "chat",
4041 + "batch",
4042 + "assistants"
4043 + ],
4044 + "knowledgeCutoff": "2023-10-01",
4045 + "shutdownDate": "2026-10-23",
4046 + "snapshotOf": null
4047 + },
4048 + {
4049 + "id": "o3-mini-2025-01-31",
4050 + "displayName": "o3-mini (2025-01-31)",
4051 + "family": "o-series",
4052 + "contextTokens": 200000,
4053 + "maxOutputTokens": 100000,
4054 + "capabilities": {
4055 + "text": true,
4056 + "vision": false,
4057 + "audioInput": false,
4058 + "audioOutput": false,
4059 + "imageGeneration": false,
4060 + "video": false,
4061 + "reasoning": true,
4062 + "tools": true,
4063 + "structuredOutput": true,
4064 + "streaming": true,
4065 + "files": false,
4066 + "webSearch": false
4067 + },
4068 + "parameters": {
4069 + "temperature": "unsupported",
4070 + "topP": "unsupported",
4071 + "topK": "unsupported",
4072 + "maxTokens": "supported",
4073 + "reasoningEffort": "supported",
4074 + "thinkingBudget": "unsupported",
4075 + "stop": "unsupported",
4076 + "seed": "unsupported",
4077 + "frequencyPenalty": "unsupported",
4078 + "presencePenalty": "unsupported",
4079 + "verbosity": "unsupported"
4080 + },
4081 + "pricing": {
4082 + "inputPerMillion": 1.1,
4083 + "cachedInputPerMillion": 0.55,
4084 + "outputPerMillion": 4.4
4085 + },
4086 + "status": "deprecated",
4087 + "notes": "Dated snapshot of o3-mini. shutdown_date (from GET /v1/models): 2026-10-23. TEXT ONLY (no image input). shutdown_date 2026-10-23 -> gpt-5.6-sol. Still answers (verified). Verified by probe: basic. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
4088 + "reasoningEfforts": [
4089 + "low",
4090 + "medium",
4091 + "high"
4092 + ],
4093 + "defaultReasoningEffort": "medium",
4094 + "apis": [
4095 + "responses",
4096 + "chat",
4097 + "batch",
4098 + "assistants"
4099 + ],
4100 + "knowledgeCutoff": "2023-10-01",
4101 + "shutdownDate": "2026-10-23",
4102 + "snapshotOf": "o3-mini"
4103 + },
4104 + {
4105 + "id": "o3-pro",
4106 + "displayName": "o3-pro",
4107 + "family": "o-series",
4108 + "contextTokens": 200000,
4109 + "maxOutputTokens": 100000,
4110 + "capabilities": {
4111 + "text": true,
4112 + "vision": true,
4113 + "audioInput": false,
4114 + "audioOutput": false,
4115 + "imageGeneration": true,
4116 + "video": false,
4117 + "reasoning": true,
4118 + "tools": true,
4119 + "structuredOutput": true,
4120 + "streaming": true,
4121 + "files": true,
4122 + "webSearch": true
4123 + },
4124 + "parameters": {
4125 + "temperature": "unsupported",
4126 + "topP": "unsupported",
4127 + "topK": "unsupported",
4128 + "maxTokens": "supported",
4129 + "reasoningEffort": "supported",
4130 + "thinkingBudget": "unsupported",
4131 + "stop": "unsupported",
4132 + "seed": "unsupported",
4133 + "frequencyPenalty": "unsupported",
4134 + "presencePenalty": "unsupported",
4135 + "verbosity": "unsupported"
4136 + },
4137 + "pricing": {
4138 + "inputPerMillion": 20,
4139 + "cachedInputPerMillion": null,
4140 + "outputPerMillion": 80
4141 + },
4142 + "status": "active",
4143 + "notes": "Responses only, background mode recommended; streaming not indicated in docs. Snapshot o3-pro-2025-06-10 shuts down 2026-12-11. Not probed. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
4144 + "reasoningEfforts": null,
4145 + "defaultReasoningEffort": null,
4146 + "apis": [
4147 + "responses",
4148 + "batch"
4149 + ],
4150 + "knowledgeCutoff": null,
4151 + "shutdownDate": null,
4152 + "snapshotOf": null
4153 + },
4154 + {
4155 + "id": "o3-pro-2025-06-10",
4156 + "displayName": "o3-pro (2025-06-10)",
4157 + "family": "o-series",
4158 + "contextTokens": 200000,
4159 + "maxOutputTokens": 100000,
4160 + "capabilities": {
4161 + "text": true,
4162 + "vision": true,
4163 + "audioInput": false,
4164 + "audioOutput": false,
4165 + "imageGeneration": true,
4166 + "video": false,
4167 + "reasoning": true,
4168 + "tools": true,
4169 + "structuredOutput": true,
4170 + "streaming": true,
4171 + "files": true,
4172 + "webSearch": true
4173 + },
4174 + "parameters": {
4175 + "temperature": "unsupported",
4176 + "topP": "unsupported",
4177 + "topK": "unsupported",
4178 + "maxTokens": "supported",
4179 + "reasoningEffort": "supported",
4180 + "thinkingBudget": "unsupported",
4181 + "stop": "unsupported",
4182 + "seed": "unsupported",
4183 + "frequencyPenalty": "unsupported",
4184 + "presencePenalty": "unsupported",
4185 + "verbosity": "unsupported"
4186 + },
4187 + "pricing": {
4188 + "inputPerMillion": 20,
4189 + "cachedInputPerMillion": null,
4190 + "outputPerMillion": 80
4191 + },
4192 + "status": "deprecated",
4193 + "notes": "Dated snapshot of o3-pro. shutdown_date (from GET /v1/models): 2026-12-11. Responses only, background mode recommended; streaming not indicated in docs. Snapshot o3-pro-2025-06-10 shuts down 2026-12-11. Not probed. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
4194 + "reasoningEfforts": null,
4195 + "defaultReasoningEffort": null,
4196 + "apis": [
4197 + "responses",
4198 + "batch"
4199 + ],
4200 + "knowledgeCutoff": null,
4201 + "shutdownDate": "2026-12-11",
4202 + "snapshotOf": "o3-pro"
4203 + },
4204 + {
4205 + "id": "o4-mini",
4206 + "displayName": "o4-mini",
4207 + "family": "o-series",
4208 + "contextTokens": 200000,
4209 + "maxOutputTokens": 100000,
4210 + "capabilities": {
4211 + "text": true,
4212 + "vision": true,
4213 + "audioInput": false,
4214 + "audioOutput": false,
4215 + "imageGeneration": true,
4216 + "video": false,
4217 + "reasoning": true,
4218 + "tools": true,
4219 + "structuredOutput": true,
4220 + "streaming": true,
4221 + "files": true,
4222 + "webSearch": true
4223 + },
4224 + "parameters": {
4225 + "temperature": "unsupported",
4226 + "topP": "unsupported",
4227 + "topK": "unsupported",
4228 + "maxTokens": "supported",
4229 + "reasoningEffort": "supported",
4230 + "thinkingBudget": "unsupported",
4231 + "stop": "unsupported",
4232 + "seed": "unsupported",
4233 + "frequencyPenalty": "unsupported",
4234 + "presencePenalty": "unsupported",
4235 + "verbosity": "unsupported"
4236 + },
4237 + "pricing": {
4238 + "inputPerMillion": 1.1,
4239 + "cachedInputPerMillion": 0.275,
4240 + "outputPerMillion": 4.4
4241 + },
4242 + "status": "deprecated",
4243 + "notes": "shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-terra. Verified: effort none/minimal/xhigh/max rejected ('Supported values are: low, medium, and high'); temperature/top_p/penalties/logprobs rejected; text.verbosity only 'medium'. Heavy reasoner: at max_output_tokens 200 the tool-call, structured and vision probes all came back incomplete (all tokens spent on reasoning) -> give it >= 1-2k output tokens. Reasoning summaries stream (response.reasoning_summary_*). Verified by probe: basic, stream, params, structured/vision/tools (incomplete at 200 tokens), chat completions. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
4244 + "reasoningEfforts": [
4245 + "low",
4246 + "medium",
4247 + "high"
4248 + ],
4249 + "defaultReasoningEffort": "medium",
4250 + "apis": [
4251 + "responses",
4252 + "chat",
4253 + "batch",
4254 + "fine-tuning"
4255 + ],
4256 + "knowledgeCutoff": "2024-06-01",
4257 + "shutdownDate": "2026-10-23",
4258 + "snapshotOf": null
4259 + },
4260 + {
4261 + "id": "o4-mini-2025-04-16",
4262 + "displayName": "o4-mini (2025-04-16)",
4263 + "family": "o-series",
4264 + "contextTokens": 200000,
4265 + "maxOutputTokens": 100000,
4266 + "capabilities": {
4267 + "text": true,
4268 + "vision": true,
4269 + "audioInput": false,
4270 + "audioOutput": false,
4271 + "imageGeneration": true,
4272 + "video": false,
4273 + "reasoning": true,
4274 + "tools": true,
4275 + "structuredOutput": true,
4276 + "streaming": true,
4277 + "files": true,
4278 + "webSearch": true
4279 + },
4280 + "parameters": {
4281 + "temperature": "unsupported",
4282 + "topP": "unsupported",
4283 + "topK": "unsupported",
4284 + "maxTokens": "supported",
4285 + "reasoningEffort": "supported",
4286 + "thinkingBudget": "unsupported",
4287 + "stop": "unsupported",
4288 + "seed": "unsupported",
4289 + "frequencyPenalty": "unsupported",
4290 + "presencePenalty": "unsupported",
4291 + "verbosity": "unsupported"
4292 + },
4293 + "pricing": {
4294 + "inputPerMillion": 1.1,
4295 + "cachedInputPerMillion": 0.275,
4296 + "outputPerMillion": 4.4
4297 + },
4298 + "status": "deprecated",
4299 + "notes": "Dated snapshot of o4-mini. shutdown_date (from GET /v1/models): 2026-10-23. shutdown_date 2026-10-23 -> gpt-5.6-terra. Verified: effort none/minimal/xhigh/max rejected ('Supported values are: low, medium, and high'); temperature/top_p/penalties/logprobs rejected; text.verbosity only 'medium'. Heavy reasoner: at max_output_tokens 200 the tool-call, structured and vision probes all came back incomplete (all tokens spent on reasoning) -> give it >= 1-2k output tokens. Reasoning summaries stream (response.reasoning_summary_*). Verified by probe: basic, stream, params, structured/vision/tools (incomplete at 200 tokens), chat completions. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
4300 + "reasoningEfforts": [
4301 + "low",
4302 + "medium",
4303 + "high"
4304 + ],
4305 + "defaultReasoningEffort": "medium",
4306 + "apis": [
4307 + "responses",
4308 + "chat",
4309 + "batch",
4310 + "fine-tuning"
4311 + ],
4312 + "knowledgeCutoff": "2024-06-01",
4313 + "shutdownDate": "2026-10-23",
4314 + "snapshotOf": "o4-mini"
4315 + },
4316 + {
4317 + "id": "o4-mini-deep-research",
4318 + "displayName": "o4-mini Deep Research",
4319 + "family": "o-series",
4320 + "contextTokens": 200000,
4321 + "maxOutputTokens": 100000,
4322 + "capabilities": {
4323 + "text": true,
4324 + "vision": true,
4325 + "audioInput": false,
4326 + "audioOutput": false,
4327 + "imageGeneration": false,
4328 + "video": false,
4329 + "reasoning": true,
4330 + "tools": true,
4331 + "structuredOutput": true,
4332 + "streaming": true,
4333 + "files": true,
4334 + "webSearch": true
4335 + },
4336 + "parameters": {
4337 + "temperature": "unsupported",
4338 + "topP": "unsupported",
4339 + "topK": "unsupported",
4340 + "maxTokens": "supported",
4341 + "reasoningEffort": "supported",
4342 + "thinkingBudget": "unsupported",
4343 + "stop": "unsupported",
4344 + "seed": "unsupported",
4345 + "frequencyPenalty": "unsupported",
4346 + "presencePenalty": "unsupported",
4347 + "verbosity": "supported"
4348 + },
4349 + "pricing": {
4350 + "inputPerMillion": null,
4351 + "cachedInputPerMillion": null,
4352 + "outputPerMillion": null
4353 + },
4354 + "status": "deprecated",
4355 + "notes": "shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23 (passed). Not probed; sibling o3-deep-research returns 404. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
4356 + "reasoningEfforts": null,
4357 + "defaultReasoningEffort": null,
4358 + "apis": [
4359 + "responses"
4360 + ],
4361 + "knowledgeCutoff": null,
4362 + "shutdownDate": "2026-07-23",
4363 + "snapshotOf": null
4364 + },
4365 + {
4366 + "id": "o4-mini-deep-research-2025-06-26",
4367 + "displayName": "o4-mini Deep Research (2025-06-26)",
4368 + "family": "o-series",
4369 + "contextTokens": 200000,
4370 + "maxOutputTokens": 100000,
4371 + "capabilities": {
4372 + "text": true,
4373 + "vision": true,
4374 + "audioInput": false,
4375 + "audioOutput": false,
4376 + "imageGeneration": false,
4377 + "video": false,
4378 + "reasoning": true,
4379 + "tools": true,
4380 + "structuredOutput": true,
4381 + "streaming": true,
4382 + "files": true,
4383 + "webSearch": true
4384 + },
4385 + "parameters": {
4386 + "temperature": "unsupported",
4387 + "topP": "unsupported",
4388 + "topK": "unsupported",
4389 + "maxTokens": "supported",
4390 + "reasoningEffort": "supported",
4391 + "thinkingBudget": "unsupported",
4392 + "stop": "unsupported",
4393 + "seed": "unsupported",
4394 + "frequencyPenalty": "unsupported",
4395 + "presencePenalty": "unsupported",
4396 + "verbosity": "supported"
4397 + },
4398 + "pricing": {
4399 + "inputPerMillion": null,
4400 + "cachedInputPerMillion": null,
4401 + "outputPerMillion": null
4402 + },
4403 + "status": "deprecated",
4404 + "notes": "Dated snapshot of o4-mini-deep-research. shutdown_date (from GET /v1/models): 2026-07-23 (already passed). Listed by /v1/models but no longer serves requests (404 model_not_found) or past shutdown. shutdown_date 2026-07-23 (passed). Not probed; sibling o3-deep-research returns 404. Verified by probe: none. Param legend: supported | unsupported | conditional (sampling params only accepted when reasoning.effort='none'; stop/seed only via Chat Completions) | null = unknown. files = PDF via input_file (docs: any vision model); verified only on gpt-5.4-mini. audioInput/audioOutput false: Responses API rejects input_audio ('Audio input is not available', verified); audio requires gpt-audio-*/gpt-realtime-* via Chat Completions/Realtime. imageGeneration = via the built-in image_generation tool (gpt-image-2), not native output. video false everywhere (Sora/Videos API deprecated, shutdown 2026-09-24).",
4405 + "reasoningEfforts": null,
4406 + "defaultReasoningEffort": null,
4407 + "apis": [
4408 + "responses"
4409 + ],
4410 + "knowledgeCutoff": null,
4411 + "shutdownDate": "2026-07-23",
4412 + "snapshotOf": "o4-mini-deep-research"
4413 + },
4414 + {
4415 + "id": "gpt-5.6",
4416 + "displayName": "GPT-5.6 (alias -> gpt-5.6-sol)",
4417 + "family": "gpt-5.6",
4418 + "contextTokens": 1050000,
4419 + "maxOutputTokens": 128000,
4420 + "capabilities": {
4421 + "text": true,
4422 + "vision": true,
4423 + "audioInput": false,
4424 + "audioOutput": false,
4425 + "imageGeneration": true,
4426 + "video": false,
4427 + "reasoning": true,
4428 + "tools": true,
4429 + "structuredOutput": true,
4430 + "streaming": true,
4431 + "files": true,
4432 + "webSearch": true
4433 + },
4434 + "parameters": {
4435 + "temperature": "conditional",
4436 + "topP": "conditional",
4437 + "topK": "unsupported",
4438 + "maxTokens": "supported",
4439 + "reasoningEffort": "supported",
4440 + "thinkingBudget": "unsupported",
4441 + "stop": "unsupported",
4442 + "seed": "unsupported",
4443 + "frequencyPenalty": "conditional",
4444 + "presencePenalty": "conditional",
4445 + "verbosity": "supported"
4446 + },
4447 + "pricing": {
4448 + "inputPerMillion": 4,
4449 + "cachedInputPerMillion": 0.4,
4450 + "outputPerMillion": 20
4451 + },
4452 + "status": "active",
4453 + "notes": "NOT returned by GET /v1/models for this key, but documented and verified: a request for 'gpt-5.6' returns response.model = 'gpt-5.6-sol'. Included so the registry can resolve it.",
4454 + "reasoningEfforts": [
4455 + "none",
4456 + "low",
4457 + "medium",
4458 + "high",
4459 + "xhigh",
4460 + "max"
4461 + ],
4462 + "defaultReasoningEffort": "medium",
4463 + "apis": [
4464 + "responses",
4465 + "chat",
4466 + "batch"
4467 + ],
4468 + "knowledgeCutoff": "2026-02-16",
4469 + "shutdownDate": null,
4470 + "snapshotOf": "gpt-5.6-sol"
4471 + }
4472 +]
added docs/provider-research/xai.md +280 −0
@@ -0,0 +1,280 @@
1 +# xAI (Grok API) — provider research for PolyLLM
2 +
3 +Last documentation audit: **2026-09-08**
4 +Probes executed 2026-09-08 with a real key against `https://api.x.ai/v1` (scripts in `research/xai/`, raw outputs in `research/xai/out/`). Everything marked **(probed)** was observed live; everything marked **(docs)** comes from the pages listed at the end.
5 +
6 +> Heads-up: `docs.x.ai/docs/...` URLs given in the brief are all **404** now. The documentation moved to `https://docs.x.ai/developers/...` (see "Documentation pages used"). The API error for Live Search still points to the old `/docs/guides/tools/overview` URL, which is dead.
7 +
8 +---
9 +
10 +## 1. Base URL, auth, headers
11 +
12 +| Item | Value |
13 +|---|---|
14 +| REST base URL | `https://api.x.ai/v1` (also a gRPC API at `api.x.ai:443`, not relevant for a web app) |
15 +| Auth | `Authorization: Bearer <XAI_API_KEY>` |
16 +| Content type | `application/json` (malformed JSON → **422 text/plain** Rust/serde message, e.g. `Failed to deserialize the JSON body into the target type: messages: invalid type: string "nope", expected a sequence at line 1 column 37`) **(probed)** |
17 +| Useful request headers | `x-grok-conv-id: <stable id>` — routes a conversation to the same server to maximise prompt-cache hits (docs); accepted **(probed)**. Body field `prompt_cache_key` is the equivalent for Responses API. |
18 +| Response headers **(probed)** | `x-request-id`, `x-ratelimit-limit-requests`, `x-ratelimit-remaining-requests`, `x-ratelimit-limit-tokens`, `x-ratelimit-remaining-tokens` (present on inference calls; not on `/models`). Behind Cloudflare (`cf-ray`). Observed limits: grok-4.6 `7200` req / `50 000 000` tokens per window; grok-4.3 `1800` req / `10 000 000` tokens (window is per minute per the TPM docs; the RPS numbers below suggest the header window is 1 minute). |
19 +| Key introspection | `GET /v1/api-key` (redacted key, name, ACLs, team/user ids) and `GET /v1/me` (adds `zdr_status`, `team_blocked`) **(probed, 200)**. Handy for a "validate key" button: cheap, no tokens. **But** an invalid key returns **400**, not 401 (see §14). |
20 +
21 +## 2. SDK recommendation (TypeScript / Node)
22 +
23 +- **There is no official xAI JavaScript/TypeScript SDK.** `xai-sdk` is Python-only (gRPC). npm `xai-sdk` / `@xai/sdk` do not exist (checked 2026-09-08).
24 +- xAI's own docs give JS examples with **`openai` (OpenAI SDK) pointed at `baseURL: "https://api.x.ai/v1"`** and with **Vercel AI SDK `@ai-sdk/xai`** (latest **4.0.54**; `xai(model)` = Responses API since AI SDK 7, `xai.chat(model)` = legacy chat completions; exposes `xai.tools.webSearch/xSearch/codeExecution/mcpServer/…`).
25 +- **Anthropic SDK compatibility (`/v1/messages`, `/v1/complete`) is "fully deprecated"** (docs, Legacy section). Do not build on it.
26 +- **Recommendation for PolyLLM:** use the OpenAI SDK **`openai@7.10.0`** (what we probed) with `baseURL: https://api.x.ai/v1`, `maxRetries` handled by us, and a long `timeout` (docs recommend 3600 s for reasoning models; we used 120 s fine for small prompts). Both `client.chat.completions.create` and `client.responses.create` work unchanged. A raw `fetch` SSE parser also works (see §16) and is what we used to capture exact chunk shapes.
27 +
28 +## 3. Endpoints (inference + management)
29 +
30 +| Endpoint | Status | Notes |
31 +|---|---|---|
32 +| `POST /v1/responses` | **preferred** (docs: "The Responses API is the preferred way… New features come to the Responses API first") | Stateful by default (`store: true`, 30-day retention), `previous_response_id`, server-side tools, encrypted reasoning, structured outputs via `text.format`. **(probed)** |
33 +| `GET /v1/responses/{id}`, `GET /v1/responses/{id}/input_items`, `DELETE /v1/responses/{id}` | active | Delete returns `{"id","object":"response","deleted":true}` **(probed)** |
34 +| `POST /v1/responses/compact` | active | Context compaction → opaque blob to feed back verbatim (docs) |
35 +| `POST /v1/chat/completions` | **legacy but fully working** | OpenAI-compatible; `reasoning_content` returned; no deprecation date. Multi-agent model rejected here. **(probed)** |
36 +| `GET /v1/chat/deferred-completion/{request_id}` | active | For `deferred: true` requests (202 while pending, 24 h retention, single read) (docs) |
37 +| `POST /v1/completions`, `POST /v1/messages`, `POST /v1/complete` | **deprecated/legacy** | Not supported by reasoning models; Anthropic compat fully deprecated (docs) |
38 +| `GET /v1/models`, `GET /v1/models/{id}` | active | Minimal (id, aliases). **(probed)** |
39 +| `GET /v1/language-models`, `GET /v1/language-models/{id}` | active | Rich metadata + pricing (§12). **Does NOT include `context_length`** despite docs example. **(probed)** |
40 +| `GET /v1/image-generation-models`, `GET /v1/video-generation-models` (+`/{id}`) | active | Image: `image_price`, `pricing[]`, `max_prompt_length`. **(probed)** |
41 +| `POST /v1/tokenize-text` | active | `{text, model}` → `{token_ids:[{token_id,string_token,token_bytes}]}` **(probed)** — usable for client-side token counting (one network call). |
42 +| `GET /v1/api-key`, `GET /v1/me` | active | See §1 |
43 +| `POST /v1/images/generations`, `/v1/images/edits`, videos, voice (STT/TTS/speech-to-speech), `/v1/files`, collections, batches, embeddings (section exists, no text-embedding model listed) | active | Out of scope for the chat adapter except image generation (grok-imagine-*). |
44 +
45 +## 4. Chat Completions request/response (probed shapes)
46 +
47 +Request body fields (docs API ref + probes): `model`, `messages`, `max_completion_tokens` (default **128 000**; `max_tokens` is *deprecated but still accepted* **(probed)**), `temperature` 0–2, `top_p` 0–1, `n`, `seed`, `stop` (≤4; rejected by reasoning models), `frequency_penalty`/`presence_penalty` (rejected by every current model), `logit_bias`, `logprobs`/`top_logprobs` (0–8; "ignored by grok-4.20+", accepted **(probed)**), `reasoning_effort` (`none|low|medium|high|xhigh`, model-dependent), `response_format`, `tools` (≤128 docs API ref; ≤200 docs function-calling page), `tool_choice`, `parallel_tool_calls`, `stream`, `stream_options.include_usage`, `prompt_cache_key`, `service_tier` (`default|priority`), `user`, `deferred`, `web_search_options` (OpenAI compat), `search_parameters` (**dead → 410**).
48 +
49 +Roles: `system`, `user`, `assistant`, `tool`. `developer` role is **accepted** **(probed, all 6 models)**. Unknown top-level params (`foo_bar`) are **silently ignored** **(probed)**; `top_k` is accepted on chat completions although only documented for Responses **(probed)**.
50 +
51 +Non-streaming response **(probed)**:
52 +
53 +```json
54 +{
55 + "id": "…", "object": "chat.completion", "created": 1788842609, "model": "grok-4.6",
56 + "choices": [{ "index": 0, "finish_reason": "stop",
57 + "message": { "role": "assistant", "content": "2 + 2 equals 4.",
58 + "reasoning_content": "The user asked: …", "refusal": null } }],
59 + "usage": {
60 + "prompt_tokens": 652, "completion_tokens": 8, "total_tokens": 770,
61 + "prompt_tokens_details": { "text_tokens": 652, "audio_tokens": 0, "image_tokens": 0, "cached_tokens": 512 },
62 + "completion_tokens_details": { "reasoning_tokens": 110, "audio_tokens": 0,
63 + "accepted_prediction_tokens": 0, "rejected_prediction_tokens": 0 },
64 + "num_sources_used": 0, "cost_in_usd_ticks": 12440000 },
65 + "system_fingerprint": "fp_e41c6060b2628547", "service_tier": "default"
66 +}
67 +```
68 +
69 +- `total_tokens` = prompt + completion + **reasoning** (reasoning tokens are *not* inside `completion_tokens`; 652+8+110=770).
70 +- `cost_in_usd_ticks`: 10 000 000 000 ticks = $1 (docs) → 12 440 000 ticks = $0.001244. Responses API also returns `cost_in_usd_ticks` (and docs mention `cost_in_nano_usd`). **Use this for exact per-request cost display.**
71 +- `finish_reason`: `stop`, `length` (**probed**: `max_completion_tokens: 10` → `"length"` on both reasoning and non-reasoning models; on reasoning models the cap applies to *visible* tokens, reasoning still ran ~680 tokens), `tool_calls` **(probed)**. Docs also list `end_turn` (streaming).
72 +- Hidden system prompt: even a one-line prompt costs ~190–200 prompt tokens on grok-4.3/4.20/build, ~500 on grok-4.5 and ~650 on grok-4.6 **(probed)** — budget for it.
73 +
74 +## 5. Streaming protocol (chat completions) **(probed)**
75 +
76 +SSE, `Content-Type: text/event-stream`, no `event:` field, `data: {json}` lines, terminated by `data: [DONE]`.
77 +
78 +Chunk sequence for a reasoning model (grok-4.6):
79 +
80 +```json
81 +data: {"id":"1039…","object":"chat.completion.chunk","created":1788842609,"model":"grok-4.6",
82 + "choices":[{"index":0,"delta":{"reasoning_content":"The","role":"assistant"}}],
83 + "system_fingerprint":"fp_e41c6060b2628547","service_tier":"default"}
84 +data: {"…","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],…}
85 +…
86 +data: {"…","choices":[{"index":0,"delta":{"content":"Bonjour"}}],…}
87 +data: {"…","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],…}
88 +data: {"…","choices":[],"usage":{"prompt_tokens":646,"completion_tokens":3,"total_tokens":1189,
89 + "prompt_tokens_details":{…,"cached_tokens":512},
90 + "completion_tokens_details":{"reasoning_tokens":540,…},"num_sources_used":0,"cost_in_usd_ticks":37820000},…}
91 +data: [DONE]
92 +```
93 +
94 +- Delta keys observed: `role`, `reasoning_content`, `content`, `tool_calls`. Non-reasoning model (grok-4.20-non-reasoning): only `role`/`content`.
95 +- **Reasoning is streamed as `delta.reasoning_content` (plain text)** for grok-4.6, 4.5, 4.3, 4.20-reasoning, grok-build → PolyLLM can render a live "thinking" pane on chat completions without any extra flag.
96 +- Usage arrives in a **final extra chunk with `choices: []`** only when `stream_options: {include_usage: true}`; the `finish_reason` chunk is separate. No `x-ratelimit` differences for streams.
97 +- Chunks carry no per-chunk `usage` (docs' example showing usage on every chunk is outdated).
98 +
99 +## 6. Tool / function calling **(probed on all 6 models)**
100 +
101 +- Chat completions: OpenAI nested format `{type:"function", function:{name, description, parameters}}`; `tool_choice`: `auto|required|none|{type:"function",function:{name}}`; `parallel_tool_calls` (default true). Parameter root must be an object (or anyOf/oneOf of objects).
102 +- Round trip works with `assistant.tool_calls` + `{role:"tool", tool_call_id, content}` on every model.
103 +- **Streaming: the whole tool call arrives in ONE chunk** (docs + probed), with full `arguments`:
104 +
105 +```json
106 +{"delta":{"tool_calls":[{"id":"call-cbf4aac4-…-0","function":{"name":"get_weather","arguments":"{\"city\":\"Montreal\"}"},"index":0,"type":"function"}]}}
107 +```
108 + then `finish_reason: "tool_calls"`. The non-reasoning model also includes `"role":"assistant"` in that delta. Standard OpenAI accumulation code works, but you can also treat each tool_calls delta as complete. Tool-call ids look like `call-<uuid>-<n>`.
109 +- Responses API: flat tool `{type:"function", name, description, parameters}`; events `response.output_item.added` (item `type:"function_call"`, `call_id`, `name`, `arguments:""`), **one** `response.function_call_arguments.delta` with the full JSON, `response.function_call_arguments.done`, `response.output_item.done`. Return results as `{type:"function_call_output", call_id, output}` items **(probed)**.
110 +- Tool arguments are implicitly `strict` (docs: "Tool calling… implicit strict: true").
111 +
112 +## 7. Structured output **(probed on all 6 models)**
113 +
114 +- Chat completions: `response_format: {type:"json_schema", json_schema:{name, schema, strict:true}}` → valid JSON on all 6 models; `{type:"json_object"}` also works on all 6 (docs say it is accepted).
115 +- Responses API: `text: {format: {type:"json_schema", name, schema, strict:true}}` **(probed OK)**.
116 +- OpenAI SDK helpers work: `client.chat.completions.parse(... response_format: zodResponseFormat(...))` (docs).
117 +- JSON Schema support (docs): string/number/integer/boolean/null/enum/const/array/object/anyOf/oneOf/allOf(single)/$ref+$defs (non-circular); enforced formats date, time, date-time, email, uuid, ipv4, ipv6, uri; minLength/maxLength ≤2048, minItems/maxItems ≤256, min/maxProperties ≤64; `additionalProperties` defaults to **false**; rejected: empty enum/anyOf, boolean-valued properties, min/maxContains, tuple `items`. Regex: no backrefs/lookaround/\b/Unicode properties; `.` matches newline; `^`/`$` implicit. "Structured Outputs are available on Grok 4 family models."
118 +
119 +## 8. Reasoning controls **(probed matrix)**
120 +
121 +| Model | Reasoning | `reasoning_effort` accepted | `reasoning_content` returned |
122 +|---|---|---|---|
123 +| grok-4.6 | always on | `low`, `medium`, `high` (default), `xhigh`; `minimal` accepted (undocumented, likely mapped); **`none` → 400** `This model does not support \`reasoning_effort\` value \`none\`.` | yes (chat completions, plain text; Responses: `reasoning.summary[]` + optional `encrypted_content`) |
124 +| grok-4.5 | always on | `low`, `medium`, `high` (default); `xhigh`/`minimal` accepted (docs: xhigh treated as high); `none` → 400 same message | yes |
125 +| grok-4.3 | configurable | **`none` accepted → reasoning_tokens 0**, `low`, `medium`, `high`; `xhigh`/`minimal` accepted (mapped) | yes (empty when `none`) |
126 +| grok-4.20-0309-reasoning | always on, fixed | **any value → 400** `Model grok-4.20-0309-reasoning does not support parameter reasoningEffort.` | yes |
127 +| grok-4.20-0309-non-reasoning | none | any value → 400 same pattern | no (`reasoning_tokens: 0`) |
128 +| grok-build-0.1 | always on, fixed | any value → 400 same pattern | yes |
129 +| grok-4.20-multi-agent-0309 | always on | `low|medium` = 4 agents, `high|xhigh` = 16 agents (docs) | Responses only; sub-agents hidden |
130 +
131 +- Same behaviour via Responses API `reasoning: {effort}` **(probed)**: 4.20-*/build reject `low`; 4.3 accepts `none` (`reasoning.summary` becomes `"none"`, no reasoning item).
132 +- Responses API returns reasoning as an output item `{type:"reasoning", summary:[{type:"summary_text", text}], encrypted_content?}`; streamed as `response.reasoning_summary_part.added` / `response.reasoning_summary_text.delta` / `…done` / `response.reasoning_summary_part.done`. With `include: ["reasoning.encrypted_content"]` you get an opaque `encrypted_content` you can pass back in the `input` for stateless multi-turn with reasoning continuity (docs). `reasoning.summary` (`auto|concise|detailed`) is "compatibility only"; the API echoed `"summary":"detailed"` when we sent `auto`.
133 +- No thinking-budget parameter exists. Reasoning tokens are billed at the output price.
134 +
135 +## 9. Sampling & other parameters — support matrix **(probed, chat completions)**
136 +
137 +| Param | 4.6 | 4.5 | 4.3 | 4.20-reasoning | 4.20-non-reasoning | build-0.1 |
138 +|---|---|---|---|---|---|---|
139 +| `temperature` (0–2) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
140 +| `top_p` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
141 +| `top_k` (undocumented on chat) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
142 +| `seed` (+ `system_fingerprint`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
143 +| `max_completion_tokens` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
144 +| `max_tokens` (deprecated) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
145 +| `n: 2` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
146 +| `logprobs`/`top_logprobs` | ✓ (accepted; docs: ignored on 4.20+) | ✓ | ✓ | ✓ | ✓ | ✓ |
147 +| `response_format` json_object / json_schema | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
148 +| `stop` | **400** | **400** | **400** | **400** | ✓ | **400** |
149 +| `frequency_penalty` | **400** | **400** | **400** | **400** | **400** | **400** |
150 +| `presence_penalty` | **400** | **400** | **400** | **400** | **400** | **400** |
151 +| `reasoning_effort` | see §8 | | | 400 | 400 | 400 |
152 +| `developer` role | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
153 +
154 +Exact rejection text: `{"code":"invalid-argument","error":"Model grok-4.6 does not support parameter presencePenalty."}` (camelCase param names: `presencePenalty`, `frequencyPenalty`, `stop`, `reasoningEffort`). **Adapter rule: never send `frequency_penalty`/`presence_penalty` to xAI; send `stop` only to grok-4.20-0309-non-reasoning; send `reasoning_effort` only to 4.6/4.5/4.3 (and multi-agent).** On `/v1/responses`, `presence_penalty` was silently accepted and echoed as `0` **(probed)** — the Responses endpoint is more lenient; Responses defaults echoed: `temperature 0.7`, `top_p 0.95`, `truncation "disabled"`.
155 +
156 +## 10. Modalities, context, output limits
157 +
158 +- **Input**: text + image on **all 7 language models** (`input_modalities: ["text","image"]` from `/v1/language-models`; vision **probed OK on all 6 chat models**). No audio input on text models (separate voice models/endpoints). **Output**: text only. Image generation = separate models `grok-imagine-image`, `-2.0`, `-quality` via `/v1/images/generations` (also an `image_generation` server-side tool on Responses); video = `grok-imagine-video`, `-1.5`.
159 +- **Images**: JPG/PNG, ≤20 MiB, data URL `data:image/png;base64,…` or public URL, `detail: "high"` accepted, unlimited count (docs). **Hard minimums (probed, undocumented)**: width and height ≥ 8 px *and* total ≥ 512 pixels — errors `{"code":"invalid_image","error":"Image dimensions 2x2 are too small. Both width and height must be at least 8 pixels."}` / `"Image has 64 total pixels (8x8), which is below the minimum of 512 pixels."` / `"Invalid PNG image."`. A 32×32 PNG cost 1–3 `image_tokens`. Image tokens billed at the text input price (`prompt_image_token_price` == `prompt_text_token_price`).
160 +- Chat completions image format: `{type:"image_url", image_url:{url, detail}}`; Responses: `{type:"input_image", image_url:"<url or data url>", detail}` (string, not object) + `{type:"input_text", text}`.
161 +- **Context windows (docs, not in API)**: grok-4.6 **500k**, grok-4.5 **500k**, grok-4.3 / 4.20-* / multi-agent **1M**, grok-build-0.1 **256k**. `long_context_threshold` = **200 000** tokens for every model: when the prompt exceeds it, input/cached/output are all billed at **2×**.
162 +- **Max output**: docs — grok-4.6 "no text output limit"; API default `max_completion_tokens` / `max_output_tokens` = **128 000**. `max_output_tokens` on Responses *includes* reasoning tokens; `max_completion_tokens` on chat completions covers *visible* tokens only (docs + probed).
163 +- Files: `POST /v1/files` (48 MB, text/PDF/code), `input_file` with `file_id`/`file_url` on Responses, auto `attachment_search` tool ($10/1k calls), agentic models only (4.20, 4.5, 4.6). Collections (RAG) $2.50/1k searches.
164 +
165 +## 11. Server-side (agentic) tools, search, citations **(probed on grok-4.3 via /v1/responses)**
166 +
167 +- **Live Search (`search_parameters`) is dead**: chat completions → **410** `{"error":"Live search is deprecated. Please switch to the Agent Tools API: https://docs.x.ai/docs/guides/tools/overview"}`; `tools:[{type:"live_search",sources:[…]}]` → 410 too; `tools:[{type:"web_search"}]` on chat completions → **422** `tools[0].type: unknown variant \`web_search\`, expected \`function\` or \`live_search\``. **Server-side tools are Responses-API-only.**
168 +- Responses tools: `{type:"web_search", allowed_domains?(≤5), excluded_domains?(≤5), enable_image_understanding?, enable_image_search?}`, `{type:"x_search", allowed_x_handles?/excluded_x_handles? (≤20), from_date?, to_date?, enable_image_understanding?, enable_video_understanding?}`, `{type:"code_interpreter"}` (sandboxed Python), `{type:"mcp", server_url, server_label, server_description?, allowed_tools?, authorization?, headers?}` (Streamable HTTP/SSE), `{type:"file_search"}` / `collections_search`, `{type:"image_generation"}`. `max_turns` caps agentic loops. Tool-call output is *not* returned by default; docs' `include` values (`web_search_call_output`, …) are **rejected** (`400 Argument not supported: "web_search_call_output" in "include" field`) — what *is* accepted: `include: ["web_search_call.action.sources"]` and `["no_inline_citations"]` **(probed)**.
169 +- Streaming event names observed with web_search: `response.created`, `response.in_progress`, `response.output_item.added`, `response.reasoning_summary_part.added`, `response.reasoning_summary_text.delta`, `response.reasoning_summary_text.done`, `response.reasoning_summary_part.done`, `response.output_item.done`, `response.web_search_call.in_progress`, `response.web_search_call.searching`, `response.web_search_call.completed`, `response.content_part.added`, `response.output_text.delta`, **`response.output_text.annotation.added`**, `response.output_text.done`, `response.content_part.done`, `response.completed`. Each event has `sequence_number`, `item_id`, `output_index`.
170 +- **Citations**: (1) inline Markdown `[[N]](url)` in the text (default on; disable with `include:["no_inline_citations"]`), (2) `annotations: [{type:"url_citation", url, start_index, end_index, title:"1"}]` on the `output_text` part, (3) `output[]` items `{type:"web_search_call", status, action:{type:"search", query, sources:[{type:"url", url}]}}` (one per search, 3 searches for our question). A top-level `response.citations` field was **not** present in the REST response (the docs' `response.citations` is the Python SDK). Usage adds `num_server_side_tools_used`, `server_side_tool_usage_details:{web_search_calls, x_search_calls, code_interpreter_calls, file_search_calls, mcp_calls, document_search_calls, image_generation_calls}` and `context_details`. Our single question consumed **20 919 input tokens** (11 072 cached) + 856 output → ≈ $0.032 + 3 × $0.005 tool calls. Budget accordingly.
171 +- Tool pricing (docs): web/X search $5 per 1 000 calls, code execution $5/1k, file attachments $10/1k, collections $2.50/1k; image/video understanding token-based.
172 +- No computer-use tool. Image generation available as a tool and as `/v1/images/generations`.
173 +
174 +## 12. Model listing & pricing units **(probed)**
175 +
176 +`GET /v1/language-models` fields: `id, fingerprint, created, object, owned_by, version, input_modalities, output_modalities, prompt_text_token_price, cached_prompt_text_token_price, prompt_image_token_price, completion_text_token_price, search_price, prompt_text_token_price_long_context, cached_prompt_text_token_price_long_context, completion_text_token_price_long_context, long_context_threshold, aliases`. **No `context_length`, no max output.**
177 +
178 +**Unit (verified against the pricing page): USD cents per 100 000 000 tokens → `$ per 1M tokens = value / 10 000`.** grok-4.6 `prompt_text_token_price: 20000` → $2.00/M ✓; `cached 5000` → $0.50 ✓; `completion 60000` → $6.00 ✓; grok-4.3 `12500` → $1.25 ✓. Image models: `image_price` in 1/100 000 000 cent → `grok-imagine-image 200000000` = $0.02 ✓.
179 +
180 +| Model | ctx (docs) | in / cached / out ($/M, <200k) | ≥200k tokens | aliases |
181 +|---|---|---|---|---|
182 +| grok-4.6 | 500k | 2.00 / 0.50 / 6.00 | 4.00 / 1.00 / 12.00 | — |
183 +| grok-4.5 | 500k | 2.00 / 0.30 / 6.00 | 4.00 / 0.60 / 12.00 | grok-4.5-latest, **grok-build-latest** |
184 +| grok-4.3 | 1M | 1.25 / 0.20 / 2.50 | 2.50 / 0.40 / 5.00 | grok-4.3-latest |
185 +| grok-4.20-0309-reasoning | 1M | 1.25 / 0.20 / 2.50 | 2.50 / 0.40 / 5.00 | grok-4.20, grok-4.20-reasoning, … (15) |
186 +| grok-4.20-0309-non-reasoning | 1M | 1.25 / 0.20 / 2.50 | 2.50 / 0.40 / 5.00 | grok-4.20-non-reasoning, … (8) |
187 +| grok-4.20-multi-agent-0309 | 1M | 1.25 / 0.20 / 2.50 (all agents billed) | 2.50 / 0.40 / 5.00 | grok-4.20-multi-agent, … (6) |
188 +| grok-build-0.1 | 256k | 1.00 / 0.20 / 2.00 | 2.00 / 0.40 / 4.00 | grok-code-fast-1, grok-code-fast, grok-code-fast-1-0825 |
189 +
190 +Image gen: grok-imagine-image $0.02, -2.0 $0.04 (pricing[] by quality/resolution 0.04–0.08), -quality $0.05 (retiring **2026-11-02** → redirected to -2.0 low). Video $0.05/s, -1.5 $0.08/s. Batch API −20 % on grok-4.3 and grok-4.20 variants only. `service_tier: "priority"` = 2× tokens. Knowledge cutoff grok-4.6: 2026-02-01.
191 +
192 +## 13. Prompt caching & provider-side state
193 +
194 +- **Automatic** on all grok language models, prefix-based on the messages array; no minimum documented; no fixed TTL ("can be evicted at any time"). Reported as `usage.prompt_tokens_details.cached_tokens` (chat) / `usage.input_tokens_details.cached_tokens` (Responses). **(probed: 128–512 cached tokens on the very first request — the hidden system prompt is cached.)** Cached price = 10–25 % of input price (see table). Maximise hits with `x-grok-conv-id` header (chat) or `prompt_cache_key` (Responses) = stable session id; never edit earlier messages.
195 +- **Server-side state**: Responses API stores everything for 30 days by default (`store: true` echoed **(probed)**), `previous_response_id` continuation works **(probed: recalled "pamplemousse")**, `instructions` incompatible with `previous_response_id` (docs). For a BYOK privacy-conscious app **send `store: false`** and manage history client-side (docs image page even recommends not storing). `zdr_status` on `/v1/me` tells whether the team has zero-data-retention.
196 +
197 +## 14. Errors, rate limits, retries
198 +
199 +Error body: `{"code": "<string>", "error": "<message>"}` (not OpenAI's `{error:{message,type,code}}` — the OpenAI SDK will surface `e.error` = that object, `e.message` derived).
200 +
201 +| Case **(probed)** | HTTP | body |
202 +|---|---|---|
203 +| Invalid key | **400** | `{"code":"invalid-argument","error":"Incorrect API key provided. You can obtain an API key from https://console.x.ai."}` |
204 +| No Authorization header | 401 | `{"code":"unauthenticated:no-credentials","error":"No credentials presented."}` |
205 +| Unknown model | 400 | `{"code":"invalid-argument","error":"Model not found: grok-99"}` |
206 +| Unsupported param | 400 | `{"code":"invalid-argument","error":"Model X does not support parameter presencePenalty."}` |
207 +| Malformed body | 422 (text/plain) | serde message |
208 +| Bad image | 400 | `{"code":"invalid_image","error":"…"}` |
209 +| Bad `include` | 400 | `{"code":"400","error":"Argument not supported: …"}` |
210 +| Live search | 410 | `{"error":"Live search is deprecated. …"}` (no `code`) |
211 +| Multi-agent on chat completions | 400 (text/plain) | `Multi Agent requests are not allowed on chat completions` |
212 +| Rate limit | 429 (docs) | exponential backoff recommended |
213 +
214 +Docs also list 403 (permissions/ACL), 404, 405, 415, 202 (deferred). Rate limits (docs, tiers by cumulative spend since 2026-01-01, never downgrade): T0 $0 → T4 $5 000; grok-4.6/4.5: 150 RPS / 50M TPM (T0) → 500 RPS / 100M TPM (T4); grok-4.3, 4.20-*, build: 37 RPS / 10M TPM → 208 RPS / 85M; multi-agent 9 RPS / 2.5M → 56 / 21M. TPM counts prompt + completion + reasoning + cached tokens. Headers in §1. Status page https://status.x.ai.
215 +
216 +**Retry/timeout recommendation for the adapter:** retry 429/5xx with jittered exponential backoff (respect `retry-after` if present — none observed), never retry 400/422; do not retry mid-stream; use a long read timeout (≥ 5 min; xAI suggests 3600 s) because `xhigh` reasoning can run minutes before the first `content` delta (but `reasoning_content` deltas arrive quickly, which is a good liveness signal). Map xAI 400 "Incorrect API key" to the app's *invalid credentials* state (do not rely on 401).
217 +
218 +## 15. Lifecycle / aliases
219 +
220 +- May 15 2026 retirement: `grok-3`, `grok-4-0709`, `grok-4-fast-*`, `grok-4-1-fast-*`, `grok-code-fast-1`, `grok-imagine-image-pro`. Slugs still resolve **(probed: `grok-3` and `grok-4-fast-reasoning` answered with `model: "grok-4.3"` and were billed at 4.3 rates)**; reasoning slugs → grok-4.3 `low`, non-reasoning → grok-4.3 `none`, grok-code-fast-1 → grok-build-0.1. Do **not** list retired slugs in the UI; if a user types one, show the redirect.
221 +- `-latest` aliases exist for 4.5, 4.3, 4.20-*; grok-4.6 has none yet. `grok-build-latest` → grok-4.5 (surprising). Use canonical ids from `/v1/language-models` and display aliases as secondary.
222 +- grok-4.20-multi-agent is **beta** ("potential breaking changes"), Responses-only, no client tools.
223 +- Docs pages under `/docs/*` are gone; only `/developers/*` is maintained.
224 +
225 +## 16. Exact streaming code that worked
226 +
227 +OpenAI SDK (`openai@7.10.0`) — chat completions with reasoning + usage:
228 +
229 +```ts
230 +import OpenAI from "openai";
231 +const client = new OpenAI({ apiKey: process.env.XAI_API_KEY, baseURL: "https://api.x.ai/v1", timeout: 3_600_000, maxRetries: 0 });
232 +
233 +const stream = await client.chat.completions.create({
234 + model: "grok-4.6",
235 + messages: [{ role: "user", content: "Say hello in French, 5 words max." }],
236 + stream: true,
237 + stream_options: { include_usage: true },
238 + max_completion_tokens: 200,
239 + reasoning_effort: "low", // only 4.6 / 4.5 / 4.3
240 +}, { headers: { "x-grok-conv-id": sessionId } });
241 +
242 +for await (const chunk of stream) {
243 + const d = (chunk.choices[0]?.delta ?? {}) as any;
244 + if (d.reasoning_content) onThinking(d.reasoning_content);
245 + if (d.content) onText(d.content);
246 + if (d.tool_calls) onToolCalls(d.tool_calls); // arrives complete in one chunk
247 + if (chunk.choices[0]?.finish_reason) onFinish(chunk.choices[0].finish_reason);
248 + if (chunk.usage) onUsage(chunk.usage); // last chunk, choices: []
249 +}
250 +```
251 +
252 +Raw fetch SSE for `/v1/responses` (used in `research/xai/lib.ts` → `rawSSE`): POST JSON, read `res.body` with `TextDecoder`, split on `\n\n`, take `data:` lines, `JSON.parse`, stop at `[DONE]`; each event's `type` field is the event name (`response.output_text.delta` → `delta`, `response.completed` → `response.usage`, `response.function_call_arguments.done` → `arguments`, `response.output_text.annotation.added` → citation).
253 +
254 +## 17. Probe results table
255 +
256 +| # | Probe | Model(s) | Result |
257 +|---|---|---|---|
258 +| 00 | `GET /models`, `/language-models`, `/image-generation-models`, `/video-generation-models`, `/api-key`, `/me`, `POST /tokenize-text` | — | all 200; 7 language, 3 image, 2 video models; prices in cents/100M tokens; no context_length; tokenizer returns token ids + bytes |
259 +| 01a | tiny chat completion `max_completion_tokens: 200` | 6 models | all 200, `finish_reason: stop`; `reasoning_content` present on 5/6; reasoning 46–333 tokens for "2+2"; ~2.6 s for grok-4.6 |
260 +| 01b | streaming + `include_usage` | 6 models | SSE `data:` only; `delta.reasoning_content` then `delta.content`; final `choices: []` usage chunk with `cached_tokens`, `reasoning_tokens`, `cost_in_usd_ticks`; `[DONE]` |
261 +| 02 | param matrix (21 variants) | 6 models | see §9; penalties rejected everywhere; `stop` only on non-reasoning; `reasoning_effort` per §8; unknown params ignored |
262 +| 03 | function call round trip, streaming | 6 models | tool call in a single chunk with complete `arguments`; `finish_reason: tool_calls`; round 2 with `role: tool` OK on all |
263 +| 04 | `response_format: json_schema` strict | 6 models | valid JSON matching schema on all |
264 +| 05 | vision, base64 PNG data URL | 6 models | 2×2 → 400 (min 8 px sides); 8×8 → 400 (min 512 px total); 32×32 → 200 on all, `image_tokens` 1–3 |
265 +| 06 | invalid key / no auth / unknown model / bad body / retired slugs | — | 400 invalid-argument / 401 / 400 / 422 text / 200 served by grok-4.3 |
266 +| 07 | `/v1/responses`: basic + `reasoning.summary` + `encrypted_content`, streaming events, function call (flat tool) + `function_call_output`, `text.format` json_schema, `input_image`, multi-agent on chat | grok-4.3 (+multi-agent) | all 200; 13 event types; encrypted reasoning returned; multi-agent on chat completions → 400 |
267 +| 08 | web_search tool streaming; legacy `search_parameters`; `web_search` on chat; `include` variants | grok-4.3 | Responses OK (3 searches, `url_citation` annotations + inline `[[N]](url)`, 20.9k input tokens); chat: 410 / 422; `include` accepts `web_search_call.action.sources`, `no_inline_citations` only |
268 +| 09 | `finish_reason` on truncation; Responses `reasoning.effort` on 4.20/build/4.3; `x-grok-conv-id` + `prompt_cache_key` + `service_tier`; `store` default + `previous_response_id` + DELETE | mixed | `length`; 4.20/build reject effort, 4.3 `none` OK; header/params accepted, `service_tier: default`; store default `true`, follow-up recalled word, delete → `deleted: true` |
269 +| 10 | `tools:[{type:"live_search", sources:[{type:"web"}]}]` on chat | grok-4.3 | 410 Live search deprecated |
270 +
271 +## Documentation pages used (all fetched 2026-09-08)
272 +
273 +- https://docs.x.ai/docs/overview (redirect hub) · https://docs.x.ai/developers/quickstart · https://docs.x.ai/developers/community · https://docs.x.ai/developers/release-notes
274 +- https://docs.x.ai/developers/models · https://docs.x.ai/developers/grok-4-6 · https://docs.x.ai/developers/pricing · https://docs.x.ai/developers/rate-limits · https://docs.x.ai/developers/migration/may-15-retirement
275 +- https://docs.x.ai/developers/rest-api-reference/inference/chat-completions · https://docs.x.ai/developers/rest-api-reference/inference/responses · https://docs.x.ai/developers/rest-api-reference/inference/models · https://docs.x.ai/developers/rest-api-reference/inference/legacy · https://docs.x.ai/developers/rest-api-reference/inference/other
276 +- https://docs.x.ai/developers/model-capabilities/text/generate-text · …/text/streaming · …/text/reasoning · …/text/structured-outputs · …/text/multi-agent · …/text/comparison (Responses vs Chat Completions migration) · https://docs.x.ai/developers/model-capabilities/legacy/chat-completions · https://docs.x.ai/developers/model-capabilities/images/understanding
277 +- https://docs.x.ai/developers/tools/overview · …/tools/function-calling · …/tools/web-search · …/tools/x-search · …/tools/code-execution · …/tools/remote-mcp · …/tools/citations · …/tools/streaming-and-sync · …/tools/tool-usage-details
278 +- https://docs.x.ai/developers/advanced-api-usage/prompt-caching (+ /how-it-works, /usage-and-pricing, /best-practices) · …/batch-api · …/priority-processing · …/deferred-chat-completions · …/context-compaction · https://docs.x.ai/developers/files · https://docs.x.ai/developers/debugging
279 +- https://docs.x.ai/sitemap.xml (to discover the new paths) · https://ai-sdk.dev/providers/ai-sdk-providers/xai (Vercel provider)
280 +- 404 at audit time: `/docs/guides/responses`, `/docs/api-reference`, `/docs/guides/migration`, `/docs/key-information/rate-limits`, `/docs/guides/prompt-caching`, `/developers/rest-api-reference/inference/legacy-deprecated`, `/developers/rest-api-reference/inference/account`, `/developers/advanced-api-usage/rate-limits`, `/developers/advanced-api-usage/migration`, `/developers/advanced-api-usage/error-handling`, `/developers/model-capabilities/text/chat-completions`.
added docs/provider-research/xai.models.json +356 −0
@@ -0,0 +1,356 @@
1 +[
2 + {
3 + "id": "grok-4.6",
4 + "displayName": "Grok 4.6",
5 + "family": "grok-4.6",
6 + "contextTokens": 500000,
7 + "maxOutputTokens": 128000,
8 + "capabilities": {
9 + "text": true,
10 + "vision": true,
11 + "audioInput": false,
12 + "audioOutput": false,
13 + "imageGeneration": false,
14 + "video": false,
15 + "reasoning": true,
16 + "tools": true,
17 + "structuredOutput": true,
18 + "streaming": true,
19 + "files": true,
20 + "webSearch": true
21 + },
22 + "parameters": {
23 + "temperature": true,
24 + "topP": true,
25 + "topK": "accepted-on-chat-completions-undocumented",
26 + "maxTokens": true,
27 + "reasoningEffort": ["low", "medium", "high", "xhigh"],
28 + "thinkingBudget": false,
29 + "stop": false,
30 + "seed": true,
31 + "frequencyPenalty": false,
32 + "presencePenalty": false
33 + },
34 + "pricing": {
35 + "inputPerMillion": 2.0,
36 + "cachedInputPerMillion": 0.5,
37 + "outputPerMillion": 6.0,
38 + "longContextThresholdTokens": 200000,
39 + "longContextInputPerMillion": 4.0,
40 + "longContextCachedInputPerMillion": 1.0,
41 + "longContextOutputPerMillion": 12.0,
42 + "imageInputPerMillionTokens": 2.0
43 + },
44 + "status": "active",
45 + "aliases": [],
46 + "notes": "Flagship (Aug 2026). Always-reasoning; reasoning_effort default high, 'none' rejected ('This model does not support `reasoning_effort` value `none`'). reasoning_content returned in chat completions (plain text, also streamed as delta.reasoning_content). Knowledge cutoff 2026-02-01. Docs: 'no text output limit'; API default cap max_completion_tokens=128000. Large hidden system prompt (~640 prompt tokens on an empty request). Supports web_search/x_search/code_interpreter/mcp/file tools on /v1/responses. Rate-limit headers observed: 7200 req / 50M tokens per window."
47 + },
48 + {
49 + "id": "grok-4.5",
50 + "displayName": "Grok 4.5",
51 + "family": "grok-4.5",
52 + "contextTokens": 500000,
53 + "maxOutputTokens": 128000,
54 + "capabilities": {
55 + "text": true,
56 + "vision": true,
57 + "audioInput": false,
58 + "audioOutput": false,
59 + "imageGeneration": false,
60 + "video": false,
61 + "reasoning": true,
62 + "tools": true,
63 + "structuredOutput": true,
64 + "streaming": true,
65 + "files": true,
66 + "webSearch": true
67 + },
68 + "parameters": {
69 + "temperature": true,
70 + "topP": true,
71 + "topK": "accepted-on-chat-completions-undocumented",
72 + "maxTokens": true,
73 + "reasoningEffort": ["low", "medium", "high"],
74 + "thinkingBudget": false,
75 + "stop": false,
76 + "seed": true,
77 + "frequencyPenalty": false,
78 + "presencePenalty": false
79 + },
80 + "pricing": {
81 + "inputPerMillion": 2.0,
82 + "cachedInputPerMillion": 0.3,
83 + "outputPerMillion": 6.0,
84 + "longContextThresholdTokens": 200000,
85 + "longContextInputPerMillion": 4.0,
86 + "longContextCachedInputPerMillion": 0.6,
87 + "longContextOutputPerMillion": 12.0,
88 + "imageInputPerMillionTokens": 2.0
89 + },
90 + "status": "active",
91 + "aliases": ["grok-4.5-latest", "grok-build-latest"],
92 + "notes": "Coding/agentic model (Jul 2026). Always-reasoning; 'none' rejected; 'xhigh' accepted by the API but docs say it is treated as 'high' on models that do not support it. Very few reasoning tokens on trivial prompts (~13-50). reasoning_content returned. Note the alias 'grok-build-latest' points here, not to grok-build-0.1."
93 + },
94 + {
95 + "id": "grok-4.3",
96 + "displayName": "Grok 4.3",
97 + "family": "grok-4.3",
98 + "contextTokens": 1000000,
99 + "maxOutputTokens": 128000,
100 + "capabilities": {
101 + "text": true,
102 + "vision": true,
103 + "audioInput": false,
104 + "audioOutput": false,
105 + "imageGeneration": false,
106 + "video": false,
107 + "reasoning": true,
108 + "tools": true,
109 + "structuredOutput": true,
110 + "streaming": true,
111 + "files": true,
112 + "webSearch": true
113 + },
114 + "parameters": {
115 + "temperature": true,
116 + "topP": true,
117 + "topK": "accepted-on-chat-completions-undocumented",
118 + "maxTokens": true,
119 + "reasoningEffort": ["none", "low", "medium", "high"],
120 + "thinkingBudget": false,
121 + "stop": false,
122 + "seed": true,
123 + "frequencyPenalty": false,
124 + "presencePenalty": false
125 + },
126 + "pricing": {
127 + "inputPerMillion": 1.25,
128 + "cachedInputPerMillion": 0.2,
129 + "outputPerMillion": 2.5,
130 + "longContextThresholdTokens": 200000,
131 + "longContextInputPerMillion": 2.5,
132 + "longContextCachedInputPerMillion": 0.4,
133 + "longContextOutputPerMillion": 5.0,
134 + "imageInputPerMillionTokens": 1.25
135 + },
136 + "status": "active",
137 + "aliases": ["grok-4.3-latest"],
138 + "notes": "Best value general model; 1M context. The ONLY probed model that accepts reasoning_effort 'none' (reasoning_tokens=0 -> effectively a non-reasoning mode). 'xhigh' accepted (docs/AI SDK say not supported -> treated as high). Retired May-15-2026 slugs (grok-3, grok-4-0709, grok-4-fast-*, grok-4-1-fast-*) are transparently served by grok-4.3 (response.model = 'grok-4.3'). Retired non-reasoning slugs map to effort 'none', reasoning slugs to 'low'. reasoning_content returned. Batch API 20% discount."
139 + },
140 + {
141 + "id": "grok-4.20-0309-reasoning",
142 + "displayName": "Grok 4.20 Reasoning (0309)",
143 + "family": "grok-4.20",
144 + "contextTokens": 1000000,
145 + "maxOutputTokens": 128000,
146 + "capabilities": {
147 + "text": true,
148 + "vision": true,
149 + "audioInput": false,
150 + "audioOutput": false,
151 + "imageGeneration": false,
152 + "video": false,
153 + "reasoning": true,
154 + "tools": true,
155 + "structuredOutput": true,
156 + "streaming": true,
157 + "files": true,
158 + "webSearch": true
159 + },
160 + "parameters": {
161 + "temperature": true,
162 + "topP": true,
163 + "topK": "accepted-on-chat-completions-undocumented",
164 + "maxTokens": true,
165 + "reasoningEffort": false,
166 + "thinkingBudget": false,
167 + "stop": false,
168 + "seed": true,
169 + "frequencyPenalty": false,
170 + "presencePenalty": false
171 + },
172 + "pricing": {
173 + "inputPerMillion": 1.25,
174 + "cachedInputPerMillion": 0.2,
175 + "outputPerMillion": 2.5,
176 + "longContextThresholdTokens": 200000,
177 + "longContextInputPerMillion": 2.5,
178 + "longContextCachedInputPerMillion": 0.4,
179 + "longContextOutputPerMillion": 5.0,
180 + "imageInputPerMillionTokens": 1.25
181 + },
182 + "status": "active",
183 + "aliases": [
184 + "grok-4.20-reasoning-latest",
185 + "grok-4.20",
186 + "grok-4.20-reasoning",
187 + "grok-4.20-0309",
188 + "grok-4.20-beta-0309-reasoning",
189 + "grok-4.20-beta",
190 + "grok-4.20-beta-0309",
191 + "grok-4.20-beta-latest",
192 + "grok-4.20-beta-latest-reasoning",
193 + "grok-4.20-beta-reasoning",
194 + "grok-4.20-experimental-beta-0304-reasoning",
195 + "grok-4.20-experimental-beta-0304",
196 + "grok-4.20-experimental-beta-reasoning-latest",
197 + "grok-4.20-experimental-beta-latest",
198 + "grok-4.20-reasoning-gv2"
199 + ],
200 + "notes": "Always-reasoning, fixed depth: ANY reasoning_effort value (incl. 'none') is rejected with 400 'Model grok-4.20-0309-reasoning does not support parameter reasoningEffort.' (both chat completions and /v1/responses reasoning.effort). reasoning_content returned. Occasionally emits stray '\\\\confidence{NN}' tokens after the answer on trivial prompts (observed with top_k/logprobs). Batch API 20% discount."
201 + },
202 + {
203 + "id": "grok-4.20-0309-non-reasoning",
204 + "displayName": "Grok 4.20 Non-Reasoning (0309)",
205 + "family": "grok-4.20",
206 + "contextTokens": 1000000,
207 + "maxOutputTokens": 128000,
208 + "capabilities": {
209 + "text": true,
210 + "vision": true,
211 + "audioInput": false,
212 + "audioOutput": false,
213 + "imageGeneration": false,
214 + "video": false,
215 + "reasoning": false,
216 + "tools": true,
217 + "structuredOutput": true,
218 + "streaming": true,
219 + "files": true,
220 + "webSearch": true
221 + },
222 + "parameters": {
223 + "temperature": true,
224 + "topP": true,
225 + "topK": "accepted-on-chat-completions-undocumented",
226 + "maxTokens": true,
227 + "reasoningEffort": false,
228 + "thinkingBudget": false,
229 + "stop": true,
230 + "seed": true,
231 + "frequencyPenalty": false,
232 + "presencePenalty": false
233 + },
234 + "pricing": {
235 + "inputPerMillion": 1.25,
236 + "cachedInputPerMillion": 0.2,
237 + "outputPerMillion": 2.5,
238 + "longContextThresholdTokens": 200000,
239 + "longContextInputPerMillion": 2.5,
240 + "longContextCachedInputPerMillion": 0.4,
241 + "longContextOutputPerMillion": 5.0,
242 + "imageInputPerMillionTokens": 1.25
243 + },
244 + "status": "active",
245 + "aliases": [
246 + "grok-4.20-non-reasoning",
247 + "grok-4.20-non-reasoning-latest",
248 + "grok-4.20-beta-non-reasoning",
249 + "grok-4.20-beta-latest-non-reasoning",
250 + "grok-4.20-experimental-beta-0304-non-reasoning",
251 + "grok-4.20-experimental-beta-non-reasoning-latest",
252 + "grok-4.20-beta-0309-non-reasoning",
253 + "grok-4.20-non-reasoning-gv2"
254 + ],
255 + "notes": "The only true non-reasoning model in the lineup (fastest TTFT, reasoning_tokens always 0, no reasoning_content). The ONLY model that accepts `stop`. reasoning_effort rejected. frequency/presence_penalty still rejected (400). Good default for cheap/fast chat. Batch API 20% discount."
256 + },
257 + {
258 + "id": "grok-4.20-multi-agent-0309",
259 + "displayName": "Grok 4.20 Multi-Agent (0309, beta)",
260 + "family": "grok-4.20",
261 + "contextTokens": 1000000,
262 + "maxOutputTokens": null,
263 + "capabilities": {
264 + "text": true,
265 + "vision": true,
266 + "audioInput": false,
267 + "audioOutput": false,
268 + "imageGeneration": false,
269 + "video": false,
270 + "reasoning": true,
271 + "tools": "server-side-only",
272 + "structuredOutput": null,
273 + "streaming": true,
274 + "files": true,
275 + "webSearch": true
276 + },
277 + "parameters": {
278 + "temperature": null,
279 + "topP": null,
280 + "topK": null,
281 + "maxTokens": false,
282 + "reasoningEffort": ["low", "medium", "high", "xhigh"],
283 + "thinkingBudget": false,
284 + "stop": false,
285 + "seed": null,
286 + "frequencyPenalty": false,
287 + "presencePenalty": false
288 + },
289 + "pricing": {
290 + "inputPerMillion": 1.25,
291 + "cachedInputPerMillion": 0.2,
292 + "outputPerMillion": 2.5,
293 + "longContextThresholdTokens": 200000,
294 + "longContextInputPerMillion": 2.5,
295 + "longContextCachedInputPerMillion": 0.4,
296 + "longContextOutputPerMillion": 5.0,
297 + "imageInputPerMillionTokens": 1.25
298 + },
299 + "status": "beta",
300 + "aliases": [
301 + "grok-4.20-multi-agent",
302 + "grok-4.20-multi-agent-latest",
303 + "grok-4.20-multi-agent-beta-latest",
304 + "grok-4.20-multi-agent-experimental-beta-0304",
305 + "grok-4.20-multi-agent-experimental-beta-latest",
306 + "grok-4.20-multi-agent-beta-0309"
307 + ],
308 + "notes": "/v1/responses ONLY: chat completions returns 400 'Multi Agent requests are not allowed on chat completions' (probed). reasoning.effort selects agent count (low/medium = 4 agents, high/xhigh = 16), not depth. No client-side function tools, no max_tokens. All leader + sub-agent tokens billed -> expensive; lower rate limits (T0 9 RPS / 2.5M TPM). Not probed for generation (cost). Deliberately NOT recommended as a default chat model in PolyLLM."
309 + },
310 + {
311 + "id": "grok-build-0.1",
312 + "displayName": "Grok Build 0.1",
313 + "family": "grok-build",
314 + "contextTokens": 256000,
315 + "maxOutputTokens": 128000,
316 + "capabilities": {
317 + "text": true,
318 + "vision": true,
319 + "audioInput": false,
320 + "audioOutput": false,
321 + "imageGeneration": false,
322 + "video": false,
323 + "reasoning": true,
324 + "tools": true,
325 + "structuredOutput": true,
326 + "streaming": true,
327 + "files": null,
328 + "webSearch": null
329 + },
330 + "parameters": {
331 + "temperature": true,
332 + "topP": true,
333 + "topK": "accepted-on-chat-completions-undocumented",
334 + "maxTokens": true,
335 + "reasoningEffort": false,
336 + "thinkingBudget": false,
337 + "stop": false,
338 + "seed": true,
339 + "frequencyPenalty": false,
340 + "presencePenalty": false
341 + },
342 + "pricing": {
343 + "inputPerMillion": 1.0,
344 + "cachedInputPerMillion": 0.2,
345 + "outputPerMillion": 2.0,
346 + "longContextThresholdTokens": 200000,
347 + "longContextInputPerMillion": 2.0,
348 + "longContextCachedInputPerMillion": 0.4,
349 + "longContextOutputPerMillion": 4.0,
350 + "imageInputPerMillionTokens": 1.0
351 + },
352 + "status": "active",
353 + "aliases": ["grok-code-fast-1", "grok-code-fast", "grok-code-fast-1-0825"],
354 + "notes": "Cheapest text model; successor of grok-code-fast-1 (those slugs alias here). Always-reasoning with fixed depth: every reasoning_effort value rejected (400 'does not support parameter reasoningEffort'). Tends to spend many reasoning tokens even on trivial prompts (300-650). reasoning_content returned. Coding-oriented; image input accepted (image_tokens billed)."
355 + }
356 +]
added docs/provider-test-matrix.md +34 −0
@@ -0,0 +1,34 @@
1 +# Provider test matrix
2 +
3 +Generated by `pnpm providers:matrix` against the REAL provider APIs on 2026-09-08. A cell is ✅ only when the live request succeeded and the assertion passed. “—” = not run (no key).
4 +
5 +Test models: openai: gpt-5.4-mini / reasoning gpt-5.4-mini; anthropic: claude-haiku-4-5 / reasoning claude-sonnet-5; gemini: gemini-3.5-flash-lite / reasoning gemini-3.5-flash-lite; xai: grok-4.20-0309-non-reasoning / reasoning grok-4.3.
6 +
7 +| Capability | OpenAI | Anthropic | Gemini | xAI |
8 +| --- | :-: | :-: | :-: | :-: |
9 +| Auth | ✅ | ✅ | ✅ | ✅ |
10 +| Model list | ✅ | ✅ | ✅ | ✅ |
11 +| Text | ✅ | ✅ | ✅ | ✅ |
12 +| Streaming | ✅ | ✅ | ✅ | ✅ |
13 +| System | ✅ | ✅ | ✅ | ✅ |
14 +| Vision | ✅ | ✅ | ✅ | ✅ |
15 +| Tools | ✅ | ✅ | ✅ | ✅ |
16 +| Structured output | ✅ | ✅ | ✅ | ✅ |
17 +| Reasoning | ✅ | ✅ | ✅ | ✅ |
18 +| Token usage | ✅ | ✅ | ✅ | ✅ |
19 +| Invalid key | ✅ | ✅ | ✅ | ✅ |
20 +| Error normalization | ✅ | ✅ | ✅ | ✅ |
21 +| Long response | ✅ | ✅ | ✅ | ✅ |
22 +
23 +## Notes
24 +
25 +- gemini: models: 18 (gemini-2.5-flash, gemini-2.5-pro, gemma-4-26b-a4b-it, gemma-4-31b-it, gemini-flash-latest…)
26 +- gemini: text(gemini-3.5-flash-lite): "OK" deltas=1 usage={"inputTokens":6,"outputTokens":1,"totalTokens":7} finish=stop
27 +- gemini: system: "Arr, hello there, me hearty!"
28 +- gemini: vision: "Red"
29 +- gemini: tools: [{"n":"calculator","a":{"expression":"1234 * 5678"}}] finish=tool-calls
30 +- gemini: structured: { "city": "Ottawa", "country": "Canada" }
31 +- gemini: reasoning(gemini-3.5-flash-lite): text="16" reasoningChars=2115 reasoningTokens=3907
32 +- gemini: invalid key → INVALID_API_KEY (400)
33 +- gemini: unknown model → MODEL_NOT_FOUND: { "error": { "code": 404, "message": "models/definitely-not-a-model-xyz is not f
34 +- gemini: long: 471 words, 25 deltas
added drizzle.config.ts +10 −0
@@ -0,0 +1,10 @@
1 +import { defineConfig } from "drizzle-kit";
2 +
3 +export default defineConfig({
4 + dialect: "postgresql",
5 + schema: "./src/db/schema.ts",
6 + out: "./drizzle",
7 + dbCredentials: { url: process.env.DATABASE_URL ?? "postgres://localhost:5432/polyllm" },
8 + strict: true,
9 + verbose: false,
10 +});
added drizzle/0000_foamy_loners.sql +370 −0
@@ -0,0 +1,370 @@
1 +CREATE TABLE "accounts" (
2 + "id" text PRIMARY KEY NOT NULL,
3 + "account_id" text NOT NULL,
4 + "provider_id" text NOT NULL,
5 + "user_id" text NOT NULL,
6 + "access_token" text,
7 + "refresh_token" text,
8 + "id_token" text,
9 + "access_token_expires_at" timestamp with time zone,
10 + "refresh_token_expires_at" timestamp with time zone,
11 + "scope" text,
12 + "password" text,
13 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
14 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
15 +);
16 +--> statement-breakpoint
17 +CREATE TABLE "arena_responses" (
18 + "id" text PRIMARY KEY NOT NULL,
19 + "session_id" text NOT NULL,
20 + "model_key" text NOT NULL,
21 + "provider" text NOT NULL,
22 + "content" text DEFAULT '' NOT NULL,
23 + "reasoning" text,
24 + "status" text DEFAULT 'complete' NOT NULL,
25 + "error" jsonb,
26 + "usage" jsonb,
27 + "latency_ms" integer,
28 + "ttft_ms" integer,
29 + "cost_usd" double precision,
30 + "ratings" jsonb DEFAULT '{}'::jsonb NOT NULL,
31 + "created_at" timestamp with time zone DEFAULT now() NOT NULL
32 +);
33 +--> statement-breakpoint
34 +CREATE TABLE "arena_sessions" (
35 + "id" text PRIMARY KEY NOT NULL,
36 + "user_id" text NOT NULL,
37 + "prompt" text NOT NULL,
38 + "system_prompt" text,
39 + "model_keys" jsonb NOT NULL,
40 + "settings" jsonb DEFAULT '{}'::jsonb NOT NULL,
41 + "created_at" timestamp with time zone DEFAULT now() NOT NULL
42 +);
43 +--> statement-breakpoint
44 +CREATE TABLE "audit_events" (
45 + "id" text PRIMARY KEY NOT NULL,
46 + "user_id" text,
47 + "action" text NOT NULL,
48 + "ip_address" text,
49 + "user_agent" text,
50 + "meta" jsonb DEFAULT '{}'::jsonb NOT NULL,
51 + "created_at" timestamp with time zone DEFAULT now() NOT NULL
52 +);
53 +--> statement-breakpoint
54 +CREATE TABLE "conversation_tags" (
55 + "conversation_id" text NOT NULL,
56 + "tag_id" text NOT NULL,
57 + CONSTRAINT "conversation_tags_conversation_id_tag_id_pk" PRIMARY KEY("conversation_id","tag_id")
58 +);
59 +--> statement-breakpoint
60 +CREATE TABLE "conversations" (
61 + "id" text PRIMARY KEY NOT NULL,
62 + "user_id" text NOT NULL,
63 + "title" text DEFAULT 'New chat' NOT NULL,
64 + "title_source" text DEFAULT 'auto' NOT NULL,
65 + "folder_id" text,
66 + "pinned" boolean DEFAULT false NOT NULL,
67 + "archived" boolean DEFAULT false NOT NULL,
68 + "model_key" text,
69 + "provider" text,
70 + "system_prompt" text,
71 + "settings" jsonb DEFAULT '{}'::jsonb NOT NULL,
72 + "parent_conversation_id" text,
73 + "branched_from_message_id" text,
74 + "message_count" integer DEFAULT 0 NOT NULL,
75 + "total_cost_usd" double precision DEFAULT 0 NOT NULL,
76 + "total_input_tokens" integer DEFAULT 0 NOT NULL,
77 + "total_output_tokens" integer DEFAULT 0 NOT NULL,
78 + "last_message_at" timestamp with time zone,
79 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
80 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
81 +);
82 +--> statement-breakpoint
83 +CREATE TABLE "folders" (
84 + "id" text PRIMARY KEY NOT NULL,
85 + "user_id" text NOT NULL,
86 + "name" text NOT NULL,
87 + "color" text,
88 + "sort_order" integer DEFAULT 0 NOT NULL,
89 + "created_at" timestamp with time zone DEFAULT now() NOT NULL
90 +);
91 +--> statement-breakpoint
92 +CREATE TABLE "message_attachments" (
93 + "id" text PRIMARY KEY NOT NULL,
94 + "user_id" text NOT NULL,
95 + "message_id" text,
96 + "conversation_id" text,
97 + "kind" text NOT NULL,
98 + "name" text NOT NULL,
99 + "mime_type" text NOT NULL,
100 + "size_bytes" integer NOT NULL,
101 + "data_base64" text NOT NULL,
102 + "width" integer,
103 + "height" integer,
104 + "created_at" timestamp with time zone DEFAULT now() NOT NULL
105 +);
106 +--> statement-breakpoint
107 +CREATE TABLE "messages" (
108 + "id" text PRIMARY KEY NOT NULL,
109 + "conversation_id" text NOT NULL,
110 + "user_id" text NOT NULL,
111 + "role" text NOT NULL,
112 + "content" text DEFAULT '' NOT NULL,
113 + "parts" jsonb DEFAULT '[]'::jsonb NOT NULL,
114 + "model_key" text,
115 + "provider" text,
116 + "status" text DEFAULT 'complete' NOT NULL,
117 + "finish_reason" text,
118 + "error" jsonb,
119 + "usage" jsonb,
120 + "settings" jsonb,
121 + "latency_ms" integer,
122 + "ttft_ms" integer,
123 + "cost_usd" double precision,
124 + "parent_message_id" text,
125 + "version" integer DEFAULT 1 NOT NULL,
126 + "active" boolean DEFAULT true NOT NULL,
127 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
128 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
129 +);
130 +--> statement-breakpoint
131 +CREATE TABLE "model_presets" (
132 + "id" text PRIMARY KEY NOT NULL,
133 + "user_id" text NOT NULL,
134 + "name" text NOT NULL,
135 + "description" text,
136 + "icon" text,
137 + "model_key" text NOT NULL,
138 + "system_prompt" text,
139 + "parameters" jsonb DEFAULT '{}'::jsonb NOT NULL,
140 + "tools" jsonb DEFAULT '{}'::jsonb NOT NULL,
141 + "file_settings" jsonb DEFAULT '{}'::jsonb NOT NULL,
142 + "sort_order" integer DEFAULT 0 NOT NULL,
143 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
144 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
145 +);
146 +--> statement-breakpoint
147 +CREATE TABLE "model_sync_runs" (
148 + "id" text PRIMARY KEY NOT NULL,
149 + "provider" text NOT NULL,
150 + "triggered_by" text DEFAULT 'schedule' NOT NULL,
151 + "started_at" timestamp with time zone DEFAULT now() NOT NULL,
152 + "finished_at" timestamp with time zone,
153 + "ok" boolean,
154 + "models_found" integer,
155 + "models_added" integer,
156 + "models_removed" integer,
157 + "latency_ms" integer,
158 + "error_code" text,
159 + "error_message" text
160 +);
161 +--> statement-breakpoint
162 +CREATE TABLE "models" (
163 + "key" text PRIMARY KEY NOT NULL,
164 + "provider" text NOT NULL,
165 + "model_id" text NOT NULL,
166 + "display_name" text NOT NULL,
167 + "family" text,
168 + "capabilities" jsonb NOT NULL,
169 + "limits" jsonb DEFAULT '{}'::jsonb NOT NULL,
170 + "parameters" jsonb DEFAULT '{}'::jsonb NOT NULL,
171 + "pricing" jsonb,
172 + "status" text DEFAULT 'unknown' NOT NULL,
173 + "source" text DEFAULT 'catalog' NOT NULL,
174 + "hidden" boolean DEFAULT false NOT NULL,
175 + "sort_weight" integer DEFAULT 0 NOT NULL,
176 + "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL,
177 + "first_seen_at" timestamp with time zone DEFAULT now() NOT NULL,
178 + "last_seen_at" timestamp with time zone DEFAULT now() NOT NULL,
179 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
180 +);
181 +--> statement-breakpoint
182 +CREATE TABLE "prompt_presets" (
183 + "id" text PRIMARY KEY NOT NULL,
184 + "user_id" text NOT NULL,
185 + "name" text NOT NULL,
186 + "description" text,
187 + "icon" text,
188 + "system_prompt" text NOT NULL,
189 + "default_model_key" text,
190 + "parameters" jsonb DEFAULT '{}'::jsonb NOT NULL,
191 + "tools" jsonb DEFAULT '{}'::jsonb NOT NULL,
192 + "sort_order" integer DEFAULT 0 NOT NULL,
193 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
194 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
195 +);
196 +--> statement-breakpoint
197 +CREATE TABLE "provider_connections" (
198 + "id" text PRIMARY KEY NOT NULL,
199 + "user_id" text NOT NULL,
200 + "provider" text NOT NULL,
201 + "encrypted_key" text NOT NULL,
202 + "key_hint" text NOT NULL,
203 + "key_fingerprint" text NOT NULL,
204 + "status" text DEFAULT 'unverified' NOT NULL,
205 + "last_validated_at" timestamp with time zone,
206 + "last_validation_error" text,
207 + "last_success_at" timestamp with time zone,
208 + "last_error_at" timestamp with time zone,
209 + "last_error_code" text,
210 + "models_available" integer,
211 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
212 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
213 +);
214 +--> statement-breakpoint
215 +CREATE TABLE "sessions" (
216 + "id" text PRIMARY KEY NOT NULL,
217 + "expires_at" timestamp with time zone NOT NULL,
218 + "token" text NOT NULL,
219 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
220 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
221 + "ip_address" text,
222 + "user_agent" text,
223 + "user_id" text NOT NULL
224 +);
225 +--> statement-breakpoint
226 +CREATE TABLE "shared_conversations" (
227 + "id" text PRIMARY KEY NOT NULL,
228 + "conversation_id" text NOT NULL,
229 + "user_id" text NOT NULL,
230 + "title" text NOT NULL,
231 + "snapshot" jsonb NOT NULL,
232 + "is_public" boolean DEFAULT true NOT NULL,
233 + "view_count" integer DEFAULT 0 NOT NULL,
234 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
235 + "revoked_at" timestamp with time zone
236 +);
237 +--> statement-breakpoint
238 +CREATE TABLE "tags" (
239 + "id" text PRIMARY KEY NOT NULL,
240 + "user_id" text NOT NULL,
241 + "name" text NOT NULL,
242 + "color" text,
243 + "created_at" timestamp with time zone DEFAULT now() NOT NULL
244 +);
245 +--> statement-breakpoint
246 +CREATE TABLE "usage_records" (
247 + "id" text PRIMARY KEY NOT NULL,
248 + "user_id" text NOT NULL,
249 + "conversation_id" text,
250 + "message_id" text,
251 + "arena_session_id" text,
252 + "provider" text NOT NULL,
253 + "model_key" text NOT NULL,
254 + "kind" text DEFAULT 'chat' NOT NULL,
255 + "status" text DEFAULT 'ok' NOT NULL,
256 + "error_code" text,
257 + "input_tokens" integer DEFAULT 0 NOT NULL,
258 + "output_tokens" integer DEFAULT 0 NOT NULL,
259 + "cached_tokens" integer DEFAULT 0 NOT NULL,
260 + "reasoning_tokens" integer DEFAULT 0 NOT NULL,
261 + "cost_usd" double precision,
262 + "latency_ms" integer,
263 + "ttft_ms" integer,
264 + "created_at" timestamp with time zone DEFAULT now() NOT NULL
265 +);
266 +--> statement-breakpoint
267 +CREATE TABLE "user_model_favorites" (
268 + "user_id" text NOT NULL,
269 + "model_key" text NOT NULL,
270 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
271 + CONSTRAINT "user_model_favorites_user_id_model_key_pk" PRIMARY KEY("user_id","model_key")
272 +);
273 +--> statement-breakpoint
274 +CREATE TABLE "user_model_recents" (
275 + "user_id" text NOT NULL,
276 + "model_key" text NOT NULL,
277 + "used_at" timestamp with time zone DEFAULT now() NOT NULL,
278 + "uses" integer DEFAULT 1 NOT NULL,
279 + CONSTRAINT "user_model_recents_user_id_model_key_pk" PRIMARY KEY("user_id","model_key")
280 +);
281 +--> statement-breakpoint
282 +CREATE TABLE "user_preferences" (
283 + "user_id" text PRIMARY KEY NOT NULL,
284 + "theme" text DEFAULT 'system' NOT NULL,
285 + "language" text DEFAULT 'en' NOT NULL,
286 + "default_model_key" text,
287 + "default_system_prompt" text,
288 + "enter_to_send" boolean DEFAULT true NOT NULL,
289 + "streaming" boolean DEFAULT true NOT NULL,
290 + "code_wrap" boolean DEFAULT false NOT NULL,
291 + "show_reasoning" boolean DEFAULT true NOT NULL,
292 + "show_costs" boolean DEFAULT true NOT NULL,
293 + "auto_title" boolean DEFAULT true NOT NULL,
294 + "extra" jsonb DEFAULT '{}'::jsonb NOT NULL,
295 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
296 +);
297 +--> statement-breakpoint
298 +CREATE TABLE "users" (
299 + "id" text PRIMARY KEY NOT NULL,
300 + "name" text DEFAULT '' NOT NULL,
301 + "email" text NOT NULL,
302 + "email_verified" boolean DEFAULT false NOT NULL,
303 + "image" text,
304 + "role" text DEFAULT 'user' NOT NULL,
305 + "onboarding_completed_at" timestamp with time zone,
306 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
307 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
308 +);
309 +--> statement-breakpoint
310 +CREATE TABLE "verifications" (
311 + "id" text PRIMARY KEY NOT NULL,
312 + "identifier" text NOT NULL,
313 + "value" text NOT NULL,
314 + "expires_at" timestamp with time zone NOT NULL,
315 + "created_at" timestamp with time zone DEFAULT now() NOT NULL,
316 + "updated_at" timestamp with time zone DEFAULT now() NOT NULL
317 +);
318 +--> statement-breakpoint
319 +ALTER TABLE "accounts" ADD CONSTRAINT "accounts_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
320 +ALTER TABLE "arena_responses" ADD CONSTRAINT "arena_responses_session_id_arena_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."arena_sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
321 +ALTER TABLE "arena_sessions" ADD CONSTRAINT "arena_sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
322 +ALTER TABLE "audit_events" ADD CONSTRAINT "audit_events_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
323 +ALTER TABLE "conversation_tags" ADD CONSTRAINT "conversation_tags_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
324 +ALTER TABLE "conversation_tags" ADD CONSTRAINT "conversation_tags_tag_id_tags_id_fk" FOREIGN KEY ("tag_id") REFERENCES "public"."tags"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
325 +ALTER TABLE "conversations" ADD CONSTRAINT "conversations_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
326 +ALTER TABLE "conversations" ADD CONSTRAINT "conversations_folder_id_folders_id_fk" FOREIGN KEY ("folder_id") REFERENCES "public"."folders"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
327 +ALTER TABLE "folders" ADD CONSTRAINT "folders_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
328 +ALTER TABLE "message_attachments" ADD CONSTRAINT "message_attachments_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
329 +ALTER TABLE "message_attachments" ADD CONSTRAINT "message_attachments_message_id_messages_id_fk" FOREIGN KEY ("message_id") REFERENCES "public"."messages"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
330 +ALTER TABLE "message_attachments" ADD CONSTRAINT "message_attachments_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
331 +ALTER TABLE "messages" ADD CONSTRAINT "messages_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
332 +ALTER TABLE "messages" ADD CONSTRAINT "messages_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
333 +ALTER TABLE "model_presets" ADD CONSTRAINT "model_presets_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
334 +ALTER TABLE "prompt_presets" ADD CONSTRAINT "prompt_presets_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
335 +ALTER TABLE "provider_connections" ADD CONSTRAINT "provider_connections_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
336 +ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
337 +ALTER TABLE "shared_conversations" ADD CONSTRAINT "shared_conversations_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
338 +ALTER TABLE "shared_conversations" ADD CONSTRAINT "shared_conversations_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
339 +ALTER TABLE "tags" ADD CONSTRAINT "tags_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
340 +ALTER TABLE "usage_records" ADD CONSTRAINT "usage_records_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
341 +ALTER TABLE "user_model_favorites" ADD CONSTRAINT "user_model_favorites_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
342 +ALTER TABLE "user_model_recents" ADD CONSTRAINT "user_model_recents_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
343 +ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
344 +CREATE INDEX "accounts_user_idx" ON "accounts" USING btree ("user_id");--> statement-breakpoint
345 +CREATE INDEX "arena_responses_session_idx" ON "arena_responses" USING btree ("session_id");--> statement-breakpoint
346 +CREATE INDEX "arena_sessions_user_idx" ON "arena_sessions" USING btree ("user_id","created_at");--> statement-breakpoint
347 +CREATE INDEX "audit_user_created_idx" ON "audit_events" USING btree ("user_id","created_at");--> statement-breakpoint
348 +CREATE INDEX "conversations_user_updated_idx" ON "conversations" USING btree ("user_id","updated_at");--> statement-breakpoint
349 +CREATE INDEX "conversations_user_folder_idx" ON "conversations" USING btree ("user_id","folder_id");--> statement-breakpoint
350 +CREATE INDEX "conversations_user_model_idx" ON "conversations" USING btree ("user_id","model_key");--> statement-breakpoint
351 +CREATE INDEX "folders_user_idx" ON "folders" USING btree ("user_id");--> statement-breakpoint
352 +CREATE INDEX "attachments_message_idx" ON "message_attachments" USING btree ("message_id");--> statement-breakpoint
353 +CREATE INDEX "attachments_user_idx" ON "message_attachments" USING btree ("user_id");--> statement-breakpoint
354 +CREATE INDEX "messages_conversation_created_idx" ON "messages" USING btree ("conversation_id","created_at");--> statement-breakpoint
355 +CREATE INDEX "messages_user_idx" ON "messages" USING btree ("user_id");--> statement-breakpoint
356 +CREATE INDEX "model_presets_user_idx" ON "model_presets" USING btree ("user_id");--> statement-breakpoint
357 +CREATE INDEX "model_sync_runs_provider_started_idx" ON "model_sync_runs" USING btree ("provider","started_at");--> statement-breakpoint
358 +CREATE INDEX "models_provider_idx" ON "models" USING btree ("provider");--> statement-breakpoint
359 +CREATE INDEX "models_status_idx" ON "models" USING btree ("status");--> statement-breakpoint
360 +CREATE INDEX "prompt_presets_user_idx" ON "prompt_presets" USING btree ("user_id");--> statement-breakpoint
361 +CREATE UNIQUE INDEX "provider_connections_user_provider_uq" ON "provider_connections" USING btree ("user_id","provider");--> statement-breakpoint
362 +CREATE UNIQUE INDEX "sessions_token_uq" ON "sessions" USING btree ("token");--> statement-breakpoint
363 +CREATE INDEX "sessions_user_idx" ON "sessions" USING btree ("user_id");--> statement-breakpoint
364 +CREATE INDEX "shared_conversation_idx" ON "shared_conversations" USING btree ("conversation_id");--> statement-breakpoint
365 +CREATE UNIQUE INDEX "tags_user_name_uq" ON "tags" USING btree ("user_id","name");--> statement-breakpoint
366 +CREATE INDEX "usage_user_created_idx" ON "usage_records" USING btree ("user_id","created_at");--> statement-breakpoint
367 +CREATE INDEX "usage_user_provider_idx" ON "usage_records" USING btree ("user_id","provider");--> statement-breakpoint
368 +CREATE INDEX "usage_user_model_idx" ON "usage_records" USING btree ("user_id","model_key");--> statement-breakpoint
369 +CREATE UNIQUE INDEX "users_email_uq" ON "users" USING btree ("email");--> statement-breakpoint
370 +CREATE INDEX "verifications_identifier_idx" ON "verifications" USING btree ("identifier");
\ No newline at end of file
added drizzle/meta/0000_snapshot.json +2748 −0
@@ -0,0 +1,2748 @@
1 +{
2 + "id": "6f7e7f5c-d043-4e85-b3e5-b92b0ee9d52b",
3 + "prevId": "00000000-0000-0000-0000-000000000000",
4 + "version": "7",
5 + "dialect": "postgresql",
6 + "tables": {
7 + "public.accounts": {
8 + "name": "accounts",
9 + "schema": "",
10 + "columns": {
11 + "id": {
12 + "name": "id",
13 + "type": "text",
14 + "primaryKey": true,
15 + "notNull": true
16 + },
17 + "account_id": {
18 + "name": "account_id",
19 + "type": "text",
20 + "primaryKey": false,
21 + "notNull": true
22 + },
23 + "provider_id": {
24 + "name": "provider_id",
25 + "type": "text",
26 + "primaryKey": false,
27 + "notNull": true
28 + },
29 + "user_id": {
30 + "name": "user_id",
31 + "type": "text",
32 + "primaryKey": false,
33 + "notNull": true
34 + },
35 + "access_token": {
36 + "name": "access_token",
37 + "type": "text",
38 + "primaryKey": false,
39 + "notNull": false
40 + },
41 + "refresh_token": {
42 + "name": "refresh_token",
43 + "type": "text",
44 + "primaryKey": false,
45 + "notNull": false
46 + },
47 + "id_token": {
48 + "name": "id_token",
49 + "type": "text",
50 + "primaryKey": false,
51 + "notNull": false
52 + },
53 + "access_token_expires_at": {
54 + "name": "access_token_expires_at",
55 + "type": "timestamp with time zone",
56 + "primaryKey": false,
57 + "notNull": false
58 + },
59 + "refresh_token_expires_at": {
60 + "name": "refresh_token_expires_at",
61 + "type": "timestamp with time zone",
62 + "primaryKey": false,
63 + "notNull": false
64 + },
65 + "scope": {
66 + "name": "scope",
67 + "type": "text",
68 + "primaryKey": false,
69 + "notNull": false
70 + },
71 + "password": {
72 + "name": "password",
73 + "type": "text",
74 + "primaryKey": false,
75 + "notNull": false
76 + },
77 + "created_at": {
78 + "name": "created_at",
79 + "type": "timestamp with time zone",
80 + "primaryKey": false,
81 + "notNull": true,
82 + "default": "now()"
83 + },
84 + "updated_at": {
85 + "name": "updated_at",
86 + "type": "timestamp with time zone",
87 + "primaryKey": false,
88 + "notNull": true,
89 + "default": "now()"
90 + }
91 + },
92 + "indexes": {
93 + "accounts_user_idx": {
94 + "name": "accounts_user_idx",
95 + "columns": [
96 + {
97 + "expression": "user_id",
98 + "isExpression": false,
99 + "asc": true,
100 + "nulls": "last"
101 + }
102 + ],
103 + "isUnique": false,
104 + "concurrently": false,
105 + "method": "btree",
106 + "with": {}
107 + }
108 + },
109 + "foreignKeys": {
110 + "accounts_user_id_users_id_fk": {
111 + "name": "accounts_user_id_users_id_fk",
112 + "tableFrom": "accounts",
113 + "tableTo": "users",
114 + "columnsFrom": [
115 + "user_id"
116 + ],
117 + "columnsTo": [
118 + "id"
119 + ],
120 + "onDelete": "cascade",
121 + "onUpdate": "no action"
122 + }
123 + },
124 + "compositePrimaryKeys": {},
125 + "uniqueConstraints": {},
126 + "policies": {},
127 + "checkConstraints": {},
128 + "isRLSEnabled": false
129 + },
130 + "public.arena_responses": {
131 + "name": "arena_responses",
132 + "schema": "",
133 + "columns": {
134 + "id": {
135 + "name": "id",
136 + "type": "text",
137 + "primaryKey": true,
138 + "notNull": true
139 + },
140 + "session_id": {
141 + "name": "session_id",
142 + "type": "text",
143 + "primaryKey": false,
144 + "notNull": true
145 + },
146 + "model_key": {
147 + "name": "model_key",
148 + "type": "text",
149 + "primaryKey": false,
150 + "notNull": true
151 + },
152 + "provider": {
153 + "name": "provider",
154 + "type": "text",
155 + "primaryKey": false,
156 + "notNull": true
157 + },
158 + "content": {
159 + "name": "content",
160 + "type": "text",
161 + "primaryKey": false,
162 + "notNull": true,
163 + "default": "''"
164 + },
165 + "reasoning": {
166 + "name": "reasoning",
167 + "type": "text",
168 + "primaryKey": false,
169 + "notNull": false
170 + },
171 + "status": {
172 + "name": "status",
173 + "type": "text",
174 + "primaryKey": false,
175 + "notNull": true,
176 + "default": "'complete'"
177 + },
178 + "error": {
179 + "name": "error",
180 + "type": "jsonb",
181 + "primaryKey": false,
182 + "notNull": false
183 + },
184 + "usage": {
185 + "name": "usage",
186 + "type": "jsonb",
187 + "primaryKey": false,
188 + "notNull": false
189 + },
190 + "latency_ms": {
191 + "name": "latency_ms",
192 + "type": "integer",
193 + "primaryKey": false,
194 + "notNull": false
195 + },
196 + "ttft_ms": {
197 + "name": "ttft_ms",
198 + "type": "integer",
199 + "primaryKey": false,
200 + "notNull": false
201 + },
202 + "cost_usd": {
203 + "name": "cost_usd",
204 + "type": "double precision",
205 + "primaryKey": false,
206 + "notNull": false
207 + },
208 + "ratings": {
209 + "name": "ratings",
210 + "type": "jsonb",
211 + "primaryKey": false,
212 + "notNull": true,
213 + "default": "'{}'::jsonb"
214 + },
215 + "created_at": {
216 + "name": "created_at",
217 + "type": "timestamp with time zone",
218 + "primaryKey": false,
219 + "notNull": true,
220 + "default": "now()"
221 + }
222 + },
223 + "indexes": {
224 + "arena_responses_session_idx": {
225 + "name": "arena_responses_session_idx",
226 + "columns": [
227 + {
228 + "expression": "session_id",
229 + "isExpression": false,
230 + "asc": true,
231 + "nulls": "last"
232 + }
233 + ],
234 + "isUnique": false,
235 + "concurrently": false,
236 + "method": "btree",
237 + "with": {}
238 + }
239 + },
240 + "foreignKeys": {
241 + "arena_responses_session_id_arena_sessions_id_fk": {
242 + "name": "arena_responses_session_id_arena_sessions_id_fk",
243 + "tableFrom": "arena_responses",
244 + "tableTo": "arena_sessions",
245 + "columnsFrom": [
246 + "session_id"
247 + ],
248 + "columnsTo": [
249 + "id"
250 + ],
251 + "onDelete": "cascade",
252 + "onUpdate": "no action"
253 + }
254 + },
255 + "compositePrimaryKeys": {},
256 + "uniqueConstraints": {},
257 + "policies": {},
258 + "checkConstraints": {},
259 + "isRLSEnabled": false
260 + },
261 + "public.arena_sessions": {
262 + "name": "arena_sessions",
263 + "schema": "",
264 + "columns": {
265 + "id": {
266 + "name": "id",
267 + "type": "text",
268 + "primaryKey": true,
269 + "notNull": true
270 + },
271 + "user_id": {
272 + "name": "user_id",
273 + "type": "text",
274 + "primaryKey": false,
275 + "notNull": true
276 + },
277 + "prompt": {
278 + "name": "prompt",
279 + "type": "text",
280 + "primaryKey": false,
281 + "notNull": true
282 + },
283 + "system_prompt": {
284 + "name": "system_prompt",
285 + "type": "text",
286 + "primaryKey": false,
287 + "notNull": false
288 + },
289 + "model_keys": {
290 + "name": "model_keys",
291 + "type": "jsonb",
292 + "primaryKey": false,
293 + "notNull": true
294 + },
295 + "settings": {
296 + "name": "settings",
297 + "type": "jsonb",
298 + "primaryKey": false,
299 + "notNull": true,
300 + "default": "'{}'::jsonb"
301 + },
302 + "created_at": {
303 + "name": "created_at",
304 + "type": "timestamp with time zone",
305 + "primaryKey": false,
306 + "notNull": true,
307 + "default": "now()"
308 + }
309 + },
310 + "indexes": {
311 + "arena_sessions_user_idx": {
312 + "name": "arena_sessions_user_idx",
313 + "columns": [
314 + {
315 + "expression": "user_id",
316 + "isExpression": false,
317 + "asc": true,
318 + "nulls": "last"
319 + },
320 + {
321 + "expression": "created_at",
322 + "isExpression": false,
323 + "asc": true,
324 + "nulls": "last"
325 + }
326 + ],
327 + "isUnique": false,
328 + "concurrently": false,
329 + "method": "btree",
330 + "with": {}
331 + }
332 + },
333 + "foreignKeys": {
334 + "arena_sessions_user_id_users_id_fk": {
335 + "name": "arena_sessions_user_id_users_id_fk",
336 + "tableFrom": "arena_sessions",
337 + "tableTo": "users",
338 + "columnsFrom": [
339 + "user_id"
340 + ],
341 + "columnsTo": [
342 + "id"
343 + ],
344 + "onDelete": "cascade",
345 + "onUpdate": "no action"
346 + }
347 + },
348 + "compositePrimaryKeys": {},
349 + "uniqueConstraints": {},
350 + "policies": {},
351 + "checkConstraints": {},
352 + "isRLSEnabled": false
353 + },
354 + "public.audit_events": {
355 + "name": "audit_events",
356 + "schema": "",
357 + "columns": {
358 + "id": {
359 + "name": "id",
360 + "type": "text",
361 + "primaryKey": true,
362 + "notNull": true
363 + },
364 + "user_id": {
365 + "name": "user_id",
366 + "type": "text",
367 + "primaryKey": false,
368 + "notNull": false
369 + },
370 + "action": {
371 + "name": "action",
372 + "type": "text",
373 + "primaryKey": false,
374 + "notNull": true
375 + },
376 + "ip_address": {
377 + "name": "ip_address",
378 + "type": "text",
379 + "primaryKey": false,
380 + "notNull": false
381 + },
382 + "user_agent": {
383 + "name": "user_agent",
384 + "type": "text",
385 + "primaryKey": false,
386 + "notNull": false
387 + },
388 + "meta": {
389 + "name": "meta",
390 + "type": "jsonb",
391 + "primaryKey": false,
392 + "notNull": true,
393 + "default": "'{}'::jsonb"
394 + },
395 + "created_at": {
396 + "name": "created_at",
397 + "type": "timestamp with time zone",
398 + "primaryKey": false,
399 + "notNull": true,
400 + "default": "now()"
401 + }
402 + },
403 + "indexes": {
404 + "audit_user_created_idx": {
405 + "name": "audit_user_created_idx",
406 + "columns": [
407 + {
408 + "expression": "user_id",
409 + "isExpression": false,
410 + "asc": true,
411 + "nulls": "last"
412 + },
413 + {
414 + "expression": "created_at",
415 + "isExpression": false,
416 + "asc": true,
417 + "nulls": "last"
418 + }
419 + ],
420 + "isUnique": false,
421 + "concurrently": false,
422 + "method": "btree",
423 + "with": {}
424 + }
425 + },
426 + "foreignKeys": {
427 + "audit_events_user_id_users_id_fk": {
428 + "name": "audit_events_user_id_users_id_fk",
429 + "tableFrom": "audit_events",
430 + "tableTo": "users",
431 + "columnsFrom": [
432 + "user_id"
433 + ],
434 + "columnsTo": [
435 + "id"
436 + ],
437 + "onDelete": "set null",
438 + "onUpdate": "no action"
439 + }
440 + },
441 + "compositePrimaryKeys": {},
442 + "uniqueConstraints": {},
443 + "policies": {},
444 + "checkConstraints": {},
445 + "isRLSEnabled": false
446 + },
447 + "public.conversation_tags": {
448 + "name": "conversation_tags",
449 + "schema": "",
450 + "columns": {
451 + "conversation_id": {
452 + "name": "conversation_id",
453 + "type": "text",
454 + "primaryKey": false,
455 + "notNull": true
456 + },
457 + "tag_id": {
458 + "name": "tag_id",
459 + "type": "text",
460 + "primaryKey": false,
461 + "notNull": true
462 + }
463 + },
464 + "indexes": {},
465 + "foreignKeys": {
466 + "conversation_tags_conversation_id_conversations_id_fk": {
467 + "name": "conversation_tags_conversation_id_conversations_id_fk",
468 + "tableFrom": "conversation_tags",
469 + "tableTo": "conversations",
470 + "columnsFrom": [
471 + "conversation_id"
472 + ],
473 + "columnsTo": [
474 + "id"
475 + ],
476 + "onDelete": "cascade",
477 + "onUpdate": "no action"
478 + },
479 + "conversation_tags_tag_id_tags_id_fk": {
480 + "name": "conversation_tags_tag_id_tags_id_fk",
481 + "tableFrom": "conversation_tags",
482 + "tableTo": "tags",
483 + "columnsFrom": [
484 + "tag_id"
485 + ],
486 + "columnsTo": [
487 + "id"
488 + ],
489 + "onDelete": "cascade",
490 + "onUpdate": "no action"
491 + }
492 + },
493 + "compositePrimaryKeys": {
494 + "conversation_tags_conversation_id_tag_id_pk": {
495 + "name": "conversation_tags_conversation_id_tag_id_pk",
496 + "columns": [
497 + "conversation_id",
498 + "tag_id"
499 + ]
500 + }
501 + },
502 + "uniqueConstraints": {},
503 + "policies": {},
504 + "checkConstraints": {},
505 + "isRLSEnabled": false
506 + },
507 + "public.conversations": {
508 + "name": "conversations",
509 + "schema": "",
510 + "columns": {
511 + "id": {
512 + "name": "id",
513 + "type": "text",
514 + "primaryKey": true,
515 + "notNull": true
516 + },
517 + "user_id": {
518 + "name": "user_id",
519 + "type": "text",
520 + "primaryKey": false,
521 + "notNull": true
522 + },
523 + "title": {
524 + "name": "title",
525 + "type": "text",
526 + "primaryKey": false,
527 + "notNull": true,
528 + "default": "'New chat'"
529 + },
530 + "title_source": {
531 + "name": "title_source",
532 + "type": "text",
533 + "primaryKey": false,
534 + "notNull": true,
535 + "default": "'auto'"
536 + },
537 + "folder_id": {
538 + "name": "folder_id",
539 + "type": "text",
540 + "primaryKey": false,
541 + "notNull": false
542 + },
543 + "pinned": {
544 + "name": "pinned",
545 + "type": "boolean",
546 + "primaryKey": false,
547 + "notNull": true,
548 + "default": false
549 + },
550 + "archived": {
551 + "name": "archived",
552 + "type": "boolean",
553 + "primaryKey": false,
554 + "notNull": true,
555 + "default": false
556 + },
557 + "model_key": {
558 + "name": "model_key",
559 + "type": "text",
560 + "primaryKey": false,
561 + "notNull": false
562 + },
563 + "provider": {
564 + "name": "provider",
565 + "type": "text",
566 + "primaryKey": false,
567 + "notNull": false
568 + },
569 + "system_prompt": {
570 + "name": "system_prompt",
571 + "type": "text",
572 + "primaryKey": false,
573 + "notNull": false
574 + },
575 + "settings": {
576 + "name": "settings",
577 + "type": "jsonb",
578 + "primaryKey": false,
579 + "notNull": true,
580 + "default": "'{}'::jsonb"
581 + },
582 + "parent_conversation_id": {
583 + "name": "parent_conversation_id",
584 + "type": "text",
585 + "primaryKey": false,
586 + "notNull": false
587 + },
588 + "branched_from_message_id": {
589 + "name": "branched_from_message_id",
590 + "type": "text",
591 + "primaryKey": false,
592 + "notNull": false
593 + },
594 + "message_count": {
595 + "name": "message_count",
596 + "type": "integer",
597 + "primaryKey": false,
598 + "notNull": true,
599 + "default": 0
600 + },
601 + "total_cost_usd": {
602 + "name": "total_cost_usd",
603 + "type": "double precision",
604 + "primaryKey": false,
605 + "notNull": true,
606 + "default": 0
607 + },
608 + "total_input_tokens": {
609 + "name": "total_input_tokens",
610 + "type": "integer",
611 + "primaryKey": false,
612 + "notNull": true,
613 + "default": 0
614 + },
615 + "total_output_tokens": {
616 + "name": "total_output_tokens",
617 + "type": "integer",
618 + "primaryKey": false,
619 + "notNull": true,
620 + "default": 0
621 + },
622 + "last_message_at": {
623 + "name": "last_message_at",
624 + "type": "timestamp with time zone",
625 + "primaryKey": false,
626 + "notNull": false
627 + },
628 + "created_at": {
629 + "name": "created_at",
630 + "type": "timestamp with time zone",
631 + "primaryKey": false,
632 + "notNull": true,
633 + "default": "now()"
634 + },
635 + "updated_at": {
636 + "name": "updated_at",
637 + "type": "timestamp with time zone",
638 + "primaryKey": false,
639 + "notNull": true,
640 + "default": "now()"
641 + }
642 + },
643 + "indexes": {
644 + "conversations_user_updated_idx": {
645 + "name": "conversations_user_updated_idx",
646 + "columns": [
647 + {
648 + "expression": "user_id",
649 + "isExpression": false,
650 + "asc": true,
651 + "nulls": "last"
652 + },
653 + {
654 + "expression": "updated_at",
655 + "isExpression": false,
656 + "asc": true,
657 + "nulls": "last"
658 + }
659 + ],
660 + "isUnique": false,
661 + "concurrently": false,
662 + "method": "btree",
663 + "with": {}
664 + },
665 + "conversations_user_folder_idx": {
666 + "name": "conversations_user_folder_idx",
667 + "columns": [
668 + {
669 + "expression": "user_id",
670 + "isExpression": false,
671 + "asc": true,
672 + "nulls": "last"
673 + },
674 + {
675 + "expression": "folder_id",
676 + "isExpression": false,
677 + "asc": true,
678 + "nulls": "last"
679 + }
680 + ],
681 + "isUnique": false,
682 + "concurrently": false,
683 + "method": "btree",
684 + "with": {}
685 + },
686 + "conversations_user_model_idx": {
687 + "name": "conversations_user_model_idx",
688 + "columns": [
689 + {
690 + "expression": "user_id",
691 + "isExpression": false,
692 + "asc": true,
693 + "nulls": "last"
694 + },
695 + {
696 + "expression": "model_key",
697 + "isExpression": false,
698 + "asc": true,
699 + "nulls": "last"
700 + }
701 + ],
702 + "isUnique": false,
703 + "concurrently": false,
704 + "method": "btree",
705 + "with": {}
706 + }
707 + },
708 + "foreignKeys": {
709 + "conversations_user_id_users_id_fk": {
710 + "name": "conversations_user_id_users_id_fk",
711 + "tableFrom": "conversations",
712 + "tableTo": "users",
713 + "columnsFrom": [
714 + "user_id"
715 + ],
716 + "columnsTo": [
717 + "id"
718 + ],
719 + "onDelete": "cascade",
720 + "onUpdate": "no action"
721 + },
722 + "conversations_folder_id_folders_id_fk": {
723 + "name": "conversations_folder_id_folders_id_fk",
724 + "tableFrom": "conversations",
725 + "tableTo": "folders",
726 + "columnsFrom": [
727 + "folder_id"
728 + ],
729 + "columnsTo": [
730 + "id"
731 + ],
732 + "onDelete": "set null",
733 + "onUpdate": "no action"
734 + }
735 + },
736 + "compositePrimaryKeys": {},
737 + "uniqueConstraints": {},
738 + "policies": {},
739 + "checkConstraints": {},
740 + "isRLSEnabled": false
741 + },
742 + "public.folders": {
743 + "name": "folders",
744 + "schema": "",
745 + "columns": {
746 + "id": {
747 + "name": "id",
748 + "type": "text",
749 + "primaryKey": true,
750 + "notNull": true
751 + },
752 + "user_id": {
753 + "name": "user_id",
754 + "type": "text",
755 + "primaryKey": false,
756 + "notNull": true
757 + },
758 + "name": {
759 + "name": "name",
760 + "type": "text",
761 + "primaryKey": false,
762 + "notNull": true
763 + },
764 + "color": {
765 + "name": "color",
766 + "type": "text",
767 + "primaryKey": false,
768 + "notNull": false
769 + },
770 + "sort_order": {
771 + "name": "sort_order",
772 + "type": "integer",
773 + "primaryKey": false,
774 + "notNull": true,
775 + "default": 0
776 + },
777 + "created_at": {
778 + "name": "created_at",
779 + "type": "timestamp with time zone",
780 + "primaryKey": false,
781 + "notNull": true,
782 + "default": "now()"
783 + }
784 + },
785 + "indexes": {
786 + "folders_user_idx": {
787 + "name": "folders_user_idx",
788 + "columns": [
789 + {
790 + "expression": "user_id",
791 + "isExpression": false,
792 + "asc": true,
793 + "nulls": "last"
794 + }
795 + ],
796 + "isUnique": false,
797 + "concurrently": false,
798 + "method": "btree",
799 + "with": {}
800 + }
801 + },
802 + "foreignKeys": {
803 + "folders_user_id_users_id_fk": {
804 + "name": "folders_user_id_users_id_fk",
805 + "tableFrom": "folders",
806 + "tableTo": "users",
807 + "columnsFrom": [
808 + "user_id"
809 + ],
810 + "columnsTo": [
811 + "id"
812 + ],
813 + "onDelete": "cascade",
814 + "onUpdate": "no action"
815 + }
816 + },
817 + "compositePrimaryKeys": {},
818 + "uniqueConstraints": {},
819 + "policies": {},
820 + "checkConstraints": {},
821 + "isRLSEnabled": false
822 + },
823 + "public.message_attachments": {
824 + "name": "message_attachments",
825 + "schema": "",
826 + "columns": {
827 + "id": {
828 + "name": "id",
829 + "type": "text",
830 + "primaryKey": true,
831 + "notNull": true
832 + },
833 + "user_id": {
834 + "name": "user_id",
835 + "type": "text",
836 + "primaryKey": false,
837 + "notNull": true
838 + },
839 + "message_id": {
840 + "name": "message_id",
841 + "type": "text",
842 + "primaryKey": false,
843 + "notNull": false
844 + },
845 + "conversation_id": {
846 + "name": "conversation_id",
847 + "type": "text",
848 + "primaryKey": false,
849 + "notNull": false
850 + },
851 + "kind": {
852 + "name": "kind",
853 + "type": "text",
854 + "primaryKey": false,
855 + "notNull": true
856 + },
857 + "name": {
858 + "name": "name",
859 + "type": "text",
860 + "primaryKey": false,
861 + "notNull": true
862 + },
863 + "mime_type": {
864 + "name": "mime_type",
865 + "type": "text",
866 + "primaryKey": false,
867 + "notNull": true
868 + },
869 + "size_bytes": {
870 + "name": "size_bytes",
871 + "type": "integer",
872 + "primaryKey": false,
873 + "notNull": true
874 + },
875 + "data_base64": {
876 + "name": "data_base64",
877 + "type": "text",
878 + "primaryKey": false,
879 + "notNull": true
880 + },
881 + "width": {
882 + "name": "width",
883 + "type": "integer",
884 + "primaryKey": false,
885 + "notNull": false
886 + },
887 + "height": {
888 + "name": "height",
889 + "type": "integer",
890 + "primaryKey": false,
891 + "notNull": false
892 + },
893 + "created_at": {
894 + "name": "created_at",
895 + "type": "timestamp with time zone",
896 + "primaryKey": false,
897 + "notNull": true,
898 + "default": "now()"
899 + }
900 + },
901 + "indexes": {
902 + "attachments_message_idx": {
903 + "name": "attachments_message_idx",
904 + "columns": [
905 + {
906 + "expression": "message_id",
907 + "isExpression": false,
908 + "asc": true,
909 + "nulls": "last"
910 + }
911 + ],
912 + "isUnique": false,
913 + "concurrently": false,
914 + "method": "btree",
915 + "with": {}
916 + },
917 + "attachments_user_idx": {
918 + "name": "attachments_user_idx",
919 + "columns": [
920 + {
921 + "expression": "user_id",
922 + "isExpression": false,
923 + "asc": true,
924 + "nulls": "last"
925 + }
926 + ],
927 + "isUnique": false,
928 + "concurrently": false,
929 + "method": "btree",
930 + "with": {}
931 + }
932 + },
933 + "foreignKeys": {
934 + "message_attachments_user_id_users_id_fk": {
935 + "name": "message_attachments_user_id_users_id_fk",
936 + "tableFrom": "message_attachments",
937 + "tableTo": "users",
938 + "columnsFrom": [
939 + "user_id"
940 + ],
941 + "columnsTo": [
942 + "id"
943 + ],
944 + "onDelete": "cascade",
945 + "onUpdate": "no action"
946 + },
947 + "message_attachments_message_id_messages_id_fk": {
948 + "name": "message_attachments_message_id_messages_id_fk",
949 + "tableFrom": "message_attachments",
950 + "tableTo": "messages",
951 + "columnsFrom": [
952 + "message_id"
953 + ],
954 + "columnsTo": [
955 + "id"
956 + ],
957 + "onDelete": "cascade",
958 + "onUpdate": "no action"
959 + },
960 + "message_attachments_conversation_id_conversations_id_fk": {
961 + "name": "message_attachments_conversation_id_conversations_id_fk",
962 + "tableFrom": "message_attachments",
963 + "tableTo": "conversations",
964 + "columnsFrom": [
965 + "conversation_id"
966 + ],
967 + "columnsTo": [
968 + "id"
969 + ],
970 + "onDelete": "cascade",
971 + "onUpdate": "no action"
972 + }
973 + },
974 + "compositePrimaryKeys": {},
975 + "uniqueConstraints": {},
976 + "policies": {},
977 + "checkConstraints": {},
978 + "isRLSEnabled": false
979 + },
980 + "public.messages": {
981 + "name": "messages",
982 + "schema": "",
983 + "columns": {
984 + "id": {
985 + "name": "id",
986 + "type": "text",
987 + "primaryKey": true,
988 + "notNull": true
989 + },
990 + "conversation_id": {
991 + "name": "conversation_id",
992 + "type": "text",
993 + "primaryKey": false,
994 + "notNull": true
995 + },
996 + "user_id": {
997 + "name": "user_id",
998 + "type": "text",
999 + "primaryKey": false,
1000 + "notNull": true
1001 + },
1002 + "role": {
1003 + "name": "role",
1004 + "type": "text",
1005 + "primaryKey": false,
1006 + "notNull": true
1007 + },
1008 + "content": {
1009 + "name": "content",
1010 + "type": "text",
1011 + "primaryKey": false,
1012 + "notNull": true,
1013 + "default": "''"
1014 + },
1015 + "parts": {
1016 + "name": "parts",
1017 + "type": "jsonb",
1018 + "primaryKey": false,
1019 + "notNull": true,
1020 + "default": "'[]'::jsonb"
1021 + },
1022 + "model_key": {
1023 + "name": "model_key",
1024 + "type": "text",
1025 + "primaryKey": false,
1026 + "notNull": false
1027 + },
1028 + "provider": {
1029 + "name": "provider",
1030 + "type": "text",
1031 + "primaryKey": false,
1032 + "notNull": false
1033 + },
1034 + "status": {
1035 + "name": "status",
1036 + "type": "text",
1037 + "primaryKey": false,
1038 + "notNull": true,
1039 + "default": "'complete'"
1040 + },
1041 + "finish_reason": {
1042 + "name": "finish_reason",
1043 + "type": "text",
1044 + "primaryKey": false,
1045 + "notNull": false
1046 + },
1047 + "error": {
1048 + "name": "error",
1049 + "type": "jsonb",
1050 + "primaryKey": false,
1051 + "notNull": false
1052 + },
1053 + "usage": {
1054 + "name": "usage",
1055 + "type": "jsonb",
1056 + "primaryKey": false,
1057 + "notNull": false
1058 + },
1059 + "settings": {
1060 + "name": "settings",
1061 + "type": "jsonb",
1062 + "primaryKey": false,
1063 + "notNull": false
1064 + },
1065 + "latency_ms": {
1066 + "name": "latency_ms",
1067 + "type": "integer",
1068 + "primaryKey": false,
1069 + "notNull": false
1070 + },
1071 + "ttft_ms": {
1072 + "name": "ttft_ms",
1073 + "type": "integer",
1074 + "primaryKey": false,
1075 + "notNull": false
1076 + },
1077 + "cost_usd": {
1078 + "name": "cost_usd",
1079 + "type": "double precision",
1080 + "primaryKey": false,
1081 + "notNull": false
1082 + },
1083 + "parent_message_id": {
1084 + "name": "parent_message_id",
1085 + "type": "text",
1086 + "primaryKey": false,
1087 + "notNull": false
1088 + },
1089 + "version": {
1090 + "name": "version",
1091 + "type": "integer",
1092 + "primaryKey": false,
1093 + "notNull": true,
1094 + "default": 1
1095 + },
1096 + "active": {
1097 + "name": "active",
1098 + "type": "boolean",
1099 + "primaryKey": false,
1100 + "notNull": true,
1101 + "default": true
1102 + },
1103 + "created_at": {
1104 + "name": "created_at",
1105 + "type": "timestamp with time zone",
1106 + "primaryKey": false,
1107 + "notNull": true,
1108 + "default": "now()"
1109 + },
1110 + "updated_at": {
1111 + "name": "updated_at",
1112 + "type": "timestamp with time zone",
1113 + "primaryKey": false,
1114 + "notNull": true,
1115 + "default": "now()"
1116 + }
1117 + },
1118 + "indexes": {
1119 + "messages_conversation_created_idx": {
1120 + "name": "messages_conversation_created_idx",
1121 + "columns": [
1122 + {
1123 + "expression": "conversation_id",
1124 + "isExpression": false,
1125 + "asc": true,
1126 + "nulls": "last"
1127 + },
1128 + {
1129 + "expression": "created_at",
1130 + "isExpression": false,
1131 + "asc": true,
1132 + "nulls": "last"
1133 + }
1134 + ],
1135 + "isUnique": false,
1136 + "concurrently": false,
1137 + "method": "btree",
1138 + "with": {}
1139 + },
1140 + "messages_user_idx": {
1141 + "name": "messages_user_idx",
1142 + "columns": [
1143 + {
1144 + "expression": "user_id",
1145 + "isExpression": false,
1146 + "asc": true,
1147 + "nulls": "last"
1148 + }
1149 + ],
1150 + "isUnique": false,
1151 + "concurrently": false,
1152 + "method": "btree",
1153 + "with": {}
1154 + }
1155 + },
1156 + "foreignKeys": {
1157 + "messages_conversation_id_conversations_id_fk": {
1158 + "name": "messages_conversation_id_conversations_id_fk",
1159 + "tableFrom": "messages",
1160 + "tableTo": "conversations",
1161 + "columnsFrom": [
1162 + "conversation_id"
1163 + ],
1164 + "columnsTo": [
1165 + "id"
1166 + ],
1167 + "onDelete": "cascade",
1168 + "onUpdate": "no action"
1169 + },
1170 + "messages_user_id_users_id_fk": {
1171 + "name": "messages_user_id_users_id_fk",
1172 + "tableFrom": "messages",
1173 + "tableTo": "users",
1174 + "columnsFrom": [
1175 + "user_id"
1176 + ],
1177 + "columnsTo": [
1178 + "id"
1179 + ],
1180 + "onDelete": "cascade",
1181 + "onUpdate": "no action"
1182 + }
1183 + },
1184 + "compositePrimaryKeys": {},
1185 + "uniqueConstraints": {},
1186 + "policies": {},
1187 + "checkConstraints": {},
1188 + "isRLSEnabled": false
1189 + },
1190 + "public.model_presets": {
1191 + "name": "model_presets",
1192 + "schema": "",
1193 + "columns": {
1194 + "id": {
1195 + "name": "id",
1196 + "type": "text",
1197 + "primaryKey": true,
1198 + "notNull": true
1199 + },
1200 + "user_id": {
1201 + "name": "user_id",
1202 + "type": "text",
1203 + "primaryKey": false,
1204 + "notNull": true
1205 + },
1206 + "name": {
1207 + "name": "name",
1208 + "type": "text",
1209 + "primaryKey": false,
1210 + "notNull": true
1211 + },
1212 + "description": {
1213 + "name": "description",
1214 + "type": "text",
1215 + "primaryKey": false,
1216 + "notNull": false
1217 + },
1218 + "icon": {
1219 + "name": "icon",
1220 + "type": "text",
1221 + "primaryKey": false,
1222 + "notNull": false
1223 + },
1224 + "model_key": {
1225 + "name": "model_key",
1226 + "type": "text",
1227 + "primaryKey": false,
1228 + "notNull": true
1229 + },
1230 + "system_prompt": {
1231 + "name": "system_prompt",
1232 + "type": "text",
1233 + "primaryKey": false,
1234 + "notNull": false
1235 + },
1236 + "parameters": {
1237 + "name": "parameters",
1238 + "type": "jsonb",
1239 + "primaryKey": false,
1240 + "notNull": true,
1241 + "default": "'{}'::jsonb"
1242 + },
1243 + "tools": {
1244 + "name": "tools",
1245 + "type": "jsonb",
1246 + "primaryKey": false,
1247 + "notNull": true,
1248 + "default": "'{}'::jsonb"
1249 + },
1250 + "file_settings": {
1251 + "name": "file_settings",
1252 + "type": "jsonb",
1253 + "primaryKey": false,
1254 + "notNull": true,
1255 + "default": "'{}'::jsonb"
1256 + },
1257 + "sort_order": {
1258 + "name": "sort_order",
1259 + "type": "integer",
1260 + "primaryKey": false,
1261 + "notNull": true,
1262 + "default": 0
1263 + },
1264 + "created_at": {
1265 + "name": "created_at",
1266 + "type": "timestamp with time zone",
1267 + "primaryKey": false,
1268 + "notNull": true,
1269 + "default": "now()"
1270 + },
1271 + "updated_at": {
1272 + "name": "updated_at",
1273 + "type": "timestamp with time zone",
1274 + "primaryKey": false,
1275 + "notNull": true,
1276 + "default": "now()"
1277 + }
1278 + },
1279 + "indexes": {
1280 + "model_presets_user_idx": {
1281 + "name": "model_presets_user_idx",
1282 + "columns": [
1283 + {
1284 + "expression": "user_id",
1285 + "isExpression": false,
1286 + "asc": true,
1287 + "nulls": "last"
1288 + }
1289 + ],
1290 + "isUnique": false,
1291 + "concurrently": false,
1292 + "method": "btree",
1293 + "with": {}
1294 + }
1295 + },
1296 + "foreignKeys": {
1297 + "model_presets_user_id_users_id_fk": {
1298 + "name": "model_presets_user_id_users_id_fk",
1299 + "tableFrom": "model_presets",
1300 + "tableTo": "users",
1301 + "columnsFrom": [
1302 + "user_id"
1303 + ],
1304 + "columnsTo": [
1305 + "id"
1306 + ],
1307 + "onDelete": "cascade",
1308 + "onUpdate": "no action"
1309 + }
1310 + },
1311 + "compositePrimaryKeys": {},
1312 + "uniqueConstraints": {},
1313 + "policies": {},
1314 + "checkConstraints": {},
1315 + "isRLSEnabled": false
1316 + },
1317 + "public.model_sync_runs": {
1318 + "name": "model_sync_runs",
1319 + "schema": "",
1320 + "columns": {
1321 + "id": {
1322 + "name": "id",
1323 + "type": "text",
1324 + "primaryKey": true,
1325 + "notNull": true
1326 + },
1327 + "provider": {
1328 + "name": "provider",
1329 + "type": "text",
1330 + "primaryKey": false,
1331 + "notNull": true
1332 + },
1333 + "triggered_by": {
1334 + "name": "triggered_by",
1335 + "type": "text",
1336 + "primaryKey": false,
1337 + "notNull": true,
1338 + "default": "'schedule'"
1339 + },
1340 + "started_at": {
1341 + "name": "started_at",
1342 + "type": "timestamp with time zone",
1343 + "primaryKey": false,
1344 + "notNull": true,
1345 + "default": "now()"
1346 + },
1347 + "finished_at": {
1348 + "name": "finished_at",
1349 + "type": "timestamp with time zone",
1350 + "primaryKey": false,
1351 + "notNull": false
1352 + },
1353 + "ok": {
1354 + "name": "ok",
1355 + "type": "boolean",
1356 + "primaryKey": false,
1357 + "notNull": false
1358 + },
1359 + "models_found": {
1360 + "name": "models_found",
1361 + "type": "integer",
1362 + "primaryKey": false,
1363 + "notNull": false
1364 + },
1365 + "models_added": {
1366 + "name": "models_added",
1367 + "type": "integer",
1368 + "primaryKey": false,
1369 + "notNull": false
1370 + },
1371 + "models_removed": {
1372 + "name": "models_removed",
1373 + "type": "integer",
1374 + "primaryKey": false,
1375 + "notNull": false
1376 + },
1377 + "latency_ms": {
1378 + "name": "latency_ms",
1379 + "type": "integer",
1380 + "primaryKey": false,
1381 + "notNull": false
1382 + },
1383 + "error_code": {
1384 + "name": "error_code",
1385 + "type": "text",
1386 + "primaryKey": false,
1387 + "notNull": false
1388 + },
1389 + "error_message": {
1390 + "name": "error_message",
1391 + "type": "text",
1392 + "primaryKey": false,
1393 + "notNull": false
1394 + }
1395 + },
1396 + "indexes": {
1397 + "model_sync_runs_provider_started_idx": {
1398 + "name": "model_sync_runs_provider_started_idx",
1399 + "columns": [
1400 + {
1401 + "expression": "provider",
1402 + "isExpression": false,
1403 + "asc": true,
1404 + "nulls": "last"
1405 + },
1406 + {
1407 + "expression": "started_at",
1408 + "isExpression": false,
1409 + "asc": true,
1410 + "nulls": "last"
1411 + }
1412 + ],
1413 + "isUnique": false,
1414 + "concurrently": false,
1415 + "method": "btree",
1416 + "with": {}
1417 + }
1418 + },
1419 + "foreignKeys": {},
1420 + "compositePrimaryKeys": {},
1421 + "uniqueConstraints": {},
1422 + "policies": {},
1423 + "checkConstraints": {},
1424 + "isRLSEnabled": false
1425 + },
1426 + "public.models": {
1427 + "name": "models",
1428 + "schema": "",
1429 + "columns": {
1430 + "key": {
1431 + "name": "key",
1432 + "type": "text",
1433 + "primaryKey": true,
1434 + "notNull": true
1435 + },
1436 + "provider": {
1437 + "name": "provider",
1438 + "type": "text",
1439 + "primaryKey": false,
1440 + "notNull": true
1441 + },
1442 + "model_id": {
1443 + "name": "model_id",
1444 + "type": "text",
1445 + "primaryKey": false,
1446 + "notNull": true
1447 + },
1448 + "display_name": {
1449 + "name": "display_name",
1450 + "type": "text",
1451 + "primaryKey": false,
1452 + "notNull": true
1453 + },
1454 + "family": {
1455 + "name": "family",
1456 + "type": "text",
1457 + "primaryKey": false,
1458 + "notNull": false
1459 + },
1460 + "capabilities": {
1461 + "name": "capabilities",
1462 + "type": "jsonb",
1463 + "primaryKey": false,
1464 + "notNull": true
1465 + },
1466 + "limits": {
1467 + "name": "limits",
1468 + "type": "jsonb",
1469 + "primaryKey": false,
1470 + "notNull": true,
1471 + "default": "'{}'::jsonb"
1472 + },
1473 + "parameters": {
1474 + "name": "parameters",
1475 + "type": "jsonb",
1476 + "primaryKey": false,
1477 + "notNull": true,
1478 + "default": "'{}'::jsonb"
1479 + },
1480 + "pricing": {
1481 + "name": "pricing",
1482 + "type": "jsonb",
1483 + "primaryKey": false,
1484 + "notNull": false
1485 + },
1486 + "status": {
1487 + "name": "status",
1488 + "type": "text",
1489 + "primaryKey": false,
1490 + "notNull": true,
1491 + "default": "'unknown'"
1492 + },
1493 + "source": {
1494 + "name": "source",
1495 + "type": "text",
1496 + "primaryKey": false,
1497 + "notNull": true,
1498 + "default": "'catalog'"
1499 + },
1500 + "hidden": {
1501 + "name": "hidden",
1502 + "type": "boolean",
1503 + "primaryKey": false,
1504 + "notNull": true,
1505 + "default": false
1506 + },
1507 + "sort_weight": {
1508 + "name": "sort_weight",
1509 + "type": "integer",
1510 + "primaryKey": false,
1511 + "notNull": true,
1512 + "default": 0
1513 + },
1514 + "metadata": {
1515 + "name": "metadata",
1516 + "type": "jsonb",
1517 + "primaryKey": false,
1518 + "notNull": true,
1519 + "default": "'{}'::jsonb"
1520 + },
1521 + "first_seen_at": {
1522 + "name": "first_seen_at",
1523 + "type": "timestamp with time zone",
1524 + "primaryKey": false,
1525 + "notNull": true,
1526 + "default": "now()"
1527 + },
1528 + "last_seen_at": {
1529 + "name": "last_seen_at",
1530 + "type": "timestamp with time zone",
1531 + "primaryKey": false,
1532 + "notNull": true,
1533 + "default": "now()"
1534 + },
1535 + "updated_at": {
1536 + "name": "updated_at",
1537 + "type": "timestamp with time zone",
1538 + "primaryKey": false,
1539 + "notNull": true,
1540 + "default": "now()"
1541 + }
1542 + },
1543 + "indexes": {
1544 + "models_provider_idx": {
1545 + "name": "models_provider_idx",
1546 + "columns": [
1547 + {
1548 + "expression": "provider",
1549 + "isExpression": false,
1550 + "asc": true,
1551 + "nulls": "last"
1552 + }
1553 + ],
1554 + "isUnique": false,
1555 + "concurrently": false,
1556 + "method": "btree",
1557 + "with": {}
1558 + },
1559 + "models_status_idx": {
1560 + "name": "models_status_idx",
1561 + "columns": [
1562 + {
1563 + "expression": "status",
1564 + "isExpression": false,
1565 + "asc": true,
1566 + "nulls": "last"
1567 + }
1568 + ],
1569 + "isUnique": false,
1570 + "concurrently": false,
1571 + "method": "btree",
1572 + "with": {}
1573 + }
1574 + },
1575 + "foreignKeys": {},
1576 + "compositePrimaryKeys": {},
1577 + "uniqueConstraints": {},
1578 + "policies": {},
1579 + "checkConstraints": {},
1580 + "isRLSEnabled": false
1581 + },
1582 + "public.prompt_presets": {
1583 + "name": "prompt_presets",
1584 + "schema": "",
1585 + "columns": {
1586 + "id": {
1587 + "name": "id",
1588 + "type": "text",
1589 + "primaryKey": true,
1590 + "notNull": true
1591 + },
1592 + "user_id": {
1593 + "name": "user_id",
1594 + "type": "text",
1595 + "primaryKey": false,
1596 + "notNull": true
1597 + },
1598 + "name": {
1599 + "name": "name",
1600 + "type": "text",
1601 + "primaryKey": false,
1602 + "notNull": true
1603 + },
1604 + "description": {
1605 + "name": "description",
1606 + "type": "text",
1607 + "primaryKey": false,
1608 + "notNull": false
1609 + },
1610 + "icon": {
1611 + "name": "icon",
1612 + "type": "text",
1613 + "primaryKey": false,
1614 + "notNull": false
1615 + },
1616 + "system_prompt": {
1617 + "name": "system_prompt",
1618 + "type": "text",
1619 + "primaryKey": false,
1620 + "notNull": true
1621 + },
1622 + "default_model_key": {
1623 + "name": "default_model_key",
1624 + "type": "text",
1625 + "primaryKey": false,
1626 + "notNull": false
1627 + },
1628 + "parameters": {
1629 + "name": "parameters",
1630 + "type": "jsonb",
1631 + "primaryKey": false,
1632 + "notNull": true,
1633 + "default": "'{}'::jsonb"
1634 + },
1635 + "tools": {
1636 + "name": "tools",
1637 + "type": "jsonb",
1638 + "primaryKey": false,
1639 + "notNull": true,
1640 + "default": "'{}'::jsonb"
1641 + },
1642 + "sort_order": {
1643 + "name": "sort_order",
1644 + "type": "integer",
1645 + "primaryKey": false,
1646 + "notNull": true,
1647 + "default": 0
1648 + },
1649 + "created_at": {
1650 + "name": "created_at",
1651 + "type": "timestamp with time zone",
1652 + "primaryKey": false,
1653 + "notNull": true,
1654 + "default": "now()"
1655 + },
1656 + "updated_at": {
1657 + "name": "updated_at",
1658 + "type": "timestamp with time zone",
1659 + "primaryKey": false,
1660 + "notNull": true,
1661 + "default": "now()"
1662 + }
1663 + },
1664 + "indexes": {
1665 + "prompt_presets_user_idx": {
1666 + "name": "prompt_presets_user_idx",
1667 + "columns": [
1668 + {
1669 + "expression": "user_id",
1670 + "isExpression": false,
1671 + "asc": true,
1672 + "nulls": "last"
1673 + }
1674 + ],
1675 + "isUnique": false,
1676 + "concurrently": false,
1677 + "method": "btree",
1678 + "with": {}
1679 + }
1680 + },
1681 + "foreignKeys": {
1682 + "prompt_presets_user_id_users_id_fk": {
1683 + "name": "prompt_presets_user_id_users_id_fk",
1684 + "tableFrom": "prompt_presets",
1685 + "tableTo": "users",
1686 + "columnsFrom": [
1687 + "user_id"
1688 + ],
1689 + "columnsTo": [
1690 + "id"
1691 + ],
1692 + "onDelete": "cascade",
1693 + "onUpdate": "no action"
1694 + }
1695 + },
1696 + "compositePrimaryKeys": {},
1697 + "uniqueConstraints": {},
1698 + "policies": {},
1699 + "checkConstraints": {},
1700 + "isRLSEnabled": false
1701 + },
1702 + "public.provider_connections": {
1703 + "name": "provider_connections",
1704 + "schema": "",
1705 + "columns": {
1706 + "id": {
1707 + "name": "id",
1708 + "type": "text",
1709 + "primaryKey": true,
1710 + "notNull": true
1711 + },
1712 + "user_id": {
1713 + "name": "user_id",
1714 + "type": "text",
1715 + "primaryKey": false,
1716 + "notNull": true
1717 + },
1718 + "provider": {
1719 + "name": "provider",
1720 + "type": "text",
1721 + "primaryKey": false,
1722 + "notNull": true
1723 + },
1724 + "encrypted_key": {
1725 + "name": "encrypted_key",
1726 + "type": "text",
1727 + "primaryKey": false,
1728 + "notNull": true
1729 + },
1730 + "key_hint": {
1731 + "name": "key_hint",
1732 + "type": "text",
1733 + "primaryKey": false,
1734 + "notNull": true
1735 + },
1736 + "key_fingerprint": {
1737 + "name": "key_fingerprint",
1738 + "type": "text",
1739 + "primaryKey": false,
1740 + "notNull": true
1741 + },
1742 + "status": {
1743 + "name": "status",
1744 + "type": "text",
1745 + "primaryKey": false,
1746 + "notNull": true,
1747 + "default": "'unverified'"
1748 + },
1749 + "last_validated_at": {
1750 + "name": "last_validated_at",
1751 + "type": "timestamp with time zone",
1752 + "primaryKey": false,
1753 + "notNull": false
1754 + },
1755 + "last_validation_error": {
1756 + "name": "last_validation_error",
1757 + "type": "text",
1758 + "primaryKey": false,
1759 + "notNull": false
1760 + },
1761 + "last_success_at": {
1762 + "name": "last_success_at",
1763 + "type": "timestamp with time zone",
1764 + "primaryKey": false,
1765 + "notNull": false
1766 + },
1767 + "last_error_at": {
1768 + "name": "last_error_at",
1769 + "type": "timestamp with time zone",
1770 + "primaryKey": false,
1771 + "notNull": false
1772 + },
1773 + "last_error_code": {
1774 + "name": "last_error_code",
1775 + "type": "text",
1776 + "primaryKey": false,
1777 + "notNull": false
1778 + },
1779 + "models_available": {
1780 + "name": "models_available",
1781 + "type": "integer",
1782 + "primaryKey": false,
1783 + "notNull": false
1784 + },
1785 + "created_at": {
1786 + "name": "created_at",
1787 + "type": "timestamp with time zone",
1788 + "primaryKey": false,
1789 + "notNull": true,
1790 + "default": "now()"
1791 + },
1792 + "updated_at": {
1793 + "name": "updated_at",
1794 + "type": "timestamp with time zone",
1795 + "primaryKey": false,
1796 + "notNull": true,
1797 + "default": "now()"
1798 + }
1799 + },
1800 + "indexes": {
1801 + "provider_connections_user_provider_uq": {
1802 + "name": "provider_connections_user_provider_uq",
1803 + "columns": [
1804 + {
1805 + "expression": "user_id",
1806 + "isExpression": false,
1807 + "asc": true,
1808 + "nulls": "last"
1809 + },
1810 + {
1811 + "expression": "provider",
1812 + "isExpression": false,
1813 + "asc": true,
1814 + "nulls": "last"
1815 + }
1816 + ],
1817 + "isUnique": true,
1818 + "concurrently": false,
1819 + "method": "btree",
1820 + "with": {}
1821 + }
1822 + },
1823 + "foreignKeys": {
1824 + "provider_connections_user_id_users_id_fk": {
1825 + "name": "provider_connections_user_id_users_id_fk",
1826 + "tableFrom": "provider_connections",
1827 + "tableTo": "users",
1828 + "columnsFrom": [
1829 + "user_id"
1830 + ],
1831 + "columnsTo": [
1832 + "id"
1833 + ],
1834 + "onDelete": "cascade",
1835 + "onUpdate": "no action"
1836 + }
1837 + },
1838 + "compositePrimaryKeys": {},
1839 + "uniqueConstraints": {},
1840 + "policies": {},
1841 + "checkConstraints": {},
1842 + "isRLSEnabled": false
1843 + },
1844 + "public.sessions": {
1845 + "name": "sessions",
1846 + "schema": "",
1847 + "columns": {
1848 + "id": {
1849 + "name": "id",
1850 + "type": "text",
1851 + "primaryKey": true,
1852 + "notNull": true
1853 + },
1854 + "expires_at": {
1855 + "name": "expires_at",
1856 + "type": "timestamp with time zone",
1857 + "primaryKey": false,
1858 + "notNull": true
1859 + },
1860 + "token": {
1861 + "name": "token",
1862 + "type": "text",
1863 + "primaryKey": false,
1864 + "notNull": true
1865 + },
1866 + "created_at": {
1867 + "name": "created_at",
1868 + "type": "timestamp with time zone",
1869 + "primaryKey": false,
1870 + "notNull": true,
1871 + "default": "now()"
1872 + },
1873 + "updated_at": {
1874 + "name": "updated_at",
1875 + "type": "timestamp with time zone",
1876 + "primaryKey": false,
1877 + "notNull": true,
1878 + "default": "now()"
1879 + },
1880 + "ip_address": {
1881 + "name": "ip_address",
1882 + "type": "text",
1883 + "primaryKey": false,
1884 + "notNull": false
1885 + },
1886 + "user_agent": {
1887 + "name": "user_agent",
1888 + "type": "text",
1889 + "primaryKey": false,
1890 + "notNull": false
1891 + },
1892 + "user_id": {
1893 + "name": "user_id",
1894 + "type": "text",
1895 + "primaryKey": false,
1896 + "notNull": true
1897 + }
1898 + },
1899 + "indexes": {
1900 + "sessions_token_uq": {
1901 + "name": "sessions_token_uq",
1902 + "columns": [
1903 + {
1904 + "expression": "token",
1905 + "isExpression": false,
1906 + "asc": true,
1907 + "nulls": "last"
1908 + }
1909 + ],
1910 + "isUnique": true,
1911 + "concurrently": false,
1912 + "method": "btree",
1913 + "with": {}
1914 + },
1915 + "sessions_user_idx": {
1916 + "name": "sessions_user_idx",
1917 + "columns": [
1918 + {
1919 + "expression": "user_id",
1920 + "isExpression": false,
1921 + "asc": true,
1922 + "nulls": "last"
1923 + }
1924 + ],
1925 + "isUnique": false,
1926 + "concurrently": false,
1927 + "method": "btree",
1928 + "with": {}
1929 + }
1930 + },
1931 + "foreignKeys": {
1932 + "sessions_user_id_users_id_fk": {
1933 + "name": "sessions_user_id_users_id_fk",
1934 + "tableFrom": "sessions",
1935 + "tableTo": "users",
1936 + "columnsFrom": [
1937 + "user_id"
1938 + ],
1939 + "columnsTo": [
1940 + "id"
1941 + ],
1942 + "onDelete": "cascade",
1943 + "onUpdate": "no action"
1944 + }
1945 + },
1946 + "compositePrimaryKeys": {},
1947 + "uniqueConstraints": {},
1948 + "policies": {},
1949 + "checkConstraints": {},
1950 + "isRLSEnabled": false
1951 + },
1952 + "public.shared_conversations": {
1953 + "name": "shared_conversations",
1954 + "schema": "",
1955 + "columns": {
1956 + "id": {
1957 + "name": "id",
1958 + "type": "text",
1959 + "primaryKey": true,
1960 + "notNull": true
1961 + },
1962 + "conversation_id": {
1963 + "name": "conversation_id",
1964 + "type": "text",
1965 + "primaryKey": false,
1966 + "notNull": true
1967 + },
1968 + "user_id": {
1969 + "name": "user_id",
1970 + "type": "text",
1971 + "primaryKey": false,
1972 + "notNull": true
1973 + },
1974 + "title": {
1975 + "name": "title",
1976 + "type": "text",
1977 + "primaryKey": false,
1978 + "notNull": true
1979 + },
1980 + "snapshot": {
1981 + "name": "snapshot",
1982 + "type": "jsonb",
1983 + "primaryKey": false,
1984 + "notNull": true
1985 + },
1986 + "is_public": {
1987 + "name": "is_public",
1988 + "type": "boolean",
1989 + "primaryKey": false,
1990 + "notNull": true,
1991 + "default": true
1992 + },
1993 + "view_count": {
1994 + "name": "view_count",
1995 + "type": "integer",
1996 + "primaryKey": false,
1997 + "notNull": true,
1998 + "default": 0
1999 + },
2000 + "created_at": {
2001 + "name": "created_at",
2002 + "type": "timestamp with time zone",
2003 + "primaryKey": false,
2004 + "notNull": true,
2005 + "default": "now()"
2006 + },
2007 + "revoked_at": {
2008 + "name": "revoked_at",
2009 + "type": "timestamp with time zone",
2010 + "primaryKey": false,
2011 + "notNull": false
2012 + }
2013 + },
2014 + "indexes": {
2015 + "shared_conversation_idx": {
2016 + "name": "shared_conversation_idx",
2017 + "columns": [
2018 + {
2019 + "expression": "conversation_id",
2020 + "isExpression": false,
2021 + "asc": true,
2022 + "nulls": "last"
2023 + }
2024 + ],
2025 + "isUnique": false,
2026 + "concurrently": false,
2027 + "method": "btree",
2028 + "with": {}
2029 + }
2030 + },
2031 + "foreignKeys": {
2032 + "shared_conversations_conversation_id_conversations_id_fk": {
2033 + "name": "shared_conversations_conversation_id_conversations_id_fk",
2034 + "tableFrom": "shared_conversations",
2035 + "tableTo": "conversations",
2036 + "columnsFrom": [
2037 + "conversation_id"
2038 + ],
2039 + "columnsTo": [
2040 + "id"
2041 + ],
2042 + "onDelete": "cascade",
2043 + "onUpdate": "no action"
2044 + },
2045 + "shared_conversations_user_id_users_id_fk": {
2046 + "name": "shared_conversations_user_id_users_id_fk",
2047 + "tableFrom": "shared_conversations",
2048 + "tableTo": "users",
2049 + "columnsFrom": [
2050 + "user_id"
2051 + ],
2052 + "columnsTo": [
2053 + "id"
2054 + ],
2055 + "onDelete": "cascade",
2056 + "onUpdate": "no action"
2057 + }
2058 + },
2059 + "compositePrimaryKeys": {},
2060 + "uniqueConstraints": {},
2061 + "policies": {},
2062 + "checkConstraints": {},
2063 + "isRLSEnabled": false
2064 + },
2065 + "public.tags": {
2066 + "name": "tags",
2067 + "schema": "",
2068 + "columns": {
2069 + "id": {
2070 + "name": "id",
2071 + "type": "text",
2072 + "primaryKey": true,
2073 + "notNull": true
2074 + },
2075 + "user_id": {
2076 + "name": "user_id",
2077 + "type": "text",
2078 + "primaryKey": false,
2079 + "notNull": true
2080 + },
2081 + "name": {
2082 + "name": "name",
2083 + "type": "text",
2084 + "primaryKey": false,
2085 + "notNull": true
2086 + },
2087 + "color": {
2088 + "name": "color",
2089 + "type": "text",
2090 + "primaryKey": false,
2091 + "notNull": false
2092 + },
2093 + "created_at": {
2094 + "name": "created_at",
2095 + "type": "timestamp with time zone",
2096 + "primaryKey": false,
2097 + "notNull": true,
2098 + "default": "now()"
2099 + }
2100 + },
2101 + "indexes": {
2102 + "tags_user_name_uq": {
2103 + "name": "tags_user_name_uq",
2104 + "columns": [
2105 + {
2106 + "expression": "user_id",
2107 + "isExpression": false,
2108 + "asc": true,
2109 + "nulls": "last"
2110 + },
2111 + {
2112 + "expression": "name",
2113 + "isExpression": false,
2114 + "asc": true,
2115 + "nulls": "last"
2116 + }
2117 + ],
2118 + "isUnique": true,
2119 + "concurrently": false,
2120 + "method": "btree",
2121 + "with": {}
2122 + }
2123 + },
2124 + "foreignKeys": {
2125 + "tags_user_id_users_id_fk": {
2126 + "name": "tags_user_id_users_id_fk",
2127 + "tableFrom": "tags",
2128 + "tableTo": "users",
2129 + "columnsFrom": [
2130 + "user_id"
2131 + ],
2132 + "columnsTo": [
2133 + "id"
2134 + ],
2135 + "onDelete": "cascade",
2136 + "onUpdate": "no action"
2137 + }
2138 + },
2139 + "compositePrimaryKeys": {},
2140 + "uniqueConstraints": {},
2141 + "policies": {},
2142 + "checkConstraints": {},
2143 + "isRLSEnabled": false
2144 + },
2145 + "public.usage_records": {
2146 + "name": "usage_records",
2147 + "schema": "",
2148 + "columns": {
2149 + "id": {
2150 + "name": "id",
2151 + "type": "text",
2152 + "primaryKey": true,
2153 + "notNull": true
2154 + },
2155 + "user_id": {
2156 + "name": "user_id",
2157 + "type": "text",
2158 + "primaryKey": false,
2159 + "notNull": true
2160 + },
2161 + "conversation_id": {
2162 + "name": "conversation_id",
2163 + "type": "text",
2164 + "primaryKey": false,
2165 + "notNull": false
2166 + },
2167 + "message_id": {
2168 + "name": "message_id",
2169 + "type": "text",
2170 + "primaryKey": false,
2171 + "notNull": false
2172 + },
2173 + "arena_session_id": {
2174 + "name": "arena_session_id",
2175 + "type": "text",
2176 + "primaryKey": false,
2177 + "notNull": false
2178 + },
2179 + "provider": {
2180 + "name": "provider",
2181 + "type": "text",
2182 + "primaryKey": false,
2183 + "notNull": true
2184 + },
2185 + "model_key": {
2186 + "name": "model_key",
2187 + "type": "text",
2188 + "primaryKey": false,
2189 + "notNull": true
2190 + },
2191 + "kind": {
2192 + "name": "kind",
2193 + "type": "text",
2194 + "primaryKey": false,
2195 + "notNull": true,
2196 + "default": "'chat'"
2197 + },
2198 + "status": {
2199 + "name": "status",
2200 + "type": "text",
2201 + "primaryKey": false,
2202 + "notNull": true,
2203 + "default": "'ok'"
2204 + },
2205 + "error_code": {
2206 + "name": "error_code",
2207 + "type": "text",
2208 + "primaryKey": false,
2209 + "notNull": false
2210 + },
2211 + "input_tokens": {
2212 + "name": "input_tokens",
2213 + "type": "integer",
2214 + "primaryKey": false,
2215 + "notNull": true,
2216 + "default": 0
2217 + },
2218 + "output_tokens": {
2219 + "name": "output_tokens",
2220 + "type": "integer",
2221 + "primaryKey": false,
2222 + "notNull": true,
2223 + "default": 0
2224 + },
2225 + "cached_tokens": {
2226 + "name": "cached_tokens",
2227 + "type": "integer",
2228 + "primaryKey": false,
2229 + "notNull": true,
2230 + "default": 0
2231 + },
2232 + "reasoning_tokens": {
2233 + "name": "reasoning_tokens",
2234 + "type": "integer",
2235 + "primaryKey": false,
2236 + "notNull": true,
2237 + "default": 0
2238 + },
2239 + "cost_usd": {
2240 + "name": "cost_usd",
2241 + "type": "double precision",
2242 + "primaryKey": false,
2243 + "notNull": false
2244 + },
2245 + "latency_ms": {
2246 + "name": "latency_ms",
2247 + "type": "integer",
2248 + "primaryKey": false,
2249 + "notNull": false
2250 + },
2251 + "ttft_ms": {
2252 + "name": "ttft_ms",
2253 + "type": "integer",
2254 + "primaryKey": false,
2255 + "notNull": false
2256 + },
2257 + "created_at": {
2258 + "name": "created_at",
2259 + "type": "timestamp with time zone",
2260 + "primaryKey": false,
2261 + "notNull": true,
2262 + "default": "now()"
2263 + }
2264 + },
2265 + "indexes": {
2266 + "usage_user_created_idx": {
2267 + "name": "usage_user_created_idx",
2268 + "columns": [
2269 + {
2270 + "expression": "user_id",
2271 + "isExpression": false,
2272 + "asc": true,
2273 + "nulls": "last"
2274 + },
2275 + {
2276 + "expression": "created_at",
2277 + "isExpression": false,
2278 + "asc": true,
2279 + "nulls": "last"
2280 + }
2281 + ],
2282 + "isUnique": false,
2283 + "concurrently": false,
2284 + "method": "btree",
2285 + "with": {}
2286 + },
2287 + "usage_user_provider_idx": {
2288 + "name": "usage_user_provider_idx",
2289 + "columns": [
2290 + {
2291 + "expression": "user_id",
2292 + "isExpression": false,
2293 + "asc": true,
2294 + "nulls": "last"
2295 + },
2296 + {
2297 + "expression": "provider",
2298 + "isExpression": false,
2299 + "asc": true,
2300 + "nulls": "last"
2301 + }
2302 + ],
2303 + "isUnique": false,
2304 + "concurrently": false,
2305 + "method": "btree",
2306 + "with": {}
2307 + },
2308 + "usage_user_model_idx": {
2309 + "name": "usage_user_model_idx",
2310 + "columns": [
2311 + {
2312 + "expression": "user_id",
2313 + "isExpression": false,
2314 + "asc": true,
2315 + "nulls": "last"
2316 + },
2317 + {
2318 + "expression": "model_key",
2319 + "isExpression": false,
2320 + "asc": true,
2321 + "nulls": "last"
2322 + }
2323 + ],
2324 + "isUnique": false,
2325 + "concurrently": false,
2326 + "method": "btree",
2327 + "with": {}
2328 + }
2329 + },
2330 + "foreignKeys": {
2331 + "usage_records_user_id_users_id_fk": {
2332 + "name": "usage_records_user_id_users_id_fk",
2333 + "tableFrom": "usage_records",
2334 + "tableTo": "users",
2335 + "columnsFrom": [
2336 + "user_id"
2337 + ],
2338 + "columnsTo": [
2339 + "id"
2340 + ],
2341 + "onDelete": "cascade",
2342 + "onUpdate": "no action"
2343 + }
2344 + },
2345 + "compositePrimaryKeys": {},
2346 + "uniqueConstraints": {},
2347 + "policies": {},
2348 + "checkConstraints": {},
2349 + "isRLSEnabled": false
2350 + },
2351 + "public.user_model_favorites": {
2352 + "name": "user_model_favorites",
2353 + "schema": "",
2354 + "columns": {
2355 + "user_id": {
2356 + "name": "user_id",
2357 + "type": "text",
2358 + "primaryKey": false,
2359 + "notNull": true
2360 + },
2361 + "model_key": {
2362 + "name": "model_key",
2363 + "type": "text",
2364 + "primaryKey": false,
2365 + "notNull": true
2366 + },
2367 + "created_at": {
2368 + "name": "created_at",
2369 + "type": "timestamp with time zone",
2370 + "primaryKey": false,
2371 + "notNull": true,
2372 + "default": "now()"
2373 + }
2374 + },
2375 + "indexes": {},
2376 + "foreignKeys": {
2377 + "user_model_favorites_user_id_users_id_fk": {
2378 + "name": "user_model_favorites_user_id_users_id_fk",
2379 + "tableFrom": "user_model_favorites",
2380 + "tableTo": "users",
2381 + "columnsFrom": [
2382 + "user_id"
2383 + ],
2384 + "columnsTo": [
2385 + "id"
2386 + ],
2387 + "onDelete": "cascade",
2388 + "onUpdate": "no action"
2389 + }
2390 + },
2391 + "compositePrimaryKeys": {
2392 + "user_model_favorites_user_id_model_key_pk": {
2393 + "name": "user_model_favorites_user_id_model_key_pk",
2394 + "columns": [
2395 + "user_id",
2396 + "model_key"
2397 + ]
2398 + }
2399 + },
2400 + "uniqueConstraints": {},
2401 + "policies": {},
2402 + "checkConstraints": {},
2403 + "isRLSEnabled": false
2404 + },
2405 + "public.user_model_recents": {
2406 + "name": "user_model_recents",
2407 + "schema": "",
2408 + "columns": {
2409 + "user_id": {
2410 + "name": "user_id",
2411 + "type": "text",
2412 + "primaryKey": false,
2413 + "notNull": true
2414 + },
2415 + "model_key": {
2416 + "name": "model_key",
2417 + "type": "text",
2418 + "primaryKey": false,
2419 + "notNull": true
2420 + },
2421 + "used_at": {
2422 + "name": "used_at",
2423 + "type": "timestamp with time zone",
2424 + "primaryKey": false,
2425 + "notNull": true,
2426 + "default": "now()"
2427 + },
2428 + "uses": {
2429 + "name": "uses",
2430 + "type": "integer",
2431 + "primaryKey": false,
2432 + "notNull": true,
2433 + "default": 1
2434 + }
2435 + },
2436 + "indexes": {},
2437 + "foreignKeys": {
2438 + "user_model_recents_user_id_users_id_fk": {
2439 + "name": "user_model_recents_user_id_users_id_fk",
2440 + "tableFrom": "user_model_recents",
2441 + "tableTo": "users",
2442 + "columnsFrom": [
2443 + "user_id"
2444 + ],
2445 + "columnsTo": [
2446 + "id"
2447 + ],
2448 + "onDelete": "cascade",
2449 + "onUpdate": "no action"
2450 + }
2451 + },
2452 + "compositePrimaryKeys": {
2453 + "user_model_recents_user_id_model_key_pk": {
2454 + "name": "user_model_recents_user_id_model_key_pk",
2455 + "columns": [
2456 + "user_id",
2457 + "model_key"
2458 + ]
2459 + }
2460 + },
2461 + "uniqueConstraints": {},
2462 + "policies": {},
2463 + "checkConstraints": {},
2464 + "isRLSEnabled": false
2465 + },
2466 + "public.user_preferences": {
2467 + "name": "user_preferences",
2468 + "schema": "",
2469 + "columns": {
2470 + "user_id": {
2471 + "name": "user_id",
2472 + "type": "text",
2473 + "primaryKey": true,
2474 + "notNull": true
2475 + },
2476 + "theme": {
2477 + "name": "theme",
2478 + "type": "text",
2479 + "primaryKey": false,
2480 + "notNull": true,
2481 + "default": "'system'"
2482 + },
2483 + "language": {
2484 + "name": "language",
2485 + "type": "text",
2486 + "primaryKey": false,
2487 + "notNull": true,
2488 + "default": "'en'"
2489 + },
2490 + "default_model_key": {
2491 + "name": "default_model_key",
2492 + "type": "text",
2493 + "primaryKey": false,
2494 + "notNull": false
2495 + },
2496 + "default_system_prompt": {
2497 + "name": "default_system_prompt",
2498 + "type": "text",
2499 + "primaryKey": false,
2500 + "notNull": false
2501 + },
2502 + "enter_to_send": {
2503 + "name": "enter_to_send",
2504 + "type": "boolean",
2505 + "primaryKey": false,
2506 + "notNull": true,
2507 + "default": true
2508 + },
2509 + "streaming": {
2510 + "name": "streaming",
2511 + "type": "boolean",
2512 + "primaryKey": false,
2513 + "notNull": true,
2514 + "default": true
2515 + },
2516 + "code_wrap": {
2517 + "name": "code_wrap",
2518 + "type": "boolean",
2519 + "primaryKey": false,
2520 + "notNull": true,
2521 + "default": false
2522 + },
2523 + "show_reasoning": {
2524 + "name": "show_reasoning",
2525 + "type": "boolean",
2526 + "primaryKey": false,
2527 + "notNull": true,
2528 + "default": true
2529 + },
2530 + "show_costs": {
2531 + "name": "show_costs",
2532 + "type": "boolean",
2533 + "primaryKey": false,
2534 + "notNull": true,
2535 + "default": true
2536 + },
2537 + "auto_title": {
2538 + "name": "auto_title",
2539 + "type": "boolean",
2540 + "primaryKey": false,
2541 + "notNull": true,
2542 + "default": true
2543 + },
2544 + "extra": {
2545 + "name": "extra",
2546 + "type": "jsonb",
2547 + "primaryKey": false,
2548 + "notNull": true,
2549 + "default": "'{}'::jsonb"
2550 + },
2551 + "updated_at": {
2552 + "name": "updated_at",
2553 + "type": "timestamp with time zone",
2554 + "primaryKey": false,
2555 + "notNull": true,
2556 + "default": "now()"
2557 + }
2558 + },
2559 + "indexes": {},
2560 + "foreignKeys": {
2561 + "user_preferences_user_id_users_id_fk": {
2562 + "name": "user_preferences_user_id_users_id_fk",
2563 + "tableFrom": "user_preferences",
2564 + "tableTo": "users",
2565 + "columnsFrom": [
2566 + "user_id"
2567 + ],
2568 + "columnsTo": [
2569 + "id"
2570 + ],
2571 + "onDelete": "cascade",
2572 + "onUpdate": "no action"
2573 + }
2574 + },
2575 + "compositePrimaryKeys": {},
2576 + "uniqueConstraints": {},
2577 + "policies": {},
2578 + "checkConstraints": {},
2579 + "isRLSEnabled": false
2580 + },
2581 + "public.users": {
2582 + "name": "users",
2583 + "schema": "",
2584 + "columns": {
2585 + "id": {
2586 + "name": "id",
2587 + "type": "text",
2588 + "primaryKey": true,
2589 + "notNull": true
2590 + },
2591 + "name": {
2592 + "name": "name",
2593 + "type": "text",
2594 + "primaryKey": false,
2595 + "notNull": true,
2596 + "default": "''"
2597 + },
2598 + "email": {
2599 + "name": "email",
2600 + "type": "text",
2601 + "primaryKey": false,
2602 + "notNull": true
2603 + },
2604 + "email_verified": {
2605 + "name": "email_verified",
2606 + "type": "boolean",
2607 + "primaryKey": false,
2608 + "notNull": true,
2609 + "default": false
2610 + },
2611 + "image": {
2612 + "name": "image",
2613 + "type": "text",
2614 + "primaryKey": false,
2615 + "notNull": false
2616 + },
2617 + "role": {
2618 + "name": "role",
2619 + "type": "text",
2620 + "primaryKey": false,
2621 + "notNull": true,
2622 + "default": "'user'"
2623 + },
2624 + "onboarding_completed_at": {
2625 + "name": "onboarding_completed_at",
2626 + "type": "timestamp with time zone",
2627 + "primaryKey": false,
2628 + "notNull": false
2629 + },
2630 + "created_at": {
2631 + "name": "created_at",
2632 + "type": "timestamp with time zone",
2633 + "primaryKey": false,
2634 + "notNull": true,
2635 + "default": "now()"
2636 + },
2637 + "updated_at": {
2638 + "name": "updated_at",
2639 + "type": "timestamp with time zone",
2640 + "primaryKey": false,
2641 + "notNull": true,
2642 + "default": "now()"
2643 + }
2644 + },
2645 + "indexes": {
2646 + "users_email_uq": {
2647 + "name": "users_email_uq",
2648 + "columns": [
2649 + {
2650 + "expression": "email",
2651 + "isExpression": false,
2652 + "asc": true,
2653 + "nulls": "last"
2654 + }
2655 + ],
2656 + "isUnique": true,
2657 + "concurrently": false,
2658 + "method": "btree",
2659 + "with": {}
2660 + }
2661 + },
2662 + "foreignKeys": {},
2663 + "compositePrimaryKeys": {},
2664 + "uniqueConstraints": {},
2665 + "policies": {},
2666 + "checkConstraints": {},
2667 + "isRLSEnabled": false
2668 + },
2669 + "public.verifications": {
2670 + "name": "verifications",
2671 + "schema": "",
2672 + "columns": {
2673 + "id": {
2674 + "name": "id",
2675 + "type": "text",
2676 + "primaryKey": true,
2677 + "notNull": true
2678 + },
2679 + "identifier": {
2680 + "name": "identifier",
2681 + "type": "text",
2682 + "primaryKey": false,
2683 + "notNull": true
2684 + },
2685 + "value": {
2686 + "name": "value",
2687 + "type": "text",
2688 + "primaryKey": false,
2689 + "notNull": true
2690 + },
2691 + "expires_at": {
2692 + "name": "expires_at",
2693 + "type": "timestamp with time zone",
2694 + "primaryKey": false,
2695 + "notNull": true
2696 + },
2697 + "created_at": {
2698 + "name": "created_at",
2699 + "type": "timestamp with time zone",
2700 + "primaryKey": false,
2701 + "notNull": true,
2702 + "default": "now()"
2703 + },
2704 + "updated_at": {
2705 + "name": "updated_at",
2706 + "type": "timestamp with time zone",
2707 + "primaryKey": false,
2708 + "notNull": true,
2709 + "default": "now()"
2710 + }
2711 + },
2712 + "indexes": {
2713 + "verifications_identifier_idx": {
2714 + "name": "verifications_identifier_idx",
2715 + "columns": [
2716 + {
2717 + "expression": "identifier",
2718 + "isExpression": false,
2719 + "asc": true,
2720 + "nulls": "last"
2721 + }
2722 + ],
2723 + "isUnique": false,
2724 + "concurrently": false,
2725 + "method": "btree",
2726 + "with": {}
2727 + }
2728 + },
2729 + "foreignKeys": {},
2730 + "compositePrimaryKeys": {},
2731 + "uniqueConstraints": {},
2732 + "policies": {},
2733 + "checkConstraints": {},
2734 + "isRLSEnabled": false
2735 + }
2736 + },
2737 + "enums": {},
2738 + "schemas": {},
2739 + "sequences": {},
2740 + "roles": {},
2741 + "policies": {},
2742 + "views": {},
2743 + "_meta": {
2744 + "columns": {},
2745 + "schemas": {},
2746 + "tables": {}
2747 + }
2748 +}
\ No newline at end of file
added drizzle/meta/_journal.json +13 −0
@@ -0,0 +1,13 @@
1 +{
2 + "version": "7",
3 + "dialect": "postgresql",
4 + "entries": [
5 + {
6 + "idx": 0,
7 + "version": "7",
8 + "when": 1788844960714,
9 + "tag": "0000_foamy_loners",
10 + "breakpoints": true
11 + }
12 + ]
13 +}
\ No newline at end of file
added e2e/full-flow.spec.ts +156 −0
@@ -0,0 +1,156 @@
1 +import { test, expect } from "@playwright/test";
2 +import { TEST_EMAIL, TEST_PASSWORD, lastLinkFromLog, login, noConsoleErrors, readEnv, sql } from "./helpers";
3 +
4 +/**
5 + * Full workflow against the dev server (EMAIL_DRY_RUN=1 EMAIL_DRY_RUN_PRINT=1 so links land in the log):
6 + * sign up → verify email → login → add provider key → validate → select model → send → stream → new chat →
7 + * reload → persistence → change password → logout → login again.
8 + */
9 +test.describe.serial("PolyLLM full flow", () => {
10 + const email = TEST_EMAIL;
11 + const password = TEST_PASSWORD;
12 + let conversationUrl = "";
13 +
14 + test("landing renders without console errors", async ({ page }) => {
15 + const errors = await noConsoleErrors(page);
16 + await page.goto("/");
17 + await expect(page.getByRole("heading", { level: 1 })).toContainText(/every model/i);
18 + await expect(page.getByRole("link", { name: /start using polyllm/i }).first()).toBeVisible();
19 + expect(errors).toEqual([]);
20 + });
21 +
22 + test("sign up sends a verification email", async ({ page }) => {
23 + await page.goto("/signup");
24 + await page.getByLabel(/name/i).fill("E2E Tester");
25 + await page.getByLabel(/email/i).fill(email);
26 + await page.getByLabel(/^password$/i).fill(password);
27 + const confirm = page.getByLabel(/confirm/i);
28 + if (await confirm.count()) await confirm.fill(password);
29 + await page.getByRole("button", { name: /create account|sign up/i }).click();
30 + await expect(page.getByText(/check your inbox|verify/i).first()).toBeVisible({ timeout: 30_000 });
31 + // the account exists but is unverified
32 + await expect.poll(() => sql(`select email_verified from users where email='${email}'`)).toBe("f");
33 + });
34 +
35 + test("login before verification is refused", async ({ page }) => {
36 + await page.goto("/login");
37 + await page.getByLabel(/email/i).fill(email);
38 + await page.getByLabel(/^password$/i).fill(password);
39 + await page.getByRole("button", { name: /sign in/i }).click();
40 + await expect(page.getByText(/verify|not verified|check your inbox/i).first()).toBeVisible({ timeout: 20_000 });
41 + });
42 +
43 + test("verification link activates the account and signs in", async ({ page }) => {
44 + const link = lastLinkFromLog(/http:\/\/localhost:3000\/api\/auth\/verify-email\?token=[^\s"'<>]+/g);
45 + expect(link, "verification link should be printed in the dev log").toBeTruthy();
46 + await page.goto(link!);
47 + await page.waitForURL(/\/app|\/verify-email/, { timeout: 30_000 });
48 + await expect.poll(() => sql(`select email_verified from users where email='${email}'`)).toBe("t");
49 + if (!/\/app/.test(page.url())) await login(page, email, password);
50 + await expect(page).toHaveURL(/\/app\/chat/);
51 + });
52 +
53 + test("add + validate provider keys (real providers)", async ({ page }) => {
54 + await login(page, email, password);
55 + await page.goto("/app/settings/providers");
56 + const names: Record<string, RegExp> = { anthropic: /^Anthropic$/, openai: /^OpenAI$/, xai: /^xAI$/, gemini: /^Google Gemini$/ };
57 + for (const [provider, envName] of [
58 + ["anthropic", "ANTHROPIC_API_KEY"],
59 + ["openai", "OPENAI_API_KEY"],
60 + ["xai", "XAI_API_KEY"],
61 + ["gemini", "GOOGLE_GEMINI_API_KEY"],
62 + ] as const) {
63 + const key = readEnv(envName);
64 + test.skip(!key, `${envName} missing`);
65 + const item = page.locator("li", { has: page.getByRole("heading", { level: 3, name: names[provider] }) }).first();
66 + await item.getByRole("button", { name: /add key|replace key/i }).click();
67 + await page.locator("#provider-api-key").fill(key!);
68 + await page.getByRole("button", { name: /^connect$|^replace key$/i }).last().click();
69 + await expect(item).toContainText(/connected/i, { timeout: 60_000 });
70 + await expect(page.locator("#provider-api-key")).toHaveCount(0);
71 + }
72 + // never in the DOM
73 + const html = await page.content();
74 + expect(html).not.toContain(readEnv("ANTHROPIC_API_KEY")!.slice(10, 30));
75 + await expect.poll(() => sql(`select count(*) from provider_connections pc join users u on u.id=pc.user_id where u.email='${email}' and pc.status='valid'`)).toBe("4");
76 + // keys are encrypted at rest
77 + const stored = sql(`select encrypted_key from provider_connections pc join users u on u.id=pc.user_id where u.email='${email}' and provider='anthropic'`);
78 + expect(stored.startsWith("v1.")).toBe(true);
79 + expect(stored).not.toContain("sk-ant");
80 + });
81 +
82 + test("select a model, send a message and receive a real stream", async ({ page }) => {
83 + await login(page, email, password);
84 + await page.goto("/app/chat");
85 + await page.getByRole("button", { name: /select model/i }).click();
86 + await page.getByLabel(/search models/i).fill("haiku 4.5");
87 + await page.getByRole("option").first().click();
88 + await expect(page.getByRole("button", { name: /select model/i })).toContainText(/haiku/i);
89 + await page.getByLabel(/^message$/i).fill("Reply with exactly the word PONG and nothing else.");
90 + await page.getByRole("button", { name: /^send$/i }).click();
91 + await expect(page.getByText(/PONG/).first()).toBeVisible({ timeout: 60_000 });
92 + await page.waitForURL(/\/app\/chat\/cnv_/, { timeout: 30_000 });
93 + conversationUrl = page.url();
94 + // footer meta appears (tokens + latency)
95 + await expect(page.getByText(/tok\/s|\bin ·/).first()).toBeVisible({ timeout: 30_000 });
96 + // sidebar shows the conversation with an auto title
97 + await expect(page.locator("aside").getByText(/reply with exactly/i).first()).toBeVisible();
98 + });
99 +
100 + test("conversation persists after reload and a second model works", async ({ page }) => {
101 + await login(page, email, password);
102 + await page.goto(conversationUrl);
103 + await expect(page.getByText(/PONG/).first()).toBeVisible();
104 + // switch to an OpenAI model in the same conversation and continue
105 + await page.getByRole("button", { name: /select model/i }).click();
106 + await page.getByLabel(/search models/i).fill("gpt-5.4-nano");
107 + await page.getByRole("option").first().click();
108 + await page.getByLabel(/^message$/i).fill("Now reply with exactly the word PING.");
109 + await page.getByRole("button", { name: /^send$/i }).click();
110 + await expect(page.getByText(/PING/).first()).toBeVisible({ timeout: 60_000 });
111 + await page.reload();
112 + await expect(page.getByText(/PONG/).first()).toBeVisible();
113 + await expect(page.getByText(/PING/).first()).toBeVisible();
114 + });
115 +
116 + test("model configuration is capability-driven", async ({ page }) => {
117 + await login(page, email, password);
118 + await page.goto("/app/chat");
119 + await page.getByRole("button", { name: /select model/i }).click();
120 + await page.getByLabel(/search models/i).fill("gpt-5.5");
121 + await page.getByRole("option").first().click();
122 + await page.getByRole("button", { name: /model configuration/i }).click();
123 + await expect(page.getByText(/reasoning/i).first()).toBeVisible();
124 + await expect(page.getByText(/^Effort$/)).toBeVisible();
125 + // seed/stop are not supported by the Responses API → never shown
126 + await expect(page.getByText(/^Seed$/)).toHaveCount(0);
127 + await expect(page.getByText(/stop sequences/i)).toHaveCount(0);
128 + await page.keyboard.press("Escape");
129 + });
130 +
131 + test("usage dashboard shows the requests", async ({ page }) => {
132 + await login(page, email, password);
133 + await page.goto("/app/usage");
134 + await expect(page.getByText(/requests/i).first()).toBeVisible();
135 + await expect.poll(() => Number(sql(`select count(*) from usage_records ur join users u on u.id=ur.user_id where u.email='${email}'`))).toBeGreaterThanOrEqual(2);
136 + });
137 +
138 + test("change password, logout, login again", async ({ page }) => {
139 + await login(page, email, password);
140 + await page.goto("/app/settings/security");
141 + const newPassword = `${password}-2`;
142 + await page.getByLabel(/current password/i).fill(password);
143 + await page.getByLabel(/^new password$/i).fill(newPassword);
144 + const confirm = page.getByLabel(/confirm/i);
145 + if (await confirm.count()) await confirm.fill(newPassword);
146 + await page.getByRole("button", { name: /change password|update password/i }).click();
147 + await expect(page.getByText(/password (changed|updated)/i).first()).toBeVisible({ timeout: 20_000 });
148 + // sign out via the sidebar menu
149 + await page.goto("/app/chat");
150 + await page.getByText(email).first().click();
151 + await page.getByRole("menuitem", { name: /sign out/i }).click();
152 + await page.waitForURL(/\/login/);
153 + await login(page, email, newPassword);
154 + await expect(page).toHaveURL(/\/app/);
155 + });
156 +});
added e2e/helpers.ts +44 −0
@@ -0,0 +1,44 @@
1 +import { execSync } from "node:child_process";
2 +import fs from "node:fs";
3 +import type { Page } from "@playwright/test";
4 +
5 +export const DB = process.env.E2E_DATABASE_URL ?? "postgres://localhost:5432/polyllm";
6 +export const DEV_LOG = process.env.E2E_DEV_LOG ?? "/tmp/polyllm-dev.log";
7 +
8 +export function sql(q: string): string {
9 + return execSync(`psql "${DB}" -Atc ${JSON.stringify(q)}`, { encoding: "utf8" }).trim();
10 +}
11 +
12 +/** Finds the latest verification / reset URL for an email in the dev log (EMAIL_DRY_RUN_PRINT=1). */
13 +export function lastLinkFromLog(pattern: RegExp): string | null {
14 + const log = fs.readFileSync(DEV_LOG, "utf8");
15 + const matches = [...log.matchAll(pattern)];
16 + return matches.length ? matches[matches.length - 1][0] : null;
17 +}
18 +
19 +export function readEnv(name: string): string | undefined {
20 + if (process.env[name]) return process.env[name];
21 + const env = fs.existsSync(".env") ? fs.readFileSync(".env", "utf8") : "";
22 + const m = env.match(new RegExp(`^${name}=(.*)$`, "m"));
23 + return m ? m[1].replace(/^"|"$/g, "") : undefined;
24 +}
25 +
26 +export const TEST_EMAIL = process.env.E2E_EMAIL ?? `e2e+${Date.now()}@polyllm.test`;
27 +export const TEST_PASSWORD = "Str0ng-Passw0rd-e2e!";
28 +
29 +export async function login(page: Page, email: string, password: string) {
30 + await page.goto("/login");
31 + await page.getByLabel(/email/i).fill(email);
32 + await page.getByLabel(/^password$/i).fill(password);
33 + await page.getByRole("button", { name: /sign in/i }).click();
34 + await page.waitForURL(/\/app/);
35 +}
36 +
37 +export async function noConsoleErrors(page: Page) {
38 + const errors: string[] = [];
39 + page.on("console", (msg) => {
40 + if (msg.type() === "error" && !/favicon|hydration|Download the React DevTools/i.test(msg.text())) errors.push(msg.text());
41 + });
42 + page.on("pageerror", (e) => errors.push(e.message));
43 + return errors;
44 +}
added e2e/mobile.spec.ts +12 −0
@@ -0,0 +1,12 @@
1 +import { test, expect } from "@playwright/test";
2 +import { noConsoleErrors } from "./helpers";
3 +
4 +test("landing and auth pages have no horizontal overflow on mobile", async ({ page }) => {
5 + const errors = await noConsoleErrors(page);
6 + for (const path of ["/", "/login", "/signup", "/forgot-password"]) {
7 + await page.goto(path);
8 + const overflow = await page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth);
9 + expect(overflow, `${path} overflows horizontally by ${overflow}px`).toBeLessThanOrEqual(1);
10 + }
11 + expect(errors).toEqual([]);
12 +});
added eslint.config.mjs +10 −0
@@ -0,0 +1,10 @@
1 +import nextVitals from "eslint-config-next/core-web-vitals";
2 +import nextTs from "eslint-config-next/typescript";
3 +
4 +const eslintConfig = [
5 + ...nextVitals,
6 + ...nextTs,
7 + { ignores: [".next/**", "node_modules/**", "research/**", "drizzle/**", "playwright-report/**", "test-results/**"] },
8 +];
9 +
10 +export default eslintConfig;
added next.config.ts +51 −0
@@ -0,0 +1,51 @@
1 +import type { NextConfig } from "next";
2 +
3 +const isProd = process.env.NODE_ENV === "production";
4 +
5 +/**
6 + * Content-Security-Policy. Inline styles are required by Tailwind's runtime-free
7 + * output only for a few third-party components (Radix measures via style attrs),
8 + * and Next.js injects inline scripts for hydration; nonces are not used because the
9 + * app is fully static-shell + client-fetch and `next start` runs behind ngrok.
10 + */
11 +const csp = [
12 + "default-src 'self'",
13 + "base-uri 'self'",
14 + "frame-ancestors 'none'",
15 + "form-action 'self'",
16 + "object-src 'none'",
17 + "img-src 'self' data: blob: https:",
18 + "font-src 'self' data:",
19 + "style-src 'self' 'unsafe-inline'",
20 + isProd ? "script-src 'self' 'unsafe-inline'" : "script-src 'self' 'unsafe-inline' 'unsafe-eval'",
21 + "connect-src 'self'",
22 + "worker-src 'self' blob:",
23 + "upgrade-insecure-requests",
24 +].join("; ");
25 +
26 +const nextConfig: NextConfig = {
27 + reactStrictMode: true,
28 + poweredByHeader: false,
29 + agentRules: false,
30 + serverExternalPackages: ["pg", "argon2", "resend", "@anthropic-ai/sdk", "openai", "@google/genai", "shiki"],
31 + experimental: {
32 + serverActions: { bodySizeLimit: "2mb" },
33 + },
34 + async headers() {
35 + return [
36 + {
37 + source: "/(.*)",
38 + headers: [
39 + { key: "X-Content-Type-Options", value: "nosniff" },
40 + { key: "X-Frame-Options", value: "DENY" },
41 + { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
42 + { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=(), payment=()" },
43 + { key: "Content-Security-Policy", value: csp },
44 + ...(isProd ? [{ key: "Strict-Transport-Security", value: "max-age=31536000; includeSubDomains" }] : []),
45 + ],
46 + },
47 + ];
48 + },
49 +};
50 +
51 +export default nextConfig;
added package.json +80 −0
@@ -0,0 +1,80 @@
1 +{
2 + "name": "polyllm",
3 + "version": "0.1.0",
4 + "private": true,
5 + "description": "PolyLLM — One interface. Every model. Bring your own keys.",
6 + "type": "module",
7 + "packageManager": "pnpm@11.1.2",
8 + "engines": {
9 + "node": ">=22"
10 + },
11 + "scripts": {
12 + "dev": "next dev -p ${PORT:-3000}",
13 + "build": "next build",
14 + "start": "next start -p ${PORT:-3000} -H 0.0.0.0",
15 + "lint": "eslint",
16 + "typecheck": "tsc -p tsconfig.json --noEmit",
17 + "test": "vitest run",
18 + "test:e2e": "playwright test",
19 + "db:generate": "drizzle-kit generate",
20 + "db:migrate": "tsx src/db/migrate.ts",
21 + "db:studio": "drizzle-kit studio",
22 + "models:sync": "tsx --tsconfig tsconfig.json --import ./scripts/hooks.mjs scripts/sync-models.ts",
23 + "providers:matrix": "tsx --tsconfig tsconfig.json --import ./scripts/hooks.mjs scripts/provider-matrix.ts"
24 + },
25 + "dependencies": {
26 + "@anthropic-ai/sdk": "^0.124.0",
27 + "@google/genai": "^2.21.0",
28 + "@radix-ui/react-dialog": "^1.1.14",
29 + "@radix-ui/react-dropdown-menu": "^2.1.15",
30 + "@radix-ui/react-popover": "^1.1.14",
31 + "@radix-ui/react-scroll-area": "^1.2.9",
32 + "@radix-ui/react-select": "^2.2.5",
33 + "@radix-ui/react-slider": "^1.3.5",
34 + "@radix-ui/react-slot": "^1.2.3",
35 + "@radix-ui/react-switch": "^1.2.5",
36 + "@radix-ui/react-tabs": "^1.1.12",
37 + "@radix-ui/react-tooltip": "^1.2.7",
38 + "@tanstack/react-virtual": "^3.13.0",
39 + "argon2": "^0.45.0",
40 + "better-auth": "^1.7.3",
41 + "class-variance-authority": "^0.7.1",
42 + "clsx": "^2.1.1",
43 + "cmdk": "^1.1.1",
44 + "drizzle-orm": "^0.45.2",
45 + "geist": "^1.5.0",
46 + "lucide-react": "^1.42.0",
47 + "motion": "^12.23.0",
48 + "next": "16.3.4",
49 + "next-themes": "^0.4.6",
50 + "openai": "^7.10.0",
51 + "pg": "^8.23.0",
52 + "react": "19.2.8",
53 + "react-dom": "19.2.8",
54 + "react-markdown": "^10.1.0",
55 + "recharts": "^3.0.0",
56 + "rehype-raw": "^7.0.0",
57 + "remark-gfm": "^4.0.1",
58 + "resend": "^6.26.0",
59 + "server-only": "^0.0.1",
60 + "shiki": "^4.4.3",
61 + "swr": "^2.5.1",
62 + "tailwind-merge": "^3.3.1",
63 + "zod": "^4.5.4"
64 + },
65 + "devDependencies": {
66 + "@playwright/test": "^1.63.0",
67 + "@tailwindcss/postcss": "^4.3.3",
68 + "@types/node": "^24.0.0",
69 + "@types/pg": "^8.15.0",
70 + "@types/react": "^19",
71 + "@types/react-dom": "^19",
72 + "drizzle-kit": "^0.31.10",
73 + "eslint": "^9",
74 + "eslint-config-next": "16.3.4",
75 + "tailwindcss": "^4.3.3",
76 + "tsx": "^4.20.0",
77 + "typescript": "^5.9.3",
78 + "vitest": "^3.2.0"
79 + }
80 +}
added playwright.config.ts +18 −0
@@ -0,0 +1,18 @@
1 +import { defineConfig, devices } from "@playwright/test";
2 +
3 +const baseURL = process.env.E2E_BASE_URL ?? "http://localhost:3000";
4 +
5 +export default defineConfig({
6 + testDir: "./e2e",
7 + timeout: 180_000,
8 + expect: { timeout: 20_000 },
9 + fullyParallel: false,
10 + workers: 1,
11 + retries: 0,
12 + reporter: [["list"], ["html", { open: "never", outputFolder: "playwright-report" }]],
13 + use: { baseURL, trace: "retain-on-failure", screenshot: "only-on-failure", video: "off" },
14 + projects: [
15 + { name: "desktop", use: { ...devices["Desktop Chrome"], viewport: { width: 1360, height: 860 } } },
16 + { name: "mobile", use: { ...devices["iPhone 14"], browserName: "chromium" }, testMatch: /mobile\.spec\.ts/ },
17 + ],
18 +});
added pnpm-lock.yaml +9267 −0
@@ -0,0 +1,9267 @@
1 +lockfileVersion: '9.0'
2 +
3 +settings:
4 + autoInstallPeers: true
5 + excludeLinksFromLockfile: false
6 +
7 +importers:
8 +
9 + .:
10 + dependencies:
11 + '@anthropic-ai/sdk':
12 + specifier: ^0.124.0
13 + version: 0.124.0(zod@4.5.4)
14 + '@google/genai':
15 + specifier: ^2.21.0
16 + version: 2.21.0
17 + '@radix-ui/react-dialog':
18 + specifier: ^1.1.14
19 + version: 1.1.23(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
20 + '@radix-ui/react-dropdown-menu':
21 + specifier: ^2.1.15
22 + version: 2.1.24(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
23 + '@radix-ui/react-popover':
24 + specifier: ^1.1.14
25 + version: 1.1.23(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
26 + '@radix-ui/react-scroll-area':
27 + specifier: ^1.2.9
28 + version: 1.2.18(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
29 + '@radix-ui/react-select':
30 + specifier: ^2.2.5
31 + version: 2.3.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
32 + '@radix-ui/react-slider':
33 + specifier: ^1.3.5
34 + version: 1.4.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
35 + '@radix-ui/react-slot':
36 + specifier: ^1.2.3
37 + version: 1.3.3(@types/react@19.2.18)(react@19.2.8)
38 + '@radix-ui/react-switch':
39 + specifier: ^1.2.5
40 + version: 1.3.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
41 + '@radix-ui/react-tabs':
42 + specifier: ^1.1.12
43 + version: 1.1.21(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
44 + '@radix-ui/react-tooltip':
45 + specifier: ^1.2.7
46 + version: 1.2.16(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
47 + '@tanstack/react-virtual':
48 + specifier: ^3.13.0
49 + version: 3.14.10(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
50 + argon2:
51 + specifier: ^0.45.0
52 + version: 0.45.1
53 + better-auth:
54 + specifier: ^1.7.3
55 + version: 1.7.3(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@types/pg@8.23.1)(kysely@0.29.5)(pg@8.23.0))(next@16.3.4(@babel/core@7.29.7)(@playwright/test@1.63.0)(@types/node@24.13.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(pg@8.23.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13))
56 + class-variance-authority:
57 + specifier: ^0.7.1
58 + version: 0.7.1
59 + clsx:
60 + specifier: ^2.1.1
61 + version: 2.1.1
62 + cmdk:
63 + specifier: ^1.1.1
64 + version: 1.1.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
65 + drizzle-orm:
66 + specifier: ^0.45.2
67 + version: 0.45.2(@types/pg@8.23.1)(kysely@0.29.5)(pg@8.23.0)
68 + geist:
69 + specifier: ^1.5.0
70 + version: 1.7.2(next@16.3.4(@babel/core@7.29.7)(@playwright/test@1.63.0)(@types/node@24.13.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))
71 + lucide-react:
72 + specifier: ^1.42.0
73 + version: 1.42.0(react@19.2.8)
74 + motion:
75 + specifier: ^12.23.0
76 + version: 12.43.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
77 + next:
78 + specifier: 16.3.4
79 + version: 16.3.4(@babel/core@7.29.7)(@playwright/test@1.63.0)(@types/node@24.13.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
80 + next-themes:
81 + specifier: ^0.4.6
82 + version: 0.4.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
83 + openai:
84 + specifier: ^7.10.0
85 + version: 7.10.0(ws@8.21.3)(zod@4.5.4)
86 + pg:
87 + specifier: ^8.23.0
88 + version: 8.23.0
89 + react:
90 + specifier: 19.2.8
91 + version: 19.2.8
92 + react-dom:
93 + specifier: 19.2.8
94 + version: 19.2.8(react@19.2.8)
95 + react-markdown:
96 + specifier: ^10.1.0
97 + version: 10.1.0(@types/react@19.2.18)(react@19.2.8)
98 + recharts:
99 + specifier: ^3.0.0
100 + version: 3.10.1(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react-is@16.13.1)(react@19.2.8)(redux@5.0.1)
101 + rehype-raw:
102 + specifier: ^7.0.0
103 + version: 7.0.0
104 + remark-gfm:
105 + specifier: ^4.0.1
106 + version: 4.0.1
107 + resend:
108 + specifier: ^6.26.0
109 + version: 6.26.0
110 + server-only:
111 + specifier: ^0.0.1
112 + version: 0.0.1
113 + shiki:
114 + specifier: ^4.4.3
115 + version: 4.4.3
116 + swr:
117 + specifier: ^2.5.1
118 + version: 2.5.1(react@19.2.8)
119 + tailwind-merge:
120 + specifier: ^3.3.1
121 + version: 3.6.0
122 + zod:
123 + specifier: ^4.5.4
124 + version: 4.5.4
125 + devDependencies:
126 + '@playwright/test':
127 + specifier: ^1.63.0
128 + version: 1.63.0
129 + '@tailwindcss/postcss':
130 + specifier: ^4.3.3
131 + version: 4.3.3
132 + '@types/node':
133 + specifier: ^24.0.0
134 + version: 24.13.3
135 + '@types/pg':
136 + specifier: ^8.15.0
137 + version: 8.23.1
138 + '@types/react':
139 + specifier: ^19
140 + version: 19.2.18
141 + '@types/react-dom':
142 + specifier: ^19
143 + version: 19.2.7(@types/react@19.2.18)
144 + drizzle-kit:
145 + specifier: ^0.31.10
146 + version: 0.31.10
147 + eslint:
148 + specifier: ^9
149 + version: 9.39.5(jiti@2.7.0)
150 + eslint-config-next:
151 + specifier: 16.3.4
152 + version: 16.3.4(@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
153 + tailwindcss:
154 + specifier: ^4.3.3
155 + version: 4.3.3
156 + tsx:
157 + specifier: ^4.20.0
158 + version: 4.23.13
159 + typescript:
160 + specifier: ^5.9.3
161 + version: 5.9.3
162 + vitest:
163 + specifier: ^3.2.0
164 + version: 3.2.7(@types/debug@4.1.13)(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)
165 +
166 +packages:
167 +
168 + '@alloc/quick-lru@5.3.0':
169 + resolution: {integrity: sha512-U4+70Pc5ZS9osnCBCE5Jha/ciHM+Yp+CNMNC/7HvYbNRk1Ldd+f7qO65W5qfhu/TCv+/ozljlXXe9Nj8419DMA==}
170 + engines: {node: '>=10'}
171 +
172 + '@anthropic-ai/sdk@0.124.0':
173 + resolution: {integrity: sha512-cN5O8i9UVxHeOQAzj/XjshWXG8KiibJDw9OGpH2Z/eR3n/RBxdoLxDJOcfqAJWvjaMDFfHTBADU04hWRJVkDyA==}
174 + hasBin: true
175 + peerDependencies:
176 + zod: ^3.25.0 || ^4.0.0
177 + peerDependenciesMeta:
178 + zod:
179 + optional: true
180 +
181 + '@babel/code-frame@7.29.7':
182 + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==}
183 + engines: {node: '>=6.9.0'}
184 +
185 + '@babel/compat-data@7.29.7':
186 + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==}
187 + engines: {node: '>=6.9.0'}
188 +
189 + '@babel/core@7.29.7':
190 + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==}
191 + engines: {node: '>=6.9.0'}
192 +
193 + '@babel/generator@7.29.8':
194 + resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==}
195 + engines: {node: '>=6.9.0'}
196 +
197 + '@babel/helper-compilation-targets@7.29.7':
198 + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==}
199 + engines: {node: '>=6.9.0'}
200 +
201 + '@babel/helper-globals@7.29.7':
202 + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==}
203 + engines: {node: '>=6.9.0'}
204 +
205 + '@babel/helper-module-imports@7.29.7':
206 + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==}
207 + engines: {node: '>=6.9.0'}
208 +
209 + '@babel/helper-module-transforms@7.29.7':
210 + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==}
211 + engines: {node: '>=6.9.0'}
212 + peerDependencies:
213 + '@babel/core': ^7.0.0
214 +
215 + '@babel/helper-string-parser@7.29.7':
216 + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
217 + engines: {node: '>=6.9.0'}
218 +
219 + '@babel/helper-validator-identifier@7.29.7':
220 + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
221 + engines: {node: '>=6.9.0'}
222 +
223 + '@babel/helper-validator-option@7.29.7':
224 + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==}
225 + engines: {node: '>=6.9.0'}
226 +
227 + '@babel/helpers@7.29.7':
228 + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==}
229 + engines: {node: '>=6.9.0'}
230 +
231 + '@babel/parser@7.29.8':
232 + resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==}
233 + engines: {node: '>=6.0.0'}
234 + hasBin: true
235 +
236 + '@babel/runtime@7.29.7':
237 + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
238 + engines: {node: '>=6.9.0'}
239 +
240 + '@babel/template@7.29.7':
241 + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
242 + engines: {node: '>=6.9.0'}
243 +
244 + '@babel/traverse@7.29.8':
245 + resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==}
246 + engines: {node: '>=6.9.0'}
247 +
248 + '@babel/types@7.29.8':
249 + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==}
250 + engines: {node: '>=6.9.0'}
251 +
252 + '@better-auth/core@1.7.3':
253 + resolution: {integrity: sha512-JdP7lOkyE83jgjn7RilJj1XvZ7n2JjRsErKJuaXchjyuNo6cf1iVd3GtbhAtiUyJJkWdk8yL+LaUBKT80H0zLA==}
254 + peerDependencies:
255 + '@better-auth/utils': 0.4.2
256 + '@better-fetch/fetch': 1.3.1
257 + '@cloudflare/workers-types': '>=4'
258 + '@opentelemetry/api': ^1.9.0
259 + better-call: 1.4.0
260 + jose: ^6.1.0
261 + kysely: ^0.28.5 || ^0.29.0
262 + nanostores: ^1.0.1
263 + peerDependenciesMeta:
264 + '@cloudflare/workers-types':
265 + optional: true
266 + '@opentelemetry/api':
267 + optional: true
268 +
269 + '@better-auth/drizzle-adapter@1.7.3':
270 + resolution: {integrity: sha512-S+nQRlxbUhkR43LrSv8c98ZvOvmv3nrtOnHkiZXkdDkr60PWp7maC2cqgzZ2C9exCC1a+4TugJlx2jRL+r+/9A==}
271 + peerDependencies:
272 + '@better-auth/core': ^1.7.3
273 + '@better-auth/utils': 0.4.2
274 + drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0
275 + peerDependenciesMeta:
276 + drizzle-orm:
277 + optional: true
278 +
279 + '@better-auth/kysely-adapter@1.7.3':
280 + resolution: {integrity: sha512-UIsyJMIrjUnT+yTaS6dkCxYYmtPwxFHxwSJ8+CLty2II5w9BewlDxDA0/QzhoL/InYCPxQ5Y6xIgLHZG1dhwRA==}
281 + peerDependencies:
282 + '@better-auth/core': ^1.7.3
283 + '@better-auth/utils': 0.4.2
284 + kysely: ^0.28.17 || ^0.29.0
285 + peerDependenciesMeta:
286 + kysely:
287 + optional: true
288 +
289 + '@better-auth/memory-adapter@1.7.3':
290 + resolution: {integrity: sha512-WdLANFY/QWC3G351RCzxU+Y9YlW+BQ1oG9NwBTSOUWQw5rZ87ws+weU8tvAMO7sQ4C9gKIlkOKBKUKXrSt91Tw==}
291 + peerDependencies:
292 + '@better-auth/core': ^1.7.3
293 + '@better-auth/utils': 0.4.2
294 +
295 + '@better-auth/mongo-adapter@1.7.3':
296 + resolution: {integrity: sha512-YL9m01tNogmFmRvOWJ46M9WwE6HirCXHDell29mtsQB/Qs1TPNLrgj7ybGMMGhQuyj6S218+8Wbls8m9s+i8RQ==}
297 + peerDependencies:
298 + '@better-auth/core': ^1.7.3
299 + '@better-auth/utils': 0.4.2
300 + mongodb: ^6.0.0 || ^7.0.0
301 + peerDependenciesMeta:
302 + mongodb:
303 + optional: true
304 +
305 + '@better-auth/prisma-adapter@1.7.3':
306 + resolution: {integrity: sha512-TJ/DhlU7oLzrC626/1wfYA1Pl+lVsXa/zXBZ8d7Rlc2YO5fGd5fsAYJdRrYMyA51iZEo+rWLXMhZ0cez1BamsQ==}
307 + peerDependencies:
308 + '@better-auth/core': ^1.7.3
309 + '@better-auth/utils': 0.4.2
310 + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
311 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0
312 + peerDependenciesMeta:
313 + '@prisma/client':
314 + optional: true
315 + prisma:
316 + optional: true
317 +
318 + '@better-auth/telemetry@1.7.3':
319 + resolution: {integrity: sha512-aixgHbJhGvS8PRczX/LR3murYyBnIvOGmJw37ZZBMg6ZtLR/UBJAkufbDi1HYn5THSuTJ3D5DtY85Ahh/ABQtw==}
320 + peerDependencies:
321 + '@better-auth/core': ^1.7.3
322 + '@better-auth/utils': 0.4.2
323 + '@better-fetch/fetch': 1.3.1
324 +
325 + '@better-auth/utils@0.4.2':
326 + resolution: {integrity: sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A==}
327 +
328 + '@better-auth/utils@0.5.0':
329 + resolution: {integrity: sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA==}
330 +
331 + '@better-fetch/fetch@1.3.1':
332 + resolution: {integrity: sha512-ABkD1WhyfPZprKRQI3bhATjeiFuNWC9PXhfGWqL+sg/gKrM977oFrYkdb4msM3hgUGonr7KlOsOFT5TU2rht9g==}
333 +
334 + '@drizzle-team/brocli@0.10.2':
335 + resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==}
336 +
337 + '@emnapi/core@1.10.0':
338 + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
339 +
340 + '@emnapi/runtime@1.10.0':
341 + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
342 +
343 + '@emnapi/runtime@1.11.3':
344 + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==}
345 +
346 + '@emnapi/wasi-threads@1.2.1':
347 + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
348 +
349 + '@epic-web/invariant@1.0.0':
350 + resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==}
351 +
352 + '@esbuild-kit/core-utils@3.3.2':
353 + resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==}
354 + deprecated: 'Merged into tsx: https://tsx.hirok.io'
355 +
356 + '@esbuild-kit/esm-loader@2.6.5':
357 + resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==}
358 + deprecated: 'Merged into tsx: https://tsx.hirok.io'
359 +
360 + '@esbuild/aix-ppc64@0.25.12':
361 + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
362 + engines: {node: '>=18'}
363 + cpu: [ppc64]
364 + os: [aix]
365 +
366 + '@esbuild/aix-ppc64@0.28.2':
367 + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==}
368 + engines: {node: '>=18'}
369 + cpu: [ppc64]
370 + os: [aix]
371 +
372 + '@esbuild/android-arm64@0.18.20':
373 + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
374 + engines: {node: '>=12'}
375 + cpu: [arm64]
376 + os: [android]
377 +
378 + '@esbuild/android-arm64@0.25.12':
379 + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
380 + engines: {node: '>=18'}
381 + cpu: [arm64]
382 + os: [android]
383 +
384 + '@esbuild/android-arm64@0.28.2':
385 + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==}
386 + engines: {node: '>=18'}
387 + cpu: [arm64]
388 + os: [android]
389 +
390 + '@esbuild/android-arm@0.18.20':
391 + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
392 + engines: {node: '>=12'}
393 + cpu: [arm]
394 + os: [android]
395 +
396 + '@esbuild/android-arm@0.25.12':
397 + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
398 + engines: {node: '>=18'}
399 + cpu: [arm]
400 + os: [android]
401 +
402 + '@esbuild/android-arm@0.28.2':
403 + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==}
404 + engines: {node: '>=18'}
405 + cpu: [arm]
406 + os: [android]
407 +
408 + '@esbuild/android-x64@0.18.20':
409 + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
410 + engines: {node: '>=12'}
411 + cpu: [x64]
412 + os: [android]
413 +
414 + '@esbuild/android-x64@0.25.12':
415 + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
416 + engines: {node: '>=18'}
417 + cpu: [x64]
418 + os: [android]
419 +
420 + '@esbuild/android-x64@0.28.2':
421 + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==}
422 + engines: {node: '>=18'}
423 + cpu: [x64]
424 + os: [android]
425 +
426 + '@esbuild/darwin-arm64@0.18.20':
427 + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
428 + engines: {node: '>=12'}
429 + cpu: [arm64]
430 + os: [darwin]
431 +
432 + '@esbuild/darwin-arm64@0.25.12':
433 + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
434 + engines: {node: '>=18'}
435 + cpu: [arm64]
436 + os: [darwin]
437 +
438 + '@esbuild/darwin-arm64@0.28.2':
439 + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==}
440 + engines: {node: '>=18'}
441 + cpu: [arm64]
442 + os: [darwin]
443 +
444 + '@esbuild/darwin-x64@0.18.20':
445 + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
446 + engines: {node: '>=12'}
447 + cpu: [x64]
448 + os: [darwin]
449 +
450 + '@esbuild/darwin-x64@0.25.12':
451 + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
452 + engines: {node: '>=18'}
453 + cpu: [x64]
454 + os: [darwin]
455 +
456 + '@esbuild/darwin-x64@0.28.2':
457 + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==}
458 + engines: {node: '>=18'}
459 + cpu: [x64]
460 + os: [darwin]
461 +
462 + '@esbuild/freebsd-arm64@0.18.20':
463 + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
464 + engines: {node: '>=12'}
465 + cpu: [arm64]
466 + os: [freebsd]
467 +
468 + '@esbuild/freebsd-arm64@0.25.12':
469 + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
470 + engines: {node: '>=18'}
471 + cpu: [arm64]
472 + os: [freebsd]
473 +
474 + '@esbuild/freebsd-arm64@0.28.2':
475 + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==}
476 + engines: {node: '>=18'}
477 + cpu: [arm64]
478 + os: [freebsd]
479 +
480 + '@esbuild/freebsd-x64@0.18.20':
481 + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
482 + engines: {node: '>=12'}
483 + cpu: [x64]
484 + os: [freebsd]
485 +
486 + '@esbuild/freebsd-x64@0.25.12':
487 + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
488 + engines: {node: '>=18'}
489 + cpu: [x64]
490 + os: [freebsd]
491 +
492 + '@esbuild/freebsd-x64@0.28.2':
493 + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==}
494 + engines: {node: '>=18'}
495 + cpu: [x64]
496 + os: [freebsd]
497 +
498 + '@esbuild/linux-arm64@0.18.20':
499 + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
500 + engines: {node: '>=12'}
501 + cpu: [arm64]
502 + os: [linux]
503 +
504 + '@esbuild/linux-arm64@0.25.12':
505 + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
506 + engines: {node: '>=18'}
507 + cpu: [arm64]
508 + os: [linux]
509 +
510 + '@esbuild/linux-arm64@0.28.2':
511 + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==}
512 + engines: {node: '>=18'}
513 + cpu: [arm64]
514 + os: [linux]
515 +
516 + '@esbuild/linux-arm@0.18.20':
517 + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
518 + engines: {node: '>=12'}
519 + cpu: [arm]
520 + os: [linux]
521 +
522 + '@esbuild/linux-arm@0.25.12':
523 + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
524 + engines: {node: '>=18'}
525 + cpu: [arm]
526 + os: [linux]
527 +
528 + '@esbuild/linux-arm@0.28.2':
529 + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==}
530 + engines: {node: '>=18'}
531 + cpu: [arm]
532 + os: [linux]
533 +
534 + '@esbuild/linux-ia32@0.18.20':
535 + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
536 + engines: {node: '>=12'}
537 + cpu: [ia32]
538 + os: [linux]
539 +
540 + '@esbuild/linux-ia32@0.25.12':
541 + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
542 + engines: {node: '>=18'}
543 + cpu: [ia32]
544 + os: [linux]
545 +
546 + '@esbuild/linux-ia32@0.28.2':
547 + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==}
548 + engines: {node: '>=18'}
549 + cpu: [ia32]
550 + os: [linux]
551 +
552 + '@esbuild/linux-loong64@0.18.20':
553 + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
554 + engines: {node: '>=12'}
555 + cpu: [loong64]
556 + os: [linux]
557 +
558 + '@esbuild/linux-loong64@0.25.12':
559 + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
560 + engines: {node: '>=18'}
561 + cpu: [loong64]
562 + os: [linux]
563 +
564 + '@esbuild/linux-loong64@0.28.2':
565 + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==}
566 + engines: {node: '>=18'}
567 + cpu: [loong64]
568 + os: [linux]
569 +
570 + '@esbuild/linux-mips64el@0.18.20':
571 + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
572 + engines: {node: '>=12'}
573 + cpu: [mips64el]
574 + os: [linux]
575 +
576 + '@esbuild/linux-mips64el@0.25.12':
577 + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
578 + engines: {node: '>=18'}
579 + cpu: [mips64el]
580 + os: [linux]
581 +
582 + '@esbuild/linux-mips64el@0.28.2':
583 + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==}
584 + engines: {node: '>=18'}
585 + cpu: [mips64el]
586 + os: [linux]
587 +
588 + '@esbuild/linux-ppc64@0.18.20':
589 + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
590 + engines: {node: '>=12'}
591 + cpu: [ppc64]
592 + os: [linux]
593 +
594 + '@esbuild/linux-ppc64@0.25.12':
595 + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
596 + engines: {node: '>=18'}
597 + cpu: [ppc64]
598 + os: [linux]
599 +
600 + '@esbuild/linux-ppc64@0.28.2':
601 + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==}
602 + engines: {node: '>=18'}
603 + cpu: [ppc64]
604 + os: [linux]
605 +
606 + '@esbuild/linux-riscv64@0.18.20':
607 + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
608 + engines: {node: '>=12'}
609 + cpu: [riscv64]
610 + os: [linux]
611 +
612 + '@esbuild/linux-riscv64@0.25.12':
613 + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
614 + engines: {node: '>=18'}
615 + cpu: [riscv64]
616 + os: [linux]
617 +
618 + '@esbuild/linux-riscv64@0.28.2':
619 + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==}
620 + engines: {node: '>=18'}
621 + cpu: [riscv64]
622 + os: [linux]
623 +
624 + '@esbuild/linux-s390x@0.18.20':
625 + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
626 + engines: {node: '>=12'}
627 + cpu: [s390x]
628 + os: [linux]
629 +
630 + '@esbuild/linux-s390x@0.25.12':
631 + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
632 + engines: {node: '>=18'}
633 + cpu: [s390x]
634 + os: [linux]
635 +
636 + '@esbuild/linux-s390x@0.28.2':
637 + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==}
638 + engines: {node: '>=18'}
639 + cpu: [s390x]
640 + os: [linux]
641 +
642 + '@esbuild/linux-x64@0.18.20':
643 + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
644 + engines: {node: '>=12'}
645 + cpu: [x64]
646 + os: [linux]
647 +
648 + '@esbuild/linux-x64@0.25.12':
649 + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
650 + engines: {node: '>=18'}
651 + cpu: [x64]
652 + os: [linux]
653 +
654 + '@esbuild/linux-x64@0.28.2':
655 + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==}
656 + engines: {node: '>=18'}
657 + cpu: [x64]
658 + os: [linux]
659 +
660 + '@esbuild/netbsd-arm64@0.25.12':
661 + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
662 + engines: {node: '>=18'}
663 + cpu: [arm64]
664 + os: [netbsd]
665 +
666 + '@esbuild/netbsd-arm64@0.28.2':
667 + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==}
668 + engines: {node: '>=18'}
669 + cpu: [arm64]
670 + os: [netbsd]
671 +
672 + '@esbuild/netbsd-x64@0.18.20':
673 + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
674 + engines: {node: '>=12'}
675 + cpu: [x64]
676 + os: [netbsd]
677 +
678 + '@esbuild/netbsd-x64@0.25.12':
679 + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
680 + engines: {node: '>=18'}
681 + cpu: [x64]
682 + os: [netbsd]
683 +
684 + '@esbuild/netbsd-x64@0.28.2':
685 + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==}
686 + engines: {node: '>=18'}
687 + cpu: [x64]
688 + os: [netbsd]
689 +
690 + '@esbuild/openbsd-arm64@0.25.12':
691 + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
692 + engines: {node: '>=18'}
693 + cpu: [arm64]
694 + os: [openbsd]
695 +
696 + '@esbuild/openbsd-arm64@0.28.2':
697 + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==}
698 + engines: {node: '>=18'}
699 + cpu: [arm64]
700 + os: [openbsd]
701 +
702 + '@esbuild/openbsd-x64@0.18.20':
703 + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
704 + engines: {node: '>=12'}
705 + cpu: [x64]
706 + os: [openbsd]
707 +
708 + '@esbuild/openbsd-x64@0.25.12':
709 + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
710 + engines: {node: '>=18'}
711 + cpu: [x64]
712 + os: [openbsd]
713 +
714 + '@esbuild/openbsd-x64@0.28.2':
715 + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==}
716 + engines: {node: '>=18'}
717 + cpu: [x64]
718 + os: [openbsd]
719 +
720 + '@esbuild/openharmony-arm64@0.25.12':
721 + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
722 + engines: {node: '>=18'}
723 + cpu: [arm64]
724 + os: [openharmony]
725 +
726 + '@esbuild/openharmony-arm64@0.28.2':
727 + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==}
728 + engines: {node: '>=18'}
729 + cpu: [arm64]
730 + os: [openharmony]
731 +
732 + '@esbuild/sunos-x64@0.18.20':
733 + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
734 + engines: {node: '>=12'}
735 + cpu: [x64]
736 + os: [sunos]
737 +
738 + '@esbuild/sunos-x64@0.25.12':
739 + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
740 + engines: {node: '>=18'}
741 + cpu: [x64]
742 + os: [sunos]
743 +
744 + '@esbuild/sunos-x64@0.28.2':
745 + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==}
746 + engines: {node: '>=18'}
747 + cpu: [x64]
748 + os: [sunos]
749 +
750 + '@esbuild/win32-arm64@0.18.20':
751 + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
752 + engines: {node: '>=12'}
753 + cpu: [arm64]
754 + os: [win32]
755 +
756 + '@esbuild/win32-arm64@0.25.12':
757 + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
758 + engines: {node: '>=18'}
759 + cpu: [arm64]
760 + os: [win32]
761 +
762 + '@esbuild/win32-arm64@0.28.2':
763 + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==}
764 + engines: {node: '>=18'}
765 + cpu: [arm64]
766 + os: [win32]
767 +
768 + '@esbuild/win32-ia32@0.18.20':
769 + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
770 + engines: {node: '>=12'}
771 + cpu: [ia32]
772 + os: [win32]
773 +
774 + '@esbuild/win32-ia32@0.25.12':
775 + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
776 + engines: {node: '>=18'}
777 + cpu: [ia32]
778 + os: [win32]
779 +
780 + '@esbuild/win32-ia32@0.28.2':
781 + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==}
782 + engines: {node: '>=18'}
783 + cpu: [ia32]
784 + os: [win32]
785 +
786 + '@esbuild/win32-x64@0.18.20':
787 + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
788 + engines: {node: '>=12'}
789 + cpu: [x64]
790 + os: [win32]
791 +
792 + '@esbuild/win32-x64@0.25.12':
793 + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
794 + engines: {node: '>=18'}
795 + cpu: [x64]
796 + os: [win32]
797 +
798 + '@esbuild/win32-x64@0.28.2':
799 + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==}
800 + engines: {node: '>=18'}
801 + cpu: [x64]
802 + os: [win32]
803 +
804 + '@eslint-community/eslint-utils@4.10.1':
805 + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==}
806 + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
807 + peerDependencies:
808 + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
809 +
810 + '@eslint-community/eslint-utils@4.9.1':
811 + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
812 + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
813 + peerDependencies:
814 + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
815 +
816 + '@eslint-community/regexpp@4.12.2':
817 + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
818 + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
819 +
820 + '@eslint/config-array@0.21.2':
821 + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==}
822 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
823 +
824 + '@eslint/config-helpers@0.4.2':
825 + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==}
826 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
827 +
828 + '@eslint/core@0.17.0':
829 + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
830 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
831 +
832 + '@eslint/eslintrc@3.3.7':
833 + resolution: {integrity: sha512-F42g89Qd5oAWtp0k0nnSrjziAKza7w8SVT4mStc18LZMaRb4J1HQAHLCalEtDCxrTuksx7NU9qsmeLwpOfPqWw==}
834 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
835 +
836 + '@eslint/js@9.39.5':
837 + resolution: {integrity: sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==}
838 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
839 +
840 + '@eslint/object-schema@2.1.7':
841 + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
842 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
843 +
844 + '@eslint/plugin-kit@0.4.1':
845 + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
846 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
847 +
848 + '@floating-ui/core@1.8.0':
849 + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==}
850 +
851 + '@floating-ui/dom@1.8.0':
852 + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==}
853 +
854 + '@floating-ui/react-dom@2.1.9':
855 + resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==}
856 + peerDependencies:
857 + react: '>=16.8.0'
858 + react-dom: '>=16.8.0'
859 +
860 + '@floating-ui/utils@0.2.12':
861 + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==}
862 +
863 + '@google/genai@2.21.0':
864 + resolution: {integrity: sha512-+PDtco2/Z0ONdzCGekCoCT+O1VJS9xJQNN4XzQpXG/t3El/SWWMkCWlFRO1KmivOHPa4Q0VjUYu1HBKCZ/v33Q==}
865 + engines: {node: '>=20.0.0'}
866 + peerDependencies:
867 + '@modelcontextprotocol/sdk': ^1.25.2
868 + peerDependenciesMeta:
869 + '@modelcontextprotocol/sdk':
870 + optional: true
871 +
872 + '@humanfs/core@0.19.2':
873 + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==}
874 + engines: {node: '>=18.18.0'}
875 +
876 + '@humanfs/node@0.16.8':
877 + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==}
878 + engines: {node: '>=18.18.0'}
879 +
880 + '@humanfs/types@0.15.0':
881 + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==}
882 + engines: {node: '>=18.18.0'}
883 +
884 + '@humanwhocodes/module-importer@1.0.1':
885 + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
886 + engines: {node: '>=12.22'}
887 +
888 + '@humanwhocodes/retry@0.4.3':
889 + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
890 + engines: {node: '>=18.18'}
891 +
892 + '@img/colour@1.1.0':
893 + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
894 + engines: {node: '>=18'}
895 +
896 + '@img/sharp-darwin-arm64@0.35.4':
897 + resolution: {integrity: sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==}
898 + engines: {node: '>=20.9.0'}
899 + cpu: [arm64]
900 + os: [darwin]
901 +
902 + '@img/sharp-darwin-x64@0.35.4':
903 + resolution: {integrity: sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==}
904 + engines: {node: '>=20.9.0'}
905 + cpu: [x64]
906 + os: [darwin]
907 +
908 + '@img/sharp-freebsd-wasm32@0.35.4':
909 + resolution: {integrity: sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==}
910 + engines: {node: '>=20.9.0'}
911 + os: [freebsd]
912 +
913 + '@img/sharp-libvips-darwin-arm64@1.3.3':
914 + resolution: {integrity: sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==}
915 + cpu: [arm64]
916 + os: [darwin]
917 +
918 + '@img/sharp-libvips-darwin-x64@1.3.3':
919 + resolution: {integrity: sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==}
920 + cpu: [x64]
921 + os: [darwin]
922 +
923 + '@img/sharp-libvips-linux-arm64@1.3.3':
924 + resolution: {integrity: sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==}
925 + cpu: [arm64]
926 + os: [linux]
927 + libc: [glibc]
928 +
929 + '@img/sharp-libvips-linux-arm@1.3.3':
930 + resolution: {integrity: sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==}
931 + cpu: [arm]
932 + os: [linux]
933 + libc: [glibc]
934 +
935 + '@img/sharp-libvips-linux-ppc64@1.3.3':
936 + resolution: {integrity: sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==}
937 + cpu: [ppc64]
938 + os: [linux]
939 + libc: [glibc]
940 +
941 + '@img/sharp-libvips-linux-riscv64@1.3.3':
942 + resolution: {integrity: sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==}
943 + cpu: [riscv64]
944 + os: [linux]
945 + libc: [glibc]
946 +
947 + '@img/sharp-libvips-linux-s390x@1.3.3':
948 + resolution: {integrity: sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==}
949 + cpu: [s390x]
950 + os: [linux]
951 + libc: [glibc]
952 +
953 + '@img/sharp-libvips-linux-x64@1.3.3':
954 + resolution: {integrity: sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==}
955 + cpu: [x64]
956 + os: [linux]
957 + libc: [glibc]
958 +
959 + '@img/sharp-libvips-linuxmusl-arm64@1.3.3':
960 + resolution: {integrity: sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==}
961 + cpu: [arm64]
962 + os: [linux]
963 + libc: [musl]
964 +
965 + '@img/sharp-libvips-linuxmusl-x64@1.3.3':
966 + resolution: {integrity: sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==}
967 + cpu: [x64]
968 + os: [linux]
969 + libc: [musl]
970 +
971 + '@img/sharp-linux-arm64@0.35.4':
972 + resolution: {integrity: sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==}
973 + engines: {node: '>=20.9.0'}
974 + cpu: [arm64]
975 + os: [linux]
976 + libc: [glibc]
977 +
978 + '@img/sharp-linux-arm@0.35.4':
979 + resolution: {integrity: sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==}
980 + engines: {node: '>=20.9.0'}
981 + cpu: [arm]
982 + os: [linux]
983 + libc: [glibc]
984 +
985 + '@img/sharp-linux-ppc64@0.35.4':
986 + resolution: {integrity: sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==}
987 + engines: {node: '>=20.9.0'}
988 + cpu: [ppc64]
989 + os: [linux]
990 + libc: [glibc]
991 +
992 + '@img/sharp-linux-riscv64@0.35.4':
993 + resolution: {integrity: sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==}
994 + engines: {node: '>=20.9.0'}
995 + cpu: [riscv64]
996 + os: [linux]
997 + libc: [glibc]
998 +
999 + '@img/sharp-linux-s390x@0.35.4':
1000 + resolution: {integrity: sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==}
1001 + engines: {node: '>=20.9.0'}
1002 + cpu: [s390x]
1003 + os: [linux]
1004 + libc: [glibc]
1005 +
1006 + '@img/sharp-linux-x64@0.35.4':
1007 + resolution: {integrity: sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==}
1008 + engines: {node: '>=20.9.0'}
1009 + cpu: [x64]
1010 + os: [linux]
1011 + libc: [glibc]
1012 +
1013 + '@img/sharp-linuxmusl-arm64@0.35.4':
1014 + resolution: {integrity: sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==}
1015 + engines: {node: '>=20.9.0'}
1016 + cpu: [arm64]
1017 + os: [linux]
1018 + libc: [musl]
1019 +
1020 + '@img/sharp-linuxmusl-x64@0.35.4':
1021 + resolution: {integrity: sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==}
1022 + engines: {node: '>=20.9.0'}
1023 + cpu: [x64]
1024 + os: [linux]
1025 + libc: [musl]
1026 +
1027 + '@img/sharp-wasm32@0.35.4':
1028 + resolution: {integrity: sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==}
1029 + engines: {node: '>=20.9.0'}
1030 +
1031 + '@img/sharp-webcontainers-wasm32@0.35.4':
1032 + resolution: {integrity: sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==}
1033 + engines: {node: '>=20.9.0'}
1034 + cpu: [wasm32]
1035 +
1036 + '@img/sharp-win32-arm64@0.35.4':
1037 + resolution: {integrity: sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==}
1038 + engines: {node: '>=20.9.0'}
1039 + cpu: [arm64]
1040 + os: [win32]
1041 +
1042 + '@img/sharp-win32-ia32@0.35.4':
1043 + resolution: {integrity: sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==}
1044 + engines: {node: ^20.9.0}
1045 + cpu: [ia32]
1046 + os: [win32]
1047 +
1048 + '@img/sharp-win32-x64@0.35.4':
1049 + resolution: {integrity: sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==}
1050 + engines: {node: '>=20.9.0'}
1051 + cpu: [x64]
1052 + os: [win32]
1053 +
1054 + '@jridgewell/gen-mapping@0.3.13':
1055 + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
1056 +
1057 + '@jridgewell/remapping@2.3.5':
1058 + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
1059 +
1060 + '@jridgewell/resolve-uri@3.1.2':
1061 + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
1062 + engines: {node: '>=6.0.0'}
1063 +
1064 + '@jridgewell/sourcemap-codec@1.6.0':
1065 + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==}
1066 +
1067 + '@jridgewell/trace-mapping@0.3.31':
1068 + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
1069 +
1070 + '@napi-rs/lzma-linux-x64-gnu@1.5.1':
1071 + resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==}
1072 + engines: {node: ^22.20 || ^24.12 || >=25}
1073 + cpu: [x64]
1074 + os: [linux]
1075 + libc: [glibc]
1076 +
1077 + '@napi-rs/wasm-runtime@1.2.3':
1078 + resolution: {integrity: sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==}
1079 + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
1080 + peerDependencies:
1081 + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4
1082 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4
1083 +
1084 + '@next/env@16.3.4':
1085 + resolution: {integrity: sha512-cjWZnUUa6jZq2kFaNe/ZyJdZonOZ/QoN0Zka2nz/FLOrfx14pQuM9c5RaSVkWMqgdt4ksgPAMWPyHSs/CyV48Q==}
1086 +
1087 + '@next/eslint-plugin-next@16.3.4':
1088 + resolution: {integrity: sha512-szW9y2Aumu4z88YXfTzcFsgUAg2k64uzbtcO5L9f1AKS4w/GUKJcbFllRflROVyNPgJtGOnvNxiyp3v6b+prIA==}
1089 +
1090 + '@next/swc-darwin-arm64@16.3.4':
1091 + resolution: {integrity: sha512-iBr3I5LZNk5/bgl5//iTgD2tcym14MX0Xo7fD//u9dYAEgGzza1y9oywluPtf74YnOswVdH1908aK9xVz7zQTw==}
1092 + engines: {node: '>= 10'}
1093 + cpu: [arm64]
1094 + os: [darwin]
1095 +
1096 + '@next/swc-darwin-x64@16.3.4':
1097 + resolution: {integrity: sha512-2dpiSyl2Jw/NrBPaU2MAKGSa+2MR82pJIn4Sm5Rjr+gxAeuh0z158Su3Z2O8zn7UNNq+ej4bToed6RcRN/Lydg==}
1098 + engines: {node: '>= 10'}
1099 + cpu: [x64]
1100 + os: [darwin]
1101 +
1102 + '@next/swc-linux-arm64-gnu@16.3.4':
1103 + resolution: {integrity: sha512-+t+U8HZT+fApePCS5h89CSH3datz29MkzyfCn+6fpsZBG/oiEOhINcb9rtkv6sdpToLGFn2e6146NzaKCXkqrA==}
1104 + engines: {node: '>= 10'}
1105 + cpu: [arm64]
1106 + os: [linux]
1107 + libc: [glibc]
1108 +
1109 + '@next/swc-linux-arm64-musl@16.3.4':
1110 + resolution: {integrity: sha512-mx03GNs1ocQA5JQ4FxDMmIsNkdrZh8cuezKCrId28e5/gIPU/l7Kcy2+vmCCzdjnnmXJy+iOAu+7K0QppO6Urg==}
1111 + engines: {node: '>= 10'}
1112 + cpu: [arm64]
1113 + os: [linux]
1114 + libc: [musl]
1115 +
1116 + '@next/swc-linux-x64-gnu@16.3.4':
1117 + resolution: {integrity: sha512-YIhGY6fSMfha52bnVxnzc9zaVBzJg+cqQTOD8tXIBSx4fuv0pVMxQTE0PaS59YhnMOiYiG09IMwxJAf/CFm/Dw==}
1118 + engines: {node: '>= 10'}
1119 + cpu: [x64]
1120 + os: [linux]
1121 + libc: [glibc]
1122 +
1123 + '@next/swc-linux-x64-musl@16.3.4':
1124 + resolution: {integrity: sha512-+eaaX6axpDb0yF1GCpiERe6njplvdC+nks/fKfcHu3XPGRrald8P3/X7yv7QLdjA51knnxwl9pxdIJsg+w1L+Q==}
1125 + engines: {node: '>= 10'}
1126 + cpu: [x64]
1127 + os: [linux]
1128 + libc: [musl]
1129 +
1130 + '@next/swc-win32-arm64-msvc@16.3.4':
1131 + resolution: {integrity: sha512-0jcXW7Xs/uzICrmgV3MhDYDeRy++1CqnpDIerlPIqYO4bhzB4WNbX/aRnQclustsAyTkFKB0z6rbcjmNg5tR8A==}
1132 + engines: {node: '>= 10'}
1133 + cpu: [arm64]
1134 + os: [win32]
1135 +
1136 + '@next/swc-win32-x64-msvc@16.3.4':
1137 + resolution: {integrity: sha512-vvBzwu1pYQCp92maZCFCIw/XgOTMR5tur9GjakwIo2cmwRTMKajRZZDS9+e4KsUZWKu1E007WUeAFXRRjZeuzw==}
1138 + engines: {node: '>= 10'}
1139 + cpu: [x64]
1140 + os: [win32]
1141 +
1142 + '@noble/ciphers@2.4.0':
1143 + resolution: {integrity: sha512-AnjFn0Jv92laAkvMrghlFZq4qQCIN/4DxFV/eooqtC2YTjB7kBeLMS2T9KJX4Dn+ZVXLOwK0lSgqDtx9gvxtiw==}
1144 + engines: {node: '>= 20.19.0'}
1145 +
1146 + '@noble/hashes@2.4.0':
1147 + resolution: {integrity: sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==}
1148 + engines: {node: '>= 20.19.0'}
1149 +
1150 + '@nodelib/fs.scandir@2.1.5':
1151 + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
1152 + engines: {node: '>= 8'}
1153 +
1154 + '@nodelib/fs.stat@2.0.5':
1155 + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
1156 + engines: {node: '>= 8'}
1157 +
1158 + '@nodelib/fs.walk@1.2.8':
1159 + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
1160 + engines: {node: '>= 8'}
1161 +
1162 + '@nolyfill/is-core-module@1.0.39':
1163 + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
1164 + engines: {node: '>=12.4.0'}
1165 +
1166 + '@opentelemetry/semantic-conventions@1.43.0':
1167 + resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==}
1168 + engines: {node: '>=14'}
1169 +
1170 + '@phc/format@1.0.0':
1171 + resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==}
1172 + engines: {node: '>=10'}
1173 +
1174 + '@playwright/test@1.63.0':
1175 + resolution: {integrity: sha512-oxMK4vllB9RK5NQ2l1pq1IfOf2AvnEuj/vYGDj0H2nMtmtZpKtCwt/l00GEO6xjGfpBNAvjovvYdCm50dRQkpQ==}
1176 + engines: {node: '>=20'}
1177 + hasBin: true
1178 +
1179 + '@protobufjs/aspromise@1.1.2':
1180 + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
1181 +
1182 + '@protobufjs/base64@1.1.2':
1183 + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
1184 +
1185 + '@protobufjs/codegen@2.0.5':
1186 + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==}
1187 +
1188 + '@protobufjs/eventemitter@1.1.1':
1189 + resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==}
1190 +
1191 + '@protobufjs/fetch@1.1.1':
1192 + resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==}
1193 +
1194 + '@protobufjs/float@1.0.2':
1195 + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
1196 +
1197 + '@protobufjs/path@1.1.2':
1198 + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
1199 +
1200 + '@protobufjs/pool@1.1.0':
1201 + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
1202 +
1203 + '@protobufjs/utf8@1.1.2':
1204 + resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==}
1205 +
1206 + '@radix-ui/number@1.1.3':
1207 + resolution: {integrity: sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==}
1208 +
1209 + '@radix-ui/primitive@1.1.7':
1210 + resolution: {integrity: sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q==}
1211 +
1212 + '@radix-ui/react-arrow@1.1.15':
1213 + resolution: {integrity: sha512-v4zggRcjadnI+ClKDuijlQEW4tw3NoaeHc/PwpKnLoLLKNUG4InLegkstooLcRIUWCs+8L22dGURCVuFfOKfnA==}
1214 + peerDependencies:
1215 + '@types/react': '*'
1216 + '@types/react-dom': '*'
1217 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1218 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1219 + peerDependenciesMeta:
1220 + '@types/react':
1221 + optional: true
1222 + '@types/react-dom':
1223 + optional: true
1224 +
1225 + '@radix-ui/react-collection@1.1.15':
1226 + resolution: {integrity: sha512-9W+B9NPF0NaaPh/1NJd3+KqsnlLqU9H7T2rvww+fp+T/evVXdNAyYcnfRQZFOjkR1ajQp3yORlqnI8soawLvNA==}
1227 + peerDependencies:
1228 + '@types/react': '*'
1229 + '@types/react-dom': '*'
1230 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1231 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1232 + peerDependenciesMeta:
1233 + '@types/react':
1234 + optional: true
1235 + '@types/react-dom':
1236 + optional: true
1237 +
1238 + '@radix-ui/react-compose-refs@1.1.5':
1239 + resolution: {integrity: sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==}
1240 + peerDependencies:
1241 + '@types/react': '*'
1242 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1243 + peerDependenciesMeta:
1244 + '@types/react':
1245 + optional: true
1246 +
1247 + '@radix-ui/react-context@1.2.2':
1248 + resolution: {integrity: sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA==}
1249 + peerDependencies:
1250 + '@types/react': '*'
1251 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1252 + peerDependenciesMeta:
1253 + '@types/react':
1254 + optional: true
1255 +
1256 + '@radix-ui/react-dialog@1.1.23':
1257 + resolution: {integrity: sha512-Ksw4WeROkO4rC9k/onilX/Ao2Cr1ku1unMNH+XSCcP4jSXYu7HDsg9n4ojMjVb22XpYjAQ9qfrFlVbru1vXDUA==}
1258 + peerDependencies:
1259 + '@types/react': '*'
1260 + '@types/react-dom': '*'
1261 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1262 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1263 + peerDependenciesMeta:
1264 + '@types/react':
1265 + optional: true
1266 + '@types/react-dom':
1267 + optional: true
1268 +
1269 + '@radix-ui/react-direction@1.1.4':
1270 + resolution: {integrity: sha512-5pzg4FGQNpExhnhT2zlrP1wZFaYCd1K0nYWoFAdcYoYK868IEigqMX3B3f8yIoRlAhAeDWciLI6ZdCKHF9P4Vg==}
1271 + peerDependencies:
1272 + '@types/react': '*'
1273 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1274 + peerDependenciesMeta:
1275 + '@types/react':
1276 + optional: true
1277 +
1278 + '@radix-ui/react-dismissable-layer@1.1.19':
1279 + resolution: {integrity: sha512-8g4pfOL9HoKKLWGiypT+dphVqjFfmcXO5GBnhsG6zI+lxAx/8feQpr+1LSN8Re3hiZ+XkLNS4O9ztK11/LzQ6w==}
1280 + peerDependencies:
1281 + '@types/react': '*'
1282 + '@types/react-dom': '*'
1283 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1284 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1285 + peerDependenciesMeta:
1286 + '@types/react':
1287 + optional: true
1288 + '@types/react-dom':
1289 + optional: true
1290 +
1291 + '@radix-ui/react-dropdown-menu@2.1.24':
1292 + resolution: {integrity: sha512-geq8l2rJkxvkXsT9RMgtUE3P8pITFpTsvYpbySi1IH4fZEABD/Gp85myayFgxk0ktljGMJnCbeFkyTusvSvv7g==}
1293 + peerDependencies:
1294 + '@types/react': '*'
1295 + '@types/react-dom': '*'
1296 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1297 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1298 + peerDependenciesMeta:
1299 + '@types/react':
1300 + optional: true
1301 + '@types/react-dom':
1302 + optional: true
1303 +
1304 + '@radix-ui/react-focus-guards@1.1.6':
1305 + resolution: {integrity: sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ==}
1306 + peerDependencies:
1307 + '@types/react': '*'
1308 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1309 + peerDependenciesMeta:
1310 + '@types/react':
1311 + optional: true
1312 +
1313 + '@radix-ui/react-focus-scope@1.1.16':
1314 + resolution: {integrity: sha512-wmRZ2WWLvmt6KHy2rNPOdPUjwq5xOHY02+m+udwJTn0aNIox/rkskAvJTyTLGhPK6KgrUjlJUJpgmx/+wFiFIQ==}
1315 + peerDependencies:
1316 + '@types/react': '*'
1317 + '@types/react-dom': '*'
1318 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1319 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1320 + peerDependenciesMeta:
1321 + '@types/react':
1322 + optional: true
1323 + '@types/react-dom':
1324 + optional: true
1325 +
1326 + '@radix-ui/react-id@1.1.4':
1327 + resolution: {integrity: sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==}
1328 + peerDependencies:
1329 + '@types/react': '*'
1330 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1331 + peerDependenciesMeta:
1332 + '@types/react':
1333 + optional: true
1334 +
1335 + '@radix-ui/react-menu@2.1.24':
1336 + resolution: {integrity: sha512-uW7RVuU6Lp/ZtfeY4b3kL32zccgEWvPv1+cf17ubYzHa9cL8AHokmk36cG/XEiH/smbQvumnieXX9j/e9RqJWA==}
1337 + peerDependencies:
1338 + '@types/react': '*'
1339 + '@types/react-dom': '*'
1340 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1341 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1342 + peerDependenciesMeta:
1343 + '@types/react':
1344 + optional: true
1345 + '@types/react-dom':
1346 + optional: true
1347 +
1348 + '@radix-ui/react-popover@1.1.23':
1349 + resolution: {integrity: sha512-mw58MrBlyHWFisTOYignD0vf/3gdcgAR+9of1s9G/38CbFiUwH1nCDkc0AUM9IrXFgN5Ue8n45j9WCgyM1sbiQ==}
1350 + peerDependencies:
1351 + '@types/react': '*'
1352 + '@types/react-dom': '*'
1353 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1354 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1355 + peerDependenciesMeta:
1356 + '@types/react':
1357 + optional: true
1358 + '@types/react-dom':
1359 + optional: true
1360 +
1361 + '@radix-ui/react-popper@1.3.7':
1362 + resolution: {integrity: sha512-UsJrrd7w4wuKKTdvd/DNERVlwSlUcyXzjhyDwBk+3aPOsCjOY6ZSbxuw8E6lZTjjfP8Cpd0J8VVkrYUWyGYXyg==}
1363 + peerDependencies:
1364 + '@types/react': '*'
1365 + '@types/react-dom': '*'
1366 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1367 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1368 + peerDependenciesMeta:
1369 + '@types/react':
1370 + optional: true
1371 + '@types/react-dom':
1372 + optional: true
1373 +
1374 + '@radix-ui/react-portal@1.1.17':
1375 + resolution: {integrity: sha512-vKQLcWypUnwZVvfV7UkGahH2g6ySe8M8R+zYBwPrv5byZ9QAW6cQVvNKo7GgmD+p8aYb6D9JBuvy8/WhOno2wQ==}
1376 + peerDependencies:
1377 + '@types/react': '*'
1378 + '@types/react-dom': '*'
1379 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1380 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1381 + peerDependenciesMeta:
1382 + '@types/react':
1383 + optional: true
1384 + '@types/react-dom':
1385 + optional: true
1386 +
1387 + '@radix-ui/react-presence@1.1.10':
1388 + resolution: {integrity: sha512-3wyzCQ6+ubRA+D4uv9m95JYLXxmOHp05qjrkjeA7uKHHtjpPggQzc6DAb0URl7j67oR0K2foO4ip27TiX037Bw==}
1389 + peerDependencies:
1390 + '@types/react': '*'
1391 + '@types/react-dom': '*'
1392 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1393 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1394 + peerDependenciesMeta:
1395 + '@types/react':
1396 + optional: true
1397 + '@types/react-dom':
1398 + optional: true
1399 +
1400 + '@radix-ui/react-primitive@2.1.10':
1401 + resolution: {integrity: sha512-MucOnzh6hR5mid6VpkbglRAMYMjKLqRnGBbjXkzjK52fuQDd1qbkx78a5P40mkcnVXJdEVxm26E9OPAiUq7nBg==}
1402 + peerDependencies:
1403 + '@types/react': '*'
1404 + '@types/react-dom': '*'
1405 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1406 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1407 + peerDependenciesMeta:
1408 + '@types/react':
1409 + optional: true
1410 + '@types/react-dom':
1411 + optional: true
1412 +
1413 + '@radix-ui/react-roving-focus@1.1.19':
1414 + resolution: {integrity: sha512-V9jI6hDjT7l3jsCQD9bLNvDLM3tH/gdbOTp7Tefp3hbbgCGQoK7tUvrWiRlcoBHIZ809ElXwNQwVo0B98LuTXQ==}
1415 + peerDependencies:
1416 + '@types/react': '*'
1417 + '@types/react-dom': '*'
1418 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1419 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1420 + peerDependenciesMeta:
1421 + '@types/react':
1422 + optional: true
1423 + '@types/react-dom':
1424 + optional: true
1425 +
1426 + '@radix-ui/react-scroll-area@1.2.18':
1427 + resolution: {integrity: sha512-Zn5Cd171wxsO3Dfg8HaW6RifTb9CYTKQJHs/G4+LN1GfmJpaQMZQyQxMprVPHpaz7QY4l9BxK2JwQuzHsXC8nA==}
1428 + peerDependencies:
1429 + '@types/react': '*'
1430 + '@types/react-dom': '*'
1431 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1432 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1433 + peerDependenciesMeta:
1434 + '@types/react':
1435 + optional: true
1436 + '@types/react-dom':
1437 + optional: true
1438 +
1439 + '@radix-ui/react-select@2.3.7':
1440 + resolution: {integrity: sha512-WFGImkmbzcfxeIwq/+4HvRN0pizBwbwQUED4I13ezQsDdfl38ZntN6TmR8XaSzPBqoCToe8rF75j6NPNDSzhbg==}
1441 + peerDependencies:
1442 + '@types/react': '*'
1443 + '@types/react-dom': '*'
1444 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1445 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1446 + peerDependenciesMeta:
1447 + '@types/react':
1448 + optional: true
1449 + '@types/react-dom':
1450 + optional: true
1451 +
1452 + '@radix-ui/react-slider@1.4.7':
1453 + resolution: {integrity: sha512-mTSLf1GC/C0moWjTbvCM6Qn/gBjvlFt1azuWF2v7MN5C3Zq2U2J2lN3ZEYkpujuOU5Ro7A28wkviSxaKnG0BYg==}
1454 + peerDependencies:
1455 + '@types/react': '*'
1456 + '@types/react-dom': '*'
1457 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1458 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1459 + peerDependenciesMeta:
1460 + '@types/react':
1461 + optional: true
1462 + '@types/react-dom':
1463 + optional: true
1464 +
1465 + '@radix-ui/react-slot@1.3.3':
1466 + resolution: {integrity: sha512-qx7oqnYbxnK9kYI9m317qmFmEgo6ywqWvbTogdj7cL9p3/yx4M48p7Rnw5z3H890cL/ow/EeWJsuTykeZVXP5Q==}
1467 + peerDependencies:
1468 + '@types/react': '*'
1469 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1470 + peerDependenciesMeta:
1471 + '@types/react':
1472 + optional: true
1473 +
1474 + '@radix-ui/react-switch@1.3.7':
1475 + resolution: {integrity: sha512-48tB/4dn2UVLBCYhTu9AuR63IHl73l/qLbLgxd86noTUor4/K4LFDAcYjK+isP5313qxaFpjPVogE7+Y0/V3Kw==}
1476 + peerDependencies:
1477 + '@types/react': '*'
1478 + '@types/react-dom': '*'
1479 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1480 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1481 + peerDependenciesMeta:
1482 + '@types/react':
1483 + optional: true
1484 + '@types/react-dom':
1485 + optional: true
1486 +
1487 + '@radix-ui/react-tabs@1.1.21':
1488 + resolution: {integrity: sha512-UKxJlZid7FVtsk/WTxj4i4uSEgj2Au+KBbS7SQyTlzMhhn+86Cz3tISZdTa87bfEfcuvZezf2ZsxD4xuEKtkog==}
1489 + peerDependencies:
1490 + '@types/react': '*'
1491 + '@types/react-dom': '*'
1492 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1493 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1494 + peerDependenciesMeta:
1495 + '@types/react':
1496 + optional: true
1497 + '@types/react-dom':
1498 + optional: true
1499 +
1500 + '@radix-ui/react-tooltip@1.2.16':
1501 + resolution: {integrity: sha512-6EamKFRRnlpdadndbZ6LMwycfwkwPte1B42hs6QA0gYhjaOKqW4PZ4pjaW9UrlDX5eVt/OjncE7BFTPL5nmZhg==}
1502 + peerDependencies:
1503 + '@types/react': '*'
1504 + '@types/react-dom': '*'
1505 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1506 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1507 + peerDependenciesMeta:
1508 + '@types/react':
1509 + optional: true
1510 + '@types/react-dom':
1511 + optional: true
1512 +
1513 + '@radix-ui/react-use-callback-ref@1.1.4':
1514 + resolution: {integrity: sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ==}
1515 + peerDependencies:
1516 + '@types/react': '*'
1517 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1518 + peerDependenciesMeta:
1519 + '@types/react':
1520 + optional: true
1521 +
1522 + '@radix-ui/react-use-controllable-state@1.2.6':
1523 + resolution: {integrity: sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ==}
1524 + peerDependencies:
1525 + '@types/react': '*'
1526 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1527 + peerDependenciesMeta:
1528 + '@types/react':
1529 + optional: true
1530 +
1531 + '@radix-ui/react-use-effect-event@0.0.5':
1532 + resolution: {integrity: sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==}
1533 + peerDependencies:
1534 + '@types/react': '*'
1535 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1536 + peerDependenciesMeta:
1537 + '@types/react':
1538 + optional: true
1539 +
1540 + '@radix-ui/react-use-is-hydrated@0.1.3':
1541 + resolution: {integrity: sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==}
1542 + peerDependencies:
1543 + '@types/react': '*'
1544 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1545 + peerDependenciesMeta:
1546 + '@types/react':
1547 + optional: true
1548 +
1549 + '@radix-ui/react-use-layout-effect@1.1.4':
1550 + resolution: {integrity: sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==}
1551 + peerDependencies:
1552 + '@types/react': '*'
1553 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1554 + peerDependenciesMeta:
1555 + '@types/react':
1556 + optional: true
1557 +
1558 + '@radix-ui/react-use-previous@1.1.4':
1559 + resolution: {integrity: sha512-XoSLhbRbqxFtgJoi2fNHA3C6pDlY34x508vUpUGoFZfvePfHXHbE1lC4FYFMnJWgiCRroSTw6fOsXQoVS9RwZg==}
1560 + peerDependencies:
1561 + '@types/react': '*'
1562 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1563 + peerDependenciesMeta:
1564 + '@types/react':
1565 + optional: true
1566 +
1567 + '@radix-ui/react-use-rect@1.1.4':
1568 + resolution: {integrity: sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==}
1569 + peerDependencies:
1570 + '@types/react': '*'
1571 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1572 + peerDependenciesMeta:
1573 + '@types/react':
1574 + optional: true
1575 +
1576 + '@radix-ui/react-use-size@1.1.4':
1577 + resolution: {integrity: sha512-D3anSY15EJoxrihpsXI6SMrmmonnQtR2ni7arO+Lfdg3O95b9hNXxONk8jA5C8ANdF/h5HMAxejgs8PWJ6rlhw==}
1578 + peerDependencies:
1579 + '@types/react': '*'
1580 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1581 + peerDependenciesMeta:
1582 + '@types/react':
1583 + optional: true
1584 +
1585 + '@radix-ui/react-visually-hidden@1.2.11':
1586 + resolution: {integrity: sha512-NFS86RYYZb4/exihaESBGOpMJFz8MGLAfu3mOBSGByVnVPC9JPASfYubxd/8KbkQK0sYAv8lVQDEQukDX/qXvQ==}
1587 + peerDependencies:
1588 + '@types/react': '*'
1589 + '@types/react-dom': '*'
1590 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1591 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1592 + peerDependenciesMeta:
1593 + '@types/react':
1594 + optional: true
1595 + '@types/react-dom':
1596 + optional: true
1597 +
1598 + '@radix-ui/rect@1.1.3':
1599 + resolution: {integrity: sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==}
1600 +
1601 + '@reduxjs/toolkit@2.12.0':
1602 + resolution: {integrity: sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==}
1603 + peerDependencies:
1604 + react: ^16.9.0 || ^17.0.0 || ^18 || ^19
1605 + react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
1606 + peerDependenciesMeta:
1607 + react:
1608 + optional: true
1609 + react-redux:
1610 + optional: true
1611 +
1612 + '@rollup/rollup-android-arm-eabi@4.63.1':
1613 + resolution: {integrity: sha512-UZ8sUxPTiHWYX9QNdJedb1kDZSpS1t/VPWBWGSgqHNi9w3Cu6IXvu2mzbhiTiPvtrqgTQJ+zqiAq2iPIPilpaQ==}
1614 + cpu: [arm]
1615 + os: [android]
1616 +
1617 + '@rollup/rollup-android-arm64@4.63.1':
1618 + resolution: {integrity: sha512-cQ4nFQABN5cDvDpbvJ7bMStCpnaVxynZrRMfUJYgxcIk9Sh54FIO1vtfkg0B69REjER77ioZ/ov+eAApx/KmLQ==}
1619 + cpu: [arm64]
1620 + os: [android]
1621 +
1622 + '@rollup/rollup-darwin-arm64@4.63.1':
1623 + resolution: {integrity: sha512-FQNqd1lRy/0QhDk3xeRIkSBiCpXCiDnZO3YLVdcDKN1UBiKToNftCzcXYNLshmPDUMlu2TdeS8tGcsU6f3YF1Q==}
1624 + cpu: [arm64]
1625 + os: [darwin]
1626 +
1627 + '@rollup/rollup-darwin-x64@4.63.1':
1628 + resolution: {integrity: sha512-pvD16V939D3CloK0+qikpGaxiPrDUXTe7Y5cWOMkMSy7m1cawa8EGy/kXYi/G/cKAC4HDAbSnzCIk1WmsoOKXg==}
1629 + cpu: [x64]
1630 + os: [darwin]
1631 +
1632 + '@rollup/rollup-freebsd-arm64@4.63.1':
1633 + resolution: {integrity: sha512-pcFGeL2345VwdTnJhA6zLbew+YgWB0qBG2+dMtXjCicf6+rm6kO6cOoh5VnTe0ZMrMRgRyuHmCJxZWrIdzYuOw==}
1634 + cpu: [arm64]
1635 + os: [freebsd]
1636 +
1637 + '@rollup/rollup-freebsd-x64@4.63.1':
1638 + resolution: {integrity: sha512-mRJlqSRulVzcKq/LKA6ICSIc3K/l4fzlVn/gePn2nXIHy8seRi5z/eeRE0d/XMBxcMldiXtQTSpRj0tkkC3g8Q==}
1639 + cpu: [x64]
1640 + os: [freebsd]
1641 +
1642 + '@rollup/rollup-linux-arm-gnueabihf@4.63.1':
1643 + resolution: {integrity: sha512-YDUNvVM85TI3g/1OpnqKP1h4NeW/j64DfWMf+G3M809xNk1bJSnpFp4sh83NpmVE5DXnkh8ULor4LTVZKoYLHw==}
1644 + cpu: [arm]
1645 + os: [linux]
1646 + libc: [glibc]
1647 +
1648 + '@rollup/rollup-linux-arm-musleabihf@4.63.1':
1649 + resolution: {integrity: sha512-7Mcn71p9ZuQFAj+h+dhQXy/yeLePRS2yKRnmW1DijA9thKO5qap0GNOIQK4yQ6iP3SU0Mrb/yWo8h8vgRba8lw==}
1650 + cpu: [arm]
1651 + os: [linux]
1652 + libc: [musl]
1653 +
1654 + '@rollup/rollup-linux-arm64-gnu@4.63.1':
1655 + resolution: {integrity: sha512-4YiLQTX6U4CSl0L9cluep9A9W6UmTfqBDc2/CH6wlu54pl4E7Jn3cOD8oxzvBDEGk/JMKgJ47C8g+radF7mwvg==}
1656 + cpu: [arm64]
1657 + os: [linux]
1658 + libc: [glibc]
1659 +
1660 + '@rollup/rollup-linux-arm64-musl@4.63.1':
1661 + resolution: {integrity: sha512-2ra8F7w8OquwZN9z2/fKFnli69wa8PLwaVzRMIPGb13ByMJwC28Fbp8YcVGoUhlYMTt7j5j9bNgpysrN2UM+vw==}
1662 + cpu: [arm64]
1663 + os: [linux]
1664 + libc: [musl]
1665 +
1666 + '@rollup/rollup-linux-loong64-gnu@4.63.1':
1667 + resolution: {integrity: sha512-Sy20ncyhjmBP0Ml+UvQbimjlk6VFgjW5uNP+qqwHB00mTE8Bl2C1TuHTlRwK2YoXeZbee5lP2XevBWVkAQAtSQ==}
1668 + cpu: [loong64]
1669 + os: [linux]
1670 + libc: [glibc]
1671 +
1672 + '@rollup/rollup-linux-loong64-musl@4.63.1':
1673 + resolution: {integrity: sha512-noITLp8oNjYliPnGWmLyelIHwULGqbHloQHGw1rtxbWhTuWooRpnZarZQJ1y9EUC4szuCusCc+HEpUtxpIwYvA==}
1674 + cpu: [loong64]
1675 + os: [linux]
1676 + libc: [musl]
1677 +
1678 + '@rollup/rollup-linux-ppc64-gnu@4.63.1':
1679 + resolution: {integrity: sha512-hlxxXd+F1mWiAcaFR7Sv9ZQT6m6UfI8+Vy/kFJzztq2pDMU/0wZ9sish0iszNZvsQDo8Gc0i5yuFEOz5dDf6fA==}
1680 + cpu: [ppc64]
1681 + os: [linux]
1682 + libc: [glibc]
1683 +
1684 + '@rollup/rollup-linux-ppc64-musl@4.63.1':
1685 + resolution: {integrity: sha512-EF7OpqQTQ/BvGqLzUi4rEHuagCV9MugAUXSHemwPW5vxZ75RR+jxO/2j95Ph2dalMpFHSVECjRoioHZgA9zOYA==}
1686 + cpu: [ppc64]
1687 + os: [linux]
1688 + libc: [musl]
1689 +
1690 + '@rollup/rollup-linux-riscv64-gnu@4.63.1':
1691 + resolution: {integrity: sha512-wQO3JesW9PRkwlabQ27y7sPfVOOTLRG73I4F2UYHG5PXun3J9U3y+b7ezVKSYbsvSKGQ1k1cq8Qlun4C9kLt3w==}
1692 + cpu: [riscv64]
1693 + os: [linux]
1694 + libc: [glibc]
1695 +
1696 + '@rollup/rollup-linux-riscv64-musl@4.63.1':
1697 + resolution: {integrity: sha512-ouAGwhO6wHRXdnOVCOsB0tRFkA7nhNB2Nwax6oECXN0YiN8EYUTBAOudADOB1PI+yDL61TeNx/u7MVCzksNbkQ==}
1698 + cpu: [riscv64]
1699 + os: [linux]
1700 + libc: [musl]
1701 +
1702 + '@rollup/rollup-linux-s390x-gnu@4.63.1':
1703 + resolution: {integrity: sha512-q2R38Sn+1J8RxhfJ+T54wSWmyKXWec+9jgDfqO2AtArEqHO5R2aeayp5H5OYLr5UYDVGsVaZPEFUooMhYCdz5A==}
1704 + cpu: [s390x]
1705 + os: [linux]
1706 + libc: [glibc]
1707 +
1708 + '@rollup/rollup-linux-x64-gnu@4.63.1':
1709 + resolution: {integrity: sha512-gfI5T24WLLuFfSKw7Go/zDXjAAV0fny0swTaDv+WjK7vqcw4cRhFfdsyKL1n+ukI+ooBxn3bVQnyrn06WpI50w==}
1710 + cpu: [x64]
1711 + os: [linux]
1712 + libc: [glibc]
1713 +
1714 + '@rollup/rollup-linux-x64-musl@4.63.1':
1715 + resolution: {integrity: sha512-4h6XqthmB4Hspji84wvgk+ElodTsGj+dbZqHJHHtKxj4mYq0ANSEEPX9ys3moJueqsRjwpaJYH7874Itwnj2ow==}
1716 + cpu: [x64]
1717 + os: [linux]
1718 + libc: [musl]
1719 +
1720 + '@rollup/rollup-openbsd-x64@4.63.1':
1721 + resolution: {integrity: sha512-dlfCOa87o1VAYegLQ9EKilx2JCeRofiyPGhTCmqnuXZ6bMPiycO1rq1+sKoulAp7pGLIsTIw+1x5R+zgh5LhhA==}
1722 + cpu: [x64]
1723 + os: [openbsd]
1724 +
1725 + '@rollup/rollup-openharmony-arm64@4.63.1':
1726 + resolution: {integrity: sha512-cjkLbOlfcm3QGhMM1J5zaZjsw1GggbN6rw9UTSSRrPrR1KkcXnN7Uq9rPw34xImQ9VOY9GN+6u2Zj80B9ptkcw==}
1727 + cpu: [arm64]
1728 + os: [openharmony]
1729 +
1730 + '@rollup/rollup-win32-arm64-msvc@4.63.1':
1731 + resolution: {integrity: sha512-Li1KdUnWGE4N3e1F/B4RTB1ms+nG4WBgjByO46pkeBVX/2UBsY53xf5vK9WygVmnH3RwncIST7lkSdLSY6P9lg==}
1732 + cpu: [arm64]
1733 + os: [win32]
1734 +
1735 + '@rollup/rollup-win32-ia32-msvc@4.63.1':
1736 + resolution: {integrity: sha512-t4ZYOSoLTgwhuFMrmTMLx/+i1DQVK7HYqMc6kY46EApwi8X0nIVphzdNoThU3xt6n+N5urG1/gxBdCaKDLavfg==}
1737 + cpu: [ia32]
1738 + os: [win32]
1739 +
1740 + '@rollup/rollup-win32-x64-gnu@4.63.1':
1741 + resolution: {integrity: sha512-RgroPfMmKlD1RzSDxvwgcPiy2HNQKoYV7OmwIXDsk73uKW5t6B/V8KIy27SMv/FNXFo/oSBtWc9J0X7t91ezZg==}
1742 + cpu: [x64]
1743 + os: [win32]
1744 +
1745 + '@rollup/rollup-win32-x64-msvc@4.63.1':
1746 + resolution: {integrity: sha512-at8QVep6S3h5Y6gSbdGU06bRY5WJkf6WUduM9YtvYMbYhB1MOFfUgc6kehitQXzOtMSaT70q7f9ydPhpqu821w==}
1747 + cpu: [x64]
1748 + os: [win32]
1749 +
1750 + '@rtsao/scc@1.1.0':
1751 + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
1752 +
1753 + '@shikijs/core@4.4.3':
1754 + resolution: {integrity: sha512-QCR4q2ZO/ILJEuwiBMel4wdcTDb1JGwfjKTxPDF6x8ixOaluPrVqIn06C99AcRPhmYlBR56d/Fb+GN58GzExpg==}
1755 + engines: {node: '>=20'}
1756 +
1757 + '@shikijs/engine-javascript@4.4.3':
1758 + resolution: {integrity: sha512-FbOjFJp9VLdo1Wevs10BBtVxiTWwNLqZh5Gkhjgda/ioL15YOgeSl9n+6XMa3qRlPQzfhFNe641SrynFHYG0nQ==}
1759 + engines: {node: '>=20'}
1760 +
1761 + '@shikijs/engine-oniguruma@4.4.3':
1762 + resolution: {integrity: sha512-EcOQkxdxGQrc1Row/cC2c96/v1dbZqGnEVu1qTuT/MJmp6+cXCvQussowVmCv5Tqr3KuY3c7IbM6HTW3LJ1k9w==}
1763 + engines: {node: '>=20'}
1764 +
1765 + '@shikijs/langs@4.4.3':
1766 + resolution: {integrity: sha512-ePic0yfAJGOF83D5wBHK/00EjK65oahBYxFk5epgq33WRv7X9UuxLEV8PtR0szC0z8dl7INIpIodB99JRFlR+A==}
1767 + engines: {node: '>=20'}
1768 +
1769 + '@shikijs/primitive@4.4.3':
1770 + resolution: {integrity: sha512-m0wBeLDQDeIxRdUmrCPdQqfuUamDwRL5isCfYbguKD6NiaKpVbsv+3J81DyIKgNW5h4WAIIr8T4EkgQrBBxvaQ==}
1771 + engines: {node: '>=20'}
1772 +
1773 + '@shikijs/themes@4.4.3':
1774 + resolution: {integrity: sha512-w8UHjeUnIR965KMWJHUPXOc2mNJUnK3vpVLYLvw5IYU2mnTTJ89E24OrJDBNiJDQ0qzb0tc4l7mrIXx5cFeIyw==}
1775 + engines: {node: '>=20'}
1776 +
1777 + '@shikijs/types@4.4.3':
1778 + resolution: {integrity: sha512-UEJxmRR++MAGR6hugn0vgVS2W/6lWAts84FFSrnlH9sP0LNol7E5+NQ792pH8liWUhyMyjhTgSUH3k7iD7tc5g==}
1779 + engines: {node: '>=20'}
1780 +
1781 + '@shikijs/vscode-textmate@10.0.2':
1782 + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
1783 +
1784 + '@stablelib/base64@1.0.1':
1785 + resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==}
1786 +
1787 + '@standard-schema/spec@1.1.0':
1788 + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
1789 +
1790 + '@standard-schema/utils@0.3.0':
1791 + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==}
1792 +
1793 + '@swc/helpers@0.5.23':
1794 + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==}
1795 +
1796 + '@tailwindcss/node@4.3.3':
1797 + resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==}
1798 +
1799 + '@tailwindcss/oxide-android-arm64@4.3.3':
1800 + resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==}
1801 + engines: {node: '>= 20'}
1802 + cpu: [arm64]
1803 + os: [android]
1804 +
1805 + '@tailwindcss/oxide-darwin-arm64@4.3.3':
1806 + resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==}
1807 + engines: {node: '>= 20'}
1808 + cpu: [arm64]
1809 + os: [darwin]
1810 +
1811 + '@tailwindcss/oxide-darwin-x64@4.3.3':
1812 + resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==}
1813 + engines: {node: '>= 20'}
1814 + cpu: [x64]
1815 + os: [darwin]
1816 +
1817 + '@tailwindcss/oxide-freebsd-x64@4.3.3':
1818 + resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==}
1819 + engines: {node: '>= 20'}
1820 + cpu: [x64]
1821 + os: [freebsd]
1822 +
1823 + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3':
1824 + resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==}
1825 + engines: {node: '>= 20'}
1826 + cpu: [arm]
1827 + os: [linux]
1828 +
1829 + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3':
1830 + resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==}
1831 + engines: {node: '>= 20'}
1832 + cpu: [arm64]
1833 + os: [linux]
1834 + libc: [glibc]
1835 +
1836 + '@tailwindcss/oxide-linux-arm64-musl@4.3.3':
1837 + resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==}
1838 + engines: {node: '>= 20'}
1839 + cpu: [arm64]
1840 + os: [linux]
1841 + libc: [musl]
1842 +
1843 + '@tailwindcss/oxide-linux-x64-gnu@4.3.3':
1844 + resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==}
1845 + engines: {node: '>= 20'}
1846 + cpu: [x64]
1847 + os: [linux]
1848 + libc: [glibc]
1849 +
1850 + '@tailwindcss/oxide-linux-x64-musl@4.3.3':
1851 + resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==}
1852 + engines: {node: '>= 20'}
1853 + cpu: [x64]
1854 + os: [linux]
1855 + libc: [musl]
1856 +
1857 + '@tailwindcss/oxide-wasm32-wasi@4.3.3':
1858 + resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==}
1859 + engines: {node: '>=14.0.0'}
1860 + cpu: [wasm32]
1861 + bundledDependencies:
1862 + - '@napi-rs/wasm-runtime'
1863 + - '@emnapi/core'
1864 + - '@emnapi/runtime'
1865 + - '@tybys/wasm-util'
1866 + - '@emnapi/wasi-threads'
1867 + - tslib
1868 +
1869 + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3':
1870 + resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==}
1871 + engines: {node: '>= 20'}
1872 + cpu: [arm64]
1873 + os: [win32]
1874 +
1875 + '@tailwindcss/oxide-win32-x64-msvc@4.3.3':
1876 + resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==}
1877 + engines: {node: '>= 20'}
1878 + cpu: [x64]
1879 + os: [win32]
1880 +
1881 + '@tailwindcss/oxide@4.3.3':
1882 + resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==}
1883 + engines: {node: '>= 20'}
1884 +
1885 + '@tailwindcss/postcss@4.3.3':
1886 + resolution: {integrity: sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==}
1887 +
1888 + '@tanstack/react-virtual@3.14.10':
1889 + resolution: {integrity: sha512-SRyoUbdFMRHuYXMijV5H4ZarQWpXkj3iANq8OFre+pybeVap8ZJjZ3Nz9bVjx4d8PfobVUQUdKyyyHYk3E+djw==}
1890 + peerDependencies:
1891 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1892 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1893 +
1894 + '@tanstack/virtual-core@3.17.8':
1895 + resolution: {integrity: sha512-BfEvehNpOT75r5Ksc5xW6NZuXujTfb7nlSEyVu4XHG3gdxNg1KqXruWbDewXOUaUYIo4oRbSfkjIajz4MAT8tA==}
1896 +
1897 + '@tybys/wasm-util@0.10.3':
1898 + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==}
1899 +
1900 + '@types/chai@5.2.3':
1901 + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
1902 +
1903 + '@types/d3-array@3.2.2':
1904 + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==}
1905 +
1906 + '@types/d3-color@3.1.3':
1907 + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
1908 +
1909 + '@types/d3-ease@3.0.2':
1910 + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
1911 +
1912 + '@types/d3-interpolate@3.0.4':
1913 + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
1914 +
1915 + '@types/d3-path@3.1.1':
1916 + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==}
1917 +
1918 + '@types/d3-scale@4.0.9':
1919 + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==}
1920 +
1921 + '@types/d3-shape@3.2.0':
1922 + resolution: {integrity: sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==}
1923 +
1924 + '@types/d3-time@3.0.4':
1925 + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==}
1926 +
1927 + '@types/d3-timer@3.0.2':
1928 + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
1929 +
1930 + '@types/debug@4.1.13':
1931 + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==}
1932 +
1933 + '@types/deep-eql@4.0.2':
1934 + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
1935 +
1936 + '@types/estree-jsx@1.0.5':
1937 + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
1938 +
1939 + '@types/estree@1.0.9':
1940 + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
1941 +
1942 + '@types/hast@3.0.5':
1943 + resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==}
1944 +
1945 + '@types/json-schema@7.0.15':
1946 + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
1947 +
1948 + '@types/json5@0.0.29':
1949 + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
1950 +
1951 + '@types/mdast@4.0.4':
1952 + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
1953 +
1954 + '@types/ms@2.1.0':
1955 + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
1956 +
1957 + '@types/node@24.13.3':
1958 + resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==}
1959 +
1960 + '@types/pg@8.23.1':
1961 + resolution: {integrity: sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==}
1962 +
1963 + '@types/react-dom@19.2.7':
1964 + resolution: {integrity: sha512-I8bPpDLcHBv1qiIiXDCy71Rt8eQDKJP0sMSWJphDdAcdqiJ1sGpZamavoEIRZmYzjia9LuEb2HlYdDpmoENpvQ==}
1965 + peerDependencies:
1966 + '@types/react': ^19.2.0
1967 +
1968 + '@types/react@19.2.18':
1969 + resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==}
1970 +
1971 + '@types/retry@0.12.0':
1972 + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==}
1973 +
1974 + '@types/unist@2.0.11':
1975 + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
1976 +
1977 + '@types/unist@3.0.3':
1978 + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
1979 +
1980 + '@types/use-sync-external-store@0.0.6':
1981 + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
1982 +
1983 + '@typescript-eslint/eslint-plugin@8.69.0':
1984 + resolution: {integrity: sha512-t5jQTKPIgVW1PE6dR6H6Qz5gm8zjMlX5/2gRaOGd9eO6V7J+tQc6iWKukEe7dY8u9HyYasQ0yfF0/FSSTEO2gA==}
1985 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1986 + peerDependencies:
1987 + '@typescript-eslint/parser': ^8.69.0
1988 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
1989 + typescript: '>=4.8.4 <6.1.0'
1990 +
1991 + '@typescript-eslint/parser@8.69.0':
1992 + resolution: {integrity: sha512-l4b0DhWioGg6Gt2ebGlvfkFMOjRsauxtsnDRwUSRX1qHq3HdTfQHV8wW9zEXeciai6HfeaKOedQn2Zoofx3WBw==}
1993 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1994 + peerDependencies:
1995 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
1996 + typescript: '>=4.8.4 <6.1.0'
1997 +
1998 + '@typescript-eslint/project-service@8.69.0':
1999 + resolution: {integrity: sha512-yi4obFrHMmnsesWehHbkg9zMA7Jt8cXT+mKM08G999pH1yT6nqgsHx7MYm0uY1wAj8CqiBXYRJ7WAT0QdQHQXg==}
2000 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2001 + peerDependencies:
2002 + typescript: '>=4.8.4 <6.1.0'
2003 +
2004 + '@typescript-eslint/scope-manager@8.69.0':
2005 + resolution: {integrity: sha512-ewfspqWvSxKSOaplqAUNbaSFO0eB6w1EtQ+esfYFRm3614Ty4uNtExkcbgd6nWsXphbqKyf9ZYdbZdv2xEoWEQ==}
2006 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2007 +
2008 + '@typescript-eslint/tsconfig-utils@8.69.0':
2009 + resolution: {integrity: sha512-xNqK7YTDZsLniQMV/4rpFR8Z5JlqeRvVjuG1YgF/mdPVH84HSD19L8CczMA0qg2RfwEV231GHH3VnToJDo4MfQ==}
2010 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2011 + peerDependencies:
2012 + typescript: '>=4.8.4 <6.1.0'
2013 +
2014 + '@typescript-eslint/type-utils@8.69.0':
2015 + resolution: {integrity: sha512-ZfoJAVg3JZndQEpEl9petVlxau3lRuElc4HRMuAlLCf8to04/iHz692RUSNmXKDjEuJmIL+KZ2/BsOcBc16dsA==}
2016 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2017 + peerDependencies:
2018 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
2019 + typescript: '>=4.8.4 <6.1.0'
2020 +
2021 + '@typescript-eslint/types@8.69.0':
2022 + resolution: {integrity: sha512-K3VrubUPhlo9VDBS6QdI8YB5j7ClpqLRdefcz6PFrhnwicehBweqQ9Evhl4l+FYz0HdDmMqIiSX0aldGRYtDCA==}
2023 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2024 +
2025 + '@typescript-eslint/typescript-estree@8.69.0':
2026 + resolution: {integrity: sha512-AdFkgqck3Vudb/kWnxlyafU/4aBhHrbQ9locP2N4psXTy5mOBg0SHJumnLvx7r6g1gV4DKvUFwV2nJZBoqOD8w==}
2027 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2028 + peerDependencies:
2029 + typescript: '>=4.8.4 <6.1.0'
2030 +
2031 + '@typescript-eslint/utils@8.69.0':
2032 + resolution: {integrity: sha512-tUbx60BBqQa31kXF5MCsOOLL5E/WzUuxIn7YpAvq+eaUlqvk8/NXnXMBNAdLCr0icjkzem7iUA5QqWHe/hJ1aw==}
2033 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2034 + peerDependencies:
2035 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
2036 + typescript: '>=4.8.4 <6.1.0'
2037 +
2038 + '@typescript-eslint/visitor-keys@8.69.0':
2039 + resolution: {integrity: sha512-+rmdgPA+EXkNgKYvHvFfhrs35utXbwaC5PGpDquSXcoXQDKUA5UjV0LmTucG/4JXkM31BTu4TilHtrN8IVBe8w==}
2040 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2041 +
2042 + '@ungap/structured-clone@1.4.0':
2043 + resolution: {integrity: sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==}
2044 +
2045 + '@unrs/resolver-binding-android-arm-eabi@1.12.2':
2046 + resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==}
2047 + cpu: [arm]
2048 + os: [android]
2049 +
2050 + '@unrs/resolver-binding-android-arm64@1.12.2':
2051 + resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==}
2052 + cpu: [arm64]
2053 + os: [android]
2054 +
2055 + '@unrs/resolver-binding-darwin-arm64@1.12.2':
2056 + resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==}
2057 + cpu: [arm64]
2058 + os: [darwin]
2059 +
2060 + '@unrs/resolver-binding-darwin-x64@1.12.2':
2061 + resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==}
2062 + cpu: [x64]
2063 + os: [darwin]
2064 +
2065 + '@unrs/resolver-binding-freebsd-x64@1.12.2':
2066 + resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==}
2067 + cpu: [x64]
2068 + os: [freebsd]
2069 +
2070 + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2':
2071 + resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==}
2072 + cpu: [arm]
2073 + os: [linux]
2074 +
2075 + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2':
2076 + resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==}
2077 + cpu: [arm]
2078 + os: [linux]
2079 +
2080 + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2':
2081 + resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==}
2082 + cpu: [arm64]
2083 + os: [linux]
2084 + libc: [glibc]
2085 +
2086 + '@unrs/resolver-binding-linux-arm64-musl@1.12.2':
2087 + resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==}
2088 + cpu: [arm64]
2089 + os: [linux]
2090 + libc: [musl]
2091 +
2092 + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2':
2093 + resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==}
2094 + cpu: [loong64]
2095 + os: [linux]
2096 + libc: [glibc]
2097 +
2098 + '@unrs/resolver-binding-linux-loong64-musl@1.12.2':
2099 + resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==}
2100 + cpu: [loong64]
2101 + os: [linux]
2102 + libc: [musl]
2103 +
2104 + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2':
2105 + resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==}
2106 + cpu: [ppc64]
2107 + os: [linux]
2108 + libc: [glibc]
2109 +
2110 + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2':
2111 + resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==}
2112 + cpu: [riscv64]
2113 + os: [linux]
2114 + libc: [glibc]
2115 +
2116 + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2':
2117 + resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==}
2118 + cpu: [riscv64]
2119 + os: [linux]
2120 + libc: [musl]
2121 +
2122 + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2':
2123 + resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==}
2124 + cpu: [s390x]
2125 + os: [linux]
2126 + libc: [glibc]
2127 +
2128 + '@unrs/resolver-binding-linux-x64-gnu@1.12.2':
2129 + resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==}
2130 + cpu: [x64]
2131 + os: [linux]
2132 + libc: [glibc]
2133 +
2134 + '@unrs/resolver-binding-linux-x64-musl@1.12.2':
2135 + resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==}
2136 + cpu: [x64]
2137 + os: [linux]
2138 + libc: [musl]
2139 +
2140 + '@unrs/resolver-binding-openharmony-arm64@1.12.2':
2141 + resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==}
2142 + cpu: [arm64]
2143 + os: [openharmony]
2144 +
2145 + '@unrs/resolver-binding-wasm32-wasi@1.12.2':
2146 + resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==}
2147 + engines: {node: '>=14.0.0'}
2148 + cpu: [wasm32]
2149 +
2150 + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2':
2151 + resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==}
2152 + cpu: [arm64]
2153 + os: [win32]
2154 +
2155 + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2':
2156 + resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==}
2157 + cpu: [ia32]
2158 + os: [win32]
2159 +
2160 + '@unrs/resolver-binding-win32-x64-msvc@1.12.2':
2161 + resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==}
2162 + cpu: [x64]
2163 + os: [win32]
2164 +
2165 + '@vitest/expect@3.2.7':
2166 + resolution: {integrity: sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==}
2167 +
2168 + '@vitest/mocker@3.2.7':
2169 + resolution: {integrity: sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==}
2170 + peerDependencies:
2171 + msw: ^2.4.9
2172 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0
2173 + peerDependenciesMeta:
2174 + msw:
2175 + optional: true
2176 + vite:
2177 + optional: true
2178 +
2179 + '@vitest/pretty-format@3.2.7':
2180 + resolution: {integrity: sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==}
2181 +
2182 + '@vitest/runner@3.2.7':
2183 + resolution: {integrity: sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==}
2184 +
2185 + '@vitest/snapshot@3.2.7':
2186 + resolution: {integrity: sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==}
2187 +
2188 + '@vitest/spy@3.2.7':
2189 + resolution: {integrity: sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==}
2190 +
2191 + '@vitest/utils@3.2.7':
2192 + resolution: {integrity: sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==}
2193 +
2194 + acorn-jsx@5.3.2:
2195 + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
2196 + peerDependencies:
2197 + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
2198 +
2199 + acorn@8.18.0:
2200 + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==}
2201 + engines: {node: '>=0.4.0'}
2202 + hasBin: true
2203 +
2204 + agent-base@7.1.4:
2205 + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
2206 + engines: {node: '>= 14'}
2207 +
2208 + ajv@6.15.0:
2209 + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
2210 +
2211 + ansi-styles@4.3.0:
2212 + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
2213 + engines: {node: '>=8'}
2214 +
2215 + argon2@0.45.1:
2216 + resolution: {integrity: sha512-skm+/WCjkGqCQxF7FG1LuZXM5yvbFjgbfiCGsud2oLgaDhh6b6dbH0b1EkghbM+xx4Bj8Ape+KKgixoIlWZicQ==}
2217 + engines: {node: '>=16.17.0'}
2218 +
2219 + argparse@2.0.1:
2220 + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
2221 +
2222 + aria-hidden@1.2.6:
2223 + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
2224 + engines: {node: '>=10'}
2225 +
2226 + aria-query@5.3.2:
2227 + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
2228 + engines: {node: '>= 0.4'}
2229 +
2230 + array-buffer-byte-length@1.0.2:
2231 + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
2232 + engines: {node: '>= 0.4'}
2233 +
2234 + array-includes@3.1.9:
2235 + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==}
2236 + engines: {node: '>= 0.4'}
2237 +
2238 + array.prototype.findlast@1.2.5:
2239 + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
2240 + engines: {node: '>= 0.4'}
2241 +
2242 + array.prototype.findlastindex@1.2.6:
2243 + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==}
2244 + engines: {node: '>= 0.4'}
2245 +
2246 + array.prototype.flat@1.3.3:
2247 + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==}
2248 + engines: {node: '>= 0.4'}
2249 +
2250 + array.prototype.flatmap@1.3.3:
2251 + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==}
2252 + engines: {node: '>= 0.4'}
2253 +
2254 + array.prototype.tosorted@1.1.4:
2255 + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
2256 + engines: {node: '>= 0.4'}
2257 +
2258 + arraybuffer.prototype.slice@1.0.4:
2259 + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
2260 + engines: {node: '>= 0.4'}
2261 +
2262 + assertion-error@2.0.1:
2263 + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
2264 + engines: {node: '>=12'}
2265 +
2266 + ast-types-flow@0.0.8:
2267 + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
2268 +
2269 + async-function@1.0.0:
2270 + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
2271 + engines: {node: '>= 0.4'}
2272 +
2273 + available-typed-arrays@1.0.7:
2274 + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
2275 + engines: {node: '>= 0.4'}
2276 +
2277 + axe-core@4.13.0:
2278 + resolution: {integrity: sha512-UzGt8zg7Ny8djbYMhxl2zuEevVa7r2gJjYY5Lwr1xM7+XU2nd6CkIWFTVcCIbAP63vSz71NaVyyuSk9lHKcy0A==}
2279 + engines: {node: '>=4'}
2280 +
2281 + axobject-query@4.1.0:
2282 + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
2283 + engines: {node: '>= 0.4'}
2284 +
2285 + bail@2.0.2:
2286 + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
2287 +
2288 + balanced-match@1.0.2:
2289 + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
2290 +
2291 + balanced-match@4.0.4:
2292 + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
2293 + engines: {node: 18 || 20 || >=22}
2294 +
2295 + base64-js@1.5.1:
2296 + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
2297 +
2298 + baseline-browser-mapping@2.11.21:
2299 + resolution: {integrity: sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ==}
2300 + engines: {node: '>=6.0.0'}
2301 + hasBin: true
2302 +
2303 + better-auth@1.7.3:
2304 + resolution: {integrity: sha512-8xGp68JQ+l36kniDEgP8bP99TLi1GdEv0NTEUBkyqnYnus/cgFUZseUfqUHKzr2BAsg2O6aD88I9f0U68shanQ==}
2305 + peerDependencies:
2306 + '@lynx-js/react': '*'
2307 + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
2308 + '@sveltejs/kit': ^2.0.0
2309 + '@tanstack/react-start': ^1.0.0
2310 + '@tanstack/solid-start': ^1.0.0
2311 + better-sqlite3: ^12.0.0
2312 + drizzle-kit: '>=0.31.4 || >=1.0.0-beta.1'
2313 + drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0
2314 + mongodb: ^6.0.0 || ^7.0.0
2315 + mysql2: ^3.0.0
2316 + next: ^14.0.0 || ^15.0.0 || ^16.0.0
2317 + pg: ^8.0.0
2318 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0
2319 + react: ^18.0.0 || ^19.0.0
2320 + react-dom: ^18.0.0 || ^19.0.0
2321 + solid-js: ^1.0.0
2322 + svelte: ^4.0.0 || ^5.0.0
2323 + vitest: ^2.0.0 || ^3.0.0 || ^4.0.0
2324 + vue: ^3.0.0
2325 + peerDependenciesMeta:
2326 + '@lynx-js/react':
2327 + optional: true
2328 + '@prisma/client':
2329 + optional: true
2330 + '@sveltejs/kit':
2331 + optional: true
2332 + '@tanstack/react-start':
2333 + optional: true
2334 + '@tanstack/solid-start':
2335 + optional: true
2336 + better-sqlite3:
2337 + optional: true
2338 + drizzle-kit:
2339 + optional: true
2340 + drizzle-orm:
2341 + optional: true
2342 + mongodb:
2343 + optional: true
2344 + mysql2:
2345 + optional: true
2346 + next:
2347 + optional: true
2348 + pg:
2349 + optional: true
2350 + prisma:
2351 + optional: true
2352 + react:
2353 + optional: true
2354 + react-dom:
2355 + optional: true
2356 + solid-js:
2357 + optional: true
2358 + svelte:
2359 + optional: true
2360 + vitest:
2361 + optional: true
2362 + vue:
2363 + optional: true
2364 +
2365 + better-call@1.4.0:
2366 + resolution: {integrity: sha512-bBKOT4vv1kZLDgxVePdilk/Jwkn+dtRRsmi3DzHcDP+WnswyVl6dR59l2HEeP/0cB+bDoopASAesWDPIdd/zZA==}
2367 + peerDependencies:
2368 + zod: ^4.0.0
2369 + peerDependenciesMeta:
2370 + zod:
2371 + optional: true
2372 +
2373 + bignumber.js@9.3.1:
2374 + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==}
2375 +
2376 + brace-expansion@1.1.18:
2377 + resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==}
2378 +
2379 + brace-expansion@5.0.9:
2380 + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==}
2381 + engines: {node: 20 || >=22}
2382 +
2383 + braces@3.0.3:
2384 + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
2385 + engines: {node: '>=8'}
2386 +
2387 + browserslist@4.28.9:
2388 + resolution: {integrity: sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==}
2389 + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
2390 + hasBin: true
2391 +
2392 + buffer-equal-constant-time@1.0.1:
2393 + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
2394 +
2395 + buffer-from@1.1.2:
2396 + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
2397 +
2398 + cac@6.7.14:
2399 + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
2400 + engines: {node: '>=8'}
2401 +
2402 + call-bind-apply-helpers@1.0.2:
2403 + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
2404 + engines: {node: '>= 0.4'}
2405 +
2406 + call-bind@1.0.9:
2407 + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==}
2408 + engines: {node: '>= 0.4'}
2409 +
2410 + call-bound@1.0.4:
2411 + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
2412 + engines: {node: '>= 0.4'}
2413 +
2414 + callsites@3.1.0:
2415 + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
2416 + engines: {node: '>=6'}
2417 +
2418 + caniuse-lite@1.0.30001810:
2419 + resolution: {integrity: sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==}
2420 +
2421 + ccount@2.0.1:
2422 + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
2423 +
2424 + chai@5.3.3:
2425 + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
2426 + engines: {node: '>=18'}
2427 +
2428 + chalk@4.1.2:
2429 + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
2430 + engines: {node: '>=10'}
2431 +
2432 + character-entities-html4@2.1.0:
2433 + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
2434 +
2435 + character-entities-legacy@3.0.0:
2436 + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
2437 +
2438 + character-entities@2.0.2:
2439 + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
2440 +
2441 + character-reference-invalid@2.0.1:
2442 + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
2443 +
2444 + check-error@2.1.3:
2445 + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==}
2446 + engines: {node: '>= 16'}
2447 +
2448 + class-variance-authority@0.7.1:
2449 + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
2450 +
2451 + client-only@0.0.1:
2452 + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
2453 +
2454 + clsx@2.1.1:
2455 + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
2456 + engines: {node: '>=6'}
2457 +
2458 + cmdk@1.1.1:
2459 + resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==}
2460 + peerDependencies:
2461 + react: ^18 || ^19 || ^19.0.0-rc
2462 + react-dom: ^18 || ^19 || ^19.0.0-rc
2463 +
2464 + color-convert@2.0.1:
2465 + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
2466 + engines: {node: '>=7.0.0'}
2467 +
2468 + color-name@1.1.4:
2469 + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
2470 +
2471 + comma-separated-tokens@2.0.3:
2472 + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
2473 +
2474 + concat-map@0.0.1:
2475 + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
2476 +
2477 + convert-source-map@2.0.0:
2478 + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
2479 +
2480 + cross-env@10.1.0:
2481 + resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==}
2482 + engines: {node: '>=20'}
2483 + hasBin: true
2484 +
2485 + cross-spawn@7.0.6:
2486 + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
2487 + engines: {node: '>= 8'}
2488 +
2489 + csstype@3.2.3:
2490 + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
2491 +
2492 + d3-array@3.2.4:
2493 + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
2494 + engines: {node: '>=12'}
2495 +
2496 + d3-color@3.1.0:
2497 + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
2498 + engines: {node: '>=12'}
2499 +
2500 + d3-ease@3.0.1:
2501 + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
2502 + engines: {node: '>=12'}
2503 +
2504 + d3-format@3.1.2:
2505 + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==}
2506 + engines: {node: '>=12'}
2507 +
2508 + d3-interpolate@3.0.1:
2509 + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
2510 + engines: {node: '>=12'}
2511 +
2512 + d3-path@3.1.0:
2513 + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==}
2514 + engines: {node: '>=12'}
2515 +
2516 + d3-scale@4.0.2:
2517 + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
2518 + engines: {node: '>=12'}
2519 +
2520 + d3-shape@3.2.0:
2521 + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==}
2522 + engines: {node: '>=12'}
2523 +
2524 + d3-time-format@4.1.0:
2525 + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
2526 + engines: {node: '>=12'}
2527 +
2528 + d3-time@3.1.0:
2529 + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==}
2530 + engines: {node: '>=12'}
2531 +
2532 + d3-timer@3.0.1:
2533 + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
2534 + engines: {node: '>=12'}
2535 +
2536 + damerau-levenshtein@1.0.8:
2537 + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
2538 +
2539 + data-uri-to-buffer@4.0.1:
2540 + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
2541 + engines: {node: '>= 12'}
2542 +
2543 + data-view-buffer@1.0.2:
2544 + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
2545 + engines: {node: '>= 0.4'}
2546 +
2547 + data-view-byte-length@1.0.2:
2548 + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==}
2549 + engines: {node: '>= 0.4'}
2550 +
2551 + data-view-byte-offset@1.0.1:
2552 + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
2553 + engines: {node: '>= 0.4'}
2554 +
2555 + debug@3.2.7:
2556 + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
2557 + peerDependencies:
2558 + supports-color: '*'
2559 + peerDependenciesMeta:
2560 + supports-color:
2561 + optional: true
2562 +
2563 + debug@4.4.3:
2564 + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
2565 + engines: {node: '>=6.0'}
2566 + peerDependencies:
2567 + supports-color: '*'
2568 + peerDependenciesMeta:
2569 + supports-color:
2570 + optional: true
2571 +
2572 + decimal.js-light@2.5.1:
2573 + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
2574 +
2575 + decode-named-character-reference@1.3.0:
2576 + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
2577 +
2578 + deep-eql@5.0.2:
2579 + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
2580 + engines: {node: '>=6'}
2581 +
2582 + deep-is@0.1.4:
2583 + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
2584 +
2585 + define-data-property@1.1.4:
2586 + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
2587 + engines: {node: '>= 0.4'}
2588 +
2589 + define-properties@1.2.1:
2590 + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
2591 + engines: {node: '>= 0.4'}
2592 +
2593 + defu@6.1.7:
2594 + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
2595 +
2596 + dequal@2.0.3:
2597 + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
2598 + engines: {node: '>=6'}
2599 +
2600 + detect-libc@2.1.2:
2601 + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
2602 + engines: {node: '>=8'}
2603 +
2604 + detect-node-es@1.1.0:
2605 + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
2606 +
2607 + devlop@1.1.0:
2608 + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
2609 +
2610 + doctrine@2.1.0:
2611 + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
2612 + engines: {node: '>=0.10.0'}
2613 +
2614 + drizzle-kit@0.31.10:
2615 + resolution: {integrity: sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw==}
2616 + hasBin: true
2617 +
2618 + drizzle-orm@0.45.2:
2619 + resolution: {integrity: sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==}
2620 + peerDependencies:
2621 + '@aws-sdk/client-rds-data': '>=3'
2622 + '@cloudflare/workers-types': '>=4'
2623 + '@electric-sql/pglite': '>=0.2.0'
2624 + '@libsql/client': '>=0.10.0'
2625 + '@libsql/client-wasm': '>=0.10.0'
2626 + '@neondatabase/serverless': '>=0.10.0'
2627 + '@op-engineering/op-sqlite': '>=2'
2628 + '@opentelemetry/api': ^1.4.1
2629 + '@planetscale/database': '>=1.13'
2630 + '@prisma/client': '*'
2631 + '@tidbcloud/serverless': '*'
2632 + '@types/better-sqlite3': '*'
2633 + '@types/pg': '*'
2634 + '@types/sql.js': '*'
2635 + '@upstash/redis': '>=1.34.7'
2636 + '@vercel/postgres': '>=0.8.0'
2637 + '@xata.io/client': '*'
2638 + better-sqlite3: '>=7'
2639 + bun-types: '*'
2640 + expo-sqlite: '>=14.0.0'
2641 + gel: '>=2'
2642 + knex: '*'
2643 + kysely: '*'
2644 + mysql2: '>=2'
2645 + pg: '>=8'
2646 + postgres: '>=3'
2647 + prisma: '*'
2648 + sql.js: '>=1'
2649 + sqlite3: '>=5'
2650 + peerDependenciesMeta:
2651 + '@aws-sdk/client-rds-data':
2652 + optional: true
2653 + '@cloudflare/workers-types':
2654 + optional: true
2655 + '@electric-sql/pglite':
2656 + optional: true
2657 + '@libsql/client':
2658 + optional: true
2659 + '@libsql/client-wasm':
2660 + optional: true
2661 + '@neondatabase/serverless':
2662 + optional: true
2663 + '@op-engineering/op-sqlite':
2664 + optional: true
2665 + '@opentelemetry/api':
2666 + optional: true
2667 + '@planetscale/database':
2668 + optional: true
2669 + '@prisma/client':
2670 + optional: true
2671 + '@tidbcloud/serverless':
2672 + optional: true
2673 + '@types/better-sqlite3':
2674 + optional: true
2675 + '@types/pg':
2676 + optional: true
2677 + '@types/sql.js':
2678 + optional: true
2679 + '@upstash/redis':
2680 + optional: true
2681 + '@vercel/postgres':
2682 + optional: true
2683 + '@xata.io/client':
2684 + optional: true
2685 + better-sqlite3:
2686 + optional: true
2687 + bun-types:
2688 + optional: true
2689 + expo-sqlite:
2690 + optional: true
2691 + gel:
2692 + optional: true
2693 + knex:
2694 + optional: true
2695 + kysely:
2696 + optional: true
2697 + mysql2:
2698 + optional: true
2699 + pg:
2700 + optional: true
2701 + postgres:
2702 + optional: true
2703 + prisma:
2704 + optional: true
2705 + sql.js:
2706 + optional: true
2707 + sqlite3:
2708 + optional: true
2709 +
2710 + dunder-proto@1.0.1:
2711 + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
2712 + engines: {node: '>= 0.4'}
2713 +
2714 + ecdsa-sig-formatter@1.0.11:
2715 + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
2716 +
2717 + electron-to-chromium@1.5.422:
2718 + resolution: {integrity: sha512-UvA/32XqrLDdZSn7Jllo1AYNcWji/G0d5M0GTViE7KoGBiMunw3a34Sb2KO4ZZyrSEhqsxFoVhWWJshdyfKqJA==}
2719 +
2720 + emoji-regex@9.2.2:
2721 + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
2722 +
2723 + enhanced-resolve@5.24.5:
2724 + resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==}
2725 + engines: {node: '>=10.13.0'}
2726 +
2727 + entities@6.0.1:
2728 + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
2729 + engines: {node: '>=0.12'}
2730 +
2731 + es-abstract-get@1.0.0:
2732 + resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==}
2733 + engines: {node: '>= 0.4'}
2734 +
2735 + es-abstract@1.24.2:
2736 + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==}
2737 + engines: {node: '>= 0.4'}
2738 +
2739 + es-define-property@1.0.1:
2740 + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
2741 + engines: {node: '>= 0.4'}
2742 +
2743 + es-errors@1.3.0:
2744 + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
2745 + engines: {node: '>= 0.4'}
2746 +
2747 + es-iterator-helpers@1.4.0:
2748 + resolution: {integrity: sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==}
2749 + engines: {node: '>= 0.4'}
2750 +
2751 + es-module-lexer@1.7.0:
2752 + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
2753 +
2754 + es-object-atoms@1.1.2:
2755 + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==}
2756 + engines: {node: '>= 0.4'}
2757 +
2758 + es-set-tostringtag@2.1.0:
2759 + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
2760 + engines: {node: '>= 0.4'}
2761 +
2762 + es-shim-unscopables@1.1.0:
2763 + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==}
2764 + engines: {node: '>= 0.4'}
2765 +
2766 + es-to-primitive@1.3.4:
2767 + resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==}
2768 + engines: {node: '>= 0.4'}
2769 +
2770 + es-toolkit@1.52.0:
2771 + resolution: {integrity: sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==}
2772 +
2773 + esbuild@0.18.20:
2774 + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
2775 + engines: {node: '>=12'}
2776 + hasBin: true
2777 +
2778 + esbuild@0.25.12:
2779 + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
2780 + engines: {node: '>=18'}
2781 + hasBin: true
2782 +
2783 + esbuild@0.28.2:
2784 + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==}
2785 + engines: {node: '>=18'}
2786 + hasBin: true
2787 +
2788 + escalade@3.2.0:
2789 + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
2790 + engines: {node: '>=6'}
2791 +
2792 + escape-string-regexp@4.0.0:
2793 + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
2794 + engines: {node: '>=10'}
2795 +
2796 + escape-string-regexp@5.0.0:
2797 + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
2798 + engines: {node: '>=12'}
2799 +
2800 + eslint-config-next@16.3.4:
2801 + resolution: {integrity: sha512-35/8RM10huEL9vlr8hUZMERMENHBrnyHN3ZZkF9efSgzGaqK34jIqry44A956//zriUhUAUW0XSkcolhrryqAA==}
2802 + peerDependencies:
2803 + eslint: '>=9.0.0'
2804 + typescript: '>=3.3.1'
2805 + peerDependenciesMeta:
2806 + typescript:
2807 + optional: true
2808 +
2809 + eslint-import-resolver-node@0.3.10:
2810 + resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==}
2811 +
2812 + eslint-import-resolver-typescript@3.10.1:
2813 + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==}
2814 + engines: {node: ^14.18.0 || >=16.0.0}
2815 + peerDependencies:
2816 + eslint: '*'
2817 + eslint-plugin-import: '*'
2818 + eslint-plugin-import-x: '*'
2819 + peerDependenciesMeta:
2820 + eslint-plugin-import:
2821 + optional: true
2822 + eslint-plugin-import-x:
2823 + optional: true
2824 +
2825 + eslint-module-utils@2.14.0:
2826 + resolution: {integrity: sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==}
2827 + engines: {node: '>=4'}
2828 + peerDependencies:
2829 + '@typescript-eslint/parser': '*'
2830 + eslint: '*'
2831 + eslint-import-resolver-node: '*'
2832 + eslint-import-resolver-typescript: '*'
2833 + eslint-import-resolver-webpack: '*'
2834 + peerDependenciesMeta:
2835 + '@typescript-eslint/parser':
2836 + optional: true
2837 + eslint:
2838 + optional: true
2839 + eslint-import-resolver-node:
2840 + optional: true
2841 + eslint-import-resolver-typescript:
2842 + optional: true
2843 + eslint-import-resolver-webpack:
2844 + optional: true
2845 +
2846 + eslint-plugin-import@2.32.0:
2847 + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==}
2848 + engines: {node: '>=4'}
2849 + peerDependencies:
2850 + '@typescript-eslint/parser': '*'
2851 + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9
2852 + peerDependenciesMeta:
2853 + '@typescript-eslint/parser':
2854 + optional: true
2855 +
2856 + eslint-plugin-jsx-a11y@6.10.2:
2857 + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==}
2858 + engines: {node: '>=4.0'}
2859 + peerDependencies:
2860 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9
2861 +
2862 + eslint-plugin-react-hooks@7.1.1:
2863 + resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==}
2864 + engines: {node: '>=18'}
2865 + peerDependencies:
2866 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0
2867 +
2868 + eslint-plugin-react@7.37.5:
2869 + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==}
2870 + engines: {node: '>=4'}
2871 + peerDependencies:
2872 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
2873 +
2874 + eslint-scope@8.4.0:
2875 + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
2876 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2877 +
2878 + eslint-visitor-keys@3.4.3:
2879 + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
2880 + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
2881 +
2882 + eslint-visitor-keys@4.2.1:
2883 + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
2884 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2885 +
2886 + eslint-visitor-keys@5.0.1:
2887 + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
2888 + engines: {node: ^20.19.0 || ^22.13.0 || >=24}
2889 +
2890 + eslint@9.39.5:
2891 + resolution: {integrity: sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==}
2892 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2893 + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
2894 + hasBin: true
2895 + peerDependencies:
2896 + jiti: '*'
2897 + peerDependenciesMeta:
2898 + jiti:
2899 + optional: true
2900 +
2901 + espree@10.4.0:
2902 + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
2903 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2904 +
2905 + esquery@1.7.0:
2906 + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
2907 + engines: {node: '>=0.10'}
2908 +
2909 + esrecurse@4.3.0:
2910 + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
2911 + engines: {node: '>=4.0'}
2912 +
2913 + estraverse@5.3.0:
2914 + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
2915 + engines: {node: '>=4.0'}
2916 +
2917 + estree-util-is-identifier-name@3.0.0:
2918 + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
2919 +
2920 + estree-walker@3.0.3:
2921 + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
2922 +
2923 + esutils@2.0.3:
2924 + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
2925 + engines: {node: '>=0.10.0'}
2926 +
2927 + eventemitter3@5.0.4:
2928 + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
2929 +
2930 + expect-type@1.4.0:
2931 + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
2932 + engines: {node: '>=12.0.0'}
2933 +
2934 + extend@3.0.2:
2935 + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
2936 +
2937 + fast-deep-equal@3.1.3:
2938 + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
2939 +
2940 + fast-glob@3.3.1:
2941 + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
2942 + engines: {node: '>=8.6.0'}
2943 +
2944 + fast-json-stable-stringify@2.1.0:
2945 + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
2946 +
2947 + fast-levenshtein@2.0.6:
2948 + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
2949 +
2950 + fast-sha256@1.3.0:
2951 + resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==}
2952 +
2953 + fastq@1.20.3:
2954 + resolution: {integrity: sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==}
2955 +
2956 + fdir@6.5.0:
2957 + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
2958 + engines: {node: '>=12.0.0'}
2959 + peerDependencies:
2960 + picomatch: ^3 || ^4
2961 + peerDependenciesMeta:
2962 + picomatch:
2963 + optional: true
2964 +
2965 + fetch-blob@3.2.0:
2966 + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
2967 + engines: {node: ^12.20 || >= 14.13}
2968 +
2969 + file-entry-cache@8.0.0:
2970 + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
2971 + engines: {node: '>=16.0.0'}
2972 +
2973 + fill-range@7.1.1:
2974 + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
2975 + engines: {node: '>=8'}
2976 +
2977 + find-up@5.0.0:
2978 + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
2979 + engines: {node: '>=10'}
2980 +
2981 + flat-cache@4.0.1:
2982 + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
2983 + engines: {node: '>=16'}
2984 +
2985 + flatted@3.4.4:
2986 + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==}
2987 +
2988 + for-each@0.3.5:
2989 + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
2990 + engines: {node: '>= 0.4'}
2991 +
2992 + formdata-polyfill@4.0.10:
2993 + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
2994 + engines: {node: '>=12.20.0'}
2995 +
2996 + framer-motion@12.43.0:
2997 + resolution: {integrity: sha512-1eaL3RvR/kAlbG7UYcpMptEyzPoENO0c6w7ZnB3/hh2vSAz/6uGAFn6fdoqTBguNstf3MsFhJHsD/0DHiclG+g==}
2998 + peerDependencies:
2999 + '@emotion/is-prop-valid': '*'
3000 + react: ^18.0.0 || ^19.0.0
3001 + react-dom: ^18.0.0 || ^19.0.0
3002 + peerDependenciesMeta:
3003 + '@emotion/is-prop-valid':
3004 + optional: true
3005 + react:
3006 + optional: true
3007 + react-dom:
3008 + optional: true
3009 +
3010 + fsevents@2.3.3:
3011 + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
3012 + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
3013 + os: [darwin]
3014 +
3015 + function-bind@1.1.2:
3016 + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
3017 +
3018 + function.prototype.name@1.2.0:
3019 + resolution: {integrity: sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==}
3020 + engines: {node: '>= 0.4'}
3021 +
3022 + functions-have-names@1.2.3:
3023 + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
3024 +
3025 + gaxios@7.3.1:
3026 + resolution: {integrity: sha512-kB3rzJV7d9juLZh8/56QTXCwQfxyhdOMdyYk1HdQKFtF8TJTDTZQJtixWIwXdE9Jji91mC41DUNpjleo4L4eAQ==}
3027 + engines: {node: '>=18'}
3028 +
3029 + gcp-metadata@8.1.2:
3030 + resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==}
3031 + engines: {node: '>=18'}
3032 +
3033 + geist@1.7.2:
3034 + resolution: {integrity: sha512-Gu5lDFa3pLRyoBlBPf0QIFHVdWAnpco7fS1bJm41jyLPFoguBgiubseUN2oLXMgqZ7uxAxDoXcHMhCY/fOTTgg==}
3035 + peerDependencies:
3036 + next: '>=13.2.0'
3037 +
3038 + generator-function@2.0.1:
3039 + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==}
3040 + engines: {node: '>= 0.4'}
3041 +
3042 + gensync@1.0.0-beta.2:
3043 + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
3044 + engines: {node: '>=6.9.0'}
3045 +
3046 + get-intrinsic@1.3.0:
3047 + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
3048 + engines: {node: '>= 0.4'}
3049 +
3050 + get-nonce@1.0.1:
3051 + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
3052 + engines: {node: '>=6'}
3053 +
3054 + get-proto@1.0.1:
3055 + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
3056 + engines: {node: '>= 0.4'}
3057 +
3058 + get-symbol-description@1.1.0:
3059 + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
3060 + engines: {node: '>= 0.4'}
3061 +
3062 + get-tsconfig@4.14.3:
3063 + resolution: {integrity: sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==}
3064 +
3065 + glob-parent@5.1.2:
3066 + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
3067 + engines: {node: '>= 6'}
3068 +
3069 + glob-parent@6.0.2:
3070 + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
3071 + engines: {node: '>=10.13.0'}
3072 +
3073 + globals@14.0.0:
3074 + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
3075 + engines: {node: '>=18'}
3076 +
3077 + globals@16.4.0:
3078 + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==}
3079 + engines: {node: '>=18'}
3080 +
3081 + globalthis@1.0.4:
3082 + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
3083 + engines: {node: '>= 0.4'}
3084 +
3085 + google-auth-library@10.9.1:
3086 + resolution: {integrity: sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw==}
3087 + engines: {node: '>=18'}
3088 +
3089 + google-logging-utils@1.1.3:
3090 + resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==}
3091 + engines: {node: '>=14'}
3092 +
3093 + gopd@1.2.0:
3094 + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
3095 + engines: {node: '>= 0.4'}
3096 +
3097 + graceful-fs@4.2.11:
3098 + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
3099 +
3100 + has-bigints@1.1.0:
3101 + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
3102 + engines: {node: '>= 0.4'}
3103 +
3104 + has-flag@4.0.0:
3105 + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
3106 + engines: {node: '>=8'}
3107 +
3108 + has-property-descriptors@1.0.2:
3109 + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
3110 +
3111 + has-proto@1.2.0:
3112 + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==}
3113 + engines: {node: '>= 0.4'}
3114 +
3115 + has-symbols@1.1.0:
3116 + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
3117 + engines: {node: '>= 0.4'}
3118 +
3119 + has-tostringtag@1.0.2:
3120 + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
3121 + engines: {node: '>= 0.4'}
3122 +
3123 + hasown@2.0.4:
3124 + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
3125 + engines: {node: '>= 0.4'}
3126 +
3127 + hast-util-from-parse5@8.0.3:
3128 + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
3129 +
3130 + hast-util-parse-selector@4.0.0:
3131 + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
3132 +
3133 + hast-util-raw@9.1.0:
3134 + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
3135 +
3136 + hast-util-to-html@9.0.5:
3137 + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
3138 +
3139 + hast-util-to-jsx-runtime@2.3.6:
3140 + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
3141 +
3142 + hast-util-to-parse5@8.0.1:
3143 + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==}
3144 +
3145 + hast-util-whitespace@3.0.0:
3146 + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
3147 +
3148 + hastscript@9.0.1:
3149 + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
3150 +
3151 + hermes-estree@0.25.1:
3152 + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==}
3153 +
3154 + hermes-parser@0.25.1:
3155 + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==}
3156 +
3157 + html-url-attributes@3.0.1:
3158 + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
3159 +
3160 + html-void-elements@3.0.0:
3161 + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
3162 +
3163 + https-proxy-agent@7.0.6:
3164 + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
3165 + engines: {node: '>= 14'}
3166 +
3167 + ignore@5.3.2:
3168 + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
3169 + engines: {node: '>= 4'}
3170 +
3171 + ignore@7.0.8:
3172 + resolution: {integrity: sha512-YYNsSlXBjMk92SKnkwvB5LOVSa6OznlFUGcsvrFgNJbJCd0M1XKeFVRc8ZByeCqz32FivYNHJVooLmdqrmvp/Q==}
3173 + engines: {node: '>= 4'}
3174 +
3175 + immer@11.1.18:
3176 + resolution: {integrity: sha512-EQyQtLiYW029lyoczMl/Hh4Xu7cDecSc58JRYpHyL4tIAu3eqd1yJzQX04d2BZHDkzFFvm6qJEJWOtfDSWAXbQ==}
3177 +
3178 + import-fresh@3.3.1:
3179 + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
3180 + engines: {node: '>=6'}
3181 +
3182 + imurmurhash@0.1.4:
3183 + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
3184 + engines: {node: '>=0.8.19'}
3185 +
3186 + inline-style-parser@0.2.7:
3187 + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
3188 +
3189 + internal-slot@1.1.0:
3190 + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
3191 + engines: {node: '>= 0.4'}
3192 +
3193 + internmap@2.0.3:
3194 + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
3195 + engines: {node: '>=12'}
3196 +
3197 + is-alphabetical@2.0.1:
3198 + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
3199 +
3200 + is-alphanumerical@2.0.1:
3201 + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
3202 +
3203 + is-array-buffer@3.0.5:
3204 + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
3205 + engines: {node: '>= 0.4'}
3206 +
3207 + is-async-function@2.1.1:
3208 + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
3209 + engines: {node: '>= 0.4'}
3210 +
3211 + is-bigint@1.1.0:
3212 + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
3213 + engines: {node: '>= 0.4'}
3214 +
3215 + is-boolean-object@1.2.2:
3216 + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
3217 + engines: {node: '>= 0.4'}
3218 +
3219 + is-bun-module@2.0.0:
3220 + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==}
3221 +
3222 + is-callable@1.2.7:
3223 + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
3224 + engines: {node: '>= 0.4'}
3225 +
3226 + is-core-module@2.16.2:
3227 + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==}
3228 + engines: {node: '>= 0.4'}
3229 +
3230 + is-data-view@1.0.2:
3231 + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==}
3232 + engines: {node: '>= 0.4'}
3233 +
3234 + is-date-object@1.1.0:
3235 + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
3236 + engines: {node: '>= 0.4'}
3237 +
3238 + is-decimal@2.0.1:
3239 + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
3240 +
3241 + is-document.all@1.0.0:
3242 + resolution: {integrity: sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==}
3243 + engines: {node: '>= 0.4'}
3244 +
3245 + is-extglob@2.1.1:
3246 + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
3247 + engines: {node: '>=0.10.0'}
3248 +
3249 + is-finalizationregistry@1.1.1:
3250 + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
3251 + engines: {node: '>= 0.4'}
3252 +
3253 + is-generator-function@1.1.2:
3254 + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==}
3255 + engines: {node: '>= 0.4'}
3256 +
3257 + is-glob@4.0.3:
3258 + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
3259 + engines: {node: '>=0.10.0'}
3260 +
3261 + is-hexadecimal@2.0.1:
3262 + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
3263 +
3264 + is-map@2.0.3:
3265 + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
3266 + engines: {node: '>= 0.4'}
3267 +
3268 + is-negative-zero@2.0.3:
3269 + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
3270 + engines: {node: '>= 0.4'}
3271 +
3272 + is-number-object@1.1.1:
3273 + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==}
3274 + engines: {node: '>= 0.4'}
3275 +
3276 + is-number@7.0.0:
3277 + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
3278 + engines: {node: '>=0.12.0'}
3279 +
3280 + is-plain-obj@4.1.0:
3281 + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
3282 + engines: {node: '>=12'}
3283 +
3284 + is-regex@1.2.1:
3285 + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
3286 + engines: {node: '>= 0.4'}
3287 +
3288 + is-set@2.0.3:
3289 + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
3290 + engines: {node: '>= 0.4'}
3291 +
3292 + is-shared-array-buffer@1.0.4:
3293 + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
3294 + engines: {node: '>= 0.4'}
3295 +
3296 + is-string@1.1.1:
3297 + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
3298 + engines: {node: '>= 0.4'}
3299 +
3300 + is-symbol@1.1.1:
3301 + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==}
3302 + engines: {node: '>= 0.4'}
3303 +
3304 + is-typed-array@1.1.15:
3305 + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
3306 + engines: {node: '>= 0.4'}
3307 +
3308 + is-weakmap@2.0.2:
3309 + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
3310 + engines: {node: '>= 0.4'}
3311 +
3312 + is-weakref@1.1.1:
3313 + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==}
3314 + engines: {node: '>= 0.4'}
3315 +
3316 + is-weakset@2.0.4:
3317 + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
3318 + engines: {node: '>= 0.4'}
3319 +
3320 + isarray@2.0.5:
3321 + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
3322 +
3323 + isexe@2.0.0:
3324 + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
3325 +
3326 + iterator.prototype@1.1.5:
3327 + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
3328 + engines: {node: '>= 0.4'}
3329 +
3330 + jiti@2.7.0:
3331 + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
3332 + hasBin: true
3333 +
3334 + jose@6.2.12:
3335 + resolution: {integrity: sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==}
3336 +
3337 + js-tokens@4.0.0:
3338 + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
3339 +
3340 + js-tokens@9.0.1:
3341 + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
3342 +
3343 + js-yaml@4.3.2:
3344 + resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==}
3345 + hasBin: true
3346 +
3347 + jsesc@3.1.0:
3348 + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
3349 + engines: {node: '>=6'}
3350 + hasBin: true
3351 +
3352 + json-bigint@1.0.0:
3353 + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==}
3354 +
3355 + json-buffer@3.0.1:
3356 + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
3357 +
3358 + json-schema-to-ts@3.1.1:
3359 + resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==}
3360 + engines: {node: '>=16'}
3361 +
3362 + json-schema-traverse@0.4.1:
3363 + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
3364 +
3365 + json-stable-stringify-without-jsonify@1.0.1:
3366 + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
3367 +
3368 + json5@1.0.2:
3369 + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
3370 + hasBin: true
3371 +
3372 + json5@2.2.3:
3373 + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
3374 + engines: {node: '>=6'}
3375 + hasBin: true
3376 +
3377 + jsx-ast-utils@3.3.5:
3378 + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
3379 + engines: {node: '>=4.0'}
3380 +
3381 + jwa@2.0.1:
3382 + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==}
3383 +
3384 + jws@4.0.1:
3385 + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==}
3386 +
3387 + keyv@4.5.4:
3388 + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
3389 +
3390 + kysely@0.29.5:
3391 + resolution: {integrity: sha512-ooa+eSbBNPTo3MycPEuW5jdrxQdQwdtB3LC3h43FiXQbIry5tR0C5lDG7eealK0E4D7XjrnOP5DIUg/LyjRMYQ==}
3392 + engines: {node: '>=22.0.0'}
3393 +
3394 + language-subtag-registry@0.3.23:
3395 + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==}
3396 +
3397 + language-tags@1.0.9:
3398 + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==}
3399 + engines: {node: '>=0.10'}
3400 +
3401 + levn@0.4.1:
3402 + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
3403 + engines: {node: '>= 0.8.0'}
3404 +
3405 + lightningcss-android-arm64@1.32.0:
3406 + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
3407 + engines: {node: '>= 12.0.0'}
3408 + cpu: [arm64]
3409 + os: [android]
3410 +
3411 + lightningcss-darwin-arm64@1.32.0:
3412 + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
3413 + engines: {node: '>= 12.0.0'}
3414 + cpu: [arm64]
3415 + os: [darwin]
3416 +
3417 + lightningcss-darwin-x64@1.32.0:
3418 + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
3419 + engines: {node: '>= 12.0.0'}
3420 + cpu: [x64]
3421 + os: [darwin]
3422 +
3423 + lightningcss-freebsd-x64@1.32.0:
3424 + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
3425 + engines: {node: '>= 12.0.0'}
3426 + cpu: [x64]
3427 + os: [freebsd]
3428 +
3429 + lightningcss-linux-arm-gnueabihf@1.32.0:
3430 + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
3431 + engines: {node: '>= 12.0.0'}
3432 + cpu: [arm]
3433 + os: [linux]
3434 +
3435 + lightningcss-linux-arm64-gnu@1.32.0:
3436 + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
3437 + engines: {node: '>= 12.0.0'}
3438 + cpu: [arm64]
3439 + os: [linux]
3440 + libc: [glibc]
3441 +
3442 + lightningcss-linux-arm64-musl@1.32.0:
3443 + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
3444 + engines: {node: '>= 12.0.0'}
3445 + cpu: [arm64]
3446 + os: [linux]
3447 + libc: [musl]
3448 +
3449 + lightningcss-linux-x64-gnu@1.32.0:
3450 + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
3451 + engines: {node: '>= 12.0.0'}
3452 + cpu: [x64]
3453 + os: [linux]
3454 + libc: [glibc]
3455 +
3456 + lightningcss-linux-x64-musl@1.32.0:
3457 + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
3458 + engines: {node: '>= 12.0.0'}
3459 + cpu: [x64]
3460 + os: [linux]
3461 + libc: [musl]
3462 +
3463 + lightningcss-win32-arm64-msvc@1.32.0:
3464 + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
3465 + engines: {node: '>= 12.0.0'}
3466 + cpu: [arm64]
3467 + os: [win32]
3468 +
3469 + lightningcss-win32-x64-msvc@1.32.0:
3470 + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
3471 + engines: {node: '>= 12.0.0'}
3472 + cpu: [x64]
3473 + os: [win32]
3474 +
3475 + lightningcss@1.32.0:
3476 + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
3477 + engines: {node: '>= 12.0.0'}
3478 +
3479 + locate-path@6.0.0:
3480 + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
3481 + engines: {node: '>=10'}
3482 +
3483 + lodash.merge@4.6.2:
3484 + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
3485 +
3486 + long@5.3.2:
3487 + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
3488 +
3489 + longest-streak@3.1.0:
3490 + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
3491 +
3492 + loose-envify@1.4.0:
3493 + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
3494 + hasBin: true
3495 +
3496 + loupe@3.2.1:
3497 + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
3498 +
3499 + lru-cache@5.1.1:
3500 + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
3501 +
3502 + lucide-react@1.42.0:
3503 + resolution: {integrity: sha512-b3jprplnoLS8n5etw1z8xODe3hF/yjKATrTitsrKrnjUhCef5BdDct6Ppv3zVvzFwmtfWgLO6XNM3C9fAD93ug==}
3504 + peerDependencies:
3505 + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
3506 +
3507 + magic-string@0.30.21:
3508 + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
3509 +
3510 + markdown-table@3.0.4:
3511 + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
3512 +
3513 + math-intrinsics@1.1.0:
3514 + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
3515 + engines: {node: '>= 0.4'}
3516 +
3517 + mdast-util-find-and-replace@3.0.2:
3518 + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
3519 +
3520 + mdast-util-from-markdown@2.0.3:
3521 + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==}
3522 +
3523 + mdast-util-gfm-autolink-literal@2.0.1:
3524 + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
3525 +
3526 + mdast-util-gfm-footnote@2.1.0:
3527 + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
3528 +
3529 + mdast-util-gfm-strikethrough@2.0.0:
3530 + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
3531 +
3532 + mdast-util-gfm-table@2.0.0:
3533 + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
3534 +
3535 + mdast-util-gfm-task-list-item@2.0.0:
3536 + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
3537 +
3538 + mdast-util-gfm@3.1.0:
3539 + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
3540 +
3541 + mdast-util-mdx-expression@2.0.1:
3542 + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
3543 +
3544 + mdast-util-mdx-jsx@3.2.0:
3545 + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==}
3546 +
3547 + mdast-util-mdxjs-esm@2.0.1:
3548 + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
3549 +
3550 + mdast-util-phrasing@4.1.0:
3551 + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
3552 +
3553 + mdast-util-to-hast@13.2.1:
3554 + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
3555 +
3556 + mdast-util-to-markdown@2.1.2:
3557 + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
3558 +
3559 + mdast-util-to-string@4.0.0:
3560 + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
3561 +
3562 + merge2@1.4.1:
3563 + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
3564 + engines: {node: '>= 8'}
3565 +
3566 + micromark-core-commonmark@2.0.3:
3567 + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
3568 +
3569 + micromark-extension-gfm-autolink-literal@2.1.0:
3570 + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
3571 +
3572 + micromark-extension-gfm-footnote@2.1.0:
3573 + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
3574 +
3575 + micromark-extension-gfm-strikethrough@2.1.0:
3576 + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
3577 +
3578 + micromark-extension-gfm-table@2.1.1:
3579 + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==}
3580 +
3581 + micromark-extension-gfm-tagfilter@2.0.0:
3582 + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
3583 +
3584 + micromark-extension-gfm-task-list-item@2.1.0:
3585 + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
3586 +
3587 + micromark-extension-gfm@3.0.0:
3588 + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
3589 +
3590 + micromark-factory-destination@2.0.1:
3591 + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
3592 +
3593 + micromark-factory-label@2.0.1:
3594 + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
3595 +
3596 + micromark-factory-space@2.0.1:
3597 + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
3598 +
3599 + micromark-factory-title@2.0.1:
3600 + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
3601 +
3602 + micromark-factory-whitespace@2.0.1:
3603 + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
3604 +
3605 + micromark-util-character@2.1.1:
3606 + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
3607 +
3608 + micromark-util-chunked@2.0.1:
3609 + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
3610 +
3611 + micromark-util-classify-character@2.0.1:
3612 + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
3613 +
3614 + micromark-util-combine-extensions@2.0.1:
3615 + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
3616 +
3617 + micromark-util-decode-numeric-character-reference@2.0.2:
3618 + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
3619 +
3620 + micromark-util-decode-string@2.0.1:
3621 + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
3622 +
3623 + micromark-util-encode@2.0.1:
3624 + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
3625 +
3626 + micromark-util-html-tag-name@2.0.1:
3627 + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
3628 +
3629 + micromark-util-normalize-identifier@2.0.1:
3630 + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
3631 +
3632 + micromark-util-resolve-all@2.0.1:
3633 + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
3634 +
3635 + micromark-util-sanitize-uri@2.0.1:
3636 + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
3637 +
3638 + micromark-util-subtokenize@2.1.0:
3639 + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
3640 +
3641 + micromark-util-symbol@2.0.1:
3642 + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
3643 +
3644 + micromark-util-types@2.0.2:
3645 + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
3646 +
3647 + micromark@4.0.2:
3648 + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
3649 +
3650 + micromatch@4.0.8:
3651 + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
3652 + engines: {node: '>=8.6'}
3653 +
3654 + minimatch@10.2.6:
3655 + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==}
3656 + engines: {node: 18 || 20 || >=22}
3657 +
3658 + minimatch@3.1.5:
3659 + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
3660 +
3661 + minimist@1.2.8:
3662 + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
3663 +
3664 + motion-dom@12.43.0:
3665 + resolution: {integrity: sha512-azKON4d9S65PEoFUiQTMTgPheEmzf2QngdRc50AKfJp9Q9mmcBVw22c8eMq9k8kxOFHdL7+WZY7N/5F/lwiDag==}
3666 +
3667 + motion-utils@12.39.0:
3668 + resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==}
3669 +
3670 + motion@12.43.0:
3671 + resolution: {integrity: sha512-BQgQbSa9Hn3/mtbib0MK53y6JSANa+YKUKlaYnWzAVDH424RYQ5LVpV3pNiWH00BA2z4ojsSdMzqT7g2FQwjuQ==}
3672 + peerDependencies:
3673 + '@emotion/is-prop-valid': '*'
3674 + react: ^18.0.0 || ^19.0.0
3675 + react-dom: ^18.0.0 || ^19.0.0
3676 + peerDependenciesMeta:
3677 + '@emotion/is-prop-valid':
3678 + optional: true
3679 + react:
3680 + optional: true
3681 + react-dom:
3682 + optional: true
3683 +
3684 + ms@2.1.3:
3685 + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
3686 +
3687 + nanoid@3.3.18:
3688 + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==}
3689 + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
3690 + hasBin: true
3691 +
3692 + nanostores@1.5.3:
3693 + resolution: {integrity: sha512-rQLB6eV4f2AW/n3L0JmwCROpaisYy9EDEADvEFSd1C/qG8hB6O5TPlh9A791JRbJr4CnMQBzptDcvD9OR1+6WA==}
3694 + engines: {node: ^20.0.0 || >=22.0.0}
3695 +
3696 + napi-postinstall@0.3.4:
3697 + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==}
3698 + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
3699 + hasBin: true
3700 +
3701 + natural-compare@1.4.0:
3702 + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
3703 +
3704 + next-themes@0.4.6:
3705 + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
3706 + peerDependencies:
3707 + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
3708 + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
3709 +
3710 + next@16.3.4:
3711 + resolution: {integrity: sha512-/Ztf6CeRH+ejEXUrYtqI4gkS66eFIHuSwqi60RgcpWKodxFZx2/dqVCMKBwILfAHXQ+F1b1vAudgj3mnxqtoIA==}
3712 + engines: {node: '>=20.9.0'}
3713 + hasBin: true
3714 + peerDependencies:
3715 + '@opentelemetry/api': ^1.1.0
3716 + '@playwright/test': ^1.51.1
3717 + babel-plugin-react-compiler: '*'
3718 + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
3719 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
3720 + sass: ^1.3.0
3721 + peerDependenciesMeta:
3722 + '@opentelemetry/api':
3723 + optional: true
3724 + '@playwright/test':
3725 + optional: true
3726 + babel-plugin-react-compiler:
3727 + optional: true
3728 + sass:
3729 + optional: true
3730 +
3731 + node-addon-api@8.9.2:
3732 + resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==}
3733 + engines: {node: ^18 || ^20 || >= 21}
3734 +
3735 + node-domexception@1.0.0:
3736 + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
3737 + engines: {node: '>=10.5.0'}
3738 + deprecated: Use your platform's native DOMException instead
3739 +
3740 + node-exports-info@1.6.2:
3741 + resolution: {integrity: sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==}
3742 + engines: {node: '>= 0.4'}
3743 +
3744 + node-fetch@3.3.2:
3745 + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
3746 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
3747 +
3748 + node-gyp-build@4.8.4:
3749 + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
3750 + hasBin: true
3751 +
3752 + node-releases@2.0.54:
3753 + resolution: {integrity: sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==}
3754 + engines: {node: '>=18'}
3755 +
3756 + object-assign@4.1.1:
3757 + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
3758 + engines: {node: '>=0.10.0'}
3759 +
3760 + object-inspect@1.13.4:
3761 + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
3762 + engines: {node: '>= 0.4'}
3763 +
3764 + object-keys@1.1.1:
3765 + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
3766 + engines: {node: '>= 0.4'}
3767 +
3768 + object.assign@4.1.7:
3769 + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
3770 + engines: {node: '>= 0.4'}
3771 +
3772 + object.entries@1.1.9:
3773 + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==}
3774 + engines: {node: '>= 0.4'}
3775 +
3776 + object.fromentries@2.0.8:
3777 + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
3778 + engines: {node: '>= 0.4'}
3779 +
3780 + object.groupby@1.0.3:
3781 + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==}
3782 + engines: {node: '>= 0.4'}
3783 +
3784 + object.values@1.2.1:
3785 + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==}
3786 + engines: {node: '>= 0.4'}
3787 +
3788 + oniguruma-parser@0.12.2:
3789 + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==}
3790 +
3791 + oniguruma-to-es@4.3.6:
3792 + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==}
3793 +
3794 + openai@7.10.0:
3795 + resolution: {integrity: sha512-sn9t2Kls7O52PwuF9BUTYNu4Gk/r0lXJyrgaNht4TNRlZFb3dJIGO0RciSgjARGCBRtWjySubAQFJttlzUvGQQ==}
3796 + engines: {node: '>=22.0.0'}
3797 + peerDependencies:
3798 + '@aws-sdk/credential-provider-node': '>=3.972.0 <4'
3799 + '@smithy/hash-node': '>=4.3.0 <5'
3800 + '@smithy/signature-v4': '>=5.4.0 <6'
3801 + undici: '>=5 <9'
3802 + ws: ^8.21.0
3803 + zod: ^3.25 || ^4.0
3804 + peerDependenciesMeta:
3805 + '@aws-sdk/credential-provider-node':
3806 + optional: true
3807 + '@smithy/hash-node':
3808 + optional: true
3809 + '@smithy/signature-v4':
3810 + optional: true
3811 + undici:
3812 + optional: true
3813 + ws:
3814 + optional: true
3815 + zod:
3816 + optional: true
3817 +
3818 + optionator@0.9.4:
3819 + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
3820 + engines: {node: '>= 0.8.0'}
3821 +
3822 + own-keys@1.0.2:
3823 + resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==}
3824 + engines: {node: '>= 0.4'}
3825 +
3826 + p-limit@3.1.0:
3827 + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
3828 + engines: {node: '>=10'}
3829 +
3830 + p-locate@5.0.0:
3831 + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
3832 + engines: {node: '>=10'}
3833 +
3834 + p-retry@4.6.2:
3835 + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==}
3836 + engines: {node: '>=8'}
3837 +
3838 + parent-module@1.0.1:
3839 + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
3840 + engines: {node: '>=6'}
3841 +
3842 + parse-entities@4.0.2:
3843 + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
3844 +
3845 + parse5@7.3.0:
3846 + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
3847 +
3848 + path-exists@4.0.0:
3849 + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
3850 + engines: {node: '>=8'}
3851 +
3852 + path-key@3.1.1:
3853 + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
3854 + engines: {node: '>=8'}
3855 +
3856 + path-parse@1.0.7:
3857 + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
3858 +
3859 + pathe@2.0.3:
3860 + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
3861 +
3862 + pathval@2.0.1:
3863 + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
3864 + engines: {node: '>= 14.16'}
3865 +
3866 + pg-cloudflare@1.4.0:
3867 + resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==}
3868 +
3869 + pg-connection-string@2.14.0:
3870 + resolution: {integrity: sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==}
3871 +
3872 + pg-int8@1.0.1:
3873 + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
3874 + engines: {node: '>=4.0.0'}
3875 +
3876 + pg-pool@3.14.0:
3877 + resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==}
3878 + peerDependencies:
3879 + pg: '>=8.0'
3880 +
3881 + pg-protocol@1.16.0:
3882 + resolution: {integrity: sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==}
3883 +
3884 + pg-types@2.2.0:
3885 + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
3886 + engines: {node: '>=4'}
3887 +
3888 + pg@8.23.0:
3889 + resolution: {integrity: sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==}
3890 + engines: {node: '>= 16.0.0'}
3891 + peerDependencies:
3892 + pg-native: '>=3.0.1'
3893 + peerDependenciesMeta:
3894 + pg-native:
3895 + optional: true
3896 +
3897 + pgpass@1.0.5:
3898 + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
3899 +
3900 + picocolors@1.1.1:
3901 + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
3902 +
3903 + picomatch@2.3.2:
3904 + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
3905 + engines: {node: '>=8.6'}
3906 +
3907 + picomatch@4.0.7:
3908 + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==}
3909 + engines: {node: '>=12'}
3910 +
3911 + playwright-core@1.63.0:
3912 + resolution: {integrity: sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==}
3913 + engines: {node: '>=20'}
3914 + hasBin: true
3915 +
3916 + playwright@1.63.0:
3917 + resolution: {integrity: sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==}
3918 + engines: {node: '>=20'}
3919 + hasBin: true
3920 +
3921 + possible-typed-array-names@1.1.0:
3922 + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
3923 + engines: {node: '>= 0.4'}
3924 +
3925 + postal-mime@2.7.5:
3926 + resolution: {integrity: sha512-GNEXKvWFQnbgO5NlrGzVa0FmWzBZ24PersAWErttSg1Hjpf0ATxTwS5DOMGaOpTG6bUh5cTr7xi0jAD942wCJA==}
3927 +
3928 + postcss@8.5.23:
3929 + resolution: {integrity: sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==}
3930 + engines: {node: ^10 || ^12 || >=14}
3931 +
3932 + postcss@8.5.28:
3933 + resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==}
3934 + engines: {node: ^10 || ^12 || >=14}
3935 +
3936 + postgres-array@2.0.0:
3937 + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
3938 + engines: {node: '>=4'}
3939 +
3940 + postgres-bytea@1.0.1:
3941 + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==}
3942 + engines: {node: '>=0.10.0'}
3943 +
3944 + postgres-date@1.0.7:
3945 + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
3946 + engines: {node: '>=0.10.0'}
3947 +
3948 + postgres-interval@1.2.0:
3949 + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
3950 + engines: {node: '>=0.10.0'}
3951 +
3952 + prelude-ls@1.2.1:
3953 + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
3954 + engines: {node: '>= 0.8.0'}
3955 +
3956 + prop-types@15.8.1:
3957 + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
3958 +
3959 + property-information@7.2.0:
3960 + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==}
3961 +
3962 + protobufjs@7.6.6:
3963 + resolution: {integrity: sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==}
3964 + engines: {node: '>=12.0.0'}
3965 +
3966 + punycode@2.3.1:
3967 + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
3968 + engines: {node: '>=6'}
3969 +
3970 + queue-microtask@1.2.3:
3971 + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
3972 +
3973 + react-dom@19.2.8:
3974 + resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==}
3975 + peerDependencies:
3976 + react: ^19.2.8
3977 +
3978 + react-is@16.13.1:
3979 + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
3980 +
3981 + react-markdown@10.1.0:
3982 + resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==}
3983 + peerDependencies:
3984 + '@types/react': '>=18'
3985 + react: '>=18'
3986 +
3987 + react-redux@9.3.0:
3988 + resolution: {integrity: sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==}
3989 + peerDependencies:
3990 + '@types/react': ^18.2.25 || ^19
3991 + react: ^18.0 || ^19
3992 + redux: ^5.0.0
3993 + peerDependenciesMeta:
3994 + '@types/react':
3995 + optional: true
3996 + redux:
3997 + optional: true
3998 +
3999 + react-remove-scroll-bar@2.3.8:
4000 + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
4001 + engines: {node: '>=10'}
4002 + peerDependencies:
4003 + '@types/react': '*'
4004 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
4005 + peerDependenciesMeta:
4006 + '@types/react':
4007 + optional: true
4008 +
4009 + react-remove-scroll@2.7.2:
4010 + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==}
4011 + engines: {node: '>=10'}
4012 + peerDependencies:
4013 + '@types/react': '*'
4014 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
4015 + peerDependenciesMeta:
4016 + '@types/react':
4017 + optional: true
4018 +
4019 + react-style-singleton@2.2.3:
4020 + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
4021 + engines: {node: '>=10'}
4022 + peerDependencies:
4023 + '@types/react': '*'
4024 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
4025 + peerDependenciesMeta:
4026 + '@types/react':
4027 + optional: true
4028 +
4029 + react@19.2.8:
4030 + resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==}
4031 + engines: {node: '>=0.10.0'}
4032 +
4033 + recharts@3.10.1:
4034 + resolution: {integrity: sha512-QXFrvt6IVcw7eeZCoyXTwkIJAX3Dv1nyVhMicXJ47GsGDDpcN8z6o644DibE9XjpBTThtsomLKnTV6lc+cVFUA==}
4035 + engines: {node: '>=18'}
4036 + peerDependencies:
4037 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
4038 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
4039 + react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
4040 +
4041 + redux-thunk@3.1.0:
4042 + resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
4043 + peerDependencies:
4044 + redux: ^5.0.0
4045 +
4046 + redux@5.0.1:
4047 + resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
4048 +
4049 + reflect.getprototypeof@1.0.10:
4050 + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
4051 + engines: {node: '>= 0.4'}
4052 +
4053 + regex-recursion@6.0.2:
4054 + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
4055 +
4056 + regex-utilities@2.3.0:
4057 + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
4058 +
4059 + regex@6.1.0:
4060 + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
4061 +
4062 + regexp.prototype.flags@1.5.4:
4063 + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
4064 + engines: {node: '>= 0.4'}
4065 +
4066 + rehype-raw@7.0.0:
4067 + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
4068 +
4069 + remark-gfm@4.0.1:
4070 + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
4071 +
4072 + remark-parse@11.0.0:
4073 + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
4074 +
4075 + remark-rehype@11.1.2:
4076 + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
4077 +
4078 + remark-stringify@11.0.0:
4079 + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
4080 +
4081 + reselect@5.2.0:
4082 + resolution: {integrity: sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==}
4083 +
4084 + resend@6.26.0:
4085 + resolution: {integrity: sha512-vkrULozV5nGF8o7tyun/t0+qFgtPpn+cyRhVqeorhOsPUNDiSc/9p/pn8AprdHqJpYaTvftpnQgWurW++FkCdw==}
4086 + engines: {node: '>=20'}
4087 + peerDependencies:
4088 + '@react-email/render': '*'
4089 + peerDependenciesMeta:
4090 + '@react-email/render':
4091 + optional: true
4092 +
4093 + resolve-from@4.0.0:
4094 + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
4095 + engines: {node: '>=4'}
4096 +
4097 + resolve-pkg-maps@1.0.0:
4098 + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
4099 +
4100 + resolve@2.0.0-next.7:
4101 + resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==}
4102 + engines: {node: '>= 0.4'}
4103 + hasBin: true
4104 +
4105 + retry@0.13.1:
4106 + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
4107 + engines: {node: '>= 4'}
4108 +
4109 + reusify@1.1.0:
4110 + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
4111 + engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
4112 +
4113 + rollup@4.63.1:
4114 + resolution: {integrity: sha512-3Df9jsstwhccuEfmAMi9l8XUh/GOkVObmFTU7CCVBysEbcOZLl84jCtaAZMcPiMz2EGKsATzQcU+Xr3n/wU6cg==}
4115 + engines: {node: '>=18.0.0', npm: '>=8.0.0'}
4116 + hasBin: true
4117 +
4118 + rou3@0.9.2:
4119 + resolution: {integrity: sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ==}
4120 +
4121 + run-parallel@1.2.0:
4122 + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
4123 +
4124 + safe-array-concat@1.1.4:
4125 + resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==}
4126 + engines: {node: '>=0.4'}
4127 +
4128 + safe-buffer@5.2.1:
4129 + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
4130 +
4131 + safe-push-apply@1.0.0:
4132 + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
4133 + engines: {node: '>= 0.4'}
4134 +
4135 + safe-regex-test@1.1.0:
4136 + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
4137 + engines: {node: '>= 0.4'}
4138 +
4139 + scheduler@0.27.0:
4140 + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
4141 +
4142 + semver@6.3.1:
4143 + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
4144 + hasBin: true
4145 +
4146 + semver@7.8.5:
4147 + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
4148 + engines: {node: '>=10'}
4149 + hasBin: true
4150 +
4151 + server-only@0.0.1:
4152 + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==}
4153 +
4154 + set-cookie-parser@3.1.2:
4155 + resolution: {integrity: sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==}
4156 +
4157 + set-function-length@1.2.2:
4158 + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
4159 + engines: {node: '>= 0.4'}
4160 +
4161 + set-function-name@2.0.2:
4162 + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
4163 + engines: {node: '>= 0.4'}
4164 +
4165 + set-proto@1.0.0:
4166 + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
4167 + engines: {node: '>= 0.4'}
4168 +
4169 + sharp@0.35.4:
4170 + resolution: {integrity: sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==}
4171 + engines: {node: '>=20.9.0'}
4172 + peerDependencies:
4173 + '@types/node': '*'
4174 + peerDependenciesMeta:
4175 + '@types/node':
4176 + optional: true
4177 +
4178 + shebang-command@2.0.0:
4179 + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
4180 + engines: {node: '>=8'}
4181 +
4182 + shebang-regex@3.0.0:
4183 + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
4184 + engines: {node: '>=8'}
4185 +
4186 + shiki@4.4.3:
4187 + resolution: {integrity: sha512-Mb/GvXPHBAXdgGIcnfU5L3ldpn1XcxrGkPHwqgRx17/I2XRfqlFKk2vGkHWINn1kdXvzJZeuO3is6I9KLPFm0g==}
4188 + engines: {node: '>=20'}
4189 +
4190 + side-channel-list@1.0.1:
4191 + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==}
4192 + engines: {node: '>= 0.4'}
4193 +
4194 + side-channel-map@1.0.1:
4195 + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
4196 + engines: {node: '>= 0.4'}
4197 +
4198 + side-channel-weakmap@1.0.2:
4199 + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
4200 + engines: {node: '>= 0.4'}
4201 +
4202 + side-channel@1.1.1:
4203 + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==}
4204 + engines: {node: '>= 0.4'}
4205 +
4206 + siginfo@2.0.0:
4207 + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
4208 +
4209 + source-map-js@1.2.1:
4210 + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
4211 + engines: {node: '>=0.10.0'}
4212 +
4213 + source-map-support@0.5.21:
4214 + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
4215 +
4216 + source-map@0.6.1:
4217 + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
4218 + engines: {node: '>=0.10.0'}
4219 +
4220 + space-separated-tokens@2.0.2:
4221 + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
4222 +
4223 + split2@4.2.0:
4224 + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
4225 + engines: {node: '>= 10.x'}
4226 +
4227 + stable-hash@0.0.5:
4228 + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==}
4229 +
4230 + stackback@0.0.2:
4231 + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
4232 +
4233 + standardwebhooks@1.0.0:
4234 + resolution: {integrity: sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==}
4235 +
4236 + standardwebhooks@1.1.1:
4237 + resolution: {integrity: sha512-bCbX9ZEyFkWPsRz7Bl3NuQUJohmwGSev/yhr7vhaGPlc4AfIrspIRa6cPTBuI1ItmrTDJ4d/S2hCsfe4+vQGnQ==}
4238 +
4239 + std-env@3.10.0:
4240 + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
4241 +
4242 + stop-iteration-iterator@1.1.0:
4243 + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
4244 + engines: {node: '>= 0.4'}
4245 +
4246 + string.prototype.includes@2.0.1:
4247 + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==}
4248 + engines: {node: '>= 0.4'}
4249 +
4250 + string.prototype.matchall@4.1.0:
4251 + resolution: {integrity: sha512-tHNHTxInrYLCga9O9YGxWA3G9/nnzQw8UGAyqGx3Ar1pSTTzIuM4woFSq4SowkXCjJIwq5sIiQvEfRI9tCH1qQ==}
4252 + engines: {node: '>= 0.4'}
4253 +
4254 + string.prototype.repeat@1.0.0:
4255 + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==}
4256 +
4257 + string.prototype.trim@1.2.11:
4258 + resolution: {integrity: sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==}
4259 + engines: {node: '>= 0.4'}
4260 +
4261 + string.prototype.trimend@1.0.10:
4262 + resolution: {integrity: sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==}
4263 + engines: {node: '>= 0.4'}
4264 +
4265 + string.prototype.trimstart@1.0.8:
4266 + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
4267 + engines: {node: '>= 0.4'}
4268 +
4269 + stringify-entities@4.0.4:
4270 + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
4271 +
4272 + strip-bom@3.0.0:
4273 + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
4274 + engines: {node: '>=4'}
4275 +
4276 + strip-json-comments@3.1.1:
4277 + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
4278 + engines: {node: '>=8'}
4279 +
4280 + strip-literal@3.1.0:
4281 + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
4282 +
4283 + style-to-js@1.1.21:
4284 + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
4285 +
4286 + style-to-object@1.0.14:
4287 + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==}
4288 +
4289 + styled-jsx@5.1.6:
4290 + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
4291 + engines: {node: '>= 12.0.0'}
4292 + peerDependencies:
4293 + '@babel/core': '*'
4294 + babel-plugin-macros: '*'
4295 + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
4296 + peerDependenciesMeta:
4297 + '@babel/core':
4298 + optional: true
4299 + babel-plugin-macros:
4300 + optional: true
4301 +
4302 + supports-color@7.2.0:
4303 + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
4304 + engines: {node: '>=8'}
4305 +
4306 + supports-preserve-symlinks-flag@1.0.0:
4307 + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
4308 + engines: {node: '>= 0.4'}
4309 +
4310 + swr@2.5.1:
4311 + resolution: {integrity: sha512-BRw55e8r0B7SpDN20CAzoQAHl7y1yP7/Zt7oqUjMv0vSt2u2Xnkm88Ws+VypbV9BXHQVuSuyVq7zMjO16wSExw==}
4312 + peerDependencies:
4313 + react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
4314 +
4315 + tailwind-merge@3.6.0:
4316 + resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==}
4317 +
4318 + tailwindcss@4.3.3:
4319 + resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==}
4320 +
4321 + tapable@2.3.3:
4322 + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
4323 + engines: {node: '>=6'}
4324 +
4325 + tiny-invariant@1.3.3:
4326 + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
4327 +
4328 + tinybench@2.9.0:
4329 + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
4330 +
4331 + tinyexec@0.3.2:
4332 + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
4333 +
4334 + tinyglobby@0.2.17:
4335 + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
4336 + engines: {node: '>=12.0.0'}
4337 +
4338 + tinypool@1.1.1:
4339 + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==}
4340 + engines: {node: ^18.0.0 || >=20.0.0}
4341 +
4342 + tinyrainbow@2.0.0:
4343 + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
4344 + engines: {node: '>=14.0.0'}
4345 +
4346 + tinyspy@4.0.6:
4347 + resolution: {integrity: sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg==}
4348 + engines: {node: '>=14.0.0'}
4349 +
4350 + to-regex-range@5.0.1:
4351 + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
4352 + engines: {node: '>=8.0'}
4353 +
4354 + trim-lines@3.0.1:
4355 + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
4356 +
4357 + trough@2.2.0:
4358 + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
4359 +
4360 + ts-algebra@2.0.0:
4361 + resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==}
4362 +
4363 + ts-api-utils@2.5.0:
4364 + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==}
4365 + engines: {node: '>=18.12'}
4366 + peerDependencies:
4367 + typescript: '>=4.8.4'
4368 +
4369 + tsconfig-paths@3.15.0:
4370 + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
4371 +
4372 + tslib@2.8.1:
4373 + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
4374 +
4375 + tsx@4.23.13:
4376 + resolution: {integrity: sha512-BL5MGkRln6aDYhb0xbQlEAGw743BaZYWdbWtdJOBriYJboKgUUYCadFp2/FpBBZquBC/ezNBn7wMMPx7FDZUDw==}
4377 + engines: {node: '>=18.0.0'}
4378 + hasBin: true
4379 +
4380 + type-check@0.4.0:
4381 + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
4382 + engines: {node: '>= 0.8.0'}
4383 +
4384 + typed-array-buffer@1.0.3:
4385 + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
4386 + engines: {node: '>= 0.4'}
4387 +
4388 + typed-array-byte-length@1.0.3:
4389 + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==}
4390 + engines: {node: '>= 0.4'}
4391 +
4392 + typed-array-byte-offset@1.0.4:
4393 + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==}
4394 + engines: {node: '>= 0.4'}
4395 +
4396 + typed-array-length@1.0.8:
4397 + resolution: {integrity: sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==}
4398 + engines: {node: '>= 0.4'}
4399 +
4400 + typescript-eslint@8.69.0:
4401 + resolution: {integrity: sha512-B3MltX0VqjUBNEe3b3sSuiRbfa6XrfHFtBiPamjT5AsW/dfq+y+bc0wyuS9DxAS1LyzCxRp2+rxzpLUvqM2BvA==}
4402 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
4403 + peerDependencies:
4404 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
4405 + typescript: '>=4.8.4 <6.1.0'
4406 +
4407 + typescript@5.9.3:
4408 + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
4409 + engines: {node: '>=14.17'}
4410 + hasBin: true
4411 +
4412 + unbox-primitive@1.1.0:
4413 + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
4414 + engines: {node: '>= 0.4'}
4415 +
4416 + undici-types@7.18.2:
4417 + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
4418 +
4419 + unified@11.0.5:
4420 + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
4421 +
4422 + unist-util-is@6.0.1:
4423 + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
4424 +
4425 + unist-util-position@5.0.0:
4426 + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
4427 +
4428 + unist-util-stringify-position@4.0.0:
4429 + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
4430 +
4431 + unist-util-visit-parents@6.0.2:
4432 + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
4433 +
4434 + unist-util-visit@5.1.0:
4435 + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
4436 +
4437 + unrs-resolver@1.12.2:
4438 + resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==}
4439 +
4440 + update-browserslist-db@1.3.2:
4441 + resolution: {integrity: sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==}
4442 + hasBin: true
4443 + peerDependencies:
4444 + browserslist: '>= 4.21.0'
4445 +
4446 + uri-js@4.4.1:
4447 + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
4448 +
4449 + use-callback-ref@1.3.3:
4450 + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
4451 + engines: {node: '>=10'}
4452 + peerDependencies:
4453 + '@types/react': '*'
4454 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
4455 + peerDependenciesMeta:
4456 + '@types/react':
4457 + optional: true
4458 +
4459 + use-sidecar@1.1.3:
4460 + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
4461 + engines: {node: '>=10'}
4462 + peerDependencies:
4463 + '@types/react': '*'
4464 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
4465 + peerDependenciesMeta:
4466 + '@types/react':
4467 + optional: true
4468 +
4469 + use-sync-external-store@1.6.0:
4470 + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
4471 + peerDependencies:
4472 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
4473 +
4474 + vfile-location@5.0.3:
4475 + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
4476 +
4477 + vfile-message@4.0.3:
4478 + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
4479 +
4480 + vfile@6.0.3:
4481 + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
4482 +
4483 + victory-vendor@37.3.6:
4484 + resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==}
4485 +
4486 + vite-node@3.2.4:
4487 + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==}
4488 + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
4489 + hasBin: true
4490 +
4491 + vite@7.3.6:
4492 + resolution: {integrity: sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==}
4493 + engines: {node: ^20.19.0 || >=22.12.0}
4494 + hasBin: true
4495 + peerDependencies:
4496 + '@types/node': ^20.19.0 || >=22.12.0
4497 + jiti: '>=1.21.0'
4498 + less: ^4.0.0
4499 + lightningcss: ^1.21.0
4500 + sass: ^1.70.0
4501 + sass-embedded: ^1.70.0
4502 + stylus: '>=0.54.8'
4503 + sugarss: ^5.0.0
4504 + terser: ^5.16.0
4505 + tsx: ^4.8.1
4506 + yaml: ^2.4.2
4507 + peerDependenciesMeta:
4508 + '@types/node':
4509 + optional: true
4510 + jiti:
4511 + optional: true
4512 + less:
4513 + optional: true
4514 + lightningcss:
4515 + optional: true
4516 + sass:
4517 + optional: true
4518 + sass-embedded:
4519 + optional: true
4520 + stylus:
4521 + optional: true
4522 + sugarss:
4523 + optional: true
4524 + terser:
4525 + optional: true
4526 + tsx:
4527 + optional: true
4528 + yaml:
4529 + optional: true
4530 +
4531 + vitest@3.2.7:
4532 + resolution: {integrity: sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==}
4533 + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
4534 + hasBin: true
4535 + peerDependencies:
4536 + '@edge-runtime/vm': '*'
4537 + '@types/debug': ^4.1.12
4538 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
4539 + '@vitest/browser': 3.2.7
4540 + '@vitest/ui': 3.2.7
4541 + happy-dom: '*'
4542 + jsdom: '*'
4543 + peerDependenciesMeta:
4544 + '@edge-runtime/vm':
4545 + optional: true
4546 + '@types/debug':
4547 + optional: true
4548 + '@types/node':
4549 + optional: true
4550 + '@vitest/browser':
4551 + optional: true
4552 + '@vitest/ui':
4553 + optional: true
4554 + happy-dom:
4555 + optional: true
4556 + jsdom:
4557 + optional: true
4558 +
4559 + web-namespaces@2.0.1:
4560 + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
4561 +
4562 + web-streams-polyfill@3.3.3:
4563 + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
4564 + engines: {node: '>= 8'}
4565 +
4566 + which-boxed-primitive@1.1.1:
4567 + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
4568 + engines: {node: '>= 0.4'}
4569 +
4570 + which-builtin-type@1.2.1:
4571 + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==}
4572 + engines: {node: '>= 0.4'}
4573 +
4574 + which-collection@1.0.2:
4575 + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
4576 + engines: {node: '>= 0.4'}
4577 +
4578 + which-typed-array@1.1.22:
4579 + resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==}
4580 + engines: {node: '>= 0.4'}
4581 +
4582 + which@2.0.2:
4583 + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
4584 + engines: {node: '>= 8'}
4585 + hasBin: true
4586 +
4587 + why-is-node-running@2.3.0:
4588 + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
4589 + engines: {node: '>=8'}
4590 + hasBin: true
4591 +
4592 + word-wrap@1.2.5:
4593 + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
4594 + engines: {node: '>=0.10.0'}
4595 +
4596 + ws@8.21.3:
4597 + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==}
4598 + engines: {node: '>=10.0.0'}
4599 + peerDependencies:
4600 + bufferutil: ^4.0.1
4601 + utf-8-validate: '>=5.0.2'
4602 + peerDependenciesMeta:
4603 + bufferutil:
4604 + optional: true
4605 + utf-8-validate:
4606 + optional: true
4607 +
4608 + xtend@4.0.2:
4609 + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
4610 + engines: {node: '>=0.4'}
4611 +
4612 + yallist@3.1.1:
4613 + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
4614 +
4615 + yocto-queue@0.1.0:
4616 + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
4617 + engines: {node: '>=10'}
4618 +
4619 + zod-validation-error@4.0.2:
4620 + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==}
4621 + engines: {node: '>=18.0.0'}
4622 + peerDependencies:
4623 + zod: ^3.25.0 || ^4.0.0
4624 +
4625 + zod@4.5.4:
4626 + resolution: {integrity: sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==}
4627 +
4628 + zwitch@2.0.4:
4629 + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
4630 +
4631 +snapshots:
4632 +
4633 + '@alloc/quick-lru@5.3.0': {}
4634 +
4635 + '@anthropic-ai/sdk@0.124.0(zod@4.5.4)':
4636 + dependencies:
4637 + json-schema-to-ts: 3.1.1
4638 + standardwebhooks: 1.1.1
4639 + optionalDependencies:
4640 + zod: 4.5.4
4641 +
4642 + '@babel/code-frame@7.29.7':
4643 + dependencies:
4644 + '@babel/helper-validator-identifier': 7.29.7
4645 + js-tokens: 4.0.0
4646 + picocolors: 1.1.1
4647 +
4648 + '@babel/compat-data@7.29.7': {}
4649 +
4650 + '@babel/core@7.29.7':
4651 + dependencies:
4652 + '@babel/code-frame': 7.29.7
4653 + '@babel/generator': 7.29.8
4654 + '@babel/helper-compilation-targets': 7.29.7
4655 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7)
4656 + '@babel/helpers': 7.29.7
4657 + '@babel/parser': 7.29.8
4658 + '@babel/template': 7.29.7
4659 + '@babel/traverse': 7.29.8
4660 + '@babel/types': 7.29.8
4661 + '@jridgewell/remapping': 2.3.5
4662 + convert-source-map: 2.0.0
4663 + debug: 4.4.3
4664 + gensync: 1.0.0-beta.2
4665 + json5: 2.2.3
4666 + semver: 6.3.1
4667 + transitivePeerDependencies:
4668 + - supports-color
4669 +
4670 + '@babel/generator@7.29.8':
4671 + dependencies:
4672 + '@babel/parser': 7.29.8
4673 + '@babel/types': 7.29.8
4674 + '@jridgewell/gen-mapping': 0.3.13
4675 + '@jridgewell/trace-mapping': 0.3.31
4676 + jsesc: 3.1.0
4677 +
4678 + '@babel/helper-compilation-targets@7.29.7':
4679 + dependencies:
4680 + '@babel/compat-data': 7.29.7
4681 + '@babel/helper-validator-option': 7.29.7
4682 + browserslist: 4.28.9
4683 + lru-cache: 5.1.1
4684 + semver: 6.3.1
4685 +
4686 + '@babel/helper-globals@7.29.7': {}
4687 +
4688 + '@babel/helper-module-imports@7.29.7':
4689 + dependencies:
4690 + '@babel/traverse': 7.29.8
4691 + '@babel/types': 7.29.8
4692 + transitivePeerDependencies:
4693 + - supports-color
4694 +
4695 + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)':
4696 + dependencies:
4697 + '@babel/core': 7.29.7
4698 + '@babel/helper-module-imports': 7.29.7
4699 + '@babel/helper-validator-identifier': 7.29.7
4700 + '@babel/traverse': 7.29.8
4701 + transitivePeerDependencies:
4702 + - supports-color
4703 +
4704 + '@babel/helper-string-parser@7.29.7': {}
4705 +
4706 + '@babel/helper-validator-identifier@7.29.7': {}
4707 +
4708 + '@babel/helper-validator-option@7.29.7': {}
4709 +
4710 + '@babel/helpers@7.29.7':
4711 + dependencies:
4712 + '@babel/template': 7.29.7
4713 + '@babel/types': 7.29.8
4714 +
4715 + '@babel/parser@7.29.8':
4716 + dependencies:
4717 + '@babel/types': 7.29.8
4718 +
4719 + '@babel/runtime@7.29.7': {}
4720 +
4721 + '@babel/template@7.29.7':
4722 + dependencies:
4723 + '@babel/code-frame': 7.29.7
4724 + '@babel/parser': 7.29.8
4725 + '@babel/types': 7.29.8
4726 +
4727 + '@babel/traverse@7.29.8':
4728 + dependencies:
4729 + '@babel/code-frame': 7.29.7
4730 + '@babel/generator': 7.29.8
4731 + '@babel/helper-globals': 7.29.7
4732 + '@babel/parser': 7.29.8
4733 + '@babel/template': 7.29.7
4734 + '@babel/types': 7.29.8
4735 + debug: 4.4.3
4736 + transitivePeerDependencies:
4737 + - supports-color
4738 +
4739 + '@babel/types@7.29.8':
4740 + dependencies:
4741 + '@babel/helper-string-parser': 7.29.7
4742 + '@babel/helper-validator-identifier': 7.29.7
4743 +
4744 + '@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3)':
4745 + dependencies:
4746 + '@better-auth/utils': 0.4.2
4747 + '@better-fetch/fetch': 1.3.1
4748 + '@opentelemetry/semantic-conventions': 1.43.0
4749 + '@standard-schema/spec': 1.1.0
4750 + better-call: 1.4.0(zod@4.5.4)
4751 + jose: 6.2.12
4752 + kysely: 0.29.5
4753 + nanostores: 1.5.3
4754 + zod: 4.5.4
4755 +
4756 + '@better-auth/drizzle-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@types/pg@8.23.1)(kysely@0.29.5)(pg@8.23.0))':
4757 + dependencies:
4758 + '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3)
4759 + '@better-auth/utils': 0.4.2
4760 + optionalDependencies:
4761 + drizzle-orm: 0.45.2(@types/pg@8.23.1)(kysely@0.29.5)(pg@8.23.0)
4762 +
4763 + '@better-auth/kysely-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)(kysely@0.29.5)':
4764 + dependencies:
4765 + '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3)
4766 + '@better-auth/utils': 0.4.2
4767 + optionalDependencies:
4768 + kysely: 0.29.5
4769 +
4770 + '@better-auth/memory-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)':
4771 + dependencies:
4772 + '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3)
4773 + '@better-auth/utils': 0.4.2
4774 +
4775 + '@better-auth/mongo-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)':
4776 + dependencies:
4777 + '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3)
4778 + '@better-auth/utils': 0.4.2
4779 +
4780 + '@better-auth/prisma-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)':
4781 + dependencies:
4782 + '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3)
4783 + '@better-auth/utils': 0.4.2
4784 +
4785 + '@better-auth/telemetry@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)':
4786 + dependencies:
4787 + '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3)
4788 + '@better-auth/utils': 0.4.2
4789 + '@better-fetch/fetch': 1.3.1
4790 +
4791 + '@better-auth/utils@0.4.2':
4792 + dependencies:
4793 + '@noble/hashes': 2.4.0
4794 +
4795 + '@better-auth/utils@0.5.0':
4796 + dependencies:
4797 + '@noble/hashes': 2.4.0
4798 +
4799 + '@better-fetch/fetch@1.3.1': {}
4800 +
4801 + '@drizzle-team/brocli@0.10.2': {}
4802 +
4803 + '@emnapi/core@1.10.0':
4804 + dependencies:
4805 + '@emnapi/wasi-threads': 1.2.1
4806 + tslib: 2.8.1
4807 + optional: true
4808 +
4809 + '@emnapi/runtime@1.10.0':
4810 + dependencies:
4811 + tslib: 2.8.1
4812 + optional: true
4813 +
4814 + '@emnapi/runtime@1.11.3':
4815 + dependencies:
4816 + tslib: 2.8.1
4817 + optional: true
4818 +
4819 + '@emnapi/wasi-threads@1.2.1':
4820 + dependencies:
4821 + tslib: 2.8.1
4822 + optional: true
4823 +
4824 + '@epic-web/invariant@1.0.0': {}
4825 +
4826 + '@esbuild-kit/core-utils@3.3.2':
4827 + dependencies:
4828 + esbuild: 0.18.20
4829 + source-map-support: 0.5.21
4830 +
4831 + '@esbuild-kit/esm-loader@2.6.5':
4832 + dependencies:
4833 + '@esbuild-kit/core-utils': 3.3.2
4834 + get-tsconfig: 4.14.3
4835 +
4836 + '@esbuild/aix-ppc64@0.25.12':
4837 + optional: true
4838 +
4839 + '@esbuild/aix-ppc64@0.28.2':
4840 + optional: true
4841 +
4842 + '@esbuild/android-arm64@0.18.20':
4843 + optional: true
4844 +
4845 + '@esbuild/android-arm64@0.25.12':
4846 + optional: true
4847 +
4848 + '@esbuild/android-arm64@0.28.2':
4849 + optional: true
4850 +
4851 + '@esbuild/android-arm@0.18.20':
4852 + optional: true
4853 +
4854 + '@esbuild/android-arm@0.25.12':
4855 + optional: true
4856 +
4857 + '@esbuild/android-arm@0.28.2':
4858 + optional: true
4859 +
4860 + '@esbuild/android-x64@0.18.20':
4861 + optional: true
4862 +
4863 + '@esbuild/android-x64@0.25.12':
4864 + optional: true
4865 +
4866 + '@esbuild/android-x64@0.28.2':
4867 + optional: true
4868 +
4869 + '@esbuild/darwin-arm64@0.18.20':
4870 + optional: true
4871 +
4872 + '@esbuild/darwin-arm64@0.25.12':
4873 + optional: true
4874 +
4875 + '@esbuild/darwin-arm64@0.28.2':
4876 + optional: true
4877 +
4878 + '@esbuild/darwin-x64@0.18.20':
4879 + optional: true
4880 +
4881 + '@esbuild/darwin-x64@0.25.12':
4882 + optional: true
4883 +
4884 + '@esbuild/darwin-x64@0.28.2':
4885 + optional: true
4886 +
4887 + '@esbuild/freebsd-arm64@0.18.20':
4888 + optional: true
4889 +
4890 + '@esbuild/freebsd-arm64@0.25.12':
4891 + optional: true
4892 +
4893 + '@esbuild/freebsd-arm64@0.28.2':
4894 + optional: true
4895 +
4896 + '@esbuild/freebsd-x64@0.18.20':
4897 + optional: true
4898 +
4899 + '@esbuild/freebsd-x64@0.25.12':
4900 + optional: true
4901 +
4902 + '@esbuild/freebsd-x64@0.28.2':
4903 + optional: true
4904 +
4905 + '@esbuild/linux-arm64@0.18.20':
4906 + optional: true
4907 +
4908 + '@esbuild/linux-arm64@0.25.12':
4909 + optional: true
4910 +
4911 + '@esbuild/linux-arm64@0.28.2':
4912 + optional: true
4913 +
4914 + '@esbuild/linux-arm@0.18.20':
4915 + optional: true
4916 +
4917 + '@esbuild/linux-arm@0.25.12':
4918 + optional: true
4919 +
4920 + '@esbuild/linux-arm@0.28.2':
4921 + optional: true
4922 +
4923 + '@esbuild/linux-ia32@0.18.20':
4924 + optional: true
4925 +
4926 + '@esbuild/linux-ia32@0.25.12':
4927 + optional: true
4928 +
4929 + '@esbuild/linux-ia32@0.28.2':
4930 + optional: true
4931 +
4932 + '@esbuild/linux-loong64@0.18.20':
4933 + optional: true
4934 +
4935 + '@esbuild/linux-loong64@0.25.12':
4936 + optional: true
4937 +
4938 + '@esbuild/linux-loong64@0.28.2':
4939 + optional: true
4940 +
4941 + '@esbuild/linux-mips64el@0.18.20':
4942 + optional: true
4943 +
4944 + '@esbuild/linux-mips64el@0.25.12':
4945 + optional: true
4946 +
4947 + '@esbuild/linux-mips64el@0.28.2':
4948 + optional: true
4949 +
4950 + '@esbuild/linux-ppc64@0.18.20':
4951 + optional: true
4952 +
4953 + '@esbuild/linux-ppc64@0.25.12':
4954 + optional: true
4955 +
4956 + '@esbuild/linux-ppc64@0.28.2':
4957 + optional: true
4958 +
4959 + '@esbuild/linux-riscv64@0.18.20':
4960 + optional: true
4961 +
4962 + '@esbuild/linux-riscv64@0.25.12':
4963 + optional: true
4964 +
4965 + '@esbuild/linux-riscv64@0.28.2':
4966 + optional: true
4967 +
4968 + '@esbuild/linux-s390x@0.18.20':
4969 + optional: true
4970 +
4971 + '@esbuild/linux-s390x@0.25.12':
4972 + optional: true
4973 +
4974 + '@esbuild/linux-s390x@0.28.2':
4975 + optional: true
4976 +
4977 + '@esbuild/linux-x64@0.18.20':
4978 + optional: true
4979 +
4980 + '@esbuild/linux-x64@0.25.12':
4981 + optional: true
4982 +
4983 + '@esbuild/linux-x64@0.28.2':
4984 + optional: true
4985 +
4986 + '@esbuild/netbsd-arm64@0.25.12':
4987 + optional: true
4988 +
4989 + '@esbuild/netbsd-arm64@0.28.2':
4990 + optional: true
4991 +
4992 + '@esbuild/netbsd-x64@0.18.20':
4993 + optional: true
4994 +
4995 + '@esbuild/netbsd-x64@0.25.12':
4996 + optional: true
4997 +
4998 + '@esbuild/netbsd-x64@0.28.2':
4999 + optional: true
5000 +
5001 + '@esbuild/openbsd-arm64@0.25.12':
5002 + optional: true
5003 +
5004 + '@esbuild/openbsd-arm64@0.28.2':
5005 + optional: true
5006 +
5007 + '@esbuild/openbsd-x64@0.18.20':
5008 + optional: true
5009 +
5010 + '@esbuild/openbsd-x64@0.25.12':
5011 + optional: true
5012 +
5013 + '@esbuild/openbsd-x64@0.28.2':
5014 + optional: true
5015 +
5016 + '@esbuild/openharmony-arm64@0.25.12':
5017 + optional: true
5018 +
5019 + '@esbuild/openharmony-arm64@0.28.2':
5020 + optional: true
5021 +
5022 + '@esbuild/sunos-x64@0.18.20':
5023 + optional: true
5024 +
5025 + '@esbuild/sunos-x64@0.25.12':
5026 + optional: true
5027 +
5028 + '@esbuild/sunos-x64@0.28.2':
5029 + optional: true
5030 +
5031 + '@esbuild/win32-arm64@0.18.20':
5032 + optional: true
5033 +
5034 + '@esbuild/win32-arm64@0.25.12':
5035 + optional: true
5036 +
5037 + '@esbuild/win32-arm64@0.28.2':
5038 + optional: true
5039 +
5040 + '@esbuild/win32-ia32@0.18.20':
5041 + optional: true
5042 +
5043 + '@esbuild/win32-ia32@0.25.12':
5044 + optional: true
5045 +
5046 + '@esbuild/win32-ia32@0.28.2':
5047 + optional: true
5048 +
5049 + '@esbuild/win32-x64@0.18.20':
5050 + optional: true
5051 +
5052 + '@esbuild/win32-x64@0.25.12':
5053 + optional: true
5054 +
5055 + '@esbuild/win32-x64@0.28.2':
5056 + optional: true
5057 +
5058 + '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(jiti@2.7.0))':
5059 + dependencies:
5060 + eslint: 9.39.5(jiti@2.7.0)
5061 + eslint-visitor-keys: 3.4.3
5062 +
5063 + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.5(jiti@2.7.0))':
5064 + dependencies:
5065 + eslint: 9.39.5(jiti@2.7.0)
5066 + eslint-visitor-keys: 3.4.3
5067 +
5068 + '@eslint-community/regexpp@4.12.2': {}
5069 +
5070 + '@eslint/config-array@0.21.2':
5071 + dependencies:
5072 + '@eslint/object-schema': 2.1.7
5073 + debug: 4.4.3
5074 + minimatch: 3.1.5
5075 + transitivePeerDependencies:
5076 + - supports-color
5077 +
5078 + '@eslint/config-helpers@0.4.2':
5079 + dependencies:
5080 + '@eslint/core': 0.17.0
5081 +
5082 + '@eslint/core@0.17.0':
5083 + dependencies:
5084 + '@types/json-schema': 7.0.15
5085 +
5086 + '@eslint/eslintrc@3.3.7':
5087 + dependencies:
5088 + ajv: 6.15.0
5089 + debug: 4.4.3
5090 + espree: 10.4.0
5091 + globals: 14.0.0
5092 + ignore: 5.3.2
5093 + import-fresh: 3.3.1
5094 + js-yaml: 4.3.2
5095 + minimatch: 3.1.5
5096 + strip-json-comments: 3.1.1
5097 + transitivePeerDependencies:
5098 + - supports-color
5099 +
5100 + '@eslint/js@9.39.5': {}
5101 +
5102 + '@eslint/object-schema@2.1.7': {}
5103 +
5104 + '@eslint/plugin-kit@0.4.1':
5105 + dependencies:
5106 + '@eslint/core': 0.17.0
5107 + levn: 0.4.1
5108 +
5109 + '@floating-ui/core@1.8.0':
5110 + dependencies:
5111 + '@floating-ui/utils': 0.2.12
5112 +
5113 + '@floating-ui/dom@1.8.0':
5114 + dependencies:
5115 + '@floating-ui/core': 1.8.0
5116 + '@floating-ui/utils': 0.2.12
5117 +
5118 + '@floating-ui/react-dom@2.1.9(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5119 + dependencies:
5120 + '@floating-ui/dom': 1.8.0
5121 + react: 19.2.8
5122 + react-dom: 19.2.8(react@19.2.8)
5123 +
5124 + '@floating-ui/utils@0.2.12': {}
5125 +
5126 + '@google/genai@2.21.0':
5127 + dependencies:
5128 + google-auth-library: 10.9.1
5129 + p-retry: 4.6.2
5130 + protobufjs: 7.6.6
5131 + ws: 8.21.3
5132 + transitivePeerDependencies:
5133 + - bufferutil
5134 + - supports-color
5135 + - utf-8-validate
5136 +
5137 + '@humanfs/core@0.19.2':
5138 + dependencies:
5139 + '@humanfs/types': 0.15.0
5140 +
5141 + '@humanfs/node@0.16.8':
5142 + dependencies:
5143 + '@humanfs/core': 0.19.2
5144 + '@humanfs/types': 0.15.0
5145 + '@humanwhocodes/retry': 0.4.3
5146 +
5147 + '@humanfs/types@0.15.0': {}
5148 +
5149 + '@humanwhocodes/module-importer@1.0.1': {}
5150 +
5151 + '@humanwhocodes/retry@0.4.3': {}
5152 +
5153 + '@img/colour@1.1.0':
5154 + optional: true
5155 +
5156 + '@img/sharp-darwin-arm64@0.35.4':
5157 + optionalDependencies:
5158 + '@img/sharp-libvips-darwin-arm64': 1.3.3
5159 + optional: true
5160 +
5161 + '@img/sharp-darwin-x64@0.35.4':
5162 + optionalDependencies:
5163 + '@img/sharp-libvips-darwin-x64': 1.3.3
5164 + optional: true
5165 +
5166 + '@img/sharp-freebsd-wasm32@0.35.4':
5167 + dependencies:
5168 + '@img/sharp-wasm32': 0.35.4
5169 + optional: true
5170 +
5171 + '@img/sharp-libvips-darwin-arm64@1.3.3':
5172 + optional: true
5173 +
5174 + '@img/sharp-libvips-darwin-x64@1.3.3':
5175 + optional: true
5176 +
5177 + '@img/sharp-libvips-linux-arm64@1.3.3':
5178 + optional: true
5179 +
5180 + '@img/sharp-libvips-linux-arm@1.3.3':
5181 + optional: true
5182 +
5183 + '@img/sharp-libvips-linux-ppc64@1.3.3':
5184 + optional: true
5185 +
5186 + '@img/sharp-libvips-linux-riscv64@1.3.3':
5187 + optional: true
5188 +
5189 + '@img/sharp-libvips-linux-s390x@1.3.3':
5190 + optional: true
5191 +
5192 + '@img/sharp-libvips-linux-x64@1.3.3':
5193 + optional: true
5194 +
5195 + '@img/sharp-libvips-linuxmusl-arm64@1.3.3':
5196 + optional: true
5197 +
5198 + '@img/sharp-libvips-linuxmusl-x64@1.3.3':
5199 + optional: true
5200 +
5201 + '@img/sharp-linux-arm64@0.35.4':
5202 + optionalDependencies:
5203 + '@img/sharp-libvips-linux-arm64': 1.3.3
5204 + optional: true
5205 +
5206 + '@img/sharp-linux-arm@0.35.4':
5207 + optionalDependencies:
5208 + '@img/sharp-libvips-linux-arm': 1.3.3
5209 + optional: true
5210 +
5211 + '@img/sharp-linux-ppc64@0.35.4':
5212 + optionalDependencies:
5213 + '@img/sharp-libvips-linux-ppc64': 1.3.3
5214 + optional: true
5215 +
5216 + '@img/sharp-linux-riscv64@0.35.4':
5217 + optionalDependencies:
5218 + '@img/sharp-libvips-linux-riscv64': 1.3.3
5219 + optional: true
5220 +
5221 + '@img/sharp-linux-s390x@0.35.4':
5222 + optionalDependencies:
5223 + '@img/sharp-libvips-linux-s390x': 1.3.3
5224 + optional: true
5225 +
5226 + '@img/sharp-linux-x64@0.35.4':
5227 + optionalDependencies:
5228 + '@img/sharp-libvips-linux-x64': 1.3.3
5229 + optional: true
5230 +
5231 + '@img/sharp-linuxmusl-arm64@0.35.4':
5232 + optionalDependencies:
5233 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.3
5234 + optional: true
5235 +
5236 + '@img/sharp-linuxmusl-x64@0.35.4':
5237 + optionalDependencies:
5238 + '@img/sharp-libvips-linuxmusl-x64': 1.3.3
5239 + optional: true
5240 +
5241 + '@img/sharp-wasm32@0.35.4':
5242 + dependencies:
5243 + '@emnapi/runtime': 1.11.3
5244 + optional: true
5245 +
5246 + '@img/sharp-webcontainers-wasm32@0.35.4':
5247 + dependencies:
5248 + '@img/sharp-wasm32': 0.35.4
5249 + optional: true
5250 +
5251 + '@img/sharp-win32-arm64@0.35.4':
5252 + optional: true
5253 +
5254 + '@img/sharp-win32-ia32@0.35.4':
5255 + optional: true
5256 +
5257 + '@img/sharp-win32-x64@0.35.4':
5258 + optional: true
5259 +
5260 + '@jridgewell/gen-mapping@0.3.13':
5261 + dependencies:
5262 + '@jridgewell/sourcemap-codec': 1.6.0
5263 + '@jridgewell/trace-mapping': 0.3.31
5264 +
5265 + '@jridgewell/remapping@2.3.5':
5266 + dependencies:
5267 + '@jridgewell/gen-mapping': 0.3.13
5268 + '@jridgewell/trace-mapping': 0.3.31
5269 +
5270 + '@jridgewell/resolve-uri@3.1.2': {}
5271 +
5272 + '@jridgewell/sourcemap-codec@1.6.0': {}
5273 +
5274 + '@jridgewell/trace-mapping@0.3.31':
5275 + dependencies:
5276 + '@jridgewell/resolve-uri': 3.1.2
5277 + '@jridgewell/sourcemap-codec': 1.6.0
5278 +
5279 + '@napi-rs/lzma-linux-x64-gnu@1.5.1':
5280 + optional: true
5281 +
5282 + '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
5283 + dependencies:
5284 + '@emnapi/core': 1.10.0
5285 + '@emnapi/runtime': 1.10.0
5286 + '@tybys/wasm-util': 0.10.3
5287 + optional: true
5288 +
5289 + '@next/env@16.3.4': {}
5290 +
5291 + '@next/eslint-plugin-next@16.3.4(eslint@9.39.5(jiti@2.7.0))':
5292 + dependencies:
5293 + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5(jiti@2.7.0))
5294 + fast-glob: 3.3.1
5295 + transitivePeerDependencies:
5296 + - eslint
5297 +
5298 + '@next/swc-darwin-arm64@16.3.4':
5299 + optional: true
5300 +
5301 + '@next/swc-darwin-x64@16.3.4':
5302 + optional: true
5303 +
5304 + '@next/swc-linux-arm64-gnu@16.3.4':
5305 + optional: true
5306 +
5307 + '@next/swc-linux-arm64-musl@16.3.4':
5308 + optional: true
5309 +
5310 + '@next/swc-linux-x64-gnu@16.3.4':
5311 + optional: true
5312 +
5313 + '@next/swc-linux-x64-musl@16.3.4':
5314 + optional: true
5315 +
5316 + '@next/swc-win32-arm64-msvc@16.3.4':
5317 + optional: true
5318 +
5319 + '@next/swc-win32-x64-msvc@16.3.4':
5320 + optional: true
5321 +
5322 + '@noble/ciphers@2.4.0': {}
5323 +
5324 + '@noble/hashes@2.4.0': {}
5325 +
5326 + '@nodelib/fs.scandir@2.1.5':
5327 + dependencies:
5328 + '@nodelib/fs.stat': 2.0.5
5329 + run-parallel: 1.2.0
5330 +
5331 + '@nodelib/fs.stat@2.0.5': {}
5332 +
5333 + '@nodelib/fs.walk@1.2.8':
5334 + dependencies:
5335 + '@nodelib/fs.scandir': 2.1.5
5336 + fastq: 1.20.3
5337 +
5338 + '@nolyfill/is-core-module@1.0.39': {}
5339 +
5340 + '@opentelemetry/semantic-conventions@1.43.0': {}
5341 +
5342 + '@phc/format@1.0.0': {}
5343 +
5344 + '@playwright/test@1.63.0':
5345 + dependencies:
5346 + playwright: 1.63.0
5347 +
5348 + '@protobufjs/aspromise@1.1.2': {}
5349 +
5350 + '@protobufjs/base64@1.1.2': {}
5351 +
5352 + '@protobufjs/codegen@2.0.5': {}
5353 +
5354 + '@protobufjs/eventemitter@1.1.1': {}
5355 +
5356 + '@protobufjs/fetch@1.1.1':
5357 + dependencies:
5358 + '@protobufjs/aspromise': 1.1.2
5359 +
5360 + '@protobufjs/float@1.0.2': {}
5361 +
5362 + '@protobufjs/path@1.1.2': {}
5363 +
5364 + '@protobufjs/pool@1.1.0': {}
5365 +
5366 + '@protobufjs/utf8@1.1.2': {}
5367 +
5368 + '@radix-ui/number@1.1.3': {}
5369 +
5370 + '@radix-ui/primitive@1.1.7': {}
5371 +
5372 + '@radix-ui/react-arrow@1.1.15(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5373 + dependencies:
5374 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5375 + react: 19.2.8
5376 + react-dom: 19.2.8(react@19.2.8)
5377 + optionalDependencies:
5378 + '@types/react': 19.2.18
5379 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5380 +
5381 + '@radix-ui/react-collection@1.1.15(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5382 + dependencies:
5383 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5384 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5385 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5386 + '@radix-ui/react-slot': 1.3.3(@types/react@19.2.18)(react@19.2.8)
5387 + react: 19.2.8
5388 + react-dom: 19.2.8(react@19.2.8)
5389 + optionalDependencies:
5390 + '@types/react': 19.2.18
5391 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5392 +
5393 + '@radix-ui/react-compose-refs@1.1.5(@types/react@19.2.18)(react@19.2.8)':
5394 + dependencies:
5395 + react: 19.2.8
5396 + optionalDependencies:
5397 + '@types/react': 19.2.18
5398 +
5399 + '@radix-ui/react-context@1.2.2(@types/react@19.2.18)(react@19.2.8)':
5400 + dependencies:
5401 + react: 19.2.8
5402 + optionalDependencies:
5403 + '@types/react': 19.2.18
5404 +
5405 + '@radix-ui/react-dialog@1.1.23(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5406 + dependencies:
5407 + '@radix-ui/primitive': 1.1.7
5408 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5409 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5410 + '@radix-ui/react-dismissable-layer': 1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5411 + '@radix-ui/react-focus-guards': 1.1.6(@types/react@19.2.18)(react@19.2.8)
5412 + '@radix-ui/react-focus-scope': 1.1.16(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5413 + '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5414 + '@radix-ui/react-portal': 1.1.17(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5415 + '@radix-ui/react-presence': 1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5416 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5417 + '@radix-ui/react-slot': 1.3.3(@types/react@19.2.18)(react@19.2.8)
5418 + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8)
5419 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5420 + aria-hidden: 1.2.6
5421 + react: 19.2.8
5422 + react-dom: 19.2.8(react@19.2.8)
5423 + react-remove-scroll: 2.7.2(@types/react@19.2.18)(react@19.2.8)
5424 + optionalDependencies:
5425 + '@types/react': 19.2.18
5426 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5427 +
5428 + '@radix-ui/react-direction@1.1.4(@types/react@19.2.18)(react@19.2.8)':
5429 + dependencies:
5430 + react: 19.2.8
5431 + optionalDependencies:
5432 + '@types/react': 19.2.18
5433 +
5434 + '@radix-ui/react-dismissable-layer@1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5435 + dependencies:
5436 + '@radix-ui/primitive': 1.1.7
5437 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5438 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5439 + '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5440 + '@radix-ui/react-use-effect-event': 0.0.5(@types/react@19.2.18)(react@19.2.8)
5441 + react: 19.2.8
5442 + react-dom: 19.2.8(react@19.2.8)
5443 + optionalDependencies:
5444 + '@types/react': 19.2.18
5445 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5446 +
5447 + '@radix-ui/react-dropdown-menu@2.1.24(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5448 + dependencies:
5449 + '@radix-ui/primitive': 1.1.7
5450 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5451 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5452 + '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5453 + '@radix-ui/react-menu': 2.1.24(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5454 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5455 + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8)
5456 + react: 19.2.8
5457 + react-dom: 19.2.8(react@19.2.8)
5458 + optionalDependencies:
5459 + '@types/react': 19.2.18
5460 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5461 +
5462 + '@radix-ui/react-focus-guards@1.1.6(@types/react@19.2.18)(react@19.2.8)':
5463 + dependencies:
5464 + react: 19.2.8
5465 + optionalDependencies:
5466 + '@types/react': 19.2.18
5467 +
5468 + '@radix-ui/react-focus-scope@1.1.16(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5469 + dependencies:
5470 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5471 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5472 + '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5473 + react: 19.2.8
5474 + react-dom: 19.2.8(react@19.2.8)
5475 + optionalDependencies:
5476 + '@types/react': 19.2.18
5477 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5478 +
5479 + '@radix-ui/react-id@1.1.4(@types/react@19.2.18)(react@19.2.8)':
5480 + dependencies:
5481 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5482 + react: 19.2.8
5483 + optionalDependencies:
5484 + '@types/react': 19.2.18
5485 +
5486 + '@radix-ui/react-menu@2.1.24(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5487 + dependencies:
5488 + '@radix-ui/primitive': 1.1.7
5489 + '@radix-ui/react-collection': 1.1.15(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5490 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5491 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5492 + '@radix-ui/react-direction': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5493 + '@radix-ui/react-dismissable-layer': 1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5494 + '@radix-ui/react-focus-guards': 1.1.6(@types/react@19.2.18)(react@19.2.8)
5495 + '@radix-ui/react-focus-scope': 1.1.16(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5496 + '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5497 + '@radix-ui/react-popper': 1.3.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5498 + '@radix-ui/react-portal': 1.1.17(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5499 + '@radix-ui/react-presence': 1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5500 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5501 + '@radix-ui/react-roving-focus': 1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5502 + '@radix-ui/react-slot': 1.3.3(@types/react@19.2.18)(react@19.2.8)
5503 + '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5504 + aria-hidden: 1.2.6
5505 + react: 19.2.8
5506 + react-dom: 19.2.8(react@19.2.8)
5507 + react-remove-scroll: 2.7.2(@types/react@19.2.18)(react@19.2.8)
5508 + optionalDependencies:
5509 + '@types/react': 19.2.18
5510 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5511 +
5512 + '@radix-ui/react-popover@1.1.23(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5513 + dependencies:
5514 + '@radix-ui/primitive': 1.1.7
5515 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5516 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5517 + '@radix-ui/react-dismissable-layer': 1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5518 + '@radix-ui/react-focus-guards': 1.1.6(@types/react@19.2.18)(react@19.2.8)
5519 + '@radix-ui/react-focus-scope': 1.1.16(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5520 + '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5521 + '@radix-ui/react-popper': 1.3.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5522 + '@radix-ui/react-portal': 1.1.17(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5523 + '@radix-ui/react-presence': 1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5524 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5525 + '@radix-ui/react-slot': 1.3.3(@types/react@19.2.18)(react@19.2.8)
5526 + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8)
5527 + aria-hidden: 1.2.6
5528 + react: 19.2.8
5529 + react-dom: 19.2.8(react@19.2.8)
5530 + react-remove-scroll: 2.7.2(@types/react@19.2.18)(react@19.2.8)
5531 + optionalDependencies:
5532 + '@types/react': 19.2.18
5533 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5534 +
5535 + '@radix-ui/react-popper@1.3.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5536 + dependencies:
5537 + '@floating-ui/react-dom': 2.1.9(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5538 + '@radix-ui/react-arrow': 1.1.15(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5539 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5540 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5541 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5542 + '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5543 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5544 + '@radix-ui/react-use-rect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5545 + '@radix-ui/react-use-size': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5546 + '@radix-ui/rect': 1.1.3
5547 + react: 19.2.8
5548 + react-dom: 19.2.8(react@19.2.8)
5549 + optionalDependencies:
5550 + '@types/react': 19.2.18
5551 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5552 +
5553 + '@radix-ui/react-portal@1.1.17(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5554 + dependencies:
5555 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5556 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5557 + react: 19.2.8
5558 + react-dom: 19.2.8(react@19.2.8)
5559 + optionalDependencies:
5560 + '@types/react': 19.2.18
5561 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5562 +
5563 + '@radix-ui/react-presence@1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5564 + dependencies:
5565 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5566 + react: 19.2.8
5567 + react-dom: 19.2.8(react@19.2.8)
5568 + optionalDependencies:
5569 + '@types/react': 19.2.18
5570 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5571 +
5572 + '@radix-ui/react-primitive@2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5573 + dependencies:
5574 + '@radix-ui/react-slot': 1.3.3(@types/react@19.2.18)(react@19.2.8)
5575 + react: 19.2.8
5576 + react-dom: 19.2.8(react@19.2.8)
5577 + optionalDependencies:
5578 + '@types/react': 19.2.18
5579 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5580 +
5581 + '@radix-ui/react-roving-focus@1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5582 + dependencies:
5583 + '@radix-ui/primitive': 1.1.7
5584 + '@radix-ui/react-collection': 1.1.15(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5585 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5586 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5587 + '@radix-ui/react-direction': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5588 + '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5589 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5590 + '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5591 + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8)
5592 + '@radix-ui/react-use-is-hydrated': 0.1.3(@types/react@19.2.18)(react@19.2.8)
5593 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5594 + react: 19.2.8
5595 + react-dom: 19.2.8(react@19.2.8)
5596 + optionalDependencies:
5597 + '@types/react': 19.2.18
5598 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5599 +
5600 + '@radix-ui/react-scroll-area@1.2.18(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5601 + dependencies:
5602 + '@radix-ui/number': 1.1.3
5603 + '@radix-ui/primitive': 1.1.7
5604 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5605 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5606 + '@radix-ui/react-direction': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5607 + '@radix-ui/react-presence': 1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5608 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5609 + '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5610 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5611 + react: 19.2.8
5612 + react-dom: 19.2.8(react@19.2.8)
5613 + optionalDependencies:
5614 + '@types/react': 19.2.18
5615 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5616 +
5617 + '@radix-ui/react-select@2.3.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5618 + dependencies:
5619 + '@radix-ui/number': 1.1.3
5620 + '@radix-ui/primitive': 1.1.7
5621 + '@radix-ui/react-collection': 1.1.15(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5622 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5623 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5624 + '@radix-ui/react-direction': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5625 + '@radix-ui/react-dismissable-layer': 1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5626 + '@radix-ui/react-focus-guards': 1.1.6(@types/react@19.2.18)(react@19.2.8)
5627 + '@radix-ui/react-focus-scope': 1.1.16(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5628 + '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5629 + '@radix-ui/react-popper': 1.3.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5630 + '@radix-ui/react-portal': 1.1.17(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5631 + '@radix-ui/react-presence': 1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5632 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5633 + '@radix-ui/react-slot': 1.3.3(@types/react@19.2.18)(react@19.2.8)
5634 + '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5635 + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8)
5636 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5637 + '@radix-ui/react-use-previous': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5638 + '@radix-ui/react-visually-hidden': 1.2.11(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5639 + aria-hidden: 1.2.6
5640 + react: 19.2.8
5641 + react-dom: 19.2.8(react@19.2.8)
5642 + react-remove-scroll: 2.7.2(@types/react@19.2.18)(react@19.2.8)
5643 + optionalDependencies:
5644 + '@types/react': 19.2.18
5645 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5646 +
5647 + '@radix-ui/react-slider@1.4.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5648 + dependencies:
5649 + '@radix-ui/number': 1.1.3
5650 + '@radix-ui/primitive': 1.1.7
5651 + '@radix-ui/react-collection': 1.1.15(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5652 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5653 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5654 + '@radix-ui/react-direction': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5655 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5656 + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8)
5657 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5658 + '@radix-ui/react-use-previous': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5659 + '@radix-ui/react-use-size': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5660 + react: 19.2.8
5661 + react-dom: 19.2.8(react@19.2.8)
5662 + optionalDependencies:
5663 + '@types/react': 19.2.18
5664 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5665 +
5666 + '@radix-ui/react-slot@1.3.3(@types/react@19.2.18)(react@19.2.8)':
5667 + dependencies:
5668 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5669 + react: 19.2.8
5670 + optionalDependencies:
5671 + '@types/react': 19.2.18
5672 +
5673 + '@radix-ui/react-switch@1.3.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5674 + dependencies:
5675 + '@radix-ui/primitive': 1.1.7
5676 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5677 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5678 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5679 + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8)
5680 + '@radix-ui/react-use-size': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5681 + react: 19.2.8
5682 + react-dom: 19.2.8(react@19.2.8)
5683 + optionalDependencies:
5684 + '@types/react': 19.2.18
5685 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5686 +
5687 + '@radix-ui/react-tabs@1.1.21(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5688 + dependencies:
5689 + '@radix-ui/primitive': 1.1.7
5690 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5691 + '@radix-ui/react-direction': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5692 + '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5693 + '@radix-ui/react-presence': 1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5694 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5695 + '@radix-ui/react-roving-focus': 1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5696 + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8)
5697 + react: 19.2.8
5698 + react-dom: 19.2.8(react@19.2.8)
5699 + optionalDependencies:
5700 + '@types/react': 19.2.18
5701 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5702 +
5703 + '@radix-ui/react-tooltip@1.2.16(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5704 + dependencies:
5705 + '@radix-ui/primitive': 1.1.7
5706 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
5707 + '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8)
5708 + '@radix-ui/react-dismissable-layer': 1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5709 + '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5710 + '@radix-ui/react-popper': 1.3.7(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5711 + '@radix-ui/react-portal': 1.1.17(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5712 + '@radix-ui/react-presence': 1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5713 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5714 + '@radix-ui/react-slot': 1.3.3(@types/react@19.2.18)(react@19.2.8)
5715 + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8)
5716 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5717 + '@radix-ui/react-visually-hidden': 1.2.11(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5718 + react: 19.2.8
5719 + react-dom: 19.2.8(react@19.2.8)
5720 + optionalDependencies:
5721 + '@types/react': 19.2.18
5722 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5723 +
5724 + '@radix-ui/react-use-callback-ref@1.1.4(@types/react@19.2.18)(react@19.2.8)':
5725 + dependencies:
5726 + react: 19.2.8
5727 + optionalDependencies:
5728 + '@types/react': 19.2.18
5729 +
5730 + '@radix-ui/react-use-controllable-state@1.2.6(@types/react@19.2.18)(react@19.2.8)':
5731 + dependencies:
5732 + '@radix-ui/primitive': 1.1.7
5733 + '@radix-ui/react-use-effect-event': 0.0.5(@types/react@19.2.18)(react@19.2.8)
5734 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5735 + react: 19.2.8
5736 + optionalDependencies:
5737 + '@types/react': 19.2.18
5738 +
5739 + '@radix-ui/react-use-effect-event@0.0.5(@types/react@19.2.18)(react@19.2.8)':
5740 + dependencies:
5741 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5742 + react: 19.2.8
5743 + optionalDependencies:
5744 + '@types/react': 19.2.18
5745 +
5746 + '@radix-ui/react-use-is-hydrated@0.1.3(@types/react@19.2.18)(react@19.2.8)':
5747 + dependencies:
5748 + react: 19.2.8
5749 + optionalDependencies:
5750 + '@types/react': 19.2.18
5751 +
5752 + '@radix-ui/react-use-layout-effect@1.1.4(@types/react@19.2.18)(react@19.2.8)':
5753 + dependencies:
5754 + react: 19.2.8
5755 + optionalDependencies:
5756 + '@types/react': 19.2.18
5757 +
5758 + '@radix-ui/react-use-previous@1.1.4(@types/react@19.2.18)(react@19.2.8)':
5759 + dependencies:
5760 + react: 19.2.8
5761 + optionalDependencies:
5762 + '@types/react': 19.2.18
5763 +
5764 + '@radix-ui/react-use-rect@1.1.4(@types/react@19.2.18)(react@19.2.8)':
5765 + dependencies:
5766 + '@radix-ui/rect': 1.1.3
5767 + react: 19.2.8
5768 + optionalDependencies:
5769 + '@types/react': 19.2.18
5770 +
5771 + '@radix-ui/react-use-size@1.1.4(@types/react@19.2.18)(react@19.2.8)':
5772 + dependencies:
5773 + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8)
5774 + react: 19.2.8
5775 + optionalDependencies:
5776 + '@types/react': 19.2.18
5777 +
5778 + '@radix-ui/react-visually-hidden@1.2.11(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5779 + dependencies:
5780 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
5781 + react: 19.2.8
5782 + react-dom: 19.2.8(react@19.2.8)
5783 + optionalDependencies:
5784 + '@types/react': 19.2.18
5785 + '@types/react-dom': 19.2.7(@types/react@19.2.18)
5786 +
5787 + '@radix-ui/rect@1.1.3': {}
5788 +
5789 + '@reduxjs/toolkit@2.12.0(react-redux@9.3.0(@types/react@19.2.18)(react@19.2.8)(redux@5.0.1))(react@19.2.8)':
5790 + dependencies:
5791 + '@standard-schema/spec': 1.1.0
5792 + '@standard-schema/utils': 0.3.0
5793 + immer: 11.1.18
5794 + redux: 5.0.1
5795 + redux-thunk: 3.1.0(redux@5.0.1)
5796 + reselect: 5.2.0
5797 + optionalDependencies:
5798 + react: 19.2.8
5799 + react-redux: 9.3.0(@types/react@19.2.18)(react@19.2.8)(redux@5.0.1)
5800 +
5801 + '@rollup/rollup-android-arm-eabi@4.63.1':
5802 + optional: true
5803 +
5804 + '@rollup/rollup-android-arm64@4.63.1':
5805 + optional: true
5806 +
5807 + '@rollup/rollup-darwin-arm64@4.63.1':
5808 + optional: true
5809 +
5810 + '@rollup/rollup-darwin-x64@4.63.1':
5811 + optional: true
5812 +
5813 + '@rollup/rollup-freebsd-arm64@4.63.1':
5814 + optional: true
5815 +
5816 + '@rollup/rollup-freebsd-x64@4.63.1':
5817 + optional: true
5818 +
5819 + '@rollup/rollup-linux-arm-gnueabihf@4.63.1':
5820 + optional: true
5821 +
5822 + '@rollup/rollup-linux-arm-musleabihf@4.63.1':
5823 + optional: true
5824 +
5825 + '@rollup/rollup-linux-arm64-gnu@4.63.1':
5826 + optional: true
5827 +
5828 + '@rollup/rollup-linux-arm64-musl@4.63.1':
5829 + optional: true
5830 +
5831 + '@rollup/rollup-linux-loong64-gnu@4.63.1':
5832 + optional: true
5833 +
5834 + '@rollup/rollup-linux-loong64-musl@4.63.1':
5835 + optional: true
5836 +
5837 + '@rollup/rollup-linux-ppc64-gnu@4.63.1':
5838 + optional: true
5839 +
5840 + '@rollup/rollup-linux-ppc64-musl@4.63.1':
5841 + optional: true
5842 +
5843 + '@rollup/rollup-linux-riscv64-gnu@4.63.1':
5844 + optional: true
5845 +
5846 + '@rollup/rollup-linux-riscv64-musl@4.63.1':
5847 + optional: true
5848 +
5849 + '@rollup/rollup-linux-s390x-gnu@4.63.1':
5850 + optional: true
5851 +
5852 + '@rollup/rollup-linux-x64-gnu@4.63.1':
5853 + optional: true
5854 +
5855 + '@rollup/rollup-linux-x64-musl@4.63.1':
5856 + optional: true
5857 +
5858 + '@rollup/rollup-openbsd-x64@4.63.1':
5859 + optional: true
5860 +
5861 + '@rollup/rollup-openharmony-arm64@4.63.1':
5862 + optional: true
5863 +
5864 + '@rollup/rollup-win32-arm64-msvc@4.63.1':
5865 + optional: true
5866 +
5867 + '@rollup/rollup-win32-ia32-msvc@4.63.1':
5868 + optional: true
5869 +
5870 + '@rollup/rollup-win32-x64-gnu@4.63.1':
5871 + optional: true
5872 +
5873 + '@rollup/rollup-win32-x64-msvc@4.63.1':
5874 + optional: true
5875 +
5876 + '@rtsao/scc@1.1.0': {}
5877 +
5878 + '@shikijs/core@4.4.3':
5879 + dependencies:
5880 + '@shikijs/primitive': 4.4.3
5881 + '@shikijs/types': 4.4.3
5882 + '@shikijs/vscode-textmate': 10.0.2
5883 + '@types/hast': 3.0.5
5884 + hast-util-to-html: 9.0.5
5885 +
5886 + '@shikijs/engine-javascript@4.4.3':
5887 + dependencies:
5888 + '@shikijs/types': 4.4.3
5889 + '@shikijs/vscode-textmate': 10.0.2
5890 + oniguruma-to-es: 4.3.6
5891 +
5892 + '@shikijs/engine-oniguruma@4.4.3':
5893 + dependencies:
5894 + '@shikijs/types': 4.4.3
5895 + '@shikijs/vscode-textmate': 10.0.2
5896 +
5897 + '@shikijs/langs@4.4.3':
5898 + dependencies:
5899 + '@shikijs/types': 4.4.3
5900 +
5901 + '@shikijs/primitive@4.4.3':
5902 + dependencies:
5903 + '@shikijs/types': 4.4.3
5904 + '@shikijs/vscode-textmate': 10.0.2
5905 + '@types/hast': 3.0.5
5906 +
5907 + '@shikijs/themes@4.4.3':
5908 + dependencies:
5909 + '@shikijs/types': 4.4.3
5910 +
5911 + '@shikijs/types@4.4.3':
5912 + dependencies:
5913 + '@shikijs/vscode-textmate': 10.0.2
5914 + '@types/hast': 3.0.5
5915 +
5916 + '@shikijs/vscode-textmate@10.0.2': {}
5917 +
5918 + '@stablelib/base64@1.0.1': {}
5919 +
5920 + '@standard-schema/spec@1.1.0': {}
5921 +
5922 + '@standard-schema/utils@0.3.0': {}
5923 +
5924 + '@swc/helpers@0.5.23':
5925 + dependencies:
5926 + tslib: 2.8.1
5927 +
5928 + '@tailwindcss/node@4.3.3':
5929 + dependencies:
5930 + '@jridgewell/remapping': 2.3.5
5931 + enhanced-resolve: 5.24.5
5932 + jiti: 2.7.0
5933 + lightningcss: 1.32.0
5934 + magic-string: 0.30.21
5935 + source-map-js: 1.2.1
5936 + tailwindcss: 4.3.3
5937 +
5938 + '@tailwindcss/oxide-android-arm64@4.3.3':
5939 + optional: true
5940 +
5941 + '@tailwindcss/oxide-darwin-arm64@4.3.3':
5942 + optional: true
5943 +
5944 + '@tailwindcss/oxide-darwin-x64@4.3.3':
5945 + optional: true
5946 +
5947 + '@tailwindcss/oxide-freebsd-x64@4.3.3':
5948 + optional: true
5949 +
5950 + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3':
5951 + optional: true
5952 +
5953 + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3':
5954 + optional: true
5955 +
5956 + '@tailwindcss/oxide-linux-arm64-musl@4.3.3':
5957 + optional: true
5958 +
5959 + '@tailwindcss/oxide-linux-x64-gnu@4.3.3':
5960 + optional: true
5961 +
5962 + '@tailwindcss/oxide-linux-x64-musl@4.3.3':
5963 + optional: true
5964 +
5965 + '@tailwindcss/oxide-wasm32-wasi@4.3.3':
5966 + optional: true
5967 +
5968 + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3':
5969 + optional: true
5970 +
5971 + '@tailwindcss/oxide-win32-x64-msvc@4.3.3':
5972 + optional: true
5973 +
5974 + '@tailwindcss/oxide@4.3.3':
5975 + optionalDependencies:
5976 + '@tailwindcss/oxide-android-arm64': 4.3.3
5977 + '@tailwindcss/oxide-darwin-arm64': 4.3.3
5978 + '@tailwindcss/oxide-darwin-x64': 4.3.3
5979 + '@tailwindcss/oxide-freebsd-x64': 4.3.3
5980 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3
5981 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3
5982 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.3
5983 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.3
5984 + '@tailwindcss/oxide-linux-x64-musl': 4.3.3
5985 + '@tailwindcss/oxide-wasm32-wasi': 4.3.3
5986 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3
5987 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.3
5988 +
5989 + '@tailwindcss/postcss@4.3.3':
5990 + dependencies:
5991 + '@alloc/quick-lru': 5.3.0
5992 + '@tailwindcss/node': 4.3.3
5993 + '@tailwindcss/oxide': 4.3.3
5994 + postcss: 8.5.28
5995 + tailwindcss: 4.3.3
5996 +
5997 + '@tanstack/react-virtual@3.14.10(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
5998 + dependencies:
5999 + '@tanstack/virtual-core': 3.17.8
6000 + react: 19.2.8
6001 + react-dom: 19.2.8(react@19.2.8)
6002 +
6003 + '@tanstack/virtual-core@3.17.8': {}
6004 +
6005 + '@tybys/wasm-util@0.10.3':
6006 + dependencies:
6007 + tslib: 2.8.1
6008 + optional: true
6009 +
6010 + '@types/chai@5.2.3':
6011 + dependencies:
6012 + '@types/deep-eql': 4.0.2
6013 + assertion-error: 2.0.1
6014 +
6015 + '@types/d3-array@3.2.2': {}
6016 +
6017 + '@types/d3-color@3.1.3': {}
6018 +
6019 + '@types/d3-ease@3.0.2': {}
6020 +
6021 + '@types/d3-interpolate@3.0.4':
6022 + dependencies:
6023 + '@types/d3-color': 3.1.3
6024 +
6025 + '@types/d3-path@3.1.1': {}
6026 +
6027 + '@types/d3-scale@4.0.9':
6028 + dependencies:
6029 + '@types/d3-time': 3.0.4
6030 +
6031 + '@types/d3-shape@3.2.0':
6032 + dependencies:
6033 + '@types/d3-path': 3.1.1
6034 +
6035 + '@types/d3-time@3.0.4': {}
6036 +
6037 + '@types/d3-timer@3.0.2': {}
6038 +
6039 + '@types/debug@4.1.13':
6040 + dependencies:
6041 + '@types/ms': 2.1.0
6042 +
6043 + '@types/deep-eql@4.0.2': {}
6044 +
6045 + '@types/estree-jsx@1.0.5':
6046 + dependencies:
6047 + '@types/estree': 1.0.9
6048 +
6049 + '@types/estree@1.0.9': {}
6050 +
6051 + '@types/hast@3.0.5':
6052 + dependencies:
6053 + '@types/unist': 3.0.3
6054 +
6055 + '@types/json-schema@7.0.15': {}
6056 +
6057 + '@types/json5@0.0.29': {}
6058 +
6059 + '@types/mdast@4.0.4':
6060 + dependencies:
6061 + '@types/unist': 3.0.3
6062 +
6063 + '@types/ms@2.1.0': {}
6064 +
6065 + '@types/node@24.13.3':
6066 + dependencies:
6067 + undici-types: 7.18.2
6068 +
6069 + '@types/pg@8.23.1':
6070 + dependencies:
6071 + '@types/node': 24.13.3
6072 + pg-protocol: 1.16.0
6073 + pg-types: 2.2.0
6074 +
6075 + '@types/react-dom@19.2.7(@types/react@19.2.18)':
6076 + dependencies:
6077 + '@types/react': 19.2.18
6078 +
6079 + '@types/react@19.2.18':
6080 + dependencies:
6081 + csstype: 3.2.3
6082 +
6083 + '@types/retry@0.12.0': {}
6084 +
6085 + '@types/unist@2.0.11': {}
6086 +
6087 + '@types/unist@3.0.3': {}
6088 +
6089 + '@types/use-sync-external-store@0.0.6': {}
6090 +
6091 + '@typescript-eslint/eslint-plugin@8.69.0(@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)':
6092 + dependencies:
6093 + '@eslint-community/regexpp': 4.12.2
6094 + '@typescript-eslint/parser': 8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
6095 + '@typescript-eslint/scope-manager': 8.69.0
6096 + '@typescript-eslint/type-utils': 8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
6097 + '@typescript-eslint/utils': 8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
6098 + '@typescript-eslint/visitor-keys': 8.69.0
6099 + eslint: 9.39.5(jiti@2.7.0)
6100 + ignore: 7.0.8
6101 + natural-compare: 1.4.0
6102 + ts-api-utils: 2.5.0(typescript@5.9.3)
6103 + typescript: 5.9.3
6104 + transitivePeerDependencies:
6105 + - supports-color
6106 +
6107 + '@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)':
6108 + dependencies:
6109 + '@typescript-eslint/scope-manager': 8.69.0
6110 + '@typescript-eslint/types': 8.69.0
6111 + '@typescript-eslint/typescript-estree': 8.69.0(typescript@5.9.3)
6112 + '@typescript-eslint/visitor-keys': 8.69.0
6113 + debug: 4.4.3
6114 + eslint: 9.39.5(jiti@2.7.0)
6115 + typescript: 5.9.3
6116 + transitivePeerDependencies:
6117 + - supports-color
6118 +
6119 + '@typescript-eslint/project-service@8.69.0(typescript@5.9.3)':
6120 + dependencies:
6121 + '@typescript-eslint/tsconfig-utils': 8.69.0(typescript@5.9.3)
6122 + '@typescript-eslint/types': 8.69.0
6123 + debug: 4.4.3
6124 + typescript: 5.9.3
6125 + transitivePeerDependencies:
6126 + - supports-color
6127 +
6128 + '@typescript-eslint/scope-manager@8.69.0':
6129 + dependencies:
6130 + '@typescript-eslint/types': 8.69.0
6131 + '@typescript-eslint/visitor-keys': 8.69.0
6132 +
6133 + '@typescript-eslint/tsconfig-utils@8.69.0(typescript@5.9.3)':
6134 + dependencies:
6135 + typescript: 5.9.3
6136 +
6137 + '@typescript-eslint/type-utils@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)':
6138 + dependencies:
6139 + '@typescript-eslint/types': 8.69.0
6140 + '@typescript-eslint/typescript-estree': 8.69.0(typescript@5.9.3)
6141 + '@typescript-eslint/utils': 8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
6142 + debug: 4.4.3
6143 + eslint: 9.39.5(jiti@2.7.0)
6144 + ts-api-utils: 2.5.0(typescript@5.9.3)
6145 + typescript: 5.9.3
6146 + transitivePeerDependencies:
6147 + - supports-color
6148 +
6149 + '@typescript-eslint/types@8.69.0': {}
6150 +
6151 + '@typescript-eslint/typescript-estree@8.69.0(typescript@5.9.3)':
6152 + dependencies:
6153 + '@typescript-eslint/project-service': 8.69.0(typescript@5.9.3)
6154 + '@typescript-eslint/tsconfig-utils': 8.69.0(typescript@5.9.3)
6155 + '@typescript-eslint/types': 8.69.0
6156 + '@typescript-eslint/visitor-keys': 8.69.0
6157 + debug: 4.4.3
6158 + minimatch: 10.2.6
6159 + semver: 7.8.5
6160 + tinyglobby: 0.2.17
6161 + ts-api-utils: 2.5.0(typescript@5.9.3)
6162 + typescript: 5.9.3
6163 + transitivePeerDependencies:
6164 + - supports-color
6165 +
6166 + '@typescript-eslint/utils@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)':
6167 + dependencies:
6168 + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0))
6169 + '@typescript-eslint/scope-manager': 8.69.0
6170 + '@typescript-eslint/types': 8.69.0
6171 + '@typescript-eslint/typescript-estree': 8.69.0(typescript@5.9.3)
6172 + eslint: 9.39.5(jiti@2.7.0)
6173 + typescript: 5.9.3
6174 + transitivePeerDependencies:
6175 + - supports-color
6176 +
6177 + '@typescript-eslint/visitor-keys@8.69.0':
6178 + dependencies:
6179 + '@typescript-eslint/types': 8.69.0
6180 + eslint-visitor-keys: 5.0.1
6181 +
6182 + '@ungap/structured-clone@1.4.0': {}
6183 +
6184 + '@unrs/resolver-binding-android-arm-eabi@1.12.2':
6185 + optional: true
6186 +
6187 + '@unrs/resolver-binding-android-arm64@1.12.2':
6188 + optional: true
6189 +
6190 + '@unrs/resolver-binding-darwin-arm64@1.12.2':
6191 + optional: true
6192 +
6193 + '@unrs/resolver-binding-darwin-x64@1.12.2':
6194 + optional: true
6195 +
6196 + '@unrs/resolver-binding-freebsd-x64@1.12.2':
6197 + optional: true
6198 +
6199 + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2':
6200 + optional: true
6201 +
6202 + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2':
6203 + optional: true
6204 +
6205 + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2':
6206 + optional: true
6207 +
6208 + '@unrs/resolver-binding-linux-arm64-musl@1.12.2':
6209 + optional: true
6210 +
6211 + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2':
6212 + optional: true
6213 +
6214 + '@unrs/resolver-binding-linux-loong64-musl@1.12.2':
6215 + optional: true
6216 +
6217 + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2':
6218 + optional: true
6219 +
6220 + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2':
6221 + optional: true
6222 +
6223 + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2':
6224 + optional: true
6225 +
6226 + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2':
6227 + optional: true
6228 +
6229 + '@unrs/resolver-binding-linux-x64-gnu@1.12.2':
6230 + optional: true
6231 +
6232 + '@unrs/resolver-binding-linux-x64-musl@1.12.2':
6233 + optional: true
6234 +
6235 + '@unrs/resolver-binding-openharmony-arm64@1.12.2':
6236 + optional: true
6237 +
6238 + '@unrs/resolver-binding-wasm32-wasi@1.12.2':
6239 + dependencies:
6240 + '@emnapi/core': 1.10.0
6241 + '@emnapi/runtime': 1.10.0
6242 + '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
6243 + optional: true
6244 +
6245 + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2':
6246 + optional: true
6247 +
6248 + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2':
6249 + optional: true
6250 +
6251 + '@unrs/resolver-binding-win32-x64-msvc@1.12.2':
6252 + optional: true
6253 +
6254 + '@vitest/expect@3.2.7':
6255 + dependencies:
6256 + '@types/chai': 5.2.3
6257 + '@vitest/spy': 3.2.7
6258 + '@vitest/utils': 3.2.7
6259 + chai: 5.3.3
6260 + tinyrainbow: 2.0.0
6261 +
6262 + '@vitest/mocker@3.2.7(vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13))':
6263 + dependencies:
6264 + '@vitest/spy': 3.2.7
6265 + estree-walker: 3.0.3
6266 + magic-string: 0.30.21
6267 + optionalDependencies:
6268 + vite: 7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)
6269 +
6270 + '@vitest/pretty-format@3.2.7':
6271 + dependencies:
6272 + tinyrainbow: 2.0.0
6273 +
6274 + '@vitest/runner@3.2.7':
6275 + dependencies:
6276 + '@vitest/utils': 3.2.7
6277 + pathe: 2.0.3
6278 + strip-literal: 3.1.0
6279 +
6280 + '@vitest/snapshot@3.2.7':
6281 + dependencies:
6282 + '@vitest/pretty-format': 3.2.7
6283 + magic-string: 0.30.21
6284 + pathe: 2.0.3
6285 +
6286 + '@vitest/spy@3.2.7':
6287 + dependencies:
6288 + tinyspy: 4.0.6
6289 +
6290 + '@vitest/utils@3.2.7':
6291 + dependencies:
6292 + '@vitest/pretty-format': 3.2.7
6293 + loupe: 3.2.1
6294 + tinyrainbow: 2.0.0
6295 +
6296 + acorn-jsx@5.3.2(acorn@8.18.0):
6297 + dependencies:
6298 + acorn: 8.18.0
6299 +
6300 + acorn@8.18.0: {}
6301 +
6302 + agent-base@7.1.4: {}
6303 +
6304 + ajv@6.15.0:
6305 + dependencies:
6306 + fast-deep-equal: 3.1.3
6307 + fast-json-stable-stringify: 2.1.0
6308 + json-schema-traverse: 0.4.1
6309 + uri-js: 4.4.1
6310 +
6311 + ansi-styles@4.3.0:
6312 + dependencies:
6313 + color-convert: 2.0.1
6314 +
6315 + argon2@0.45.1:
6316 + dependencies:
6317 + '@phc/format': 1.0.0
6318 + cross-env: 10.1.0
6319 + node-addon-api: 8.9.2
6320 + node-gyp-build: 4.8.4
6321 +
6322 + argparse@2.0.1: {}
6323 +
6324 + aria-hidden@1.2.6:
6325 + dependencies:
6326 + tslib: 2.8.1
6327 +
6328 + aria-query@5.3.2: {}
6329 +
6330 + array-buffer-byte-length@1.0.2:
6331 + dependencies:
6332 + call-bound: 1.0.4
6333 + is-array-buffer: 3.0.5
6334 +
6335 + array-includes@3.1.9:
6336 + dependencies:
6337 + call-bind: 1.0.9
6338 + call-bound: 1.0.4
6339 + define-properties: 1.2.1
6340 + es-abstract: 1.24.2
6341 + es-object-atoms: 1.1.2
6342 + get-intrinsic: 1.3.0
6343 + is-string: 1.1.1
6344 + math-intrinsics: 1.1.0
6345 +
6346 + array.prototype.findlast@1.2.5:
6347 + dependencies:
6348 + call-bind: 1.0.9
6349 + define-properties: 1.2.1
6350 + es-abstract: 1.24.2
6351 + es-errors: 1.3.0
6352 + es-object-atoms: 1.1.2
6353 + es-shim-unscopables: 1.1.0
6354 +
6355 + array.prototype.findlastindex@1.2.6:
6356 + dependencies:
6357 + call-bind: 1.0.9
6358 + call-bound: 1.0.4
6359 + define-properties: 1.2.1
6360 + es-abstract: 1.24.2
6361 + es-errors: 1.3.0
6362 + es-object-atoms: 1.1.2
6363 + es-shim-unscopables: 1.1.0
6364 +
6365 + array.prototype.flat@1.3.3:
6366 + dependencies:
6367 + call-bind: 1.0.9
6368 + define-properties: 1.2.1
6369 + es-abstract: 1.24.2
6370 + es-shim-unscopables: 1.1.0
6371 +
6372 + array.prototype.flatmap@1.3.3:
6373 + dependencies:
6374 + call-bind: 1.0.9
6375 + define-properties: 1.2.1
6376 + es-abstract: 1.24.2
6377 + es-shim-unscopables: 1.1.0
6378 +
6379 + array.prototype.tosorted@1.1.4:
6380 + dependencies:
6381 + call-bind: 1.0.9
6382 + define-properties: 1.2.1
6383 + es-abstract: 1.24.2
6384 + es-errors: 1.3.0
6385 + es-shim-unscopables: 1.1.0
6386 +
6387 + arraybuffer.prototype.slice@1.0.4:
6388 + dependencies:
6389 + array-buffer-byte-length: 1.0.2
6390 + call-bind: 1.0.9
6391 + define-properties: 1.2.1
6392 + es-abstract: 1.24.2
6393 + es-errors: 1.3.0
6394 + get-intrinsic: 1.3.0
6395 + is-array-buffer: 3.0.5
6396 +
6397 + assertion-error@2.0.1: {}
6398 +
6399 + ast-types-flow@0.0.8: {}
6400 +
6401 + async-function@1.0.0: {}
6402 +
6403 + available-typed-arrays@1.0.7:
6404 + dependencies:
6405 + possible-typed-array-names: 1.1.0
6406 +
6407 + axe-core@4.13.0: {}
6408 +
6409 + axobject-query@4.1.0: {}
6410 +
6411 + bail@2.0.2: {}
6412 +
6413 + balanced-match@1.0.2: {}
6414 +
6415 + balanced-match@4.0.4: {}
6416 +
6417 + base64-js@1.5.1: {}
6418 +
6419 + baseline-browser-mapping@2.11.21: {}
6420 +
6421 + better-auth@1.7.3(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@types/pg@8.23.1)(kysely@0.29.5)(pg@8.23.0))(next@16.3.4(@babel/core@7.29.7)(@playwright/test@1.63.0)(@types/node@24.13.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(pg@8.23.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@3.2.7(@types/debug@4.1.13)(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)):
6422 + dependencies:
6423 + '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3)
6424 + '@better-auth/drizzle-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@types/pg@8.23.1)(kysely@0.29.5)(pg@8.23.0))
6425 + '@better-auth/kysely-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)(kysely@0.29.5)
6426 + '@better-auth/memory-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)
6427 + '@better-auth/mongo-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)
6428 + '@better-auth/prisma-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)
6429 + '@better-auth/telemetry': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.12)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)
6430 + '@better-auth/utils': 0.4.2
6431 + '@better-fetch/fetch': 1.3.1
6432 + '@noble/ciphers': 2.4.0
6433 + '@noble/hashes': 2.4.0
6434 + better-call: 1.4.0(zod@4.5.4)
6435 + defu: 6.1.7
6436 + jose: 6.2.12
6437 + kysely: 0.29.5
6438 + nanostores: 1.5.3
6439 + zod: 4.5.4
6440 + optionalDependencies:
6441 + drizzle-kit: 0.31.10
6442 + drizzle-orm: 0.45.2(@types/pg@8.23.1)(kysely@0.29.5)(pg@8.23.0)
6443 + next: 16.3.4(@babel/core@7.29.7)(@playwright/test@1.63.0)(@types/node@24.13.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
6444 + pg: 8.23.0
6445 + react: 19.2.8
6446 + react-dom: 19.2.8(react@19.2.8)
6447 + vitest: 3.2.7(@types/debug@4.1.13)(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)
6448 + transitivePeerDependencies:
6449 + - '@cloudflare/workers-types'
6450 + - '@opentelemetry/api'
6451 +
6452 + better-call@1.4.0(zod@4.5.4):
6453 + dependencies:
6454 + '@better-auth/utils': 0.5.0
6455 + '@better-fetch/fetch': 1.3.1
6456 + rou3: 0.9.2
6457 + set-cookie-parser: 3.1.2
6458 + optionalDependencies:
6459 + zod: 4.5.4
6460 +
6461 + bignumber.js@9.3.1: {}
6462 +
6463 + brace-expansion@1.1.18:
6464 + dependencies:
6465 + balanced-match: 1.0.2
6466 + concat-map: 0.0.1
6467 +
6468 + brace-expansion@5.0.9:
6469 + dependencies:
6470 + balanced-match: 4.0.4
6471 +
6472 + braces@3.0.3:
6473 + dependencies:
6474 + fill-range: 7.1.1
6475 +
6476 + browserslist@4.28.9:
6477 + dependencies:
6478 + baseline-browser-mapping: 2.11.21
6479 + caniuse-lite: 1.0.30001810
6480 + electron-to-chromium: 1.5.422
6481 + node-releases: 2.0.54
6482 + update-browserslist-db: 1.3.2(browserslist@4.28.9)
6483 +
6484 + buffer-equal-constant-time@1.0.1: {}
6485 +
6486 + buffer-from@1.1.2: {}
6487 +
6488 + cac@6.7.14: {}
6489 +
6490 + call-bind-apply-helpers@1.0.2:
6491 + dependencies:
6492 + es-errors: 1.3.0
6493 + function-bind: 1.1.2
6494 +
6495 + call-bind@1.0.9:
6496 + dependencies:
6497 + call-bind-apply-helpers: 1.0.2
6498 + es-define-property: 1.0.1
6499 + get-intrinsic: 1.3.0
6500 + set-function-length: 1.2.2
6501 +
6502 + call-bound@1.0.4:
6503 + dependencies:
6504 + call-bind-apply-helpers: 1.0.2
6505 + get-intrinsic: 1.3.0
6506 +
6507 + callsites@3.1.0: {}
6508 +
6509 + caniuse-lite@1.0.30001810: {}
6510 +
6511 + ccount@2.0.1: {}
6512 +
6513 + chai@5.3.3:
6514 + dependencies:
6515 + assertion-error: 2.0.1
6516 + check-error: 2.1.3
6517 + deep-eql: 5.0.2
6518 + loupe: 3.2.1
6519 + pathval: 2.0.1
6520 +
6521 + chalk@4.1.2:
6522 + dependencies:
6523 + ansi-styles: 4.3.0
6524 + supports-color: 7.2.0
6525 +
6526 + character-entities-html4@2.1.0: {}
6527 +
6528 + character-entities-legacy@3.0.0: {}
6529 +
6530 + character-entities@2.0.2: {}
6531 +
6532 + character-reference-invalid@2.0.1: {}
6533 +
6534 + check-error@2.1.3: {}
6535 +
6536 + class-variance-authority@0.7.1:
6537 + dependencies:
6538 + clsx: 2.1.1
6539 +
6540 + client-only@0.0.1: {}
6541 +
6542 + clsx@2.1.1: {}
6543 +
6544 + cmdk@1.1.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
6545 + dependencies:
6546 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8)
6547 + '@radix-ui/react-dialog': 1.1.23(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
6548 + '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8)
6549 + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
6550 + react: 19.2.8
6551 + react-dom: 19.2.8(react@19.2.8)
6552 + transitivePeerDependencies:
6553 + - '@types/react'
6554 + - '@types/react-dom'
6555 +
6556 + color-convert@2.0.1:
6557 + dependencies:
6558 + color-name: 1.1.4
6559 +
6560 + color-name@1.1.4: {}
6561 +
6562 + comma-separated-tokens@2.0.3: {}
6563 +
6564 + concat-map@0.0.1: {}
6565 +
6566 + convert-source-map@2.0.0: {}
6567 +
6568 + cross-env@10.1.0:
6569 + dependencies:
6570 + '@epic-web/invariant': 1.0.0
6571 + cross-spawn: 7.0.6
6572 +
6573 + cross-spawn@7.0.6:
6574 + dependencies:
6575 + path-key: 3.1.1
6576 + shebang-command: 2.0.0
6577 + which: 2.0.2
6578 +
6579 + csstype@3.2.3: {}
6580 +
6581 + d3-array@3.2.4:
6582 + dependencies:
6583 + internmap: 2.0.3
6584 +
6585 + d3-color@3.1.0: {}
6586 +
6587 + d3-ease@3.0.1: {}
6588 +
6589 + d3-format@3.1.2: {}
6590 +
6591 + d3-interpolate@3.0.1:
6592 + dependencies:
6593 + d3-color: 3.1.0
6594 +
6595 + d3-path@3.1.0: {}
6596 +
6597 + d3-scale@4.0.2:
6598 + dependencies:
6599 + d3-array: 3.2.4
6600 + d3-format: 3.1.2
6601 + d3-interpolate: 3.0.1
6602 + d3-time: 3.1.0
6603 + d3-time-format: 4.1.0
6604 +
6605 + d3-shape@3.2.0:
6606 + dependencies:
6607 + d3-path: 3.1.0
6608 +
6609 + d3-time-format@4.1.0:
6610 + dependencies:
6611 + d3-time: 3.1.0
6612 +
6613 + d3-time@3.1.0:
6614 + dependencies:
6615 + d3-array: 3.2.4
6616 +
6617 + d3-timer@3.0.1: {}
6618 +
6619 + damerau-levenshtein@1.0.8: {}
6620 +
6621 + data-uri-to-buffer@4.0.1: {}
6622 +
6623 + data-view-buffer@1.0.2:
6624 + dependencies:
6625 + call-bound: 1.0.4
6626 + es-errors: 1.3.0
6627 + is-data-view: 1.0.2
6628 +
6629 + data-view-byte-length@1.0.2:
6630 + dependencies:
6631 + call-bound: 1.0.4
6632 + es-errors: 1.3.0
6633 + is-data-view: 1.0.2
6634 +
6635 + data-view-byte-offset@1.0.1:
6636 + dependencies:
6637 + call-bound: 1.0.4
6638 + es-errors: 1.3.0
6639 + is-data-view: 1.0.2
6640 +
6641 + debug@3.2.7:
6642 + dependencies:
6643 + ms: 2.1.3
6644 +
6645 + debug@4.4.3:
6646 + dependencies:
6647 + ms: 2.1.3
6648 +
6649 + decimal.js-light@2.5.1: {}
6650 +
6651 + decode-named-character-reference@1.3.0:
6652 + dependencies:
6653 + character-entities: 2.0.2
6654 +
6655 + deep-eql@5.0.2: {}
6656 +
6657 + deep-is@0.1.4: {}
6658 +
6659 + define-data-property@1.1.4:
6660 + dependencies:
6661 + es-define-property: 1.0.1
6662 + es-errors: 1.3.0
6663 + gopd: 1.2.0
6664 +
6665 + define-properties@1.2.1:
6666 + dependencies:
6667 + define-data-property: 1.1.4
6668 + has-property-descriptors: 1.0.2
6669 + object-keys: 1.1.1
6670 +
6671 + defu@6.1.7: {}
6672 +
6673 + dequal@2.0.3: {}
6674 +
6675 + detect-libc@2.1.2: {}
6676 +
6677 + detect-node-es@1.1.0: {}
6678 +
6679 + devlop@1.1.0:
6680 + dependencies:
6681 + dequal: 2.0.3
6682 +
6683 + doctrine@2.1.0:
6684 + dependencies:
6685 + esutils: 2.0.3
6686 +
6687 + drizzle-kit@0.31.10:
6688 + dependencies:
6689 + '@drizzle-team/brocli': 0.10.2
6690 + '@esbuild-kit/esm-loader': 2.6.5
6691 + esbuild: 0.25.12
6692 + tsx: 4.23.13
6693 +
6694 + drizzle-orm@0.45.2(@types/pg@8.23.1)(kysely@0.29.5)(pg@8.23.0):
6695 + optionalDependencies:
6696 + '@types/pg': 8.23.1
6697 + kysely: 0.29.5
6698 + pg: 8.23.0
6699 +
6700 + dunder-proto@1.0.1:
6701 + dependencies:
6702 + call-bind-apply-helpers: 1.0.2
6703 + es-errors: 1.3.0
6704 + gopd: 1.2.0
6705 +
6706 + ecdsa-sig-formatter@1.0.11:
6707 + dependencies:
6708 + safe-buffer: 5.2.1
6709 +
6710 + electron-to-chromium@1.5.422: {}
6711 +
6712 + emoji-regex@9.2.2: {}
6713 +
6714 + enhanced-resolve@5.24.5:
6715 + dependencies:
6716 + graceful-fs: 4.2.11
6717 + tapable: 2.3.3
6718 +
6719 + entities@6.0.1: {}
6720 +
6721 + es-abstract-get@1.0.0:
6722 + dependencies:
6723 + es-errors: 1.3.0
6724 + es-object-atoms: 1.1.2
6725 + is-callable: 1.2.7
6726 + object-inspect: 1.13.4
6727 +
6728 + es-abstract@1.24.2:
6729 + dependencies:
6730 + array-buffer-byte-length: 1.0.2
6731 + arraybuffer.prototype.slice: 1.0.4
6732 + available-typed-arrays: 1.0.7
6733 + call-bind: 1.0.9
6734 + call-bound: 1.0.4
6735 + data-view-buffer: 1.0.2
6736 + data-view-byte-length: 1.0.2
6737 + data-view-byte-offset: 1.0.1
6738 + es-define-property: 1.0.1
6739 + es-errors: 1.3.0
6740 + es-object-atoms: 1.1.2
6741 + es-set-tostringtag: 2.1.0
6742 + es-to-primitive: 1.3.4
6743 + function.prototype.name: 1.2.0
6744 + get-intrinsic: 1.3.0
6745 + get-proto: 1.0.1
6746 + get-symbol-description: 1.1.0
6747 + globalthis: 1.0.4
6748 + gopd: 1.2.0
6749 + has-property-descriptors: 1.0.2
6750 + has-proto: 1.2.0
6751 + has-symbols: 1.1.0
6752 + hasown: 2.0.4
6753 + internal-slot: 1.1.0
6754 + is-array-buffer: 3.0.5
6755 + is-callable: 1.2.7
6756 + is-data-view: 1.0.2
6757 + is-negative-zero: 2.0.3
6758 + is-regex: 1.2.1
6759 + is-set: 2.0.3
6760 + is-shared-array-buffer: 1.0.4
6761 + is-string: 1.1.1
6762 + is-typed-array: 1.1.15
6763 + is-weakref: 1.1.1
6764 + math-intrinsics: 1.1.0
6765 + object-inspect: 1.13.4
6766 + object-keys: 1.1.1
6767 + object.assign: 4.1.7
6768 + own-keys: 1.0.2
6769 + regexp.prototype.flags: 1.5.4
6770 + safe-array-concat: 1.1.4
6771 + safe-push-apply: 1.0.0
6772 + safe-regex-test: 1.1.0
6773 + set-proto: 1.0.0
6774 + stop-iteration-iterator: 1.1.0
6775 + string.prototype.trim: 1.2.11
6776 + string.prototype.trimend: 1.0.10
6777 + string.prototype.trimstart: 1.0.8
6778 + typed-array-buffer: 1.0.3
6779 + typed-array-byte-length: 1.0.3
6780 + typed-array-byte-offset: 1.0.4
6781 + typed-array-length: 1.0.8
6782 + unbox-primitive: 1.1.0
6783 + which-typed-array: 1.1.22
6784 +
6785 + es-define-property@1.0.1: {}
6786 +
6787 + es-errors@1.3.0: {}
6788 +
6789 + es-iterator-helpers@1.4.0:
6790 + dependencies:
6791 + call-bind: 1.0.9
6792 + call-bound: 1.0.4
6793 + define-properties: 1.2.1
6794 + es-abstract: 1.24.2
6795 + es-errors: 1.3.0
6796 + es-set-tostringtag: 2.1.0
6797 + function-bind: 1.1.2
6798 + get-intrinsic: 1.3.0
6799 + globalthis: 1.0.4
6800 + gopd: 1.2.0
6801 + has-property-descriptors: 1.0.2
6802 + has-proto: 1.2.0
6803 + has-symbols: 1.1.0
6804 + internal-slot: 1.1.0
6805 + iterator.prototype: 1.1.5
6806 + math-intrinsics: 1.1.0
6807 +
6808 + es-module-lexer@1.7.0: {}
6809 +
6810 + es-object-atoms@1.1.2:
6811 + dependencies:
6812 + es-errors: 1.3.0
6813 +
6814 + es-set-tostringtag@2.1.0:
6815 + dependencies:
6816 + es-errors: 1.3.0
6817 + get-intrinsic: 1.3.0
6818 + has-tostringtag: 1.0.2
6819 + hasown: 2.0.4
6820 +
6821 + es-shim-unscopables@1.1.0:
6822 + dependencies:
6823 + hasown: 2.0.4
6824 +
6825 + es-to-primitive@1.3.4:
6826 + dependencies:
6827 + es-abstract-get: 1.0.0
6828 + es-define-property: 1.0.1
6829 + es-errors: 1.3.0
6830 + is-callable: 1.2.7
6831 + is-date-object: 1.1.0
6832 + is-symbol: 1.1.1
6833 +
6834 + es-toolkit@1.52.0: {}
6835 +
6836 + esbuild@0.18.20:
6837 + optionalDependencies:
6838 + '@esbuild/android-arm': 0.18.20
6839 + '@esbuild/android-arm64': 0.18.20
6840 + '@esbuild/android-x64': 0.18.20
6841 + '@esbuild/darwin-arm64': 0.18.20
6842 + '@esbuild/darwin-x64': 0.18.20
6843 + '@esbuild/freebsd-arm64': 0.18.20
6844 + '@esbuild/freebsd-x64': 0.18.20
6845 + '@esbuild/linux-arm': 0.18.20
6846 + '@esbuild/linux-arm64': 0.18.20
6847 + '@esbuild/linux-ia32': 0.18.20
6848 + '@esbuild/linux-loong64': 0.18.20
6849 + '@esbuild/linux-mips64el': 0.18.20
6850 + '@esbuild/linux-ppc64': 0.18.20
6851 + '@esbuild/linux-riscv64': 0.18.20
6852 + '@esbuild/linux-s390x': 0.18.20
6853 + '@esbuild/linux-x64': 0.18.20
6854 + '@esbuild/netbsd-x64': 0.18.20
6855 + '@esbuild/openbsd-x64': 0.18.20
6856 + '@esbuild/sunos-x64': 0.18.20
6857 + '@esbuild/win32-arm64': 0.18.20
6858 + '@esbuild/win32-ia32': 0.18.20
6859 + '@esbuild/win32-x64': 0.18.20
6860 +
6861 + esbuild@0.25.12:
6862 + optionalDependencies:
6863 + '@esbuild/aix-ppc64': 0.25.12
6864 + '@esbuild/android-arm': 0.25.12
6865 + '@esbuild/android-arm64': 0.25.12
6866 + '@esbuild/android-x64': 0.25.12
6867 + '@esbuild/darwin-arm64': 0.25.12
6868 + '@esbuild/darwin-x64': 0.25.12
6869 + '@esbuild/freebsd-arm64': 0.25.12
6870 + '@esbuild/freebsd-x64': 0.25.12
6871 + '@esbuild/linux-arm': 0.25.12
6872 + '@esbuild/linux-arm64': 0.25.12
6873 + '@esbuild/linux-ia32': 0.25.12
6874 + '@esbuild/linux-loong64': 0.25.12
6875 + '@esbuild/linux-mips64el': 0.25.12
6876 + '@esbuild/linux-ppc64': 0.25.12
6877 + '@esbuild/linux-riscv64': 0.25.12
6878 + '@esbuild/linux-s390x': 0.25.12
6879 + '@esbuild/linux-x64': 0.25.12
6880 + '@esbuild/netbsd-arm64': 0.25.12
6881 + '@esbuild/netbsd-x64': 0.25.12
6882 + '@esbuild/openbsd-arm64': 0.25.12
6883 + '@esbuild/openbsd-x64': 0.25.12
6884 + '@esbuild/openharmony-arm64': 0.25.12
6885 + '@esbuild/sunos-x64': 0.25.12
6886 + '@esbuild/win32-arm64': 0.25.12
6887 + '@esbuild/win32-ia32': 0.25.12
6888 + '@esbuild/win32-x64': 0.25.12
6889 +
6890 + esbuild@0.28.2:
6891 + optionalDependencies:
6892 + '@esbuild/aix-ppc64': 0.28.2
6893 + '@esbuild/android-arm': 0.28.2
6894 + '@esbuild/android-arm64': 0.28.2
6895 + '@esbuild/android-x64': 0.28.2
6896 + '@esbuild/darwin-arm64': 0.28.2
6897 + '@esbuild/darwin-x64': 0.28.2
6898 + '@esbuild/freebsd-arm64': 0.28.2
6899 + '@esbuild/freebsd-x64': 0.28.2
6900 + '@esbuild/linux-arm': 0.28.2
6901 + '@esbuild/linux-arm64': 0.28.2
6902 + '@esbuild/linux-ia32': 0.28.2
6903 + '@esbuild/linux-loong64': 0.28.2
6904 + '@esbuild/linux-mips64el': 0.28.2
6905 + '@esbuild/linux-ppc64': 0.28.2
6906 + '@esbuild/linux-riscv64': 0.28.2
6907 + '@esbuild/linux-s390x': 0.28.2
6908 + '@esbuild/linux-x64': 0.28.2
6909 + '@esbuild/netbsd-arm64': 0.28.2
6910 + '@esbuild/netbsd-x64': 0.28.2
6911 + '@esbuild/openbsd-arm64': 0.28.2
6912 + '@esbuild/openbsd-x64': 0.28.2
6913 + '@esbuild/openharmony-arm64': 0.28.2
6914 + '@esbuild/sunos-x64': 0.28.2
6915 + '@esbuild/win32-arm64': 0.28.2
6916 + '@esbuild/win32-ia32': 0.28.2
6917 + '@esbuild/win32-x64': 0.28.2
6918 +
6919 + escalade@3.2.0: {}
6920 +
6921 + escape-string-regexp@4.0.0: {}
6922 +
6923 + escape-string-regexp@5.0.0: {}
6924 +
6925 + eslint-config-next@16.3.4(@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3):
6926 + dependencies:
6927 + '@next/eslint-plugin-next': 16.3.4(eslint@9.39.5(jiti@2.7.0))
6928 + eslint: 9.39.5(jiti@2.7.0)
6929 + eslint-import-resolver-node: 0.3.10
6930 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0))
6931 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0))
6932 + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.5(jiti@2.7.0))
6933 + eslint-plugin-react: 7.37.5(eslint@9.39.5(jiti@2.7.0))
6934 + eslint-plugin-react-hooks: 7.1.1(eslint@9.39.5(jiti@2.7.0))
6935 + globals: 16.4.0
6936 + typescript-eslint: 8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
6937 + optionalDependencies:
6938 + typescript: 5.9.3
6939 + transitivePeerDependencies:
6940 + - '@typescript-eslint/parser'
6941 + - eslint-import-resolver-webpack
6942 + - eslint-plugin-import-x
6943 + - supports-color
6944 +
6945 + eslint-import-resolver-node@0.3.10:
6946 + dependencies:
6947 + debug: 3.2.7
6948 + is-core-module: 2.16.2
6949 + resolve: 2.0.0-next.7
6950 + transitivePeerDependencies:
6951 + - supports-color
6952 +
6953 + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)):
6954 + dependencies:
6955 + '@nolyfill/is-core-module': 1.0.39
6956 + debug: 4.4.3
6957 + eslint: 9.39.5(jiti@2.7.0)
6958 + get-tsconfig: 4.14.3
6959 + is-bun-module: 2.0.0
6960 + stable-hash: 0.0.5
6961 + tinyglobby: 0.2.17
6962 + unrs-resolver: 1.12.2
6963 + optionalDependencies:
6964 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0))
6965 + transitivePeerDependencies:
6966 + - supports-color
6967 +
6968 + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)):
6969 + dependencies:
6970 + debug: 3.2.7
6971 + optionalDependencies:
6972 + '@typescript-eslint/parser': 8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
6973 + eslint: 9.39.5(jiti@2.7.0)
6974 + eslint-import-resolver-node: 0.3.10
6975 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0))
6976 + transitivePeerDependencies:
6977 + - supports-color
6978 +
6979 + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)):
6980 + dependencies:
6981 + '@rtsao/scc': 1.1.0
6982 + array-includes: 3.1.9
6983 + array.prototype.findlastindex: 1.2.6
6984 + array.prototype.flat: 1.3.3
6985 + array.prototype.flatmap: 1.3.3
6986 + debug: 3.2.7
6987 + doctrine: 2.1.0
6988 + eslint: 9.39.5(jiti@2.7.0)
6989 + eslint-import-resolver-node: 0.3.10
6990 + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0))
6991 + hasown: 2.0.4
6992 + is-core-module: 2.16.2
6993 + is-glob: 4.0.3
6994 + minimatch: 3.1.5
6995 + object.fromentries: 2.0.8
6996 + object.groupby: 1.0.3
6997 + object.values: 1.2.1
6998 + semver: 6.3.1
6999 + string.prototype.trimend: 1.0.10
7000 + tsconfig-paths: 3.15.0
7001 + optionalDependencies:
7002 + '@typescript-eslint/parser': 8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
7003 + transitivePeerDependencies:
7004 + - eslint-import-resolver-typescript
7005 + - eslint-import-resolver-webpack
7006 + - supports-color
7007 +
7008 + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.5(jiti@2.7.0)):
7009 + dependencies:
7010 + aria-query: 5.3.2
7011 + array-includes: 3.1.9
7012 + array.prototype.flatmap: 1.3.3
7013 + ast-types-flow: 0.0.8
7014 + axe-core: 4.13.0
7015 + axobject-query: 4.1.0
7016 + damerau-levenshtein: 1.0.8
7017 + emoji-regex: 9.2.2
7018 + eslint: 9.39.5(jiti@2.7.0)
7019 + hasown: 2.0.4
7020 + jsx-ast-utils: 3.3.5
7021 + language-tags: 1.0.9
7022 + minimatch: 3.1.5
7023 + object.fromentries: 2.0.8
7024 + safe-regex-test: 1.1.0
7025 + string.prototype.includes: 2.0.1
7026 +
7027 + eslint-plugin-react-hooks@7.1.1(eslint@9.39.5(jiti@2.7.0)):
7028 + dependencies:
7029 + '@babel/core': 7.29.7
7030 + '@babel/parser': 7.29.8
7031 + eslint: 9.39.5(jiti@2.7.0)
7032 + hermes-parser: 0.25.1
7033 + zod: 4.5.4
7034 + zod-validation-error: 4.0.2(zod@4.5.4)
7035 + transitivePeerDependencies:
7036 + - supports-color
7037 +
7038 + eslint-plugin-react@7.37.5(eslint@9.39.5(jiti@2.7.0)):
7039 + dependencies:
7040 + array-includes: 3.1.9
7041 + array.prototype.findlast: 1.2.5
7042 + array.prototype.flatmap: 1.3.3
7043 + array.prototype.tosorted: 1.1.4
7044 + doctrine: 2.1.0
7045 + es-iterator-helpers: 1.4.0
7046 + eslint: 9.39.5(jiti@2.7.0)
7047 + estraverse: 5.3.0
7048 + hasown: 2.0.4
7049 + jsx-ast-utils: 3.3.5
7050 + minimatch: 3.1.5
7051 + object.entries: 1.1.9
7052 + object.fromentries: 2.0.8
7053 + object.values: 1.2.1
7054 + prop-types: 15.8.1
7055 + resolve: 2.0.0-next.7
7056 + semver: 6.3.1
7057 + string.prototype.matchall: 4.1.0
7058 + string.prototype.repeat: 1.0.0
7059 +
7060 + eslint-scope@8.4.0:
7061 + dependencies:
7062 + esrecurse: 4.3.0
7063 + estraverse: 5.3.0
7064 +
7065 + eslint-visitor-keys@3.4.3: {}
7066 +
7067 + eslint-visitor-keys@4.2.1: {}
7068 +
7069 + eslint-visitor-keys@5.0.1: {}
7070 +
7071 + eslint@9.39.5(jiti@2.7.0):
7072 + dependencies:
7073 + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0))
7074 + '@eslint-community/regexpp': 4.12.2
7075 + '@eslint/config-array': 0.21.2
7076 + '@eslint/config-helpers': 0.4.2
7077 + '@eslint/core': 0.17.0
7078 + '@eslint/eslintrc': 3.3.7
7079 + '@eslint/js': 9.39.5
7080 + '@eslint/plugin-kit': 0.4.1
7081 + '@humanfs/node': 0.16.8
7082 + '@humanwhocodes/module-importer': 1.0.1
7083 + '@humanwhocodes/retry': 0.4.3
7084 + '@types/estree': 1.0.9
7085 + ajv: 6.15.0
7086 + chalk: 4.1.2
7087 + cross-spawn: 7.0.6
7088 + debug: 4.4.3
7089 + escape-string-regexp: 4.0.0
7090 + eslint-scope: 8.4.0
7091 + eslint-visitor-keys: 4.2.1
7092 + espree: 10.4.0
7093 + esquery: 1.7.0
7094 + esutils: 2.0.3
7095 + fast-deep-equal: 3.1.3
7096 + file-entry-cache: 8.0.0
7097 + find-up: 5.0.0
7098 + glob-parent: 6.0.2
7099 + ignore: 5.3.2
7100 + imurmurhash: 0.1.4
7101 + is-glob: 4.0.3
7102 + json-stable-stringify-without-jsonify: 1.0.1
7103 + lodash.merge: 4.6.2
7104 + minimatch: 3.1.5
7105 + natural-compare: 1.4.0
7106 + optionator: 0.9.4
7107 + optionalDependencies:
7108 + jiti: 2.7.0
7109 + transitivePeerDependencies:
7110 + - supports-color
7111 +
7112 + espree@10.4.0:
7113 + dependencies:
7114 + acorn: 8.18.0
7115 + acorn-jsx: 5.3.2(acorn@8.18.0)
7116 + eslint-visitor-keys: 4.2.1
7117 +
7118 + esquery@1.7.0:
7119 + dependencies:
7120 + estraverse: 5.3.0
7121 +
7122 + esrecurse@4.3.0:
7123 + dependencies:
7124 + estraverse: 5.3.0
7125 +
7126 + estraverse@5.3.0: {}
7127 +
7128 + estree-util-is-identifier-name@3.0.0: {}
7129 +
7130 + estree-walker@3.0.3:
7131 + dependencies:
7132 + '@types/estree': 1.0.9
7133 +
7134 + esutils@2.0.3: {}
7135 +
7136 + eventemitter3@5.0.4: {}
7137 +
7138 + expect-type@1.4.0: {}
7139 +
7140 + extend@3.0.2: {}
7141 +
7142 + fast-deep-equal@3.1.3: {}
7143 +
7144 + fast-glob@3.3.1:
7145 + dependencies:
7146 + '@nodelib/fs.stat': 2.0.5
7147 + '@nodelib/fs.walk': 1.2.8
7148 + glob-parent: 5.1.2
7149 + merge2: 1.4.1
7150 + micromatch: 4.0.8
7151 +
7152 + fast-json-stable-stringify@2.1.0: {}
7153 +
7154 + fast-levenshtein@2.0.6: {}
7155 +
7156 + fast-sha256@1.3.0: {}
7157 +
7158 + fastq@1.20.3:
7159 + dependencies:
7160 + reusify: 1.1.0
7161 +
7162 + fdir@6.5.0(picomatch@4.0.7):
7163 + optionalDependencies:
7164 + picomatch: 4.0.7
7165 +
7166 + fetch-blob@3.2.0:
7167 + dependencies:
7168 + node-domexception: 1.0.0
7169 + web-streams-polyfill: 3.3.3
7170 +
7171 + file-entry-cache@8.0.0:
7172 + dependencies:
7173 + flat-cache: 4.0.1
7174 +
7175 + fill-range@7.1.1:
7176 + dependencies:
7177 + to-regex-range: 5.0.1
7178 +
7179 + find-up@5.0.0:
7180 + dependencies:
7181 + locate-path: 6.0.0
7182 + path-exists: 4.0.0
7183 +
7184 + flat-cache@4.0.1:
7185 + dependencies:
7186 + flatted: 3.4.4
7187 + keyv: 4.5.4
7188 +
7189 + flatted@3.4.4: {}
7190 +
7191 + for-each@0.3.5:
7192 + dependencies:
7193 + is-callable: 1.2.7
7194 +
7195 + formdata-polyfill@4.0.10:
7196 + dependencies:
7197 + fetch-blob: 3.2.0
7198 +
7199 + framer-motion@12.43.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
7200 + dependencies:
7201 + motion-dom: 12.43.0
7202 + motion-utils: 12.39.0
7203 + tslib: 2.8.1
7204 + optionalDependencies:
7205 + react: 19.2.8
7206 + react-dom: 19.2.8(react@19.2.8)
7207 +
7208 + fsevents@2.3.3:
7209 + optional: true
7210 +
7211 + function-bind@1.1.2: {}
7212 +
7213 + function.prototype.name@1.2.0:
7214 + dependencies:
7215 + call-bind: 1.0.9
7216 + call-bound: 1.0.4
7217 + es-define-property: 1.0.1
7218 + es-errors: 1.3.0
7219 + functions-have-names: 1.2.3
7220 + has-property-descriptors: 1.0.2
7221 + hasown: 2.0.4
7222 + is-callable: 1.2.7
7223 + is-document.all: 1.0.0
7224 +
7225 + functions-have-names@1.2.3: {}
7226 +
7227 + gaxios@7.3.1:
7228 + dependencies:
7229 + extend: 3.0.2
7230 + https-proxy-agent: 7.0.6
7231 + node-fetch: 3.3.2
7232 + transitivePeerDependencies:
7233 + - supports-color
7234 +
7235 + gcp-metadata@8.1.2:
7236 + dependencies:
7237 + gaxios: 7.3.1
7238 + google-logging-utils: 1.1.3
7239 + json-bigint: 1.0.0
7240 + transitivePeerDependencies:
7241 + - supports-color
7242 +
7243 + geist@1.7.2(next@16.3.4(@babel/core@7.29.7)(@playwright/test@1.63.0)(@types/node@24.13.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)):
7244 + dependencies:
7245 + next: 16.3.4(@babel/core@7.29.7)(@playwright/test@1.63.0)(@types/node@24.13.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
7246 +
7247 + generator-function@2.0.1: {}
7248 +
7249 + gensync@1.0.0-beta.2: {}
7250 +
7251 + get-intrinsic@1.3.0:
7252 + dependencies:
7253 + call-bind-apply-helpers: 1.0.2
7254 + es-define-property: 1.0.1
7255 + es-errors: 1.3.0
7256 + es-object-atoms: 1.1.2
7257 + function-bind: 1.1.2
7258 + get-proto: 1.0.1
7259 + gopd: 1.2.0
7260 + has-symbols: 1.1.0
7261 + hasown: 2.0.4
7262 + math-intrinsics: 1.1.0
7263 +
7264 + get-nonce@1.0.1: {}
7265 +
7266 + get-proto@1.0.1:
7267 + dependencies:
7268 + dunder-proto: 1.0.1
7269 + es-object-atoms: 1.1.2
7270 +
7271 + get-symbol-description@1.1.0:
7272 + dependencies:
7273 + call-bound: 1.0.4
7274 + es-errors: 1.3.0
7275 + get-intrinsic: 1.3.0
7276 +
7277 + get-tsconfig@4.14.3:
7278 + dependencies:
7279 + resolve-pkg-maps: 1.0.0
7280 +
7281 + glob-parent@5.1.2:
7282 + dependencies:
7283 + is-glob: 4.0.3
7284 +
7285 + glob-parent@6.0.2:
7286 + dependencies:
7287 + is-glob: 4.0.3
7288 +
7289 + globals@14.0.0: {}
7290 +
7291 + globals@16.4.0: {}
7292 +
7293 + globalthis@1.0.4:
7294 + dependencies:
7295 + define-properties: 1.2.1
7296 + gopd: 1.2.0
7297 +
7298 + google-auth-library@10.9.1:
7299 + dependencies:
7300 + base64-js: 1.5.1
7301 + ecdsa-sig-formatter: 1.0.11
7302 + gaxios: 7.3.1
7303 + gcp-metadata: 8.1.2
7304 + google-logging-utils: 1.1.3
7305 + jws: 4.0.1
7306 + transitivePeerDependencies:
7307 + - supports-color
7308 +
7309 + google-logging-utils@1.1.3: {}
7310 +
7311 + gopd@1.2.0: {}
7312 +
7313 + graceful-fs@4.2.11: {}
7314 +
7315 + has-bigints@1.1.0: {}
7316 +
7317 + has-flag@4.0.0: {}
7318 +
7319 + has-property-descriptors@1.0.2:
7320 + dependencies:
7321 + es-define-property: 1.0.1
7322 +
7323 + has-proto@1.2.0:
7324 + dependencies:
7325 + dunder-proto: 1.0.1
7326 +
7327 + has-symbols@1.1.0: {}
7328 +
7329 + has-tostringtag@1.0.2:
7330 + dependencies:
7331 + has-symbols: 1.1.0
7332 +
7333 + hasown@2.0.4:
7334 + dependencies:
7335 + function-bind: 1.1.2
7336 +
7337 + hast-util-from-parse5@8.0.3:
7338 + dependencies:
7339 + '@types/hast': 3.0.5
7340 + '@types/unist': 3.0.3
7341 + devlop: 1.1.0
7342 + hastscript: 9.0.1
7343 + property-information: 7.2.0
7344 + vfile: 6.0.3
7345 + vfile-location: 5.0.3
7346 + web-namespaces: 2.0.1
7347 +
7348 + hast-util-parse-selector@4.0.0:
7349 + dependencies:
7350 + '@types/hast': 3.0.5
7351 +
7352 + hast-util-raw@9.1.0:
7353 + dependencies:
7354 + '@types/hast': 3.0.5
7355 + '@types/unist': 3.0.3
7356 + '@ungap/structured-clone': 1.4.0
7357 + hast-util-from-parse5: 8.0.3
7358 + hast-util-to-parse5: 8.0.1
7359 + html-void-elements: 3.0.0
7360 + mdast-util-to-hast: 13.2.1
7361 + parse5: 7.3.0
7362 + unist-util-position: 5.0.0
7363 + unist-util-visit: 5.1.0
7364 + vfile: 6.0.3
7365 + web-namespaces: 2.0.1
7366 + zwitch: 2.0.4
7367 +
7368 + hast-util-to-html@9.0.5:
7369 + dependencies:
7370 + '@types/hast': 3.0.5
7371 + '@types/unist': 3.0.3
7372 + ccount: 2.0.1
7373 + comma-separated-tokens: 2.0.3
7374 + hast-util-whitespace: 3.0.0
7375 + html-void-elements: 3.0.0
7376 + mdast-util-to-hast: 13.2.1
7377 + property-information: 7.2.0
7378 + space-separated-tokens: 2.0.2
7379 + stringify-entities: 4.0.4
7380 + zwitch: 2.0.4
7381 +
7382 + hast-util-to-jsx-runtime@2.3.6:
7383 + dependencies:
7384 + '@types/estree': 1.0.9
7385 + '@types/hast': 3.0.5
7386 + '@types/unist': 3.0.3
7387 + comma-separated-tokens: 2.0.3
7388 + devlop: 1.1.0
7389 + estree-util-is-identifier-name: 3.0.0
7390 + hast-util-whitespace: 3.0.0
7391 + mdast-util-mdx-expression: 2.0.1
7392 + mdast-util-mdx-jsx: 3.2.0
7393 + mdast-util-mdxjs-esm: 2.0.1
7394 + property-information: 7.2.0
7395 + space-separated-tokens: 2.0.2
7396 + style-to-js: 1.1.21
7397 + unist-util-position: 5.0.0
7398 + vfile-message: 4.0.3
7399 + transitivePeerDependencies:
7400 + - supports-color
7401 +
7402 + hast-util-to-parse5@8.0.1:
7403 + dependencies:
7404 + '@types/hast': 3.0.5
7405 + comma-separated-tokens: 2.0.3
7406 + devlop: 1.1.0
7407 + property-information: 7.2.0
7408 + space-separated-tokens: 2.0.2
7409 + web-namespaces: 2.0.1
7410 + zwitch: 2.0.4
7411 +
7412 + hast-util-whitespace@3.0.0:
7413 + dependencies:
7414 + '@types/hast': 3.0.5
7415 +
7416 + hastscript@9.0.1:
7417 + dependencies:
7418 + '@types/hast': 3.0.5
7419 + comma-separated-tokens: 2.0.3
7420 + hast-util-parse-selector: 4.0.0
7421 + property-information: 7.2.0
7422 + space-separated-tokens: 2.0.2
7423 +
7424 + hermes-estree@0.25.1: {}
7425 +
7426 + hermes-parser@0.25.1:
7427 + dependencies:
7428 + hermes-estree: 0.25.1
7429 +
7430 + html-url-attributes@3.0.1: {}
7431 +
7432 + html-void-elements@3.0.0: {}
7433 +
7434 + https-proxy-agent@7.0.6:
7435 + dependencies:
7436 + agent-base: 7.1.4
7437 + debug: 4.4.3
7438 + transitivePeerDependencies:
7439 + - supports-color
7440 +
7441 + ignore@5.3.2: {}
7442 +
7443 + ignore@7.0.8: {}
7444 +
7445 + immer@11.1.18: {}
7446 +
7447 + import-fresh@3.3.1:
7448 + dependencies:
7449 + parent-module: 1.0.1
7450 + resolve-from: 4.0.0
7451 +
7452 + imurmurhash@0.1.4: {}
7453 +
7454 + inline-style-parser@0.2.7: {}
7455 +
7456 + internal-slot@1.1.0:
7457 + dependencies:
7458 + es-errors: 1.3.0
7459 + hasown: 2.0.4
7460 + side-channel: 1.1.1
7461 +
7462 + internmap@2.0.3: {}
7463 +
7464 + is-alphabetical@2.0.1: {}
7465 +
7466 + is-alphanumerical@2.0.1:
7467 + dependencies:
7468 + is-alphabetical: 2.0.1
7469 + is-decimal: 2.0.1
7470 +
7471 + is-array-buffer@3.0.5:
7472 + dependencies:
7473 + call-bind: 1.0.9
7474 + call-bound: 1.0.4
7475 + get-intrinsic: 1.3.0
7476 +
7477 + is-async-function@2.1.1:
7478 + dependencies:
7479 + async-function: 1.0.0
7480 + call-bound: 1.0.4
7481 + get-proto: 1.0.1
7482 + has-tostringtag: 1.0.2
7483 + safe-regex-test: 1.1.0
7484 +
7485 + is-bigint@1.1.0:
7486 + dependencies:
7487 + has-bigints: 1.1.0
7488 +
7489 + is-boolean-object@1.2.2:
7490 + dependencies:
7491 + call-bound: 1.0.4
7492 + has-tostringtag: 1.0.2
7493 +
7494 + is-bun-module@2.0.0:
7495 + dependencies:
7496 + semver: 7.8.5
7497 +
7498 + is-callable@1.2.7: {}
7499 +
7500 + is-core-module@2.16.2:
7501 + dependencies:
7502 + hasown: 2.0.4
7503 +
7504 + is-data-view@1.0.2:
7505 + dependencies:
7506 + call-bound: 1.0.4
7507 + get-intrinsic: 1.3.0
7508 + is-typed-array: 1.1.15
7509 +
7510 + is-date-object@1.1.0:
7511 + dependencies:
7512 + call-bound: 1.0.4
7513 + has-tostringtag: 1.0.2
7514 +
7515 + is-decimal@2.0.1: {}
7516 +
7517 + is-document.all@1.0.0:
7518 + dependencies:
7519 + call-bound: 1.0.4
7520 +
7521 + is-extglob@2.1.1: {}
7522 +
7523 + is-finalizationregistry@1.1.1:
7524 + dependencies:
7525 + call-bound: 1.0.4
7526 +
7527 + is-generator-function@1.1.2:
7528 + dependencies:
7529 + call-bound: 1.0.4
7530 + generator-function: 2.0.1
7531 + get-proto: 1.0.1
7532 + has-tostringtag: 1.0.2
7533 + safe-regex-test: 1.1.0
7534 +
7535 + is-glob@4.0.3:
7536 + dependencies:
7537 + is-extglob: 2.1.1
7538 +
7539 + is-hexadecimal@2.0.1: {}
7540 +
7541 + is-map@2.0.3: {}
7542 +
7543 + is-negative-zero@2.0.3: {}
7544 +
7545 + is-number-object@1.1.1:
7546 + dependencies:
7547 + call-bound: 1.0.4
7548 + has-tostringtag: 1.0.2
7549 +
7550 + is-number@7.0.0: {}
7551 +
7552 + is-plain-obj@4.1.0: {}
7553 +
7554 + is-regex@1.2.1:
7555 + dependencies:
7556 + call-bound: 1.0.4
7557 + gopd: 1.2.0
7558 + has-tostringtag: 1.0.2
7559 + hasown: 2.0.4
7560 +
7561 + is-set@2.0.3: {}
7562 +
7563 + is-shared-array-buffer@1.0.4:
7564 + dependencies:
7565 + call-bound: 1.0.4
7566 +
7567 + is-string@1.1.1:
7568 + dependencies:
7569 + call-bound: 1.0.4
7570 + has-tostringtag: 1.0.2
7571 +
7572 + is-symbol@1.1.1:
7573 + dependencies:
7574 + call-bound: 1.0.4
7575 + has-symbols: 1.1.0
7576 + safe-regex-test: 1.1.0
7577 +
7578 + is-typed-array@1.1.15:
7579 + dependencies:
7580 + which-typed-array: 1.1.22
7581 +
7582 + is-weakmap@2.0.2: {}
7583 +
7584 + is-weakref@1.1.1:
7585 + dependencies:
7586 + call-bound: 1.0.4
7587 +
7588 + is-weakset@2.0.4:
7589 + dependencies:
7590 + call-bound: 1.0.4
7591 + get-intrinsic: 1.3.0
7592 +
7593 + isarray@2.0.5: {}
7594 +
7595 + isexe@2.0.0: {}
7596 +
7597 + iterator.prototype@1.1.5:
7598 + dependencies:
7599 + define-data-property: 1.1.4
7600 + es-object-atoms: 1.1.2
7601 + get-intrinsic: 1.3.0
7602 + get-proto: 1.0.1
7603 + has-symbols: 1.1.0
7604 + set-function-name: 2.0.2
7605 +
7606 + jiti@2.7.0: {}
7607 +
7608 + jose@6.2.12: {}
7609 +
7610 + js-tokens@4.0.0: {}
7611 +
7612 + js-tokens@9.0.1: {}
7613 +
7614 + js-yaml@4.3.2:
7615 + dependencies:
7616 + argparse: 2.0.1
7617 +
7618 + jsesc@3.1.0: {}
7619 +
7620 + json-bigint@1.0.0:
7621 + dependencies:
7622 + bignumber.js: 9.3.1
7623 +
7624 + json-buffer@3.0.1: {}
7625 +
7626 + json-schema-to-ts@3.1.1:
7627 + dependencies:
7628 + '@babel/runtime': 7.29.7
7629 + ts-algebra: 2.0.0
7630 +
7631 + json-schema-traverse@0.4.1: {}
7632 +
7633 + json-stable-stringify-without-jsonify@1.0.1: {}
7634 +
7635 + json5@1.0.2:
7636 + dependencies:
7637 + minimist: 1.2.8
7638 +
7639 + json5@2.2.3: {}
7640 +
7641 + jsx-ast-utils@3.3.5:
7642 + dependencies:
7643 + array-includes: 3.1.9
7644 + array.prototype.flat: 1.3.3
7645 + object.assign: 4.1.7
7646 + object.values: 1.2.1
7647 +
7648 + jwa@2.0.1:
7649 + dependencies:
7650 + buffer-equal-constant-time: 1.0.1
7651 + ecdsa-sig-formatter: 1.0.11
7652 + safe-buffer: 5.2.1
7653 +
7654 + jws@4.0.1:
7655 + dependencies:
7656 + jwa: 2.0.1
7657 + safe-buffer: 5.2.1
7658 +
7659 + keyv@4.5.4:
7660 + dependencies:
7661 + json-buffer: 3.0.1
7662 +
7663 + kysely@0.29.5: {}
7664 +
7665 + language-subtag-registry@0.3.23: {}
7666 +
7667 + language-tags@1.0.9:
7668 + dependencies:
7669 + language-subtag-registry: 0.3.23
7670 +
7671 + levn@0.4.1:
7672 + dependencies:
7673 + prelude-ls: 1.2.1
7674 + type-check: 0.4.0
7675 +
7676 + lightningcss-android-arm64@1.32.0:
7677 + optional: true
7678 +
7679 + lightningcss-darwin-arm64@1.32.0:
7680 + optional: true
7681 +
7682 + lightningcss-darwin-x64@1.32.0:
7683 + optional: true
7684 +
7685 + lightningcss-freebsd-x64@1.32.0:
7686 + optional: true
7687 +
7688 + lightningcss-linux-arm-gnueabihf@1.32.0:
7689 + optional: true
7690 +
7691 + lightningcss-linux-arm64-gnu@1.32.0:
7692 + optional: true
7693 +
7694 + lightningcss-linux-arm64-musl@1.32.0:
7695 + optional: true
7696 +
7697 + lightningcss-linux-x64-gnu@1.32.0:
7698 + optional: true
7699 +
7700 + lightningcss-linux-x64-musl@1.32.0:
7701 + optional: true
7702 +
7703 + lightningcss-win32-arm64-msvc@1.32.0:
7704 + optional: true
7705 +
7706 + lightningcss-win32-x64-msvc@1.32.0:
7707 + optional: true
7708 +
7709 + lightningcss@1.32.0:
7710 + dependencies:
7711 + detect-libc: 2.1.2
7712 + optionalDependencies:
7713 + lightningcss-android-arm64: 1.32.0
7714 + lightningcss-darwin-arm64: 1.32.0
7715 + lightningcss-darwin-x64: 1.32.0
7716 + lightningcss-freebsd-x64: 1.32.0
7717 + lightningcss-linux-arm-gnueabihf: 1.32.0
7718 + lightningcss-linux-arm64-gnu: 1.32.0
7719 + lightningcss-linux-arm64-musl: 1.32.0
7720 + lightningcss-linux-x64-gnu: 1.32.0
7721 + lightningcss-linux-x64-musl: 1.32.0
7722 + lightningcss-win32-arm64-msvc: 1.32.0
7723 + lightningcss-win32-x64-msvc: 1.32.0
7724 +
7725 + locate-path@6.0.0:
7726 + dependencies:
7727 + p-locate: 5.0.0
7728 +
7729 + lodash.merge@4.6.2: {}
7730 +
7731 + long@5.3.2: {}
7732 +
7733 + longest-streak@3.1.0: {}
7734 +
7735 + loose-envify@1.4.0:
7736 + dependencies:
7737 + js-tokens: 4.0.0
7738 +
7739 + loupe@3.2.1: {}
7740 +
7741 + lru-cache@5.1.1:
7742 + dependencies:
7743 + yallist: 3.1.1
7744 +
7745 + lucide-react@1.42.0(react@19.2.8):
7746 + dependencies:
7747 + react: 19.2.8
7748 +
7749 + magic-string@0.30.21:
7750 + dependencies:
7751 + '@jridgewell/sourcemap-codec': 1.6.0
7752 +
7753 + markdown-table@3.0.4: {}
7754 +
7755 + math-intrinsics@1.1.0: {}
7756 +
7757 + mdast-util-find-and-replace@3.0.2:
7758 + dependencies:
7759 + '@types/mdast': 4.0.4
7760 + escape-string-regexp: 5.0.0
7761 + unist-util-is: 6.0.1
7762 + unist-util-visit-parents: 6.0.2
7763 +
7764 + mdast-util-from-markdown@2.0.3:
7765 + dependencies:
7766 + '@types/mdast': 4.0.4
7767 + '@types/unist': 3.0.3
7768 + decode-named-character-reference: 1.3.0
7769 + devlop: 1.1.0
7770 + mdast-util-to-string: 4.0.0
7771 + micromark: 4.0.2
7772 + micromark-util-decode-numeric-character-reference: 2.0.2
7773 + micromark-util-decode-string: 2.0.1
7774 + micromark-util-normalize-identifier: 2.0.1
7775 + micromark-util-symbol: 2.0.1
7776 + micromark-util-types: 2.0.2
7777 + unist-util-stringify-position: 4.0.0
7778 + transitivePeerDependencies:
7779 + - supports-color
7780 +
7781 + mdast-util-gfm-autolink-literal@2.0.1:
7782 + dependencies:
7783 + '@types/mdast': 4.0.4
7784 + ccount: 2.0.1
7785 + devlop: 1.1.0
7786 + mdast-util-find-and-replace: 3.0.2
7787 + micromark-util-character: 2.1.1
7788 +
7789 + mdast-util-gfm-footnote@2.1.0:
7790 + dependencies:
7791 + '@types/mdast': 4.0.4
7792 + devlop: 1.1.0
7793 + mdast-util-from-markdown: 2.0.3
7794 + mdast-util-to-markdown: 2.1.2
7795 + micromark-util-normalize-identifier: 2.0.1
7796 + transitivePeerDependencies:
7797 + - supports-color
7798 +
7799 + mdast-util-gfm-strikethrough@2.0.0:
7800 + dependencies:
7801 + '@types/mdast': 4.0.4
7802 + mdast-util-from-markdown: 2.0.3
7803 + mdast-util-to-markdown: 2.1.2
7804 + transitivePeerDependencies:
7805 + - supports-color
7806 +
7807 + mdast-util-gfm-table@2.0.0:
7808 + dependencies:
7809 + '@types/mdast': 4.0.4
7810 + devlop: 1.1.0
7811 + markdown-table: 3.0.4
7812 + mdast-util-from-markdown: 2.0.3
7813 + mdast-util-to-markdown: 2.1.2
7814 + transitivePeerDependencies:
7815 + - supports-color
7816 +
7817 + mdast-util-gfm-task-list-item@2.0.0:
7818 + dependencies:
7819 + '@types/mdast': 4.0.4
7820 + devlop: 1.1.0
7821 + mdast-util-from-markdown: 2.0.3
7822 + mdast-util-to-markdown: 2.1.2
7823 + transitivePeerDependencies:
7824 + - supports-color
7825 +
7826 + mdast-util-gfm@3.1.0:
7827 + dependencies:
7828 + mdast-util-from-markdown: 2.0.3
7829 + mdast-util-gfm-autolink-literal: 2.0.1
7830 + mdast-util-gfm-footnote: 2.1.0
7831 + mdast-util-gfm-strikethrough: 2.0.0
7832 + mdast-util-gfm-table: 2.0.0
7833 + mdast-util-gfm-task-list-item: 2.0.0
7834 + mdast-util-to-markdown: 2.1.2
7835 + transitivePeerDependencies:
7836 + - supports-color
7837 +
7838 + mdast-util-mdx-expression@2.0.1:
7839 + dependencies:
7840 + '@types/estree-jsx': 1.0.5
7841 + '@types/hast': 3.0.5
7842 + '@types/mdast': 4.0.4
7843 + devlop: 1.1.0
7844 + mdast-util-from-markdown: 2.0.3
7845 + mdast-util-to-markdown: 2.1.2
7846 + transitivePeerDependencies:
7847 + - supports-color
7848 +
7849 + mdast-util-mdx-jsx@3.2.0:
7850 + dependencies:
7851 + '@types/estree-jsx': 1.0.5
7852 + '@types/hast': 3.0.5
7853 + '@types/mdast': 4.0.4
7854 + '@types/unist': 3.0.3
7855 + ccount: 2.0.1
7856 + devlop: 1.1.0
7857 + mdast-util-from-markdown: 2.0.3
7858 + mdast-util-to-markdown: 2.1.2
7859 + parse-entities: 4.0.2
7860 + stringify-entities: 4.0.4
7861 + unist-util-stringify-position: 4.0.0
7862 + vfile-message: 4.0.3
7863 + transitivePeerDependencies:
7864 + - supports-color
7865 +
7866 + mdast-util-mdxjs-esm@2.0.1:
7867 + dependencies:
7868 + '@types/estree-jsx': 1.0.5
7869 + '@types/hast': 3.0.5
7870 + '@types/mdast': 4.0.4
7871 + devlop: 1.1.0
7872 + mdast-util-from-markdown: 2.0.3
7873 + mdast-util-to-markdown: 2.1.2
7874 + transitivePeerDependencies:
7875 + - supports-color
7876 +
7877 + mdast-util-phrasing@4.1.0:
7878 + dependencies:
7879 + '@types/mdast': 4.0.4
7880 + unist-util-is: 6.0.1
7881 +
7882 + mdast-util-to-hast@13.2.1:
7883 + dependencies:
7884 + '@types/hast': 3.0.5
7885 + '@types/mdast': 4.0.4
7886 + '@ungap/structured-clone': 1.4.0
7887 + devlop: 1.1.0
7888 + micromark-util-sanitize-uri: 2.0.1
7889 + trim-lines: 3.0.1
7890 + unist-util-position: 5.0.0
7891 + unist-util-visit: 5.1.0
7892 + vfile: 6.0.3
7893 +
7894 + mdast-util-to-markdown@2.1.2:
7895 + dependencies:
7896 + '@types/mdast': 4.0.4
7897 + '@types/unist': 3.0.3
7898 + longest-streak: 3.1.0
7899 + mdast-util-phrasing: 4.1.0
7900 + mdast-util-to-string: 4.0.0
7901 + micromark-util-classify-character: 2.0.1
7902 + micromark-util-decode-string: 2.0.1
7903 + unist-util-visit: 5.1.0
7904 + zwitch: 2.0.4
7905 +
7906 + mdast-util-to-string@4.0.0:
7907 + dependencies:
7908 + '@types/mdast': 4.0.4
7909 +
7910 + merge2@1.4.1: {}
7911 +
7912 + micromark-core-commonmark@2.0.3:
7913 + dependencies:
7914 + decode-named-character-reference: 1.3.0
7915 + devlop: 1.1.0
7916 + micromark-factory-destination: 2.0.1
7917 + micromark-factory-label: 2.0.1
7918 + micromark-factory-space: 2.0.1
7919 + micromark-factory-title: 2.0.1
7920 + micromark-factory-whitespace: 2.0.1
7921 + micromark-util-character: 2.1.1
7922 + micromark-util-chunked: 2.0.1
7923 + micromark-util-classify-character: 2.0.1
7924 + micromark-util-html-tag-name: 2.0.1
7925 + micromark-util-normalize-identifier: 2.0.1
7926 + micromark-util-resolve-all: 2.0.1
7927 + micromark-util-subtokenize: 2.1.0
7928 + micromark-util-symbol: 2.0.1
7929 + micromark-util-types: 2.0.2
7930 +
7931 + micromark-extension-gfm-autolink-literal@2.1.0:
7932 + dependencies:
7933 + micromark-util-character: 2.1.1
7934 + micromark-util-sanitize-uri: 2.0.1
7935 + micromark-util-symbol: 2.0.1
7936 + micromark-util-types: 2.0.2
7937 +
7938 + micromark-extension-gfm-footnote@2.1.0:
7939 + dependencies:
7940 + devlop: 1.1.0
7941 + micromark-core-commonmark: 2.0.3
7942 + micromark-factory-space: 2.0.1
7943 + micromark-util-character: 2.1.1
7944 + micromark-util-normalize-identifier: 2.0.1
7945 + micromark-util-sanitize-uri: 2.0.1
7946 + micromark-util-symbol: 2.0.1
7947 + micromark-util-types: 2.0.2
7948 +
7949 + micromark-extension-gfm-strikethrough@2.1.0:
7950 + dependencies:
7951 + devlop: 1.1.0
7952 + micromark-util-chunked: 2.0.1
7953 + micromark-util-classify-character: 2.0.1
7954 + micromark-util-resolve-all: 2.0.1
7955 + micromark-util-symbol: 2.0.1
7956 + micromark-util-types: 2.0.2
7957 +
7958 + micromark-extension-gfm-table@2.1.1:
7959 + dependencies:
7960 + devlop: 1.1.0
7961 + micromark-factory-space: 2.0.1
7962 + micromark-util-character: 2.1.1
7963 + micromark-util-symbol: 2.0.1
7964 + micromark-util-types: 2.0.2
7965 +
7966 + micromark-extension-gfm-tagfilter@2.0.0:
7967 + dependencies:
7968 + micromark-util-types: 2.0.2
7969 +
7970 + micromark-extension-gfm-task-list-item@2.1.0:
7971 + dependencies:
7972 + devlop: 1.1.0
7973 + micromark-factory-space: 2.0.1
7974 + micromark-util-character: 2.1.1
7975 + micromark-util-symbol: 2.0.1
7976 + micromark-util-types: 2.0.2
7977 +
7978 + micromark-extension-gfm@3.0.0:
7979 + dependencies:
7980 + micromark-extension-gfm-autolink-literal: 2.1.0
7981 + micromark-extension-gfm-footnote: 2.1.0
7982 + micromark-extension-gfm-strikethrough: 2.1.0
7983 + micromark-extension-gfm-table: 2.1.1
7984 + micromark-extension-gfm-tagfilter: 2.0.0
7985 + micromark-extension-gfm-task-list-item: 2.1.0
7986 + micromark-util-combine-extensions: 2.0.1
7987 + micromark-util-types: 2.0.2
7988 +
7989 + micromark-factory-destination@2.0.1:
7990 + dependencies:
7991 + micromark-util-character: 2.1.1
7992 + micromark-util-symbol: 2.0.1
7993 + micromark-util-types: 2.0.2
7994 +
7995 + micromark-factory-label@2.0.1:
7996 + dependencies:
7997 + devlop: 1.1.0
7998 + micromark-util-character: 2.1.1
7999 + micromark-util-symbol: 2.0.1
8000 + micromark-util-types: 2.0.2
8001 +
8002 + micromark-factory-space@2.0.1:
8003 + dependencies:
8004 + micromark-util-character: 2.1.1
8005 + micromark-util-types: 2.0.2
8006 +
8007 + micromark-factory-title@2.0.1:
8008 + dependencies:
8009 + micromark-factory-space: 2.0.1
8010 + micromark-util-character: 2.1.1
8011 + micromark-util-symbol: 2.0.1
8012 + micromark-util-types: 2.0.2
8013 +
8014 + micromark-factory-whitespace@2.0.1:
8015 + dependencies:
8016 + micromark-factory-space: 2.0.1
8017 + micromark-util-character: 2.1.1
8018 + micromark-util-symbol: 2.0.1
8019 + micromark-util-types: 2.0.2
8020 +
8021 + micromark-util-character@2.1.1:
8022 + dependencies:
8023 + micromark-util-symbol: 2.0.1
8024 + micromark-util-types: 2.0.2
8025 +
8026 + micromark-util-chunked@2.0.1:
8027 + dependencies:
8028 + micromark-util-symbol: 2.0.1
8029 +
8030 + micromark-util-classify-character@2.0.1:
8031 + dependencies:
8032 + micromark-util-character: 2.1.1
8033 + micromark-util-symbol: 2.0.1
8034 + micromark-util-types: 2.0.2
8035 +
8036 + micromark-util-combine-extensions@2.0.1:
8037 + dependencies:
8038 + micromark-util-chunked: 2.0.1
8039 + micromark-util-types: 2.0.2
8040 +
8041 + micromark-util-decode-numeric-character-reference@2.0.2:
8042 + dependencies:
8043 + micromark-util-symbol: 2.0.1
8044 +
8045 + micromark-util-decode-string@2.0.1:
8046 + dependencies:
8047 + decode-named-character-reference: 1.3.0
8048 + micromark-util-character: 2.1.1
8049 + micromark-util-decode-numeric-character-reference: 2.0.2
8050 + micromark-util-symbol: 2.0.1
8051 +
8052 + micromark-util-encode@2.0.1: {}
8053 +
8054 + micromark-util-html-tag-name@2.0.1: {}
8055 +
8056 + micromark-util-normalize-identifier@2.0.1:
8057 + dependencies:
8058 + micromark-util-symbol: 2.0.1
8059 +
8060 + micromark-util-resolve-all@2.0.1:
8061 + dependencies:
8062 + micromark-util-types: 2.0.2
8063 +
8064 + micromark-util-sanitize-uri@2.0.1:
8065 + dependencies:
8066 + micromark-util-character: 2.1.1
8067 + micromark-util-encode: 2.0.1
8068 + micromark-util-symbol: 2.0.1
8069 +
8070 + micromark-util-subtokenize@2.1.0:
8071 + dependencies:
8072 + devlop: 1.1.0
8073 + micromark-util-chunked: 2.0.1
8074 + micromark-util-symbol: 2.0.1
8075 + micromark-util-types: 2.0.2
8076 +
8077 + micromark-util-symbol@2.0.1: {}
8078 +
8079 + micromark-util-types@2.0.2: {}
8080 +
8081 + micromark@4.0.2:
8082 + dependencies:
8083 + '@types/debug': 4.1.13
8084 + debug: 4.4.3
8085 + decode-named-character-reference: 1.3.0
8086 + devlop: 1.1.0
8087 + micromark-core-commonmark: 2.0.3
8088 + micromark-factory-space: 2.0.1
8089 + micromark-util-character: 2.1.1
8090 + micromark-util-chunked: 2.0.1
8091 + micromark-util-combine-extensions: 2.0.1
8092 + micromark-util-decode-numeric-character-reference: 2.0.2
8093 + micromark-util-encode: 2.0.1
8094 + micromark-util-normalize-identifier: 2.0.1
8095 + micromark-util-resolve-all: 2.0.1
8096 + micromark-util-sanitize-uri: 2.0.1
8097 + micromark-util-subtokenize: 2.1.0
8098 + micromark-util-symbol: 2.0.1
8099 + micromark-util-types: 2.0.2
8100 + transitivePeerDependencies:
8101 + - supports-color
8102 +
8103 + micromatch@4.0.8:
8104 + dependencies:
8105 + braces: 3.0.3
8106 + picomatch: 2.3.2
8107 +
8108 + minimatch@10.2.6:
8109 + dependencies:
8110 + brace-expansion: 5.0.9
8111 +
8112 + minimatch@3.1.5:
8113 + dependencies:
8114 + brace-expansion: 1.1.18
8115 +
8116 + minimist@1.2.8: {}
8117 +
8118 + motion-dom@12.43.0:
8119 + dependencies:
8120 + motion-utils: 12.39.0
8121 +
8122 + motion-utils@12.39.0: {}
8123 +
8124 + motion@12.43.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
8125 + dependencies:
8126 + framer-motion: 12.43.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
8127 + tslib: 2.8.1
8128 + optionalDependencies:
8129 + react: 19.2.8
8130 + react-dom: 19.2.8(react@19.2.8)
8131 +
8132 + ms@2.1.3: {}
8133 +
8134 + nanoid@3.3.18: {}
8135 +
8136 + nanostores@1.5.3: {}
8137 +
8138 + napi-postinstall@0.3.4: {}
8139 +
8140 + natural-compare@1.4.0: {}
8141 +
8142 + next-themes@0.4.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
8143 + dependencies:
8144 + react: 19.2.8
8145 + react-dom: 19.2.8(react@19.2.8)
8146 +
8147 + next@16.3.4(@babel/core@7.29.7)(@playwright/test@1.63.0)(@types/node@24.13.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
8148 + dependencies:
8149 + '@next/env': 16.3.4
8150 + '@swc/helpers': 0.5.23
8151 + baseline-browser-mapping: 2.11.21
8152 + caniuse-lite: 1.0.30001810
8153 + postcss: 8.5.23
8154 + react: 19.2.8
8155 + react-dom: 19.2.8(react@19.2.8)
8156 + styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.8)
8157 + optionalDependencies:
8158 + '@next/swc-darwin-arm64': 16.3.4
8159 + '@next/swc-darwin-x64': 16.3.4
8160 + '@next/swc-linux-arm64-gnu': 16.3.4
8161 + '@next/swc-linux-arm64-musl': 16.3.4
8162 + '@next/swc-linux-x64-gnu': 16.3.4
8163 + '@next/swc-linux-x64-musl': 16.3.4
8164 + '@next/swc-win32-arm64-msvc': 16.3.4
8165 + '@next/swc-win32-x64-msvc': 16.3.4
8166 + '@playwright/test': 1.63.0
8167 + sharp: 0.35.4(@types/node@24.13.3)
8168 + transitivePeerDependencies:
8169 + - '@babel/core'
8170 + - '@types/node'
8171 + - babel-plugin-macros
8172 +
8173 + node-addon-api@8.9.2: {}
8174 +
8175 + node-domexception@1.0.0: {}
8176 +
8177 + node-exports-info@1.6.2:
8178 + dependencies:
8179 + array.prototype.flatmap: 1.3.3
8180 + es-errors: 1.3.0
8181 + object.entries: 1.1.9
8182 + semver: 6.3.1
8183 +
8184 + node-fetch@3.3.2:
8185 + dependencies:
8186 + data-uri-to-buffer: 4.0.1
8187 + fetch-blob: 3.2.0
8188 + formdata-polyfill: 4.0.10
8189 +
8190 + node-gyp-build@4.8.4: {}
8191 +
8192 + node-releases@2.0.54: {}
8193 +
8194 + object-assign@4.1.1: {}
8195 +
8196 + object-inspect@1.13.4: {}
8197 +
8198 + object-keys@1.1.1: {}
8199 +
8200 + object.assign@4.1.7:
8201 + dependencies:
8202 + call-bind: 1.0.9
8203 + call-bound: 1.0.4
8204 + define-properties: 1.2.1
8205 + es-object-atoms: 1.1.2
8206 + has-symbols: 1.1.0
8207 + object-keys: 1.1.1
8208 +
8209 + object.entries@1.1.9:
8210 + dependencies:
8211 + call-bind: 1.0.9
8212 + call-bound: 1.0.4
8213 + define-properties: 1.2.1
8214 + es-object-atoms: 1.1.2
8215 +
8216 + object.fromentries@2.0.8:
8217 + dependencies:
8218 + call-bind: 1.0.9
8219 + define-properties: 1.2.1
8220 + es-abstract: 1.24.2
8221 + es-object-atoms: 1.1.2
8222 +
8223 + object.groupby@1.0.3:
8224 + dependencies:
8225 + call-bind: 1.0.9
8226 + define-properties: 1.2.1
8227 + es-abstract: 1.24.2
8228 +
8229 + object.values@1.2.1:
8230 + dependencies:
8231 + call-bind: 1.0.9
8232 + call-bound: 1.0.4
8233 + define-properties: 1.2.1
8234 + es-object-atoms: 1.1.2
8235 +
8236 + oniguruma-parser@0.12.2: {}
8237 +
8238 + oniguruma-to-es@4.3.6:
8239 + dependencies:
8240 + oniguruma-parser: 0.12.2
8241 + regex: 6.1.0
8242 + regex-recursion: 6.0.2
8243 +
8244 + openai@7.10.0(ws@8.21.3)(zod@4.5.4):
8245 + optionalDependencies:
8246 + ws: 8.21.3
8247 + zod: 4.5.4
8248 +
8249 + optionator@0.9.4:
8250 + dependencies:
8251 + deep-is: 0.1.4
8252 + fast-levenshtein: 2.0.6
8253 + levn: 0.4.1
8254 + prelude-ls: 1.2.1
8255 + type-check: 0.4.0
8256 + word-wrap: 1.2.5
8257 +
8258 + own-keys@1.0.2:
8259 + dependencies:
8260 + call-bound: 1.0.4
8261 + get-intrinsic: 1.3.0
8262 + object-keys: 1.1.1
8263 + safe-push-apply: 1.0.0
8264 +
8265 + p-limit@3.1.0:
8266 + dependencies:
8267 + yocto-queue: 0.1.0
8268 +
8269 + p-locate@5.0.0:
8270 + dependencies:
8271 + p-limit: 3.1.0
8272 +
8273 + p-retry@4.6.2:
8274 + dependencies:
8275 + '@types/retry': 0.12.0
8276 + retry: 0.13.1
8277 +
8278 + parent-module@1.0.1:
8279 + dependencies:
8280 + callsites: 3.1.0
8281 +
8282 + parse-entities@4.0.2:
8283 + dependencies:
8284 + '@types/unist': 2.0.11
8285 + character-entities-legacy: 3.0.0
8286 + character-reference-invalid: 2.0.1
8287 + decode-named-character-reference: 1.3.0
8288 + is-alphanumerical: 2.0.1
8289 + is-decimal: 2.0.1
8290 + is-hexadecimal: 2.0.1
8291 +
8292 + parse5@7.3.0:
8293 + dependencies:
8294 + entities: 6.0.1
8295 +
8296 + path-exists@4.0.0: {}
8297 +
8298 + path-key@3.1.1: {}
8299 +
8300 + path-parse@1.0.7: {}
8301 +
8302 + pathe@2.0.3: {}
8303 +
8304 + pathval@2.0.1: {}
8305 +
8306 + pg-cloudflare@1.4.0:
8307 + optional: true
8308 +
8309 + pg-connection-string@2.14.0: {}
8310 +
8311 + pg-int8@1.0.1: {}
8312 +
8313 + pg-pool@3.14.0(pg@8.23.0):
8314 + dependencies:
8315 + pg: 8.23.0
8316 +
8317 + pg-protocol@1.16.0: {}
8318 +
8319 + pg-types@2.2.0:
8320 + dependencies:
8321 + pg-int8: 1.0.1
8322 + postgres-array: 2.0.0
8323 + postgres-bytea: 1.0.1
8324 + postgres-date: 1.0.7
8325 + postgres-interval: 1.2.0
8326 +
8327 + pg@8.23.0:
8328 + dependencies:
8329 + pg-connection-string: 2.14.0
8330 + pg-pool: 3.14.0(pg@8.23.0)
8331 + pg-protocol: 1.16.0
8332 + pg-types: 2.2.0
8333 + pgpass: 1.0.5
8334 + optionalDependencies:
8335 + pg-cloudflare: 1.4.0
8336 +
8337 + pgpass@1.0.5:
8338 + dependencies:
8339 + split2: 4.2.0
8340 +
8341 + picocolors@1.1.1: {}
8342 +
8343 + picomatch@2.3.2: {}
8344 +
8345 + picomatch@4.0.7: {}
8346 +
8347 + playwright-core@1.63.0: {}
8348 +
8349 + playwright@1.63.0:
8350 + dependencies:
8351 + playwright-core: 1.63.0
8352 +
8353 + possible-typed-array-names@1.1.0: {}
8354 +
8355 + postal-mime@2.7.5: {}
8356 +
8357 + postcss@8.5.23:
8358 + dependencies:
8359 + nanoid: 3.3.18
8360 + picocolors: 1.1.1
8361 + source-map-js: 1.2.1
8362 +
8363 + postcss@8.5.28:
8364 + dependencies:
8365 + nanoid: 3.3.18
8366 + picocolors: 1.1.1
8367 + source-map-js: 1.2.1
8368 +
8369 + postgres-array@2.0.0: {}
8370 +
8371 + postgres-bytea@1.0.1: {}
8372 +
8373 + postgres-date@1.0.7: {}
8374 +
8375 + postgres-interval@1.2.0:
8376 + dependencies:
8377 + xtend: 4.0.2
8378 +
8379 + prelude-ls@1.2.1: {}
8380 +
8381 + prop-types@15.8.1:
8382 + dependencies:
8383 + loose-envify: 1.4.0
8384 + object-assign: 4.1.1
8385 + react-is: 16.13.1
8386 +
8387 + property-information@7.2.0: {}
8388 +
8389 + protobufjs@7.6.6:
8390 + dependencies:
8391 + '@protobufjs/aspromise': 1.1.2
8392 + '@protobufjs/base64': 1.1.2
8393 + '@protobufjs/codegen': 2.0.5
8394 + '@protobufjs/eventemitter': 1.1.1
8395 + '@protobufjs/fetch': 1.1.1
8396 + '@protobufjs/float': 1.0.2
8397 + '@protobufjs/path': 1.1.2
8398 + '@protobufjs/pool': 1.1.0
8399 + '@protobufjs/utf8': 1.1.2
8400 + '@types/node': 24.13.3
8401 + long: 5.3.2
8402 +
8403 + punycode@2.3.1: {}
8404 +
8405 + queue-microtask@1.2.3: {}
8406 +
8407 + react-dom@19.2.8(react@19.2.8):
8408 + dependencies:
8409 + react: 19.2.8
8410 + scheduler: 0.27.0
8411 +
8412 + react-is@16.13.1: {}
8413 +
8414 + react-markdown@10.1.0(@types/react@19.2.18)(react@19.2.8):
8415 + dependencies:
8416 + '@types/hast': 3.0.5
8417 + '@types/mdast': 4.0.4
8418 + '@types/react': 19.2.18
8419 + devlop: 1.1.0
8420 + hast-util-to-jsx-runtime: 2.3.6
8421 + html-url-attributes: 3.0.1
8422 + mdast-util-to-hast: 13.2.1
8423 + react: 19.2.8
8424 + remark-parse: 11.0.0
8425 + remark-rehype: 11.1.2
8426 + unified: 11.0.5
8427 + unist-util-visit: 5.1.0
8428 + vfile: 6.0.3
8429 + transitivePeerDependencies:
8430 + - supports-color
8431 +
8432 + react-redux@9.3.0(@types/react@19.2.18)(react@19.2.8)(redux@5.0.1):
8433 + dependencies:
8434 + '@types/use-sync-external-store': 0.0.6
8435 + react: 19.2.8
8436 + use-sync-external-store: 1.6.0(react@19.2.8)
8437 + optionalDependencies:
8438 + '@types/react': 19.2.18
8439 + redux: 5.0.1
8440 +
8441 + react-remove-scroll-bar@2.3.8(@types/react@19.2.18)(react@19.2.8):
8442 + dependencies:
8443 + react: 19.2.8
8444 + react-style-singleton: 2.2.3(@types/react@19.2.18)(react@19.2.8)
8445 + tslib: 2.8.1
8446 + optionalDependencies:
8447 + '@types/react': 19.2.18
8448 +
8449 + react-remove-scroll@2.7.2(@types/react@19.2.18)(react@19.2.8):
8450 + dependencies:
8451 + react: 19.2.8
8452 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.18)(react@19.2.8)
8453 + react-style-singleton: 2.2.3(@types/react@19.2.18)(react@19.2.8)
8454 + tslib: 2.8.1
8455 + use-callback-ref: 1.3.3(@types/react@19.2.18)(react@19.2.8)
8456 + use-sidecar: 1.1.3(@types/react@19.2.18)(react@19.2.8)
8457 + optionalDependencies:
8458 + '@types/react': 19.2.18
8459 +
8460 + react-style-singleton@2.2.3(@types/react@19.2.18)(react@19.2.8):
8461 + dependencies:
8462 + get-nonce: 1.0.1
8463 + react: 19.2.8
8464 + tslib: 2.8.1
8465 + optionalDependencies:
8466 + '@types/react': 19.2.18
8467 +
8468 + react@19.2.8: {}
8469 +
8470 + recharts@3.10.1(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react-is@16.13.1)(react@19.2.8)(redux@5.0.1):
8471 + dependencies:
8472 + '@reduxjs/toolkit': 2.12.0(react-redux@9.3.0(@types/react@19.2.18)(react@19.2.8)(redux@5.0.1))(react@19.2.8)
8473 + clsx: 2.1.1
8474 + decimal.js-light: 2.5.1
8475 + es-toolkit: 1.52.0
8476 + eventemitter3: 5.0.4
8477 + immer: 11.1.18
8478 + react: 19.2.8
8479 + react-dom: 19.2.8(react@19.2.8)
8480 + react-is: 16.13.1
8481 + react-redux: 9.3.0(@types/react@19.2.18)(react@19.2.8)(redux@5.0.1)
8482 + reselect: 5.2.0
8483 + tiny-invariant: 1.3.3
8484 + use-sync-external-store: 1.6.0(react@19.2.8)
8485 + victory-vendor: 37.3.6
8486 + transitivePeerDependencies:
8487 + - '@types/react'
8488 + - redux
8489 +
8490 + redux-thunk@3.1.0(redux@5.0.1):
8491 + dependencies:
8492 + redux: 5.0.1
8493 +
8494 + redux@5.0.1: {}
8495 +
8496 + reflect.getprototypeof@1.0.10:
8497 + dependencies:
8498 + call-bind: 1.0.9
8499 + define-properties: 1.2.1
8500 + es-abstract: 1.24.2
8501 + es-errors: 1.3.0
8502 + es-object-atoms: 1.1.2
8503 + get-intrinsic: 1.3.0
8504 + get-proto: 1.0.1
8505 + which-builtin-type: 1.2.1
8506 +
8507 + regex-recursion@6.0.2:
8508 + dependencies:
8509 + regex-utilities: 2.3.0
8510 +
8511 + regex-utilities@2.3.0: {}
8512 +
8513 + regex@6.1.0:
8514 + dependencies:
8515 + regex-utilities: 2.3.0
8516 +
8517 + regexp.prototype.flags@1.5.4:
8518 + dependencies:
8519 + call-bind: 1.0.9
8520 + define-properties: 1.2.1
8521 + es-errors: 1.3.0
8522 + get-proto: 1.0.1
8523 + gopd: 1.2.0
8524 + set-function-name: 2.0.2
8525 +
8526 + rehype-raw@7.0.0:
8527 + dependencies:
8528 + '@types/hast': 3.0.5
8529 + hast-util-raw: 9.1.0
8530 + vfile: 6.0.3
8531 +
8532 + remark-gfm@4.0.1:
8533 + dependencies:
8534 + '@types/mdast': 4.0.4
8535 + mdast-util-gfm: 3.1.0
8536 + micromark-extension-gfm: 3.0.0
8537 + remark-parse: 11.0.0
8538 + remark-stringify: 11.0.0
8539 + unified: 11.0.5
8540 + transitivePeerDependencies:
8541 + - supports-color
8542 +
8543 + remark-parse@11.0.0:
8544 + dependencies:
8545 + '@types/mdast': 4.0.4
8546 + mdast-util-from-markdown: 2.0.3
8547 + micromark-util-types: 2.0.2
8548 + unified: 11.0.5
8549 + transitivePeerDependencies:
8550 + - supports-color
8551 +
8552 + remark-rehype@11.1.2:
8553 + dependencies:
8554 + '@types/hast': 3.0.5
8555 + '@types/mdast': 4.0.4
8556 + mdast-util-to-hast: 13.2.1
8557 + unified: 11.0.5
8558 + vfile: 6.0.3
8559 +
8560 + remark-stringify@11.0.0:
8561 + dependencies:
8562 + '@types/mdast': 4.0.4
8563 + mdast-util-to-markdown: 2.1.2
8564 + unified: 11.0.5
8565 +
8566 + reselect@5.2.0: {}
8567 +
8568 + resend@6.26.0:
8569 + dependencies:
8570 + postal-mime: 2.7.5
8571 + standardwebhooks: 1.0.0
8572 +
8573 + resolve-from@4.0.0: {}
8574 +
8575 + resolve-pkg-maps@1.0.0: {}
8576 +
8577 + resolve@2.0.0-next.7:
8578 + dependencies:
8579 + es-errors: 1.3.0
8580 + is-core-module: 2.16.2
8581 + node-exports-info: 1.6.2
8582 + object-keys: 1.1.1
8583 + path-parse: 1.0.7
8584 + supports-preserve-symlinks-flag: 1.0.0
8585 +
8586 + retry@0.13.1: {}
8587 +
8588 + reusify@1.1.0: {}
8589 +
8590 + rollup@4.63.1:
8591 + dependencies:
8592 + '@types/estree': 1.0.9
8593 + optionalDependencies:
8594 + '@napi-rs/lzma-linux-x64-gnu': 1.5.1
8595 + '@rollup/rollup-android-arm-eabi': 4.63.1
8596 + '@rollup/rollup-android-arm64': 4.63.1
8597 + '@rollup/rollup-darwin-arm64': 4.63.1
8598 + '@rollup/rollup-darwin-x64': 4.63.1
8599 + '@rollup/rollup-freebsd-arm64': 4.63.1
8600 + '@rollup/rollup-freebsd-x64': 4.63.1
8601 + '@rollup/rollup-linux-arm-gnueabihf': 4.63.1
8602 + '@rollup/rollup-linux-arm-musleabihf': 4.63.1
8603 + '@rollup/rollup-linux-arm64-gnu': 4.63.1
8604 + '@rollup/rollup-linux-arm64-musl': 4.63.1
8605 + '@rollup/rollup-linux-loong64-gnu': 4.63.1
8606 + '@rollup/rollup-linux-loong64-musl': 4.63.1
8607 + '@rollup/rollup-linux-ppc64-gnu': 4.63.1
8608 + '@rollup/rollup-linux-ppc64-musl': 4.63.1
8609 + '@rollup/rollup-linux-riscv64-gnu': 4.63.1
8610 + '@rollup/rollup-linux-riscv64-musl': 4.63.1
8611 + '@rollup/rollup-linux-s390x-gnu': 4.63.1
8612 + '@rollup/rollup-linux-x64-gnu': 4.63.1
8613 + '@rollup/rollup-linux-x64-musl': 4.63.1
8614 + '@rollup/rollup-openbsd-x64': 4.63.1
8615 + '@rollup/rollup-openharmony-arm64': 4.63.1
8616 + '@rollup/rollup-win32-arm64-msvc': 4.63.1
8617 + '@rollup/rollup-win32-ia32-msvc': 4.63.1
8618 + '@rollup/rollup-win32-x64-gnu': 4.63.1
8619 + '@rollup/rollup-win32-x64-msvc': 4.63.1
8620 + fsevents: 2.3.3
8621 +
8622 + rou3@0.9.2: {}
8623 +
8624 + run-parallel@1.2.0:
8625 + dependencies:
8626 + queue-microtask: 1.2.3
8627 +
8628 + safe-array-concat@1.1.4:
8629 + dependencies:
8630 + call-bind: 1.0.9
8631 + call-bound: 1.0.4
8632 + get-intrinsic: 1.3.0
8633 + has-symbols: 1.1.0
8634 + isarray: 2.0.5
8635 +
8636 + safe-buffer@5.2.1: {}
8637 +
8638 + safe-push-apply@1.0.0:
8639 + dependencies:
8640 + es-errors: 1.3.0
8641 + isarray: 2.0.5
8642 +
8643 + safe-regex-test@1.1.0:
8644 + dependencies:
8645 + call-bound: 1.0.4
8646 + es-errors: 1.3.0
8647 + is-regex: 1.2.1
8648 +
8649 + scheduler@0.27.0: {}
8650 +
8651 + semver@6.3.1: {}
8652 +
8653 + semver@7.8.5: {}
8654 +
8655 + server-only@0.0.1: {}
8656 +
8657 + set-cookie-parser@3.1.2: {}
8658 +
8659 + set-function-length@1.2.2:
8660 + dependencies:
8661 + define-data-property: 1.1.4
8662 + es-errors: 1.3.0
8663 + function-bind: 1.1.2
8664 + get-intrinsic: 1.3.0
8665 + gopd: 1.2.0
8666 + has-property-descriptors: 1.0.2
8667 +
8668 + set-function-name@2.0.2:
8669 + dependencies:
8670 + define-data-property: 1.1.4
8671 + es-errors: 1.3.0
8672 + functions-have-names: 1.2.3
8673 + has-property-descriptors: 1.0.2
8674 +
8675 + set-proto@1.0.0:
8676 + dependencies:
8677 + dunder-proto: 1.0.1
8678 + es-errors: 1.3.0
8679 + es-object-atoms: 1.1.2
8680 +
8681 + sharp@0.35.4(@types/node@24.13.3):
8682 + dependencies:
8683 + '@img/colour': 1.1.0
8684 + detect-libc: 2.1.2
8685 + semver: 7.8.5
8686 + optionalDependencies:
8687 + '@img/sharp-darwin-arm64': 0.35.4
8688 + '@img/sharp-darwin-x64': 0.35.4
8689 + '@img/sharp-freebsd-wasm32': 0.35.4
8690 + '@img/sharp-libvips-darwin-arm64': 1.3.3
8691 + '@img/sharp-libvips-darwin-x64': 1.3.3
8692 + '@img/sharp-libvips-linux-arm': 1.3.3
8693 + '@img/sharp-libvips-linux-arm64': 1.3.3
8694 + '@img/sharp-libvips-linux-ppc64': 1.3.3
8695 + '@img/sharp-libvips-linux-riscv64': 1.3.3
8696 + '@img/sharp-libvips-linux-s390x': 1.3.3
8697 + '@img/sharp-libvips-linux-x64': 1.3.3
8698 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.3
8699 + '@img/sharp-libvips-linuxmusl-x64': 1.3.3
8700 + '@img/sharp-linux-arm': 0.35.4
8701 + '@img/sharp-linux-arm64': 0.35.4
8702 + '@img/sharp-linux-ppc64': 0.35.4
8703 + '@img/sharp-linux-riscv64': 0.35.4
8704 + '@img/sharp-linux-s390x': 0.35.4
8705 + '@img/sharp-linux-x64': 0.35.4
8706 + '@img/sharp-linuxmusl-arm64': 0.35.4
8707 + '@img/sharp-linuxmusl-x64': 0.35.4
8708 + '@img/sharp-webcontainers-wasm32': 0.35.4
8709 + '@img/sharp-win32-arm64': 0.35.4
8710 + '@img/sharp-win32-ia32': 0.35.4
8711 + '@img/sharp-win32-x64': 0.35.4
8712 + '@types/node': 24.13.3
8713 + optional: true
8714 +
8715 + shebang-command@2.0.0:
8716 + dependencies:
8717 + shebang-regex: 3.0.0
8718 +
8719 + shebang-regex@3.0.0: {}
8720 +
8721 + shiki@4.4.3:
8722 + dependencies:
8723 + '@shikijs/core': 4.4.3
8724 + '@shikijs/engine-javascript': 4.4.3
8725 + '@shikijs/engine-oniguruma': 4.4.3
8726 + '@shikijs/langs': 4.4.3
8727 + '@shikijs/themes': 4.4.3
8728 + '@shikijs/types': 4.4.3
8729 + '@shikijs/vscode-textmate': 10.0.2
8730 + '@types/hast': 3.0.5
8731 +
8732 + side-channel-list@1.0.1:
8733 + dependencies:
8734 + es-errors: 1.3.0
8735 + object-inspect: 1.13.4
8736 +
8737 + side-channel-map@1.0.1:
8738 + dependencies:
8739 + call-bound: 1.0.4
8740 + es-errors: 1.3.0
8741 + get-intrinsic: 1.3.0
8742 + object-inspect: 1.13.4
8743 +
8744 + side-channel-weakmap@1.0.2:
8745 + dependencies:
8746 + call-bound: 1.0.4
8747 + es-errors: 1.3.0
8748 + get-intrinsic: 1.3.0
8749 + object-inspect: 1.13.4
8750 + side-channel-map: 1.0.1
8751 +
8752 + side-channel@1.1.1:
8753 + dependencies:
8754 + es-errors: 1.3.0
8755 + object-inspect: 1.13.4
8756 + side-channel-list: 1.0.1
8757 + side-channel-map: 1.0.1
8758 + side-channel-weakmap: 1.0.2
8759 +
8760 + siginfo@2.0.0: {}
8761 +
8762 + source-map-js@1.2.1: {}
8763 +
8764 + source-map-support@0.5.21:
8765 + dependencies:
8766 + buffer-from: 1.1.2
8767 + source-map: 0.6.1
8768 +
8769 + source-map@0.6.1: {}
8770 +
8771 + space-separated-tokens@2.0.2: {}
8772 +
8773 + split2@4.2.0: {}
8774 +
8775 + stable-hash@0.0.5: {}
8776 +
8777 + stackback@0.0.2: {}
8778 +
8779 + standardwebhooks@1.0.0:
8780 + dependencies:
8781 + '@stablelib/base64': 1.0.1
8782 + fast-sha256: 1.3.0
8783 +
8784 + standardwebhooks@1.1.1:
8785 + dependencies:
8786 + '@stablelib/base64': 1.0.1
8787 + fast-sha256: 1.3.0
8788 +
8789 + std-env@3.10.0: {}
8790 +
8791 + stop-iteration-iterator@1.1.0:
8792 + dependencies:
8793 + es-errors: 1.3.0
8794 + internal-slot: 1.1.0
8795 +
8796 + string.prototype.includes@2.0.1:
8797 + dependencies:
8798 + call-bind: 1.0.9
8799 + define-properties: 1.2.1
8800 + es-abstract: 1.24.2
8801 +
8802 + string.prototype.matchall@4.1.0:
8803 + dependencies:
8804 + call-bind: 1.0.9
8805 + call-bound: 1.0.4
8806 + define-properties: 1.2.1
8807 + es-abstract: 1.24.2
8808 + es-errors: 1.3.0
8809 + es-object-atoms: 1.1.2
8810 + get-intrinsic: 1.3.0
8811 + gopd: 1.2.0
8812 + has-symbols: 1.1.0
8813 + internal-slot: 1.1.0
8814 + regexp.prototype.flags: 1.5.4
8815 + set-function-name: 2.0.2
8816 + side-channel: 1.1.1
8817 +
8818 + string.prototype.repeat@1.0.0:
8819 + dependencies:
8820 + define-properties: 1.2.1
8821 + es-abstract: 1.24.2
8822 +
8823 + string.prototype.trim@1.2.11:
8824 + dependencies:
8825 + call-bind: 1.0.9
8826 + call-bound: 1.0.4
8827 + define-data-property: 1.1.4
8828 + define-properties: 1.2.1
8829 + es-abstract: 1.24.2
8830 + es-object-atoms: 1.1.2
8831 + has-property-descriptors: 1.0.2
8832 + safe-regex-test: 1.1.0
8833 +
8834 + string.prototype.trimend@1.0.10:
8835 + dependencies:
8836 + call-bind: 1.0.9
8837 + call-bound: 1.0.4
8838 + define-properties: 1.2.1
8839 + es-object-atoms: 1.1.2
8840 +
8841 + string.prototype.trimstart@1.0.8:
8842 + dependencies:
8843 + call-bind: 1.0.9
8844 + define-properties: 1.2.1
8845 + es-object-atoms: 1.1.2
8846 +
8847 + stringify-entities@4.0.4:
8848 + dependencies:
8849 + character-entities-html4: 2.1.0
8850 + character-entities-legacy: 3.0.0
8851 +
8852 + strip-bom@3.0.0: {}
8853 +
8854 + strip-json-comments@3.1.1: {}
8855 +
8856 + strip-literal@3.1.0:
8857 + dependencies:
8858 + js-tokens: 9.0.1
8859 +
8860 + style-to-js@1.1.21:
8861 + dependencies:
8862 + style-to-object: 1.0.14
8863 +
8864 + style-to-object@1.0.14:
8865 + dependencies:
8866 + inline-style-parser: 0.2.7
8867 +
8868 + styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.8):
8869 + dependencies:
8870 + client-only: 0.0.1
8871 + react: 19.2.8
8872 + optionalDependencies:
8873 + '@babel/core': 7.29.7
8874 +
8875 + supports-color@7.2.0:
8876 + dependencies:
8877 + has-flag: 4.0.0
8878 +
8879 + supports-preserve-symlinks-flag@1.0.0: {}
8880 +
8881 + swr@2.5.1(react@19.2.8):
8882 + dependencies:
8883 + dequal: 2.0.3
8884 + react: 19.2.8
8885 + use-sync-external-store: 1.6.0(react@19.2.8)
8886 +
8887 + tailwind-merge@3.6.0: {}
8888 +
8889 + tailwindcss@4.3.3: {}
8890 +
8891 + tapable@2.3.3: {}
8892 +
8893 + tiny-invariant@1.3.3: {}
8894 +
8895 + tinybench@2.9.0: {}
8896 +
8897 + tinyexec@0.3.2: {}
8898 +
8899 + tinyglobby@0.2.17:
8900 + dependencies:
8901 + fdir: 6.5.0(picomatch@4.0.7)
8902 + picomatch: 4.0.7
8903 +
8904 + tinypool@1.1.1: {}
8905 +
8906 + tinyrainbow@2.0.0: {}
8907 +
8908 + tinyspy@4.0.6: {}
8909 +
8910 + to-regex-range@5.0.1:
8911 + dependencies:
8912 + is-number: 7.0.0
8913 +
8914 + trim-lines@3.0.1: {}
8915 +
8916 + trough@2.2.0: {}
8917 +
8918 + ts-algebra@2.0.0: {}
8919 +
8920 + ts-api-utils@2.5.0(typescript@5.9.3):
8921 + dependencies:
8922 + typescript: 5.9.3
8923 +
8924 + tsconfig-paths@3.15.0:
8925 + dependencies:
8926 + '@types/json5': 0.0.29
8927 + json5: 1.0.2
8928 + minimist: 1.2.8
8929 + strip-bom: 3.0.0
8930 +
8931 + tslib@2.8.1: {}
8932 +
8933 + tsx@4.23.13:
8934 + dependencies:
8935 + esbuild: 0.28.2
8936 + optionalDependencies:
8937 + fsevents: 2.3.3
8938 +
8939 + type-check@0.4.0:
8940 + dependencies:
8941 + prelude-ls: 1.2.1
8942 +
8943 + typed-array-buffer@1.0.3:
8944 + dependencies:
8945 + call-bound: 1.0.4
8946 + es-errors: 1.3.0
8947 + is-typed-array: 1.1.15
8948 +
8949 + typed-array-byte-length@1.0.3:
8950 + dependencies:
8951 + call-bind: 1.0.9
8952 + for-each: 0.3.5
8953 + gopd: 1.2.0
8954 + has-proto: 1.2.0
8955 + is-typed-array: 1.1.15
8956 +
8957 + typed-array-byte-offset@1.0.4:
8958 + dependencies:
8959 + available-typed-arrays: 1.0.7
8960 + call-bind: 1.0.9
8961 + for-each: 0.3.5
8962 + gopd: 1.2.0
8963 + has-proto: 1.2.0
8964 + is-typed-array: 1.1.15
8965 + reflect.getprototypeof: 1.0.10
8966 +
8967 + typed-array-length@1.0.8:
8968 + dependencies:
8969 + call-bind: 1.0.9
8970 + for-each: 0.3.5
8971 + gopd: 1.2.0
8972 + is-typed-array: 1.1.15
8973 + possible-typed-array-names: 1.1.0
8974 + reflect.getprototypeof: 1.0.10
8975 +
8976 + typescript-eslint@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3):
8977 + dependencies:
8978 + '@typescript-eslint/eslint-plugin': 8.69.0(@typescript-eslint/parser@8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
8979 + '@typescript-eslint/parser': 8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
8980 + '@typescript-eslint/typescript-estree': 8.69.0(typescript@5.9.3)
8981 + '@typescript-eslint/utils': 8.69.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)
8982 + eslint: 9.39.5(jiti@2.7.0)
8983 + typescript: 5.9.3
8984 + transitivePeerDependencies:
8985 + - supports-color
8986 +
8987 + typescript@5.9.3: {}
8988 +
8989 + unbox-primitive@1.1.0:
8990 + dependencies:
8991 + call-bound: 1.0.4
8992 + has-bigints: 1.1.0
8993 + has-symbols: 1.1.0
8994 + which-boxed-primitive: 1.1.1
8995 +
8996 + undici-types@7.18.2: {}
8997 +
8998 + unified@11.0.5:
8999 + dependencies:
9000 + '@types/unist': 3.0.3
9001 + bail: 2.0.2
9002 + devlop: 1.1.0
9003 + extend: 3.0.2
9004 + is-plain-obj: 4.1.0
9005 + trough: 2.2.0
9006 + vfile: 6.0.3
9007 +
9008 + unist-util-is@6.0.1:
9009 + dependencies:
9010 + '@types/unist': 3.0.3
9011 +
9012 + unist-util-position@5.0.0:
9013 + dependencies:
9014 + '@types/unist': 3.0.3
9015 +
9016 + unist-util-stringify-position@4.0.0:
9017 + dependencies:
9018 + '@types/unist': 3.0.3
9019 +
9020 + unist-util-visit-parents@6.0.2:
9021 + dependencies:
9022 + '@types/unist': 3.0.3
9023 + unist-util-is: 6.0.1
9024 +
9025 + unist-util-visit@5.1.0:
9026 + dependencies:
9027 + '@types/unist': 3.0.3
9028 + unist-util-is: 6.0.1
9029 + unist-util-visit-parents: 6.0.2
9030 +
9031 + unrs-resolver@1.12.2:
9032 + dependencies:
9033 + napi-postinstall: 0.3.4
9034 + optionalDependencies:
9035 + '@unrs/resolver-binding-android-arm-eabi': 1.12.2
9036 + '@unrs/resolver-binding-android-arm64': 1.12.2
9037 + '@unrs/resolver-binding-darwin-arm64': 1.12.2
9038 + '@unrs/resolver-binding-darwin-x64': 1.12.2
9039 + '@unrs/resolver-binding-freebsd-x64': 1.12.2
9040 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2
9041 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2
9042 + '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2
9043 + '@unrs/resolver-binding-linux-arm64-musl': 1.12.2
9044 + '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2
9045 + '@unrs/resolver-binding-linux-loong64-musl': 1.12.2
9046 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2
9047 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2
9048 + '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2
9049 + '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2
9050 + '@unrs/resolver-binding-linux-x64-gnu': 1.12.2
9051 + '@unrs/resolver-binding-linux-x64-musl': 1.12.2
9052 + '@unrs/resolver-binding-openharmony-arm64': 1.12.2
9053 + '@unrs/resolver-binding-wasm32-wasi': 1.12.2
9054 + '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2
9055 + '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2
9056 + '@unrs/resolver-binding-win32-x64-msvc': 1.12.2
9057 +
9058 + update-browserslist-db@1.3.2(browserslist@4.28.9):
9059 + dependencies:
9060 + browserslist: 4.28.9
9061 + escalade: 3.2.0
9062 + picocolors: 1.1.1
9063 +
9064 + uri-js@4.4.1:
9065 + dependencies:
9066 + punycode: 2.3.1
9067 +
9068 + use-callback-ref@1.3.3(@types/react@19.2.18)(react@19.2.8):
9069 + dependencies:
9070 + react: 19.2.8
9071 + tslib: 2.8.1
9072 + optionalDependencies:
9073 + '@types/react': 19.2.18
9074 +
9075 + use-sidecar@1.1.3(@types/react@19.2.18)(react@19.2.8):
9076 + dependencies:
9077 + detect-node-es: 1.1.0
9078 + react: 19.2.8
9079 + tslib: 2.8.1
9080 + optionalDependencies:
9081 + '@types/react': 19.2.18
9082 +
9083 + use-sync-external-store@1.6.0(react@19.2.8):
9084 + dependencies:
9085 + react: 19.2.8
9086 +
9087 + vfile-location@5.0.3:
9088 + dependencies:
9089 + '@types/unist': 3.0.3
9090 + vfile: 6.0.3
9091 +
9092 + vfile-message@4.0.3:
9093 + dependencies:
9094 + '@types/unist': 3.0.3
9095 + unist-util-stringify-position: 4.0.0
9096 +
9097 + vfile@6.0.3:
9098 + dependencies:
9099 + '@types/unist': 3.0.3
9100 + vfile-message: 4.0.3
9101 +
9102 + victory-vendor@37.3.6:
9103 + dependencies:
9104 + '@types/d3-array': 3.2.2
9105 + '@types/d3-ease': 3.0.2
9106 + '@types/d3-interpolate': 3.0.4
9107 + '@types/d3-scale': 4.0.9
9108 + '@types/d3-shape': 3.2.0
9109 + '@types/d3-time': 3.0.4
9110 + '@types/d3-timer': 3.0.2
9111 + d3-array: 3.2.4
9112 + d3-ease: 3.0.1
9113 + d3-interpolate: 3.0.1
9114 + d3-scale: 4.0.2
9115 + d3-shape: 3.2.0
9116 + d3-time: 3.1.0
9117 + d3-timer: 3.0.1
9118 +
9119 + vite-node@3.2.4(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13):
9120 + dependencies:
9121 + cac: 6.7.14
9122 + debug: 4.4.3
9123 + es-module-lexer: 1.7.0
9124 + pathe: 2.0.3
9125 + vite: 7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)
9126 + transitivePeerDependencies:
9127 + - '@types/node'
9128 + - jiti
9129 + - less
9130 + - lightningcss
9131 + - sass
9132 + - sass-embedded
9133 + - stylus
9134 + - sugarss
9135 + - supports-color
9136 + - terser
9137 + - tsx
9138 + - yaml
9139 +
9140 + vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13):
9141 + dependencies:
9142 + esbuild: 0.28.2
9143 + fdir: 6.5.0(picomatch@4.0.7)
9144 + picomatch: 4.0.7
9145 + postcss: 8.5.28
9146 + rollup: 4.63.1
9147 + tinyglobby: 0.2.17
9148 + optionalDependencies:
9149 + '@types/node': 24.13.3
9150 + fsevents: 2.3.3
9151 + jiti: 2.7.0
9152 + lightningcss: 1.32.0
9153 + tsx: 4.23.13
9154 +
9155 + vitest@3.2.7(@types/debug@4.1.13)(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13):
9156 + dependencies:
9157 + '@types/chai': 5.2.3
9158 + '@vitest/expect': 3.2.7
9159 + '@vitest/mocker': 3.2.7(vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13))
9160 + '@vitest/pretty-format': 3.2.7
9161 + '@vitest/runner': 3.2.7
9162 + '@vitest/snapshot': 3.2.7
9163 + '@vitest/spy': 3.2.7
9164 + '@vitest/utils': 3.2.7
9165 + chai: 5.3.3
9166 + debug: 4.4.3
9167 + expect-type: 1.4.0
9168 + magic-string: 0.30.21
9169 + pathe: 2.0.3
9170 + picomatch: 4.0.7
9171 + std-env: 3.10.0
9172 + tinybench: 2.9.0
9173 + tinyexec: 0.3.2
9174 + tinyglobby: 0.2.17
9175 + tinypool: 1.1.1
9176 + tinyrainbow: 2.0.0
9177 + vite: 7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)
9178 + vite-node: 3.2.4(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)
9179 + why-is-node-running: 2.3.0
9180 + optionalDependencies:
9181 + '@types/debug': 4.1.13
9182 + '@types/node': 24.13.3
9183 + transitivePeerDependencies:
9184 + - jiti
9185 + - less
9186 + - lightningcss
9187 + - msw
9188 + - sass
9189 + - sass-embedded
9190 + - stylus
9191 + - sugarss
9192 + - supports-color
9193 + - terser
9194 + - tsx
9195 + - yaml
9196 +
9197 + web-namespaces@2.0.1: {}
9198 +
9199 + web-streams-polyfill@3.3.3: {}
9200 +
9201 + which-boxed-primitive@1.1.1:
9202 + dependencies:
9203 + is-bigint: 1.1.0
9204 + is-boolean-object: 1.2.2
9205 + is-number-object: 1.1.1
9206 + is-string: 1.1.1
9207 + is-symbol: 1.1.1
9208 +
9209 + which-builtin-type@1.2.1:
9210 + dependencies:
9211 + call-bound: 1.0.4
9212 + function.prototype.name: 1.2.0
9213 + has-tostringtag: 1.0.2
9214 + is-async-function: 2.1.1
9215 + is-date-object: 1.1.0
9216 + is-finalizationregistry: 1.1.1
9217 + is-generator-function: 1.1.2
9218 + is-regex: 1.2.1
9219 + is-weakref: 1.1.1
9220 + isarray: 2.0.5
9221 + which-boxed-primitive: 1.1.1
9222 + which-collection: 1.0.2
9223 + which-typed-array: 1.1.22
9224 +
9225 + which-collection@1.0.2:
9226 + dependencies:
9227 + is-map: 2.0.3
9228 + is-set: 2.0.3
9229 + is-weakmap: 2.0.2
9230 + is-weakset: 2.0.4
9231 +
9232 + which-typed-array@1.1.22:
9233 + dependencies:
9234 + available-typed-arrays: 1.0.7
9235 + call-bind: 1.0.9
9236 + call-bound: 1.0.4
9237 + for-each: 0.3.5
9238 + get-proto: 1.0.1
9239 + gopd: 1.2.0
9240 + has-tostringtag: 1.0.2
9241 +
9242 + which@2.0.2:
9243 + dependencies:
9244 + isexe: 2.0.0
9245 +
9246 + why-is-node-running@2.3.0:
9247 + dependencies:
9248 + siginfo: 2.0.0
9249 + stackback: 0.0.2
9250 +
9251 + word-wrap@1.2.5: {}
9252 +
9253 + ws@8.21.3: {}
9254 +
9255 + xtend@4.0.2: {}
9256 +
9257 + yallist@3.1.1: {}
9258 +
9259 + yocto-queue@0.1.0: {}
9260 +
9261 + zod-validation-error@4.0.2(zod@4.5.4):
9262 + dependencies:
9263 + zod: 4.5.4
9264 +
9265 + zod@4.5.4: {}
9266 +
9267 + zwitch@2.0.4: {}
added postcss.config.mjs +2 −0
@@ -0,0 +1,2 @@
1 +const config = { plugins: { "@tailwindcss/postcss": {} } };
2 +export default config;
added public/icon.svg +1 −0
@@ -0,0 +1 @@
1 +<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none"><defs><linearGradient id="g" x1="4" y1="4" x2="28" y2="28" gradientUnits="userSpaceOnUse"><stop stop-color="#8b8dff"/><stop offset="0.55" stop-color="#b58cff"/><stop offset="1" stop-color="#ff8fab"/></linearGradient></defs><rect x="1" y="1" width="30" height="30" rx="9" fill="url(#g)"/><g stroke="#0b0c10" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 10.5h4.5M9 16h6M9 21.5h4.5"/><path d="M23 10.5h-4.5M23 16h-6M23 21.5h-4.5"/><circle cx="16" cy="16" r="2.4" fill="#0b0c10" stroke="none"/></g></svg>
added public/robots.txt +6 −0
@@ -0,0 +1,6 @@
1 +User-agent: *
2 +Allow: /
3 +Disallow: /app/
4 +Disallow: /admin/
5 +Disallow: /api/
6 +Sitemap: https://www.polyllm.io/sitemap.xml
added research/gemini/00-models-list.ts +44 −0
@@ -0,0 +1,44 @@
1 +// Probe 00: list models via REST (x-goog-api-key) and via SDK; dump per-model metadata.
2 +// Run: set -a; . ../../.env; set +a; npx tsx 00-models-list.ts
3 +import { GoogleGenAI } from "@google/genai";
4 +import { writeFileSync } from "node:fs";
5 +
6 +const key = process.env.GOOGLE_GEMINI_API_KEY!;
7 +if (!key) throw new Error("GOOGLE_GEMINI_API_KEY missing");
8 +
9 +async function main() {
10 + // REST, paginated
11 + const all: any[] = [];
12 + let pageToken: string | undefined;
13 + do {
14 + const url = new URL("https://generativelanguage.googleapis.com/v1beta/models");
15 + url.searchParams.set("pageSize", "1000");
16 + if (pageToken) url.searchParams.set("pageToken", pageToken);
17 + const r = await fetch(url, { headers: { "x-goog-api-key": key } });
18 + console.log("REST status", r.status, "headers:", Object.fromEntries([...r.headers.entries()].filter(([k]) => !/set-cookie/.test(k))));
19 + const j = await r.json();
20 + all.push(...(j.models ?? []));
21 + pageToken = j.nextPageToken;
22 + } while (pageToken);
23 + writeFileSync("out/models.json", JSON.stringify(all, null, 2));
24 + console.log("model count", all.length);
25 + const keys = new Set<string>();
26 + for (const m of all) Object.keys(m).forEach((k) => keys.add(k));
27 + console.log("metadata fields seen:", [...keys].join(", "));
28 + for (const m of all) {
29 + console.log(
30 + m.name.replace("models/", "").padEnd(48),
31 + String(m.inputTokenLimit).padStart(8),
32 + String(m.outputTokenLimit).padStart(7),
33 + (m.thinking ? "think" : " "),
34 + (m.supportedGenerationMethods ?? []).join("|"),
35 + `T=${m.temperature ?? "-"}/${m.maxTemperature ?? "-"} P=${m.topP ?? "-"} K=${m.topK ?? "-"}`,
36 + );
37 + }
38 + // SDK
39 + const ai = new GoogleGenAI({ apiKey: key });
40 + const pager = await ai.models.list({ config: { pageSize: 5 } });
41 + let n = 0;
42 + for await (const m of pager) { n++; if (n === 1) console.log("SDK first model sample:", JSON.stringify(m)); if (n >= 5) break; }
43 +}
44 +main().catch((e) => { console.error("ERR", e?.message ?? e); process.exit(1); });
added research/gemini/01-basic-stream.ts +83 −0
@@ -0,0 +1,83 @@
1 +// Probe 01: per model — (a) tiny generateContent with systemInstruction, (b) generateContentStream chunk shape,
2 +// usage arrival pattern, part.thought flag, finishReason, modelVersion. Also raw REST SSE for one model.
3 +import { ai, MODELS, KEY, SUFFIX, save, errInfo, shortText, withRetry, sleep, PACE_MS } from "./lib.js";
4 +
5 +const results: any = {};
6 +
7 +for (const model of MODELS) {
8 + const r: any = (results[model] = {});
9 + // (a) + (i) non-streaming with systemInstruction
10 + try {
11 + const res = await withRetry(() => ai.models.generateContent({
12 + model,
13 + contents: "Reply with exactly one word: what colour is the sky on a clear day?",
14 + config: { systemInstruction: "You are terse. Always answer in UPPERCASE.", maxOutputTokens: 400 },
15 + }));
16 + r.generate = {
17 + ok: true,
18 + text: shortText(res),
19 + modelVersion: res.modelVersion,
20 + responseId: res.responseId,
21 + finishReason: res.candidates?.[0]?.finishReason,
22 + partKeys: res.candidates?.[0]?.content?.parts?.map((p: any) => Object.keys(p)),
23 + role: res.candidates?.[0]?.content?.role,
24 + usage: res.usageMetadata,
25 + topLevelKeys: Object.keys(res).filter((k) => !k.startsWith("_")),
26 + };
27 + } catch (e) {
28 + r.generate = { ok: false, error: errInfo(e) };
29 + }
30 +
31 + // (b) streaming
32 + try {
33 + await sleep(PACE_MS);
34 + const stream = await withRetry(() => ai.models.generateContentStream({
35 + model,
36 + contents: "Count from 1 to 12 separated by spaces, then say DONE.",
37 + config: { maxOutputTokens: 2000, thinkingConfig: { includeThoughts: true } },
38 + }));
39 + const chunks: any[] = [];
40 + for await (const c of stream) {
41 + chunks.push({
42 + parts: c.candidates?.[0]?.content?.parts?.map((p: any) => ({
43 + keys: Object.keys(p), thought: p.thought ?? undefined, textLen: p.text?.length, hasSig: !!p.thoughtSignature,
44 + })),
45 + role: c.candidates?.[0]?.content?.role,
46 + finishReason: c.candidates?.[0]?.finishReason,
47 + usage: c.usageMetadata,
48 + modelVersion: c.modelVersion,
49 + responseId: c.responseId,
50 + keys: Object.keys(c).filter((k) => !k.startsWith("_") && (c as any)[k] !== undefined),
51 + });
52 + }
53 + r.stream = {
54 + ok: true,
55 + chunkCount: chunks.length,
56 + usageOnChunks: chunks.map((c) => (c.usage ? (c.usage.candidatesTokenCount != null ? "full" : "partial") : "none")),
57 + thoughtChunks: chunks.filter((c) => c.parts?.some((p: any) => p.thought)).length,
58 + lastUsage: chunks.at(-1)?.usage,
59 + finishReasons: chunks.map((c) => c.finishReason ?? null),
60 + sampleFirst: chunks[0],
61 + sampleLast: chunks.at(-1),
62 + };
63 + } catch (e) {
64 + r.stream = { ok: false, error: errInfo(e) };
65 + }
66 + await sleep(PACE_MS);
67 + console.log(model, JSON.stringify({ gen: r.generate.ok ? r.generate.text : r.generate.error, stream: r.stream.ok ? { n: r.stream.chunkCount, usage: r.stream.usageOnChunks, thoughts: r.stream.thoughtChunks } : r.stream.error }));
68 +}
69 +
70 +// Raw REST SSE protocol sample (one model)
71 +if (!process.argv[2]) {
72 + const model = "gemini-3.5-flash-lite";
73 + const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse`, {
74 + method: "POST",
75 + headers: { "x-goog-api-key": KEY, "content-type": "application/json" },
76 + body: JSON.stringify({ contents: [{ role: "user", parts: [{ text: "Say hello in three words." }] }], generationConfig: { maxOutputTokens: 50, thinkingConfig: { thinkingBudget: 0 } } }),
77 + });
78 + const raw = await res.text();
79 + results.restSse = { status: res.status, contentType: res.headers.get("content-type"), rawFirst1200: raw.slice(0, 1200), eventCount: raw.split("\n\n").filter((s) => s.trim()).length };
80 + console.log("REST SSE", res.status, res.headers.get("content-type"), "events:", results.restSse.eventCount);
81 +}
82 +
83 +save(`01-basic-stream${SUFFIX}.json`, results);
added research/gemini/02-params.ts +68 −0
@@ -0,0 +1,68 @@
1 +// Probe 02: generationConfig parameter acceptance matrix per model. One request per (model, param).
2 +import { ai, MODELS, SUFFIX, save, errInfo, shortText, withRetry, sleep, PACE_MS } from "./lib.js";
3 +
4 +const schema = { type: "object", properties: { answer: { type: "string" } }, required: ["answer"] };
5 +
6 +const CASES: Record<string, Record<string, unknown>> = {
7 + temperature_0: { temperature: 0 },
8 + temperature_1_5: { temperature: 1.5 },
9 + temperature_2: { temperature: 2 },
10 + temperature_2_5_out_of_range: { temperature: 2.5 },
11 + topP_0_9: { topP: 0.9 },
12 + topK_40: { topK: 40 },
13 + seed_42: { seed: 42 },
14 + stopSequences: { stopSequences: ["DONE"] },
15 + frequencyPenalty_0_5: { frequencyPenalty: 0.5 },
16 + presencePenalty_0_5: { presencePenalty: 0.5 },
17 + candidateCount_2: { candidateCount: 2 },
18 + responseMimeType_json: { responseMimeType: "application/json" },
19 + responseSchema: { responseMimeType: "application/json", responseSchema: { type: "OBJECT", properties: { answer: { type: "STRING" } }, required: ["answer"] } },
20 + responseJsonSchema: { responseMimeType: "application/json", responseJsonSchema: schema },
21 + responseMimeType_enum: { responseMimeType: "text/x.enum", responseSchema: { type: "STRING", enum: ["red", "blue", "green"] } },
22 + thinkingBudget_0: { thinkingConfig: { thinkingBudget: 0 } },
23 + thinkingBudget_1024: { thinkingConfig: { thinkingBudget: 1024 } },
24 + thinkingBudget_minus1: { thinkingConfig: { thinkingBudget: -1 } },
25 + includeThoughts: { thinkingConfig: { includeThoughts: true } },
26 + thinkingLevel_minimal: { thinkingConfig: { thinkingLevel: "MINIMAL" } },
27 + thinkingLevel_low: { thinkingConfig: { thinkingLevel: "LOW" } },
28 + thinkingLevel_medium: { thinkingConfig: { thinkingLevel: "MEDIUM" } },
29 + thinkingLevel_high: { thinkingConfig: { thinkingLevel: "HIGH" } },
30 + thinkingLevel_and_budget: { thinkingConfig: { thinkingLevel: "LOW", thinkingBudget: 512 } },
31 + responseLogprobs: { responseLogprobs: true, logprobs: 2 },
32 +};
33 +
34 +const only = MODELS;
35 +const onlyCases = process.argv[3] ? new Set(process.argv[3].split(",")) : null;
36 +const results: any = {};
37 +
38 +for (const model of only) {
39 + results[model] = {};
40 + for (const [name, cfg] of Object.entries(CASES)) {
41 + if (onlyCases && !onlyCases.has(name)) continue;
42 + const t0 = Date.now();
43 + try {
44 + const res = await withRetry(() => ai.models.generateContent({
45 + model,
46 + contents: name.startsWith("responseMimeType_enum") ? "Which colour is the sky? Answer with one of the enum values." : "Answer in <= 5 words: what is 2+2? Then write DONE.",
47 + config: { maxOutputTokens: 1500, ...cfg } as any,
48 + }));
49 + const usage = res.usageMetadata ?? {};
50 + results[model][name] = {
51 + ok: true,
52 + text: shortText(res),
53 + finishReason: res.candidates?.[0]?.finishReason,
54 + thoughtsTokenCount: usage.thoughtsTokenCount ?? 0,
55 + candidatesTokenCount: usage.candidatesTokenCount,
56 + nCandidates: res.candidates?.length,
57 + hasThoughtParts: res.candidates?.[0]?.content?.parts?.some((p: any) => p.thought) ?? false,
58 + ms: Date.now() - t0,
59 + };
60 + } catch (e) {
61 + results[model][name] = { ok: false, error: errInfo(e), ms: Date.now() - t0 };
62 + }
63 + await sleep(PACE_MS);
64 + const r = results[model][name];
65 + console.log(model.padEnd(24), name.padEnd(30), r.ok ? `OK thoughts=${r.thoughtsTokenCount} fin=${r.finishReason} "${r.text.slice(0, 40).replace(/\n/g, " ")}"` : `FAIL ${r.error.httpStatus} ${r.error.status}: ${r.error.message.slice(0, 160)}`);
66 + }
67 +}
68 +save(`02-params${SUFFIX}${onlyCases ? "-subset-" + Date.now() : ""}.json`, results);
added research/gemini/03-tools.ts +107 −0
@@ -0,0 +1,107 @@
1 +// Probe 03: per model — (d) function-calling round trip with streaming, (e) structured output via responseJsonSchema.
2 +// Plus (h) googleSearch grounding and code execution on selected models.
3 +import { ai, MODELS, SUFFIX, save, errInfo, shortText, withRetry, sleep, PACE_MS } from "./lib.js";
4 +
5 +const results: any = {};
6 +const weatherTool = {
7 + functionDeclarations: [{
8 + name: "get_weather",
9 + description: "Get the current weather for a city.",
10 + parametersJsonSchema: { type: "object", properties: { city: { type: "string" }, unit: { type: "string", enum: ["C", "F"] } }, required: ["city"] },
11 + }],
12 +};
13 +
14 +for (const model of MODELS) {
15 + const r: any = (results[model] = {});
16 +
17 + // (d) function calling, streaming, then send functionResponse
18 + try {
19 + const contents: any[] = [{ role: "user", parts: [{ text: "What is the weather in Montreal right now? Use the tool." }] }];
20 + const stream = await withRetry(() => ai.models.generateContentStream({ model, contents, config: { tools: [weatherTool], maxOutputTokens: 2000 } }));
21 + const chunks: any[] = [];
22 + let modelParts: any[] = [];
23 + for await (const c of stream) {
24 + const parts = c.candidates?.[0]?.content?.parts ?? [];
25 + chunks.push({ parts: parts.map((p: any) => ({ keys: Object.keys(p), fc: p.functionCall, thought: p.thought, sig: p.thoughtSignature ? `${p.thoughtSignature.length} chars` : undefined })), finishReason: c.candidates?.[0]?.finishReason, usage: c.usageMetadata ? Object.keys(c.usageMetadata) : null });
26 + modelParts.push(...parts);
27 + }
28 + const fcParts = modelParts.filter((p) => p.functionCall);
29 + r.functionCall = { ok: true, chunkCount: chunks.length, chunks, functionCalls: fcParts.map((p) => p.functionCall), sigOnFcPart: fcParts.map((p) => !!p.thoughtSignature) };
30 + if (fcParts.length) {
31 + // Round trip: append model content (with thoughtSignature preserved) and functionResponse parts
32 + contents.push({ role: "model", parts: modelParts });
33 + contents.push({
34 + role: "user",
35 + parts: fcParts.map((p) => ({ functionResponse: { name: p.functionCall.name, id: p.functionCall.id, response: { temperatureC: 21, condition: "sunny" } } })),
36 + });
37 + await sleep(PACE_MS);
38 + const res2 = await withRetry(() => ai.models.generateContent({ model, contents, config: { tools: [weatherTool], maxOutputTokens: 2000 } }));
39 + r.functionCall.roundTrip = { text: shortText(res2), finishReason: res2.candidates?.[0]?.finishReason, usage: res2.usageMetadata };
40 + }
41 + } catch (e) {
42 + r.functionCall = { ok: false, error: errInfo(e) };
43 + }
44 +
45 + // (e) structured output responseJsonSchema
46 + try {
47 + await sleep(PACE_MS);
48 + const res = await withRetry(() => ai.models.generateContent({
49 + model,
50 + contents: "Extract: 'Alice is 30 and lives in Paris.'",
51 + config: {
52 + maxOutputTokens: 2000,
53 + responseMimeType: "application/json",
54 + responseJsonSchema: { type: "object", properties: { name: { type: "string" }, age: { type: "integer" }, city: { type: "string" } }, required: ["name", "age", "city"], additionalProperties: false },
55 + },
56 + }));
57 + const txt = shortText(res);
58 + let parsed: any = null; try { parsed = JSON.parse(res.candidates?.[0]?.content?.parts?.filter((p: any) => !p.thought).map((p: any) => p.text).join("") ?? ""); } catch {}
59 + r.structured = { ok: true, text: txt, parsedOk: !!parsed, parsed, finishReason: res.candidates?.[0]?.finishReason };
60 + } catch (e) {
61 + r.structured = { ok: false, error: errInfo(e) };
62 + }
63 + await sleep(PACE_MS);
64 + console.log(model, "fc:", r.functionCall.ok ? `${r.functionCall.functionCalls.length} call(s) chunks=${r.functionCall.chunkCount} rt="${r.functionCall.roundTrip?.text?.slice(0, 50)}"` : r.functionCall.error.message.slice(0, 200), "| structured:", r.structured.ok ? r.structured.text.slice(0, 80) : r.structured.error.message.slice(0, 200));
65 +}
66 +
67 +const EXTRAS = process.argv[3] === "extras";
68 +// (h) Google Search grounding (3.x models; 2.5 is 404 for this key)
69 +for (const model of EXTRAS ? [MODELS[0]] : []) {
70 + await sleep(PACE_MS);
71 + try {
72 + const res = await withRetry(() => ai.models.generateContent({ model, contents: "Who won the most recent FIFA World Cup final and what was the score? One sentence.", config: { tools: [{ googleSearch: {} }], maxOutputTokens: 3000 } }));
73 + const gm: any = res.candidates?.[0]?.groundingMetadata;
74 + results[`search:${model}`] = {
75 + ok: true, text: shortText(res),
76 + groundingMetadataKeys: gm ? Object.keys(gm) : null,
77 + webSearchQueries: gm?.webSearchQueries,
78 + groundingChunksSample: gm?.groundingChunks?.slice(0, 2),
79 + groundingSupportsSample: gm?.groundingSupports?.slice(0, 2),
80 + searchEntryPointKeys: gm?.searchEntryPoint ? Object.keys(gm.searchEntryPoint) : null,
81 + renderedContentLen: gm?.searchEntryPoint?.renderedContent?.length,
82 + usage: res.usageMetadata,
83 + partKeys: res.candidates?.[0]?.content?.parts?.map((p: any) => Object.keys(p)),
84 + };
85 + } catch (e) { results[`search:${model}`] = { ok: false, error: errInfo(e) }; }
86 + console.log("search", model, JSON.stringify(results[`search:${model}`]).slice(0, 300));
87 +}
88 +
89 +// Code execution on one model
90 +if (EXTRAS) try {
91 + await sleep(PACE_MS);
92 + const res = await withRetry(() => ai.models.generateContent({ model: MODELS[0], contents: "Compute the 30th Fibonacci number with Python and report it.", config: { tools: [{ codeExecution: {} }], maxOutputTokens: 3000 } }));
93 + results[`codeExecution:${MODELS[0]}`] = { ok: true, parts: res.candidates?.[0]?.content?.parts?.map((p: any) => ({ keys: Object.keys(p), executableCode: p.executableCode, codeExecutionResult: p.codeExecutionResult, text: p.text?.slice(0, 100) })), usage: res.usageMetadata };
94 +} catch (e) { results[`codeExecution:${MODELS[0]}`] = { ok: false, error: errInfo(e) }; }
95 +if (EXTRAS) console.log("codeExec", JSON.stringify(results[`codeExecution:${MODELS[0]}`]).slice(0, 400));
96 +
97 +// toolConfig mode ANY (+ streamFunctionCallArguments is Vertex-only: SDK throws before sending) on 3.8
98 +if (EXTRAS) try {
99 + await sleep(PACE_MS);
100 + const stream = await withRetry(() => ai.models.generateContentStream({ model: MODELS[0], contents: "Weather in Quebec City?", config: { tools: [weatherTool], toolConfig: { functionCallingConfig: { mode: "ANY" as any, allowedFunctionNames: ["get_weather"] } }, maxOutputTokens: 2000 } }));
101 + const chunks: any[] = [];
102 + for await (const c of stream) chunks.push(c.candidates?.[0]?.content?.parts);
103 + results[`fcModeAny:${MODELS[0]}`] = { ok: true, chunks };
104 +} catch (e) { results[`fcModeAny:${MODELS[0]}`] = { ok: false, error: errInfo(e) }; }
105 +if (EXTRAS) console.log("fcAny", JSON.stringify(results[`fcModeAny:${MODELS[0]}`]).slice(0, 500));
106 +
107 +save(`03-tools${SUFFIX}.json`, results);
added research/gemini/04-vision.ts +36 −0
@@ -0,0 +1,36 @@
1 +// Probe 04: (f) vision with a tiny inline base64 PNG (2x2, generated in node), per model.
2 +import { deflateSync } from "node:zlib";
3 +import { ai, MODELS, SUFFIX, save, errInfo, shortText, withRetry, sleep, PACE_MS } from "./lib.js";
4 +
5 +function crc32(buf: Buffer) {
6 + let c, crc = 0xffffffff;
7 + for (let n = 0; n < buf.length; n++) { c = (crc ^ buf[n]) & 0xff; for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; crc = (crc >>> 8) ^ c; }
8 + return (crc ^ 0xffffffff) >>> 0;
9 +}
10 +function chunk(type: string, data: Buffer) {
11 + const len = Buffer.alloc(4); len.writeUInt32BE(data.length);
12 + const td = Buffer.concat([Buffer.from(type, "ascii"), data]);
13 + const crc = Buffer.alloc(4); crc.writeUInt32BE(crc32(td));
14 + return Buffer.concat([len, td, crc]);
15 +}
16 +// 2x2 RGB: red, green / blue, white
17 +const ihdr = Buffer.alloc(13); ihdr.writeUInt32BE(2, 0); ihdr.writeUInt32BE(2, 4); ihdr[8] = 8; ihdr[9] = 2; ihdr[10] = 0; ihdr[11] = 0; ihdr[12] = 0;
18 +const raw = Buffer.from([0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255, 255, 255]);
19 +const png = Buffer.concat([Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]), chunk("IHDR", ihdr), chunk("IDAT", deflateSync(raw)), chunk("IEND", Buffer.alloc(0))]);
20 +const b64 = png.toString("base64");
21 +console.log("png bytes", png.length, "b64", b64);
22 +
23 +const results: any = {};
24 +for (const model of MODELS) {
25 + try {
26 + const res = await withRetry(() => ai.models.generateContent({
27 + model,
28 + contents: [{ role: "user", parts: [{ inlineData: { mimeType: "image/png", data: b64 } }, { text: "This is a tiny 2x2 pixel image. List the colours you can identify, comma-separated." }] }],
29 + config: { maxOutputTokens: 1500 },
30 + }));
31 + results[model] = { ok: true, text: shortText(res), usage: res.usageMetadata, finishReason: res.candidates?.[0]?.finishReason };
32 + } catch (e) { results[model] = { ok: false, error: errInfo(e) }; }
33 + await sleep(PACE_MS);
34 + console.log(model.padEnd(24), results[model].ok ? `OK "${results[model].text.slice(0, 60)}" promptTokens=${results[model].usage?.promptTokenCount} details=${JSON.stringify(results[model].usage?.promptTokensDetails)}` : `FAIL ${results[model].error.message.slice(0, 200)}`);
35 +}
36 +save(`04-vision${SUFFIX}.json`, results);
added research/gemini/05-errors-misc.ts +104 −0
@@ -0,0 +1,104 @@
1 +// Probe 05: (g) invalid key (SDK + REST), unknown model 404, bad param 400 raw body, countTokens, chats helper,
2 +// Authorization: Bearer test, v1 vs v1beta, models.get, explicit cache creation minimum error, and the Interactions API surface.
3 +import { GoogleGenAI } from "@google/genai";
4 +import { ai, KEY, save, errInfo } from "./lib.js";
5 +
6 +const results: any = {};
7 +const BASE = "https://generativelanguage.googleapis.com";
8 +
9 +// (g) invalid key — REST
10 +{
11 + const r = await fetch(`${BASE}/v1beta/models/gemini-2.5-flash:generateContent`, { method: "POST", headers: { "x-goog-api-key": "AQ.invalid-key-for-probe", "content-type": "application/json" }, body: JSON.stringify({ contents: [{ parts: [{ text: "hi" }] }] }) });
12 + results.invalidKeyRest = { status: r.status, body: await r.json(), wwwAuthenticate: r.headers.get("www-authenticate") };
13 + console.log("invalid key REST", r.status, JSON.stringify(results.invalidKeyRest.body).slice(0, 400));
14 +}
15 +// (g) invalid key — SDK
16 +try {
17 + const bad = new GoogleGenAI({ apiKey: "AQ.invalid-key-for-probe" });
18 + await bad.models.generateContent({ model: "gemini-2.5-flash", contents: "hi", config: { maxOutputTokens: 5 } });
19 +} catch (e: any) { results.invalidKeySdk = { ...errInfo(e), rawMessage: String(e?.message).slice(0, 500), ctor: e?.constructor?.name }; console.log("invalid key SDK", JSON.stringify(results.invalidKeySdk).slice(0, 400)); }
20 +
21 +// Bearer auth (does Authorization: Bearer <api key> work?)
22 +{
23 + const r = await fetch(`${BASE}/v1beta/models?pageSize=1`, { headers: { authorization: `Bearer ${KEY}` } });
24 + results.bearerAuth = { status: r.status, body: r.status !== 200 ? await r.json() : "(ok)" };
25 + console.log("bearer", r.status, JSON.stringify(results.bearerAuth.body).slice(0, 300));
26 +}
27 +// ?key= query param
28 +{
29 + const r = await fetch(`${BASE}/v1beta/models?pageSize=1&key=${encodeURIComponent(KEY)}`);
30 + results.keyQueryParam = { status: r.status };
31 + console.log("?key=", r.status);
32 +}
33 +// Unknown model
34 +try { await ai.models.generateContent({ model: "gemini-9-ultra", contents: "hi" }); } catch (e) { results.unknownModel = errInfo(e); console.log("unknown model", JSON.stringify(results.unknownModel).slice(0, 400)); }
35 +// Raw 400 error body
36 +{
37 + const r = await fetch(`${BASE}/v1beta/models/gemini-2.5-flash:generateContent`, { method: "POST", headers: { "x-goog-api-key": KEY, "content-type": "application/json" }, body: JSON.stringify({ contents: [{ parts: [{ text: "hi" }] }], generationConfig: { temperature: 5 } }) });
38 + results.raw400 = { status: r.status, body: await r.json() };
39 + console.log("raw 400", JSON.stringify(results.raw400).slice(0, 500));
40 +}
41 +// Streaming error (bad param) via SSE: does the error come as HTTP status or as an SSE event?
42 +{
43 + const r = await fetch(`${BASE}/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse`, { method: "POST", headers: { "x-goog-api-key": KEY, "content-type": "application/json" }, body: JSON.stringify({ contents: [{ parts: [{ text: "hi" }] }], generationConfig: { temperature: 5 } }) });
44 + results.streamError = { status: r.status, contentType: r.headers.get("content-type"), body: (await r.text()).slice(0, 500) };
45 + console.log("stream error", results.streamError.status, results.streamError.contentType);
46 +}
47 +// countTokens
48 +try {
49 + const c = await ai.models.countTokens({ model: "gemini-3.8-flash", contents: "The quick brown fox jumps over the lazy dog." });
50 + results.countTokens = c; console.log("countTokens", JSON.stringify(c));
51 +} catch (e) { results.countTokens = errInfo(e); console.log("countTokens ERR", JSON.stringify(results.countTokens)); }
52 +// countTokens with systemInstruction + tools via REST generateContentRequest
53 +{
54 + const r = await fetch(`${BASE}/v1beta/models/gemini-3.8-flash:countTokens`, { method: "POST", headers: { "x-goog-api-key": KEY, "content-type": "application/json" }, body: JSON.stringify({ generateContentRequest: { model: "models/gemini-3.8-flash", contents: [{ role: "user", parts: [{ text: "The quick brown fox jumps over the lazy dog." }] }], systemInstruction: { parts: [{ text: "You are a helpful assistant that answers briefly." }] }, tools: [{ functionDeclarations: [{ name: "f", description: "A function", parameters: { type: "OBJECT", properties: { a: { type: "STRING" } } } }] }] } }) });
55 + results.countTokensFull = { status: r.status, body: await r.json() };
56 + console.log("countTokens full", JSON.stringify(results.countTokensFull));
57 +}
58 +// models.get
59 +try { const m = await ai.models.get({ model: "gemini-3.8-flash" }); results.modelsGet = m; console.log("models.get", JSON.stringify(m).slice(0, 400)); } catch (e) { results.modelsGet = errInfo(e); }
60 +// v1 API version: does gemini-3.8-flash exist on v1? does thinkingConfig work there?
61 +try {
62 + const v1 = new GoogleGenAI({ apiKey: KEY, httpOptions: { apiVersion: "v1" } });
63 + const res = await v1.models.generateContent({ model: "gemini-3.8-flash", contents: "Say hi", config: { maxOutputTokens: 50, thinkingConfig: { thinkingLevel: "LOW" as any } } });
64 + results.v1 = { ok: true, text: res.text, modelVersion: res.modelVersion };
65 +} catch (e) { results.v1 = { ok: false, error: errInfo(e) }; }
66 +console.log("v1", JSON.stringify(results.v1).slice(0, 300));
67 +// chats helper (client-side history)
68 +try {
69 + const chat = ai.chats.create({ model: "gemini-2.5-flash-lite", config: { maxOutputTokens: 60, thinkingConfig: { thinkingBudget: 0 } } });
70 + await chat.sendMessage({ message: "My name is Simon. Reply OK." });
71 + const r2 = await chat.sendMessage({ message: "What is my name? One word." });
72 + results.chats = { ok: true, text: r2.text, historyLen: chat.getHistory().length, historyRoles: chat.getHistory().map((c) => c.role) };
73 +} catch (e) { results.chats = { ok: false, error: errInfo(e) }; }
74 +console.log("chats", JSON.stringify(results.chats));
75 +// explicit cache: small content should fail with minimum-token error → record exact message
76 +try {
77 + const c = await ai.caches.create({ model: "gemini-2.5-flash", config: { contents: [{ role: "user", parts: [{ text: "short" }] }], ttl: "60s" } });
78 + results.cacheCreate = { ok: true, name: c.name }; await ai.caches.delete({ name: c.name! });
79 +} catch (e) { results.cacheCreate = { ok: false, error: errInfo(e) }; }
80 +console.log("cache", JSON.stringify(results.cacheCreate).slice(0, 400));
81 +// Interactions API (new recommended surface) — does the SDK expose it, and does it work with this key?
82 +try {
83 + const anyAi: any = ai;
84 + results.interactionsExposed = typeof anyAi.interactions?.create === "function";
85 + if (results.interactionsExposed) {
86 + const it = await anyAi.interactions.create({ model: "gemini-3.8-flash", input: "Say hi in two words.", generation_config: { thinking_level: "low", max_output_tokens: 50 }, store: false });
87 + results.interactions = { ok: true, keys: Object.keys(it), output_text: it.output_text, usage: it.usage, stepsTypes: (it.steps ?? it.outputs ?? []).map((s: any) => s.type) };
88 + }
89 +} catch (e) { results.interactions = { ok: false, error: errInfo(e), raw: String((e as any)?.message).slice(0, 300) }; }
90 +console.log("interactions", JSON.stringify(results.interactions).slice(0, 500));
91 +// Safety settings accepted?
92 +try {
93 + const res = await ai.models.generateContent({ model: "gemini-2.5-flash-lite", contents: "Say hi", config: { maxOutputTokens: 20, thinkingConfig: { thinkingBudget: 0 }, safetySettings: [{ category: "HARM_CATEGORY_HARASSMENT" as any, threshold: "BLOCK_NONE" as any }, { category: "HARM_CATEGORY_HATE_SPEECH" as any, threshold: "OFF" as any }] } });
94 + results.safety = { ok: true, text: res.text, safetyRatings: res.candidates?.[0]?.safetyRatings ?? null, promptFeedback: res.promptFeedback ?? null };
95 +} catch (e) { results.safety = { ok: false, error: errInfo(e) }; }
96 +console.log("safety", JSON.stringify(results.safety).slice(0, 300));
97 +// Response headers on a normal request (rate-limit headers?)
98 +{
99 + const r = await fetch(`${BASE}/v1beta/models/gemini-2.5-flash-lite:generateContent`, { method: "POST", headers: { "x-goog-api-key": KEY, "content-type": "application/json" }, body: JSON.stringify({ contents: [{ parts: [{ text: "hi" }] }], generationConfig: { maxOutputTokens: 5, thinkingConfig: { thinkingBudget: 0 } } }) });
100 + results.responseHeaders = Object.fromEntries([...r.headers.entries()]);
101 + await r.text();
102 + console.log("headers", JSON.stringify(results.responseHeaders));
103 +}
104 +save("05-errors-misc.json", results);
added research/gemini/06-availability.ts +26 −0
@@ -0,0 +1,26 @@
1 +// Probe 06: which generateContent-capable text models actually answer with this (free-tier) key?
2 +// One tiny request per model, serial and paced. Classifies: ok / 404 gone / 429 free-tier-zero / other.
3 +import { readFileSync } from "node:fs";
4 +import { ai, save, errInfo, quotaKind, sleep, PACE_MS, shortText } from "./lib.js";
5 +
6 +const models: any[] = JSON.parse(readFileSync("out/models.json", "utf8"));
7 +const skip = /embedding|veo|lyria|tts|image|aqa|transcribe|live|native-audio|robotics|computer-use|deep-research|antigravity|nano-banana/;
8 +const targets = models.filter((m) => m.supportedGenerationMethods?.includes("generateContent") && !skip.test(m.name)).map((m) => m.name.replace("models/", ""));
9 +console.log("targets:", targets.join(", "));
10 +
11 +const results: any = {};
12 +for (const model of targets) {
13 + const t0 = Date.now();
14 + try {
15 + const res = await ai.models.generateContent({ model, contents: "Reply with the single word: pong", config: { maxOutputTokens: 100 } });
16 + results[model] = { status: "ok", text: shortText(res), modelVersion: res.modelVersion, usage: res.usageMetadata, finishReason: res.candidates?.[0]?.finishReason, ms: Date.now() - t0 };
17 + } catch (e) {
18 + const info = errInfo(e);
19 + const kind = quotaKind(e);
20 + results[model] = { status: info.httpStatus === 404 ? "gone-404" : kind === "day" ? "free-tier-zero-429" : `error-${info.httpStatus}`, error: info, ms: Date.now() - t0 };
21 + }
22 + const r = results[model];
23 + console.log(model.padEnd(36), r.status.padEnd(20), r.status === "ok" ? `"${r.text}" v=${r.modelVersion} thoughts=${r.usage?.thoughtsTokenCount ?? 0}` : r.error.message.slice(0, 110).replace(/\n/g, " "));
24 + await sleep(1500);
25 +}
26 +save("06-availability.json", results);
added research/gemini/07-signature.ts +47 −0
@@ -0,0 +1,47 @@
1 +// Probe 07: thought-signature strictness on function calling (Gemini 3.x).
2 +// 1) get a functionCall (records whether thoughtSignature is on the functionCall part)
3 +// 2) send functionResponse WITHOUT echoing the signature → record exact error (if any)
4 +// 3) send with the real signature → OK? 4) send with dummy "skip_thought_signature_validator" → OK?
5 +// 5) multi-turn text-only without echoing signature → OK? (signatures on text parts are optional per docs)
6 +import { ai, MODELS, SUFFIX, save, errInfo, shortText, withRetry, sleep, PACE_MS } from "./lib.js";
7 +
8 +const model = MODELS[0];
9 +const tool = { functionDeclarations: [{ name: "get_weather", description: "Get weather for a city.", parametersJsonSchema: { type: "object", properties: { city: { type: "string" } }, required: ["city"] } }] };
10 +const results: any = { model };
11 +
12 +const first = await withRetry(() => ai.models.generateContent({ model, contents: [{ role: "user", parts: [{ text: "Weather in Montreal? Use the tool." }] }], config: { tools: [tool], maxOutputTokens: 2000 } }));
13 +const parts: any[] = first.candidates?.[0]?.content?.parts ?? [];
14 +results.firstTurnParts = parts.map((p) => ({ keys: Object.keys(p), fc: p.functionCall, sigLen: p.thoughtSignature?.length }));
15 +console.log("first turn parts", JSON.stringify(results.firstTurnParts));
16 +const fc = parts.find((p) => p.functionCall);
17 +if (!fc) { console.log("no function call; abort"); save(`07-signature${SUFFIX}.json`, results); process.exit(0); }
18 +
19 +async function roundTrip(label: string, modelParts: any[]) {
20 + await sleep(PACE_MS);
21 + const contents = [
22 + { role: "user", parts: [{ text: "Weather in Montreal? Use the tool." }] },
23 + { role: "model", parts: modelParts },
24 + { role: "user", parts: [{ functionResponse: { name: fc.functionCall.name, id: fc.functionCall.id, response: { temperatureC: 21, condition: "sunny" } } }] },
25 + ];
26 + try {
27 + const r = await withRetry(() => ai.models.generateContent({ model, contents, config: { tools: [tool], maxOutputTokens: 2000 } }));
28 + results[label] = { ok: true, text: shortText(r), finishReason: r.candidates?.[0]?.finishReason };
29 + } catch (e) { results[label] = { ok: false, error: errInfo(e) }; }
30 + console.log(label, JSON.stringify(results[label]).slice(0, 400));
31 +}
32 +const stripSig = (p: any) => { const { thoughtSignature, ...rest } = p; return rest; };
33 +await roundTrip("withSignature", parts);
34 +await roundTrip("withoutSignature", parts.map(stripSig));
35 +await roundTrip("dummySignature", parts.map((p) => (p.functionCall ? { ...stripSig(p), thoughtSignature: "skip_thought_signature_validator" } : stripSig(p))));
36 +
37 +// 5) text-only multi-turn without signatures
38 +await sleep(PACE_MS);
39 +try {
40 + const t1 = await withRetry(() => ai.models.generateContent({ model, contents: "Pick a random fruit and tell me only its name.", config: { maxOutputTokens: 1500 } }));
41 + const p1: any[] = (t1.candidates?.[0]?.content?.parts ?? []).map(stripSig);
42 + await sleep(PACE_MS);
43 + const t2 = await withRetry(() => ai.models.generateContent({ model, contents: [{ role: "user", parts: [{ text: "Pick a random fruit and tell me only its name." }] }, { role: "model", parts: p1 }, { role: "user", parts: [{ text: "What colour is it? One word." }] }], config: { maxOutputTokens: 1500 } }));
44 + results.textMultiTurnNoSig = { ok: true, fruit: shortText(t1), colour: shortText(t2), firstTurnHadSig: (t1.candidates?.[0]?.content?.parts ?? []).some((p: any) => p.thoughtSignature) };
45 +} catch (e) { results.textMultiTurnNoSig = { ok: false, error: errInfo(e) }; }
46 +console.log("textMultiTurnNoSig", JSON.stringify(results.textMultiTurnNoSig));
47 +save(`07-signature${SUFFIX}.json`, results);
added research/gemini/08-rest-sse.ts +20 −0
@@ -0,0 +1,20 @@
1 +// Probe 08: raw REST streaming protocol (alt=sse) and the default (no alt) JSON-array streaming, on one model.
2 +import { KEY, MODELS, save } from "./lib.js";
3 +const model = MODELS[0];
4 +const body = JSON.stringify({ contents: [{ role: "user", parts: [{ text: "Say hello in five words, then think of nothing else." }] }], generationConfig: { maxOutputTokens: 1500, thinkingConfig: { includeThoughts: true, thinkingLevel: "LOW" } } });
5 +const results: any = { model };
6 +{
7 + const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse`, { method: "POST", headers: { "x-goog-api-key": KEY, "content-type": "application/json" }, body });
8 + const raw = await res.text();
9 + const events = raw.split("\n\n").filter((s) => s.trim());
10 + results.sse = { status: res.status, contentType: res.headers.get("content-type"), transferEncoding: res.headers.get("transfer-encoding"), eventCount: events.length, firstEventRaw: events[0]?.slice(0, 1500), lastEventRaw: events.at(-1)?.slice(0, 1500), linePrefixes: [...new Set(events.flatMap((e) => e.split("\n").map((l) => l.split(":")[0])))] };
11 + console.log("SSE", res.status, results.sse.contentType, "events", events.length, "prefixes", results.sse.linePrefixes);
12 + console.log(events[0]?.slice(0, 600));
13 +}
14 +{
15 + const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent`, { method: "POST", headers: { "x-goog-api-key": KEY, "content-type": "application/json" }, body });
16 + const raw = await res.text();
17 + results.noAlt = { status: res.status, contentType: res.headers.get("content-type"), startsWith: raw.slice(0, 120), endsWith: raw.slice(-60) };
18 + console.log("no-alt", res.status, results.noAlt.contentType, JSON.stringify(results.noAlt.startsWith));
19 +}
20 +save(`08-rest-sse-${model}.json`, results);
added research/gemini/lib.ts +89 −0
@@ -0,0 +1,89 @@
1 +// Shared helpers for the Gemini probes. No secrets here: the key comes from env GOOGLE_GEMINI_API_KEY.
2 +import { GoogleGenAI } from "@google/genai";
3 +import { mkdirSync, writeFileSync } from "node:fs";
4 +
5 +export const KEY = process.env.GOOGLE_GEMINI_API_KEY ?? "";
6 +if (!KEY) throw new Error("GOOGLE_GEMINI_API_KEY missing (set -a; . ../../.env; set +a)");
7 +
8 +export const ai = new GoogleGenAI({ apiKey: KEY, httpOptions: { timeout: 120_000 } });
9 +
10 +// Requested set was 3.8-flash, 3.5-flash, 3.1-pro-preview, 2.5-flash, 2.5-pro, omni — but with this free-tier key
11 +// 2.5-* return 404 "no longer available to new users" and 3.1-pro / omni have free-tier quota 0 (see out/06-availability.json).
12 +// Default probe set = accessible models; override with argv[2] = comma-separated ids.
13 +export const DEFAULT_MODELS = [
14 + "gemini-3.8-flash",
15 + "gemini-3.5-flash",
16 + "gemini-3.5-flash-lite",
17 + "gemini-3.1-flash-lite",
18 + "gemini-3-flash-preview",
19 + "gemma-4-31b-it",
20 +];
21 +export const MODELS = process.argv[2] ? process.argv[2].split(",") : DEFAULT_MODELS;
22 +export const SUFFIX = process.argv[2] ? "-" + process.argv[2].replace(/[^a-z0-9.-]/gi, "_") : "";
23 +
24 +mkdirSync("out", { recursive: true });
25 +
26 +export function save(name: string, data: unknown) {
27 + writeFileSync(`out/${name}`, JSON.stringify(data, redact, 2));
28 +}
29 +
30 +// Never let a key leak into saved output.
31 +function redact(_k: string, v: unknown) {
32 + if (typeof v === "string" && KEY && v.includes(KEY)) return v.replaceAll(KEY, "[REDACTED]");
33 + return v;
34 +}
35 +
36 +export function errInfo(e: any) {
37 + // SDK throws ApiError {name, message, status}. message is usually the JSON error body as string.
38 + let parsed: any = null;
39 + const m: string = e?.message ?? String(e);
40 + try { parsed = JSON.parse(m); } catch { /* not json */ }
41 + const inner = parsed?.error ?? parsed;
42 + return {
43 + name: e?.name,
44 + httpStatus: e?.status ?? inner?.code ?? null,
45 + status: inner?.status ?? null,
46 + message: (inner?.message ?? m).slice(0, 400),
47 + details: inner?.details ?? null,
48 + };
49 +}
50 +
51 +export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
52 +
53 +/** Classify a 429: per-minute quota → retryable; per-day / limit 0 → give up for this model. */
54 +export function quotaKind(e: any): "minute" | "day" | "other" {
55 + const info = errInfo(e);
56 + if (info.httpStatus !== 429) return "other";
57 + const q = (info.details ?? []).find((d: any) => String(d["@type"]).includes("QuotaFailure"));
58 + const ids: string[] = (q?.violations ?? []).map((v: any) => v.quotaId);
59 + if (ids.some((i) => /PerDay/.test(i))) return "day";
60 + if (ids.some((i) => /PerMinute/.test(i))) return "minute";
61 + return "other";
62 +}
63 +
64 +/** Retry on per-minute 429 (honouring RetryInfo.retryDelay) and on 503 high demand; max `tries`. */
65 +export async function withRetry<T>(fn: () => Promise<T>, tries = 4): Promise<T> {
66 + let last: any;
67 + for (let i = 0; i < tries; i++) {
68 + try { return await fn(); } catch (e: any) {
69 + last = e;
70 + const info = errInfo(e);
71 + const kind = quotaKind(e);
72 + if (kind === "minute" || info.httpStatus === 503) {
73 + const ri = (info.details ?? []).find((d: any) => String(d["@type"]).includes("RetryInfo"));
74 + const secs = ri?.retryDelay ? parseInt(String(ri.retryDelay)) + 2 : 20;
75 + console.log(` ..${info.httpStatus} (${kind}); waiting ${secs}s then retry ${i + 1}/${tries - 1}`);
76 + await sleep(secs * 1000);
77 + continue;
78 + }
79 + throw e;
80 + }
81 + }
82 + throw last;
83 +}
84 +
85 +/** Pace requests to stay under the free-tier RPM for a given model. */
86 +export const PACE_MS = Number(process.env.PROBE_PACE_MS ?? 7000);
87 +
88 +export const shortText = (r: any) =>
89 + (r?.candidates?.[0]?.content?.parts ?? []).filter((p: any) => p.text && !p.thought).map((p: any) => p.text).join("").slice(0, 120);
added research/gemini/package.json +24 −0
@@ -0,0 +1,24 @@
1 +{
2 + "name": "gemini",
3 + "version": "1.0.0",
4 + "description": "",
5 + "main": "index.js",
6 + "scripts": {
7 + "test": "echo \"Error: no test specified\" && exit 1"
8 + },
9 + "keywords": [],
10 + "author": "",
11 + "license": "ISC",
12 + "devEngines": {
13 + "packageManager": {
14 + "name": "pnpm",
15 + "version": "^11.1.2",
16 + "onFail": "download"
17 + }
18 + },
19 + "type": "module",
20 + "dependencies": {
21 + "@google/genai": "^2.21.0",
22 + "tsx": "^4.23.13"
23 + }
24 +}
added research/gemini/pnpm-lock.yaml +91 −0
@@ -0,0 +1,824 @@
1 +---
2 +lockfileVersion: '9.0'
3 +
4 +importers:
5 +
6 + .:
7 + configDependencies: {}
8 + packageManagerDependencies:
9 + '@pnpm/exe':
10 + specifier: ^11.1.2
11 + version: 11.26.0
12 + pnpm:
13 + specifier: ^11.1.2
14 + version: 11.26.0
15 +
16 +packages:
17 +
18 + '@pnpm/exe@11.26.0':
19 + resolution: {integrity: sha512-eeiNi7WeXulOO1BzDAU9HIk+N3dokG+xwKPUupNQoZT5auL3rh2pFW9DqdIEnCC2xtt/hZd6UGtKyb6OMpqndw==}
20 + hasBin: true
21 +
22 + '@pnpm/linux-arm64@11.26.0':
23 + resolution: {integrity: sha512-M0IDuD4hbXxpLBsj1/I9pODcxu/gxTDtbyQmsVGYu1TZwCCpf6YU1x3lzq8aCGjrysmXYQAtCiY8GBjdw4UGFg==}
24 + cpu: [arm64]
25 + os: [linux]
26 +
27 + '@pnpm/linux-x64@11.26.0':
28 + resolution: {integrity: sha512-nUuNRsFCGVje3FHtOaWxIQl2EP4NBktKr+PpLN7uhuWnJCCMN/F9RKjNJAM+dUPyvAZs8VDvS0kA8J55kyybyg==}
29 + cpu: [x64]
30 + os: [linux]
31 +
32 + '@pnpm/linuxstatic-arm64@11.26.0':
33 + resolution: {integrity: sha512-+dXROkvdWjskrQtjwJAFuJI7Q2uTkghBfLsd0vqRmorX3fPuinhoRjJJ/UPtWXzJqwcByJBmdJRW+q2964m5qQ==}
34 + cpu: [arm64]
35 + os: [linux]
36 + libc: [musl]
37 +
38 + '@pnpm/linuxstatic-x64@11.26.0':
39 + resolution: {integrity: sha512-0eXE6spzIBdCbYhJZQ0u/sIOD0v30sqk2PrzoixzsNMc7S/lhd7EkBMVJ6cCPiCL2TXvOsrJC2SpWPBK769A9A==}
40 + cpu: [x64]
41 + os: [linux]
42 + libc: [musl]
43 +
44 + '@pnpm/macos-arm64@11.26.0':
45 + resolution: {integrity: sha512-Za3kKV89Zj0SFzQf6zEUTUIy13xH8UiNyb7aILDRjPiTvTaUSCh3q+nvljISfGH1XcopXvo+p3K8Q2nrKYWAug==}
46 + cpu: [arm64]
47 + os: [darwin]
48 +
49 + '@pnpm/win-arm64@11.26.0':
50 + resolution: {integrity: sha512-5akeLtbqbFDdJtCV4qgLmDBV3R+XNs6E7h7Xb4ZBzS3rLRp8e/y/ZdgrZaGF5Kjo45g0BLAxdGUREHbU2/lGUw==}
51 + cpu: [arm64]
52 + os: [win32]
53 +
54 + '@pnpm/win-x64@11.26.0':
55 + resolution: {integrity: sha512-f15SfIo7nppxBII+STy6jpd1z3LgGTZh6skfuxKA/xHmkzopnQJQXr4hBnl1rJLJAnmuOhN8BssaC4LiXmS78w==}
56 + cpu: [x64]
57 + os: [win32]
58 +
59 + '@reflink/reflink-darwin-arm64@0.1.19':
60 + resolution: {integrity: sha512-ruy44Lpepdk1FqDz38vExBY/PVUsjxZA+chd9wozjUH9JjuDT/HEaQYA6wYN9mf041l0yLVar6BCZuWABJvHSA==}
61 + engines: {node: '>= 10'}
62 + cpu: [arm64]
63 + os: [darwin]
64 +
65 + '@reflink/reflink-darwin-x64@0.1.19':
66 + resolution: {integrity: sha512-By85MSWrMZa+c26TcnAy8SDk0sTUkYlNnwknSchkhHpGXOtjNDUOxJE9oByBnGbeuIE1PiQsxDG3Ud+IVV9yuA==}
67 + engines: {node: '>= 10'}
68 + cpu: [x64]
69 + os: [darwin]
70 +
71 + '@reflink/reflink-linux-arm64-gnu@0.1.19':
72 + resolution: {integrity: sha512-7P+er8+rP9iNeN+bfmccM4hTAaLP6PQJPKWSA4iSk2bNvo6KU6RyPgYeHxXmzNKzPVRcypZQTpFgstHam6maVg==}
73 + engines: {node: '>= 10'}
74 + cpu: [arm64]
75 + os: [linux]
76 + libc: [glibc]
77 +
78 + '@reflink/reflink-linux-arm64-musl@0.1.19':
79 + resolution: {integrity: sha512-37iO/Dp6m5DDaC2sf3zPtx/hl9FV3Xze4xoYidrxxS9bgP3S8ALroxRK6xBG/1TtfXKTvolvp+IjrUU6ujIGmA==}
80 + engines: {node: '>= 10'}
81 + cpu: [arm64]
82 + os: [linux]
83 + libc: [musl]
84 +
85 + '@reflink/reflink-linux-x64-gnu@0.1.19':
86 + resolution: {integrity: sha512-jbI8jvuYCaA3MVUdu8vLoLAFqC+iNMpiSuLbxlAgg7x3K5bsS8nOpTRnkLF7vISJ+rVR8W+7ThXlXlUQ93ulkw==}
87 + engines: {node: '>= 10'}
88 + cpu: [x64]
89 + os: [linux]
90 + libc: [glibc]
91 +

Diff truncated — file too large.