@theokit/sdk 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +122 -0
- package/dist/a2a/index.cjs +191 -48
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +192 -49
- package/dist/a2a/index.js.map +1 -1
- package/dist/compaction.cjs +78 -0
- package/dist/compaction.cjs.map +1 -0
- package/dist/compaction.d.cts +76 -0
- package/dist/compaction.d.ts +76 -0
- package/dist/compaction.js +70 -0
- package/dist/compaction.js.map +1 -0
- package/dist/{cron-JSPSFczQ.d.cts → cron-B656C3iq.d.cts} +28 -2
- package/dist/{cron-Aksw2Hy4.d.ts → cron-CM2M9mhB.d.ts} +28 -2
- package/dist/cron.cjs +192 -57
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +2 -2
- package/dist/cron.d.ts +2 -2
- package/dist/cron.js +192 -57
- package/dist/cron.js.map +1 -1
- package/dist/{errors-Bcw_Pakm.d.ts → errors-DG_7CAUg.d.ts} +1 -1
- package/dist/{errors-Vhg6ZV4o.d.cts → errors-QDYUPABr.d.cts} +1 -1
- package/dist/errors.d.cts +2 -2
- package/dist/eval.cjs +192 -57
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +192 -57
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +275 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -7
- package/dist/index.d.ts +50 -7
- package/dist/index.js +275 -69
- package/dist/index.js.map +1 -1
- package/dist/internal/agent-loop/loop.d.ts +5 -0
- package/dist/internal/llm/model-capabilities.d.ts +40 -0
- package/dist/internal/llm/model-identifier.d.ts +9 -1
- package/dist/internal/llm/model-option.d.ts +38 -0
- package/dist/internal/runtime/compression/compression-attempt.d.ts +24 -0
- package/dist/internal/runtime/compression/compression-config.d.ts +33 -0
- package/dist/internal/runtime/compression/compression-decision.d.ts +10 -0
- package/dist/internal/runtime/compression/compression-helpers.d.ts +18 -0
- package/dist/internal/runtime/compression/compression-model-registry.d.ts +41 -0
- package/dist/internal/runtime/compression/compression-summarizer.d.ts +29 -0
- package/dist/internal/runtime/context/project-instructions.d.ts +66 -0
- package/dist/internal/runtime/context/replay-history.d.ts +43 -0
- package/dist/internal/runtime/hooks/hooks-frontmatter.d.ts +1 -1
- package/dist/internal/runtime/lifecycle/run-to-completion.d.ts +22 -0
- package/dist/internal/runtime/skills/discover-skills.d.ts +68 -0
- package/dist/internal/runtime/skills/skills-block.d.ts +18 -0
- package/dist/internal/runtime/skills/subagent-tool-scope.d.ts +25 -0
- package/dist/messages.cjs +24 -0
- package/dist/messages.cjs.map +1 -0
- package/dist/messages.d.cts +33 -0
- package/dist/messages.d.ts +33 -0
- package/dist/messages.js +20 -0
- package/dist/messages.js.map +1 -0
- package/dist/models.cjs +233 -0
- package/dist/models.cjs.map +1 -0
- package/dist/models.d.cts +16 -0
- package/dist/models.d.ts +16 -0
- package/dist/models.js +228 -0
- package/dist/models.js.map +1 -0
- package/dist/project.cjs +149 -0
- package/dist/project.cjs.map +1 -0
- package/dist/project.d.cts +14 -0
- package/dist/project.d.ts +14 -0
- package/dist/project.js +146 -0
- package/dist/project.js.map +1 -0
- package/dist/{run-ekGKZlmg.d.cts → run-BPRYG1Id.d.cts} +55 -2
- package/dist/{run-ekGKZlmg.d.ts → run-BPRYG1Id.d.ts} +55 -2
- package/dist/skills.cjs +282 -0
- package/dist/skills.cjs.map +1 -0
- package/dist/skills.d.cts +19 -0
- package/dist/skills.d.ts +19 -0
- package/dist/skills.js +279 -0
- package/dist/skills.js.map +1 -0
- package/dist/subagents.cjs +24 -0
- package/dist/subagents.cjs.map +1 -0
- package/dist/subagents.d.cts +14 -0
- package/dist/subagents.d.ts +14 -0
- package/dist/subagents.js +21 -0
- package/dist/subagents.js.map +1 -0
- package/dist/types/agent.d.ts +22 -0
- package/dist/types/conversation-storage.d.ts +5 -1
- package/dist/types/run.d.ts +54 -1
- package/package.json +62 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/messages.ts"],"names":[],"mappings":";AAmBO,SAAS,cAAc,GAAA,EAAyB;AACrD,EAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,IAAA,OAAO,EAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAI,OAAA,CAAQ,OAAA,CAChB,MAAA,CAAO,CAAC,UAA4D,KAAA,CAAM,IAAA,KAAS,MAAM,CAAA,CACzF,IAAI,CAAC,KAAA,KAAU,MAAM,IAAI,CAAA,CACzB,KAAK,EAAE,CAAA;AACZ;AASO,SAAS,gBAAgB,GAAA,EAAiC;AAC/D,EAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,IAAA,OAAO,EAAC;AAAA,EACV;AACA,EAAA,OAAO,GAAA,CAAI,QAAQ,OAAA,CAAQ,MAAA,CAAO,CAAC,KAAA,KAAiC,KAAA,CAAM,SAAS,UAAU,CAAA;AAC/F;AAQO,SAAS,cAAc,IAAA,EAAqD;AACjF,EAAA,OAAO,IAAA,EAAM,SAAA;AACf","file":"messages.js","sourcesContent":["/**\n * Pure readers over the `SDKMessage` stream (M1-5).\n *\n * Promotes the proven first-party hand-roll (`../theocode/server/lib/sdk-mappers.ts`)\n * onto the SDK's own types so consumers stop re-implementing a wire-event mapper.\n * Every reader is pure: no I/O, no mutation of its input, deterministic.\n *\n * Public from the `@theokit/sdk/messages` sub-path. See `docs.md → Message readers`.\n */\n\nimport type { SDKMessage, ToolUseBlock } from \"./types/messages.js\";\nimport type { CostBreakdown } from \"./types/usage.js\";\n\n/**\n * Concatenate the text of an assistant message's `TextBlock`s.\n *\n * Returns `\"\"` for any non-assistant message (or an assistant with no text\n * blocks). `tool_use` blocks are ignored — only `text` blocks contribute.\n */\nexport function assistantText(msg: SDKMessage): string {\n if (msg.type !== \"assistant\") {\n return \"\";\n }\n return msg.message.content\n .filter((block): block is Extract<typeof block, { type: \"text\" }> => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\");\n}\n\n/**\n * Extract the `ToolUseBlock`s from an assistant message's content.\n *\n * Returns `[]` for any non-assistant message. This reads the assistant\n * message's content blocks — NOT the separate `SDKToolUseMessage`\n * (`type:\"tool_call\"`) lifecycle event, which is a different stream (ADR D2).\n */\nexport function extractToolUses(msg: SDKMessage): ToolUseBlock[] {\n if (msg.type !== \"assistant\") {\n return [];\n }\n return msg.message.content.filter((block): block is ToolUseBlock => block.type === \"tool_use\");\n}\n\n/**\n * Read the cost amount from a `CostBreakdown`, preserving the honesty contract\n * (repo ADR `D377-cost-status-closed-enum.md`): `amountUsd` is `number | undefined`\n * where `undefined` means \"cost unknown\" — distinct from a real `$0` (e.g. a\n * subscription-included route). NEVER coerced to 0.\n */\nexport function costAmountUsd(cost: CostBreakdown | undefined): number | undefined {\n return cost?.amountUsd;\n}\n"]}
|
package/dist/models.cjs
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/internal/llm/model-capabilities.ts
|
|
4
|
+
var CONSERVATIVE_DEFAULTS = {
|
|
5
|
+
supportsVision: false,
|
|
6
|
+
supportsStructuredOutput: false,
|
|
7
|
+
supportsToolUse: false,
|
|
8
|
+
supportsCacheControl: false,
|
|
9
|
+
maxContextTokens: 4096,
|
|
10
|
+
maxOutputTokens: 4096
|
|
11
|
+
};
|
|
12
|
+
var EXACT = /* @__PURE__ */ new Map([
|
|
13
|
+
// OpenAI family
|
|
14
|
+
[
|
|
15
|
+
"openai/gpt-4o",
|
|
16
|
+
{
|
|
17
|
+
supportsVision: true,
|
|
18
|
+
supportsStructuredOutput: true,
|
|
19
|
+
supportsToolUse: true,
|
|
20
|
+
supportsCacheControl: false,
|
|
21
|
+
maxContextTokens: 128e3,
|
|
22
|
+
maxOutputTokens: 16384
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
[
|
|
26
|
+
"openai/gpt-4o-mini",
|
|
27
|
+
{
|
|
28
|
+
supportsVision: true,
|
|
29
|
+
supportsStructuredOutput: true,
|
|
30
|
+
supportsToolUse: true,
|
|
31
|
+
supportsCacheControl: false,
|
|
32
|
+
maxContextTokens: 128e3,
|
|
33
|
+
maxOutputTokens: 16384
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
"openai/gpt-4-turbo",
|
|
38
|
+
{
|
|
39
|
+
supportsVision: true,
|
|
40
|
+
supportsStructuredOutput: false,
|
|
41
|
+
supportsToolUse: true,
|
|
42
|
+
supportsCacheControl: false,
|
|
43
|
+
maxContextTokens: 128e3,
|
|
44
|
+
maxOutputTokens: 4096
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
"openai/o1",
|
|
49
|
+
{
|
|
50
|
+
supportsVision: false,
|
|
51
|
+
supportsStructuredOutput: true,
|
|
52
|
+
supportsToolUse: true,
|
|
53
|
+
supportsCacheControl: false,
|
|
54
|
+
maxContextTokens: 2e5,
|
|
55
|
+
maxOutputTokens: 1e5
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
"openai/o3",
|
|
60
|
+
{
|
|
61
|
+
supportsVision: false,
|
|
62
|
+
supportsStructuredOutput: true,
|
|
63
|
+
supportsToolUse: true,
|
|
64
|
+
supportsCacheControl: false,
|
|
65
|
+
maxContextTokens: 2e5,
|
|
66
|
+
maxOutputTokens: 1e5
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
// Anthropic family
|
|
70
|
+
[
|
|
71
|
+
"anthropic/claude-opus-4",
|
|
72
|
+
{
|
|
73
|
+
supportsVision: true,
|
|
74
|
+
supportsStructuredOutput: false,
|
|
75
|
+
supportsToolUse: true,
|
|
76
|
+
supportsCacheControl: true,
|
|
77
|
+
maxContextTokens: 2e5,
|
|
78
|
+
maxOutputTokens: 32e3
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
"anthropic/claude-sonnet-4",
|
|
83
|
+
{
|
|
84
|
+
supportsVision: true,
|
|
85
|
+
supportsStructuredOutput: false,
|
|
86
|
+
supportsToolUse: true,
|
|
87
|
+
supportsCacheControl: true,
|
|
88
|
+
maxContextTokens: 2e5,
|
|
89
|
+
maxOutputTokens: 16e3
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
[
|
|
93
|
+
"anthropic/claude-3-5-sonnet",
|
|
94
|
+
{
|
|
95
|
+
supportsVision: true,
|
|
96
|
+
supportsStructuredOutput: false,
|
|
97
|
+
supportsToolUse: true,
|
|
98
|
+
supportsCacheControl: true,
|
|
99
|
+
maxContextTokens: 2e5,
|
|
100
|
+
maxOutputTokens: 8192
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
[
|
|
104
|
+
"anthropic/claude-3-5-sonnet-latest",
|
|
105
|
+
{
|
|
106
|
+
supportsVision: true,
|
|
107
|
+
supportsStructuredOutput: false,
|
|
108
|
+
supportsToolUse: true,
|
|
109
|
+
supportsCacheControl: true,
|
|
110
|
+
maxContextTokens: 2e5,
|
|
111
|
+
maxOutputTokens: 8192
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
[
|
|
115
|
+
"anthropic/claude-3-5-haiku-latest",
|
|
116
|
+
{
|
|
117
|
+
supportsVision: false,
|
|
118
|
+
supportsStructuredOutput: false,
|
|
119
|
+
supportsToolUse: true,
|
|
120
|
+
supportsCacheControl: true,
|
|
121
|
+
maxContextTokens: 2e5,
|
|
122
|
+
maxOutputTokens: 8192
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
"anthropic/claude-3-haiku",
|
|
127
|
+
{
|
|
128
|
+
supportsVision: true,
|
|
129
|
+
supportsStructuredOutput: false,
|
|
130
|
+
supportsToolUse: true,
|
|
131
|
+
supportsCacheControl: true,
|
|
132
|
+
maxContextTokens: 2e5,
|
|
133
|
+
maxOutputTokens: 4096
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
[
|
|
137
|
+
"anthropic/claude-3-opus",
|
|
138
|
+
{
|
|
139
|
+
supportsVision: true,
|
|
140
|
+
supportsStructuredOutput: false,
|
|
141
|
+
supportsToolUse: true,
|
|
142
|
+
supportsCacheControl: true,
|
|
143
|
+
maxContextTokens: 2e5,
|
|
144
|
+
maxOutputTokens: 4096
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
]);
|
|
148
|
+
var ROUTING_PREFIXES = ["openrouter/", "vertex/", "bedrock/"];
|
|
149
|
+
function resolveModelCapabilities(modelId) {
|
|
150
|
+
const bare = stripVariantSuffix(stripRoutingPrefix(modelId));
|
|
151
|
+
const exact = EXACT.get(bare);
|
|
152
|
+
if (exact !== void 0) return exact;
|
|
153
|
+
const withVendor = inferVendorPrefix(bare);
|
|
154
|
+
if (withVendor !== bare) {
|
|
155
|
+
const vendored = EXACT.get(withVendor);
|
|
156
|
+
if (vendored !== void 0) return vendored;
|
|
157
|
+
}
|
|
158
|
+
return CONSERVATIVE_DEFAULTS;
|
|
159
|
+
}
|
|
160
|
+
function stripRoutingPrefix(modelId) {
|
|
161
|
+
for (const prefix of ROUTING_PREFIXES) {
|
|
162
|
+
if (modelId.startsWith(prefix)) return modelId.slice(prefix.length);
|
|
163
|
+
}
|
|
164
|
+
return modelId;
|
|
165
|
+
}
|
|
166
|
+
function stripVariantSuffix(modelId) {
|
|
167
|
+
const i = modelId.indexOf(":");
|
|
168
|
+
return i >= 0 ? modelId.slice(0, i) : modelId;
|
|
169
|
+
}
|
|
170
|
+
function inferVendorPrefix(bare) {
|
|
171
|
+
if (bare.startsWith("claude")) return `anthropic/${bare}`;
|
|
172
|
+
if (bare.startsWith("gpt-") || bare.startsWith("o1") || bare.startsWith("o3"))
|
|
173
|
+
return `openai/${bare}`;
|
|
174
|
+
if (bare.startsWith("gemini")) return `google/${bare}`;
|
|
175
|
+
return bare;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/internal/llm/model-identifier.ts
|
|
179
|
+
var PROVIDER_ALIASES = {
|
|
180
|
+
"llama-cpp": "llamacpp",
|
|
181
|
+
"llama.cpp": "llamacpp",
|
|
182
|
+
"lm-studio": "lmstudio",
|
|
183
|
+
lm_studio: "lmstudio"
|
|
184
|
+
};
|
|
185
|
+
function parseModelId(modelId) {
|
|
186
|
+
if (modelId === void 0 || modelId.length === 0) {
|
|
187
|
+
return { provider: void 0, name: "" };
|
|
188
|
+
}
|
|
189
|
+
const slash = modelId.indexOf("/");
|
|
190
|
+
if (slash <= 0 || slash === modelId.length - 1) {
|
|
191
|
+
return { provider: void 0, name: modelId };
|
|
192
|
+
}
|
|
193
|
+
const rawProvider = modelId.slice(0, slash).trim().toLowerCase();
|
|
194
|
+
const name = modelId.slice(slash + 1).trim();
|
|
195
|
+
if (rawProvider.length === 0 || name.length === 0) {
|
|
196
|
+
return { provider: void 0, name: modelId };
|
|
197
|
+
}
|
|
198
|
+
const canonical = PROVIDER_ALIASES[rawProvider] ?? rawProvider;
|
|
199
|
+
return { provider: canonical, name };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/internal/llm/model-option.ts
|
|
203
|
+
var ACRONYMS = /* @__PURE__ */ new Set(["gpt", "ai", "hd", "ui", "api", "sdk", "llm", "xl"]);
|
|
204
|
+
function prettyToken(token) {
|
|
205
|
+
if (ACRONYMS.has(token.toLowerCase())) return token.toUpperCase();
|
|
206
|
+
return token.charAt(0).toUpperCase() + token.slice(1);
|
|
207
|
+
}
|
|
208
|
+
function humanizeModelName(modelId) {
|
|
209
|
+
const { name } = parseModelId(modelId);
|
|
210
|
+
if (name.length === 0) return "";
|
|
211
|
+
const colon = name.indexOf(":");
|
|
212
|
+
const base = (colon >= 0 ? name.slice(0, colon) : name).replace(/\/+$/, "");
|
|
213
|
+
const variant = colon >= 0 ? name.slice(colon + 1) : "";
|
|
214
|
+
const lastSlash = base.lastIndexOf("/");
|
|
215
|
+
const core = lastSlash >= 0 ? base.slice(lastSlash + 1) : base;
|
|
216
|
+
const label = core.split(/[-_.\s]+/).filter((t) => t.length > 0).map(prettyToken).join(" ");
|
|
217
|
+
if (label.length === 0) return variant;
|
|
218
|
+
return variant.length > 0 ? `${label} (${variant})` : label;
|
|
219
|
+
}
|
|
220
|
+
function toModelOption(modelId) {
|
|
221
|
+
return {
|
|
222
|
+
value: modelId,
|
|
223
|
+
label: humanizeModelName(modelId),
|
|
224
|
+
provider: parseModelId(modelId).provider
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
exports.humanizeModelName = humanizeModelName;
|
|
229
|
+
exports.parseModelId = parseModelId;
|
|
230
|
+
exports.resolveModelCapabilities = resolveModelCapabilities;
|
|
231
|
+
exports.toModelOption = toModelOption;
|
|
232
|
+
//# sourceMappingURL=models.cjs.map
|
|
233
|
+
//# sourceMappingURL=models.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/llm/model-capabilities.ts","../src/internal/llm/model-identifier.ts","../src/internal/llm/model-option.ts"],"names":[],"mappings":"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","file":"models.cjs","sourcesContent":["/**\n * T3.10c — Model capability registry (DR3 #17).\n *\n * Typed per-model flags that let the SDK gate features at the boundary\n * (before hitting the provider) instead of letting opaque 400s surface.\n *\n * Resolution algorithm:\n * 1. Strip routing prefixes (openrouter/, vertex/, bedrock/) AND the\n * OpenRouter `:variant` suffix (:free/:nitro/…) to find the bare vendor id.\n * 2. Exact match in the `EXACT` catalog → return entry.\n * 3. Vendor inference (e.g., `claude-*` → `anthropic/claude-*`) → return entry.\n * 4. No match → conservative defaults (all false, minimum tokens).\n *\n * Module is internal, but `ModelCapabilities` + `resolveModelCapabilities` are\n * re-exported publicly via the `@theokit/sdk/models` subpath (see their @public tags).\n */\n\n/**\n * Per-model capability shape. Consumers use this to gate features at\n * the SDK boundary (before request construction, not after 400).\n *\n * @public\n */\nexport interface ModelCapabilities {\n supportsVision: boolean;\n supportsStructuredOutput: boolean;\n supportsToolUse: boolean;\n supportsCacheControl: boolean;\n maxContextTokens: number;\n maxOutputTokens: number;\n}\n\nconst CONSERVATIVE_DEFAULTS: ModelCapabilities = {\n supportsVision: false,\n supportsStructuredOutput: false,\n supportsToolUse: false,\n supportsCacheControl: false,\n maxContextTokens: 4096,\n maxOutputTokens: 4096,\n};\n\n/** Exact-match capability entries. Keys are `vendor/model` (no routing prefix). */\nconst EXACT: ReadonlyMap<string, ModelCapabilities> = new Map([\n // OpenAI family\n [\n \"openai/gpt-4o\",\n {\n supportsVision: true,\n supportsStructuredOutput: true,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 128_000,\n maxOutputTokens: 16_384,\n },\n ],\n [\n \"openai/gpt-4o-mini\",\n {\n supportsVision: true,\n supportsStructuredOutput: true,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 128_000,\n maxOutputTokens: 16_384,\n },\n ],\n [\n \"openai/gpt-4-turbo\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 128_000,\n maxOutputTokens: 4096,\n },\n ],\n [\n \"openai/o1\",\n {\n supportsVision: false,\n supportsStructuredOutput: true,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 200_000,\n maxOutputTokens: 100_000,\n },\n ],\n [\n \"openai/o3\",\n {\n supportsVision: false,\n supportsStructuredOutput: true,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 200_000,\n maxOutputTokens: 100_000,\n },\n ],\n // Anthropic family\n [\n \"anthropic/claude-opus-4\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 32_000,\n },\n ],\n [\n \"anthropic/claude-sonnet-4\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 16_000,\n },\n ],\n [\n \"anthropic/claude-3-5-sonnet\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 8192,\n },\n ],\n [\n \"anthropic/claude-3-5-sonnet-latest\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 8192,\n },\n ],\n [\n \"anthropic/claude-3-5-haiku-latest\",\n {\n supportsVision: false,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 8192,\n },\n ],\n [\n \"anthropic/claude-3-haiku\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 4096,\n },\n ],\n [\n \"anthropic/claude-3-opus\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 4096,\n },\n ],\n]);\n\n/** Routing prefixes to strip to find the underlying vendor model. */\nconst ROUTING_PREFIXES = [\"openrouter/\", \"vertex/\", \"bedrock/\"] as const;\n\n/**\n * Resolve per-model capability flags (vision/structured-output/tool-use/cache +\n * `maxContextTokens`/`maxOutputTokens`) for a model id. Pure, sync, offline (a\n * static catalog — no network). Strips routing prefixes (`openrouter/`/`vertex/`/\n * `bedrock/`) and OpenRouter `:variant` suffixes before lookup; unknown models get\n * conservative defaults. Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function resolveModelCapabilities(modelId: string): ModelCapabilities {\n const bare = stripVariantSuffix(stripRoutingPrefix(modelId));\n const exact = EXACT.get(bare);\n if (exact !== undefined) return exact;\n // Routing-prefixed models (vertex/claude-3-5-sonnet) strip to bare\n // model name without vendor. Try inferring the vendor from the name.\n const withVendor = inferVendorPrefix(bare);\n if (withVendor !== bare) {\n const vendored = EXACT.get(withVendor);\n if (vendored !== undefined) return vendored;\n }\n return CONSERVATIVE_DEFAULTS;\n}\n\nfunction stripRoutingPrefix(modelId: string): string {\n for (const prefix of ROUTING_PREFIXES) {\n if (modelId.startsWith(prefix)) return modelId.slice(prefix.length);\n }\n return modelId;\n}\n\n/**\n * Strip an OpenRouter variant suffix (`:free`/`:nitro`/`:floor`/`:beta`/…) so the\n * catalog lookup hits the underlying model. Model slugs contain no `:` except the\n * variant separator, so cutting at the first `:` is safe.\n */\nfunction stripVariantSuffix(modelId: string): string {\n const i = modelId.indexOf(\":\");\n return i >= 0 ? modelId.slice(0, i) : modelId;\n}\n\n/** Infer vendor prefix from bare model name for routing-prefixed lookups. */\nfunction inferVendorPrefix(bare: string): string {\n if (bare.startsWith(\"claude\")) return `anthropic/${bare}`;\n if (bare.startsWith(\"gpt-\") || bare.startsWith(\"o1\") || bare.startsWith(\"o3\"))\n return `openai/${bare}`;\n if (bare.startsWith(\"gemini\")) return `google/${bare}`;\n return bare;\n}\n","/**\n * Model identifier parsing (T1.2 follow-up, ADR D182 zero-config UX).\n *\n * SDK callers pass model strings like:\n * - `\"ollama/llama3.2:3b\"` → provider=\"ollama\", name=\"llama3.2:3b\"\n * - `\"anthropic/claude-3-5-sonnet\"` → provider=\"anthropic\", name=\"claude-3-5-sonnet\"\n * - `\"openrouter/meta-llama/llama-3\"` → provider=\"openrouter\", name=\"meta-llama/llama-3\"\n * - `\"claude-sonnet-4-6\"` → provider=undefined, name=\"claude-sonnet-4-6\"\n *\n * The first `/` separates the provider from the rest. Models with embedded\n * slashes (e.g. OpenRouter routing) keep the remainder intact. Tag suffixes\n * (`:latest`, `:3b`) are preserved as part of the name — Ollama expects them.\n *\n * **Returns `undefined` provider** when no `/` is present so callers can\n * fall back to env-var detection. Empty/whitespace components are treated\n * as no-prefix.\n *\n * Aligned with OpenClaw `extensions/ollama/src/discovery-shared.ts`\n * (`OLLAMA_PROVIDER_ID = \"ollama\"`) and Hermes `hermes_cli/providers.py`\n * (ALIASES table, `normalize_provider`).\n *\n * Public via `@theokit/sdk/models` (M5-8).\n *\n * @public\n */\n\nexport interface ParsedModelId {\n /** Provider name extracted from the prefix (lowercase), or undefined. */\n provider: string | undefined;\n /** Model name to send to the provider — prefix stripped. */\n name: string;\n}\n\n/** Provider aliases mirrored from Hermes `hermes_cli/providers.py` ALIASES. */\nconst PROVIDER_ALIASES: Readonly<Record<string, string>> = {\n \"llama-cpp\": \"llamacpp\",\n \"llama.cpp\": \"llamacpp\",\n \"lm-studio\": \"lmstudio\",\n lm_studio: \"lmstudio\",\n};\n\nexport function parseModelId(modelId: string | undefined): ParsedModelId {\n if (modelId === undefined || modelId.length === 0) {\n return { provider: undefined, name: \"\" };\n }\n const slash = modelId.indexOf(\"/\");\n if (slash <= 0 || slash === modelId.length - 1) {\n return { provider: undefined, name: modelId };\n }\n const rawProvider = modelId.slice(0, slash).trim().toLowerCase();\n const name = modelId.slice(slash + 1).trim();\n if (rawProvider.length === 0 || name.length === 0) {\n return { provider: undefined, name: modelId };\n }\n const canonical = PROVIDER_ALIASES[rawProvider] ?? rawProvider;\n return { provider: canonical, name };\n}\n","import { parseModelId } from \"./model-identifier.js\";\n\n/**\n * A UI-friendly model option — the shape a `<select>`/dropdown consumes.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport interface ModelOption {\n /** The original model id (what you pass back to the SDK). */\n value: string;\n /** Best-effort human label (see {@link humanizeModelName}). */\n label: string;\n /** Provider from the slug prefix, or `undefined` when none. */\n provider: string | undefined;\n}\n\n/** Tokens rendered upper-case rather than title-case. */\nconst ACRONYMS = new Set([\"gpt\", \"ai\", \"hd\", \"ui\", \"api\", \"sdk\", \"llm\", \"xl\"]);\n\nfunction prettyToken(token: string): string {\n if (ACRONYMS.has(token.toLowerCase())) return token.toUpperCase();\n return token.charAt(0).toUpperCase() + token.slice(1);\n}\n\n/**\n * Turn a model id into a best-effort human label: strip the routing/vendor\n * prefix to the core model segment, split on `-`/`_`/`.`/whitespace, title-case\n * each token (known acronyms upper-cased), and append an OpenRouter `:variant`\n * in parentheses. Deterministic, pure, dependency-free.\n *\n * Best-effort, NOT vendor-canonical: `\"anthropic/claude-3-5-sonnet\"` →\n * `\"Claude 3 5 Sonnet\"`. A UI wanting exact marketing names overrides per id.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function humanizeModelName(modelId: string): string {\n const { name } = parseModelId(modelId);\n if (name.length === 0) return \"\";\n const colon = name.indexOf(\":\");\n // Strip a trailing slash so a typo'd `gpt-4o/` keeps its name (not lost to an\n // empty last segment).\n const base = (colon >= 0 ? name.slice(0, colon) : name).replace(/\\/+$/, \"\");\n const variant = colon >= 0 ? name.slice(colon + 1) : \"\";\n const lastSlash = base.lastIndexOf(\"/\");\n const core = lastSlash >= 0 ? base.slice(lastSlash + 1) : base;\n const label = core\n .split(/[-_.\\s]+/)\n .filter((t) => t.length > 0)\n .map(prettyToken)\n .join(\" \");\n if (label.length === 0) return variant; // no base label (e.g. \":free\") → bare variant\n return variant.length > 0 ? `${label} (${variant})` : label;\n}\n\n/**\n * Build a {@link ModelOption} (`{ value, label, provider }`) for a model id —\n * a dropdown-ready entry composing {@link humanizeModelName} + `parseModelId`.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function toModelOption(modelId: string): ModelOption {\n return {\n value: modelId,\n label: humanizeModelName(modelId),\n provider: parseModelId(modelId).provider,\n };\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@theokit/sdk/models` — per-model capability catalog.
|
|
3
|
+
*
|
|
4
|
+
* `resolveModelCapabilities(modelId)` returns a model's capability flags +
|
|
5
|
+
* `maxContextTokens`/`maxOutputTokens` from a static, OFFLINE catalog (pure,
|
|
6
|
+
* sync, no network). It strips routing prefixes (`openrouter/`/`vertex/`/
|
|
7
|
+
* `bedrock/`) and OpenRouter `:variant` suffixes before lookup; unknown models
|
|
8
|
+
* get conservative defaults. The `maxContextTokens` value feeds the pre-call
|
|
9
|
+
* `shouldCompact` helper on `@theokit/sdk/compaction`.
|
|
10
|
+
*
|
|
11
|
+
* Also exposes model-id parsing + UI label helpers (M5-8): `parseModelId`,
|
|
12
|
+
* `humanizeModelName`, `toModelOption`.
|
|
13
|
+
*/
|
|
14
|
+
export { type ModelCapabilities, resolveModelCapabilities, } from "./internal/llm/model-capabilities.js";
|
|
15
|
+
export { type ParsedModelId, parseModelId } from "./internal/llm/model-identifier.js";
|
|
16
|
+
export { humanizeModelName, type ModelOption, toModelOption, } from "./internal/llm/model-option.js";
|
package/dist/models.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@theokit/sdk/models` — per-model capability catalog.
|
|
3
|
+
*
|
|
4
|
+
* `resolveModelCapabilities(modelId)` returns a model's capability flags +
|
|
5
|
+
* `maxContextTokens`/`maxOutputTokens` from a static, OFFLINE catalog (pure,
|
|
6
|
+
* sync, no network). It strips routing prefixes (`openrouter/`/`vertex/`/
|
|
7
|
+
* `bedrock/`) and OpenRouter `:variant` suffixes before lookup; unknown models
|
|
8
|
+
* get conservative defaults. The `maxContextTokens` value feeds the pre-call
|
|
9
|
+
* `shouldCompact` helper on `@theokit/sdk/compaction`.
|
|
10
|
+
*
|
|
11
|
+
* Also exposes model-id parsing + UI label helpers (M5-8): `parseModelId`,
|
|
12
|
+
* `humanizeModelName`, `toModelOption`.
|
|
13
|
+
*/
|
|
14
|
+
export { type ModelCapabilities, resolveModelCapabilities, } from "./internal/llm/model-capabilities.js";
|
|
15
|
+
export { type ParsedModelId, parseModelId } from "./internal/llm/model-identifier.js";
|
|
16
|
+
export { humanizeModelName, type ModelOption, toModelOption, } from "./internal/llm/model-option.js";
|
package/dist/models.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
// src/internal/llm/model-capabilities.ts
|
|
2
|
+
var CONSERVATIVE_DEFAULTS = {
|
|
3
|
+
supportsVision: false,
|
|
4
|
+
supportsStructuredOutput: false,
|
|
5
|
+
supportsToolUse: false,
|
|
6
|
+
supportsCacheControl: false,
|
|
7
|
+
maxContextTokens: 4096,
|
|
8
|
+
maxOutputTokens: 4096
|
|
9
|
+
};
|
|
10
|
+
var EXACT = /* @__PURE__ */ new Map([
|
|
11
|
+
// OpenAI family
|
|
12
|
+
[
|
|
13
|
+
"openai/gpt-4o",
|
|
14
|
+
{
|
|
15
|
+
supportsVision: true,
|
|
16
|
+
supportsStructuredOutput: true,
|
|
17
|
+
supportsToolUse: true,
|
|
18
|
+
supportsCacheControl: false,
|
|
19
|
+
maxContextTokens: 128e3,
|
|
20
|
+
maxOutputTokens: 16384
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
"openai/gpt-4o-mini",
|
|
25
|
+
{
|
|
26
|
+
supportsVision: true,
|
|
27
|
+
supportsStructuredOutput: true,
|
|
28
|
+
supportsToolUse: true,
|
|
29
|
+
supportsCacheControl: false,
|
|
30
|
+
maxContextTokens: 128e3,
|
|
31
|
+
maxOutputTokens: 16384
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
"openai/gpt-4-turbo",
|
|
36
|
+
{
|
|
37
|
+
supportsVision: true,
|
|
38
|
+
supportsStructuredOutput: false,
|
|
39
|
+
supportsToolUse: true,
|
|
40
|
+
supportsCacheControl: false,
|
|
41
|
+
maxContextTokens: 128e3,
|
|
42
|
+
maxOutputTokens: 4096
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
"openai/o1",
|
|
47
|
+
{
|
|
48
|
+
supportsVision: false,
|
|
49
|
+
supportsStructuredOutput: true,
|
|
50
|
+
supportsToolUse: true,
|
|
51
|
+
supportsCacheControl: false,
|
|
52
|
+
maxContextTokens: 2e5,
|
|
53
|
+
maxOutputTokens: 1e5
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
[
|
|
57
|
+
"openai/o3",
|
|
58
|
+
{
|
|
59
|
+
supportsVision: false,
|
|
60
|
+
supportsStructuredOutput: true,
|
|
61
|
+
supportsToolUse: true,
|
|
62
|
+
supportsCacheControl: false,
|
|
63
|
+
maxContextTokens: 2e5,
|
|
64
|
+
maxOutputTokens: 1e5
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
// Anthropic family
|
|
68
|
+
[
|
|
69
|
+
"anthropic/claude-opus-4",
|
|
70
|
+
{
|
|
71
|
+
supportsVision: true,
|
|
72
|
+
supportsStructuredOutput: false,
|
|
73
|
+
supportsToolUse: true,
|
|
74
|
+
supportsCacheControl: true,
|
|
75
|
+
maxContextTokens: 2e5,
|
|
76
|
+
maxOutputTokens: 32e3
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
"anthropic/claude-sonnet-4",
|
|
81
|
+
{
|
|
82
|
+
supportsVision: true,
|
|
83
|
+
supportsStructuredOutput: false,
|
|
84
|
+
supportsToolUse: true,
|
|
85
|
+
supportsCacheControl: true,
|
|
86
|
+
maxContextTokens: 2e5,
|
|
87
|
+
maxOutputTokens: 16e3
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
[
|
|
91
|
+
"anthropic/claude-3-5-sonnet",
|
|
92
|
+
{
|
|
93
|
+
supportsVision: true,
|
|
94
|
+
supportsStructuredOutput: false,
|
|
95
|
+
supportsToolUse: true,
|
|
96
|
+
supportsCacheControl: true,
|
|
97
|
+
maxContextTokens: 2e5,
|
|
98
|
+
maxOutputTokens: 8192
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
[
|
|
102
|
+
"anthropic/claude-3-5-sonnet-latest",
|
|
103
|
+
{
|
|
104
|
+
supportsVision: true,
|
|
105
|
+
supportsStructuredOutput: false,
|
|
106
|
+
supportsToolUse: true,
|
|
107
|
+
supportsCacheControl: true,
|
|
108
|
+
maxContextTokens: 2e5,
|
|
109
|
+
maxOutputTokens: 8192
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
[
|
|
113
|
+
"anthropic/claude-3-5-haiku-latest",
|
|
114
|
+
{
|
|
115
|
+
supportsVision: false,
|
|
116
|
+
supportsStructuredOutput: false,
|
|
117
|
+
supportsToolUse: true,
|
|
118
|
+
supportsCacheControl: true,
|
|
119
|
+
maxContextTokens: 2e5,
|
|
120
|
+
maxOutputTokens: 8192
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
[
|
|
124
|
+
"anthropic/claude-3-haiku",
|
|
125
|
+
{
|
|
126
|
+
supportsVision: true,
|
|
127
|
+
supportsStructuredOutput: false,
|
|
128
|
+
supportsToolUse: true,
|
|
129
|
+
supportsCacheControl: true,
|
|
130
|
+
maxContextTokens: 2e5,
|
|
131
|
+
maxOutputTokens: 4096
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
[
|
|
135
|
+
"anthropic/claude-3-opus",
|
|
136
|
+
{
|
|
137
|
+
supportsVision: true,
|
|
138
|
+
supportsStructuredOutput: false,
|
|
139
|
+
supportsToolUse: true,
|
|
140
|
+
supportsCacheControl: true,
|
|
141
|
+
maxContextTokens: 2e5,
|
|
142
|
+
maxOutputTokens: 4096
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
]);
|
|
146
|
+
var ROUTING_PREFIXES = ["openrouter/", "vertex/", "bedrock/"];
|
|
147
|
+
function resolveModelCapabilities(modelId) {
|
|
148
|
+
const bare = stripVariantSuffix(stripRoutingPrefix(modelId));
|
|
149
|
+
const exact = EXACT.get(bare);
|
|
150
|
+
if (exact !== void 0) return exact;
|
|
151
|
+
const withVendor = inferVendorPrefix(bare);
|
|
152
|
+
if (withVendor !== bare) {
|
|
153
|
+
const vendored = EXACT.get(withVendor);
|
|
154
|
+
if (vendored !== void 0) return vendored;
|
|
155
|
+
}
|
|
156
|
+
return CONSERVATIVE_DEFAULTS;
|
|
157
|
+
}
|
|
158
|
+
function stripRoutingPrefix(modelId) {
|
|
159
|
+
for (const prefix of ROUTING_PREFIXES) {
|
|
160
|
+
if (modelId.startsWith(prefix)) return modelId.slice(prefix.length);
|
|
161
|
+
}
|
|
162
|
+
return modelId;
|
|
163
|
+
}
|
|
164
|
+
function stripVariantSuffix(modelId) {
|
|
165
|
+
const i = modelId.indexOf(":");
|
|
166
|
+
return i >= 0 ? modelId.slice(0, i) : modelId;
|
|
167
|
+
}
|
|
168
|
+
function inferVendorPrefix(bare) {
|
|
169
|
+
if (bare.startsWith("claude")) return `anthropic/${bare}`;
|
|
170
|
+
if (bare.startsWith("gpt-") || bare.startsWith("o1") || bare.startsWith("o3"))
|
|
171
|
+
return `openai/${bare}`;
|
|
172
|
+
if (bare.startsWith("gemini")) return `google/${bare}`;
|
|
173
|
+
return bare;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/internal/llm/model-identifier.ts
|
|
177
|
+
var PROVIDER_ALIASES = {
|
|
178
|
+
"llama-cpp": "llamacpp",
|
|
179
|
+
"llama.cpp": "llamacpp",
|
|
180
|
+
"lm-studio": "lmstudio",
|
|
181
|
+
lm_studio: "lmstudio"
|
|
182
|
+
};
|
|
183
|
+
function parseModelId(modelId) {
|
|
184
|
+
if (modelId === void 0 || modelId.length === 0) {
|
|
185
|
+
return { provider: void 0, name: "" };
|
|
186
|
+
}
|
|
187
|
+
const slash = modelId.indexOf("/");
|
|
188
|
+
if (slash <= 0 || slash === modelId.length - 1) {
|
|
189
|
+
return { provider: void 0, name: modelId };
|
|
190
|
+
}
|
|
191
|
+
const rawProvider = modelId.slice(0, slash).trim().toLowerCase();
|
|
192
|
+
const name = modelId.slice(slash + 1).trim();
|
|
193
|
+
if (rawProvider.length === 0 || name.length === 0) {
|
|
194
|
+
return { provider: void 0, name: modelId };
|
|
195
|
+
}
|
|
196
|
+
const canonical = PROVIDER_ALIASES[rawProvider] ?? rawProvider;
|
|
197
|
+
return { provider: canonical, name };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/internal/llm/model-option.ts
|
|
201
|
+
var ACRONYMS = /* @__PURE__ */ new Set(["gpt", "ai", "hd", "ui", "api", "sdk", "llm", "xl"]);
|
|
202
|
+
function prettyToken(token) {
|
|
203
|
+
if (ACRONYMS.has(token.toLowerCase())) return token.toUpperCase();
|
|
204
|
+
return token.charAt(0).toUpperCase() + token.slice(1);
|
|
205
|
+
}
|
|
206
|
+
function humanizeModelName(modelId) {
|
|
207
|
+
const { name } = parseModelId(modelId);
|
|
208
|
+
if (name.length === 0) return "";
|
|
209
|
+
const colon = name.indexOf(":");
|
|
210
|
+
const base = (colon >= 0 ? name.slice(0, colon) : name).replace(/\/+$/, "");
|
|
211
|
+
const variant = colon >= 0 ? name.slice(colon + 1) : "";
|
|
212
|
+
const lastSlash = base.lastIndexOf("/");
|
|
213
|
+
const core = lastSlash >= 0 ? base.slice(lastSlash + 1) : base;
|
|
214
|
+
const label = core.split(/[-_.\s]+/).filter((t) => t.length > 0).map(prettyToken).join(" ");
|
|
215
|
+
if (label.length === 0) return variant;
|
|
216
|
+
return variant.length > 0 ? `${label} (${variant})` : label;
|
|
217
|
+
}
|
|
218
|
+
function toModelOption(modelId) {
|
|
219
|
+
return {
|
|
220
|
+
value: modelId,
|
|
221
|
+
label: humanizeModelName(modelId),
|
|
222
|
+
provider: parseModelId(modelId).provider
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export { humanizeModelName, parseModelId, resolveModelCapabilities, toModelOption };
|
|
227
|
+
//# sourceMappingURL=models.js.map
|
|
228
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/llm/model-capabilities.ts","../src/internal/llm/model-identifier.ts","../src/internal/llm/model-option.ts"],"names":[],"mappings":";AAgCA,IAAM,qBAAA,GAA2C;AAAA,EAC/C,cAAA,EAAgB,KAAA;AAAA,EAChB,wBAAA,EAA0B,KAAA;AAAA,EAC1B,eAAA,EAAiB,KAAA;AAAA,EACjB,oBAAA,EAAsB,KAAA;AAAA,EACtB,gBAAA,EAAkB,IAAA;AAAA,EAClB,eAAA,EAAiB;AACnB,CAAA;AAGA,IAAM,KAAA,uBAAoD,GAAA,CAAI;AAAA;AAAA,EAE5D;AAAA,IACE,eAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,IAAA;AAAA,MAChB,wBAAA,EAA0B,IAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,KAAA;AAAA,MACtB,gBAAA,EAAkB,KAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,oBAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,IAAA;AAAA,MAChB,wBAAA,EAA0B,IAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,KAAA;AAAA,MACtB,gBAAA,EAAkB,KAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,oBAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,IAAA;AAAA,MAChB,wBAAA,EAA0B,KAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,KAAA;AAAA,MACtB,gBAAA,EAAkB,KAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,WAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,KAAA;AAAA,MAChB,wBAAA,EAA0B,IAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,KAAA;AAAA,MACtB,gBAAA,EAAkB,GAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,WAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,KAAA;AAAA,MAChB,wBAAA,EAA0B,IAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,KAAA;AAAA,MACtB,gBAAA,EAAkB,GAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA;AAAA,EAEA;AAAA,IACE,yBAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,IAAA;AAAA,MAChB,wBAAA,EAA0B,KAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,IAAA;AAAA,MACtB,gBAAA,EAAkB,GAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,2BAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,IAAA;AAAA,MAChB,wBAAA,EAA0B,KAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,IAAA;AAAA,MACtB,gBAAA,EAAkB,GAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,6BAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,IAAA;AAAA,MAChB,wBAAA,EAA0B,KAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,IAAA;AAAA,MACtB,gBAAA,EAAkB,GAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,oCAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,IAAA;AAAA,MAChB,wBAAA,EAA0B,KAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,IAAA;AAAA,MACtB,gBAAA,EAAkB,GAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,mCAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,KAAA;AAAA,MAChB,wBAAA,EAA0B,KAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,IAAA;AAAA,MACtB,gBAAA,EAAkB,GAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,0BAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,IAAA;AAAA,MAChB,wBAAA,EAA0B,KAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,IAAA;AAAA,MACtB,gBAAA,EAAkB,GAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,yBAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAgB,IAAA;AAAA,MAChB,wBAAA,EAA0B,KAAA;AAAA,MAC1B,eAAA,EAAiB,IAAA;AAAA,MACjB,oBAAA,EAAsB,IAAA;AAAA,MACtB,gBAAA,EAAkB,GAAA;AAAA,MAClB,eAAA,EAAiB;AAAA;AACnB;AAEJ,CAAC,CAAA;AAGD,IAAM,gBAAA,GAAmB,CAAC,aAAA,EAAe,SAAA,EAAW,UAAU,CAAA;AAWvD,SAAS,yBAAyB,OAAA,EAAoC;AAC3E,EAAA,MAAM,IAAA,GAAO,kBAAA,CAAmB,kBAAA,CAAmB,OAAO,CAAC,CAAA;AAC3D,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA;AAC5B,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,KAAA;AAGhC,EAAA,MAAM,UAAA,GAAa,kBAAkB,IAAI,CAAA;AACzC,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,GAAA,CAAI,UAAU,CAAA;AACrC,IAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AAAA,EACrC;AACA,EAAA,OAAO,qBAAA;AACT;AAEA,SAAS,mBAAmB,OAAA,EAAyB;AACnD,EAAA,KAAA,MAAW,UAAU,gBAAA,EAAkB;AACrC,IAAA,IAAI,OAAA,CAAQ,WAAW,MAAM,CAAA,SAAU,OAAA,CAAQ,KAAA,CAAM,OAAO,MAAM,CAAA;AAAA,EACpE;AACA,EAAA,OAAO,OAAA;AACT;AAOA,SAAS,mBAAmB,OAAA,EAAyB;AACnD,EAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AAC7B,EAAA,OAAO,KAAK,CAAA,GAAI,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,GAAI,OAAA;AACxC;AAGA,SAAS,kBAAkB,IAAA,EAAsB;AAC/C,EAAA,IAAI,KAAK,UAAA,CAAW,QAAQ,CAAA,EAAG,OAAO,aAAa,IAAI,CAAA,CAAA;AACvD,EAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA,IAAK,IAAA,CAAK,WAAW,IAAI,CAAA,IAAK,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA;AAC1E,IAAA,OAAO,UAAU,IAAI,CAAA,CAAA;AACvB,EAAA,IAAI,KAAK,UAAA,CAAW,QAAQ,CAAA,EAAG,OAAO,UAAU,IAAI,CAAA,CAAA;AACpD,EAAA,OAAO,IAAA;AACT;;;ACnMA,IAAM,gBAAA,GAAqD;AAAA,EACzD,WAAA,EAAa,UAAA;AAAA,EACb,WAAA,EAAa,UAAA;AAAA,EACb,WAAA,EAAa,UAAA;AAAA,EACb,SAAA,EAAW;AACb,CAAA;AAEO,SAAS,aAAa,OAAA,EAA4C;AACvE,EAAA,IAAI,OAAA,KAAY,MAAA,IAAa,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AACjD,IAAA,OAAO,EAAE,QAAA,EAAU,MAAA,EAAW,IAAA,EAAM,EAAA,EAAG;AAAA,EACzC;AACA,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AACjC,EAAA,IAAI,KAAA,IAAS,CAAA,IAAK,KAAA,KAAU,OAAA,CAAQ,SAAS,CAAA,EAAG;AAC9C,IAAA,OAAO,EAAE,QAAA,EAAU,MAAA,EAAW,IAAA,EAAM,OAAA,EAAQ;AAAA,EAC9C;AACA,EAAA,MAAM,WAAA,GAAc,QAAQ,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY;AAC/D,EAAA,MAAM,OAAO,OAAA,CAAQ,KAAA,CAAM,KAAA,GAAQ,CAAC,EAAE,IAAA,EAAK;AAC3C,EAAA,IAAI,WAAA,CAAY,MAAA,KAAW,CAAA,IAAK,IAAA,CAAK,WAAW,CAAA,EAAG;AACjD,IAAA,OAAO,EAAE,QAAA,EAAU,MAAA,EAAW,IAAA,EAAM,OAAA,EAAQ;AAAA,EAC9C;AACA,EAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,WAAW,CAAA,IAAK,WAAA;AACnD,EAAA,OAAO,EAAE,QAAA,EAAU,SAAA,EAAW,IAAA,EAAK;AACrC;;;ACrCA,IAAM,QAAA,mBAAW,IAAI,GAAA,CAAI,CAAC,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,IAAI,CAAC,CAAA;AAE7E,SAAS,YAAY,KAAA,EAAuB;AAC1C,EAAA,IAAI,QAAA,CAAS,IAAI,KAAA,CAAM,WAAA,EAAa,CAAA,EAAG,OAAO,MAAM,WAAA,EAAY;AAChE,EAAA,OAAO,KAAA,CAAM,OAAO,CAAC,CAAA,CAAE,aAAY,GAAI,KAAA,CAAM,MAAM,CAAC,CAAA;AACtD;AAeO,SAAS,kBAAkB,OAAA,EAAyB;AACzD,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,YAAA,CAAa,OAAO,CAAA;AACrC,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,EAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAG9B,EAAA,MAAM,IAAA,GAAA,CAAQ,KAAA,IAAS,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA,GAAI,IAAA,EAAM,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC1E,EAAA,MAAM,UAAU,KAAA,IAAS,CAAA,GAAI,KAAK,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA,GAAI,EAAA;AACrD,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AACtC,EAAA,MAAM,OAAO,SAAA,IAAa,CAAA,GAAI,KAAK,KAAA,CAAM,SAAA,GAAY,CAAC,CAAA,GAAI,IAAA;AAC1D,EAAA,MAAM,QAAQ,IAAA,CACX,KAAA,CAAM,UAAU,CAAA,CAChB,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA,CAC1B,GAAA,CAAI,WAAW,CAAA,CACf,KAAK,GAAG,CAAA;AACX,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,OAAA;AAC/B,EAAA,OAAO,QAAQ,MAAA,GAAS,CAAA,GAAI,GAAG,KAAK,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,CAAA,GAAM,KAAA;AACxD;AAUO,SAAS,cAAc,OAAA,EAA8B;AAC1D,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,OAAA;AAAA,IACP,KAAA,EAAO,kBAAkB,OAAO,CAAA;AAAA,IAChC,QAAA,EAAU,YAAA,CAAa,OAAO,CAAA,CAAE;AAAA,GAClC;AACF","file":"models.js","sourcesContent":["/**\n * T3.10c — Model capability registry (DR3 #17).\n *\n * Typed per-model flags that let the SDK gate features at the boundary\n * (before hitting the provider) instead of letting opaque 400s surface.\n *\n * Resolution algorithm:\n * 1. Strip routing prefixes (openrouter/, vertex/, bedrock/) AND the\n * OpenRouter `:variant` suffix (:free/:nitro/…) to find the bare vendor id.\n * 2. Exact match in the `EXACT` catalog → return entry.\n * 3. Vendor inference (e.g., `claude-*` → `anthropic/claude-*`) → return entry.\n * 4. No match → conservative defaults (all false, minimum tokens).\n *\n * Module is internal, but `ModelCapabilities` + `resolveModelCapabilities` are\n * re-exported publicly via the `@theokit/sdk/models` subpath (see their @public tags).\n */\n\n/**\n * Per-model capability shape. Consumers use this to gate features at\n * the SDK boundary (before request construction, not after 400).\n *\n * @public\n */\nexport interface ModelCapabilities {\n supportsVision: boolean;\n supportsStructuredOutput: boolean;\n supportsToolUse: boolean;\n supportsCacheControl: boolean;\n maxContextTokens: number;\n maxOutputTokens: number;\n}\n\nconst CONSERVATIVE_DEFAULTS: ModelCapabilities = {\n supportsVision: false,\n supportsStructuredOutput: false,\n supportsToolUse: false,\n supportsCacheControl: false,\n maxContextTokens: 4096,\n maxOutputTokens: 4096,\n};\n\n/** Exact-match capability entries. Keys are `vendor/model` (no routing prefix). */\nconst EXACT: ReadonlyMap<string, ModelCapabilities> = new Map([\n // OpenAI family\n [\n \"openai/gpt-4o\",\n {\n supportsVision: true,\n supportsStructuredOutput: true,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 128_000,\n maxOutputTokens: 16_384,\n },\n ],\n [\n \"openai/gpt-4o-mini\",\n {\n supportsVision: true,\n supportsStructuredOutput: true,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 128_000,\n maxOutputTokens: 16_384,\n },\n ],\n [\n \"openai/gpt-4-turbo\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 128_000,\n maxOutputTokens: 4096,\n },\n ],\n [\n \"openai/o1\",\n {\n supportsVision: false,\n supportsStructuredOutput: true,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 200_000,\n maxOutputTokens: 100_000,\n },\n ],\n [\n \"openai/o3\",\n {\n supportsVision: false,\n supportsStructuredOutput: true,\n supportsToolUse: true,\n supportsCacheControl: false,\n maxContextTokens: 200_000,\n maxOutputTokens: 100_000,\n },\n ],\n // Anthropic family\n [\n \"anthropic/claude-opus-4\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 32_000,\n },\n ],\n [\n \"anthropic/claude-sonnet-4\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 16_000,\n },\n ],\n [\n \"anthropic/claude-3-5-sonnet\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 8192,\n },\n ],\n [\n \"anthropic/claude-3-5-sonnet-latest\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 8192,\n },\n ],\n [\n \"anthropic/claude-3-5-haiku-latest\",\n {\n supportsVision: false,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 8192,\n },\n ],\n [\n \"anthropic/claude-3-haiku\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 4096,\n },\n ],\n [\n \"anthropic/claude-3-opus\",\n {\n supportsVision: true,\n supportsStructuredOutput: false,\n supportsToolUse: true,\n supportsCacheControl: true,\n maxContextTokens: 200_000,\n maxOutputTokens: 4096,\n },\n ],\n]);\n\n/** Routing prefixes to strip to find the underlying vendor model. */\nconst ROUTING_PREFIXES = [\"openrouter/\", \"vertex/\", \"bedrock/\"] as const;\n\n/**\n * Resolve per-model capability flags (vision/structured-output/tool-use/cache +\n * `maxContextTokens`/`maxOutputTokens`) for a model id. Pure, sync, offline (a\n * static catalog — no network). Strips routing prefixes (`openrouter/`/`vertex/`/\n * `bedrock/`) and OpenRouter `:variant` suffixes before lookup; unknown models get\n * conservative defaults. Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function resolveModelCapabilities(modelId: string): ModelCapabilities {\n const bare = stripVariantSuffix(stripRoutingPrefix(modelId));\n const exact = EXACT.get(bare);\n if (exact !== undefined) return exact;\n // Routing-prefixed models (vertex/claude-3-5-sonnet) strip to bare\n // model name without vendor. Try inferring the vendor from the name.\n const withVendor = inferVendorPrefix(bare);\n if (withVendor !== bare) {\n const vendored = EXACT.get(withVendor);\n if (vendored !== undefined) return vendored;\n }\n return CONSERVATIVE_DEFAULTS;\n}\n\nfunction stripRoutingPrefix(modelId: string): string {\n for (const prefix of ROUTING_PREFIXES) {\n if (modelId.startsWith(prefix)) return modelId.slice(prefix.length);\n }\n return modelId;\n}\n\n/**\n * Strip an OpenRouter variant suffix (`:free`/`:nitro`/`:floor`/`:beta`/…) so the\n * catalog lookup hits the underlying model. Model slugs contain no `:` except the\n * variant separator, so cutting at the first `:` is safe.\n */\nfunction stripVariantSuffix(modelId: string): string {\n const i = modelId.indexOf(\":\");\n return i >= 0 ? modelId.slice(0, i) : modelId;\n}\n\n/** Infer vendor prefix from bare model name for routing-prefixed lookups. */\nfunction inferVendorPrefix(bare: string): string {\n if (bare.startsWith(\"claude\")) return `anthropic/${bare}`;\n if (bare.startsWith(\"gpt-\") || bare.startsWith(\"o1\") || bare.startsWith(\"o3\"))\n return `openai/${bare}`;\n if (bare.startsWith(\"gemini\")) return `google/${bare}`;\n return bare;\n}\n","/**\n * Model identifier parsing (T1.2 follow-up, ADR D182 zero-config UX).\n *\n * SDK callers pass model strings like:\n * - `\"ollama/llama3.2:3b\"` → provider=\"ollama\", name=\"llama3.2:3b\"\n * - `\"anthropic/claude-3-5-sonnet\"` → provider=\"anthropic\", name=\"claude-3-5-sonnet\"\n * - `\"openrouter/meta-llama/llama-3\"` → provider=\"openrouter\", name=\"meta-llama/llama-3\"\n * - `\"claude-sonnet-4-6\"` → provider=undefined, name=\"claude-sonnet-4-6\"\n *\n * The first `/` separates the provider from the rest. Models with embedded\n * slashes (e.g. OpenRouter routing) keep the remainder intact. Tag suffixes\n * (`:latest`, `:3b`) are preserved as part of the name — Ollama expects them.\n *\n * **Returns `undefined` provider** when no `/` is present so callers can\n * fall back to env-var detection. Empty/whitespace components are treated\n * as no-prefix.\n *\n * Aligned with OpenClaw `extensions/ollama/src/discovery-shared.ts`\n * (`OLLAMA_PROVIDER_ID = \"ollama\"`) and Hermes `hermes_cli/providers.py`\n * (ALIASES table, `normalize_provider`).\n *\n * Public via `@theokit/sdk/models` (M5-8).\n *\n * @public\n */\n\nexport interface ParsedModelId {\n /** Provider name extracted from the prefix (lowercase), or undefined. */\n provider: string | undefined;\n /** Model name to send to the provider — prefix stripped. */\n name: string;\n}\n\n/** Provider aliases mirrored from Hermes `hermes_cli/providers.py` ALIASES. */\nconst PROVIDER_ALIASES: Readonly<Record<string, string>> = {\n \"llama-cpp\": \"llamacpp\",\n \"llama.cpp\": \"llamacpp\",\n \"lm-studio\": \"lmstudio\",\n lm_studio: \"lmstudio\",\n};\n\nexport function parseModelId(modelId: string | undefined): ParsedModelId {\n if (modelId === undefined || modelId.length === 0) {\n return { provider: undefined, name: \"\" };\n }\n const slash = modelId.indexOf(\"/\");\n if (slash <= 0 || slash === modelId.length - 1) {\n return { provider: undefined, name: modelId };\n }\n const rawProvider = modelId.slice(0, slash).trim().toLowerCase();\n const name = modelId.slice(slash + 1).trim();\n if (rawProvider.length === 0 || name.length === 0) {\n return { provider: undefined, name: modelId };\n }\n const canonical = PROVIDER_ALIASES[rawProvider] ?? rawProvider;\n return { provider: canonical, name };\n}\n","import { parseModelId } from \"./model-identifier.js\";\n\n/**\n * A UI-friendly model option — the shape a `<select>`/dropdown consumes.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport interface ModelOption {\n /** The original model id (what you pass back to the SDK). */\n value: string;\n /** Best-effort human label (see {@link humanizeModelName}). */\n label: string;\n /** Provider from the slug prefix, or `undefined` when none. */\n provider: string | undefined;\n}\n\n/** Tokens rendered upper-case rather than title-case. */\nconst ACRONYMS = new Set([\"gpt\", \"ai\", \"hd\", \"ui\", \"api\", \"sdk\", \"llm\", \"xl\"]);\n\nfunction prettyToken(token: string): string {\n if (ACRONYMS.has(token.toLowerCase())) return token.toUpperCase();\n return token.charAt(0).toUpperCase() + token.slice(1);\n}\n\n/**\n * Turn a model id into a best-effort human label: strip the routing/vendor\n * prefix to the core model segment, split on `-`/`_`/`.`/whitespace, title-case\n * each token (known acronyms upper-cased), and append an OpenRouter `:variant`\n * in parentheses. Deterministic, pure, dependency-free.\n *\n * Best-effort, NOT vendor-canonical: `\"anthropic/claude-3-5-sonnet\"` →\n * `\"Claude 3 5 Sonnet\"`. A UI wanting exact marketing names overrides per id.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function humanizeModelName(modelId: string): string {\n const { name } = parseModelId(modelId);\n if (name.length === 0) return \"\";\n const colon = name.indexOf(\":\");\n // Strip a trailing slash so a typo'd `gpt-4o/` keeps its name (not lost to an\n // empty last segment).\n const base = (colon >= 0 ? name.slice(0, colon) : name).replace(/\\/+$/, \"\");\n const variant = colon >= 0 ? name.slice(colon + 1) : \"\";\n const lastSlash = base.lastIndexOf(\"/\");\n const core = lastSlash >= 0 ? base.slice(lastSlash + 1) : base;\n const label = core\n .split(/[-_.\\s]+/)\n .filter((t) => t.length > 0)\n .map(prettyToken)\n .join(\" \");\n if (label.length === 0) return variant; // no base label (e.g. \":free\") → bare variant\n return variant.length > 0 ? `${label} (${variant})` : label;\n}\n\n/**\n * Build a {@link ModelOption} (`{ value, label, provider }`) for a model id —\n * a dropdown-ready entry composing {@link humanizeModelName} + `parseModelId`.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function toModelOption(modelId: string): ModelOption {\n return {\n value: modelId,\n label: humanizeModelName(modelId),\n provider: parseModelId(modelId).provider,\n };\n}\n"]}
|