amalgm 0.0.0 → 0.0.32
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/README.md +41 -1
- package/bin/amalgm.js +8 -2
- package/lib/auth-store.js +223 -0
- package/lib/cli.js +1132 -0
- package/lib/paths.js +30 -0
- package/lib/supervisor.js +476 -0
- package/lib/tunnel-chat.js +328 -0
- package/lib/tunnel-events.js +499 -0
- package/package.json +30 -3
- package/runtime/README.md +4 -0
- package/runtime/lib/chatInput.js +315 -0
- package/runtime/lib/harnesses.js +988 -0
- package/runtime/lib/local/amalgmStore.js +136 -0
- package/runtime/lib/local/credentialResolver.js +425 -0
- package/runtime/lib/mcpApps/registry.js +619 -0
- package/runtime/package.json +5 -0
- package/runtime/scripts/amalgm-mcp/agents/rest.js +144 -0
- package/runtime/scripts/amalgm-mcp/agents/store.js +684 -0
- package/runtime/scripts/amalgm-mcp/agents/talk.js +1162 -0
- package/runtime/scripts/amalgm-mcp/agents/tools.js +221 -0
- package/runtime/scripts/amalgm-mcp/artifacts/advertise.js +132 -0
- package/runtime/scripts/amalgm-mcp/artifacts/rest.js +103 -0
- package/runtime/scripts/amalgm-mcp/artifacts/store.js +157 -0
- package/runtime/scripts/amalgm-mcp/artifacts/supervisor.js +402 -0
- package/runtime/scripts/amalgm-mcp/artifacts/tools.js +176 -0
- package/runtime/scripts/amalgm-mcp/browser/page.js +637 -0
- package/runtime/scripts/amalgm-mcp/browser/tools.js +688 -0
- package/runtime/scripts/amalgm-mcp/config.js +140 -0
- package/runtime/scripts/amalgm-mcp/credentials/rest.js +45 -0
- package/runtime/scripts/amalgm-mcp/deps.js +40 -0
- package/runtime/scripts/amalgm-mcp/email/inbound.js +215 -0
- package/runtime/scripts/amalgm-mcp/events/executor.js +179 -0
- package/runtime/scripts/amalgm-mcp/events/ingress.js +113 -0
- package/runtime/scripts/amalgm-mcp/events/matcher.js +125 -0
- package/runtime/scripts/amalgm-mcp/events/rest.js +200 -0
- package/runtime/scripts/amalgm-mcp/events/ring-buffer.js +19 -0
- package/runtime/scripts/amalgm-mcp/events/store.js +113 -0
- package/runtime/scripts/amalgm-mcp/events/tools.js +306 -0
- package/runtime/scripts/amalgm-mcp/events/webhook-url.js +28 -0
- package/runtime/scripts/amalgm-mcp/fs/rest.js +293 -0
- package/runtime/scripts/amalgm-mcp/index.js +100 -0
- package/runtime/scripts/amalgm-mcp/lib/chat-runner.js +167 -0
- package/runtime/scripts/amalgm-mcp/lib/email-md.js +288 -0
- package/runtime/scripts/amalgm-mcp/lib/mcp-resolver.js +63 -0
- package/runtime/scripts/amalgm-mcp/lib/prefs.js +441 -0
- package/runtime/scripts/amalgm-mcp/lib/storage.js +92 -0
- package/runtime/scripts/amalgm-mcp/lib/supabase.js +118 -0
- package/runtime/scripts/amalgm-mcp/lib/tool-result.js +177 -0
- package/runtime/scripts/amalgm-mcp/local/rest.js +87 -0
- package/runtime/scripts/amalgm-mcp/mcp-connections/rest.js +234 -0
- package/runtime/scripts/amalgm-mcp/notify/index.js +107 -0
- package/runtime/scripts/amalgm-mcp/server/core-tools.js +20 -0
- package/runtime/scripts/amalgm-mcp/server/http.js +377 -0
- package/runtime/scripts/amalgm-mcp/server/mcp.js +127 -0
- package/runtime/scripts/amalgm-mcp/slack/inbound.js +200 -0
- package/runtime/scripts/amalgm-mcp/state/db.js +194 -0
- package/runtime/scripts/amalgm-mcp/state/events.js +113 -0
- package/runtime/scripts/amalgm-mcp/state/rest.js +64 -0
- package/runtime/scripts/amalgm-mcp/state/snapshot.js +76 -0
- package/runtime/scripts/amalgm-mcp/tasks/executor.js +225 -0
- package/runtime/scripts/amalgm-mcp/tasks/rest.js +110 -0
- package/runtime/scripts/amalgm-mcp/tasks/schedule-normalization.js +85 -0
- package/runtime/scripts/amalgm-mcp/tasks/scheduler.js +105 -0
- package/runtime/scripts/amalgm-mcp/tasks/store.js +154 -0
- package/runtime/scripts/amalgm-mcp/tasks/tools.js +391 -0
- package/runtime/scripts/amalgm-mcp/toolbox/rest.js +75 -0
- package/runtime/scripts/amalgm-mcp/toolbox/runner.js +257 -0
- package/runtime/scripts/amalgm-mcp/toolbox/store.js +933 -0
- package/runtime/scripts/amalgm-mcp/toolbox/tools.js +269 -0
- package/runtime/scripts/amalgm-mcp/user-api-keys/rest.js +105 -0
- package/runtime/scripts/amalgm-mcp/workspace/rest.js +497 -0
- package/runtime/scripts/chat-core/adapters/claude.js +165 -0
- package/runtime/scripts/chat-core/adapters/codex.js +313 -0
- package/runtime/scripts/chat-core/adapters/opencode.js +412 -0
- package/runtime/scripts/chat-core/auth.js +177 -0
- package/runtime/scripts/chat-core/contract.js +328 -0
- package/runtime/scripts/chat-core/credentials/store.js +212 -0
- package/runtime/scripts/chat-core/egress.js +87 -0
- package/runtime/scripts/chat-core/engine.js +253 -0
- package/runtime/scripts/chat-core/event-schema.js +231 -0
- package/runtime/scripts/chat-core/events.js +190 -0
- package/runtime/scripts/chat-core/index.js +11 -0
- package/runtime/scripts/chat-core/input.js +50 -0
- package/runtime/scripts/chat-core/normalizers/claude.js +450 -0
- package/runtime/scripts/chat-core/normalizers/codex.js +380 -0
- package/runtime/scripts/chat-core/normalizers/normalizer_spec.md +259 -0
- package/runtime/scripts/chat-core/normalizers/opencode.js +552 -0
- package/runtime/scripts/chat-core/normalizers/tool_contract.md +123 -0
- package/runtime/scripts/chat-core/normalizers/usage_contract.md +304 -0
- package/runtime/scripts/chat-core/parts.js +253 -0
- package/runtime/scripts/chat-core/recorder.js +65 -0
- package/runtime/scripts/chat-core/runtime.js +86 -0
- package/runtime/scripts/chat-core/server.js +163 -0
- package/runtime/scripts/chat-core/sse.js +196 -0
- package/runtime/scripts/chat-core/stores.js +100 -0
- package/runtime/scripts/chat-core/tool-display.js +149 -0
- package/runtime/scripts/chat-core/tool-shape.js +143 -0
- package/runtime/scripts/chat-core/tooling/mcp-bundle.js +161 -0
- package/runtime/scripts/chat-core/tooling/mcp-relay.js +97 -0
- package/runtime/scripts/chat-core/tooling/native-binaries.js +608 -0
- package/runtime/scripts/chat-core/tooling/system-prompt.js +20 -0
- package/runtime/scripts/chat-core/usage.js +343 -0
- package/runtime/scripts/chat-server/config.js +110 -0
- package/runtime/scripts/chat-server/db.js +529 -0
- package/runtime/scripts/chat-server/index.js +33 -0
- package/runtime/scripts/chat-server/model-catalog.js +327 -0
- package/runtime/scripts/chat-server.js +75 -0
- package/runtime/scripts/credential-adapter.js +131 -0
- package/runtime/scripts/fs-watcher.js +888 -0
- package/runtime/scripts/local-gateway.js +854 -0
- package/runtime/scripts/platform-context.txt +246 -0
- package/runtime/scripts/port-monitor.js +175 -0
- package/runtime/scripts/proxy-token-store.js +162 -0
- package/runtime/scripts/runtime-auth.js +163 -0
- package/runtime/scripts/test-claude-code-models.js +87 -0
- package/runtime/tsconfig.json +15 -0
|
@@ -0,0 +1,988 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// lib/harnesses.ts
|
|
21
|
+
var harnesses_exports = {};
|
|
22
|
+
__export(harnesses_exports, {
|
|
23
|
+
AUTH_METHODS: () => AUTH_METHODS,
|
|
24
|
+
DISABLED_HARNESS_IDS: () => DISABLED_HARNESS_IDS,
|
|
25
|
+
HARNESSES: () => HARNESSES,
|
|
26
|
+
HARNESS_IDS: () => HARNESS_IDS,
|
|
27
|
+
VISIBLE_HARNESS_IDS: () => VISIBLE_HARNESS_IDS,
|
|
28
|
+
clearDynamicModels: () => clearDynamicModels,
|
|
29
|
+
coerceAuthMethodForHarness: () => coerceAuthMethodForHarness,
|
|
30
|
+
getAuthMethodsForHarness: () => getAuthMethodsForHarness,
|
|
31
|
+
getDefaultAuthMethodForHarness: () => getDefaultAuthMethodForHarness,
|
|
32
|
+
getDefaultModel: () => getDefaultModel,
|
|
33
|
+
getEnvKeyNameForHarness: () => getEnvKeyNameForHarness,
|
|
34
|
+
getHarnessForModel: () => getHarnessForModel,
|
|
35
|
+
getHarnessModels: () => getHarnessModels,
|
|
36
|
+
getLoginCommandForHarness: () => getLoginCommandForHarness,
|
|
37
|
+
getModelById: () => getModelById,
|
|
38
|
+
getModelDisplayName: () => getModelDisplayName,
|
|
39
|
+
isAuthMethod: () => isAuthMethod,
|
|
40
|
+
isAuthMethodSupportedForHarness: () => isAuthMethodSupportedForHarness,
|
|
41
|
+
isHarnessId: () => isHarnessId,
|
|
42
|
+
registerDynamicModels: () => registerDynamicModels,
|
|
43
|
+
resolveHarnessModel: () => resolveHarnessModel,
|
|
44
|
+
resolvePreferredHarnessModel: () => resolvePreferredHarnessModel
|
|
45
|
+
});
|
|
46
|
+
module.exports = __toCommonJS(harnesses_exports);
|
|
47
|
+
|
|
48
|
+
// lib/opencodeGateway.ts
|
|
49
|
+
function buildGatewayCliModel(gatewayId, harness) {
|
|
50
|
+
if (harness === "opencode") {
|
|
51
|
+
return `vercel/${gatewayId}`;
|
|
52
|
+
}
|
|
53
|
+
return gatewayId;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// lib/modelNaming.ts
|
|
57
|
+
var DEFAULT_MODEL_IDS = {
|
|
58
|
+
claude_code: "anthropic/claude-opus-4.7",
|
|
59
|
+
codex: "openai/gpt-5.4-thinking-xhigh",
|
|
60
|
+
opencode: "opencode-anthropic-claude-sonnet-4-6",
|
|
61
|
+
pi: "pi-anthropic-claude-sonnet-4.6",
|
|
62
|
+
amp: "amp-default",
|
|
63
|
+
cursor: "cursor/composer-2-fast"
|
|
64
|
+
};
|
|
65
|
+
var CLAUDE_OPUS_4_7_1M_MODEL_ID = "anthropic/claude-opus-4.7-1m";
|
|
66
|
+
var CLAUDE_LEGACY_ALIASES = {
|
|
67
|
+
"claude-code-opus": "anthropic/claude-opus-4.7",
|
|
68
|
+
"claude-code-opus-47": "anthropic/claude-opus-4.7",
|
|
69
|
+
"claude-code-opus-46": "anthropic/claude-opus-4.7",
|
|
70
|
+
"claude-code-opus-45": "anthropic/claude-opus-4.7",
|
|
71
|
+
"claude-code-opus-4.7": "anthropic/claude-opus-4.7",
|
|
72
|
+
"claude-code-opus-4-7": "anthropic/claude-opus-4.7",
|
|
73
|
+
"claude-code-opus-4.6": "anthropic/claude-opus-4.7",
|
|
74
|
+
"claude-code-opus-4-6": "anthropic/claude-opus-4.7",
|
|
75
|
+
"claude-code-opus-4.5": "anthropic/claude-opus-4.7",
|
|
76
|
+
"claude-code-opus-4-5": "anthropic/claude-opus-4.7",
|
|
77
|
+
"claude-code-opus1m": CLAUDE_OPUS_4_7_1M_MODEL_ID,
|
|
78
|
+
"claude-code-opus-1m": CLAUDE_OPUS_4_7_1M_MODEL_ID,
|
|
79
|
+
"claude-code-opus-4.7-1m": CLAUDE_OPUS_4_7_1M_MODEL_ID,
|
|
80
|
+
"claude-code-opus-4-7-1m": CLAUDE_OPUS_4_7_1M_MODEL_ID,
|
|
81
|
+
"claude-code-sonnet": "anthropic/claude-sonnet-4.6",
|
|
82
|
+
"claude-code-sonnet-45": "anthropic/claude-sonnet-4.6",
|
|
83
|
+
"claude-code-sonnet-4.6": "anthropic/claude-sonnet-4.6",
|
|
84
|
+
"claude-code-sonnet-4-6": "anthropic/claude-sonnet-4.6",
|
|
85
|
+
"claude-code-sonnet-4.5": "anthropic/claude-sonnet-4.6",
|
|
86
|
+
"claude-code-sonnet-4-5": "anthropic/claude-sonnet-4.6",
|
|
87
|
+
"claude-code-haiku": "anthropic/claude-haiku-4.5",
|
|
88
|
+
"claude-code-haiku-4.5": "anthropic/claude-haiku-4.5",
|
|
89
|
+
"claude-code-haiku-4-5": "anthropic/claude-haiku-4.5",
|
|
90
|
+
"anthropic/claude-opus-4.6": "anthropic/claude-opus-4.7",
|
|
91
|
+
"anthropic/claude-opus-4.5": "anthropic/claude-opus-4.7",
|
|
92
|
+
"anthropic/claude-sonnet-4.5": "anthropic/claude-sonnet-4.6",
|
|
93
|
+
"claude-opus-4.7-1m": CLAUDE_OPUS_4_7_1M_MODEL_ID,
|
|
94
|
+
"claude-opus-4-7-1m": CLAUDE_OPUS_4_7_1M_MODEL_ID,
|
|
95
|
+
opus: "anthropic/claude-opus-4.7",
|
|
96
|
+
opus1m: CLAUDE_OPUS_4_7_1M_MODEL_ID,
|
|
97
|
+
"opus[1m]": CLAUDE_OPUS_4_7_1M_MODEL_ID,
|
|
98
|
+
sonnet: "anthropic/claude-sonnet-4.6",
|
|
99
|
+
"sonnet[1m]": "anthropic/claude-sonnet-4.6",
|
|
100
|
+
haiku: "anthropic/claude-haiku-4.5"
|
|
101
|
+
};
|
|
102
|
+
var CLAUDE_HARNESS_MODELS = {
|
|
103
|
+
"anthropic/claude-opus-4.7": "opus",
|
|
104
|
+
[CLAUDE_OPUS_4_7_1M_MODEL_ID]: "opus[1m]",
|
|
105
|
+
"anthropic/claude-opus-4.6": "opus",
|
|
106
|
+
"anthropic/claude-opus-4.5": "opus",
|
|
107
|
+
"anthropic/claude-sonnet-4.6": "sonnet",
|
|
108
|
+
"anthropic/claude-sonnet-4.5": "sonnet",
|
|
109
|
+
"anthropic/claude-haiku-4.5": "haiku"
|
|
110
|
+
};
|
|
111
|
+
var INTERNAL_TO_GATEWAY_MODEL_IDS = {
|
|
112
|
+
[CLAUDE_OPUS_4_7_1M_MODEL_ID]: "anthropic/claude-opus-4.7"
|
|
113
|
+
};
|
|
114
|
+
var CURSOR_MODEL_ALIASES = {
|
|
115
|
+
"cursor-opus-4.6-thinking": "anthropic/claude-opus-4.6-high-thinking",
|
|
116
|
+
"cursor-opus-4.6": "anthropic/claude-opus-4.6-high",
|
|
117
|
+
"cursor-opus-4.5-thinking": "anthropic/claude-opus-4.5-high-thinking",
|
|
118
|
+
"cursor-opus-4.5": "anthropic/claude-opus-4.5-high",
|
|
119
|
+
"cursor-sonnet-4.5-thinking": "anthropic/claude-sonnet-4.5-thinking",
|
|
120
|
+
"cursor-sonnet-4.5": "anthropic/claude-sonnet-4.5",
|
|
121
|
+
"cursor-gemini-3-pro": "google/gemini-3-pro",
|
|
122
|
+
"cursor-grok": "xai/grok",
|
|
123
|
+
"cursor-gpt-5.4": "openai/gpt-5.4-medium",
|
|
124
|
+
"cursor-anthropic/claude-opus-4.7": "anthropic/claude-opus-4.7-xhigh",
|
|
125
|
+
"cursor-anthropic/claude-opus-4.6": "anthropic/claude-opus-4.6-high",
|
|
126
|
+
"cursor-anthropic/claude-opus-4.5": "anthropic/claude-opus-4.5-high",
|
|
127
|
+
"cursor-anthropic/claude-sonnet-4.6": "anthropic/claude-sonnet-4.6-medium",
|
|
128
|
+
"cursor-anthropic/claude-sonnet-4.5": "anthropic/claude-sonnet-4.5",
|
|
129
|
+
"cursor-anthropic/claude-sonnet-4": "anthropic/claude-sonnet-4",
|
|
130
|
+
"cursor-openai/gpt-5.5": "openai/gpt-5.5-medium",
|
|
131
|
+
"cursor-openai/gpt-5.4": "openai/gpt-5.4-medium",
|
|
132
|
+
"cursor-openai/gpt-5.4-mini": "openai/gpt-5.4-mini-medium",
|
|
133
|
+
"cursor-openai/gpt-5.4-nano": "openai/gpt-5.4-nano-medium",
|
|
134
|
+
"cursor-openai/gpt-5.3-codex": "openai/gpt-5.3-codex",
|
|
135
|
+
"cursor-openai/gpt-5.2": "openai/gpt-5.2",
|
|
136
|
+
"cursor-google/gemini-3.1-pro-preview": "google/gemini-3.1-pro",
|
|
137
|
+
"cursor-google/gemini-3.1-pro": "google/gemini-3.1-pro",
|
|
138
|
+
"cursor-google/gemini-3-flash": "google/gemini-3-flash",
|
|
139
|
+
"cursor-xai/grok-4.20": "xai/grok-4.20",
|
|
140
|
+
"cursor-moonshotai/kimi-k2.5": "moonshotai/kimi-k2.5"
|
|
141
|
+
};
|
|
142
|
+
var CODEX_THINKING_SUFFIX_RE = /:thinking-(low|medium|high|xhigh)$/i;
|
|
143
|
+
var CODEX_LEGACY_THINKING_SUFFIX_RE = /-thinking-(low|medium|high|xhigh)$/i;
|
|
144
|
+
function cleanModelId(value) {
|
|
145
|
+
return value.trim().replace(/^vercel\//i, "").toLowerCase();
|
|
146
|
+
}
|
|
147
|
+
function normalizeClaudeModelPart(modelPart) {
|
|
148
|
+
const hasOneMillionContext = /(?:\[\s*1m\s*\]|:1m|-1m)$/i.test(modelPart);
|
|
149
|
+
const base = modelPart.replace(/\[\s*1m\s*\]$/i, "").replace(/:1m$/i, "").replace(/-1m$/i, "").replace(/-\d{8}$/, "").replace(/-(\d+)-(\d+)(?=$|[-:])/, "-$1.$2");
|
|
150
|
+
const currentBase = {
|
|
151
|
+
"claude-opus-4.6": "claude-opus-4.7",
|
|
152
|
+
"claude-opus-4.5": "claude-opus-4.7",
|
|
153
|
+
"claude-sonnet-4.5": "claude-sonnet-4.6"
|
|
154
|
+
}[base] ?? base;
|
|
155
|
+
return hasOneMillionContext && currentBase === "claude-opus-4.7" ? `${currentBase}-1m` : currentBase;
|
|
156
|
+
}
|
|
157
|
+
function normalizeClaudeModelId(value) {
|
|
158
|
+
const cleaned = cleanModelId(value);
|
|
159
|
+
if (CLAUDE_LEGACY_ALIASES[cleaned]) return CLAUDE_LEGACY_ALIASES[cleaned];
|
|
160
|
+
if (cleaned.startsWith("anthropic/")) {
|
|
161
|
+
return `anthropic/${normalizeClaudeModelPart(cleaned.slice("anthropic/".length))}`;
|
|
162
|
+
}
|
|
163
|
+
if (cleaned.startsWith("claude-")) {
|
|
164
|
+
return `anthropic/${normalizeClaudeModelPart(cleaned)}`;
|
|
165
|
+
}
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
168
|
+
function codexLegacyBaseToCanonical(value) {
|
|
169
|
+
const cleaned = cleanModelId(value);
|
|
170
|
+
if (cleaned.startsWith("openai/")) return cleaned;
|
|
171
|
+
if (cleaned.startsWith("codex-")) return `openai/${cleaned.slice("codex-".length)}`;
|
|
172
|
+
if (/^(gpt-|gpt\d|o-|o\d)/i.test(cleaned)) return `openai/${cleaned}`;
|
|
173
|
+
return value;
|
|
174
|
+
}
|
|
175
|
+
function codexThinkingVariantId(baseModelId, effort) {
|
|
176
|
+
return `${codexLegacyBaseToCanonical(baseModelId)}-thinking-${effort.toLowerCase()}`;
|
|
177
|
+
}
|
|
178
|
+
function codexGatewayModelId(modelId) {
|
|
179
|
+
return modelId.replace(CODEX_THINKING_SUFFIX_RE, "").replace(CODEX_LEGACY_THINKING_SUFFIX_RE, "");
|
|
180
|
+
}
|
|
181
|
+
function codexHarnessModelId(modelId, effort) {
|
|
182
|
+
const baseModel = codexGatewayModelId(modelId).replace(/^openai\//, "");
|
|
183
|
+
if (effort && /^gpt-5\.[45](?:-mini)?$/i.test(baseModel)) {
|
|
184
|
+
return `${baseModel}/${effort}`;
|
|
185
|
+
}
|
|
186
|
+
return baseModel;
|
|
187
|
+
}
|
|
188
|
+
function normalizeCodexModelSelection(value) {
|
|
189
|
+
const cleaned = cleanModelId(value);
|
|
190
|
+
const legacyThinkingMatch = cleaned.match(
|
|
191
|
+
/^(codex-[a-z0-9.-]+(?:-[a-z0-9.-]+)*)-thinking-(low|medium|high|xhigh)$/i
|
|
192
|
+
);
|
|
193
|
+
if (legacyThinkingMatch) {
|
|
194
|
+
const effort = legacyThinkingMatch[2].toLowerCase();
|
|
195
|
+
return {
|
|
196
|
+
modelId: codexThinkingVariantId(legacyThinkingMatch[1], effort),
|
|
197
|
+
reasoningEffort: effort
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const canonicalThinkingMatch = cleaned.match(
|
|
201
|
+
/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)(?::thinking-|-thinking-)(low|medium|high|xhigh)$/i
|
|
202
|
+
);
|
|
203
|
+
if (canonicalThinkingMatch) {
|
|
204
|
+
const effort = canonicalThinkingMatch[2].toLowerCase();
|
|
205
|
+
return {
|
|
206
|
+
modelId: codexThinkingVariantId(canonicalThinkingMatch[1], effort),
|
|
207
|
+
reasoningEffort: effort
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
const slashThinkingMatch = cleaned.match(
|
|
211
|
+
/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)\/(low|medium|high|xhigh)$/i
|
|
212
|
+
);
|
|
213
|
+
if (slashThinkingMatch) {
|
|
214
|
+
const effort = slashThinkingMatch[2].toLowerCase();
|
|
215
|
+
return {
|
|
216
|
+
modelId: codexThinkingVariantId(slashThinkingMatch[1], effort),
|
|
217
|
+
reasoningEffort: effort
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
return { modelId: codexLegacyBaseToCanonical(cleaned) };
|
|
221
|
+
}
|
|
222
|
+
function cursorCliModelToCanonicalModelId(value) {
|
|
223
|
+
const cleaned = cleanModelId(value);
|
|
224
|
+
const cliModel = cleaned.startsWith("cursor-") ? cleaned.slice("cursor-".length) : cleaned;
|
|
225
|
+
const prefixed = `cursor-${cliModel}`;
|
|
226
|
+
if (CURSOR_MODEL_ALIASES[prefixed]) return CURSOR_MODEL_ALIASES[prefixed];
|
|
227
|
+
if (cliModel.startsWith("cursor/")) return cliModel;
|
|
228
|
+
if (["auto", "composer-2-fast", "composer-2", "composer-1.5", "composer-1"].includes(cliModel)) {
|
|
229
|
+
return `cursor/${cliModel}`;
|
|
230
|
+
}
|
|
231
|
+
if (/^(gpt-|gpt\d|o-|o\d)/i.test(cliModel)) {
|
|
232
|
+
return `openai/${cliModel}`;
|
|
233
|
+
}
|
|
234
|
+
if (cliModel.startsWith("gemini-")) {
|
|
235
|
+
return `google/${cliModel}`;
|
|
236
|
+
}
|
|
237
|
+
if (cliModel === "kimi-k2.5") {
|
|
238
|
+
return "moonshotai/kimi-k2.5";
|
|
239
|
+
}
|
|
240
|
+
if (cliModel === "grok") {
|
|
241
|
+
return "xai/grok";
|
|
242
|
+
}
|
|
243
|
+
if (cliModel.startsWith("grok-4-20")) {
|
|
244
|
+
return `xai/${cliModel.replace(/^grok-4-20/, "grok-4.20")}`;
|
|
245
|
+
}
|
|
246
|
+
const opus47Match = cliModel.match(/^claude-opus-4-7(?:-(.+))?$/);
|
|
247
|
+
if (opus47Match) {
|
|
248
|
+
return `anthropic/claude-opus-4.7${opus47Match[1] ? `-${opus47Match[1]}` : ""}`;
|
|
249
|
+
}
|
|
250
|
+
const claudeMatch = cliModel.match(/^claude-(4(?:\.\d+)?)-(opus|sonnet)(?:-(.+))?$/);
|
|
251
|
+
if (claudeMatch) {
|
|
252
|
+
const [, version, family, suffix] = claudeMatch;
|
|
253
|
+
return `anthropic/claude-${family}-${version}${suffix ? `-${suffix}` : ""}`;
|
|
254
|
+
}
|
|
255
|
+
if (cliModel.startsWith("claude-")) {
|
|
256
|
+
return `anthropic/${cliModel.replace(/-(\d+)-(\d+)(?=$|-)/, "-$1.$2")}`;
|
|
257
|
+
}
|
|
258
|
+
return `cursor/${cliModel}`;
|
|
259
|
+
}
|
|
260
|
+
function cursorCliModelToModelId(cliModel) {
|
|
261
|
+
return cursorCliModelToCanonicalModelId(cliModel);
|
|
262
|
+
}
|
|
263
|
+
function normalizeCursorModelId(value) {
|
|
264
|
+
const cleaned = cleanModelId(value);
|
|
265
|
+
if (CURSOR_MODEL_ALIASES[cleaned]) return CURSOR_MODEL_ALIASES[cleaned];
|
|
266
|
+
if (cleaned.includes("/") && !cleaned.startsWith("cursor-")) return cleaned;
|
|
267
|
+
return cursorCliModelToCanonicalModelId(cleaned);
|
|
268
|
+
}
|
|
269
|
+
function cursorCanonicalModelIdToCliModel(value) {
|
|
270
|
+
const canonical = normalizeCursorModelId(value);
|
|
271
|
+
if (canonical.startsWith("cursor/")) return canonical.slice("cursor/".length);
|
|
272
|
+
if (canonical.startsWith("cursor-")) return canonical.slice("cursor-".length);
|
|
273
|
+
if (canonical.startsWith("openai/")) return canonical.slice("openai/".length);
|
|
274
|
+
if (canonical.startsWith("google/")) return canonical.slice("google/".length);
|
|
275
|
+
if (canonical.startsWith("moonshotai/")) return canonical.slice("moonshotai/".length);
|
|
276
|
+
if (canonical.startsWith("xai/")) {
|
|
277
|
+
return canonical.slice("xai/".length).replace(/^grok-4\.20/, "grok-4-20");
|
|
278
|
+
}
|
|
279
|
+
if (canonical.startsWith("anthropic/")) {
|
|
280
|
+
const model = canonical.slice("anthropic/".length);
|
|
281
|
+
const opus47Match = model.match(/^claude-opus-4\.7(?:-(.+))?$/);
|
|
282
|
+
if (opus47Match) return `claude-opus-4-7${opus47Match[1] ? `-${opus47Match[1]}` : ""}`;
|
|
283
|
+
const claudeMatch = model.match(/^claude-(opus|sonnet)-(4(?:\.\d+)?)(?:-(.+))?$/);
|
|
284
|
+
if (claudeMatch) {
|
|
285
|
+
const [, family, version, suffix] = claudeMatch;
|
|
286
|
+
return `claude-${version}-${family}${suffix ? `-${suffix}` : ""}`;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return canonical;
|
|
290
|
+
}
|
|
291
|
+
function cursorGatewayModelId(modelId) {
|
|
292
|
+
const canonical = normalizeCursorModelId(modelId);
|
|
293
|
+
if (canonical.startsWith("cursor/")) return canonical;
|
|
294
|
+
if (canonical.startsWith("openai/")) {
|
|
295
|
+
const model = canonical.slice("openai/".length);
|
|
296
|
+
if (model.startsWith("gpt-5.5")) return "openai/gpt-5.5";
|
|
297
|
+
if (model.startsWith("gpt-5.4-mini")) return "openai/gpt-5.4-mini";
|
|
298
|
+
if (model.startsWith("gpt-5.4-nano")) return "openai/gpt-5.4-nano";
|
|
299
|
+
if (model.startsWith("gpt-5.4")) return "openai/gpt-5.4";
|
|
300
|
+
if (model.startsWith("gpt-5.3-codex-spark-preview")) return "openai/gpt-5.3-codex-spark";
|
|
301
|
+
if (model.startsWith("gpt-5.3-codex")) return "openai/gpt-5.3-codex";
|
|
302
|
+
if (model.startsWith("gpt-5.2-codex")) return "openai/gpt-5.2-codex";
|
|
303
|
+
if (model.startsWith("gpt-5.2")) return "openai/gpt-5.2";
|
|
304
|
+
if (model.startsWith("gpt-5.1-codex-max")) return "openai/gpt-5.1-codex-max";
|
|
305
|
+
if (model.startsWith("gpt-5.1-codex-mini")) return "openai/gpt-5.1-codex-mini";
|
|
306
|
+
if (model.startsWith("gpt-5.1")) return "openai/gpt-5.1";
|
|
307
|
+
return canonical;
|
|
308
|
+
}
|
|
309
|
+
if (canonical.startsWith("anthropic/")) {
|
|
310
|
+
const model = canonical.slice("anthropic/".length);
|
|
311
|
+
if (model.startsWith("claude-opus-4.7")) return "anthropic/claude-opus-4.7";
|
|
312
|
+
if (model.startsWith("claude-opus-4.6")) return "anthropic/claude-opus-4.6";
|
|
313
|
+
if (model.startsWith("claude-opus-4.5")) return "anthropic/claude-opus-4.5";
|
|
314
|
+
if (model.startsWith("claude-sonnet-4.6")) return "anthropic/claude-sonnet-4.6";
|
|
315
|
+
if (model.startsWith("claude-sonnet-4.5")) return "anthropic/claude-sonnet-4.5";
|
|
316
|
+
if (model.startsWith("claude-sonnet-4")) return "anthropic/claude-sonnet-4";
|
|
317
|
+
return canonical;
|
|
318
|
+
}
|
|
319
|
+
if (canonical === "google/gemini-3.1-pro") return "google/gemini-3.1-pro";
|
|
320
|
+
if (canonical === "google/gemini-3-pro") return "google/gemini-3-pro";
|
|
321
|
+
if (canonical.startsWith("xai/grok-4.20")) return "xai/grok-4.20";
|
|
322
|
+
return canonical;
|
|
323
|
+
}
|
|
324
|
+
function normalizeModelSelection(modelId, harnessId) {
|
|
325
|
+
if (!modelId) return null;
|
|
326
|
+
const cleaned = cleanModelId(modelId);
|
|
327
|
+
if (harnessId === "claude_code") {
|
|
328
|
+
return { modelId: normalizeClaudeModelId(cleaned) };
|
|
329
|
+
}
|
|
330
|
+
if (harnessId === "codex") {
|
|
331
|
+
return normalizeCodexModelSelection(cleaned);
|
|
332
|
+
}
|
|
333
|
+
if (harnessId === "cursor") {
|
|
334
|
+
return { modelId: normalizeCursorModelId(cleaned) };
|
|
335
|
+
}
|
|
336
|
+
if (cleaned.startsWith("claude-code-") || cleaned.startsWith("claude-") || cleaned.startsWith("anthropic/claude-") || cleaned === "opus" || cleaned === "opus1m" || cleaned === "opus[1m]" || cleaned === "sonnet" || cleaned === "sonnet[1m]" || cleaned === "haiku") {
|
|
337
|
+
return { modelId: normalizeClaudeModelId(cleaned) };
|
|
338
|
+
}
|
|
339
|
+
if (cleaned.startsWith("codex-") || cleaned.startsWith("openai/") || /^(gpt-|gpt\d|o-|o\d)/i.test(cleaned)) {
|
|
340
|
+
return normalizeCodexModelSelection(cleaned);
|
|
341
|
+
}
|
|
342
|
+
return { modelId };
|
|
343
|
+
}
|
|
344
|
+
function normalizeModelId(modelId, harnessId) {
|
|
345
|
+
return normalizeModelSelection(modelId, harnessId)?.modelId ?? null;
|
|
346
|
+
}
|
|
347
|
+
function modelIdToHarnessModel(modelId, harnessId) {
|
|
348
|
+
const canonical = normalizeModelId(modelId, harnessId);
|
|
349
|
+
if (!canonical) return null;
|
|
350
|
+
if (harnessId === "claude_code") {
|
|
351
|
+
return CLAUDE_HARNESS_MODELS[canonical] ?? canonical.replace(/^anthropic\//, "").replace(/-(\d+)\.(\d+)(?=$|-)/, "-$1-$2");
|
|
352
|
+
}
|
|
353
|
+
if (harnessId === "codex") {
|
|
354
|
+
const selection = normalizeModelSelection(modelId, harnessId);
|
|
355
|
+
return codexHarnessModelId(canonical, selection?.reasoningEffort);
|
|
356
|
+
}
|
|
357
|
+
if (harnessId === "cursor") {
|
|
358
|
+
return cursorCanonicalModelIdToCliModel(canonical);
|
|
359
|
+
}
|
|
360
|
+
if (harnessId === "amp") {
|
|
361
|
+
return canonical;
|
|
362
|
+
}
|
|
363
|
+
return modelId ?? null;
|
|
364
|
+
}
|
|
365
|
+
function modelIdToGatewayModelId(modelId, harnessId) {
|
|
366
|
+
const canonical = normalizeModelId(modelId, harnessId);
|
|
367
|
+
if (!canonical) return null;
|
|
368
|
+
if (harnessId === "codex" || CODEX_THINKING_SUFFIX_RE.test(canonical) || CODEX_LEGACY_THINKING_SUFFIX_RE.test(canonical)) {
|
|
369
|
+
return codexGatewayModelId(canonical);
|
|
370
|
+
}
|
|
371
|
+
if (harnessId === "cursor") {
|
|
372
|
+
return cursorGatewayModelId(canonical);
|
|
373
|
+
}
|
|
374
|
+
return INTERNAL_TO_GATEWAY_MODEL_IDS[canonical] ?? canonical;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// lib/harnesses.ts
|
|
378
|
+
var AUTH_METHODS = {
|
|
379
|
+
amalgm: { id: "amalgm", name: "amalgm", subtitle: "Use our API Key" },
|
|
380
|
+
byok: { id: "byok", name: "BYOK", subtitle: "Use your own API key" },
|
|
381
|
+
provider_auth: {
|
|
382
|
+
id: "provider_auth",
|
|
383
|
+
name: "Existing subscription",
|
|
384
|
+
subtitle: "Log in via terminal"
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
var CLAUDE_MODELS = [
|
|
388
|
+
{
|
|
389
|
+
id: "anthropic/claude-haiku-4.5",
|
|
390
|
+
name: "Haiku 4.5",
|
|
391
|
+
description: "Fast Claude Code model",
|
|
392
|
+
gatewayModelId: "anthropic/claude-haiku-4.5",
|
|
393
|
+
cliModel: modelIdToHarnessModel("anthropic/claude-haiku-4.5", "claude_code"),
|
|
394
|
+
provider: "claude",
|
|
395
|
+
providerGroup: "anthropic"
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
id: "anthropic/claude-sonnet-4.6",
|
|
399
|
+
name: "Sonnet 4.6",
|
|
400
|
+
description: "Balanced Claude Code model",
|
|
401
|
+
gatewayModelId: "anthropic/claude-sonnet-4.6",
|
|
402
|
+
cliModel: modelIdToHarnessModel("anthropic/claude-sonnet-4.6", "claude_code"),
|
|
403
|
+
provider: "claude",
|
|
404
|
+
providerGroup: "anthropic"
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
id: "anthropic/claude-opus-4.7",
|
|
408
|
+
name: "Opus 4.7",
|
|
409
|
+
description: "Most capable Claude Code model",
|
|
410
|
+
gatewayModelId: "anthropic/claude-opus-4.7",
|
|
411
|
+
cliModel: modelIdToHarnessModel("anthropic/claude-opus-4.7", "claude_code"),
|
|
412
|
+
provider: "claude",
|
|
413
|
+
providerGroup: "anthropic"
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
id: "anthropic/claude-opus-4.7-1m",
|
|
417
|
+
name: "Opus 4.7 1M",
|
|
418
|
+
description: "Claude Code Opus with 1M context",
|
|
419
|
+
gatewayModelId: "anthropic/claude-opus-4.7",
|
|
420
|
+
cliModel: modelIdToHarnessModel("anthropic/claude-opus-4.7-1m", "claude_code"),
|
|
421
|
+
provider: "claude",
|
|
422
|
+
providerGroup: "anthropic"
|
|
423
|
+
}
|
|
424
|
+
];
|
|
425
|
+
var OPENCODE_MODELS = [
|
|
426
|
+
// ── Anthropic ──
|
|
427
|
+
{
|
|
428
|
+
id: "opencode-anthropic-claude-opus-4-6",
|
|
429
|
+
name: "Claude Opus 4.6",
|
|
430
|
+
description: "Most capable Anthropic model",
|
|
431
|
+
cliModel: buildGatewayCliModel("anthropic/claude-opus-4.6", "opencode"),
|
|
432
|
+
provider: "opencode",
|
|
433
|
+
providerGroup: "anthropic"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
id: "opencode-anthropic-claude-sonnet-4-6",
|
|
437
|
+
name: "Claude Sonnet 4.6",
|
|
438
|
+
description: "Balanced Anthropic model",
|
|
439
|
+
cliModel: buildGatewayCliModel("anthropic/claude-sonnet-4.6", "opencode"),
|
|
440
|
+
provider: "opencode",
|
|
441
|
+
providerGroup: "anthropic"
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
id: "opencode-anthropic-claude-haiku-4-5",
|
|
445
|
+
name: "Claude Haiku 4.5",
|
|
446
|
+
description: "Fast Anthropic model",
|
|
447
|
+
cliModel: buildGatewayCliModel("anthropic/claude-haiku-4.5", "opencode"),
|
|
448
|
+
provider: "opencode",
|
|
449
|
+
providerGroup: "anthropic"
|
|
450
|
+
},
|
|
451
|
+
// ── OpenAI ──
|
|
452
|
+
{
|
|
453
|
+
id: "opencode-openai-gpt-5.4",
|
|
454
|
+
name: "GPT-5.4",
|
|
455
|
+
description: "Flagship OpenAI model",
|
|
456
|
+
cliModel: buildGatewayCliModel("openai/gpt-5.4", "opencode"),
|
|
457
|
+
provider: "opencode",
|
|
458
|
+
providerGroup: "openai"
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
id: "opencode-openai-gpt-5.3-codex",
|
|
462
|
+
name: "GPT-5.3 Codex",
|
|
463
|
+
description: "OpenAI coding model",
|
|
464
|
+
cliModel: buildGatewayCliModel("openai/gpt-5.3-codex", "opencode"),
|
|
465
|
+
provider: "opencode",
|
|
466
|
+
providerGroup: "openai"
|
|
467
|
+
},
|
|
468
|
+
// ── Google ──
|
|
469
|
+
{
|
|
470
|
+
id: "opencode-google-gemini-3.1-pro-preview",
|
|
471
|
+
name: "Gemini 3.1 Pro",
|
|
472
|
+
description: "Latest Google flagship",
|
|
473
|
+
cliModel: buildGatewayCliModel("google/gemini-3.1-pro-preview", "opencode"),
|
|
474
|
+
provider: "opencode",
|
|
475
|
+
providerGroup: "google"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
id: "opencode-google-gemini-3-flash",
|
|
479
|
+
name: "Gemini 3 Flash",
|
|
480
|
+
description: "Fast Google model",
|
|
481
|
+
cliModel: buildGatewayCliModel("google/gemini-3-flash", "opencode"),
|
|
482
|
+
provider: "opencode",
|
|
483
|
+
providerGroup: "google"
|
|
484
|
+
},
|
|
485
|
+
// ── xAI ──
|
|
486
|
+
{
|
|
487
|
+
id: "opencode-xai-grok-4",
|
|
488
|
+
name: "Grok 4",
|
|
489
|
+
description: "xAI flagship model",
|
|
490
|
+
cliModel: buildGatewayCliModel("xai/grok-4", "opencode"),
|
|
491
|
+
provider: "opencode",
|
|
492
|
+
providerGroup: "xai"
|
|
493
|
+
},
|
|
494
|
+
// ── DeepSeek ──
|
|
495
|
+
{
|
|
496
|
+
id: "opencode-deepseek-deepseek-v3.2",
|
|
497
|
+
name: "DeepSeek V3.2",
|
|
498
|
+
description: "Latest DeepSeek model",
|
|
499
|
+
cliModel: buildGatewayCliModel("deepseek/deepseek-v3.2", "opencode"),
|
|
500
|
+
provider: "opencode",
|
|
501
|
+
providerGroup: "deepseek"
|
|
502
|
+
},
|
|
503
|
+
// ── Mistral ──
|
|
504
|
+
{
|
|
505
|
+
id: "opencode-mistral-devstral-2",
|
|
506
|
+
name: "Devstral 2",
|
|
507
|
+
description: "Mistral coding model",
|
|
508
|
+
cliModel: buildGatewayCliModel("mistral/devstral-2", "opencode"),
|
|
509
|
+
provider: "opencode",
|
|
510
|
+
providerGroup: "mistral"
|
|
511
|
+
}
|
|
512
|
+
];
|
|
513
|
+
var PI_MODELS = [
|
|
514
|
+
{
|
|
515
|
+
id: "pi-anthropic-claude-sonnet-4.6",
|
|
516
|
+
name: "Claude Sonnet 4.6",
|
|
517
|
+
description: "Anthropic via AI Gateway",
|
|
518
|
+
cliModel: "anthropic/claude-sonnet-4.6",
|
|
519
|
+
provider: "pi",
|
|
520
|
+
providerGroup: "anthropic"
|
|
521
|
+
}
|
|
522
|
+
];
|
|
523
|
+
var AMP_MODELS = [
|
|
524
|
+
{
|
|
525
|
+
id: DEFAULT_MODEL_IDS.amp,
|
|
526
|
+
name: "Amp Default",
|
|
527
|
+
description: "Amp's managed default model",
|
|
528
|
+
cliModel: "amp-default",
|
|
529
|
+
provider: "amp",
|
|
530
|
+
providerGroup: "amp"
|
|
531
|
+
}
|
|
532
|
+
];
|
|
533
|
+
var CURSOR_MODEL_ROWS = [
|
|
534
|
+
["auto", "Auto", "cursor"],
|
|
535
|
+
["composer-2-fast", "Composer 2 Fast", "cursor"],
|
|
536
|
+
["composer-2", "Composer 2", "cursor"],
|
|
537
|
+
["composer-1.5", "Composer 1.5", "cursor"],
|
|
538
|
+
["gpt-5.3-codex-low", "Codex 5.3 Low", "openai"],
|
|
539
|
+
["gpt-5.3-codex-low-fast", "Codex 5.3 Low Fast", "openai"],
|
|
540
|
+
["gpt-5.3-codex", "Codex 5.3", "openai"],
|
|
541
|
+
["gpt-5.3-codex-fast", "Codex 5.3 Fast", "openai"],
|
|
542
|
+
["gpt-5.3-codex-high", "Codex 5.3 High", "openai"],
|
|
543
|
+
["gpt-5.3-codex-high-fast", "Codex 5.3 High Fast", "openai"],
|
|
544
|
+
["gpt-5.3-codex-xhigh", "Codex 5.3 Extra High", "openai"],
|
|
545
|
+
["gpt-5.3-codex-xhigh-fast", "Codex 5.3 Extra High Fast", "openai"],
|
|
546
|
+
["gpt-5.2", "GPT-5.2", "openai"],
|
|
547
|
+
["gpt-5.3-codex-spark-preview-low", "Codex 5.3 Spark Low", "openai"],
|
|
548
|
+
["gpt-5.3-codex-spark-preview", "Codex 5.3 Spark", "openai"],
|
|
549
|
+
["gpt-5.3-codex-spark-preview-high", "Codex 5.3 Spark High", "openai"],
|
|
550
|
+
["gpt-5.3-codex-spark-preview-xhigh", "Codex 5.3 Spark Extra High", "openai"],
|
|
551
|
+
["gpt-5.2-codex-low", "Codex 5.2 Low", "openai"],
|
|
552
|
+
["gpt-5.2-codex-low-fast", "Codex 5.2 Low Fast", "openai"],
|
|
553
|
+
["gpt-5.2-codex", "Codex 5.2", "openai"],
|
|
554
|
+
["gpt-5.2-codex-fast", "Codex 5.2 Fast", "openai"],
|
|
555
|
+
["gpt-5.2-codex-high", "Codex 5.2 High", "openai"],
|
|
556
|
+
["gpt-5.2-codex-high-fast", "Codex 5.2 High Fast", "openai"],
|
|
557
|
+
["gpt-5.2-codex-xhigh", "Codex 5.2 Extra High", "openai"],
|
|
558
|
+
["gpt-5.2-codex-xhigh-fast", "Codex 5.2 Extra High Fast", "openai"],
|
|
559
|
+
["gpt-5.1-codex-max-low", "Codex 5.1 Max Low", "openai"],
|
|
560
|
+
["gpt-5.1-codex-max-low-fast", "Codex 5.1 Max Low Fast", "openai"],
|
|
561
|
+
["gpt-5.1-codex-max-medium", "Codex 5.1 Max", "openai"],
|
|
562
|
+
["gpt-5.1-codex-max-medium-fast", "Codex 5.1 Max Medium Fast", "openai"],
|
|
563
|
+
["gpt-5.1-codex-max-high", "Codex 5.1 Max High", "openai"],
|
|
564
|
+
["gpt-5.1-codex-max-high-fast", "Codex 5.1 Max High Fast", "openai"],
|
|
565
|
+
["gpt-5.1-codex-max-xhigh", "Codex 5.1 Max Extra High", "openai"],
|
|
566
|
+
["gpt-5.1-codex-max-xhigh-fast", "Codex 5.1 Max Extra High Fast", "openai"],
|
|
567
|
+
["gpt-5.5-medium", "GPT-5.5 1M", "openai"],
|
|
568
|
+
["claude-opus-4-7-thinking-high", "Opus 4.7 1M High Thinking", "anthropic"],
|
|
569
|
+
["gpt-5.4-high", "GPT-5.4 1M High", "openai"],
|
|
570
|
+
["gpt-5.4-high-fast", "GPT-5.4 High Fast", "openai"],
|
|
571
|
+
["claude-4.6-opus-high-thinking-fast", "Opus 4.6 1M Thinking Fast", "anthropic"],
|
|
572
|
+
["gpt-5.5-high", "GPT-5.5 1M High", "openai"],
|
|
573
|
+
["gpt-5.5-extra-high", "GPT-5.5 1M Extra High", "openai"],
|
|
574
|
+
["claude-4.6-sonnet-medium", "Sonnet 4.6 1M", "anthropic"],
|
|
575
|
+
["claude-4.6-sonnet-medium-thinking", "Sonnet 4.6 1M Thinking", "anthropic"],
|
|
576
|
+
["claude-opus-4-7-low", "Opus 4.7 1M Low", "anthropic"],
|
|
577
|
+
["claude-opus-4-7-medium", "Opus 4.7 1M Medium", "anthropic"],
|
|
578
|
+
["claude-opus-4-7-high", "Opus 4.7 1M High", "anthropic"],
|
|
579
|
+
["claude-opus-4-7-xhigh", "Opus 4.7 1M", "anthropic"],
|
|
580
|
+
["claude-opus-4-7-max", "Opus 4.7 1M Max", "anthropic"],
|
|
581
|
+
["claude-opus-4-7-thinking-low", "Opus 4.7 1M Low Thinking", "anthropic"],
|
|
582
|
+
["claude-opus-4-7-thinking-medium", "Opus 4.7 1M Medium Thinking", "anthropic"],
|
|
583
|
+
["claude-opus-4-7-thinking-xhigh", "Opus 4.7 1M Thinking", "anthropic"],
|
|
584
|
+
["claude-opus-4-7-thinking-max", "Opus 4.7 1M Max Thinking", "anthropic"],
|
|
585
|
+
["gpt-5.4-low", "GPT-5.4 1M Low", "openai"],
|
|
586
|
+
["gpt-5.4-medium", "GPT-5.4 1M", "openai"],
|
|
587
|
+
["gpt-5.4-medium-fast", "GPT-5.4 Fast", "openai"],
|
|
588
|
+
["gpt-5.4-xhigh", "GPT-5.4 1M Extra High", "openai"],
|
|
589
|
+
["gpt-5.4-xhigh-fast", "GPT-5.4 Extra High Fast", "openai"],
|
|
590
|
+
["claude-4.6-opus-high", "Opus 4.6 1M", "anthropic"],
|
|
591
|
+
["claude-4.6-opus-max", "Opus 4.6 1M Max", "anthropic"],
|
|
592
|
+
["claude-4.6-opus-high-thinking", "Opus 4.6 1M Thinking", "anthropic"],
|
|
593
|
+
["claude-4.6-opus-max-thinking", "Opus 4.6 1M Max Thinking", "anthropic"],
|
|
594
|
+
["claude-4.6-opus-max-thinking-fast", "Opus 4.6 1M Max Thinking Fast", "anthropic"],
|
|
595
|
+
["claude-4.5-opus-high", "Opus 4.5", "anthropic"],
|
|
596
|
+
["claude-4.5-opus-high-thinking", "Opus 4.5 Thinking", "anthropic"],
|
|
597
|
+
["gpt-5.2-low", "GPT-5.2 Low", "openai"],
|
|
598
|
+
["gpt-5.2-low-fast", "GPT-5.2 Low Fast", "openai"],
|
|
599
|
+
["gpt-5.2-fast", "GPT-5.2 Fast", "openai"],
|
|
600
|
+
["gpt-5.2-high", "GPT-5.2 High", "openai"],
|
|
601
|
+
["gpt-5.2-high-fast", "GPT-5.2 High Fast", "openai"],
|
|
602
|
+
["gpt-5.2-xhigh", "GPT-5.2 Extra High", "openai"],
|
|
603
|
+
["gpt-5.2-xhigh-fast", "GPT-5.2 Extra High Fast", "openai"],
|
|
604
|
+
["gemini-3.1-pro", "Gemini 3.1 Pro", "google"],
|
|
605
|
+
["gpt-5.4-mini-none", "GPT-5.4 Mini None", "openai"],
|
|
606
|
+
["gpt-5.4-mini-low", "GPT-5.4 Mini Low", "openai"],
|
|
607
|
+
["gpt-5.4-mini-medium", "GPT-5.4 Mini", "openai"],
|
|
608
|
+
["gpt-5.4-mini-high", "GPT-5.4 Mini High", "openai"],
|
|
609
|
+
["gpt-5.4-mini-xhigh", "GPT-5.4 Mini Extra High", "openai"],
|
|
610
|
+
["gpt-5.4-nano-none", "GPT-5.4 Nano None", "openai"],
|
|
611
|
+
["gpt-5.4-nano-low", "GPT-5.4 Nano Low", "openai"],
|
|
612
|
+
["gpt-5.4-nano-medium", "GPT-5.4 Nano", "openai"],
|
|
613
|
+
["gpt-5.4-nano-high", "GPT-5.4 Nano High", "openai"],
|
|
614
|
+
["gpt-5.4-nano-xhigh", "GPT-5.4 Nano Extra High", "openai"],
|
|
615
|
+
["grok-4-20", "Grok 4.20", "xai"],
|
|
616
|
+
["grok-4-20-thinking", "Grok 4.20 Thinking", "xai"],
|
|
617
|
+
["claude-4.5-sonnet", "Sonnet 4.5", "anthropic"],
|
|
618
|
+
["claude-4.5-sonnet-thinking", "Sonnet 4.5 Thinking", "anthropic"],
|
|
619
|
+
["gpt-5.1-low", "GPT-5.1 Low", "openai"],
|
|
620
|
+
["gpt-5.1", "GPT-5.1", "openai"],
|
|
621
|
+
["gpt-5.1-high", "GPT-5.1 High", "openai"],
|
|
622
|
+
["gemini-3-flash", "Gemini 3 Flash", "google"],
|
|
623
|
+
["gpt-5.1-codex-mini-low", "Codex 5.1 Mini Low", "openai"],
|
|
624
|
+
["gpt-5.1-codex-mini", "Codex 5.1 Mini", "openai"],
|
|
625
|
+
["gpt-5.1-codex-mini-high", "Codex 5.1 Mini High", "openai"],
|
|
626
|
+
["claude-4-sonnet", "Sonnet 4", "anthropic"],
|
|
627
|
+
["claude-4-sonnet-thinking", "Sonnet 4 Thinking", "anthropic"],
|
|
628
|
+
["gpt-5-mini", "GPT-5 Mini", "openai"],
|
|
629
|
+
["kimi-k2.5", "Kimi K2.5", "moonshotai"]
|
|
630
|
+
];
|
|
631
|
+
function cursorModelDescription(providerGroup) {
|
|
632
|
+
switch (providerGroup) {
|
|
633
|
+
case "cursor":
|
|
634
|
+
return "Cursor-managed model";
|
|
635
|
+
case "anthropic":
|
|
636
|
+
return "Anthropic model through Cursor Agent";
|
|
637
|
+
case "openai":
|
|
638
|
+
return "OpenAI model through Cursor Agent";
|
|
639
|
+
case "google":
|
|
640
|
+
return "Google model through Cursor Agent";
|
|
641
|
+
case "xai":
|
|
642
|
+
return "xAI model through Cursor Agent";
|
|
643
|
+
case "moonshotai":
|
|
644
|
+
return "Moonshot model through Cursor Agent";
|
|
645
|
+
default:
|
|
646
|
+
return "Model through Cursor Agent";
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
function cursorModelPricing(cliModel) {
|
|
650
|
+
switch (cliModel) {
|
|
651
|
+
case "auto":
|
|
652
|
+
return { inputPerMTok: 1.25, outputPerMTok: 6, cacheReadPerMTok: 0.25, cacheWritePerMTok: 0 };
|
|
653
|
+
case "composer-2-fast":
|
|
654
|
+
return { inputPerMTok: 1.5, outputPerMTok: 7.5, cacheReadPerMTok: 0.35, cacheWritePerMTok: 0 };
|
|
655
|
+
case "composer-2":
|
|
656
|
+
return { inputPerMTok: 0.5, outputPerMTok: 2.5, cacheReadPerMTok: 0.2, cacheWritePerMTok: 0 };
|
|
657
|
+
case "composer-1.5":
|
|
658
|
+
return { inputPerMTok: 3.5, outputPerMTok: 17.5, cacheReadPerMTok: 0.35, cacheWritePerMTok: 0 };
|
|
659
|
+
default:
|
|
660
|
+
return void 0;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
var CURSOR_MODELS = CURSOR_MODEL_ROWS.map(
|
|
664
|
+
([cliModel, name, providerGroup]) => {
|
|
665
|
+
const id = cursorCliModelToModelId(cliModel);
|
|
666
|
+
const pricing = cursorModelPricing(cliModel);
|
|
667
|
+
return {
|
|
668
|
+
id,
|
|
669
|
+
name,
|
|
670
|
+
description: cursorModelDescription(providerGroup),
|
|
671
|
+
gatewayModelId: modelIdToGatewayModelId(id, "cursor") ?? id,
|
|
672
|
+
...pricing ? { pricing } : {},
|
|
673
|
+
cliModel,
|
|
674
|
+
provider: "cursor",
|
|
675
|
+
providerGroup
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
);
|
|
679
|
+
var THINKING_LEVELS = ["xhigh", "high", "medium", "low"];
|
|
680
|
+
var THINKING_LEVEL_LABELS = {
|
|
681
|
+
low: "Low",
|
|
682
|
+
medium: "Medium",
|
|
683
|
+
high: "High",
|
|
684
|
+
xhigh: "xHigh"
|
|
685
|
+
};
|
|
686
|
+
function codexModel(id, name, description, reasoningEffort, gatewayModelId = id.replace(/(?::thinking-|-thinking-)(low|medium|high|xhigh)$/i, ""), providerGroup = id.includes("gpt-5.5") ? "gpt-5.5" : "gpt-5.4") {
|
|
687
|
+
return {
|
|
688
|
+
id,
|
|
689
|
+
name,
|
|
690
|
+
description,
|
|
691
|
+
gatewayModelId,
|
|
692
|
+
cliModel: modelIdToHarnessModel(id, "codex"),
|
|
693
|
+
provider: "codex",
|
|
694
|
+
providerGroup,
|
|
695
|
+
...reasoningEffort ? { reasoningEffort } : {}
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
function codexThinkingModels(baseId, baseName, description) {
|
|
699
|
+
return THINKING_LEVELS.map(
|
|
700
|
+
(level) => codexModel(
|
|
701
|
+
`${baseId}-thinking-${level}`,
|
|
702
|
+
`${baseName} Thinking ${THINKING_LEVEL_LABELS[level]}`,
|
|
703
|
+
`${description} with ${THINKING_LEVEL_LABELS[level]} thinking`,
|
|
704
|
+
level,
|
|
705
|
+
baseId
|
|
706
|
+
)
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
var CODEX_MODELS = [
|
|
710
|
+
...codexThinkingModels(
|
|
711
|
+
"openai/gpt-5.5",
|
|
712
|
+
"GPT-5.5",
|
|
713
|
+
"Latest frontier model for coding and agentic work"
|
|
714
|
+
),
|
|
715
|
+
codexModel(
|
|
716
|
+
"openai/gpt-5.5",
|
|
717
|
+
"GPT-5.5",
|
|
718
|
+
"Latest frontier model for coding and agentic work"
|
|
719
|
+
),
|
|
720
|
+
codexModel(
|
|
721
|
+
"openai/gpt-5.5-pro",
|
|
722
|
+
"GPT-5.5 Pro",
|
|
723
|
+
"Highest-accuracy GPT-5.5 variant for difficult work"
|
|
724
|
+
),
|
|
725
|
+
...codexThinkingModels(
|
|
726
|
+
"openai/gpt-5.4",
|
|
727
|
+
"GPT-5.4",
|
|
728
|
+
"Frontier coding model"
|
|
729
|
+
),
|
|
730
|
+
codexModel(
|
|
731
|
+
"openai/gpt-5.4",
|
|
732
|
+
"GPT-5.4",
|
|
733
|
+
"Frontier coding model"
|
|
734
|
+
),
|
|
735
|
+
codexModel(
|
|
736
|
+
"openai/gpt-5.4-pro",
|
|
737
|
+
"GPT-5.4 Pro",
|
|
738
|
+
"Highest-accuracy GPT-5.4 variant for difficult work"
|
|
739
|
+
),
|
|
740
|
+
codexModel(
|
|
741
|
+
"openai/gpt-5.4-mini",
|
|
742
|
+
"GPT-5.4 Mini",
|
|
743
|
+
"Fast, efficient mini model"
|
|
744
|
+
),
|
|
745
|
+
codexModel(
|
|
746
|
+
"openai/gpt-5.4-nano",
|
|
747
|
+
"GPT-5.4 Nano",
|
|
748
|
+
"Smallest GPT-5.4 variant"
|
|
749
|
+
)
|
|
750
|
+
];
|
|
751
|
+
var HARNESSES = {
|
|
752
|
+
claude_code: {
|
|
753
|
+
id: "claude_code",
|
|
754
|
+
name: "Claude Code",
|
|
755
|
+
description: "Anthropic coding agent",
|
|
756
|
+
logoKey: "claude",
|
|
757
|
+
models: CLAUDE_MODELS,
|
|
758
|
+
defaultModelId: DEFAULT_MODEL_IDS.claude_code,
|
|
759
|
+
supportedAuthMethods: ["amalgm", "byok", "provider_auth"],
|
|
760
|
+
dynamicModels: true
|
|
761
|
+
},
|
|
762
|
+
opencode: {
|
|
763
|
+
id: "opencode",
|
|
764
|
+
name: "OpenCode",
|
|
765
|
+
description: "Open-source coding agent",
|
|
766
|
+
logoKey: "opencode",
|
|
767
|
+
models: OPENCODE_MODELS,
|
|
768
|
+
defaultModelId: "opencode-anthropic-claude-sonnet-4-6",
|
|
769
|
+
supportedAuthMethods: ["amalgm", "byok"],
|
|
770
|
+
dynamicModels: true
|
|
771
|
+
},
|
|
772
|
+
codex: {
|
|
773
|
+
id: "codex",
|
|
774
|
+
name: "Codex",
|
|
775
|
+
description: "OpenAI Codex CLI",
|
|
776
|
+
logoKey: "codex",
|
|
777
|
+
models: CODEX_MODELS,
|
|
778
|
+
defaultModelId: DEFAULT_MODEL_IDS.codex,
|
|
779
|
+
supportedAuthMethods: ["amalgm", "byok", "provider_auth"],
|
|
780
|
+
dynamicModels: true
|
|
781
|
+
},
|
|
782
|
+
pi: {
|
|
783
|
+
id: "pi",
|
|
784
|
+
name: "Pi",
|
|
785
|
+
description: "Multi-provider coding agent",
|
|
786
|
+
logoKey: "pi",
|
|
787
|
+
models: PI_MODELS,
|
|
788
|
+
defaultModelId: "pi-anthropic-claude-sonnet-4.6",
|
|
789
|
+
supportedAuthMethods: ["amalgm", "byok", "provider_auth"],
|
|
790
|
+
dynamicModels: true
|
|
791
|
+
},
|
|
792
|
+
amp: {
|
|
793
|
+
id: "amp",
|
|
794
|
+
name: "Amp",
|
|
795
|
+
description: "Sourcegraph Amp coding agent",
|
|
796
|
+
logoKey: "amp",
|
|
797
|
+
models: AMP_MODELS,
|
|
798
|
+
defaultModelId: DEFAULT_MODEL_IDS.amp,
|
|
799
|
+
supportedAuthMethods: ["provider_auth"]
|
|
800
|
+
},
|
|
801
|
+
cursor: {
|
|
802
|
+
id: "cursor",
|
|
803
|
+
name: "Cursor",
|
|
804
|
+
description: "Cursor Agent CLI",
|
|
805
|
+
logoKey: "cursor",
|
|
806
|
+
models: CURSOR_MODELS,
|
|
807
|
+
defaultModelId: DEFAULT_MODEL_IDS.cursor,
|
|
808
|
+
supportedAuthMethods: ["provider_auth"]
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
var HARNESS_IDS = [
|
|
812
|
+
"claude_code",
|
|
813
|
+
"codex",
|
|
814
|
+
"opencode",
|
|
815
|
+
"pi",
|
|
816
|
+
"amp",
|
|
817
|
+
"cursor"
|
|
818
|
+
];
|
|
819
|
+
var VISIBLE_HARNESS_IDS = [
|
|
820
|
+
"claude_code",
|
|
821
|
+
"codex",
|
|
822
|
+
"opencode",
|
|
823
|
+
"pi",
|
|
824
|
+
"amp",
|
|
825
|
+
"cursor"
|
|
826
|
+
];
|
|
827
|
+
var DISABLED_HARNESS_IDS = /* @__PURE__ */ new Set([]);
|
|
828
|
+
var dynamicModelCache = /* @__PURE__ */ new Map();
|
|
829
|
+
function registerDynamicModels(models) {
|
|
830
|
+
for (const m of models) {
|
|
831
|
+
dynamicModelCache.set(m.id, m);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
function clearDynamicModels() {
|
|
835
|
+
dynamicModelCache.clear();
|
|
836
|
+
}
|
|
837
|
+
function getHarnessModels(harnessId) {
|
|
838
|
+
return HARNESSES[harnessId]?.models ?? [];
|
|
839
|
+
}
|
|
840
|
+
function getModelById(modelId) {
|
|
841
|
+
const normalized = normalizeModelId(modelId) ?? modelId;
|
|
842
|
+
for (const harness of Object.values(HARNESSES)) {
|
|
843
|
+
const found = harness.models.find((m) => m.id === normalized);
|
|
844
|
+
if (found) {
|
|
845
|
+
const dynamic = dynamicModelCache.get(normalized);
|
|
846
|
+
return dynamic ? {
|
|
847
|
+
...found,
|
|
848
|
+
...dynamic,
|
|
849
|
+
cliModel: found.cliModel,
|
|
850
|
+
provider: found.provider,
|
|
851
|
+
reasoningEffort: found.reasoningEffort ?? dynamic.reasoningEffort
|
|
852
|
+
} : found;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
return dynamicModelCache.get(normalized) ?? dynamicModelCache.get(modelId);
|
|
856
|
+
}
|
|
857
|
+
function getModelDisplayName(modelId) {
|
|
858
|
+
const normalized = normalizeModelId(modelId) ?? modelId;
|
|
859
|
+
const model = getModelById(normalized);
|
|
860
|
+
return model?.name ?? normalized;
|
|
861
|
+
}
|
|
862
|
+
function isHarnessId(value) {
|
|
863
|
+
return Boolean(value && HARNESSES[value]);
|
|
864
|
+
}
|
|
865
|
+
function resolvePreferredHarnessModel({
|
|
866
|
+
explicitHarness,
|
|
867
|
+
explicitModel,
|
|
868
|
+
pinnedHarness,
|
|
869
|
+
pinnedModel,
|
|
870
|
+
lastUsedHarness,
|
|
871
|
+
selectedModels
|
|
872
|
+
}) {
|
|
873
|
+
const harness = (isHarnessId(explicitHarness) ? explicitHarness : null) || (isHarnessId(pinnedHarness) ? pinnedHarness : null) || (isHarnessId(lastUsedHarness) ? lastUsedHarness : null) || "claude_code";
|
|
874
|
+
const rawModel = explicitModel || (pinnedHarness === harness ? pinnedModel : null) || selectedModels?.[harness] || getDefaultModel(harness);
|
|
875
|
+
const model = normalizeModelId(rawModel, harness) ?? rawModel;
|
|
876
|
+
return { harness, model };
|
|
877
|
+
}
|
|
878
|
+
function getHarnessForModel(modelId) {
|
|
879
|
+
const normalized = normalizeModelId(modelId) ?? modelId;
|
|
880
|
+
for (const harness of Object.values(HARNESSES)) {
|
|
881
|
+
if (harness.models.some((m) => m.id === normalized)) {
|
|
882
|
+
return harness.id;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
const dynamicModel = dynamicModelCache.get(normalized) ?? dynamicModelCache.get(modelId);
|
|
886
|
+
if (dynamicModel) {
|
|
887
|
+
if (dynamicModel.provider === "claude") return "claude_code";
|
|
888
|
+
if (dynamicModel.provider === "codex") return "codex";
|
|
889
|
+
if (dynamicModel.provider === "pi") return "pi";
|
|
890
|
+
if (dynamicModel.provider === "amp") return "amp";
|
|
891
|
+
if (dynamicModel.provider === "cursor") return "cursor";
|
|
892
|
+
return "opencode";
|
|
893
|
+
}
|
|
894
|
+
return void 0;
|
|
895
|
+
}
|
|
896
|
+
function getDefaultModel(harnessId) {
|
|
897
|
+
return HARNESSES[harnessId]?.defaultModelId ?? DEFAULT_MODEL_IDS.claude_code;
|
|
898
|
+
}
|
|
899
|
+
function isAuthMethod(value) {
|
|
900
|
+
return value === "amalgm" || value === "byok" || value === "provider_auth";
|
|
901
|
+
}
|
|
902
|
+
function getDefaultAuthMethodForHarness(harnessId) {
|
|
903
|
+
return HARNESSES[harnessId]?.supportedAuthMethods[0] ?? "amalgm";
|
|
904
|
+
}
|
|
905
|
+
function isAuthMethodSupportedForHarness(harnessId, authMethod) {
|
|
906
|
+
return isAuthMethod(authMethod) && Boolean(HARNESSES[harnessId]?.supportedAuthMethods.includes(authMethod));
|
|
907
|
+
}
|
|
908
|
+
function coerceAuthMethodForHarness(harnessId, authMethod) {
|
|
909
|
+
return isAuthMethodSupportedForHarness(harnessId, authMethod) ? authMethod : getDefaultAuthMethodForHarness(harnessId);
|
|
910
|
+
}
|
|
911
|
+
function resolveHarnessModel(harnessId, modelId) {
|
|
912
|
+
const selection = normalizeModelSelection(modelId ?? getDefaultModel(harnessId), harnessId);
|
|
913
|
+
const normalizedModelId = selection?.modelId ?? getDefaultModel(harnessId);
|
|
914
|
+
const model = getModelById(normalizedModelId);
|
|
915
|
+
const adaptedModel = harnessId === "claude_code" || harnessId === "codex" || harnessId === "cursor" ? modelIdToHarnessModel(normalizedModelId, harnessId) : null;
|
|
916
|
+
return {
|
|
917
|
+
modelId: normalizedModelId,
|
|
918
|
+
cliModel: model?.cliModel ?? adaptedModel,
|
|
919
|
+
reasoningEffort: selection?.reasoningEffort ?? model?.reasoningEffort
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
function getAuthMethodsForHarness(harnessId) {
|
|
923
|
+
const harness = HARNESSES[harnessId];
|
|
924
|
+
return (harness?.supportedAuthMethods ?? ["amalgm"]).map(
|
|
925
|
+
(id) => AUTH_METHODS[id]
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
function getEnvKeyNameForHarness(harnessId) {
|
|
929
|
+
switch (harnessId) {
|
|
930
|
+
case "claude_code":
|
|
931
|
+
return "ANTHROPIC_API_KEY";
|
|
932
|
+
case "opencode":
|
|
933
|
+
return "AI_GATEWAY_API_KEY";
|
|
934
|
+
case "codex":
|
|
935
|
+
return "OPENAI_API_KEY";
|
|
936
|
+
case "pi":
|
|
937
|
+
return "AI_GATEWAY_API_KEY";
|
|
938
|
+
case "amp":
|
|
939
|
+
return "AMP_API_KEY";
|
|
940
|
+
case "cursor":
|
|
941
|
+
return "CURSOR_API_KEY";
|
|
942
|
+
default:
|
|
943
|
+
return "ANTHROPIC_API_KEY";
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
function getLoginCommandForHarness(harnessId) {
|
|
947
|
+
switch (harnessId) {
|
|
948
|
+
case "claude_code":
|
|
949
|
+
return "claude";
|
|
950
|
+
case "codex":
|
|
951
|
+
return "codex";
|
|
952
|
+
case "opencode":
|
|
953
|
+
return "opencode auth login";
|
|
954
|
+
case "pi":
|
|
955
|
+
return "pi --terminal-login";
|
|
956
|
+
case "amp":
|
|
957
|
+
return "amp --setup";
|
|
958
|
+
case "cursor":
|
|
959
|
+
return 'if command -v cursor-agent >/dev/null 2>&1; then cursor-agent login; else "$HOME/.local/bin/cursor-agent" login; fi';
|
|
960
|
+
default:
|
|
961
|
+
return "";
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
965
|
+
0 && (module.exports = {
|
|
966
|
+
AUTH_METHODS,
|
|
967
|
+
DISABLED_HARNESS_IDS,
|
|
968
|
+
HARNESSES,
|
|
969
|
+
HARNESS_IDS,
|
|
970
|
+
VISIBLE_HARNESS_IDS,
|
|
971
|
+
clearDynamicModels,
|
|
972
|
+
coerceAuthMethodForHarness,
|
|
973
|
+
getAuthMethodsForHarness,
|
|
974
|
+
getDefaultAuthMethodForHarness,
|
|
975
|
+
getDefaultModel,
|
|
976
|
+
getEnvKeyNameForHarness,
|
|
977
|
+
getHarnessForModel,
|
|
978
|
+
getHarnessModels,
|
|
979
|
+
getLoginCommandForHarness,
|
|
980
|
+
getModelById,
|
|
981
|
+
getModelDisplayName,
|
|
982
|
+
isAuthMethod,
|
|
983
|
+
isAuthMethodSupportedForHarness,
|
|
984
|
+
isHarnessId,
|
|
985
|
+
registerDynamicModels,
|
|
986
|
+
resolveHarnessModel,
|
|
987
|
+
resolvePreferredHarnessModel
|
|
988
|
+
});
|