@aexhq/sdk 0.26.4 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_contracts/operations.d.ts +25 -1
- package/dist/_contracts/operations.js +115 -0
- package/dist/_contracts/run-custody.js +1 -1
- package/dist/_contracts/runtime-types.d.ts +67 -0
- package/dist/_contracts/side-effect-audit.js +1 -1
- package/dist/_contracts/submission.d.ts +98 -66
- package/dist/_contracts/submission.js +162 -105
- package/dist/cli.mjs +109 -10
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +47 -21
- package/dist/client.js +60 -9
- package/dist/client.js.map +1 -1
- package/dist/data-tools.d.ts +56 -0
- package/dist/data-tools.js +149 -0
- package/dist/data-tools.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/concepts/agent-tools.md +45 -30
- package/docs/credentials.md +21 -3
- package/docs/run-config.md +1 -1
- package/package.json +10 -6
|
@@ -196,6 +196,7 @@ export const deniedSecretFields = new Set([
|
|
|
196
196
|
"providerApiKey",
|
|
197
197
|
"anthropicApiKey",
|
|
198
198
|
"apiKey",
|
|
199
|
+
"apiKeys",
|
|
199
200
|
"accessToken",
|
|
200
201
|
"refreshToken",
|
|
201
202
|
"password",
|
|
@@ -708,8 +709,12 @@ export function crossValidateSecretEnvAndValues(secretEnv, envSecrets) {
|
|
|
708
709
|
}
|
|
709
710
|
}
|
|
710
711
|
export function parseInlineSecrets(input) {
|
|
712
|
+
// A child run (parentRunId set) inherits its provider keys server-side from
|
|
713
|
+
// the parent's vault, so it may omit `secrets` entirely.
|
|
714
|
+
if (input === undefined || input === null)
|
|
715
|
+
return {};
|
|
711
716
|
const value = requireRecord(input, "secrets");
|
|
712
|
-
const allowedTopLevel = new Set(["apiKey", "mcpServers", "proxyEndpointAuth", "envSecrets"]);
|
|
717
|
+
const allowedTopLevel = new Set(["apiKey", "apiKeys", "mcpServers", "proxyEndpointAuth", "envSecrets"]);
|
|
713
718
|
for (const key of Object.keys(value)) {
|
|
714
719
|
if (key.startsWith("__aex_")) {
|
|
715
720
|
// Platform-internal namespace (e.g. __aex_proxy_token). The BFF
|
|
@@ -723,16 +728,39 @@ export function parseInlineSecrets(input) {
|
|
|
723
728
|
}
|
|
724
729
|
}
|
|
725
730
|
const apiKey = value.apiKey !== undefined ? requireString(value.apiKey, "secrets.apiKey") : undefined;
|
|
731
|
+
const apiKeys = parseApiKeys(value.apiKeys);
|
|
726
732
|
const mcpServers = parseMcpServerSecrets(value.mcpServers);
|
|
727
733
|
const proxyEndpointAuth = parseProxyEndpointAuth(value.proxyEndpointAuth);
|
|
728
734
|
const envSecrets = parseEnvSecrets(value.envSecrets);
|
|
729
735
|
return {
|
|
730
736
|
...(apiKey !== undefined ? { apiKey } : {}),
|
|
737
|
+
...(apiKeys ? { apiKeys } : {}),
|
|
731
738
|
...(mcpServers ? { mcpServers } : {}),
|
|
732
739
|
...(proxyEndpointAuth ? { proxyEndpointAuth } : {}),
|
|
733
740
|
...(envSecrets ? { envSecrets } : {})
|
|
734
741
|
};
|
|
735
742
|
}
|
|
743
|
+
/**
|
|
744
|
+
* Parse the per-provider BYOK key map. Each key must name a known
|
|
745
|
+
* {@link RunProvider}; each value must be a non-empty string. Returns
|
|
746
|
+
* `undefined` for an absent or empty map so the spread above stays clean.
|
|
747
|
+
*/
|
|
748
|
+
function parseApiKeys(input) {
|
|
749
|
+
if (input === undefined || input === null)
|
|
750
|
+
return undefined;
|
|
751
|
+
const value = requireRecord(input, "secrets.apiKeys");
|
|
752
|
+
const out = {};
|
|
753
|
+
for (const [provider, key] of Object.entries(value)) {
|
|
754
|
+
if (!RUN_PROVIDERS.includes(provider)) {
|
|
755
|
+
throw new Error(`secrets.apiKeys["${provider}"] is not a known provider; permitted: ${RUN_PROVIDERS.join(", ")}`);
|
|
756
|
+
}
|
|
757
|
+
if (typeof key !== "string" || key.length === 0) {
|
|
758
|
+
throw new Error(`secrets.apiKeys["${provider}"] must be a non-empty string`);
|
|
759
|
+
}
|
|
760
|
+
out[provider] = key;
|
|
761
|
+
}
|
|
762
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
763
|
+
}
|
|
736
764
|
function parseEnvSecrets(input) {
|
|
737
765
|
if (input === undefined || input === null)
|
|
738
766
|
return undefined;
|
|
@@ -1050,7 +1078,9 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
1050
1078
|
const postHook = parsePostHook(value.postHook, "submission.postHook");
|
|
1051
1079
|
const proxyEndpoints = parseProxyEndpoints(value.proxyEndpoints);
|
|
1052
1080
|
const secrets = parseInlineSecrets(value.secrets);
|
|
1053
|
-
enforceCredentialSecretPolicy(credentialMode, secrets
|
|
1081
|
+
enforceCredentialSecretPolicy(credentialMode, secrets, provider, {
|
|
1082
|
+
inheritsFromParent: parentRunId !== undefined
|
|
1083
|
+
});
|
|
1054
1084
|
crossValidateProxyEndpointsAndAuth(proxyEndpoints, secrets.proxyEndpointAuth);
|
|
1055
1085
|
const submission = parseSubmission(value.submission);
|
|
1056
1086
|
assertRunModelMatchesProvider(provider, submission.model);
|
|
@@ -1169,13 +1199,22 @@ export function parseRunProvider(input) {
|
|
|
1169
1199
|
}
|
|
1170
1200
|
/**
|
|
1171
1201
|
* Cross-check the supplied secrets bundle against the credential mode. BYOK
|
|
1172
|
-
* requires `secrets.
|
|
1173
|
-
*
|
|
1202
|
+
* requires `secrets.apiKeys[provider]` (the key for the run's own `provider`).
|
|
1203
|
+
* Additional provider keys are optional (validated for shape only) so the run
|
|
1204
|
+
* can supply keys for the other providers its subagents may use. MCP / proxy
|
|
1205
|
+
* endpoint auth carry across providers and are not checked here.
|
|
1206
|
+
*
|
|
1207
|
+
* A CHILD run (`inheritsFromParent`) is exempt from the own-key requirement: it
|
|
1208
|
+
* inherits its provider keys server-side from the parent's vaulted bundle, so
|
|
1209
|
+
* it need not carry any of its own. The server still verifies, at admission,
|
|
1210
|
+
* that the parent actually holds a key for the child's provider.
|
|
1174
1211
|
*/
|
|
1175
|
-
export function enforceCredentialSecretPolicy(credentialMode, secrets) {
|
|
1212
|
+
export function enforceCredentialSecretPolicy(credentialMode, secrets, provider, opts) {
|
|
1176
1213
|
void credentialMode;
|
|
1177
|
-
if (
|
|
1178
|
-
|
|
1214
|
+
if (opts?.inheritsFromParent)
|
|
1215
|
+
return;
|
|
1216
|
+
if (!(secrets.apiKeys?.[provider] ?? secrets.apiKey)) {
|
|
1217
|
+
throw new Error(`secrets.apiKey is required when credentialMode is byok (or secrets.apiKeys["${provider}"])`);
|
|
1179
1218
|
}
|
|
1180
1219
|
}
|
|
1181
1220
|
export function parseSubmission(input) {
|
|
@@ -1194,7 +1233,7 @@ export function parseSubmission(input) {
|
|
|
1194
1233
|
"securityProfile",
|
|
1195
1234
|
"metadata",
|
|
1196
1235
|
"outputs",
|
|
1197
|
-
"
|
|
1236
|
+
"includeBuiltinTools",
|
|
1198
1237
|
"outputMode",
|
|
1199
1238
|
"platform"
|
|
1200
1239
|
]);
|
|
@@ -1207,7 +1246,7 @@ export function parseSubmission(input) {
|
|
|
1207
1246
|
const system = optionalString(value.system, "submission.system");
|
|
1208
1247
|
const prompt = parsePrompt(value.prompt);
|
|
1209
1248
|
const skills = parseSkills(value.skills);
|
|
1210
|
-
const tools = parseTools(value.tools);
|
|
1249
|
+
const { tools, builtinTools } = parseTools(value.tools);
|
|
1211
1250
|
const agentsMd = parseAgentsMd(value.agentsMd);
|
|
1212
1251
|
const files = parseFiles(value.files);
|
|
1213
1252
|
const mcpServers = parseMcpServers(value.mcpServers);
|
|
@@ -1216,7 +1255,7 @@ export function parseSubmission(input) {
|
|
|
1216
1255
|
const securityProfile = parseRuntimeSecurityProfile(value.securityProfile);
|
|
1217
1256
|
const metadata = optionalJsonRecord(value.metadata, "submission.metadata");
|
|
1218
1257
|
const outputs = parseOutputs(value.outputs);
|
|
1219
|
-
const
|
|
1258
|
+
const includeBuiltinTools = parseIncludeBuiltinTools(value.includeBuiltinTools);
|
|
1220
1259
|
const outputMode = parseOutputMode(value.outputMode);
|
|
1221
1260
|
const platform = parsePlatformConfig(value.platform);
|
|
1222
1261
|
return {
|
|
@@ -1233,7 +1272,8 @@ export function parseSubmission(input) {
|
|
|
1233
1272
|
...(securityProfile ? { securityProfile } : {}),
|
|
1234
1273
|
...(metadata ? { metadata } : {}),
|
|
1235
1274
|
...(outputs ? { outputs } : {}),
|
|
1236
|
-
...(
|
|
1275
|
+
...(includeBuiltinTools !== undefined ? { includeBuiltinTools } : {}),
|
|
1276
|
+
...(builtinTools.length > 0 ? { builtinTools } : {}),
|
|
1237
1277
|
...(outputMode !== undefined ? { outputMode } : {}),
|
|
1238
1278
|
...(platform ? { platform } : {})
|
|
1239
1279
|
};
|
|
@@ -1297,108 +1337,105 @@ function parseOutputMode(input) {
|
|
|
1297
1337
|
return input;
|
|
1298
1338
|
}
|
|
1299
1339
|
/**
|
|
1300
|
-
*
|
|
1301
|
-
*
|
|
1302
|
-
*
|
|
1340
|
+
* The CLOSED set of builtin tool NAMES the managed runtime can inject — one per
|
|
1341
|
+
* machine tool the hands implement. This list is the single source of truth for
|
|
1342
|
+
* validating builtin tool references; the platform's `HANDS_TOOLS` (the execute
|
|
1343
|
+
* vocabulary) is pinned EQUAL to it at module load (`platform-runtime-agent`
|
|
1344
|
+
* `assertNamesMatch`), so a rename on either side fails loudly rather than
|
|
1345
|
+
* silently shipping a name the executors do not speak.
|
|
1303
1346
|
*
|
|
1304
|
-
*
|
|
1305
|
-
*
|
|
1347
|
+
* Order mirrors `HANDS_TOOLS`. A builtin tool reference (a bare string in
|
|
1348
|
+
* `submission.tools`) must be a member of this set.
|
|
1306
1349
|
*/
|
|
1307
|
-
export const
|
|
1308
|
-
"web_search",
|
|
1309
|
-
"web_fetch",
|
|
1310
|
-
"read",
|
|
1311
|
-
"edit",
|
|
1312
|
-
"glob",
|
|
1313
|
-
"grep",
|
|
1314
|
-
"head",
|
|
1315
|
-
"tail",
|
|
1350
|
+
export const BUILTIN_TOOL_NAMES = [
|
|
1316
1351
|
"bash",
|
|
1317
|
-
"
|
|
1318
|
-
"
|
|
1319
|
-
"
|
|
1320
|
-
"memory",
|
|
1321
|
-
"autovisualiser",
|
|
1322
|
-
"tutorial"
|
|
1323
|
-
];
|
|
1324
|
-
/**
|
|
1325
|
-
* DX-first managed-runtime defaults. Omitted `builtins` resolves to this list.
|
|
1326
|
-
* Notebook support remains opt-in through {@link Builtins.NOTEBOOK}.
|
|
1327
|
-
*/
|
|
1328
|
-
export const DEFAULT_BUILTINS = [
|
|
1329
|
-
"web_search",
|
|
1330
|
-
"web_fetch",
|
|
1331
|
-
"read",
|
|
1332
|
-
"edit",
|
|
1333
|
-
"glob",
|
|
1352
|
+
"read_file",
|
|
1353
|
+
"write_file",
|
|
1354
|
+
"edit_file",
|
|
1334
1355
|
"grep",
|
|
1356
|
+
"glob",
|
|
1335
1357
|
"head",
|
|
1336
1358
|
"tail",
|
|
1337
|
-
"
|
|
1359
|
+
"todo_write",
|
|
1360
|
+
"subagent",
|
|
1361
|
+
"subagent_result",
|
|
1362
|
+
"web_fetch",
|
|
1363
|
+
"web_search",
|
|
1364
|
+
"notebook_edit",
|
|
1365
|
+
"bash_output",
|
|
1366
|
+
"bash_kill",
|
|
1367
|
+
"code_execution",
|
|
1368
|
+
"wait",
|
|
1369
|
+
"git"
|
|
1338
1370
|
];
|
|
1339
1371
|
/**
|
|
1340
|
-
*
|
|
1341
|
-
* `
|
|
1372
|
+
* Typo-safe accessors for the closed builtin tool set: each key maps to the
|
|
1373
|
+
* real tool NAME string. Reference a builtin in `submission.tools` via
|
|
1374
|
+
* `BuiltinTools.notebook_edit` rather than the bare string so a rename is a
|
|
1375
|
+
* compile error, not a runtime 400.
|
|
1376
|
+
*
|
|
1377
|
+
* Keys are the real tool names; a unit test asserts `Object.values(BuiltinTools)`
|
|
1378
|
+
* deep-equals `BUILTIN_TOOL_NAMES` so the two can never drift.
|
|
1342
1379
|
*/
|
|
1343
|
-
export const
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
NOTEBOOK: "notebook",
|
|
1364
|
-
/** Legacy aggregate: shell/filesystem/navigation/web/notebook tools. */
|
|
1365
|
-
DEVELOPER: "developer",
|
|
1366
|
-
/** Legacy aggregate alias retained for existing callers. */
|
|
1367
|
-
COMPUTER_CONTROLLER: "computercontroller",
|
|
1368
|
-
/** Legacy aggregate alias retained for existing callers. */
|
|
1369
|
-
MEMORY: "memory",
|
|
1370
|
-
/** Legacy aggregate alias retained for existing callers. */
|
|
1371
|
-
AUTOVISUALISER: "autovisualiser",
|
|
1372
|
-
/** Legacy aggregate alias retained for existing callers. */
|
|
1373
|
-
TUTORIAL: "tutorial"
|
|
1380
|
+
export const BuiltinTools = {
|
|
1381
|
+
bash: "bash",
|
|
1382
|
+
read_file: "read_file",
|
|
1383
|
+
write_file: "write_file",
|
|
1384
|
+
edit_file: "edit_file",
|
|
1385
|
+
grep: "grep",
|
|
1386
|
+
glob: "glob",
|
|
1387
|
+
head: "head",
|
|
1388
|
+
tail: "tail",
|
|
1389
|
+
todo_write: "todo_write",
|
|
1390
|
+
subagent: "subagent",
|
|
1391
|
+
subagent_result: "subagent_result",
|
|
1392
|
+
web_fetch: "web_fetch",
|
|
1393
|
+
web_search: "web_search",
|
|
1394
|
+
notebook_edit: "notebook_edit",
|
|
1395
|
+
bash_output: "bash_output",
|
|
1396
|
+
bash_kill: "bash_kill",
|
|
1397
|
+
code_execution: "code_execution",
|
|
1398
|
+
wait: "wait",
|
|
1399
|
+
git: "git"
|
|
1374
1400
|
};
|
|
1375
|
-
|
|
1376
|
-
|
|
1401
|
+
/**
|
|
1402
|
+
* The default builtin tool set injected when `includeBuiltinTools !== false`:
|
|
1403
|
+
* every builtin tool EXCEPT `notebook_edit` (notebook editing stays opt-in —
|
|
1404
|
+
* add `BuiltinTools.notebook_edit` to `tools` to enable it). Derived by
|
|
1405
|
+
* filtering {@link BUILTIN_TOOL_NAMES} so it can never drift from the closed
|
|
1406
|
+
* set.
|
|
1407
|
+
*/
|
|
1408
|
+
export const DEFAULT_BUILTIN_TOOLS = BUILTIN_TOOL_NAMES.filter((name) => name !== "notebook_edit");
|
|
1409
|
+
/**
|
|
1410
|
+
* Resolve the set of builtin tool NAMES a submission injects, deduplicated and
|
|
1411
|
+
* in {@link BUILTIN_TOOL_NAMES} order.
|
|
1412
|
+
*
|
|
1413
|
+
* - `includeBuiltinTools !== false` ⇒ start from {@link DEFAULT_BUILTIN_TOOLS}
|
|
1414
|
+
* (the standard set); `false` ⇒ start from none (pure-MCP / pure-custom).
|
|
1415
|
+
* - union in every builtin-name string the caller listed in `tools` (a
|
|
1416
|
+
* cherry-pick, e.g. `BuiltinTools.notebook_edit` to opt the notebook in).
|
|
1417
|
+
*
|
|
1418
|
+
* Every `toolRefs` string MUST be a member of {@link BUILTIN_TOOL_NAMES}; the
|
|
1419
|
+
* union is validated ⊆ the closed set so an invalid name can never leak through.
|
|
1420
|
+
*/
|
|
1421
|
+
export function resolveBuiltinToolNames(includeBuiltinTools, toolRefs) {
|
|
1422
|
+
const enabled = new Set(includeBuiltinTools !== false ? DEFAULT_BUILTIN_TOOLS : []);
|
|
1423
|
+
for (const ref of toolRefs ?? []) {
|
|
1424
|
+
if (!BUILTIN_TOOL_NAMES.includes(ref)) {
|
|
1425
|
+
throw new Error(`${JSON.stringify(ref)} is not a builtin tool; expected one of: ${BUILTIN_TOOL_NAMES.join(", ")}`);
|
|
1426
|
+
}
|
|
1427
|
+
enabled.add(ref);
|
|
1428
|
+
}
|
|
1429
|
+
return BUILTIN_TOOL_NAMES.filter((name) => enabled.has(name));
|
|
1430
|
+
}
|
|
1431
|
+
/** Validate the optional `includeBuiltinTools` flag (default `true`). */
|
|
1432
|
+
function parseIncludeBuiltinTools(input) {
|
|
1377
1433
|
if (input === undefined || input === null)
|
|
1378
1434
|
return undefined;
|
|
1379
|
-
if (
|
|
1380
|
-
throw new Error("submission.
|
|
1381
|
-
}
|
|
1382
|
-
if (input.length > MAX_BUILTINS) {
|
|
1383
|
-
throw new Error(`submission.builtins exceeds the max of ${MAX_BUILTINS} entries`);
|
|
1384
|
-
}
|
|
1385
|
-
const seen = new Set();
|
|
1386
|
-
const out = [];
|
|
1387
|
-
for (let i = 0; i < input.length; i++) {
|
|
1388
|
-
const v = input[i];
|
|
1389
|
-
if (typeof v !== "string") {
|
|
1390
|
-
throw new Error(`submission.builtins[${i}] must be a string`);
|
|
1391
|
-
}
|
|
1392
|
-
if (!BUILTINS.includes(v)) {
|
|
1393
|
-
throw new Error(`submission.builtins[${i}] (${JSON.stringify(v)}) is not a managed-runtime builtin; ` +
|
|
1394
|
-
`expected one of: ${BUILTINS.join(", ")}`);
|
|
1395
|
-
}
|
|
1396
|
-
if (seen.has(v))
|
|
1397
|
-
continue; // dedupe silently
|
|
1398
|
-
seen.add(v);
|
|
1399
|
-
out.push(v);
|
|
1435
|
+
if (typeof input !== "boolean") {
|
|
1436
|
+
throw new Error("submission.includeBuiltinTools must be a boolean");
|
|
1400
1437
|
}
|
|
1401
|
-
return
|
|
1438
|
+
return input;
|
|
1402
1439
|
}
|
|
1403
1440
|
/**
|
|
1404
1441
|
* Maximum number of output capture entries accepted per list.
|
|
@@ -1626,17 +1663,35 @@ function parseSkills(input) {
|
|
|
1626
1663
|
return ref;
|
|
1627
1664
|
});
|
|
1628
1665
|
}
|
|
1666
|
+
/**
|
|
1667
|
+
* Parse the `submission.tools` union: each entry is either a BARE STRING (a
|
|
1668
|
+
* builtin tool reference, validated against {@link BUILTIN_TOOL_NAMES}) or a
|
|
1669
|
+
* custom tool bundle OBJECT ({@link ToolRef}). Returns the two groups split:
|
|
1670
|
+
* `tools` (custom bundles, the existing downstream shape) and `builtinTools`
|
|
1671
|
+
* (the deduped builtin-name references, in {@link BUILTIN_TOOL_NAMES} order).
|
|
1672
|
+
*/
|
|
1629
1673
|
function parseTools(input) {
|
|
1630
1674
|
if (input === undefined) {
|
|
1631
|
-
return [];
|
|
1675
|
+
return { tools: [], builtinTools: [] };
|
|
1632
1676
|
}
|
|
1633
1677
|
if (!Array.isArray(input)) {
|
|
1634
|
-
throw new Error("submission.tools must be an array of ToolRef objects");
|
|
1678
|
+
throw new Error("submission.tools must be an array of builtin tool names or ToolRef objects");
|
|
1635
1679
|
}
|
|
1636
1680
|
const seenNames = new Set();
|
|
1637
1681
|
const seenAssetIds = new Set();
|
|
1638
|
-
|
|
1682
|
+
const seenBuiltins = new Set();
|
|
1683
|
+
const tools = [];
|
|
1684
|
+
input.forEach((item, index) => {
|
|
1639
1685
|
const path = `submission.tools[${index}]`;
|
|
1686
|
+
// A bare string is a builtin tool reference (e.g. BuiltinTools.notebook_edit).
|
|
1687
|
+
if (typeof item === "string") {
|
|
1688
|
+
if (!BUILTIN_TOOL_NAMES.includes(item)) {
|
|
1689
|
+
throw new Error(`${path} (${JSON.stringify(item)}) is not a builtin tool name; ` +
|
|
1690
|
+
`expected one of: ${BUILTIN_TOOL_NAMES.join(", ")}`);
|
|
1691
|
+
}
|
|
1692
|
+
seenBuiltins.add(item);
|
|
1693
|
+
return;
|
|
1694
|
+
}
|
|
1640
1695
|
const raw = requireRecord(item, path);
|
|
1641
1696
|
for (const key of Object.keys(raw)) {
|
|
1642
1697
|
if (key !== "kind" &&
|
|
@@ -1678,15 +1733,17 @@ function parseTools(input) {
|
|
|
1678
1733
|
throw new Error(`${path}.input_schema.type must be "object"`);
|
|
1679
1734
|
}
|
|
1680
1735
|
const entry = normaliseSkillBundlePath(requireString(raw.entry, `${path}.entry`));
|
|
1681
|
-
|
|
1736
|
+
tools.push({
|
|
1682
1737
|
kind: "asset",
|
|
1683
1738
|
assetId: fields.assetId,
|
|
1684
1739
|
name: fields.name,
|
|
1685
1740
|
description,
|
|
1686
1741
|
input_schema: inputSchema,
|
|
1687
1742
|
entry
|
|
1688
|
-
};
|
|
1743
|
+
});
|
|
1689
1744
|
});
|
|
1745
|
+
const builtinTools = BUILTIN_TOOL_NAMES.filter((name) => seenBuiltins.has(name));
|
|
1746
|
+
return { tools, builtinTools };
|
|
1690
1747
|
}
|
|
1691
1748
|
function parseAgentsMd(input) {
|
|
1692
1749
|
if (input === undefined)
|
package/dist/cli.mjs
CHANGED
|
@@ -798,6 +798,28 @@ function parseRunRegion(input) {
|
|
|
798
798
|
}
|
|
799
799
|
return input;
|
|
800
800
|
}
|
|
801
|
+
var BUILTIN_TOOL_NAMES = [
|
|
802
|
+
"bash",
|
|
803
|
+
"read_file",
|
|
804
|
+
"write_file",
|
|
805
|
+
"edit_file",
|
|
806
|
+
"grep",
|
|
807
|
+
"glob",
|
|
808
|
+
"head",
|
|
809
|
+
"tail",
|
|
810
|
+
"todo_write",
|
|
811
|
+
"subagent",
|
|
812
|
+
"subagent_result",
|
|
813
|
+
"web_fetch",
|
|
814
|
+
"web_search",
|
|
815
|
+
"notebook_edit",
|
|
816
|
+
"bash_output",
|
|
817
|
+
"bash_kill",
|
|
818
|
+
"code_execution",
|
|
819
|
+
"wait",
|
|
820
|
+
"git"
|
|
821
|
+
];
|
|
822
|
+
var DEFAULT_BUILTIN_TOOLS = BUILTIN_TOOL_NAMES.filter((name) => name !== "notebook_edit");
|
|
801
823
|
var MAX_OUTPUT_CAPTURE_TIMEOUT_MS = 6 * 60 * 60 * 1e3;
|
|
802
824
|
|
|
803
825
|
// ../contracts/dist/connection-ticket.js
|
|
@@ -950,7 +972,7 @@ function highEntropyShannonBits(value) {
|
|
|
950
972
|
return bits;
|
|
951
973
|
}
|
|
952
974
|
function isForbiddenCustodyFieldName(key) {
|
|
953
|
-
return /^(apiKey|secretValue|bearerHash|signedUrl|objectStoreKey|objectKey|vaultId|providerResponseBody|responseBody|privateResourceHandle|resourceHandle|rawBody)$/i.test(key);
|
|
975
|
+
return /^(apiKey|apiKeys|secretValue|bearerHash|signedUrl|objectStoreKey|objectKey|vaultId|providerResponseBody|responseBody|privateResourceHandle|resourceHandle|rawBody)$/i.test(key);
|
|
954
976
|
}
|
|
955
977
|
|
|
956
978
|
// ../contracts/dist/run-record.js
|
|
@@ -1376,6 +1398,8 @@ function extractErrorMessage(body) {
|
|
|
1376
1398
|
// ../contracts/dist/operations.js
|
|
1377
1399
|
var operations_exports = {};
|
|
1378
1400
|
__export(operations_exports, {
|
|
1401
|
+
READ_OUTPUT_TEXT_DEFAULT_BYTES: () => READ_OUTPUT_TEXT_DEFAULT_BYTES,
|
|
1402
|
+
READ_OUTPUT_TEXT_MAX_BYTES: () => READ_OUTPUT_TEXT_MAX_BYTES,
|
|
1379
1403
|
cancelRun: () => cancelRun,
|
|
1380
1404
|
classifyOutput: () => classifyOutput,
|
|
1381
1405
|
createAgentsMd: () => createAgentsMd,
|
|
@@ -1414,10 +1438,12 @@ __export(operations_exports, {
|
|
|
1414
1438
|
listFiles: () => listFiles,
|
|
1415
1439
|
listOutputs: () => listOutputs,
|
|
1416
1440
|
listRunEvents: () => listRunEvents,
|
|
1441
|
+
listRuns: () => listRuns,
|
|
1417
1442
|
listSecrets: () => listSecrets,
|
|
1418
1443
|
listSkills: () => listSkills,
|
|
1419
1444
|
normalizeOutputLinkExpiresIn: () => normalizeOutputLinkExpiresIn,
|
|
1420
1445
|
outputLink: () => outputLink,
|
|
1446
|
+
readOutputText: () => readOutputText,
|
|
1421
1447
|
redeliverRunWebhook: () => redeliverRunWebhook,
|
|
1422
1448
|
resolveOutputFileSelector: () => resolveOutputFileSelector,
|
|
1423
1449
|
rotateSecret: () => rotateSecret,
|
|
@@ -2151,6 +2177,18 @@ async function getRun(http, runId) {
|
|
|
2151
2177
|
async function getRunUnit(http, runId) {
|
|
2152
2178
|
return http.request(`/api/runs/${encodeURIComponent(runId)}`);
|
|
2153
2179
|
}
|
|
2180
|
+
async function listRuns(http, query) {
|
|
2181
|
+
const params = {};
|
|
2182
|
+
if (query?.status !== void 0)
|
|
2183
|
+
params.status = query.status;
|
|
2184
|
+
if (query?.since !== void 0)
|
|
2185
|
+
params.since = query.since;
|
|
2186
|
+
if (query?.limit !== void 0)
|
|
2187
|
+
params.limit = String(query.limit);
|
|
2188
|
+
if (query?.cursor !== void 0)
|
|
2189
|
+
params.cursor = query.cursor;
|
|
2190
|
+
return http.request("/api/runs", {}, params);
|
|
2191
|
+
}
|
|
2154
2192
|
var LIST_EVENTS_PAGE_BUDGET = 1e3;
|
|
2155
2193
|
async function listRunEvents(http, runId) {
|
|
2156
2194
|
const path = `/api/runs/${encodeURIComponent(runId)}/events`;
|
|
@@ -2249,6 +2287,74 @@ async function downloadOutput(http, runId, selector) {
|
|
|
2249
2287
|
const { response } = await http.download(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(output.id)}/download`);
|
|
2250
2288
|
return { output, bytes: new Uint8Array(await response.arrayBuffer()) };
|
|
2251
2289
|
}
|
|
2290
|
+
var READ_OUTPUT_TEXT_MAX_BYTES = 1e7;
|
|
2291
|
+
var READ_OUTPUT_TEXT_DEFAULT_BYTES = 5e4;
|
|
2292
|
+
async function readOutputText(http, runId, selector, options) {
|
|
2293
|
+
const maxBytes = Math.max(1, Math.min(options?.maxBytes ?? READ_OUTPUT_TEXT_DEFAULT_BYTES, READ_OUTPUT_TEXT_MAX_BYTES));
|
|
2294
|
+
const output = isPathSelector(selector) ? resolveOutputFileSelector(await listOutputs(http, runId), selector, runId) : resolveOutputFileSelector([], selector, runId);
|
|
2295
|
+
const { response } = await http.download(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(output.id)}/download`);
|
|
2296
|
+
const capped = await readCappedText(response, maxBytes);
|
|
2297
|
+
const text = options?.grep === void 0 ? capped.text : grepLines(capped.text, options.grep);
|
|
2298
|
+
return { output, text, truncated: capped.truncated, totalBytes: capped.totalBytes };
|
|
2299
|
+
}
|
|
2300
|
+
async function readCappedText(response, maxBytes) {
|
|
2301
|
+
const declaredRaw = response.headers.get("content-length");
|
|
2302
|
+
const declared = declaredRaw !== null && /^\d+$/.test(declaredRaw) ? Number(declaredRaw) : void 0;
|
|
2303
|
+
const decoder = new TextDecoder("utf-8");
|
|
2304
|
+
const body = response.body;
|
|
2305
|
+
if (!body) {
|
|
2306
|
+
const buf = new Uint8Array(await response.arrayBuffer());
|
|
2307
|
+
const total = declared ?? buf.byteLength;
|
|
2308
|
+
return {
|
|
2309
|
+
text: decoder.decode(buf.subarray(0, maxBytes)),
|
|
2310
|
+
truncated: buf.byteLength > maxBytes,
|
|
2311
|
+
totalBytes: total
|
|
2312
|
+
};
|
|
2313
|
+
}
|
|
2314
|
+
const reader = body.getReader();
|
|
2315
|
+
const chunks = [];
|
|
2316
|
+
let read = 0;
|
|
2317
|
+
let sawMore = false;
|
|
2318
|
+
try {
|
|
2319
|
+
while (read < maxBytes) {
|
|
2320
|
+
const { done, value } = await reader.read();
|
|
2321
|
+
if (done)
|
|
2322
|
+
break;
|
|
2323
|
+
if (value && value.byteLength > 0) {
|
|
2324
|
+
read += value.byteLength;
|
|
2325
|
+
chunks.push(value);
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
if (read >= maxBytes) {
|
|
2329
|
+
const next = await reader.read();
|
|
2330
|
+
if (!next.done && next.value && next.value.byteLength > 0)
|
|
2331
|
+
sawMore = true;
|
|
2332
|
+
}
|
|
2333
|
+
} finally {
|
|
2334
|
+
await reader.cancel().catch(() => {
|
|
2335
|
+
});
|
|
2336
|
+
}
|
|
2337
|
+
const merged = concatBytes(chunks).subarray(0, maxBytes);
|
|
2338
|
+
const truncated = declared !== void 0 ? declared > maxBytes : sawMore;
|
|
2339
|
+
const totalBytes = declared ?? read;
|
|
2340
|
+
return { text: decoder.decode(merged), truncated, totalBytes };
|
|
2341
|
+
}
|
|
2342
|
+
function concatBytes(chunks) {
|
|
2343
|
+
if (chunks.length === 1)
|
|
2344
|
+
return chunks[0];
|
|
2345
|
+
const total = chunks.reduce((n, c) => n + c.byteLength, 0);
|
|
2346
|
+
const out = new Uint8Array(total);
|
|
2347
|
+
let offset = 0;
|
|
2348
|
+
for (const c of chunks) {
|
|
2349
|
+
out.set(c, offset);
|
|
2350
|
+
offset += c.byteLength;
|
|
2351
|
+
}
|
|
2352
|
+
return out;
|
|
2353
|
+
}
|
|
2354
|
+
function grepLines(text, pattern) {
|
|
2355
|
+
const test = typeof pattern === "string" ? (line) => line.toLowerCase().includes(pattern.toLowerCase()) : (line) => pattern.test(line);
|
|
2356
|
+
return text.split("\n").filter((line) => test(line)).join("\n");
|
|
2357
|
+
}
|
|
2252
2358
|
async function cancelRun(http, runId) {
|
|
2253
2359
|
await http.request(`/api/runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" });
|
|
2254
2360
|
}
|
|
@@ -3408,15 +3514,6 @@ async function runRunCmd(io2, argv) {
|
|
|
3408
3514
|
`);
|
|
3409
3515
|
return USAGE_ERR;
|
|
3410
3516
|
}
|
|
3411
|
-
for (const p of RUN_PROVIDERS) {
|
|
3412
|
-
if (p === provider)
|
|
3413
|
-
continue;
|
|
3414
|
-
if (providerKeyValues[p] !== void 0) {
|
|
3415
|
-
io2.stderr(`--${p}-api-key is not allowed when --provider is ${provider}
|
|
3416
|
-
`);
|
|
3417
|
-
return USAGE_ERR;
|
|
3418
|
-
}
|
|
3419
|
-
}
|
|
3420
3517
|
const runtimeFlag = takeFlagValue(rest, "--runtime");
|
|
3421
3518
|
if (runtimeFlag.error) {
|
|
3422
3519
|
io2.stderr(`${runtimeFlag.error}
|
|
@@ -3720,8 +3817,10 @@ async function runRunCmd(io2, argv) {
|
|
|
3720
3817
|
...runConfig.environment ? { environment: runConfig.environment } : {},
|
|
3721
3818
|
...runConfig.metadata ? { metadata: runConfig.metadata } : {}
|
|
3722
3819
|
};
|
|
3820
|
+
const hasAdditionalProviderKeys = Object.keys(providerKeyValues).some((p) => p !== provider);
|
|
3723
3821
|
const secrets = {
|
|
3724
3822
|
apiKey: providerKeyValues[provider],
|
|
3823
|
+
...hasAdditionalProviderKeys ? { apiKeys: providerKeyValues } : {},
|
|
3725
3824
|
...mcpServerSecrets.length > 0 ? { mcpServers: mcpServerSecrets } : {},
|
|
3726
3825
|
...proxyAuth.length > 0 ? { proxyEndpointAuth: proxyAuth } : {}
|
|
3727
3826
|
};
|
package/dist/cli.mjs.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
0386d2625bfa4f8aea426cffc3bf21546c48b33b7134eb7cd4bbfefdc2d69d96 cli.mjs
|