amalgm 0.1.147 → 0.1.148
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/package.json +3 -3
- package/runtime/lib/harnesses.js +42 -22
- package/runtime/scripts/amalgm-mcp/agents/store.js +3 -2
- package/runtime/scripts/amalgm-mcp/agents/talk.js +5 -4
- package/runtime/scripts/amalgm-mcp/lib/prefs.js +24 -17
- package/runtime/scripts/amalgm-mcp/tasks/executor.js +5 -4
- package/runtime/scripts/chat-core/adapters/claude.js +0 -1
- package/runtime/scripts/chat-core/adapters/codex.js +1 -1
- package/runtime/scripts/chat-core/contract.js +5 -2
- package/runtime/scripts/chat-server/model-catalog.js +4 -0
- package/runtime/scripts/platform-context.txt +10 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amalgm",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.148",
|
|
4
4
|
"description": "Amalgm local computer runtime: login, MCP, chat, events, previews, and tunnels.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"private": false,
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@ai-sdk/gateway": "^3.0.131",
|
|
35
|
-
"@anthropic-ai/claude-agent-sdk": "^0.3.
|
|
35
|
+
"@anthropic-ai/claude-agent-sdk": "^0.3.206",
|
|
36
36
|
"@anthropic-ai/sdk": "^0.104.1",
|
|
37
37
|
"@homebridge/node-pty-prebuilt-multiarch": "^0.13.1",
|
|
38
38
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
39
|
-
"@openai/codex": "^0.
|
|
39
|
+
"@openai/codex": "^0.144.1",
|
|
40
40
|
"@opencode-ai/sdk": "^1.17.6",
|
|
41
41
|
"agent-browser": "^0.27.3",
|
|
42
42
|
"ai": "^6.0.205",
|
package/runtime/lib/harnesses.js
CHANGED
|
@@ -57,7 +57,7 @@ function buildGatewayCliModel(gatewayId, harness) {
|
|
|
57
57
|
// lib/modelNaming.ts
|
|
58
58
|
var DEFAULT_MODEL_IDS = {
|
|
59
59
|
claude_code: "anthropic/claude-opus-4.8",
|
|
60
|
-
codex: "openai/gpt-5.
|
|
60
|
+
codex: "openai/gpt-5.6-sol",
|
|
61
61
|
opencode: "opencode-deepseek-deepseek-v4-pro",
|
|
62
62
|
pi: "pi-anthropic-claude-sonnet-4.6",
|
|
63
63
|
amp: "amp-default",
|
|
@@ -84,19 +84,21 @@ var CLAUDE_LEGACY_ALIASES = {
|
|
|
84
84
|
"claude-code-opus-4-8-1m": CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
85
85
|
"claude-code-opus-4.7-1m": CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
86
86
|
"claude-code-opus-4-7-1m": CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
87
|
-
"claude-code-sonnet": "anthropic/claude-sonnet-
|
|
88
|
-
"claude-code-sonnet-
|
|
89
|
-
"claude-code-sonnet-
|
|
90
|
-
"claude-code-sonnet-4
|
|
91
|
-
"claude-code-sonnet-4
|
|
92
|
-
"claude-code-sonnet-4
|
|
87
|
+
"claude-code-sonnet": "anthropic/claude-sonnet-5",
|
|
88
|
+
"claude-code-sonnet-5": "anthropic/claude-sonnet-5",
|
|
89
|
+
"claude-code-sonnet-45": "anthropic/claude-sonnet-5",
|
|
90
|
+
"claude-code-sonnet-4.6": "anthropic/claude-sonnet-5",
|
|
91
|
+
"claude-code-sonnet-4-6": "anthropic/claude-sonnet-5",
|
|
92
|
+
"claude-code-sonnet-4.5": "anthropic/claude-sonnet-5",
|
|
93
|
+
"claude-code-sonnet-4-5": "anthropic/claude-sonnet-5",
|
|
93
94
|
"claude-code-haiku": "anthropic/claude-haiku-4.5",
|
|
94
95
|
"claude-code-haiku-4.5": "anthropic/claude-haiku-4.5",
|
|
95
96
|
"claude-code-haiku-4-5": "anthropic/claude-haiku-4.5",
|
|
96
97
|
"anthropic/claude-opus-4.7": "anthropic/claude-opus-4.8",
|
|
97
98
|
"anthropic/claude-opus-4.6": "anthropic/claude-opus-4.8",
|
|
98
99
|
"anthropic/claude-opus-4.5": "anthropic/claude-opus-4.8",
|
|
99
|
-
"anthropic/claude-sonnet-4.
|
|
100
|
+
"anthropic/claude-sonnet-4.6": "anthropic/claude-sonnet-5",
|
|
101
|
+
"anthropic/claude-sonnet-4.5": "anthropic/claude-sonnet-5",
|
|
100
102
|
"claude-opus-4.8-1m": CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
101
103
|
"claude-opus-4-8-1m": CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
102
104
|
"claude-opus-4.7-1m": CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
@@ -104,8 +106,9 @@ var CLAUDE_LEGACY_ALIASES = {
|
|
|
104
106
|
opus: "anthropic/claude-opus-4.8",
|
|
105
107
|
opus1m: CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
106
108
|
"opus[1m]": CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
107
|
-
sonnet: "anthropic/claude-sonnet-
|
|
108
|
-
"sonnet[1m]": "anthropic/claude-sonnet-
|
|
109
|
+
sonnet: "anthropic/claude-sonnet-5",
|
|
110
|
+
"sonnet[1m]": "anthropic/claude-sonnet-5",
|
|
111
|
+
"sonnet-5": "anthropic/claude-sonnet-5",
|
|
109
112
|
haiku: "anthropic/claude-haiku-4.5",
|
|
110
113
|
fable: "anthropic/claude-fable-5",
|
|
111
114
|
"claude-code-fable": "anthropic/claude-fable-5",
|
|
@@ -117,6 +120,7 @@ var CLAUDE_HARNESS_MODELS = {
|
|
|
117
120
|
"anthropic/claude-opus-4.7": "opus",
|
|
118
121
|
"anthropic/claude-opus-4.6": "opus",
|
|
119
122
|
"anthropic/claude-opus-4.5": "opus",
|
|
123
|
+
"anthropic/claude-sonnet-5": "sonnet",
|
|
120
124
|
"anthropic/claude-sonnet-4.6": "sonnet",
|
|
121
125
|
"anthropic/claude-sonnet-4.5": "sonnet",
|
|
122
126
|
"anthropic/claude-haiku-4.5": "haiku",
|
|
@@ -202,8 +206,8 @@ var CURSOR_CLI_ALIASES = {
|
|
|
202
206
|
"composer-2": "composer-2.5",
|
|
203
207
|
"composer-2-fast": "composer-2.5-fast"
|
|
204
208
|
};
|
|
205
|
-
var CODEX_THINKING_SUFFIX_RE = /:thinking-(low|medium|high|xhigh)$/i;
|
|
206
|
-
var CODEX_LEGACY_THINKING_SUFFIX_RE = /-thinking-(low|medium|high|xhigh)$/i;
|
|
209
|
+
var CODEX_THINKING_SUFFIX_RE = /:thinking-(low|medium|high|xhigh|max|ultra)$/i;
|
|
210
|
+
var CODEX_LEGACY_THINKING_SUFFIX_RE = /-thinking-(low|medium|high|xhigh|max|ultra)$/i;
|
|
207
211
|
function cleanModelId(value) {
|
|
208
212
|
return value.trim().replace(/^vercel\//i, "").toLowerCase();
|
|
209
213
|
}
|
|
@@ -214,7 +218,8 @@ function normalizeClaudeModelPart(modelPart) {
|
|
|
214
218
|
"claude-opus-4.7": "claude-opus-4.8",
|
|
215
219
|
"claude-opus-4.6": "claude-opus-4.8",
|
|
216
220
|
"claude-opus-4.5": "claude-opus-4.8",
|
|
217
|
-
"claude-sonnet-4.
|
|
221
|
+
"claude-sonnet-4.6": "claude-sonnet-5",
|
|
222
|
+
"claude-sonnet-4.5": "claude-sonnet-5"
|
|
218
223
|
}[base] ?? base;
|
|
219
224
|
return hasOneMillionContext && currentBase === "claude-opus-4.8" ? `${currentBase}-1m` : currentBase;
|
|
220
225
|
}
|
|
@@ -244,7 +249,7 @@ function codexGatewayModelId(modelId) {
|
|
|
244
249
|
}
|
|
245
250
|
function codexHarnessModelId(modelId, effort) {
|
|
246
251
|
const baseModel = codexGatewayModelId(modelId).replace(/^openai\//, "");
|
|
247
|
-
if (effort && /^gpt-5\.[45](?:-mini)
|
|
252
|
+
if (effort && /^gpt-5\.(?:[45](?:-mini)?|6-(?:sol|terra|luna))$/i.test(baseModel)) {
|
|
248
253
|
return `${baseModel}/${effort}`;
|
|
249
254
|
}
|
|
250
255
|
return baseModel;
|
|
@@ -252,7 +257,7 @@ function codexHarnessModelId(modelId, effort) {
|
|
|
252
257
|
function normalizeCodexModelSelection(value) {
|
|
253
258
|
const cleaned = cleanModelId(value);
|
|
254
259
|
const legacyThinkingMatch = cleaned.match(
|
|
255
|
-
/^(codex-[a-z0-9.-]+(?:-[a-z0-9.-]+)*)-thinking-(low|medium|high|xhigh)$/i
|
|
260
|
+
/^(codex-[a-z0-9.-]+(?:-[a-z0-9.-]+)*)-thinking-(low|medium|high|xhigh|max|ultra)$/i
|
|
256
261
|
);
|
|
257
262
|
if (legacyThinkingMatch) {
|
|
258
263
|
const effort = legacyThinkingMatch[2].toLowerCase();
|
|
@@ -262,7 +267,7 @@ function normalizeCodexModelSelection(value) {
|
|
|
262
267
|
};
|
|
263
268
|
}
|
|
264
269
|
const canonicalThinkingMatch = cleaned.match(
|
|
265
|
-
/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)(?::thinking-|-thinking-)(low|medium|high|xhigh)$/i
|
|
270
|
+
/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)(?::thinking-|-thinking-)(low|medium|high|xhigh|max|ultra)$/i
|
|
266
271
|
);
|
|
267
272
|
if (canonicalThinkingMatch) {
|
|
268
273
|
const effort = canonicalThinkingMatch[2].toLowerCase();
|
|
@@ -272,7 +277,7 @@ function normalizeCodexModelSelection(value) {
|
|
|
272
277
|
};
|
|
273
278
|
}
|
|
274
279
|
const slashThinkingMatch = cleaned.match(
|
|
275
|
-
/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)\/(low|medium|high|xhigh)$/i
|
|
280
|
+
/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)\/(low|medium|high|xhigh|max|ultra)$/i
|
|
276
281
|
);
|
|
277
282
|
if (slashThinkingMatch) {
|
|
278
283
|
const effort = slashThinkingMatch[2].toLowerCase();
|
|
@@ -495,11 +500,11 @@ var CLAUDE_MODELS = [
|
|
|
495
500
|
providerGroup: "anthropic"
|
|
496
501
|
},
|
|
497
502
|
{
|
|
498
|
-
id: "anthropic/claude-sonnet-
|
|
499
|
-
name: "Sonnet
|
|
503
|
+
id: "anthropic/claude-sonnet-5",
|
|
504
|
+
name: "Sonnet 5",
|
|
500
505
|
description: "Balanced Claude Code model",
|
|
501
|
-
gatewayModelId: "anthropic/claude-sonnet-
|
|
502
|
-
cliModel: modelIdToHarnessModel("anthropic/claude-sonnet-
|
|
506
|
+
gatewayModelId: "anthropic/claude-sonnet-5",
|
|
507
|
+
cliModel: modelIdToHarnessModel("anthropic/claude-sonnet-5", "claude_code"),
|
|
503
508
|
provider: "claude",
|
|
504
509
|
providerGroup: "anthropic"
|
|
505
510
|
},
|
|
@@ -747,7 +752,7 @@ var CURSOR_MODELS = CURSOR_MODEL_ROWS.map(
|
|
|
747
752
|
};
|
|
748
753
|
}
|
|
749
754
|
);
|
|
750
|
-
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") {
|
|
755
|
+
function codexModel(id, name, description, reasoningEffort, gatewayModelId = id.replace(/(?::thinking-|-thinking-)(low|medium|high|xhigh|max|ultra)$/i, ""), providerGroup = id.includes("gpt-5.6") ? "gpt-5.6" : id.includes("gpt-5.5") ? "gpt-5.5" : "gpt-5.4") {
|
|
751
756
|
return {
|
|
752
757
|
id,
|
|
753
758
|
name,
|
|
@@ -760,6 +765,21 @@ function codexModel(id, name, description, reasoningEffort, gatewayModelId = id.
|
|
|
760
765
|
};
|
|
761
766
|
}
|
|
762
767
|
var CODEX_MODELS = [
|
|
768
|
+
codexModel(
|
|
769
|
+
"openai/gpt-5.6-sol",
|
|
770
|
+
"GPT-5.6 Sol",
|
|
771
|
+
"Flagship GPT-5.6 tier for complex coding and agentic work"
|
|
772
|
+
),
|
|
773
|
+
codexModel(
|
|
774
|
+
"openai/gpt-5.6-terra",
|
|
775
|
+
"GPT-5.6 Terra",
|
|
776
|
+
"Balanced GPT-5.6 tier for everyday work"
|
|
777
|
+
),
|
|
778
|
+
codexModel(
|
|
779
|
+
"openai/gpt-5.6-luna",
|
|
780
|
+
"GPT-5.6 Luna",
|
|
781
|
+
"Fastest, lowest-cost GPT-5.6 tier"
|
|
782
|
+
),
|
|
763
783
|
codexModel(
|
|
764
784
|
"openai/gpt-5.5",
|
|
765
785
|
"GPT-5.5",
|
|
@@ -184,6 +184,7 @@ function normalizeEffort(value) {
|
|
|
184
184
|
if (normalized === 'high') return 'high';
|
|
185
185
|
if (normalized === 'xhigh' || normalized === 'extra-high' || normalized === 'extra high') return 'xhigh';
|
|
186
186
|
if (normalized === 'max') return 'max';
|
|
187
|
+
if (normalized === 'ultra') return 'ultra';
|
|
187
188
|
return null;
|
|
188
189
|
}
|
|
189
190
|
|
|
@@ -195,11 +196,11 @@ function normalizeModelSettings(value, fallback = null, harnessId = null) {
|
|
|
195
196
|
harnessId === 'claude_code'
|
|
196
197
|
? new Set(['low', 'medium', 'high', 'xhigh', 'max'])
|
|
197
198
|
: harnessId === 'codex'
|
|
198
|
-
? new Set(['low', 'medium', 'high', 'xhigh'])
|
|
199
|
+
? new Set(['low', 'medium', 'high', 'xhigh', 'max', 'ultra'])
|
|
199
200
|
: null;
|
|
200
201
|
const normalized = {
|
|
201
202
|
...(effort && (!allowedEfforts || allowedEfforts.has(effort)) ? { effort } : {}),
|
|
202
|
-
...((harnessId === '
|
|
203
|
+
...((harnessId === 'codex' || !harnessId)
|
|
203
204
|
&& (raw.fastMode === true || raw.speed === 'fast')
|
|
204
205
|
? { fastMode: true }
|
|
205
206
|
: {}),
|
|
@@ -361,6 +361,7 @@ function normalizeEffort(value) {
|
|
|
361
361
|
if (normalized === 'high') return 'high';
|
|
362
362
|
if (normalized === 'xhigh' || normalized === 'extra-high' || normalized === 'extra high') return 'xhigh';
|
|
363
363
|
if (normalized === 'max') return 'max';
|
|
364
|
+
if (normalized === 'ultra') return 'ultra';
|
|
364
365
|
return null;
|
|
365
366
|
}
|
|
366
367
|
|
|
@@ -371,19 +372,19 @@ function sanitizeAgentModelSettings(settings, harness) {
|
|
|
371
372
|
harness === 'claude_code'
|
|
372
373
|
? new Set(['low', 'medium', 'high', 'xhigh', 'max'])
|
|
373
374
|
: harness === 'codex'
|
|
374
|
-
? new Set(['low', 'medium', 'high', 'xhigh'])
|
|
375
|
+
? new Set(['low', 'medium', 'high', 'xhigh', 'max', 'ultra'])
|
|
375
376
|
: new Set();
|
|
376
377
|
return {
|
|
377
378
|
...(effort && allowedEfforts.has(effort) ? { effort } : {}),
|
|
378
|
-
...(
|
|
379
|
+
...(harness === 'codex' && settings.fastMode === true ? { fastMode: true } : {}),
|
|
379
380
|
};
|
|
380
381
|
}
|
|
381
382
|
|
|
382
383
|
function modelIdForAgentSettings(modelId, harness, modelSettings) {
|
|
383
384
|
if (harness !== 'codex' || !modelSettings.effort || typeof modelId !== 'string') return modelId;
|
|
384
385
|
return modelId
|
|
385
|
-
.replace(/(?::thinking-|-thinking-)(low|medium|high|xhigh)$/i, '')
|
|
386
|
-
.replace(/\/(low|medium|high|xhigh)$/i, '') + '/' + modelSettings.effort;
|
|
386
|
+
.replace(/(?::thinking-|-thinking-)(low|medium|high|xhigh|max|ultra)$/i, '')
|
|
387
|
+
.replace(/\/(low|medium|high|xhigh|max|ultra)$/i, '') + '/' + modelSettings.effort;
|
|
387
388
|
}
|
|
388
389
|
|
|
389
390
|
async function appendAsyncCompletionToCallerSession({
|
|
@@ -15,7 +15,7 @@ const {
|
|
|
15
15
|
|
|
16
16
|
const DEFAULT_SELECTED_MODELS = {
|
|
17
17
|
claude_code: 'anthropic/claude-opus-4.8',
|
|
18
|
-
codex: 'openai/gpt-5.
|
|
18
|
+
codex: 'openai/gpt-5.6-sol',
|
|
19
19
|
opencode: 'opencode-deepseek-deepseek-v4-pro',
|
|
20
20
|
pi: 'pi-anthropic-claude-sonnet-4.6',
|
|
21
21
|
amp: 'amp-default',
|
|
@@ -70,19 +70,21 @@ const CLAUDE_LEGACY_ALIASES = {
|
|
|
70
70
|
'claude-code-opus-4-8-1m': CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
71
71
|
'claude-code-opus-4.7-1m': CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
72
72
|
'claude-code-opus-4-7-1m': CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
73
|
-
'claude-code-sonnet': 'anthropic/claude-sonnet-
|
|
74
|
-
'claude-code-sonnet-
|
|
75
|
-
'claude-code-sonnet-
|
|
76
|
-
'claude-code-sonnet-4
|
|
77
|
-
'claude-code-sonnet-4
|
|
78
|
-
'claude-code-sonnet-4
|
|
73
|
+
'claude-code-sonnet': 'anthropic/claude-sonnet-5',
|
|
74
|
+
'claude-code-sonnet-5': 'anthropic/claude-sonnet-5',
|
|
75
|
+
'claude-code-sonnet-45': 'anthropic/claude-sonnet-5',
|
|
76
|
+
'claude-code-sonnet-4.6': 'anthropic/claude-sonnet-5',
|
|
77
|
+
'claude-code-sonnet-4-6': 'anthropic/claude-sonnet-5',
|
|
78
|
+
'claude-code-sonnet-4.5': 'anthropic/claude-sonnet-5',
|
|
79
|
+
'claude-code-sonnet-4-5': 'anthropic/claude-sonnet-5',
|
|
79
80
|
'claude-code-haiku': 'anthropic/claude-haiku-4.5',
|
|
80
81
|
'claude-code-haiku-4.5': 'anthropic/claude-haiku-4.5',
|
|
81
82
|
'claude-code-haiku-4-5': 'anthropic/claude-haiku-4.5',
|
|
82
83
|
'anthropic/claude-opus-4.7': 'anthropic/claude-opus-4.8',
|
|
83
84
|
'anthropic/claude-opus-4.6': 'anthropic/claude-opus-4.8',
|
|
84
85
|
'anthropic/claude-opus-4.5': 'anthropic/claude-opus-4.8',
|
|
85
|
-
'anthropic/claude-sonnet-4.
|
|
86
|
+
'anthropic/claude-sonnet-4.6': 'anthropic/claude-sonnet-5',
|
|
87
|
+
'anthropic/claude-sonnet-4.5': 'anthropic/claude-sonnet-5',
|
|
86
88
|
'claude-opus-4.8-1m': CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
87
89
|
'claude-opus-4-8-1m': CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
88
90
|
'claude-opus-4.7-1m': CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
@@ -90,8 +92,9 @@ const CLAUDE_LEGACY_ALIASES = {
|
|
|
90
92
|
opus: 'anthropic/claude-opus-4.8',
|
|
91
93
|
opus1m: CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
92
94
|
'opus[1m]': CLAUDE_OPUS_4_8_1M_MODEL_ID,
|
|
93
|
-
sonnet: 'anthropic/claude-sonnet-
|
|
94
|
-
'sonnet[1m]': 'anthropic/claude-sonnet-
|
|
95
|
+
sonnet: 'anthropic/claude-sonnet-5',
|
|
96
|
+
'sonnet[1m]': 'anthropic/claude-sonnet-5',
|
|
97
|
+
'sonnet-5': 'anthropic/claude-sonnet-5',
|
|
95
98
|
haiku: 'anthropic/claude-haiku-4.5',
|
|
96
99
|
fable: 'anthropic/claude-fable-5',
|
|
97
100
|
'claude-code-fable': 'anthropic/claude-fable-5',
|
|
@@ -104,14 +107,15 @@ const CLAUDE_HARNESS_MODELS = {
|
|
|
104
107
|
'anthropic/claude-opus-4.7': 'opus',
|
|
105
108
|
'anthropic/claude-opus-4.6': 'opus',
|
|
106
109
|
'anthropic/claude-opus-4.5': 'opus',
|
|
110
|
+
'anthropic/claude-sonnet-5': 'sonnet',
|
|
107
111
|
'anthropic/claude-sonnet-4.6': 'sonnet',
|
|
108
112
|
'anthropic/claude-sonnet-4.5': 'sonnet',
|
|
109
113
|
'anthropic/claude-haiku-4.5': 'haiku',
|
|
110
114
|
'anthropic/claude-fable-5': 'claude-fable-5',
|
|
111
115
|
};
|
|
112
116
|
|
|
113
|
-
const CODEX_THINKING_SUFFIX_RE = /:thinking-(low|medium|high|xhigh)$/i;
|
|
114
|
-
const CODEX_LEGACY_THINKING_SUFFIX_RE = /-thinking-(low|medium|high|xhigh)$/i;
|
|
117
|
+
const CODEX_THINKING_SUFFIX_RE = /:thinking-(low|medium|high|xhigh|max|ultra)$/i;
|
|
118
|
+
const CODEX_LEGACY_THINKING_SUFFIX_RE = /-thinking-(low|medium|high|xhigh|max|ultra)$/i;
|
|
115
119
|
|
|
116
120
|
const CURSOR_MODEL_ALIASES = {
|
|
117
121
|
'cursor-opus-4.6-thinking': 'anthropic/claude-opus-4.6-high-thinking',
|
|
@@ -178,7 +182,8 @@ function normalizeClaudeModelPart(modelPart) {
|
|
|
178
182
|
'claude-opus-4.7': 'claude-opus-4.8',
|
|
179
183
|
'claude-opus-4.6': 'claude-opus-4.8',
|
|
180
184
|
'claude-opus-4.5': 'claude-opus-4.8',
|
|
181
|
-
'claude-sonnet-4.
|
|
185
|
+
'claude-sonnet-4.6': 'claude-sonnet-5',
|
|
186
|
+
'claude-sonnet-4.5': 'claude-sonnet-5',
|
|
182
187
|
}[base] || base;
|
|
183
188
|
return hasOneMillionContext && currentBase === 'claude-opus-4.8'
|
|
184
189
|
? currentBase + '-1m'
|
|
@@ -215,7 +220,7 @@ function codexGatewayModelId(modelId) {
|
|
|
215
220
|
|
|
216
221
|
function codexHarnessModelId(modelId, effort) {
|
|
217
222
|
const baseModel = codexGatewayModelId(modelId).replace(/^openai\//, '');
|
|
218
|
-
if (effort && /^gpt-5\.[45](?:-mini)
|
|
223
|
+
if (effort && /^gpt-5\.(?:[45](?:-mini)?|6-(?:sol|terra|luna))$/i.test(baseModel)) {
|
|
219
224
|
return `${baseModel}/${effort}`;
|
|
220
225
|
}
|
|
221
226
|
return baseModel;
|
|
@@ -285,7 +290,7 @@ function normalizeModelSelection(harnessId, modelId) {
|
|
|
285
290
|
}
|
|
286
291
|
|
|
287
292
|
if (harnessId === 'codex') {
|
|
288
|
-
const legacyThinkingMatch = cleaned.match(/^(codex-[a-z0-9.-]+(?:-[a-z0-9.-]+)*)-thinking-(low|medium|high|xhigh)$/i);
|
|
293
|
+
const legacyThinkingMatch = cleaned.match(/^(codex-[a-z0-9.-]+(?:-[a-z0-9.-]+)*)-thinking-(low|medium|high|xhigh|max|ultra)$/i);
|
|
289
294
|
if (legacyThinkingMatch) {
|
|
290
295
|
const effort = legacyThinkingMatch[2].toLowerCase();
|
|
291
296
|
return {
|
|
@@ -293,7 +298,7 @@ function normalizeModelSelection(harnessId, modelId) {
|
|
|
293
298
|
reasoningEffort: effort,
|
|
294
299
|
};
|
|
295
300
|
}
|
|
296
|
-
const canonicalThinkingMatch = cleaned.match(/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)(?::thinking-|-thinking-)(low|medium|high|xhigh)$/i);
|
|
301
|
+
const canonicalThinkingMatch = cleaned.match(/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)(?::thinking-|-thinking-)(low|medium|high|xhigh|max|ultra)$/i);
|
|
297
302
|
if (canonicalThinkingMatch) {
|
|
298
303
|
const effort = canonicalThinkingMatch[2].toLowerCase();
|
|
299
304
|
return {
|
|
@@ -301,7 +306,7 @@ function normalizeModelSelection(harnessId, modelId) {
|
|
|
301
306
|
reasoningEffort: effort,
|
|
302
307
|
};
|
|
303
308
|
}
|
|
304
|
-
const slashThinkingMatch = cleaned.match(/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)\/(low|medium|high|xhigh)$/i);
|
|
309
|
+
const slashThinkingMatch = cleaned.match(/^((?:openai\/)?(?:gpt|o)[a-z0-9.-]+(?:-[a-z0-9.-]+)*)\/(low|medium|high|xhigh|max|ultra)$/i);
|
|
305
310
|
if (slashThinkingMatch) {
|
|
306
311
|
const effort = slashThinkingMatch[2].toLowerCase();
|
|
307
312
|
return {
|
|
@@ -369,6 +374,8 @@ function normalizeReasoningEffort(value) {
|
|
|
369
374
|
if (normalized === 'xhigh' || normalized === 'extra-high' || normalized === 'extra high') {
|
|
370
375
|
return 'xhigh';
|
|
371
376
|
}
|
|
377
|
+
if (normalized === 'max') return 'max';
|
|
378
|
+
if (normalized === 'ultra') return 'ultra';
|
|
372
379
|
return null;
|
|
373
380
|
}
|
|
374
381
|
|
|
@@ -59,6 +59,7 @@ function normalizeEffort(value) {
|
|
|
59
59
|
if (normalized === 'high') return 'high';
|
|
60
60
|
if (normalized === 'xhigh' || normalized === 'extra-high' || normalized === 'extra high') return 'xhigh';
|
|
61
61
|
if (normalized === 'max') return 'max';
|
|
62
|
+
if (normalized === 'ultra') return 'ultra';
|
|
62
63
|
return null;
|
|
63
64
|
}
|
|
64
65
|
|
|
@@ -69,19 +70,19 @@ function sanitizeRunModelSettings(settings, harness) {
|
|
|
69
70
|
harness === 'claude_code'
|
|
70
71
|
? new Set(['low', 'medium', 'high', 'xhigh', 'max'])
|
|
71
72
|
: harness === 'codex'
|
|
72
|
-
? new Set(['low', 'medium', 'high', 'xhigh'])
|
|
73
|
+
? new Set(['low', 'medium', 'high', 'xhigh', 'max', 'ultra'])
|
|
73
74
|
: new Set();
|
|
74
75
|
return {
|
|
75
76
|
...(effort && allowedEfforts.has(effort) ? { effort } : {}),
|
|
76
|
-
...(
|
|
77
|
+
...(harness === 'codex' && settings.fastMode === true ? { fastMode: true } : {}),
|
|
77
78
|
};
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
function modelIdForSettings(modelId, harness, modelSettings) {
|
|
81
82
|
if (harness !== 'codex' || !modelSettings.effort || typeof modelId !== 'string') return modelId;
|
|
82
83
|
return modelId
|
|
83
|
-
.replace(/(?::thinking-|-thinking-)(low|medium|high|xhigh)$/i, '')
|
|
84
|
-
.replace(/\/(low|medium|high|xhigh)$/i, '');
|
|
84
|
+
.replace(/(?::thinking-|-thinking-)(low|medium|high|xhigh|max|ultra)$/i, '')
|
|
85
|
+
.replace(/\/(low|medium|high|xhigh|max|ultra)$/i, '');
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
function disableTerminalScheduleIfNeeded(task) {
|
|
@@ -37,7 +37,6 @@ class ClaudeAdapter {
|
|
|
37
37
|
const pathToClaudeCodeExecutable = process.env.CLAUDE_CODE_BINARY || bundledClaudeBinary();
|
|
38
38
|
const settings = {
|
|
39
39
|
...toClaudeSettings(contract.agentConfig),
|
|
40
|
-
...(contract.fastMode ? { fastMode: true, fastModePerSessionOptIn: true } : {}),
|
|
41
40
|
};
|
|
42
41
|
return {
|
|
43
42
|
cwd: contract.cwd,
|
|
@@ -552,7 +552,7 @@ class CodexAdapter {
|
|
|
552
552
|
threadId: session.providerSessionId,
|
|
553
553
|
input: [{ type: 'text', text: prompt }],
|
|
554
554
|
cwd: contract.cwd,
|
|
555
|
-
model: contract.cliModel.replace(/\/(?:low|medium|high|xhigh)$/i, ''),
|
|
555
|
+
model: contract.cliModel.replace(/\/(?:low|medium|high|xhigh|max|ultra)$/i, ''),
|
|
556
556
|
effort: contract.reasoningEffort || undefined,
|
|
557
557
|
serviceTier: serviceTierForContract(contract),
|
|
558
558
|
approvalPolicy: 'never',
|
|
@@ -263,6 +263,7 @@ function cliModelFor({ harness, modelId, cliModel, reasoningEffort }) {
|
|
|
263
263
|
const canonical = canonicalModel(clean, harness);
|
|
264
264
|
const aliases = {
|
|
265
265
|
'anthropic/claude-haiku-4.5': 'haiku',
|
|
266
|
+
'anthropic/claude-sonnet-5': 'sonnet',
|
|
266
267
|
'anthropic/claude-sonnet-4.6': 'sonnet',
|
|
267
268
|
'anthropic/claude-opus-4.8': 'opus',
|
|
268
269
|
'anthropic/claude-opus-4.8-1m': 'opus[1m]',
|
|
@@ -271,6 +272,8 @@ function cliModelFor({ harness, modelId, cliModel, reasoningEffort }) {
|
|
|
271
272
|
'anthropic/claude-fable-5': 'claude-fable-5',
|
|
272
273
|
'haiku': 'haiku',
|
|
273
274
|
'sonnet': 'sonnet',
|
|
275
|
+
'sonnet-5': 'sonnet',
|
|
276
|
+
'claude-sonnet-5': 'sonnet',
|
|
274
277
|
'opus': 'opus',
|
|
275
278
|
'opus1m': 'opus[1m]',
|
|
276
279
|
'opus[1m]': 'opus[1m]',
|
|
@@ -284,12 +287,12 @@ function cliModelFor({ harness, modelId, cliModel, reasoningEffort }) {
|
|
|
284
287
|
if (harness === 'codex') {
|
|
285
288
|
let base = clean.replace(/^openai\//, '');
|
|
286
289
|
let effort = reasoningEffort;
|
|
287
|
-
const slashEffort = base.match(/\/(low|medium|high|xhigh)$/i);
|
|
290
|
+
const slashEffort = base.match(/\/(low|medium|high|xhigh|max|ultra)$/i);
|
|
288
291
|
if (slashEffort) {
|
|
289
292
|
effort ||= slashEffort[1].toLowerCase();
|
|
290
293
|
base = base.slice(0, -slashEffort[0].length);
|
|
291
294
|
}
|
|
292
|
-
const thinkingEffort = base.match(/-thinking-(low|medium|high|xhigh)$/i);
|
|
295
|
+
const thinkingEffort = base.match(/-thinking-(low|medium|high|xhigh|max|ultra)$/i);
|
|
293
296
|
if (!cliModel && thinkingEffort) {
|
|
294
297
|
effort ||= thinkingEffort[1].toLowerCase();
|
|
295
298
|
base = base.slice(0, -thinkingEffort[0].length);
|
|
@@ -55,6 +55,7 @@ const MODEL_CATALOG = [
|
|
|
55
55
|
{ id: "anthropic/claude-sonnet-4", name: "Claude Sonnet 4", provider: "anthropic", contextWindow: 1000000, maxOutput: 64000, inputPrice: 3, outputPrice: 15, cacheRead: 0.3, cacheWrite: 3.75, tags: ["file-input", "reasoning", "tool-use", "vision", "explicit-caching"], released: "2025-05-22" },
|
|
56
56
|
{ id: "anthropic/claude-sonnet-4.5", name: "Claude Sonnet 4.5", provider: "anthropic", contextWindow: 1000000, maxOutput: 64000, inputPrice: 3, outputPrice: 15, cacheRead: 0.3, cacheWrite: 3.75, tags: ["file-input", "reasoning", "tool-use", "vision", "explicit-caching"], released: "2025-09-29" },
|
|
57
57
|
{ id: "anthropic/claude-sonnet-4.6", name: "Claude Sonnet 4.6", provider: "anthropic", contextWindow: 1000000, maxOutput: 128000, inputPrice: 3, outputPrice: 15, cacheRead: 0.3, cacheWrite: 3.75, tags: ["file-input", "reasoning", "tool-use", "vision", "explicit-caching", "web-search"], released: "2026-02-17" },
|
|
58
|
+
{ id: "anthropic/claude-sonnet-5", name: "Claude Sonnet 5", provider: "anthropic", contextWindow: 1000000, maxOutput: 128000, inputPrice: 3, outputPrice: 15, cacheRead: 0.3, cacheWrite: 3.75, tags: ["file-input", "reasoning", "tool-use", "vision", "explicit-caching", "web-search"], released: "2026-06-30" },
|
|
58
59
|
// ── arcee-ai (3) ──────────────────────────────────────────
|
|
59
60
|
{ id: "arcee-ai/trinity-large-preview", name: "Trinity Large Preview", provider: "arcee-ai", contextWindow: 131000, maxOutput: 131000, inputPrice: 0.25, outputPrice: 1, cacheRead: null, cacheWrite: null, tags: ["tool-use"], released: "2025-01-01" },
|
|
60
61
|
{ id: "arcee-ai/trinity-large-thinking", name: "Trinity Large Thinking", provider: "arcee-ai", contextWindow: 262100, maxOutput: 80000, inputPrice: 0.25, outputPrice: 0.9, cacheRead: null, cacheWrite: null, tags: ["reasoning", "tool-use", "implicit-caching"], released: "2026-04-01" },
|
|
@@ -182,6 +183,9 @@ const MODEL_CATALOG = [
|
|
|
182
183
|
{ id: "openai/gpt-5.4-pro", name: "GPT 5.4 Pro", provider: "openai", contextWindow: 1050000, maxOutput: 128000, inputPrice: 30, outputPrice: 180, cacheRead: null, cacheWrite: null, tags: ["reasoning", "tool-use", "vision", "file-input", "implicit-caching", "web-search"], released: "2026-03-05" },
|
|
183
184
|
{ id: "openai/gpt-5.5", name: "GPT 5.5", provider: "openai", contextWindow: 1000000, maxOutput: 128000, inputPrice: 5, outputPrice: 30, cacheRead: 0.5, cacheWrite: null, tags: ["reasoning", "tool-use", "web-search", "implicit-caching", "file-input", "vision"], released: "2026-04-24" },
|
|
184
185
|
{ id: "openai/gpt-5.5-pro", name: "GPT 5.5 Pro", provider: "openai", contextWindow: 1000000, maxOutput: 128000, inputPrice: 30, outputPrice: 180, cacheRead: null, cacheWrite: null, tags: ["reasoning", "tool-use", "implicit-caching", "file-input", "web-search", "vision"], released: "2026-04-24" },
|
|
186
|
+
{ id: "openai/gpt-5.6-sol", name: "GPT 5.6 Sol", provider: "openai", contextWindow: 1050000, maxOutput: 128000, inputPrice: 5, outputPrice: 30, cacheRead: 0.5, cacheWrite: 6.25, tags: ["reasoning", "tool-use", "web-search", "implicit-caching", "file-input", "vision"], released: "2026-06-26" },
|
|
187
|
+
{ id: "openai/gpt-5.6-terra", name: "GPT 5.6 Terra", provider: "openai", contextWindow: 1050000, maxOutput: 128000, inputPrice: 2.5, outputPrice: 15, cacheRead: 0.25, cacheWrite: 3.125, tags: ["reasoning", "tool-use", "web-search", "implicit-caching", "file-input", "vision"], released: "2026-06-26" },
|
|
188
|
+
{ id: "openai/gpt-5.6-luna", name: "GPT 5.6 Luna", provider: "openai", contextWindow: 1050000, maxOutput: 128000, inputPrice: 1, outputPrice: 6, cacheRead: 0.1, cacheWrite: 1.25, tags: ["reasoning", "tool-use", "web-search", "implicit-caching", "file-input", "vision"], released: "2026-06-26" },
|
|
185
189
|
{ id: "openai/gpt-oss-120b", name: "GPT OSS 120B", provider: "openai", contextWindow: 131072, maxOutput: 131000, inputPrice: 0.35, outputPrice: 0.75, cacheRead: 0.25, cacheWrite: null, tags: ["implicit-caching"], released: "2025-08-05" },
|
|
186
190
|
{ id: "openai/gpt-oss-20b", name: "GPT OSS 120B", provider: "openai", contextWindow: 131072, maxOutput: 8192, inputPrice: 0.05, outputPrice: 0.2, cacheRead: null, cacheWrite: null, tags: ["reasoning", "tool-use"], released: "2025-08-05" },
|
|
187
191
|
{ id: "openai/gpt-oss-safeguard-20b", name: "GPT OSS Safeguard 20B", provider: "openai", contextWindow: 131072, maxOutput: 65536, inputPrice: 0.075, outputPrice: 0.3, cacheRead: 0.037, cacheWrite: null, tags: ["reasoning", "tool-use"], released: "2024-12-01" },
|
|
@@ -95,7 +95,7 @@ If the user wants a public, highly shared, or hyperscaler-hosted service, think
|
|
|
95
95
|
|
|
96
96
|
## Primitive 3: Notifications — Keep the User Informed
|
|
97
97
|
|
|
98
|
-
- `notify_user` — Send an email notification to the user (from
|
|
98
|
+
- `notify_user` — Send an email notification to the user (from emails@amalgm.ai). Supports `level` (info, warning, error, success) and an optional `link`.
|
|
99
99
|
|
|
100
100
|
**When to use notifications:**
|
|
101
101
|
- **Usually** at the end of automation runs when the result matters to the user.
|
|
@@ -178,7 +178,7 @@ Do not force scaffolding, wrappers, or opinionated project layouts unless the us
|
|
|
178
178
|
|
|
179
179
|
## Tile Entity References
|
|
180
180
|
|
|
181
|
-
When you mention a chat session, automation, app, or preview that exists on the platform, render it as
|
|
181
|
+
When you mention a chat session, automation, app, or preview that exists on the platform, render it as a tile using markdown link syntax. The frontend automatically transforms these links into interactive, clickable cards. Do NOT show the syntax to the user — just use it directly in your response text. Tiles and expanded references are block-level: they take up the whole line, so put each one on its own line rather than mid-sentence. The compact tile is the DEFAULT for entity references; only switch to the expanded form (next section) when a full in-chat preview is worth the space.
|
|
182
182
|
|
|
183
183
|
Tile format: [label](tile:TYPE:ID)
|
|
184
184
|
|
|
@@ -188,15 +188,19 @@ Types:
|
|
|
188
188
|
- App: [label](tile:app:APP_ID)
|
|
189
189
|
- Preview: [label](tile:preview:PORT)
|
|
190
190
|
|
|
191
|
-
IMPORTANT: Never wrap these in backticks or code blocks. Never explain the syntax to the user. Just emit the markdown link
|
|
191
|
+
IMPORTANT: Never wrap these in backticks or code blocks. Never explain the syntax to the user. Just emit the markdown link on its own line. The UI handles the rest — the user sees a rich card, not a raw link.
|
|
192
192
|
|
|
193
|
-
Example response (what you output):
|
|
193
|
+
Example response (what you output):
|
|
194
|
+
|
|
195
|
+
"Here's the automation I set up for you:
|
|
196
|
+
[API Health Monitor](tile:automation:abc123)
|
|
197
|
+
It runs every hour and will notify you if anything breaks."
|
|
194
198
|
|
|
195
199
|
The user sees "API Health Monitor" as a clickable card — not a link.
|
|
196
200
|
|
|
197
201
|
## Expanded Entity References
|
|
198
202
|
|
|
199
|
-
When a full in-chat preview is useful, render the entity with the expanded form. Expanded references use the message width, have a capped height, and include top-right actions for opening the entity in a tab.
|
|
203
|
+
When a full in-chat preview is useful, render the entity with the expanded form. Expanded references use the message width, have a capped height, and include top-right actions for opening the entity in a tab. Use this sparingly — for the one entity the response is actually about; everything else stays a compact tile.
|
|
200
204
|
|
|
201
205
|
Expanded format: [label](full:TYPE:ID)
|
|
202
206
|
|
|
@@ -221,7 +225,7 @@ Rules:
|
|
|
221
225
|
|
|
222
226
|
## Citing Files, Folders, Skills, and Agents
|
|
223
227
|
|
|
224
|
-
When you reference a file, folder, skill, or agent that exists on the user's local volume, emit it as an `amalgm://` markdown link. The frontend renders these as inline citation chips by default, with a hover card showing the path and (for skills) description. Skills are files too: if you only have the `SKILL.md` path, a normal file citation is valid. This is the same format the user's `@`-menu produces, and it's how agents talk to each other about local resources.
|
|
228
|
+
When you reference a file, folder, skill, or agent that exists on the user's local volume, emit it as an `amalgm://` markdown link. The frontend renders these as inline citation chips by default, with a hover card showing the path and (for skills) description. Citations are for *referring to* a resource mid-sentence; to *show* a file's content (a screenshot, clip, or document preview), use the embed syntax from the previous section (`` on its own line) instead. Skills are files too: if you only have the `SKILL.md` path, a normal file citation is valid. This is the same format the user's `@`-menu produces, and it's how agents talk to each other about local resources.
|
|
225
229
|
|
|
226
230
|
Render format: `[label](amalgm://KIND/ENCODED_PATH_OR_ID)`
|
|
227
231
|
|