@visual-z/xeno 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +31 -746
- package/bin/xeno.exe +26 -0
- package/install.cjs +88 -0
- package/package.json +18 -48
- package/docs/app-server.md +0 -115
- package/docs/foundations.md +0 -88
- package/docs/install.md +0 -244
- package/docs/providers.md +0 -172
- package/docs/research/foundation-clients-2026-10-09.md +0 -27
- package/docs/research/foundation-editing-2026-10-09.md +0 -56
- package/docs/research/foundation-network-2026-10-09.md +0 -37
- package/docs/research/foundation-workflow-2026-10-09.md +0 -37
- package/src/apps/acp-server.ts +0 -41
- package/src/apps/agent-profiles.ts +0 -19
- package/src/apps/app-server.ts +0 -30
- package/src/apps/approve.ts +0 -49
- package/src/apps/cli.ts +0 -99
- package/src/apps/commands.ts +0 -319
- package/src/apps/completions.ts +0 -87
- package/src/apps/control-transport.ts +0 -90
- package/src/apps/export-cli.ts +0 -24
- package/src/apps/goal-flow.ts +0 -70
- package/src/apps/image-draft.ts +0 -46
- package/src/apps/input.ts +0 -312
- package/src/apps/model-catalog.ts +0 -69
- package/src/apps/preferences.ts +0 -20
- package/src/apps/project-trust.ts +0 -9
- package/src/apps/provider-connect.ts +0 -346
- package/src/apps/question-ui.ts +0 -27
- package/src/apps/render.ts +0 -181
- package/src/apps/resources.ts +0 -66
- package/src/apps/review.ts +0 -109
- package/src/apps/session-hub.ts +0 -96
- package/src/apps/session-lifecycle.ts +0 -64
- package/src/apps/shell.ts +0 -2066
- package/src/apps/startup-input.ts +0 -135
- package/src/apps/startup.ts +0 -1677
- package/src/apps/ui/app.ts +0 -1713
- package/src/apps/ui/control-model.ts +0 -43
- package/src/apps/ui/extension-host.ts +0 -194
- package/src/apps/ui/image-cache.ts +0 -121
- package/src/apps/ui/palette.ts +0 -88
- package/src/apps/ui/project.ts +0 -127
- package/src/apps/ui/standalone.ts +0 -148
- package/src/apps/ui/status-model.ts +0 -68
- package/src/apps/ui/surface.ts +0 -91
- package/src/apps/ui/theme.ts +0 -86
- package/src/apps/update-check.ts +0 -112
- package/src/apps/workflow.ts +0 -58
- package/src/core/acceptance.ts +0 -139
- package/src/core/action-defaults.ts +0 -58
- package/src/core/activity-status.ts +0 -52
- package/src/core/agent-profile.ts +0 -130
- package/src/core/attachment-input.ts +0 -17
- package/src/core/blind-checks.ts +0 -72
- package/src/core/boundary.ts +0 -174
- package/src/core/branch-receipt.ts +0 -26
- package/src/core/catalog-merge.ts +0 -19
- package/src/core/checkpoints.ts +0 -85
- package/src/core/churn.ts +0 -61
- package/src/core/command-artifacts.ts +0 -94
- package/src/core/command-contract.ts +0 -151
- package/src/core/completion-action.ts +0 -20
- package/src/core/completion-review.ts +0 -98
- package/src/core/context-detail.ts +0 -37
- package/src/core/context-policy.ts +0 -133
- package/src/core/context-window.ts +0 -54
- package/src/core/continuation.ts +0 -130
- package/src/core/control-protocol.ts +0 -69
- package/src/core/control-view.ts +0 -39
- package/src/core/cycle.ts +0 -17
- package/src/core/data-query.ts +0 -201
- package/src/core/deadline.ts +0 -40
- package/src/core/derive.ts +0 -516
- package/src/core/draft-images.ts +0 -56
- package/src/core/edit-plan.ts +0 -200
- package/src/core/environment.ts +0 -181
- package/src/core/event-validation.ts +0 -220
- package/src/core/events.ts +0 -670
- package/src/core/evidence-ladder.ts +0 -62
- package/src/core/evidence-links.ts +0 -68
- package/src/core/evidence.ts +0 -240
- package/src/core/execution.ts +0 -18
- package/src/core/exhaustive.ts +0 -18
- package/src/core/export.ts +0 -179
- package/src/core/extension-flags.ts +0 -14
- package/src/core/external-effects.ts +0 -488
- package/src/core/failure-recovery.ts +0 -173
- package/src/core/file-precondition.ts +0 -78
- package/src/core/file-references.ts +0 -35
- package/src/core/frontmatter.ts +0 -213
- package/src/core/git-status.ts +0 -29
- package/src/core/goal-view.ts +0 -64
- package/src/core/goal.ts +0 -200
- package/src/core/handoff.ts +0 -479
- package/src/core/history-query.ts +0 -139
- package/src/core/history.ts +0 -237
- package/src/core/image-limits.ts +0 -72
- package/src/core/images.ts +0 -46
- package/src/core/integration-health.ts +0 -34
- package/src/core/json-event.ts +0 -131
- package/src/core/json-pointer.ts +0 -46
- package/src/core/keymap.ts +0 -153
- package/src/core/lsp-framing.ts +0 -34
- package/src/core/mcp-config.ts +0 -68
- package/src/core/model-picker.ts +0 -64
- package/src/core/model-preferences.ts +0 -28
- package/src/core/model-replay.ts +0 -22
- package/src/core/model-scope.ts +0 -53
- package/src/core/note-guidance.ts +0 -34
- package/src/core/oauth-fields.ts +0 -44
- package/src/core/observation-view.ts +0 -152
- package/src/core/outcome.ts +0 -44
- package/src/core/overflow.ts +0 -59
- package/src/core/packages.ts +0 -47
- package/src/core/patch.ts +0 -130
- package/src/core/path-suggestions.ts +0 -59
- package/src/core/permissions.ts +0 -410
- package/src/core/process-receipt.ts +0 -105
- package/src/core/process-state.ts +0 -37
- package/src/core/program-status.ts +0 -40
- package/src/core/progress.ts +0 -150
- package/src/core/project.ts +0 -431
- package/src/core/prompt-policy.ts +0 -46
- package/src/core/prompts.ts +0 -111
- package/src/core/question.ts +0 -94
- package/src/core/queue.ts +0 -78
- package/src/core/read-bounds.ts +0 -24
- package/src/core/read-observation.ts +0 -106
- package/src/core/recovery-sources.ts +0 -74
- package/src/core/regex-dialect.ts +0 -25
- package/src/core/request-budget.ts +0 -23
- package/src/core/request-progress.ts +0 -87
- package/src/core/request-state.ts +0 -273
- package/src/core/resource-selection.ts +0 -36
- package/src/core/response-recovery.ts +0 -59
- package/src/core/resume.ts +0 -59
- package/src/core/review.ts +0 -68
- package/src/core/ripgrep-release.ts +0 -64
- package/src/core/runtime-target.ts +0 -94
- package/src/core/scheduling.ts +0 -8
- package/src/core/search-observation.ts +0 -97
- package/src/core/secrets.ts +0 -188
- package/src/core/session-archive.ts +0 -4
- package/src/core/session-browser.ts +0 -82
- package/src/core/session-entry.ts +0 -61
- package/src/core/session-exit.ts +0 -42
- package/src/core/session-format.ts +0 -169
- package/src/core/session-position.ts +0 -26
- package/src/core/session-tree.ts +0 -147
- package/src/core/settings.ts +0 -192
- package/src/core/skills.ts +0 -165
- package/src/core/sql-query.ts +0 -211
- package/src/core/stall.ts +0 -128
- package/src/core/stop-report.ts +0 -68
- package/src/core/text-normalize.ts +0 -81
- package/src/core/theme.ts +0 -166
- package/src/core/thinking.ts +0 -26
- package/src/core/tokens.ts +0 -151
- package/src/core/tool-contract.ts +0 -153
- package/src/core/tool-discovery.ts +0 -87
- package/src/core/tool-failure.ts +0 -81
- package/src/core/tool-input.ts +0 -44
- package/src/core/transcript.ts +0 -108
- package/src/core/tui-mode.ts +0 -29
- package/src/core/update-check.ts +0 -157
- package/src/core/version.ts +0 -55
- package/src/core/web-content.ts +0 -80
- package/src/core/work-state.ts +0 -154
- package/src/core/workflow-mode.ts +0 -34
- package/src/core/working-set.ts +0 -119
- package/src/core/yaml.ts +0 -282
- package/src/runtime/acp-agent.ts +0 -289
- package/src/runtime/agent-profiles.ts +0 -21
- package/src/runtime/auth.ts +0 -367
- package/src/runtime/blind-check.ts +0 -36
- package/src/runtime/branch-jobs.ts +0 -36
- package/src/runtime/catalog.ts +0 -285
- package/src/runtime/clipboard.ts +0 -125
- package/src/runtime/command-artifacts.ts +0 -64
- package/src/runtime/connection-reuse.ts +0 -40
- package/src/runtime/control-client.ts +0 -149
- package/src/runtime/control-connection.ts +0 -139
- package/src/runtime/counter-check.ts +0 -74
- package/src/runtime/environment-tools.ts +0 -60
- package/src/runtime/evidence-notes.ts +0 -35
- package/src/runtime/exec-sessions.ts +0 -456
- package/src/runtime/execution-control.ts +0 -40
- package/src/runtime/extension-loader.ts +0 -37
- package/src/runtime/extension-ui.ts +0 -47
- package/src/runtime/extensions.ts +0 -370
- package/src/runtime/formatter-tool.ts +0 -38
- package/src/runtime/formatter.ts +0 -50
- package/src/runtime/foundation.ts +0 -116
- package/src/runtime/history-cache.ts +0 -57
- package/src/runtime/history-tools.ts +0 -168
- package/src/runtime/images.ts +0 -80
- package/src/runtime/integrations.ts +0 -216
- package/src/runtime/loop.ts +0 -3001
- package/src/runtime/lsp-client.ts +0 -201
- package/src/runtime/mcp-client.ts +0 -264
- package/src/runtime/mcp-oauth.ts +0 -168
- package/src/runtime/mcp-schema.ts +0 -51
- package/src/runtime/model-config.ts +0 -232
- package/src/runtime/model-data.LICENSE +0 -27
- package/src/runtime/model-data.ts +0 -21
- package/src/runtime/model-discovery.ts +0 -208
- package/src/runtime/model-replay.ts +0 -10
- package/src/runtime/model-scope.ts +0 -20
- package/src/runtime/model-sources.ts +0 -151
- package/src/runtime/model.ts +0 -686
- package/src/runtime/models-fetch.ts +0 -57
- package/src/runtime/oauth-device.ts +0 -86
- package/src/runtime/oauth.ts +0 -853
- package/src/runtime/open-image.ts +0 -42
- package/src/runtime/openai-responses.ts +0 -304
- package/src/runtime/openai.ts +0 -697
- package/src/runtime/output-schema.ts +0 -26
- package/src/runtime/package-manager.ts +0 -125
- package/src/runtime/patch-tool.ts +0 -38
- package/src/runtime/permission-resources.ts +0 -18
- package/src/runtime/pi-provider.ts +0 -423
- package/src/runtime/program-status.ts +0 -38
- package/src/runtime/progress.ts +0 -26
- package/src/runtime/provider-access.ts +0 -21
- package/src/runtime/provider-connect.ts +0 -109
- package/src/runtime/provider-presets.ts +0 -98
- package/src/runtime/provider-protocols.ts +0 -29
- package/src/runtime/provider-request.ts +0 -87
- package/src/runtime/provider-tool-policy.ts +0 -33
- package/src/runtime/provider.ts +0 -580
- package/src/runtime/question-tool.ts +0 -62
- package/src/runtime/retry.ts +0 -447
- package/src/runtime/review-tool.ts +0 -48
- package/src/runtime/rich-text.ts +0 -36
- package/src/runtime/runtime-target.ts +0 -149
- package/src/runtime/secrets.ts +0 -79
- package/src/runtime/self-update.ts +0 -74
- package/src/runtime/session-control.ts +0 -265
- package/src/runtime/session-hub.ts +0 -85
- package/src/runtime/stream-idle.ts +0 -80
- package/src/runtime/tool-broker.ts +0 -137
- package/src/runtime/tool-discovery.ts +0 -58
- package/src/runtime/tool-queue.ts +0 -77
- package/src/runtime/tools.ts +0 -1820
- package/src/runtime/turn-effects.ts +0 -31
- package/src/runtime/update-check.ts +0 -48
- package/src/runtime/usage.ts +0 -253
- package/src/runtime/version.ts +0 -12
- package/src/runtime/web-http.ts +0 -56
- package/src/runtime/web-tools.ts +0 -88
- package/src/runtime/working-notes.ts +0 -60
- package/src/runtime/workspace-lifecycle.ts +0 -141
- package/src/store/acceptance.ts +0 -15
- package/src/store/agent-profile-files.ts +0 -13
- package/src/store/atomic.ts +0 -31
- package/src/store/auth-store.ts +0 -50
- package/src/store/blind-checks.ts +0 -32
- package/src/store/blobs.ts +0 -143
- package/src/store/checkpoint-history.ts +0 -32
- package/src/store/command-artifacts.ts +0 -96
- package/src/store/command.ts +0 -111
- package/src/store/config.ts +0 -69
- package/src/store/context-files.ts +0 -436
- package/src/store/file-checkpoints.ts +0 -108
- package/src/store/file-index.ts +0 -174
- package/src/store/foundation-config.ts +0 -24
- package/src/store/git-checkpoints.ts +0 -67
- package/src/store/git-status.ts +0 -15
- package/src/store/history-search.ts +0 -19
- package/src/store/log.ts +0 -725
- package/src/store/lsp-document.ts +0 -30
- package/src/store/mcp-credentials.ts +0 -85
- package/src/store/models.ts +0 -60
- package/src/store/observations.ts +0 -224
- package/src/store/packages.ts +0 -98
- package/src/store/patch.ts +0 -92
- package/src/store/permission-paths.ts +0 -34
- package/src/store/process-receipts.ts +0 -34
- package/src/store/query-source.ts +0 -49
- package/src/store/recovery.ts +0 -44
- package/src/store/replay.ts +0 -76
- package/src/store/resource-index.ts +0 -170
- package/src/store/resources.ts +0 -285
- package/src/store/restore.ts +0 -110
- package/src/store/review.ts +0 -109
- package/src/store/runtime-target.ts +0 -64
- package/src/store/search.ts +0 -728
- package/src/store/secrets.ts +0 -44
- package/src/store/serial.ts +0 -13
- package/src/store/session-archive.ts +0 -165
- package/src/store/session-browser.ts +0 -68
- package/src/store/session-position.ts +0 -27
- package/src/store/sessions.ts +0 -525
- package/src/store/source-cancellation.ts +0 -6
- package/src/store/tool-binaries.ts +0 -90
- package/src/store/trust.ts +0 -82
- package/src/store/update-cache.ts +0 -36
- package/src/store/user-settings.ts +0 -30
- package/src/store/workspace-clone.ts +0 -42
- package/src/store/workspace-observation.ts +0 -113
- package/src/store/workspace.ts +0 -115
- package/src/store/worktree.ts +0 -278
- package/src/tui/ansi-spans.ts +0 -126
- package/src/tui/diff.ts +0 -160
- package/src/tui/exhaustive.ts +0 -14
- package/src/tui/fuzzy.ts +0 -75
- package/src/tui/style.ts +0 -208
- package/src/tui/ui/atomic-draft.ts +0 -121
- package/src/tui/ui/canvas.ts +0 -96
- package/src/tui/ui/colors.ts +0 -70
- package/src/tui/ui/composer.ts +0 -200
- package/src/tui/ui/control-panel.ts +0 -25
- package/src/tui/ui/control-sidebar.ts +0 -49
- package/src/tui/ui/dialog.ts +0 -398
- package/src/tui/ui/draft.ts +0 -23
- package/src/tui/ui/duration.ts +0 -16
- package/src/tui/ui/edge.ts +0 -186
- package/src/tui/ui/image-size.ts +0 -44
- package/src/tui/ui/ink.ts +0 -210
- package/src/tui/ui/items.ts +0 -42
- package/src/tui/ui/keys.ts +0 -40
- package/src/tui/ui/layout.ts +0 -74
- package/src/tui/ui/list-model.ts +0 -86
- package/src/tui/ui/list-view.ts +0 -172
- package/src/tui/ui/mascot.ts +0 -67
- package/src/tui/ui/messages.ts +0 -518
- package/src/tui/ui/motion.ts +0 -28
- package/src/tui/ui/paths.ts +0 -10
- package/src/tui/ui/pictures.ts +0 -108
- package/src/tui/ui/screen.ts +0 -548
- package/src/tui/ui/status.ts +0 -403
- package/src/tui/ui/styled.ts +0 -85
- package/src/tui/ui/tool-card.ts +0 -150
- package/src/tui/width.ts +0 -567
- package/src/vendor/pi-rich/LICENSE.upstream +0 -21
- package/src/vendor/pi-rich/UPSTREAM.json +0 -17
- package/src/vendor/pi-rich/clipboard-command.ts +0 -44
- package/src/vendor/pi-rich/exif-orientation.ts +0 -182
- package/src/vendor/pi-rich/html.ts +0 -51
- package/src/vendor/pi-rich/image-convert.ts +0 -49
- package/src/vendor/pi-rich/image-resize-core.ts +0 -164
- package/src/vendor/pi-rich/image-resize-worker.ts +0 -42
- package/src/vendor/pi-rich/image-resize.ts +0 -123
- package/src/vendor/pi-rich/mime.ts +0 -116
- package/src/vendor/pi-rich/photon.ts +0 -139
- package/src/vendor/pi-rich/syntax-highlight.ts +0 -214
package/src/runtime/model.ts
DELETED
|
@@ -1,686 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What the runtime needs to know about a model: how to talk to it, and how to
|
|
3
|
-
* price what it did.
|
|
4
|
-
*
|
|
5
|
-
* This exists because the two facts turned out to be inseparable. The obvious
|
|
6
|
-
* shape is "an adapter per wire format" and nothing else, but pricing is not a
|
|
7
|
-
* property of the wire format -- two providers speaking the same OpenAI
|
|
8
|
-
* Completions dialect bill caching on completely different terms. So the model,
|
|
9
|
-
* not the adapter, is what carries the rates.
|
|
10
|
-
*
|
|
11
|
-
* Deliberately not a class and deliberately inert: a spec is data the catalog
|
|
12
|
-
* hands to an adapter, and anything that can reach the network belongs in the
|
|
13
|
-
* adapter instead.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* The protocol vocabulary is local even when the runtime delegates wire IO to Pi.
|
|
18
|
-
*/
|
|
19
|
-
import type { ProviderApi } from "./provider-protocols.ts";
|
|
20
|
-
import { SOURCE_MODELS } from "./model-data.ts";
|
|
21
|
-
import { mergeCatalogs } from "../core/catalog-merge.ts";
|
|
22
|
-
import { GROK_PROVIDER, GROK_BASE_URL } from "./oauth.ts";
|
|
23
|
-
export type Api = ProviderApi;
|
|
24
|
-
|
|
25
|
-
/** How hard the model should think. Capability and wire vocabulary are mapped per model. */
|
|
26
|
-
import type { ThinkingLevel } from "../core/thinking.ts";
|
|
27
|
-
export type Effort = ThinkingLevel;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Who decides what gets cached.
|
|
31
|
-
*
|
|
32
|
-
* explicit -- the caller places breakpoints and the provider bills for the
|
|
33
|
-
* write. Hits are predictable because you chose the boundary.
|
|
34
|
-
* (Anthropic)
|
|
35
|
-
* automatic -- the provider caches prefixes by itself, bills nothing for the
|
|
36
|
-
* write, and guarantees no hit rate. Writes land in seconds, so
|
|
37
|
-
* an early miss is normal rather than a symptom. (DeepSeek)
|
|
38
|
-
*
|
|
39
|
-
* A named pair rather than two booleans: both the cost path and the diagnosis
|
|
40
|
-
* path fork on this, and a discriminant can be closed with `assertNever`.
|
|
41
|
-
*/
|
|
42
|
-
export type CacheKind = "explicit" | "automatic";
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Cache prices as multiples of base input.
|
|
46
|
-
*
|
|
47
|
-
* Multiples rather than dollars because that is the unit `equivalentCost`
|
|
48
|
-
* reports in, and for the reason stated there: dollar prices go stale, ratios
|
|
49
|
-
* survive a price change. A provider that bills nothing for cache writes sets
|
|
50
|
-
* `write: 0`, which is not a placeholder -- it is the actual term.
|
|
51
|
-
*/
|
|
52
|
-
export interface CacheRates {
|
|
53
|
-
read: number;
|
|
54
|
-
write: number;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* USD per million tokens.
|
|
59
|
-
*
|
|
60
|
-
* Optional on the model, and filled in only where the number was read off
|
|
61
|
-
* a source we trust. An unverified price is worse than an absent one: it
|
|
62
|
-
* looks authoritative and silently misreports every session.
|
|
63
|
-
*
|
|
64
|
-
* Cache fields are optional because most providers publish input/output
|
|
65
|
-
* and nothing else. Requiring all four packed a partial fact into a total
|
|
66
|
-
* unknown — the catalog then had the groq rate and /usage still said
|
|
67
|
-
* "unknown". Filling the missing cache slot with 0 is still forbidden:
|
|
68
|
-
* `write: 0` is DeepSeek's and Z.AI's actual term, not a default.
|
|
69
|
-
*/
|
|
70
|
-
export interface Price {
|
|
71
|
-
input: number;
|
|
72
|
-
output: number;
|
|
73
|
-
cacheRead?: number;
|
|
74
|
-
cacheWrite?: number;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Which dialect of "OpenAI-compatible" a model speaks.
|
|
79
|
-
*
|
|
80
|
-
* Every field here is a difference that costs a 400 or a wrong number, and
|
|
81
|
-
* every one was found the same way: a provider quietly disagreeing with the
|
|
82
|
-
* spec. Carried as data because the alternative -- branching on the provider's
|
|
83
|
-
* name inside the adapter -- becomes an unextendable chain of `||` by the
|
|
84
|
-
* third provider.
|
|
85
|
-
*
|
|
86
|
-
* Only relevant to `openai-completions`. The Anthropic adapter has one dialect
|
|
87
|
-
* by construction: its own.
|
|
88
|
-
*/
|
|
89
|
-
export interface Compat {
|
|
90
|
-
/**
|
|
91
|
-
* Whether the system prompt may be sent with the `developer` role, which
|
|
92
|
-
* reasoning-capable OpenAI models expect. Servers that predate it (Ollama,
|
|
93
|
-
* vLLM, DeepSeek) reject the role outright, so they get `system`.
|
|
94
|
-
*/
|
|
95
|
-
supportsDeveloperRole: boolean;
|
|
96
|
-
/**
|
|
97
|
-
* OpenAI renamed this for reasoning models and most of the family did not
|
|
98
|
-
* follow. Sending the wrong one is not an error -- it is silently ignored,
|
|
99
|
-
* and the response runs to the model's own default length.
|
|
100
|
-
*/
|
|
101
|
-
maxTokensField: "max_tokens" | "max_completion_tokens";
|
|
102
|
-
/** Whether `reasoning_effort` is understood. Some servers 400 on an unknown field. */
|
|
103
|
-
supportsReasoningEffort: boolean;
|
|
104
|
-
/**
|
|
105
|
-
* Whether the server accepts `stream_options: { include_usage: true }`.
|
|
106
|
-
* Default on: an OpenAI-dialect stream that is not asked for usage reports
|
|
107
|
-
* none, the loop would park a zero-token anchor, and shouldCut never fires.
|
|
108
|
-
* Some servers 400 on the unknown field, which is why this is a bit rather
|
|
109
|
-
* than assumed of every Completions accent.
|
|
110
|
-
*/
|
|
111
|
-
supportsUsageInStreaming: boolean;
|
|
112
|
-
/**
|
|
113
|
-
* DeepSeek requires `reasoning_content` on every assistant message once
|
|
114
|
-
* `tools` is in the request -- including turns that did no thinking -- and
|
|
115
|
-
* returns 400 without it.
|
|
116
|
-
*/
|
|
117
|
-
requiresReasoningContentOnAssistantMessages: boolean;
|
|
118
|
-
/** How thinking is switched on. `deepseek` adds `thinking: {type}`; `openai` uses effort alone. */
|
|
119
|
-
thinkingFormat: "openai" | "deepseek";
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Standard OpenAI. A model that says nothing about its accent is assumed to
|
|
124
|
-
* speak the documented one -- and will be corrected by a 400 if it does not,
|
|
125
|
-
* which is the cheapest way to find out.
|
|
126
|
-
*/
|
|
127
|
-
/**
|
|
128
|
-
* Kimi K3, from Moonshot's own agent guide (platform.kimi.ai, "Build an Agent
|
|
129
|
-
* with Kimi K3" and the Reasoning Effort page): it always reasons, takes no
|
|
130
|
-
* `thinking` field, accepts only low / high / max effort (default max), and
|
|
131
|
-
* every example uses the `system` role. The complete assistant message --
|
|
132
|
-
* reasoning included -- must be sent back, which the thinking block's raw
|
|
133
|
-
* already does; turns without reasoning get none, since "unmodified" rules
|
|
134
|
-
* out inventing an empty one.
|
|
135
|
-
*/
|
|
136
|
-
export const KIMI_K3_COMPAT: Compat = {
|
|
137
|
-
supportsDeveloperRole: false,
|
|
138
|
-
maxTokensField: "max_completion_tokens",
|
|
139
|
-
supportsReasoningEffort: true,
|
|
140
|
-
supportsUsageInStreaming: true,
|
|
141
|
-
requiresReasoningContentOnAssistantMessages: false,
|
|
142
|
-
thinkingFormat: "openai",
|
|
143
|
-
};
|
|
144
|
-
export const KIMI_K3_EFFORT: Partial<Record<Effort, string | null>> = {
|
|
145
|
-
off: null, minimal: "low",
|
|
146
|
-
low: "low", medium: "high", high: "high", xhigh: "max", max: "max",
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Gemini's OpenAI-compatible endpoint (ai.google.dev/gemini-api/docs/openai).
|
|
151
|
-
* It 400s on any effort outside none / low / medium / high -- reported
|
|
152
|
-
* verbatim on Google's developer forum -- and Gemini 3 cannot turn reasoning
|
|
153
|
-
* off, so the top of our scale maps to high. `max_tokens` is the documented
|
|
154
|
-
* field; `max_completion_tokens` has been reported ignored. Every official
|
|
155
|
-
* example uses `system`. Thought signatures ride on each tool call's `wire`.
|
|
156
|
-
*/
|
|
157
|
-
export const GEMINI_COMPAT: Compat = {
|
|
158
|
-
supportsDeveloperRole: false,
|
|
159
|
-
maxTokensField: "max_tokens",
|
|
160
|
-
supportsReasoningEffort: true,
|
|
161
|
-
supportsUsageInStreaming: true,
|
|
162
|
-
requiresReasoningContentOnAssistantMessages: false,
|
|
163
|
-
thinkingFormat: "openai",
|
|
164
|
-
};
|
|
165
|
-
export const GEMINI_EFFORT: Partial<Record<Effort, string | null>> = {
|
|
166
|
-
off: null, minimal: "low",
|
|
167
|
-
low: "low", medium: "medium", high: "high", xhigh: "high", max: "high",
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
export const DEFAULT_COMPAT: Compat = {
|
|
171
|
-
supportsDeveloperRole: true,
|
|
172
|
-
maxTokensField: "max_completion_tokens",
|
|
173
|
-
supportsReasoningEffort: true,
|
|
174
|
-
supportsUsageInStreaming: true,
|
|
175
|
-
requiresReasoningContentOnAssistantMessages: false,
|
|
176
|
-
thinkingFormat: "openai",
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
export interface ModelSpec {
|
|
180
|
-
/** Public variable names from the source directory, never their values. */
|
|
181
|
-
credentialEnv?: readonly string[];
|
|
182
|
-
/** Native Pi transport is runtime-only. Existing models retain their verified adapter. */
|
|
183
|
-
driver?: "pi";
|
|
184
|
-
/** Public catalog metadata only. User credentials/headers live in provider-access's sidecar. */
|
|
185
|
-
nativeCompat?: Record<string, unknown>;
|
|
186
|
-
samplingParams?: Record<string, unknown>;
|
|
187
|
-
defaultHeaders?: Record<string, string>;
|
|
188
|
-
/** The id sent on the wire. */
|
|
189
|
-
id: string;
|
|
190
|
-
/** Optional upstream deployment/model id when a user gives it a local catalog alias. */
|
|
191
|
-
wireId?: string;
|
|
192
|
-
/** For humans, in `/model` listings. */
|
|
193
|
-
name: string;
|
|
194
|
-
api: Api;
|
|
195
|
-
/** Catalog/auth key -- the name under which a credential is stored. */
|
|
196
|
-
provider: string;
|
|
197
|
-
/**
|
|
198
|
-
* Optional: the Anthropic SDK resolves its own default, and a custom
|
|
199
|
-
* endpoint overrides it. Required in practice for `openai-completions`,
|
|
200
|
-
* where there is no default worth guessing.
|
|
201
|
-
*/
|
|
202
|
-
baseUrl?: string;
|
|
203
|
-
reasoning: boolean;
|
|
204
|
-
/** Explicit capability from the model catalog. Unknown input capability is text-only. */
|
|
205
|
-
input?: readonly ("text" | "image")[];
|
|
206
|
-
/**
|
|
207
|
-
* Absent when the provider's caching terms are not in the source we
|
|
208
|
-
* trust. Filling `automatic` + `write: 0` here would be DeepSeek's
|
|
209
|
-
* contract, not a default, and `/usage` would then report a fake zero.
|
|
210
|
-
*/
|
|
211
|
-
cache?: CacheKind;
|
|
212
|
-
rates?: CacheRates;
|
|
213
|
-
price?: Price;
|
|
214
|
-
/**
|
|
215
|
-
* Both optional because an unverified number here would be a fabrication,
|
|
216
|
-
* and nothing reads them yet -- they are descriptive, for `/model` and for
|
|
217
|
-
* a future context-window check. Fill them from the provider's own docs or
|
|
218
|
-
* leave them out.
|
|
219
|
-
*/
|
|
220
|
-
contextWindow?: number;
|
|
221
|
-
maxTokens?: number;
|
|
222
|
-
/** Only meaningful for `openai-completions`. Absent means `DEFAULT_COMPAT`. */
|
|
223
|
-
compat?: Compat;
|
|
224
|
-
/**
|
|
225
|
-
* Pi's effort names onto the wire vocabulary. `null` disables a level.
|
|
226
|
-
* Unmapped xhigh/max are unsupported; other missing names pass through.
|
|
227
|
-
*/
|
|
228
|
-
thinkingLevelMap?: Partial<Record<Effort, string | null>>;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* 5-minute ephemeral caching: reads bill at 0.1x base input, writes at 1.25x.
|
|
233
|
-
* If Anthropic changes these, every cost number in the session report is
|
|
234
|
-
* wrong by that factor and nothing will raise an error -- so they live here,
|
|
235
|
-
* next to the model they describe, rather than as loose module constants.
|
|
236
|
-
*/
|
|
237
|
-
export const ANTHROPIC_RATES: CacheRates = { read: 0.1, write: 1.25 };
|
|
238
|
-
|
|
239
|
-
export const CLAUDE_OPUS_5: ModelSpec = {
|
|
240
|
-
id: "claude-opus-5",
|
|
241
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
242
|
-
input: ["text","image"],
|
|
243
|
-
name: "Claude Opus 5",
|
|
244
|
-
api: "anthropic-messages",
|
|
245
|
-
provider: "anthropic",
|
|
246
|
-
reasoning: true,
|
|
247
|
-
// Preserve the built-in request vocabulary while the generic capability policy becomes explicit.
|
|
248
|
-
thinkingLevelMap: { minimal: "low", xhigh: "xhigh", max: "max" },
|
|
249
|
-
cache: "explicit",
|
|
250
|
-
rates: ANTHROPIC_RATES,
|
|
251
|
-
// Cost from models.dev on 2026-09-21. Ratios match ANTHROPIC_RATES.
|
|
252
|
-
price: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
|
|
253
|
-
contextWindow: 1_000_000,
|
|
254
|
-
maxTokens: 128_000,
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* DeepSeek's accent, verified against its own docs rather than inferred:
|
|
259
|
-
* `max_tokens` (not the renamed field), no `developer` role, `thinking`
|
|
260
|
-
* toggled explicitly, and reasoning echoed back on every assistant message
|
|
261
|
-
* or the request is rejected once tools are present.
|
|
262
|
-
*/
|
|
263
|
-
const DEEPSEEK_COMPAT: Compat = {
|
|
264
|
-
supportsDeveloperRole: false,
|
|
265
|
-
maxTokensField: "max_tokens",
|
|
266
|
-
supportsReasoningEffort: true,
|
|
267
|
-
supportsUsageInStreaming: true,
|
|
268
|
-
requiresReasoningContentOnAssistantMessages: true,
|
|
269
|
-
thinkingFormat: "deepseek",
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Effort levels DeepSeek accepts: low, high, max. The docs say a request's
|
|
274
|
-
* level is remapped internally (minimal/low -> low, medium/high/xhigh ->
|
|
275
|
-
* high, max -> max), so this map does the same thing explicitly rather than
|
|
276
|
-
* sending a level the API has to guess about.
|
|
277
|
-
*/
|
|
278
|
-
const DEEPSEEK_EFFORT: Partial<Record<Effort, string | null>> = {
|
|
279
|
-
minimal: "low",
|
|
280
|
-
low: "low",
|
|
281
|
-
medium: "high",
|
|
282
|
-
high: "high",
|
|
283
|
-
xhigh: "high",
|
|
284
|
-
max: "max",
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Prices read off DeepSeek's own price page (peak rates, USD per 1M tokens).
|
|
289
|
-
* Off-peak is half of these, which changes the absolute cost but not the
|
|
290
|
-
* ratios below, and the ratios are what `equivalentCost` reports in.
|
|
291
|
-
*
|
|
292
|
-
* Cache creation has no separate billing line; misses are ordinary input.
|
|
293
|
-
* A zero creation rate does not make a rebuilt prefix free: those tokens
|
|
294
|
-
* still pay the cold input rate and evidence recovery may need more requests.
|
|
295
|
-
*/
|
|
296
|
-
export const DEEPSEEK_V4_PRO: ModelSpec = {
|
|
297
|
-
id: "deepseek-v4-pro",
|
|
298
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
299
|
-
input: ["text"],
|
|
300
|
-
name: "DeepSeek V4 Pro",
|
|
301
|
-
api: "openai-completions",
|
|
302
|
-
provider: "deepseek",
|
|
303
|
-
baseUrl: "https://api.deepseek.com",
|
|
304
|
-
reasoning: true,
|
|
305
|
-
cache: "automatic",
|
|
306
|
-
rates: { read: 0.044 / 1.32, write: 0 },
|
|
307
|
-
price: { input: 1.32, output: 3.96, cacheRead: 0.044, cacheWrite: 0 },
|
|
308
|
-
contextWindow: 1_000_000,
|
|
309
|
-
maxTokens: 384_000,
|
|
310
|
-
compat: DEEPSEEK_COMPAT,
|
|
311
|
-
thinkingLevelMap: DEEPSEEK_EFFORT,
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
export const DEEPSEEK_FLASH: ModelSpec = {
|
|
315
|
-
id: "deepseek-flash",
|
|
316
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
317
|
-
input: ["text","image"],
|
|
318
|
-
name: "DeepSeek V4.1 Flash",
|
|
319
|
-
api: "openai-completions",
|
|
320
|
-
provider: "deepseek",
|
|
321
|
-
baseUrl: "https://api.deepseek.com",
|
|
322
|
-
reasoning: true,
|
|
323
|
-
cache: "automatic",
|
|
324
|
-
rates: { read: 0.006 / 0.3, write: 0 },
|
|
325
|
-
price: { input: 0.3, output: 1.2, cacheRead: 0.006, cacheWrite: 0 },
|
|
326
|
-
contextWindow: 1_000_000,
|
|
327
|
-
maxTokens: 384_000,
|
|
328
|
-
compat: DEEPSEEK_COMPAT,
|
|
329
|
-
thinkingLevelMap: DEEPSEEK_EFFORT,
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* How we talk to a provider. A third `api` is another card, not a row here.
|
|
334
|
-
*
|
|
335
|
-
* Google is listed as Completions because it publishes an OpenAI-compatible
|
|
336
|
-
* endpoint at this URL; we are not pretending Gemini's native protocol is
|
|
337
|
-
* Chat Completions. xAI, Mistral, and OpenAI likewise have a Completions
|
|
338
|
-
* surface we already speak. Pi uses other adapters for some of these;
|
|
339
|
-
* bending ours to match would be the thing the card forbids.
|
|
340
|
-
*/
|
|
341
|
-
export const PROVIDER_WIRE: Readonly<Record<string, { api: Api; baseUrl?: string }>> = {
|
|
342
|
-
anthropic: { api: "anthropic-messages" },
|
|
343
|
-
openai: { api: "openai-completions", baseUrl: "https://api.openai.com/v1" },
|
|
344
|
-
google: { api: "openai-completions", baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai" },
|
|
345
|
-
deepseek: { api: "openai-completions", baseUrl: "https://api.deepseek.com" },
|
|
346
|
-
xai: { api: "openai-completions", baseUrl: "https://api.x.ai/v1" },
|
|
347
|
-
groq: { api: "openai-completions", baseUrl: "https://api.groq.com/openai/v1" },
|
|
348
|
-
cerebras: { api: "openai-completions", baseUrl: "https://api.cerebras.ai/v1" },
|
|
349
|
-
mistral: { api: "openai-completions", baseUrl: "https://api.mistral.ai/v1" },
|
|
350
|
-
openrouter: { api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1" },
|
|
351
|
-
zai: { api: "openai-completions", baseUrl: "https://api.z.ai/api/paas/v4" },
|
|
352
|
-
moonshotai: { api: "openai-completions", baseUrl: "https://api.moonshot.ai/v1" },
|
|
353
|
-
together: { api: "openai-completions", baseUrl: "https://api.together.xyz/v1" },
|
|
354
|
-
// models.dev's id; we store the catalog key as `together`.
|
|
355
|
-
togetherai: { api: "openai-completions", baseUrl: "https://api.together.xyz/v1" },
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
function anthropicModel(spec: Omit<ModelSpec, "api" | "provider">): ModelSpec {
|
|
359
|
-
return { api: "anthropic-messages", provider: "anthropic", ...spec };
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function completionsModel(spec: Omit<ModelSpec, "api">): ModelSpec {
|
|
363
|
-
return { api: "openai-completions", ...spec };
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* OpenAI's own endpoint for its reasoning models: Chat Completions would drop
|
|
368
|
-
* their reasoning between turns (feat-openai-responses). OpenRouter's GPT
|
|
369
|
-
* entries stay on Completions, which is the API OpenRouter serves.
|
|
370
|
-
*/
|
|
371
|
-
function responsesModel(spec: Omit<ModelSpec, "api">): ModelSpec {
|
|
372
|
-
return { api: "openai-responses", ...spec };
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Built-in catalog. Numbers from models.dev on 2026-09-21 unless a comment
|
|
377
|
-
* says otherwise. Price is omitted only when input or output is missing —
|
|
378
|
-
* a zero there would look like "this is free". cacheRead / cacheWrite are
|
|
379
|
-
* filled when the source has them and left off when it does not. Cache
|
|
380
|
-
* *rates* (multiples) stay omitted unless both cache dollars are present,
|
|
381
|
-
* except DeepSeek (verified against its own page).
|
|
382
|
-
*/
|
|
383
|
-
export const CURATED_CATALOG: readonly ModelSpec[] = [
|
|
384
|
-
CLAUDE_OPUS_5,
|
|
385
|
-
anthropicModel({
|
|
386
|
-
id: "claude-fable-5-1",
|
|
387
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
388
|
-
input: ["text","image"],
|
|
389
|
-
name: "Claude Fable 5.1",
|
|
390
|
-
reasoning: true,
|
|
391
|
-
cache: "explicit",
|
|
392
|
-
rates: { read: 0.25 / 10, write: 12.5 / 10 },
|
|
393
|
-
price: { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 },
|
|
394
|
-
contextWindow: 1_000_000,
|
|
395
|
-
maxTokens: 128_000,
|
|
396
|
-
}),
|
|
397
|
-
|
|
398
|
-
responsesModel({
|
|
399
|
-
id: "gpt-5.5-pro",
|
|
400
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
401
|
-
input: ["text","image"],
|
|
402
|
-
name: "GPT-5.5 Pro",
|
|
403
|
-
provider: "openai",
|
|
404
|
-
baseUrl: "https://api.openai.com/v1",
|
|
405
|
-
reasoning: true,
|
|
406
|
-
contextWindow: 1_050_000,
|
|
407
|
-
maxTokens: 128_000,
|
|
408
|
-
// Base rate. models.dev also lists a context_over_200k tier at 60/270.
|
|
409
|
-
price: { input: 30, output: 180 },
|
|
410
|
-
}),
|
|
411
|
-
responsesModel({
|
|
412
|
-
id: "gpt-5.4-pro",
|
|
413
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
414
|
-
input: ["text","image"],
|
|
415
|
-
name: "GPT-5.4 Pro",
|
|
416
|
-
provider: "openai",
|
|
417
|
-
baseUrl: "https://api.openai.com/v1",
|
|
418
|
-
reasoning: true,
|
|
419
|
-
contextWindow: 1_050_000,
|
|
420
|
-
maxTokens: 128_000,
|
|
421
|
-
// Base rate. models.dev also lists a context_over_200k tier at 60/270.
|
|
422
|
-
price: { input: 30, output: 180 },
|
|
423
|
-
}),
|
|
424
|
-
|
|
425
|
-
completionsModel({
|
|
426
|
-
id: "gemini-3.1-pro-preview",
|
|
427
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
428
|
-
input: ["text","image"],
|
|
429
|
-
name: "Gemini 3.1 Pro Preview",
|
|
430
|
-
provider: "google",
|
|
431
|
-
baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
|
|
432
|
-
reasoning: true,
|
|
433
|
-
contextWindow: 1_048_576,
|
|
434
|
-
maxTokens: 65_536,
|
|
435
|
-
// Base rate. models.dev also lists a context_over_200k tier (4/18/0.4).
|
|
436
|
-
price: { input: 2, output: 12, cacheRead: 0.2 },
|
|
437
|
-
compat: GEMINI_COMPAT,
|
|
438
|
-
thinkingLevelMap: GEMINI_EFFORT,
|
|
439
|
-
}),
|
|
440
|
-
|
|
441
|
-
DEEPSEEK_V4_PRO,
|
|
442
|
-
DEEPSEEK_FLASH,
|
|
443
|
-
|
|
444
|
-
{
|
|
445
|
-
id: "grok-build", name: "Grok Build", provider: GROK_PROVIDER, baseUrl: GROK_BASE_URL,
|
|
446
|
-
api: "openai-completions", driver: "pi", input: ["text"],
|
|
447
|
-
// The official proxy alias has no published effort/price contract. Do not copy API model rates.
|
|
448
|
-
reasoning: false,
|
|
449
|
-
nativeCompat: { supportsDeveloperRole: false, supportsReasoningEffort: false, maxTokensField: "max_tokens" },
|
|
450
|
-
},
|
|
451
|
-
|
|
452
|
-
completionsModel({
|
|
453
|
-
id: "grok-4.6",
|
|
454
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
455
|
-
input: ["text","image"],
|
|
456
|
-
name: "Grok 4.6",
|
|
457
|
-
provider: "xai",
|
|
458
|
-
baseUrl: "https://api.x.ai/v1",
|
|
459
|
-
reasoning: true,
|
|
460
|
-
contextWindow: 500_000,
|
|
461
|
-
maxTokens: 500_000,
|
|
462
|
-
// Base rate. models.dev also lists a context_over_200k tier (4/12/1).
|
|
463
|
-
price: { input: 2, output: 6, cacheRead: 0.5 },
|
|
464
|
-
}),
|
|
465
|
-
completionsModel({
|
|
466
|
-
id: "grok-4.5",
|
|
467
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
468
|
-
input: ["text","image"],
|
|
469
|
-
name: "Grok 4.5",
|
|
470
|
-
provider: "xai",
|
|
471
|
-
baseUrl: "https://api.x.ai/v1",
|
|
472
|
-
reasoning: true,
|
|
473
|
-
contextWindow: 500_000,
|
|
474
|
-
maxTokens: 500_000,
|
|
475
|
-
// Base rate. models.dev also lists a context_over_200k tier (4/12/0.6).
|
|
476
|
-
price: { input: 2, output: 6, cacheRead: 0.3 },
|
|
477
|
-
}),
|
|
478
|
-
|
|
479
|
-
completionsModel({
|
|
480
|
-
id: "llama-3.3-70b-versatile",
|
|
481
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
482
|
-
input: ["text"],
|
|
483
|
-
name: "Llama 3.3 70B",
|
|
484
|
-
provider: "groq",
|
|
485
|
-
baseUrl: "https://api.groq.com/openai/v1",
|
|
486
|
-
reasoning: false,
|
|
487
|
-
contextWindow: 131_072,
|
|
488
|
-
maxTokens: 32_768,
|
|
489
|
-
price: { input: 0.59, output: 0.79 },
|
|
490
|
-
}),
|
|
491
|
-
completionsModel({
|
|
492
|
-
id: "qwen/qwen3.6-27b",
|
|
493
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
494
|
-
input: ["text","image"],
|
|
495
|
-
name: "Qwen3.6 27B",
|
|
496
|
-
provider: "groq",
|
|
497
|
-
baseUrl: "https://api.groq.com/openai/v1",
|
|
498
|
-
reasoning: true,
|
|
499
|
-
contextWindow: 131_072,
|
|
500
|
-
maxTokens: 16_384,
|
|
501
|
-
price: { input: 0.6, output: 3, cacheRead: 0.3 },
|
|
502
|
-
}),
|
|
503
|
-
|
|
504
|
-
completionsModel({
|
|
505
|
-
id: "gpt-oss-120b",
|
|
506
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
507
|
-
input: ["text"],
|
|
508
|
-
name: "GPT OSS 120B",
|
|
509
|
-
provider: "cerebras",
|
|
510
|
-
baseUrl: "https://api.cerebras.ai/v1",
|
|
511
|
-
reasoning: true,
|
|
512
|
-
contextWindow: 131_072,
|
|
513
|
-
maxTokens: 40_960,
|
|
514
|
-
price: { input: 0.35, output: 0.75 },
|
|
515
|
-
}),
|
|
516
|
-
completionsModel({
|
|
517
|
-
id: "qwen-3.8-27b",
|
|
518
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
519
|
-
input: ["text","image"],
|
|
520
|
-
name: "Qwen3.8 27B",
|
|
521
|
-
provider: "cerebras",
|
|
522
|
-
baseUrl: "https://api.cerebras.ai/v1",
|
|
523
|
-
reasoning: true,
|
|
524
|
-
contextWindow: 65_536,
|
|
525
|
-
maxTokens: 32_768,
|
|
526
|
-
price: { input: 0.99, output: 1.49 },
|
|
527
|
-
}),
|
|
528
|
-
|
|
529
|
-
completionsModel({
|
|
530
|
-
id: "magistral-medium-latest",
|
|
531
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
532
|
-
input: ["text"],
|
|
533
|
-
name: "Magistral Medium (latest)",
|
|
534
|
-
provider: "mistral",
|
|
535
|
-
baseUrl: "https://api.mistral.ai/v1",
|
|
536
|
-
reasoning: true,
|
|
537
|
-
contextWindow: 128_000,
|
|
538
|
-
maxTokens: 16_384,
|
|
539
|
-
price: { input: 2, output: 5 },
|
|
540
|
-
}),
|
|
541
|
-
completionsModel({
|
|
542
|
-
id: "mistral-large-2411",
|
|
543
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
544
|
-
input: ["text"],
|
|
545
|
-
name: "Mistral Large 2.1",
|
|
546
|
-
provider: "mistral",
|
|
547
|
-
baseUrl: "https://api.mistral.ai/v1",
|
|
548
|
-
reasoning: false,
|
|
549
|
-
contextWindow: 131_072,
|
|
550
|
-
maxTokens: 16_384,
|
|
551
|
-
price: { input: 2, output: 6 },
|
|
552
|
-
}),
|
|
553
|
-
|
|
554
|
-
completionsModel({
|
|
555
|
-
id: "openai/gpt-5.5-pro",
|
|
556
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
557
|
-
input: ["text","image"],
|
|
558
|
-
name: "GPT-5.5 Pro",
|
|
559
|
-
provider: "openrouter",
|
|
560
|
-
baseUrl: "https://openrouter.ai/api/v1",
|
|
561
|
-
reasoning: true,
|
|
562
|
-
contextWindow: 1_050_000,
|
|
563
|
-
maxTokens: 128_000,
|
|
564
|
-
// Base rate. Same context_over_200k tier as the OpenAI row (60/270).
|
|
565
|
-
price: { input: 30, output: 180 },
|
|
566
|
-
}),
|
|
567
|
-
completionsModel({
|
|
568
|
-
id: "openai/gpt-5.4-pro",
|
|
569
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
570
|
-
input: ["text","image"],
|
|
571
|
-
name: "GPT-5.4 Pro",
|
|
572
|
-
provider: "openrouter",
|
|
573
|
-
baseUrl: "https://openrouter.ai/api/v1",
|
|
574
|
-
reasoning: true,
|
|
575
|
-
contextWindow: 1_050_000,
|
|
576
|
-
maxTokens: 128_000,
|
|
577
|
-
// Base rate. Same context_over_200k tier as the OpenAI row (60/270).
|
|
578
|
-
price: { input: 30, output: 180 },
|
|
579
|
-
}),
|
|
580
|
-
|
|
581
|
-
completionsModel({
|
|
582
|
-
id: "glm-5.3",
|
|
583
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
584
|
-
input: ["text"],
|
|
585
|
-
name: "GLM-5.3",
|
|
586
|
-
provider: "zai",
|
|
587
|
-
baseUrl: "https://api.z.ai/api/paas/v4",
|
|
588
|
-
reasoning: true,
|
|
589
|
-
cache: "automatic",
|
|
590
|
-
rates: { read: 0.26 / 1.4, write: 0 },
|
|
591
|
-
price: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 },
|
|
592
|
-
contextWindow: 1_000_000,
|
|
593
|
-
maxTokens: 131_072,
|
|
594
|
-
}),
|
|
595
|
-
completionsModel({
|
|
596
|
-
id: "glm-5.2",
|
|
597
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
598
|
-
input: ["text"],
|
|
599
|
-
name: "GLM-5.2",
|
|
600
|
-
provider: "zai",
|
|
601
|
-
baseUrl: "https://api.z.ai/api/paas/v4",
|
|
602
|
-
reasoning: true,
|
|
603
|
-
cache: "automatic",
|
|
604
|
-
rates: { read: 0.26 / 1.4, write: 0 },
|
|
605
|
-
price: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 },
|
|
606
|
-
contextWindow: 1_000_000,
|
|
607
|
-
maxTokens: 131_072,
|
|
608
|
-
}),
|
|
609
|
-
|
|
610
|
-
completionsModel({
|
|
611
|
-
id: "kimi-k3",
|
|
612
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
613
|
-
input: ["text","image"],
|
|
614
|
-
name: "Kimi K3",
|
|
615
|
-
provider: "moonshotai",
|
|
616
|
-
baseUrl: "https://api.moonshot.ai/v1",
|
|
617
|
-
reasoning: true,
|
|
618
|
-
contextWindow: 1_048_576,
|
|
619
|
-
maxTokens: 131_072,
|
|
620
|
-
price: { input: 3, output: 15, cacheRead: 0.3 },
|
|
621
|
-
compat: KIMI_K3_COMPAT,
|
|
622
|
-
thinkingLevelMap: KIMI_K3_EFFORT,
|
|
623
|
-
}),
|
|
624
|
-
completionsModel({
|
|
625
|
-
id: "kimi-k2.6",
|
|
626
|
-
// Input modalities from the existing models.dev catalog source, 2026-09-30.
|
|
627
|
-
input: ["text","image"],
|
|
628
|
-
name: "Kimi K2.6",
|
|
629
|
-
provider: "moonshotai",
|
|
630
|
-
baseUrl: "https://api.moonshot.ai/v1",
|
|
631
|
-
reasoning: true,
|
|
632
|
-
contextWindow: 262_144,
|
|
633
|
-
maxTokens: 262_144,
|
|
634
|
-
price: { input: 0.95, output: 4, cacheRead: 0.16 },
|
|
635
|
-
}),
|
|
636
|
-
|
|
637
|
-
completionsModel({
|
|
638
|
-
id: "moonshotai/Kimi-K3",
|
|
639
|
-
name: "Kimi K3",
|
|
640
|
-
provider: "together",
|
|
641
|
-
baseUrl: "https://api.together.xyz/v1",
|
|
642
|
-
reasoning: true,
|
|
643
|
-
contextWindow: 1_048_576,
|
|
644
|
-
maxTokens: 131_072,
|
|
645
|
-
price: { input: 3, output: 15, cacheRead: 0.3 },
|
|
646
|
-
compat: KIMI_K3_COMPAT,
|
|
647
|
-
thinkingLevelMap: KIMI_K3_EFFORT,
|
|
648
|
-
}),
|
|
649
|
-
completionsModel({
|
|
650
|
-
id: "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8",
|
|
651
|
-
name: "Qwen3 Coder 480B A35B Instruct",
|
|
652
|
-
provider: "together",
|
|
653
|
-
baseUrl: "https://api.together.xyz/v1",
|
|
654
|
-
reasoning: false,
|
|
655
|
-
contextWindow: 262_144,
|
|
656
|
-
maxTokens: 262_144,
|
|
657
|
-
// models.dev has input 2 / output 2. Left unpriced so the catalog
|
|
658
|
-
// still contains a model whose price was not filled in — the existing
|
|
659
|
-
// "unknown cost instead of zero" assertion is a living fixture, not
|
|
660
|
-
// a gap we are allowed to close by inventing a reason to skip a rate.
|
|
661
|
-
// Filling every other row that has numbers already exceeds 20.
|
|
662
|
-
}),
|
|
663
|
-
];
|
|
664
|
-
|
|
665
|
-
// Keep existing default/provider order and verified wire dialects; add the source union once.
|
|
666
|
-
export const CATALOG: readonly ModelSpec[] = mergeCatalogs(CURATED_CATALOG,
|
|
667
|
-
SOURCE_MODELS.filter(model => !CURATED_CATALOG.some(curated => curated.provider === model.provider && curated.id === model.id)));
|
|
668
|
-
|
|
669
|
-
/**
|
|
670
|
-
* Output tokens to request, which is also the output reserve every window
|
|
671
|
-
* budget subtracts.
|
|
672
|
-
*
|
|
673
|
-
* Three bounds, smallest wins. The model's own limit, because asking for more
|
|
674
|
-
* is a 400. A default -- 32000 for reasoning models, whose thinking is billed
|
|
675
|
-
* as output and truncated at 16000 often enough to trigger output recovery;
|
|
676
|
-
* 16000 otherwise, the previous fixed value. A quarter of the window, so a
|
|
677
|
-
* 64k model does not hand a quarter of its context to a reply that is usually
|
|
678
|
-
* a few hundred tokens. The defaults are operational choices (32000 is also
|
|
679
|
-
* Claude Code's default), not measurements.
|
|
680
|
-
*/
|
|
681
|
-
export function outputTokenBudget(spec: ModelSpec): number {
|
|
682
|
-
const bounds = [spec.reasoning ? 32_000 : 16_000];
|
|
683
|
-
if (spec.maxTokens !== undefined) bounds.push(spec.maxTokens);
|
|
684
|
-
if (spec.contextWindow !== undefined) bounds.push(Math.floor(spec.contextWindow / 4));
|
|
685
|
-
return Math.max(1, Math.min(...bounds));
|
|
686
|
-
}
|