@tangle-network/agent-app 0.44.24 → 0.44.25
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.
|
@@ -32,6 +32,75 @@ var fail = (error) => ({
|
|
|
32
32
|
error: error instanceof Error ? error : new Error(String(error))
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
// src/sandbox/model.ts
|
|
36
|
+
function resolveModelSelection(config, override) {
|
|
37
|
+
const c = config ?? {};
|
|
38
|
+
const explicitBaseUrl = trimOrNull(c.routerBaseUrl);
|
|
39
|
+
const explicitApiKey = trimOrNull(override?.modelApiKey) ?? trimOrNull(c.apiKey);
|
|
40
|
+
const providerName = trimOrNull(c.providerName);
|
|
41
|
+
const openaiApiKey = trimOrNull(c.openaiApiKey);
|
|
42
|
+
const provider = providerName ?? (explicitApiKey ? "openai-compat" : openaiApiKey ? "openai" : void 0);
|
|
43
|
+
const overrideModel = trimOrNull(override?.model);
|
|
44
|
+
const configModel = trimOrNull(c.modelName);
|
|
45
|
+
const defaultModel = trimOrNull(c.defaultModel);
|
|
46
|
+
const modelName = overrideModel ?? configModel ?? (provider === "openai" || provider === "openai-compat" ? defaultModel : null);
|
|
47
|
+
if (!modelName) return { succeeded: true, value: void 0 };
|
|
48
|
+
const source = overrideModel ? "override" : configModel ? "config" : "default";
|
|
49
|
+
if (!provider) return { succeeded: false, error: "no_provider", model: modelName, source };
|
|
50
|
+
const apiKey = explicitApiKey ?? (provider === "openai" ? openaiApiKey : void 0);
|
|
51
|
+
if (!apiKey && !c.allowKeylessModel) {
|
|
52
|
+
return { succeeded: false, error: "no_api_key", model: modelName, provider, source };
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
succeeded: true,
|
|
56
|
+
value: {
|
|
57
|
+
model: modelName,
|
|
58
|
+
provider,
|
|
59
|
+
...apiKey ? { apiKey } : {},
|
|
60
|
+
...explicitBaseUrl ? { baseUrl: explicitBaseUrl } : {}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function resolveModel(config, override) {
|
|
65
|
+
const selection = resolveModelSelection(config, override);
|
|
66
|
+
return selection.succeeded ? selection.value : void 0;
|
|
67
|
+
}
|
|
68
|
+
var SandboxModelResolutionError = class extends Error {
|
|
69
|
+
code;
|
|
70
|
+
model;
|
|
71
|
+
provider;
|
|
72
|
+
source;
|
|
73
|
+
constructor(failure, context) {
|
|
74
|
+
const missing = failure.error === "no_provider" ? "no provider could be resolved for it" : `provider "${failure.provider}" resolved but no API key is configured`;
|
|
75
|
+
const fix = failure.error === "no_provider" ? "set providerName explicitly (provider cannot be inferred without one)" : 'set apiKey (or openaiApiKey when provider is "openai"), or pass allowKeylessModel:true to mint a keyless box';
|
|
76
|
+
super(
|
|
77
|
+
`${context}: model "${failure.model}" (from ${failure.source}) is not transportable \u2014 ${missing}. Fix: ${fix}. The requested model was NOT sent to the box.`
|
|
78
|
+
);
|
|
79
|
+
this.name = "SandboxModelResolutionError";
|
|
80
|
+
this.code = failure.error;
|
|
81
|
+
this.model = failure.model;
|
|
82
|
+
if (failure.error === "no_api_key") this.provider = failure.provider;
|
|
83
|
+
this.source = failure.source;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
function requireTransportableModel(selection, context) {
|
|
87
|
+
if (selection.succeeded) return selection.value;
|
|
88
|
+
if (selection.source === "override") {
|
|
89
|
+
throw new SandboxModelResolutionError(selection, context);
|
|
90
|
+
}
|
|
91
|
+
const reason = selection.error === "no_api_key" ? `provider "${selection.provider}" has no api key` : "no provider resolved";
|
|
92
|
+
if (selection.source === "config") {
|
|
93
|
+
console.error(
|
|
94
|
+
`[sandbox] ${context}: dropping configured provider.modelName "${selection.model}" (${reason}); the box will use its own default model \u2014 set allowKeylessModel:true to bake a keyless model, or configure an api key`
|
|
95
|
+
);
|
|
96
|
+
} else {
|
|
97
|
+
console.error(
|
|
98
|
+
`[sandbox] ${context}: dropping provider.defaultModel "${selection.model}" (${reason}); using the box default`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return void 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
35
104
|
// src/sandbox/binary-read.ts
|
|
36
105
|
function shellQuote(value) {
|
|
37
106
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
@@ -1271,7 +1340,7 @@ async function ensureWorkspaceSandbox(shell, options) {
|
|
|
1271
1340
|
const { leanProfile, deferredFiles } = shell.deferProfileFiles ? splitDeferredProfileFiles(fullProfile) : { leanProfile: fullProfile, deferredFiles: [] };
|
|
1272
1341
|
const profile = leanProfile;
|
|
1273
1342
|
const role = userId && shell.permissionRole ? shell.permissionRole("developer") : void 0;
|
|
1274
|
-
let model = shell.backendModelAtCreate ?
|
|
1343
|
+
let model = shell.backendModelAtCreate ? requireTransportableModel(resolveModelSelection(shell.provider), `backendModelAtCreate for ${name}`) : void 0;
|
|
1275
1344
|
if (model && shell.childKeyMint && model.provider === "openai-compat") {
|
|
1276
1345
|
const minted = await shell.childKeyMint(scope);
|
|
1277
1346
|
if (minted.succeeded) model = { ...model, apiKey: minted.value };
|
|
@@ -1337,22 +1406,6 @@ async function ensureWorkspaceSandbox(shell, options) {
|
|
|
1337
1406
|
}
|
|
1338
1407
|
return box;
|
|
1339
1408
|
}
|
|
1340
|
-
function resolveModel(config, override) {
|
|
1341
|
-
const c = config ?? {};
|
|
1342
|
-
const explicitBaseUrl = c.routerBaseUrl;
|
|
1343
|
-
const explicitApiKey = override?.modelApiKey ?? c.apiKey;
|
|
1344
|
-
const provider = c.providerName ?? (explicitApiKey ? "openai-compat" : c.openaiApiKey ? "openai" : void 0);
|
|
1345
|
-
const modelName = override?.model ?? c.modelName ?? (provider === "openai" || provider === "openai-compat" ? c.defaultModel : void 0);
|
|
1346
|
-
const apiKey = explicitApiKey ?? (provider === "openai" ? c.openaiApiKey : void 0);
|
|
1347
|
-
if (!provider || !modelName) return void 0;
|
|
1348
|
-
if (!apiKey && !c.allowKeylessModel) return void 0;
|
|
1349
|
-
return {
|
|
1350
|
-
model: modelName,
|
|
1351
|
-
provider,
|
|
1352
|
-
...apiKey ? { apiKey } : {},
|
|
1353
|
-
...explicitBaseUrl ? { baseUrl: explicitBaseUrl } : {}
|
|
1354
|
-
};
|
|
1355
|
-
}
|
|
1356
1409
|
function historyTranscript(history) {
|
|
1357
1410
|
return history.map((entry) => `${entry.role === "assistant" ? "Assistant" : "User"}: ${entry.content}`).join("\n\n");
|
|
1358
1411
|
}
|
|
@@ -1398,10 +1451,13 @@ function attachReasoningEffort(profile, harness, effort) {
|
|
|
1398
1451
|
}
|
|
1399
1452
|
async function* streamSandboxPrompt(shell, box, message, options) {
|
|
1400
1453
|
const harness = options?.harness ?? "opencode";
|
|
1401
|
-
const model =
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1454
|
+
const model = requireTransportableModel(
|
|
1455
|
+
resolveModelSelection(shell.provider, {
|
|
1456
|
+
model: options?.model,
|
|
1457
|
+
modelApiKey: options?.modelApiKey
|
|
1458
|
+
}),
|
|
1459
|
+
"streamSandboxPrompt"
|
|
1460
|
+
);
|
|
1405
1461
|
if (model?.model) assertHarnessModelCompatible(harness, model.model);
|
|
1406
1462
|
const prompt = typeof message === "string" ? flattenHistory(message, options?.history) : mergeHistoryIntoParts(message, options?.history);
|
|
1407
1463
|
const appToolMcp = options?.appToolMcp ?? {};
|
|
@@ -1574,10 +1630,13 @@ async function mintSandboxScopedToken(box, options) {
|
|
|
1574
1630
|
}
|
|
1575
1631
|
async function driveSandboxTurn(shell, box, message, options) {
|
|
1576
1632
|
const harness = options.harness ?? "opencode";
|
|
1577
|
-
const model =
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1633
|
+
const model = requireTransportableModel(
|
|
1634
|
+
resolveModelSelection(shell.provider, {
|
|
1635
|
+
model: options.model,
|
|
1636
|
+
modelApiKey: options.modelApiKey
|
|
1637
|
+
}),
|
|
1638
|
+
"driveSandboxTurn"
|
|
1639
|
+
);
|
|
1581
1640
|
if (model?.model) assertHarnessModelCompatible(harness, model.model);
|
|
1582
1641
|
const prompt = typeof message === "string" ? flattenHistory(message, options.history) : mergeHistoryIntoParts(message, options.history);
|
|
1583
1642
|
const appToolMcp = options.appToolMcp ?? {};
|
|
@@ -1653,6 +1712,10 @@ function firstQuestionText(value) {
|
|
|
1653
1712
|
}
|
|
1654
1713
|
|
|
1655
1714
|
export {
|
|
1715
|
+
resolveModelSelection,
|
|
1716
|
+
resolveModel,
|
|
1717
|
+
SandboxModelResolutionError,
|
|
1718
|
+
requireTransportableModel,
|
|
1656
1719
|
shellQuote,
|
|
1657
1720
|
statSandboxFileSize,
|
|
1658
1721
|
readSandboxBinaryBytes,
|
|
@@ -1694,7 +1757,6 @@ export {
|
|
|
1694
1757
|
assertEnvWithinLimits,
|
|
1695
1758
|
peekWorkspaceSandbox,
|
|
1696
1759
|
ensureWorkspaceSandbox,
|
|
1697
|
-
resolveModel,
|
|
1698
1760
|
flattenHistory,
|
|
1699
1761
|
mergeHistoryIntoParts,
|
|
1700
1762
|
mergeExtraMcp,
|
|
@@ -1715,4 +1777,4 @@ export {
|
|
|
1715
1777
|
isTerminalPromptEvent,
|
|
1716
1778
|
detectInteractiveQuestion
|
|
1717
1779
|
};
|
|
1718
|
-
//# sourceMappingURL=chunk-
|
|
1780
|
+
//# sourceMappingURL=chunk-Q74BS43G.js.map
|