@runtypelabs/sdk 4.9.0 → 4.10.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/index.cjs +1202 -303
- package/dist/index.d.cts +1626 -20
- package/dist/index.d.ts +1626 -20
- package/dist/index.mjs +1117 -242
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,24 +1,4 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __esm = (fn, res) => function __init() {
|
|
4
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
-
};
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
|
|
11
1
|
// src/stream-utils.ts
|
|
12
|
-
var stream_utils_exports = {};
|
|
13
|
-
__export(stream_utils_exports, {
|
|
14
|
-
flowErrorMessage: () => flowErrorMessage,
|
|
15
|
-
parseFinalBuffer: () => parseFinalBuffer,
|
|
16
|
-
parseSSEChunk: () => parseSSEChunk,
|
|
17
|
-
processStream: () => processStream,
|
|
18
|
-
stepDeltaText: () => stepDeltaText,
|
|
19
|
-
stepDisplayName: () => stepDisplayName,
|
|
20
|
-
streamEvents: () => streamEvents
|
|
21
|
-
});
|
|
22
2
|
function parseSSEChunk(chunk, buffer) {
|
|
23
3
|
buffer += chunk;
|
|
24
4
|
const lines = buffer.split("\n");
|
|
@@ -268,14 +248,8 @@ async function* streamEvents(response) {
|
|
|
268
248
|
reader.releaseLock();
|
|
269
249
|
}
|
|
270
250
|
}
|
|
271
|
-
var init_stream_utils = __esm({
|
|
272
|
-
"src/stream-utils.ts"() {
|
|
273
|
-
"use strict";
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
251
|
|
|
277
252
|
// src/flow-result.ts
|
|
278
|
-
init_stream_utils();
|
|
279
253
|
var FlowResult = class {
|
|
280
254
|
constructor(response, summary) {
|
|
281
255
|
this.consumed = false;
|
|
@@ -411,7 +385,6 @@ var FlowResult = class {
|
|
|
411
385
|
};
|
|
412
386
|
|
|
413
387
|
// src/flow-builder.ts
|
|
414
|
-
init_stream_utils();
|
|
415
388
|
async function validateInlineFlow(client, args, savedFlowHint) {
|
|
416
389
|
if (args.existingFlowId) {
|
|
417
390
|
throw new Error(
|
|
@@ -1121,20 +1094,20 @@ var FlowBuilder = class {
|
|
|
1121
1094
|
*/
|
|
1122
1095
|
build() {
|
|
1123
1096
|
const flow = this.existingFlowId ? { id: this.existingFlowId } : { name: this.flowConfig.name, steps: this.steps };
|
|
1124
|
-
const
|
|
1097
|
+
const request2 = { flow };
|
|
1125
1098
|
if (this.recordConfig) {
|
|
1126
|
-
|
|
1099
|
+
request2.record = this.recordConfig;
|
|
1127
1100
|
}
|
|
1128
1101
|
if (this.messagesConfig) {
|
|
1129
|
-
|
|
1102
|
+
request2.messages = this.messagesConfig;
|
|
1130
1103
|
}
|
|
1131
1104
|
if (this.inputsConfig) {
|
|
1132
|
-
|
|
1105
|
+
request2.inputs = this.inputsConfig;
|
|
1133
1106
|
}
|
|
1134
1107
|
if (Object.keys(this.optionsConfig).length > 0) {
|
|
1135
|
-
|
|
1108
|
+
request2.options = this.optionsConfig;
|
|
1136
1109
|
}
|
|
1137
|
-
return
|
|
1110
|
+
return request2;
|
|
1138
1111
|
}
|
|
1139
1112
|
/**
|
|
1140
1113
|
* Validate this prospective flow against the public validation endpoint
|
|
@@ -1371,22 +1344,22 @@ function resolveBatchExecutionId(pausedTools) {
|
|
|
1371
1344
|
return "";
|
|
1372
1345
|
}
|
|
1373
1346
|
|
|
1374
|
-
// src/flows-
|
|
1375
|
-
function
|
|
1347
|
+
// src/flows-ensure.ts
|
|
1348
|
+
function isPlainObject(value) {
|
|
1376
1349
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1377
1350
|
}
|
|
1378
|
-
function
|
|
1379
|
-
if (!
|
|
1351
|
+
function normalizeConfigForHash(config) {
|
|
1352
|
+
if (!isPlainObject(config)) return {};
|
|
1380
1353
|
const normalized = {};
|
|
1381
1354
|
for (const key of Object.keys(config).sort()) {
|
|
1382
1355
|
const value = config[key];
|
|
1383
1356
|
if (value === void 0) continue;
|
|
1384
1357
|
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
1385
|
-
normalized[key] =
|
|
1358
|
+
normalized[key] = normalizeConfigForHash(value);
|
|
1386
1359
|
} else if (Array.isArray(value)) {
|
|
1387
1360
|
normalized[key] = value.map((item) => {
|
|
1388
1361
|
if (item !== null && typeof item === "object" && !Array.isArray(item)) {
|
|
1389
|
-
return
|
|
1362
|
+
return normalizeConfigForHash(item);
|
|
1390
1363
|
}
|
|
1391
1364
|
return item;
|
|
1392
1365
|
});
|
|
@@ -1397,28 +1370,249 @@ function normalizeConfig(config) {
|
|
|
1397
1370
|
return normalized;
|
|
1398
1371
|
}
|
|
1399
1372
|
function normalizeStepForHash(step) {
|
|
1400
|
-
const stepObj =
|
|
1373
|
+
const stepObj = isPlainObject(step) ? step : {};
|
|
1401
1374
|
return {
|
|
1402
1375
|
type: typeof stepObj.type === "string" ? stepObj.type : "",
|
|
1403
1376
|
name: typeof stepObj.name === "string" ? stepObj.name : "",
|
|
1404
1377
|
enabled: stepObj.enabled !== false,
|
|
1405
1378
|
...typeof stepObj.when === "string" ? { when: stepObj.when } : {},
|
|
1406
|
-
config:
|
|
1379
|
+
config: normalizeConfigForHash(stepObj.config),
|
|
1407
1380
|
order: typeof stepObj.order === "number" ? stepObj.order : 0
|
|
1408
1381
|
};
|
|
1409
1382
|
}
|
|
1410
1383
|
async function computeFlowContentHash(steps) {
|
|
1411
1384
|
const normalized = [...steps].sort((a, b) => {
|
|
1412
|
-
const orderA =
|
|
1413
|
-
const orderB =
|
|
1385
|
+
const orderA = isPlainObject(a) && typeof a.order === "number" ? a.order : 0;
|
|
1386
|
+
const orderB = isPlainObject(b) && typeof b.order === "number" ? b.order : 0;
|
|
1414
1387
|
return orderA - orderB;
|
|
1415
1388
|
}).map(normalizeStepForHash);
|
|
1416
1389
|
const serialized = JSON.stringify(normalized);
|
|
1417
1390
|
const encoded = new TextEncoder().encode(serialized);
|
|
1418
1391
|
const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
|
|
1419
|
-
|
|
1420
|
-
|
|
1392
|
+
return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1393
|
+
}
|
|
1394
|
+
var DEFINE_FLOW_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set(["name", "steps"]);
|
|
1395
|
+
var DEFINE_FLOW_STEP_KEYS = /* @__PURE__ */ new Set([
|
|
1396
|
+
"type",
|
|
1397
|
+
"name",
|
|
1398
|
+
"order",
|
|
1399
|
+
"enabled",
|
|
1400
|
+
"when",
|
|
1401
|
+
"config"
|
|
1402
|
+
]);
|
|
1403
|
+
function collectStepNonPortableToolRefs(config, path) {
|
|
1404
|
+
const found = [];
|
|
1405
|
+
const tools = config.tools;
|
|
1406
|
+
const isAccountScoped = (ref) => typeof ref === "string" && ref.startsWith("tool_");
|
|
1407
|
+
const scanArray = (value, subPath) => {
|
|
1408
|
+
if (!Array.isArray(value)) return;
|
|
1409
|
+
value.forEach((ref, i) => {
|
|
1410
|
+
if (isAccountScoped(ref)) found.push(`${subPath}[${i}]`);
|
|
1411
|
+
});
|
|
1412
|
+
};
|
|
1413
|
+
const scanKeys = (value, subPath) => {
|
|
1414
|
+
if (!isPlainObject(value)) return;
|
|
1415
|
+
for (const key of Object.keys(value)) {
|
|
1416
|
+
if (isAccountScoped(key)) found.push(`${subPath}.${key}`);
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
if (isPlainObject(tools)) {
|
|
1420
|
+
scanArray(tools.toolIds, `${path}.tools.toolIds`);
|
|
1421
|
+
scanKeys(tools.toolConfigs, `${path}.tools.toolConfigs`);
|
|
1422
|
+
scanKeys(tools.perToolLimits, `${path}.tools.perToolLimits`);
|
|
1423
|
+
if (isPlainObject(tools.approval)) {
|
|
1424
|
+
scanArray(tools.approval.require, `${path}.tools.approval.require`);
|
|
1425
|
+
}
|
|
1426
|
+
if (isPlainObject(tools.subagentConfig)) {
|
|
1427
|
+
scanArray(tools.subagentConfig.toolPool, `${path}.tools.subagentConfig.toolPool`);
|
|
1428
|
+
}
|
|
1429
|
+
if (isPlainObject(tools.codeModeConfig)) {
|
|
1430
|
+
scanArray(tools.codeModeConfig.toolPool, `${path}.tools.codeModeConfig.toolPool`);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
for (const branch of ["trueSteps", "falseSteps"]) {
|
|
1434
|
+
const nested = config[branch];
|
|
1435
|
+
if (!Array.isArray(nested)) continue;
|
|
1436
|
+
nested.forEach((nestedStep, i) => {
|
|
1437
|
+
if (isPlainObject(nestedStep) && isPlainObject(nestedStep.config)) {
|
|
1438
|
+
found.push(
|
|
1439
|
+
...collectStepNonPortableToolRefs(
|
|
1440
|
+
nestedStep.config,
|
|
1441
|
+
`${path}.${branch}[${i}].config`
|
|
1442
|
+
)
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
return found;
|
|
1448
|
+
}
|
|
1449
|
+
function defineFlow(input) {
|
|
1450
|
+
if (!input || typeof input !== "object") {
|
|
1451
|
+
throw new Error("defineFlow requires a definition object");
|
|
1452
|
+
}
|
|
1453
|
+
if (typeof input.name !== "string" || input.name.length === 0) {
|
|
1454
|
+
throw new Error('defineFlow requires a non-empty string "name"');
|
|
1455
|
+
}
|
|
1456
|
+
const unknownKeys = Object.keys(input).filter((key) => !DEFINE_FLOW_TOP_LEVEL_KEYS.has(key));
|
|
1457
|
+
if (unknownKeys.length > 0) {
|
|
1458
|
+
throw new Error(
|
|
1459
|
+
`defineFlow: unknown field(s): ${unknownKeys.join(", ")}. Allowed fields are name and steps. (Description is not part of the v1 ensure surface.)`
|
|
1460
|
+
);
|
|
1461
|
+
}
|
|
1462
|
+
if (!Array.isArray(input.steps) || input.steps.length === 0) {
|
|
1463
|
+
throw new Error('defineFlow requires a non-empty "steps" array');
|
|
1464
|
+
}
|
|
1465
|
+
const steps = input.steps.map((step, index) => {
|
|
1466
|
+
if (!isPlainObject(step)) {
|
|
1467
|
+
throw new Error(`defineFlow: steps[${index}] must be an object`);
|
|
1468
|
+
}
|
|
1469
|
+
if (typeof step.type !== "string" || step.type.length === 0) {
|
|
1470
|
+
throw new Error(`defineFlow: steps[${index}] requires a non-empty string "type"`);
|
|
1471
|
+
}
|
|
1472
|
+
if (typeof step.name !== "string" || step.name.length === 0) {
|
|
1473
|
+
throw new Error(`defineFlow: steps[${index}] requires a non-empty string "name"`);
|
|
1474
|
+
}
|
|
1475
|
+
const unknownStepKeys = Object.keys(step).filter((key) => !DEFINE_FLOW_STEP_KEYS.has(key));
|
|
1476
|
+
if (unknownStepKeys.length > 0) {
|
|
1477
|
+
throw new Error(
|
|
1478
|
+
`defineFlow: steps[${index}] has unknown field(s): ${unknownStepKeys.join(", ")}. Allowed step fields are type, name, order, enabled, when, config. (Step ids are server artifacts and not part of a portable definition.)`
|
|
1479
|
+
);
|
|
1480
|
+
}
|
|
1481
|
+
const config = isPlainObject(step.config) ? step.config : void 0;
|
|
1482
|
+
if (config) {
|
|
1483
|
+
const nonPortable = collectStepNonPortableToolRefs(config, `steps[${index}].config`);
|
|
1484
|
+
if (nonPortable.length > 0) {
|
|
1485
|
+
throw new Error(
|
|
1486
|
+
`defineFlow: account-scoped tool reference(s) at ${nonPortable.join(", ")}. Definitions must be environment-portable \u2014 tool_\u2026 IDs belong to one account/environment. Use builtin:/platform:/mcp: references instead. Name-based resolution of saved tools is a planned follow-up.`
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
return {
|
|
1491
|
+
type: step.type,
|
|
1492
|
+
name: step.name,
|
|
1493
|
+
// Explicit 1-based order (the flow builder's convention) so the local
|
|
1494
|
+
// probe hash agrees with the server's persisted step order.
|
|
1495
|
+
order: typeof step.order === "number" ? step.order : index + 1,
|
|
1496
|
+
...step.enabled !== void 0 ? { enabled: step.enabled } : {},
|
|
1497
|
+
...typeof step.when === "string" ? { when: step.when } : {},
|
|
1498
|
+
...config ? { config } : {}
|
|
1499
|
+
};
|
|
1500
|
+
});
|
|
1501
|
+
return { name: input.name, steps };
|
|
1502
|
+
}
|
|
1503
|
+
var FlowEnsureConflictError = class extends Error {
|
|
1504
|
+
constructor(body) {
|
|
1505
|
+
super(body.error ?? `Flow ensure conflict: ${body.code}`);
|
|
1506
|
+
this.name = "FlowEnsureConflictError";
|
|
1507
|
+
this.code = body.code;
|
|
1508
|
+
this.lastModifiedSource = body.lastModifiedSource;
|
|
1509
|
+
this.modifiedAt = body.modifiedAt;
|
|
1510
|
+
this.currentHash = body.currentHash;
|
|
1511
|
+
}
|
|
1512
|
+
};
|
|
1513
|
+
var FlowDriftError = class extends Error {
|
|
1514
|
+
constructor(plan) {
|
|
1515
|
+
super(
|
|
1516
|
+
`Flow "${plan.flowId ?? "definition"}" drifted: plan is '${plan.changes}' (changed: ${plan.changedKeys.join(", ") || "n/a"}). Run client.flows.pull(name) to absorb the remote edit into your repo, or re-run ensure to converge.`
|
|
1517
|
+
);
|
|
1518
|
+
this.name = "FlowDriftError";
|
|
1519
|
+
this.plan = plan;
|
|
1520
|
+
}
|
|
1521
|
+
};
|
|
1522
|
+
function parseRequestError(err) {
|
|
1523
|
+
if (!(err instanceof Error)) return { status: null, body: null };
|
|
1524
|
+
const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
|
|
1525
|
+
if (!match) return { status: null, body: null };
|
|
1526
|
+
try {
|
|
1527
|
+
return { status: Number(match[1]), body: JSON.parse(match[2]) };
|
|
1528
|
+
} catch {
|
|
1529
|
+
return { status: Number(match[1]), body: null };
|
|
1530
|
+
}
|
|
1421
1531
|
}
|
|
1532
|
+
function toConflictError(err) {
|
|
1533
|
+
const { status, body } = parseRequestError(err);
|
|
1534
|
+
if (status !== 409 || !isPlainObject(body)) return null;
|
|
1535
|
+
const code = body.code;
|
|
1536
|
+
if (code !== "external_modification" && code !== "remote_changed") return null;
|
|
1537
|
+
return new FlowEnsureConflictError(
|
|
1538
|
+
body
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
1541
|
+
var serverHashMemo = /* @__PURE__ */ new WeakMap();
|
|
1542
|
+
function memoFor(client) {
|
|
1543
|
+
let memo = serverHashMemo.get(client);
|
|
1544
|
+
if (!memo) {
|
|
1545
|
+
memo = /* @__PURE__ */ new Map();
|
|
1546
|
+
serverHashMemo.set(client, memo);
|
|
1547
|
+
}
|
|
1548
|
+
return memo;
|
|
1549
|
+
}
|
|
1550
|
+
function memoize(memo, memoKey, result) {
|
|
1551
|
+
if (result.result !== "plan") memo.set(memoKey, result.contentHash);
|
|
1552
|
+
}
|
|
1553
|
+
async function request(client, body) {
|
|
1554
|
+
try {
|
|
1555
|
+
return await client.post(
|
|
1556
|
+
"/flows/ensure",
|
|
1557
|
+
body
|
|
1558
|
+
);
|
|
1559
|
+
} catch (err) {
|
|
1560
|
+
const conflict = toConflictError(err);
|
|
1561
|
+
if (conflict) throw conflict;
|
|
1562
|
+
throw err;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
async function ensureFlow(client, definition, options = {}) {
|
|
1566
|
+
const { dryRun, onConflict, release, expectedRemoteHash, expectNoChanges } = options;
|
|
1567
|
+
const passthrough = {
|
|
1568
|
+
...onConflict ? { onConflict } : {},
|
|
1569
|
+
...release ? { release } : {},
|
|
1570
|
+
...expectedRemoteHash ? { expectedRemoteHash } : {}
|
|
1571
|
+
};
|
|
1572
|
+
if (dryRun || expectNoChanges) {
|
|
1573
|
+
const plan = await request(client, {
|
|
1574
|
+
name: definition.name,
|
|
1575
|
+
definition,
|
|
1576
|
+
dryRun: true,
|
|
1577
|
+
...passthrough
|
|
1578
|
+
});
|
|
1579
|
+
if (plan.result !== "plan") {
|
|
1580
|
+
throw new Error(`Expected a plan result from dryRun, got '${plan.result}'`);
|
|
1581
|
+
}
|
|
1582
|
+
if (expectNoChanges && plan.changes !== "none") {
|
|
1583
|
+
throw new FlowDriftError(plan);
|
|
1584
|
+
}
|
|
1585
|
+
return plan;
|
|
1586
|
+
}
|
|
1587
|
+
const memo = memoFor(client);
|
|
1588
|
+
const localHash = await computeFlowContentHash(definition.steps);
|
|
1589
|
+
const memoKey = `${definition.name} ${localHash}`;
|
|
1590
|
+
const contentHash = memo.get(memoKey) ?? localHash;
|
|
1591
|
+
const probe = await request(client, {
|
|
1592
|
+
name: definition.name,
|
|
1593
|
+
contentHash,
|
|
1594
|
+
...passthrough
|
|
1595
|
+
});
|
|
1596
|
+
if (probe.result !== "definitionRequired") {
|
|
1597
|
+
memoize(memo, memoKey, probe);
|
|
1598
|
+
return probe;
|
|
1599
|
+
}
|
|
1600
|
+
const converged = await request(client, {
|
|
1601
|
+
name: definition.name,
|
|
1602
|
+
definition,
|
|
1603
|
+
...passthrough
|
|
1604
|
+
});
|
|
1605
|
+
if (converged.result === "definitionRequired") {
|
|
1606
|
+
throw new Error("Server reported definitionRequired for a full-definition request");
|
|
1607
|
+
}
|
|
1608
|
+
memoize(memo, memoKey, converged);
|
|
1609
|
+
return converged;
|
|
1610
|
+
}
|
|
1611
|
+
async function pullFlow(client, name) {
|
|
1612
|
+
return client.get("/flows/pull", { name });
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
// src/flows-namespace.ts
|
|
1422
1616
|
var FlowsNamespace = class {
|
|
1423
1617
|
constructor(getClient) {
|
|
1424
1618
|
this.getClient = getClient;
|
|
@@ -1426,8 +1620,11 @@ var FlowsNamespace = class {
|
|
|
1426
1620
|
/**
|
|
1427
1621
|
* Create or update a flow by name (upsert mode)
|
|
1428
1622
|
*
|
|
1429
|
-
* The recommended pattern for code-first flow management
|
|
1430
|
-
*
|
|
1623
|
+
* The recommended pattern for code-first flow management when you want to
|
|
1624
|
+
* save AND run in one dispatch. For a deploy-time, non-executing converge
|
|
1625
|
+
* (CI/CD config-as-code), use {@link ensure} instead — upsert and ensure
|
|
1626
|
+
* are siblings, not versions of each other: upsert is the runtime verb
|
|
1627
|
+
* (save-and-run), ensure is the deploy verb (converge only).
|
|
1431
1628
|
*
|
|
1432
1629
|
* @example
|
|
1433
1630
|
* ```typescript
|
|
@@ -1442,6 +1639,33 @@ var FlowsNamespace = class {
|
|
|
1442
1639
|
upsert(config) {
|
|
1443
1640
|
return new RuntypeFlowBuilder(this.getClient, "upsert", config);
|
|
1444
1641
|
}
|
|
1642
|
+
/**
|
|
1643
|
+
* Idempotently converge a `defineFlow` definition onto the platform —
|
|
1644
|
+
* the deploy-time, non-executing sibling of {@link upsert}. Hash-first:
|
|
1645
|
+
* the steady state is one tiny probe request. Creates an immutable version
|
|
1646
|
+
* snapshot on every change; never deletes; never executes the flow.
|
|
1647
|
+
*
|
|
1648
|
+
* @example
|
|
1649
|
+
* ```typescript
|
|
1650
|
+
* const def = defineFlow({ name: 'Onboarding Digest', steps: [...] })
|
|
1651
|
+
*
|
|
1652
|
+
* // Converge (CI/deploy).
|
|
1653
|
+
* const result = await Runtype.flows.ensure(def)
|
|
1654
|
+
*
|
|
1655
|
+
* // PR drift gate.
|
|
1656
|
+
* await Runtype.flows.ensure(def, { expectNoChanges: true })
|
|
1657
|
+
* ```
|
|
1658
|
+
*/
|
|
1659
|
+
async ensure(definition, options = {}) {
|
|
1660
|
+
return ensureFlow(this.getClient(), definition, options);
|
|
1661
|
+
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Pull the canonical definition + provenance for a flow by name — the
|
|
1664
|
+
* absorb-drift direction of the ensure protocol.
|
|
1665
|
+
*/
|
|
1666
|
+
async pull(name) {
|
|
1667
|
+
return pullFlow(this.getClient(), name);
|
|
1668
|
+
}
|
|
1445
1669
|
/**
|
|
1446
1670
|
* Create a virtual flow (one-off, not saved)
|
|
1447
1671
|
*
|
|
@@ -2127,9 +2351,8 @@ var RuntypeFlowBuilder = class {
|
|
|
2127
2351
|
onFlowComplete: (event) => callbacks?.onFlowComplete?.(event),
|
|
2128
2352
|
onError: (error) => callbacks?.onError?.(error)
|
|
2129
2353
|
};
|
|
2130
|
-
const { streamEvents: streamEvents2, stepDeltaText: stepDeltaText2, stepDisplayName: stepDisplayName2, flowErrorMessage: flowErrorMessage2 } = await Promise.resolve().then(() => (init_stream_utils(), stream_utils_exports));
|
|
2131
2354
|
try {
|
|
2132
|
-
for await (const event of
|
|
2355
|
+
for await (const event of streamEvents(response)) {
|
|
2133
2356
|
collectLocalToolAwait(pausedTools, event);
|
|
2134
2357
|
switch (event.type) {
|
|
2135
2358
|
case "flow_start":
|
|
@@ -2139,10 +2362,10 @@ var RuntypeFlowBuilder = class {
|
|
|
2139
2362
|
wrappedCallbacks.onStepStart?.(event);
|
|
2140
2363
|
break;
|
|
2141
2364
|
case "step_delta":
|
|
2142
|
-
wrappedCallbacks.onStepDelta?.(
|
|
2365
|
+
wrappedCallbacks.onStepDelta?.(stepDeltaText(event), event);
|
|
2143
2366
|
break;
|
|
2144
2367
|
case "step_complete": {
|
|
2145
|
-
accumulatedSummary.results?.set(
|
|
2368
|
+
accumulatedSummary.results?.set(stepDisplayName(event), event.result);
|
|
2146
2369
|
wrappedCallbacks.onStepComplete?.(event.result, event);
|
|
2147
2370
|
break;
|
|
2148
2371
|
}
|
|
@@ -2150,7 +2373,7 @@ var RuntypeFlowBuilder = class {
|
|
|
2150
2373
|
wrappedCallbacks.onFlowComplete?.(event);
|
|
2151
2374
|
break;
|
|
2152
2375
|
case "flow_error":
|
|
2153
|
-
wrappedCallbacks.onError?.(new Error(
|
|
2376
|
+
wrappedCallbacks.onError?.(new Error(flowErrorMessage(event)));
|
|
2154
2377
|
break;
|
|
2155
2378
|
}
|
|
2156
2379
|
}
|
|
@@ -2225,7 +2448,8 @@ var RuntypeFlowBuilder = class {
|
|
|
2225
2448
|
return [toolName, await localTools[toolName](parameters)];
|
|
2226
2449
|
} catch (error) {
|
|
2227
2450
|
throw new Error(
|
|
2228
|
-
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}
|
|
2451
|
+
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`,
|
|
2452
|
+
{ cause: error }
|
|
2229
2453
|
);
|
|
2230
2454
|
}
|
|
2231
2455
|
})
|
|
@@ -2258,15 +2482,15 @@ var RuntypeFlowBuilder = class {
|
|
|
2258
2482
|
build() {
|
|
2259
2483
|
const flowMode = this.mode === "existing" ? "existing" : this.mode;
|
|
2260
2484
|
const flow = this.existingFlowId ? { id: this.existingFlowId } : { name: this.flowConfig.name, steps: this.steps };
|
|
2261
|
-
const
|
|
2485
|
+
const request2 = { flow };
|
|
2262
2486
|
if (this.recordConfig) {
|
|
2263
|
-
|
|
2487
|
+
request2.record = this.recordConfig;
|
|
2264
2488
|
}
|
|
2265
2489
|
if (this.messagesConfig) {
|
|
2266
|
-
|
|
2490
|
+
request2.messages = this.messagesConfig;
|
|
2267
2491
|
}
|
|
2268
2492
|
if (this.inputsConfig) {
|
|
2269
|
-
|
|
2493
|
+
request2.inputs = this.inputsConfig;
|
|
2270
2494
|
}
|
|
2271
2495
|
const options = {
|
|
2272
2496
|
flowMode,
|
|
@@ -2284,8 +2508,8 @@ var RuntypeFlowBuilder = class {
|
|
|
2284
2508
|
if (this.mode === "upsert" && Object.keys(this.upsertOptions).length > 0) {
|
|
2285
2509
|
options.upsertOptions = this.upsertOptions;
|
|
2286
2510
|
}
|
|
2287
|
-
|
|
2288
|
-
return
|
|
2511
|
+
request2.options = options;
|
|
2512
|
+
return request2;
|
|
2289
2513
|
}
|
|
2290
2514
|
/**
|
|
2291
2515
|
* Validate this prospective flow against the public validation endpoint
|
|
@@ -2945,6 +3169,8 @@ var SkillsNamespace = class {
|
|
|
2945
3169
|
}
|
|
2946
3170
|
/**
|
|
2947
3171
|
* List skills for the authenticated owner, optionally filtered by status.
|
|
3172
|
+
* Returns just the rows (one page); pass `cursor`/`limit` to page, or use
|
|
3173
|
+
* {@link listPage} when you need the pagination envelope.
|
|
2948
3174
|
*
|
|
2949
3175
|
* @example
|
|
2950
3176
|
* ```typescript
|
|
@@ -2952,10 +3178,23 @@ var SkillsNamespace = class {
|
|
|
2952
3178
|
* ```
|
|
2953
3179
|
*/
|
|
2954
3180
|
async list(params) {
|
|
2955
|
-
const
|
|
2956
|
-
const res = await client.get("/skills", params);
|
|
3181
|
+
const res = await this.listPage(params);
|
|
2957
3182
|
return res.data;
|
|
2958
3183
|
}
|
|
3184
|
+
/**
|
|
3185
|
+
* List skills with the cursor-pagination envelope (mirrors the tools list
|
|
3186
|
+
* shape: `{ data, pagination }`).
|
|
3187
|
+
*
|
|
3188
|
+
* @example
|
|
3189
|
+
* ```typescript
|
|
3190
|
+
* const page1 = await Runtype.skills.listPage({ limit: 50, includeCount: true })
|
|
3191
|
+
* const page2 = await Runtype.skills.listPage({ limit: 50, cursor: page1.pagination?.nextCursor ?? undefined })
|
|
3192
|
+
* ```
|
|
3193
|
+
*/
|
|
3194
|
+
async listPage(params) {
|
|
3195
|
+
const client = this.getClient();
|
|
3196
|
+
return client.get("/skills", params);
|
|
3197
|
+
}
|
|
2959
3198
|
/**
|
|
2960
3199
|
* Get a skill and its full version history.
|
|
2961
3200
|
*
|
|
@@ -3048,6 +3287,260 @@ var SkillsNamespace = class {
|
|
|
3048
3287
|
}
|
|
3049
3288
|
};
|
|
3050
3289
|
|
|
3290
|
+
// src/agents-namespace.ts
|
|
3291
|
+
var AGENT_CONFIG_KEYS = [
|
|
3292
|
+
"model",
|
|
3293
|
+
"systemPrompt",
|
|
3294
|
+
"temperature",
|
|
3295
|
+
"topP",
|
|
3296
|
+
"topK",
|
|
3297
|
+
"frequencyPenalty",
|
|
3298
|
+
"presencePenalty",
|
|
3299
|
+
"seed",
|
|
3300
|
+
"tools",
|
|
3301
|
+
"reasoning",
|
|
3302
|
+
"advisor",
|
|
3303
|
+
"loopConfig",
|
|
3304
|
+
"voice",
|
|
3305
|
+
"errorHandling",
|
|
3306
|
+
"artifacts",
|
|
3307
|
+
"loggingPolicy",
|
|
3308
|
+
"temporal",
|
|
3309
|
+
"memory"
|
|
3310
|
+
];
|
|
3311
|
+
var AGENT_CONFIG_KEY_LIST = [...AGENT_CONFIG_KEYS].sort();
|
|
3312
|
+
function isPlainObject2(value) {
|
|
3313
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3314
|
+
}
|
|
3315
|
+
function normalizeValue(value) {
|
|
3316
|
+
if (Array.isArray(value)) {
|
|
3317
|
+
return value.map((item) => normalizeValue(item));
|
|
3318
|
+
}
|
|
3319
|
+
if (isPlainObject2(value)) {
|
|
3320
|
+
const normalized = {};
|
|
3321
|
+
for (const key of Object.keys(value).sort()) {
|
|
3322
|
+
const entry = value[key];
|
|
3323
|
+
if (entry === void 0 || entry === null) continue;
|
|
3324
|
+
normalized[key] = normalizeValue(entry);
|
|
3325
|
+
}
|
|
3326
|
+
return normalized;
|
|
3327
|
+
}
|
|
3328
|
+
return value;
|
|
3329
|
+
}
|
|
3330
|
+
function normalizeAgentDefinition(definition) {
|
|
3331
|
+
const config = {};
|
|
3332
|
+
const rawConfig = isPlainObject2(definition.config) ? definition.config : {};
|
|
3333
|
+
for (const key of AGENT_CONFIG_KEY_LIST) {
|
|
3334
|
+
const value = rawConfig[key];
|
|
3335
|
+
if (value === void 0 || value === null) continue;
|
|
3336
|
+
config[key] = normalizeValue(value);
|
|
3337
|
+
}
|
|
3338
|
+
return {
|
|
3339
|
+
name: definition.name,
|
|
3340
|
+
...definition.description ? { description: definition.description } : {},
|
|
3341
|
+
...definition.icon ? { icon: definition.icon } : {},
|
|
3342
|
+
config
|
|
3343
|
+
};
|
|
3344
|
+
}
|
|
3345
|
+
async function computeAgentContentHash(definition) {
|
|
3346
|
+
const serialized = JSON.stringify(normalizeAgentDefinition(definition));
|
|
3347
|
+
const encoded = new TextEncoder().encode(serialized);
|
|
3348
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
|
|
3349
|
+
return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3350
|
+
}
|
|
3351
|
+
var DEFINE_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set(["name", "description", "icon", ...AGENT_CONFIG_KEYS]);
|
|
3352
|
+
function collectNonPortableToolRefs(config) {
|
|
3353
|
+
const tools = config.tools;
|
|
3354
|
+
if (!isPlainObject2(tools)) return [];
|
|
3355
|
+
const found = [];
|
|
3356
|
+
const isAccountScoped = (ref) => typeof ref === "string" && ref.startsWith("tool_");
|
|
3357
|
+
const scanArray = (value, path) => {
|
|
3358
|
+
if (!Array.isArray(value)) return;
|
|
3359
|
+
value.forEach((ref, i) => {
|
|
3360
|
+
if (isAccountScoped(ref)) found.push(`${path}[${i}]`);
|
|
3361
|
+
});
|
|
3362
|
+
};
|
|
3363
|
+
const scanKeys = (value, path) => {
|
|
3364
|
+
if (!isPlainObject2(value)) return;
|
|
3365
|
+
for (const key of Object.keys(value)) {
|
|
3366
|
+
if (isAccountScoped(key)) found.push(`${path}.${key}`);
|
|
3367
|
+
}
|
|
3368
|
+
};
|
|
3369
|
+
scanArray(tools.toolIds, "tools.toolIds");
|
|
3370
|
+
scanKeys(tools.toolConfigs, "tools.toolConfigs");
|
|
3371
|
+
scanKeys(tools.perToolLimits, "tools.perToolLimits");
|
|
3372
|
+
if (isPlainObject2(tools.approval)) scanArray(tools.approval.require, "tools.approval.require");
|
|
3373
|
+
if (isPlainObject2(tools.subagentConfig)) {
|
|
3374
|
+
scanArray(tools.subagentConfig.toolPool, "tools.subagentConfig.toolPool");
|
|
3375
|
+
}
|
|
3376
|
+
if (isPlainObject2(tools.codeModeConfig)) {
|
|
3377
|
+
scanArray(tools.codeModeConfig.toolPool, "tools.codeModeConfig.toolPool");
|
|
3378
|
+
}
|
|
3379
|
+
return found;
|
|
3380
|
+
}
|
|
3381
|
+
function defineAgent(input) {
|
|
3382
|
+
if (!input || typeof input !== "object") {
|
|
3383
|
+
throw new Error("defineAgent requires a definition object");
|
|
3384
|
+
}
|
|
3385
|
+
if (typeof input.name !== "string" || input.name.length === 0) {
|
|
3386
|
+
throw new Error('defineAgent requires a non-empty string "name"');
|
|
3387
|
+
}
|
|
3388
|
+
const unknownKeys = Object.keys(input).filter((key) => !DEFINE_TOP_LEVEL_KEYS.has(key));
|
|
3389
|
+
if (unknownKeys.length > 0) {
|
|
3390
|
+
throw new Error(
|
|
3391
|
+
`defineAgent: unknown field(s): ${unknownKeys.join(", ")}. Allowed fields are name, description, icon, and the agent runtime config surface (${AGENT_CONFIG_KEY_LIST.join(", ")}).`
|
|
3392
|
+
);
|
|
3393
|
+
}
|
|
3394
|
+
const config = {};
|
|
3395
|
+
for (const key of AGENT_CONFIG_KEYS) {
|
|
3396
|
+
const value = input[key];
|
|
3397
|
+
if (value !== void 0) config[key] = value;
|
|
3398
|
+
}
|
|
3399
|
+
const nonPortable = collectNonPortableToolRefs(config);
|
|
3400
|
+
if (nonPortable.length > 0) {
|
|
3401
|
+
throw new Error(
|
|
3402
|
+
`defineAgent: account-scoped tool reference(s) at ${nonPortable.join(", ")}. Definitions must be environment-portable \u2014 tool_\u2026 IDs belong to one account/environment. Use builtin:/platform:/mcp: references instead. Name-based resolution of saved tools is a planned follow-up.`
|
|
3403
|
+
);
|
|
3404
|
+
}
|
|
3405
|
+
return {
|
|
3406
|
+
name: input.name,
|
|
3407
|
+
...input.description !== void 0 ? { description: input.description } : {},
|
|
3408
|
+
...input.icon !== void 0 ? { icon: input.icon } : {},
|
|
3409
|
+
config
|
|
3410
|
+
};
|
|
3411
|
+
}
|
|
3412
|
+
var AgentEnsureConflictError = class extends Error {
|
|
3413
|
+
constructor(body) {
|
|
3414
|
+
super(body.error ?? `Agent ensure conflict: ${body.code}`);
|
|
3415
|
+
this.name = "AgentEnsureConflictError";
|
|
3416
|
+
this.code = body.code;
|
|
3417
|
+
this.lastModifiedSource = body.lastModifiedSource;
|
|
3418
|
+
this.modifiedAt = body.modifiedAt;
|
|
3419
|
+
this.currentHash = body.currentHash;
|
|
3420
|
+
}
|
|
3421
|
+
};
|
|
3422
|
+
var AgentDriftError = class extends Error {
|
|
3423
|
+
constructor(plan) {
|
|
3424
|
+
super(
|
|
3425
|
+
`Agent "${plan.agentId ?? "definition"}" drifted: plan is '${plan.changes}' (changed: ${plan.changedKeys.join(", ") || "n/a"}). Run client.agents.pull(name) to absorb the remote edit into your repo, or re-run ensure to converge.`
|
|
3426
|
+
);
|
|
3427
|
+
this.name = "AgentDriftError";
|
|
3428
|
+
this.plan = plan;
|
|
3429
|
+
}
|
|
3430
|
+
};
|
|
3431
|
+
function parseRequestError2(err) {
|
|
3432
|
+
if (!(err instanceof Error)) return { status: null, body: null };
|
|
3433
|
+
const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
|
|
3434
|
+
if (!match) return { status: null, body: null };
|
|
3435
|
+
try {
|
|
3436
|
+
return { status: Number(match[1]), body: JSON.parse(match[2]) };
|
|
3437
|
+
} catch {
|
|
3438
|
+
return { status: Number(match[1]), body: null };
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
function toConflictError2(err) {
|
|
3442
|
+
const { status, body } = parseRequestError2(err);
|
|
3443
|
+
if (status !== 409 || !isPlainObject2(body)) return null;
|
|
3444
|
+
const code = body.code;
|
|
3445
|
+
if (code !== "external_modification" && code !== "remote_changed") return null;
|
|
3446
|
+
return new AgentEnsureConflictError(
|
|
3447
|
+
body
|
|
3448
|
+
);
|
|
3449
|
+
}
|
|
3450
|
+
var serverHashMemo2 = /* @__PURE__ */ new WeakMap();
|
|
3451
|
+
function memoFor2(client) {
|
|
3452
|
+
let memo = serverHashMemo2.get(client);
|
|
3453
|
+
if (!memo) {
|
|
3454
|
+
memo = /* @__PURE__ */ new Map();
|
|
3455
|
+
serverHashMemo2.set(client, memo);
|
|
3456
|
+
}
|
|
3457
|
+
return memo;
|
|
3458
|
+
}
|
|
3459
|
+
var AgentsNamespace = class {
|
|
3460
|
+
constructor(getClient) {
|
|
3461
|
+
this.getClient = getClient;
|
|
3462
|
+
}
|
|
3463
|
+
/**
|
|
3464
|
+
* Idempotently converge a definition onto the platform. Hash-first: probes
|
|
3465
|
+
* with a content hash, and only ships the full definition when the server
|
|
3466
|
+
* reports a miss (`definitionRequired`). Creates an immutable version
|
|
3467
|
+
* snapshot on every change; never deletes.
|
|
3468
|
+
*/
|
|
3469
|
+
async ensure(definition, options = {}) {
|
|
3470
|
+
const client = this.getClient();
|
|
3471
|
+
const { dryRun, onConflict, release, expectedRemoteHash, expectNoChanges } = options;
|
|
3472
|
+
const passthrough = {
|
|
3473
|
+
...onConflict ? { onConflict } : {},
|
|
3474
|
+
...release ? { release } : {},
|
|
3475
|
+
...expectedRemoteHash ? { expectedRemoteHash } : {}
|
|
3476
|
+
};
|
|
3477
|
+
if (dryRun || expectNoChanges) {
|
|
3478
|
+
const plan = await this.request(client, {
|
|
3479
|
+
name: definition.name,
|
|
3480
|
+
definition,
|
|
3481
|
+
dryRun: true,
|
|
3482
|
+
...passthrough
|
|
3483
|
+
});
|
|
3484
|
+
if (plan.result !== "plan") {
|
|
3485
|
+
throw new Error(`Expected a plan result from dryRun, got '${plan.result}'`);
|
|
3486
|
+
}
|
|
3487
|
+
if (expectNoChanges && plan.changes !== "none") {
|
|
3488
|
+
throw new AgentDriftError(plan);
|
|
3489
|
+
}
|
|
3490
|
+
return plan;
|
|
3491
|
+
}
|
|
3492
|
+
const memo = memoFor2(client);
|
|
3493
|
+
const localHash = await computeAgentContentHash({
|
|
3494
|
+
...definition,
|
|
3495
|
+
config: definition.config
|
|
3496
|
+
});
|
|
3497
|
+
const memoKey = `${definition.name}\0${localHash}`;
|
|
3498
|
+
const contentHash = memo.get(memoKey) ?? localHash;
|
|
3499
|
+
const probe = await this.request(client, {
|
|
3500
|
+
name: definition.name,
|
|
3501
|
+
contentHash,
|
|
3502
|
+
...passthrough
|
|
3503
|
+
});
|
|
3504
|
+
if (probe.result !== "definitionRequired") {
|
|
3505
|
+
this.memoize(memo, memoKey, probe);
|
|
3506
|
+
return probe;
|
|
3507
|
+
}
|
|
3508
|
+
const converged = await this.request(client, {
|
|
3509
|
+
name: definition.name,
|
|
3510
|
+
definition,
|
|
3511
|
+
...passthrough
|
|
3512
|
+
});
|
|
3513
|
+
if (converged.result === "definitionRequired") {
|
|
3514
|
+
throw new Error("Server reported definitionRequired for a full-definition request");
|
|
3515
|
+
}
|
|
3516
|
+
this.memoize(memo, memoKey, converged);
|
|
3517
|
+
return converged;
|
|
3518
|
+
}
|
|
3519
|
+
/**
|
|
3520
|
+
* Pull the canonical definition + provenance for an agent by name — the
|
|
3521
|
+
* absorb-drift direction. The contentHash reflects the live agent state.
|
|
3522
|
+
*/
|
|
3523
|
+
async pull(name) {
|
|
3524
|
+
const client = this.getClient();
|
|
3525
|
+
return client.get("/agents/pull", { name });
|
|
3526
|
+
}
|
|
3527
|
+
memoize(memo, memoKey, result) {
|
|
3528
|
+
if (result.result !== "plan") memo.set(memoKey, result.contentHash);
|
|
3529
|
+
}
|
|
3530
|
+
async request(client, body) {
|
|
3531
|
+
try {
|
|
3532
|
+
return await client.post(
|
|
3533
|
+
"/agents/ensure",
|
|
3534
|
+
body
|
|
3535
|
+
);
|
|
3536
|
+
} catch (err) {
|
|
3537
|
+
const conflict = toConflictError2(err);
|
|
3538
|
+
if (conflict) throw conflict;
|
|
3539
|
+
throw err;
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
};
|
|
3543
|
+
|
|
3051
3544
|
// src/transform.ts
|
|
3052
3545
|
function transformResponse(data) {
|
|
3053
3546
|
return data;
|
|
@@ -3208,7 +3701,7 @@ var RuntypeClient = class {
|
|
|
3208
3701
|
} catch (error) {
|
|
3209
3702
|
clearTimeout(timeoutId);
|
|
3210
3703
|
if (error instanceof Error && error.name === "AbortError") {
|
|
3211
|
-
throw new Error(`Request timeout after ${this.timeout}ms
|
|
3704
|
+
throw new Error(`Request timeout after ${this.timeout}ms`, { cause: error });
|
|
3212
3705
|
}
|
|
3213
3706
|
throw error;
|
|
3214
3707
|
}
|
|
@@ -3235,7 +3728,7 @@ var RuntypeClient = class {
|
|
|
3235
3728
|
} catch (error) {
|
|
3236
3729
|
clearTimeout(timeoutId);
|
|
3237
3730
|
if (error instanceof Error && error.name === "AbortError") {
|
|
3238
|
-
throw new Error(`Request timeout after ${this.timeout}ms
|
|
3731
|
+
throw new Error(`Request timeout after ${this.timeout}ms`, { cause: error });
|
|
3239
3732
|
}
|
|
3240
3733
|
throw error;
|
|
3241
3734
|
}
|
|
@@ -3410,6 +3903,32 @@ var Runtype = class {
|
|
|
3410
3903
|
static get skills() {
|
|
3411
3904
|
return new SkillsNamespace(() => this.getClient());
|
|
3412
3905
|
}
|
|
3906
|
+
/**
|
|
3907
|
+
* Agents namespace - Agent config-as-code (define / ensure / pull)
|
|
3908
|
+
*
|
|
3909
|
+
* @example
|
|
3910
|
+
* ```typescript
|
|
3911
|
+
* import { defineAgent, Runtype } from '@runtypelabs/sdk'
|
|
3912
|
+
*
|
|
3913
|
+
* const assistant = defineAgent({
|
|
3914
|
+
* name: 'Pricing Assistant',
|
|
3915
|
+
* model: 'claude-sonnet-4-6',
|
|
3916
|
+
* systemPrompt: renderPrompt(pricingData),
|
|
3917
|
+
* })
|
|
3918
|
+
*
|
|
3919
|
+
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
3920
|
+
* await Runtype.agents.ensure(assistant)
|
|
3921
|
+
*
|
|
3922
|
+
* // CI drift gate
|
|
3923
|
+
* await Runtype.agents.ensure(assistant, { expectNoChanges: true })
|
|
3924
|
+
*
|
|
3925
|
+
* // Absorb a dashboard edit back into the repo
|
|
3926
|
+
* const { definition } = await Runtype.agents.pull('Pricing Assistant')
|
|
3927
|
+
* ```
|
|
3928
|
+
*/
|
|
3929
|
+
static get agents() {
|
|
3930
|
+
return new AgentsNamespace(() => this.getClient());
|
|
3931
|
+
}
|
|
3413
3932
|
};
|
|
3414
3933
|
|
|
3415
3934
|
// src/generated-tool-gate.ts
|
|
@@ -3632,8 +4151,8 @@ function buildGeneratedRuntimeToolGateOutput(proposal, options = {}) {
|
|
|
3632
4151
|
...decision.tool ? { tool: decision.tool } : {}
|
|
3633
4152
|
};
|
|
3634
4153
|
}
|
|
3635
|
-
function attachRuntimeToolsToDispatchRequest(
|
|
3636
|
-
const stepList =
|
|
4154
|
+
function attachRuntimeToolsToDispatchRequest(request2, runtimeTools, options = {}) {
|
|
4155
|
+
const stepList = request2.flow.steps;
|
|
3637
4156
|
if (!stepList || !Array.isArray(stepList) || stepList.length === 0) {
|
|
3638
4157
|
throw new Error("Cannot attach runtime tools: dispatch request must include flow.steps");
|
|
3639
4158
|
}
|
|
@@ -3676,9 +4195,9 @@ function attachRuntimeToolsToDispatchRequest(request, runtimeTools, options = {}
|
|
|
3676
4195
|
}
|
|
3677
4196
|
};
|
|
3678
4197
|
return {
|
|
3679
|
-
...
|
|
4198
|
+
...request2,
|
|
3680
4199
|
flow: {
|
|
3681
|
-
...
|
|
4200
|
+
...request2.flow,
|
|
3682
4201
|
// `clonedSteps` is a structural clone of `request.flow.steps` (already
|
|
3683
4202
|
// `FlowStepDefinition[]`); only the prompt step's `config.tools` was
|
|
3684
4203
|
// merged, so every step's `type` discriminant is preserved. The clone is
|
|
@@ -3688,18 +4207,56 @@ function attachRuntimeToolsToDispatchRequest(request, runtimeTools, options = {}
|
|
|
3688
4207
|
}
|
|
3689
4208
|
};
|
|
3690
4209
|
}
|
|
3691
|
-
function applyGeneratedRuntimeToolProposalToDispatchRequest(
|
|
4210
|
+
function applyGeneratedRuntimeToolProposalToDispatchRequest(request2, proposal, options = {}) {
|
|
3692
4211
|
const decision = evaluateGeneratedRuntimeToolProposal(proposal, options.gate);
|
|
3693
4212
|
if (!decision.approved || !decision.tool) {
|
|
3694
|
-
return { decision, request };
|
|
4213
|
+
return { decision, request: request2 };
|
|
3695
4214
|
}
|
|
3696
|
-
const nextRequest = attachRuntimeToolsToDispatchRequest(
|
|
4215
|
+
const nextRequest = attachRuntimeToolsToDispatchRequest(request2, [decision.tool], options.attach);
|
|
3697
4216
|
return {
|
|
3698
4217
|
decision,
|
|
3699
4218
|
request: nextRequest
|
|
3700
4219
|
};
|
|
3701
4220
|
}
|
|
3702
4221
|
|
|
4222
|
+
// src/offload-markers.ts
|
|
4223
|
+
var LEDGER_ARTIFACT_LINE_PREFIX = "Ledger artifact: ";
|
|
4224
|
+
function formatChars(charLength) {
|
|
4225
|
+
return charLength.toLocaleString("en-US");
|
|
4226
|
+
}
|
|
4227
|
+
function buildSendViewOffloadMarker(details) {
|
|
4228
|
+
return `[${details.toolName} output (${formatChars(details.charLength)} chars) saved to ${details.filePath} \u2014 use read_file to retrieve if needed]`;
|
|
4229
|
+
}
|
|
4230
|
+
function buildLedgerOffloadReference(details) {
|
|
4231
|
+
return [
|
|
4232
|
+
`[Output offloaded as ${details.outputId} \u2014 ${formatChars(details.charLength)} chars stored in the marathon context ledger]`,
|
|
4233
|
+
`${LEDGER_ARTIFACT_LINE_PREFIX}${details.relativePath}`,
|
|
4234
|
+
`Preview: ${details.preview}${details.truncated ? "..." : ""}`,
|
|
4235
|
+
"",
|
|
4236
|
+
`Use read_offloaded_output with id "${details.outputId}" to retrieve the full output if needed.`
|
|
4237
|
+
].join("\n");
|
|
4238
|
+
}
|
|
4239
|
+
var DECLARED_CHARS_PATTERNS = [
|
|
4240
|
+
/—\s*([\d,]+)\s+chars?\s+(?:stored|saved)/i,
|
|
4241
|
+
/\(([\d,]+)\s+chars?\)\s+saved/i
|
|
4242
|
+
];
|
|
4243
|
+
function extractDeclaredToolResultChars(value) {
|
|
4244
|
+
if (typeof value !== "string") return void 0;
|
|
4245
|
+
for (const pattern of DECLARED_CHARS_PATTERNS) {
|
|
4246
|
+
const match = pattern.exec(value);
|
|
4247
|
+
if (!match?.[1]) continue;
|
|
4248
|
+
const parsed = Number.parseInt(match[1].replace(/,/g, ""), 10);
|
|
4249
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
4250
|
+
}
|
|
4251
|
+
return void 0;
|
|
4252
|
+
}
|
|
4253
|
+
function parseOffloadedOutputId(value) {
|
|
4254
|
+
return /\bread_offloaded_output\s+with\s+id\s+"([^"]+)"/i.exec(value)?.[1] || /\[Output offloaded as\s+([a-zA-Z0-9_-]+)/i.exec(value)?.[1] || void 0;
|
|
4255
|
+
}
|
|
4256
|
+
function parseLedgerArtifactRelativePath(value) {
|
|
4257
|
+
return value.split("\n").find((line) => line.startsWith(LEDGER_ARTIFACT_LINE_PREFIX))?.slice(LEDGER_ARTIFACT_LINE_PREFIX.length).trim();
|
|
4258
|
+
}
|
|
4259
|
+
|
|
3703
4260
|
// src/workflow-utils.ts
|
|
3704
4261
|
function normalizeCandidatePath(candidatePath) {
|
|
3705
4262
|
return candidatePath.trim().replace(/\\/g, "/").replace(/^\.?\//, "").replace(/\/+/g, "/");
|
|
@@ -5431,15 +5988,15 @@ var DispatchEndpoint = class {
|
|
|
5431
5988
|
* Attach approved runtime tools to a prompt step in a redispatch request.
|
|
5432
5989
|
* Returns a new request object and does not mutate the original.
|
|
5433
5990
|
*/
|
|
5434
|
-
attachApprovedRuntimeTools(
|
|
5435
|
-
return attachRuntimeToolsToDispatchRequest(
|
|
5991
|
+
attachApprovedRuntimeTools(request2, runtimeTools, options) {
|
|
5992
|
+
return attachRuntimeToolsToDispatchRequest(request2, runtimeTools, options);
|
|
5436
5993
|
}
|
|
5437
5994
|
/**
|
|
5438
5995
|
* Validate a generated runtime tool proposal and attach it to the redispatch
|
|
5439
5996
|
* request if approved, in one call.
|
|
5440
5997
|
*/
|
|
5441
|
-
applyGeneratedRuntimeToolProposal(
|
|
5442
|
-
return applyGeneratedRuntimeToolProposalToDispatchRequest(
|
|
5998
|
+
applyGeneratedRuntimeToolProposal(request2, proposal, options) {
|
|
5999
|
+
return applyGeneratedRuntimeToolProposalToDispatchRequest(request2, proposal, options);
|
|
5443
6000
|
}
|
|
5444
6001
|
};
|
|
5445
6002
|
var ChatEndpoint = class {
|
|
@@ -5944,6 +6501,22 @@ async function processAgentStream(body, callbacks) {
|
|
|
5944
6501
|
reader.releaseLock();
|
|
5945
6502
|
}
|
|
5946
6503
|
}
|
|
6504
|
+
function sleepWithAbort(delayMs, signal) {
|
|
6505
|
+
return new Promise((resolve) => {
|
|
6506
|
+
const onAbort = () => {
|
|
6507
|
+
clearTimeout(timer);
|
|
6508
|
+
resolve();
|
|
6509
|
+
};
|
|
6510
|
+
const timer = setTimeout(() => {
|
|
6511
|
+
signal?.removeEventListener("abort", onAbort);
|
|
6512
|
+
resolve();
|
|
6513
|
+
}, delayMs);
|
|
6514
|
+
if (signal) {
|
|
6515
|
+
if (signal.aborted) onAbort();
|
|
6516
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
6517
|
+
}
|
|
6518
|
+
});
|
|
6519
|
+
}
|
|
5947
6520
|
var GENERATED_RUNTIME_TOOL_PROPOSAL_SCHEMA = {
|
|
5948
6521
|
type: "object",
|
|
5949
6522
|
properties: {
|
|
@@ -5975,8 +6548,8 @@ var GENERATED_RUNTIME_TOOL_PROPOSAL_SCHEMA = {
|
|
|
5975
6548
|
},
|
|
5976
6549
|
required: ["name", "description", "toolType", "parametersSchema", "config"]
|
|
5977
6550
|
};
|
|
5978
|
-
function appendRuntimeToolsToAgentRequest(
|
|
5979
|
-
const existing =
|
|
6551
|
+
function appendRuntimeToolsToAgentRequest(request2, runtimeTools) {
|
|
6552
|
+
const existing = request2.tools?.runtimeTools || [];
|
|
5980
6553
|
const existingNames = new Set(existing.map((tool) => tool.name));
|
|
5981
6554
|
const converted = runtimeTools.filter((tool) => !existingNames.has(tool.name)).map((tool) => ({
|
|
5982
6555
|
name: tool.name,
|
|
@@ -5986,9 +6559,9 @@ function appendRuntimeToolsToAgentRequest(request, runtimeTools) {
|
|
|
5986
6559
|
...tool.config ? { config: tool.config } : {}
|
|
5987
6560
|
}));
|
|
5988
6561
|
return {
|
|
5989
|
-
...
|
|
6562
|
+
...request2,
|
|
5990
6563
|
tools: {
|
|
5991
|
-
...
|
|
6564
|
+
...request2.tools,
|
|
5992
6565
|
runtimeTools: [...existing, ...converted]
|
|
5993
6566
|
}
|
|
5994
6567
|
};
|
|
@@ -6064,21 +6637,21 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6064
6637
|
* Attach approved runtime tools to an agent execute request.
|
|
6065
6638
|
* Returns a new request object and does not mutate the original.
|
|
6066
6639
|
*/
|
|
6067
|
-
attachApprovedRuntimeTools(
|
|
6068
|
-
return appendRuntimeToolsToAgentRequest(
|
|
6640
|
+
attachApprovedRuntimeTools(request2, runtimeTools) {
|
|
6641
|
+
return appendRuntimeToolsToAgentRequest(request2, runtimeTools);
|
|
6069
6642
|
}
|
|
6070
6643
|
/**
|
|
6071
6644
|
* Validate a generated runtime tool proposal and append it to an agent execute
|
|
6072
6645
|
* request if approved, in one call.
|
|
6073
6646
|
*/
|
|
6074
|
-
applyGeneratedRuntimeToolProposal(
|
|
6647
|
+
applyGeneratedRuntimeToolProposal(request2, proposal, options) {
|
|
6075
6648
|
const decision = evaluateGeneratedRuntimeToolProposal(proposal, options);
|
|
6076
6649
|
if (!decision.approved || !decision.tool) {
|
|
6077
|
-
return { decision, request };
|
|
6650
|
+
return { decision, request: request2 };
|
|
6078
6651
|
}
|
|
6079
6652
|
return {
|
|
6080
6653
|
decision,
|
|
6081
|
-
request: appendRuntimeToolsToAgentRequest(
|
|
6654
|
+
request: appendRuntimeToolsToAgentRequest(request2, [decision.tool])
|
|
6082
6655
|
};
|
|
6083
6656
|
}
|
|
6084
6657
|
/**
|
|
@@ -6108,13 +6681,14 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6108
6681
|
* // ...
|
|
6109
6682
|
* ```
|
|
6110
6683
|
*/
|
|
6111
|
-
async executeStream(id, data) {
|
|
6684
|
+
async executeStream(id, data, init) {
|
|
6112
6685
|
return this.client.requestStream(`/agents/${id}/execute`, {
|
|
6113
6686
|
method: "POST",
|
|
6114
6687
|
body: JSON.stringify({
|
|
6115
6688
|
...data,
|
|
6116
6689
|
streamResponse: true
|
|
6117
|
-
})
|
|
6690
|
+
}),
|
|
6691
|
+
...init?.signal ? { signal: init.signal } : {}
|
|
6118
6692
|
});
|
|
6119
6693
|
}
|
|
6120
6694
|
/**
|
|
@@ -6210,56 +6784,94 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6210
6784
|
runtimeTools: [...data.tools?.runtimeTools || [], ...runtimeTools]
|
|
6211
6785
|
}
|
|
6212
6786
|
};
|
|
6213
|
-
const
|
|
6214
|
-
if (!response.ok) {
|
|
6215
|
-
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
6216
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
6217
|
-
}
|
|
6218
|
-
let currentBody = response.body;
|
|
6787
|
+
const abortSignal = options?.abortSignal;
|
|
6219
6788
|
let accumulatedOutput = "";
|
|
6220
6789
|
let lastKnownCost = 0;
|
|
6221
6790
|
let lastKnownTokens;
|
|
6791
|
+
let lastSeenExecutionId = "";
|
|
6222
6792
|
let pauseCount = 0;
|
|
6223
6793
|
let discoveryPauseCount = 0;
|
|
6224
6794
|
let consecutiveDiscoveryPauseCount = 0;
|
|
6225
6795
|
const toolNameCounts = {};
|
|
6226
6796
|
let recentActionKeys = [];
|
|
6227
6797
|
const toolMessages = [];
|
|
6798
|
+
const finishAborted = (executionId) => {
|
|
6799
|
+
const abortCompleteEvent = {
|
|
6800
|
+
type: "agent_complete",
|
|
6801
|
+
executionId,
|
|
6802
|
+
seq: 0,
|
|
6803
|
+
agentId: id,
|
|
6804
|
+
success: true,
|
|
6805
|
+
iterations: 1,
|
|
6806
|
+
stopReason: "end_turn",
|
|
6807
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6808
|
+
totalCost: lastKnownCost,
|
|
6809
|
+
...lastKnownTokens ? { totalTokens: lastKnownTokens } : {},
|
|
6810
|
+
finalOutput: [accumulatedOutput.trim(), "Session aborted by user request."].filter(Boolean).join("\n\n"),
|
|
6811
|
+
duration: 0
|
|
6812
|
+
};
|
|
6813
|
+
callbacks?.onAgentComplete?.(abortCompleteEvent);
|
|
6814
|
+
return { completeEvent: abortCompleteEvent, toolMessages };
|
|
6815
|
+
};
|
|
6816
|
+
let response;
|
|
6817
|
+
try {
|
|
6818
|
+
response = await this.executeStream(id, requestData, {
|
|
6819
|
+
...abortSignal ? { signal: abortSignal } : {}
|
|
6820
|
+
});
|
|
6821
|
+
} catch (error) {
|
|
6822
|
+
if (abortSignal?.aborted) return finishAborted(lastSeenExecutionId);
|
|
6823
|
+
throw error;
|
|
6824
|
+
}
|
|
6825
|
+
if (!response.ok) {
|
|
6826
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
6827
|
+
throw new Error(error.error || `HTTP ${response.status}`);
|
|
6828
|
+
}
|
|
6829
|
+
let currentBody = response.body;
|
|
6228
6830
|
while (true) {
|
|
6229
6831
|
let pausedEvent = null;
|
|
6230
6832
|
let completeEvent = null;
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6833
|
+
try {
|
|
6834
|
+
await processAgentStream(currentBody, {
|
|
6835
|
+
...callbacks,
|
|
6836
|
+
onAgentStart: (event) => {
|
|
6837
|
+
lastSeenExecutionId = event.executionId;
|
|
6838
|
+
callbacks?.onAgentStart?.(event);
|
|
6839
|
+
},
|
|
6840
|
+
onTurnDelta: (event) => {
|
|
6841
|
+
if (event.contentType === "text") {
|
|
6842
|
+
accumulatedOutput += event.delta;
|
|
6843
|
+
}
|
|
6844
|
+
callbacks?.onTurnDelta?.(event);
|
|
6845
|
+
},
|
|
6846
|
+
onTurnComplete: (event) => {
|
|
6847
|
+
if (typeof event.cost === "number") {
|
|
6848
|
+
lastKnownCost = event.cost;
|
|
6849
|
+
}
|
|
6850
|
+
if (event.tokens) {
|
|
6851
|
+
lastKnownTokens = event.tokens;
|
|
6852
|
+
}
|
|
6853
|
+
callbacks?.onTurnComplete?.(event);
|
|
6854
|
+
},
|
|
6855
|
+
onAgentPaused: (event) => {
|
|
6856
|
+
pausedEvent = event;
|
|
6857
|
+
callbacks?.onAgentPaused?.(event);
|
|
6858
|
+
},
|
|
6859
|
+
onAgentComplete: (event) => {
|
|
6860
|
+
if (!event.finalOutput && accumulatedOutput) {
|
|
6861
|
+
event.finalOutput = accumulatedOutput;
|
|
6862
|
+
}
|
|
6863
|
+
completeEvent = event;
|
|
6864
|
+
callbacks?.onAgentComplete?.(event);
|
|
6255
6865
|
}
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6866
|
+
});
|
|
6867
|
+
} catch (error) {
|
|
6868
|
+
if (abortSignal?.aborted) return finishAborted(lastSeenExecutionId);
|
|
6869
|
+
throw error;
|
|
6870
|
+
}
|
|
6260
6871
|
if (completeEvent) return { completeEvent, toolMessages };
|
|
6261
6872
|
if (pausedEvent) {
|
|
6262
6873
|
const { toolName, toolId, parameters, executionId } = pausedEvent;
|
|
6874
|
+
lastSeenExecutionId = executionId;
|
|
6263
6875
|
const toolDef = localTools[toolName];
|
|
6264
6876
|
if (!toolDef) {
|
|
6265
6877
|
throw new Error(`Local tool "${toolName}" required but not provided`);
|
|
@@ -6374,6 +6986,19 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6374
6986
|
callbacks?.onAgentComplete?.(forcedCompleteEvent);
|
|
6375
6987
|
return { completeEvent: forcedCompleteEvent, toolMessages };
|
|
6376
6988
|
}
|
|
6989
|
+
if (abortSignal?.aborted) {
|
|
6990
|
+
callbacks?.onLocalToolExecutionComplete?.({
|
|
6991
|
+
executionId,
|
|
6992
|
+
toolCallId: toolId,
|
|
6993
|
+
toolName,
|
|
6994
|
+
parameters: parsedParams,
|
|
6995
|
+
result: toolResult,
|
|
6996
|
+
success: true,
|
|
6997
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6998
|
+
durationMs: Date.now() - localExecutionStartedAtMs
|
|
6999
|
+
});
|
|
7000
|
+
return finishAborted(executionId);
|
|
7001
|
+
}
|
|
6377
7002
|
if (options?.shouldInterrupt?.()) {
|
|
6378
7003
|
callbacks?.onLocalToolExecutionComplete?.({
|
|
6379
7004
|
executionId,
|
|
@@ -6407,15 +7032,22 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6407
7032
|
callbacks?.onAgentComplete?.(interruptCompleteEvent);
|
|
6408
7033
|
return { completeEvent: interruptCompleteEvent, toolMessages };
|
|
6409
7034
|
}
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
7035
|
+
let resumeResponse;
|
|
7036
|
+
try {
|
|
7037
|
+
resumeResponse = await this.client.requestStream(`/agents/${id}/resume`, {
|
|
7038
|
+
method: "POST",
|
|
7039
|
+
body: JSON.stringify({
|
|
7040
|
+
executionId,
|
|
7041
|
+
toolOutputs: { [toolName]: toolResult },
|
|
7042
|
+
streamResponse: true,
|
|
7043
|
+
debugMode: data.debugMode
|
|
7044
|
+
}),
|
|
7045
|
+
...abortSignal ? { signal: abortSignal } : {}
|
|
7046
|
+
});
|
|
7047
|
+
} catch (error) {
|
|
7048
|
+
if (abortSignal?.aborted) return finishAborted(executionId);
|
|
7049
|
+
throw error;
|
|
7050
|
+
}
|
|
6419
7051
|
if (!resumeResponse.ok) {
|
|
6420
7052
|
const error = await resumeResponse.json().catch(() => ({ error: "Unknown error" }));
|
|
6421
7053
|
throw new Error(error.error || `HTTP ${resumeResponse.status}`);
|
|
@@ -6433,6 +7065,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6433
7065
|
currentBody = resumeResponse.body;
|
|
6434
7066
|
continue;
|
|
6435
7067
|
}
|
|
7068
|
+
if (abortSignal?.aborted) return finishAborted(lastSeenExecutionId);
|
|
6436
7069
|
return null;
|
|
6437
7070
|
}
|
|
6438
7071
|
}
|
|
@@ -6704,7 +7337,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6704
7337
|
reasons.push("Best candidate file has not been verified (read back after writing)");
|
|
6705
7338
|
}
|
|
6706
7339
|
if (state.verificationRequired && !state.lastVerificationPassed && !trace.verificationPassed) {
|
|
6707
|
-
reasons.push(
|
|
7340
|
+
reasons.push(
|
|
7341
|
+
"Verification has not passed \u2014 run a verification command (run_check) before completing"
|
|
7342
|
+
);
|
|
6708
7343
|
}
|
|
6709
7344
|
return reasons.length > 0 ? reasons.join("; ") : "Completion gates not satisfied for the current workflow phase";
|
|
6710
7345
|
}
|
|
@@ -6747,32 +7382,71 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6747
7382
|
);
|
|
6748
7383
|
}
|
|
6749
7384
|
/**
|
|
6750
|
-
*
|
|
6751
|
-
*
|
|
7385
|
+
* Resolve the replay window: the base index sliced off the full history and
|
|
7386
|
+
* the durable summary message that stands in for everything before it.
|
|
7387
|
+
* The base is honored ONLY when the latest summary actually exists —
|
|
7388
|
+
* slicing history with no summary substitute would silently drop prior
|
|
7389
|
+
* context (defensive against states that carried a base but lost their
|
|
7390
|
+
* summaries). The base is also clamped so a stale pointer (fork truncation,
|
|
7391
|
+
* trimmed legacy state) never slices past the end of the array.
|
|
6752
7392
|
*/
|
|
6753
|
-
|
|
6754
|
-
|
|
7393
|
+
resolveWindowReplay(state, messageCount) {
|
|
7394
|
+
const base = state.contextWindowBaseIndex ?? 0;
|
|
7395
|
+
if (!Number.isFinite(base) || base <= 0) {
|
|
7396
|
+
return { windowBase: 0, windowSummaryMessages: [] };
|
|
7397
|
+
}
|
|
7398
|
+
const summaries = state.contextCompactionSummaries;
|
|
7399
|
+
const latest = summaries?.[summaries.length - 1];
|
|
7400
|
+
if (!latest) {
|
|
7401
|
+
return { windowBase: 0, windowSummaryMessages: [] };
|
|
7402
|
+
}
|
|
7403
|
+
return {
|
|
7404
|
+
windowBase: Math.min(Math.floor(base), messageCount),
|
|
7405
|
+
windowSummaryMessages: [{ role: "system", content: latest.content }]
|
|
7406
|
+
};
|
|
7407
|
+
}
|
|
7408
|
+
/**
|
|
7409
|
+
* Derive the message view sent to the model based on context mode and window
|
|
7410
|
+
* setting. This never mutates persisted marathon history; masking/offloading
|
|
7411
|
+
* is a send-time view over the full-fidelity ledger/history.
|
|
7412
|
+
*/
|
|
7413
|
+
deriveToolContextMessages(messages, taskName, mode, window) {
|
|
7414
|
+
if (mode === "full-inline") return [...messages];
|
|
7415
|
+
const maskMessage = (msg) => ({
|
|
7416
|
+
...msg,
|
|
7417
|
+
toolResults: (msg.toolResults ?? []).map((tr) => this.compactOneResult(tr, taskName, mode))
|
|
7418
|
+
});
|
|
7419
|
+
const view = [...messages];
|
|
6755
7420
|
if (window === "session") {
|
|
6756
|
-
|
|
7421
|
+
const lastUserIndex = view.reduce(
|
|
7422
|
+
(lastIndex, message, index) => message.role === "user" ? index : lastIndex,
|
|
7423
|
+
-1
|
|
7424
|
+
);
|
|
7425
|
+
for (let index = 0; index < view.length; index++) {
|
|
7426
|
+
if (lastUserIndex >= 0 && index > lastUserIndex) continue;
|
|
7427
|
+
const msg = view[index];
|
|
7428
|
+
if (!msg) continue;
|
|
6757
7429
|
if (msg.role === "tool" && msg.toolResults) {
|
|
6758
|
-
|
|
7430
|
+
view[index] = maskMessage(msg);
|
|
6759
7431
|
}
|
|
6760
7432
|
}
|
|
6761
7433
|
} else {
|
|
6762
|
-
const newToolResultCount = newToolMessages.filter((m) => m.role === "tool").length;
|
|
6763
|
-
const keepInlineFromExisting = Math.max(0, window - newToolResultCount);
|
|
6764
7434
|
const toolResultIndices = [];
|
|
6765
|
-
for (let i = 0; i <
|
|
6766
|
-
|
|
7435
|
+
for (let i = 0; i < view.length; i++) {
|
|
7436
|
+
const message = view[i];
|
|
7437
|
+
if (message?.role === "tool" && message.toolResults) {
|
|
6767
7438
|
toolResultIndices.push(i);
|
|
6768
7439
|
}
|
|
6769
7440
|
}
|
|
6770
|
-
const compactUpTo = toolResultIndices.length -
|
|
7441
|
+
const compactUpTo = toolResultIndices.length - window;
|
|
6771
7442
|
for (let j = 0; j < compactUpTo && j < toolResultIndices.length; j++) {
|
|
6772
|
-
const
|
|
6773
|
-
msg
|
|
7443
|
+
const index = toolResultIndices[j];
|
|
7444
|
+
const msg = index === void 0 ? void 0 : view[index];
|
|
7445
|
+
if (!msg) continue;
|
|
7446
|
+
view[index] = maskMessage(msg);
|
|
6774
7447
|
}
|
|
6775
7448
|
}
|
|
7449
|
+
return view;
|
|
6776
7450
|
}
|
|
6777
7451
|
compactOneResult(tr, taskName, mode) {
|
|
6778
7452
|
if (typeof tr.result === "string" && tr.result.startsWith("[")) return tr;
|
|
@@ -6808,10 +7482,20 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6808
7482
|
}
|
|
6809
7483
|
const slug = this.sanitizeTaskSlug(taskName || "task");
|
|
6810
7484
|
const dir = `.runtype/marathons/${slug}/tool-outputs`;
|
|
6811
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
6812
7485
|
const filePath = `${dir}/${toolCallId}.txt`;
|
|
6813
|
-
|
|
6814
|
-
|
|
7486
|
+
try {
|
|
7487
|
+
if (!fs.existsSync(filePath)) {
|
|
7488
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
7489
|
+
fs.writeFileSync(filePath, resultStr, "utf-8");
|
|
7490
|
+
}
|
|
7491
|
+
} catch {
|
|
7492
|
+
return result;
|
|
7493
|
+
}
|
|
7494
|
+
return buildSendViewOffloadMarker({
|
|
7495
|
+
toolName,
|
|
7496
|
+
charLength: resultStr.length,
|
|
7497
|
+
filePath
|
|
7498
|
+
});
|
|
6815
7499
|
}
|
|
6816
7500
|
getDefaultPlanPath(taskName) {
|
|
6817
7501
|
return getDefaultPlanPath(taskName);
|
|
@@ -6933,6 +7617,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6933
7617
|
const migratedPlanPath = workflowVariant === "external" && planPath === this.getDefaultPlanPath(taskName) ? this.getDefaultExternalReportPath(taskName) : planPath;
|
|
6934
7618
|
const candidatePaths = this.dedupeNormalizedCandidatePaths(resumeState.candidatePaths);
|
|
6935
7619
|
const recentReadPaths = this.dedupeNormalizedCandidatePaths(resumeState.recentReadPaths);
|
|
7620
|
+
const contextCompactionSummaries = (resumeState.contextCompactionSummaries ?? []).slice(-20);
|
|
6936
7621
|
const normalizedBestCandidatePath = typeof resumeState.bestCandidatePath === "string" && resumeState.bestCandidatePath.trim() ? this.normalizeCandidatePath(resumeState.bestCandidatePath) : void 0;
|
|
6937
7622
|
const bestCandidatePath = normalizedBestCandidatePath && !this.isMarathonArtifactPath(normalizedBestCandidatePath) ? normalizedBestCandidatePath : [...candidatePaths, ...recentReadPaths].sort(
|
|
6938
7623
|
(left, right) => this.scoreCandidatePath(right) - this.scoreCandidatePath(left)
|
|
@@ -6952,10 +7637,14 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6952
7637
|
bestCandidateVerified: Boolean(resumeState.bestCandidateVerified),
|
|
6953
7638
|
...resumeState.verificationRequired !== void 0 ? { verificationRequired: resumeState.verificationRequired } : {},
|
|
6954
7639
|
lastVerificationPassed: Boolean(resumeState.lastVerificationPassed),
|
|
6955
|
-
...resumeState.consecutiveBlockedVerificationSessions !== void 0 ? {
|
|
7640
|
+
...resumeState.consecutiveBlockedVerificationSessions !== void 0 ? {
|
|
7641
|
+
consecutiveBlockedVerificationSessions: resumeState.consecutiveBlockedVerificationSessions
|
|
7642
|
+
} : {},
|
|
6956
7643
|
...resumeState.isCreationTask !== void 0 ? { isCreationTask: resumeState.isCreationTask } : {},
|
|
6957
7644
|
...resumeState.workflowVariant !== void 0 ? { workflowVariant: resumeState.workflowVariant } : {},
|
|
6958
7645
|
...resumeState.workflowState !== void 0 ? { workflowState: resumeState.workflowState } : {},
|
|
7646
|
+
...contextCompactionSummaries.length ? { contextCompactionSummaries } : {},
|
|
7647
|
+
...typeof resumeState.contextWindowBaseIndex === "number" && Number.isFinite(resumeState.contextWindowBaseIndex) && resumeState.contextWindowBaseIndex > 0 ? { contextWindowBaseIndex: Math.floor(resumeState.contextWindowBaseIndex) } : {},
|
|
6959
7648
|
...typeof resumeState.outputRoot === "string" && resumeState.outputRoot.trim() ? { outputRoot: resumeState.outputRoot.trim().replace(/\\/g, "/").replace(/\/+/g, "/") } : {}
|
|
6960
7649
|
};
|
|
6961
7650
|
}
|
|
@@ -7421,8 +8110,13 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7421
8110
|
} : {},
|
|
7422
8111
|
...seededResumeState?.candidatePaths ? { candidatePaths: seededResumeState.candidatePaths } : {},
|
|
7423
8112
|
...seededResumeState?.recentReadPaths ? { recentReadPaths: seededResumeState.recentReadPaths } : {},
|
|
7424
|
-
...seededResumeState?.recentActionKeys ? { recentActionKeys: seededResumeState.recentActionKeys } : {}
|
|
8113
|
+
...seededResumeState?.recentActionKeys ? { recentActionKeys: seededResumeState.recentActionKeys } : {},
|
|
8114
|
+
...seededResumeState?.contextCompactionSummaries?.length ? { contextCompactionSummaries: seededResumeState.contextCompactionSummaries } : {},
|
|
8115
|
+
...typeof seededResumeState?.contextWindowBaseIndex === "number" ? { contextWindowBaseIndex: seededResumeState.contextWindowBaseIndex } : {}
|
|
7425
8116
|
};
|
|
8117
|
+
if (options.previousMessages && options.previousMessages.length > 0) {
|
|
8118
|
+
state.messages = options.previousMessages.map((message) => structuredClone(message));
|
|
8119
|
+
}
|
|
7426
8120
|
state.workflowVariant = classifiedVariant;
|
|
7427
8121
|
state.isCreationTask = seededResumeState?.isCreationTask ?? state.workflowVariant === "create";
|
|
7428
8122
|
state.outputRoot = seededResumeState?.outputRoot ?? (state.isCreationTask ? "public/" : void 0);
|
|
@@ -7455,6 +8149,10 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7455
8149
|
}
|
|
7456
8150
|
}
|
|
7457
8151
|
for (let session = 0; session < maxSessions; session++) {
|
|
8152
|
+
if (options.abortSignal?.aborted) {
|
|
8153
|
+
state.status = "paused";
|
|
8154
|
+
break;
|
|
8155
|
+
}
|
|
7458
8156
|
const phaseAtSessionStart = state.workflowPhase;
|
|
7459
8157
|
const sessionTrace = this.createEmptyToolTrace();
|
|
7460
8158
|
const sessionLocalTools = this.wrapLocalToolsForTrace(
|
|
@@ -7491,7 +8189,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7491
8189
|
localTools: options.localTools,
|
|
7492
8190
|
builtinToolSchemas,
|
|
7493
8191
|
onContextCompaction: options.onContextCompaction,
|
|
7494
|
-
onContextNotice: options.onContextNotice
|
|
8192
|
+
onContextNotice: options.onContextNotice,
|
|
8193
|
+
toolContextMode: options.toolContextMode || "hot-tail",
|
|
8194
|
+
toolWindow: options.toolWindow ?? "session"
|
|
7495
8195
|
},
|
|
7496
8196
|
queuedSteeringMessages
|
|
7497
8197
|
);
|
|
@@ -7521,7 +8221,8 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7521
8221
|
sessionCallbacks,
|
|
7522
8222
|
{
|
|
7523
8223
|
onLocalToolResult: this.createLocalToolLoopGuard(state, sessionTrace, workflow),
|
|
7524
|
-
shouldInterrupt: options.hasQueuedUserMessages
|
|
8224
|
+
shouldInterrupt: options.hasQueuedUserMessages,
|
|
8225
|
+
...options.abortSignal ? { abortSignal: options.abortSignal } : {}
|
|
7525
8226
|
},
|
|
7526
8227
|
state.taskName
|
|
7527
8228
|
);
|
|
@@ -7670,22 +8371,13 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7670
8371
|
}
|
|
7671
8372
|
}
|
|
7672
8373
|
if (!state.messages) state.messages = [];
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
state.messages.push(...newMessages);
|
|
7678
|
-
} else {
|
|
8374
|
+
const sentUserMessage = messages[messages.length - 1];
|
|
8375
|
+
if (sentUserMessage?.role === "user") {
|
|
8376
|
+
state.messages.push(sentUserMessage);
|
|
8377
|
+
} else if (state.messages.length === 0) {
|
|
7679
8378
|
state.messages.push(...messages);
|
|
7680
8379
|
}
|
|
7681
8380
|
if (sessionToolMessages.length > 0) {
|
|
7682
|
-
this.compactToolResults(
|
|
7683
|
-
state.messages,
|
|
7684
|
-
sessionToolMessages,
|
|
7685
|
-
state.taskName,
|
|
7686
|
-
options.toolContextMode || "hot-tail",
|
|
7687
|
-
options.toolWindow ?? "session"
|
|
7688
|
-
);
|
|
7689
8381
|
state.messages.push(...sessionToolMessages);
|
|
7690
8382
|
}
|
|
7691
8383
|
const assistantContent = effectiveSessionOutput || `[Session ${session + 1} completed (${sessionResult.stopReason}). No text output captured.]`;
|
|
@@ -7705,7 +8397,10 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7705
8397
|
workflow
|
|
7706
8398
|
);
|
|
7707
8399
|
if (detectedTaskCompletion && !acceptedTaskCompletion) {
|
|
7708
|
-
state.lastCompletionRejectionReason = this.computeCompletionRejectionReason(
|
|
8400
|
+
state.lastCompletionRejectionReason = this.computeCompletionRejectionReason(
|
|
8401
|
+
state,
|
|
8402
|
+
sessionTrace
|
|
8403
|
+
);
|
|
7709
8404
|
if (state.verificationRequired && !state.lastVerificationPassed && !sessionTrace.verificationPassed && !sessionTrace.verificationAttempted) {
|
|
7710
8405
|
state.consecutiveBlockedVerificationSessions = (state.consecutiveBlockedVerificationSessions || 0) + 1;
|
|
7711
8406
|
if ((state.consecutiveBlockedVerificationSessions || 0) >= 2) {
|
|
@@ -7724,24 +8419,24 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7724
8419
|
}
|
|
7725
8420
|
if (sessionResult.stopReason === "complete" && !detectedTaskCompletion) {
|
|
7726
8421
|
const currentPhase = workflow.phases.find((p) => p.name === state.workflowPhase);
|
|
7727
|
-
const gatesSatisfied = currentPhase?.canAcceptCompletion ? currentPhase.canAcceptCompletion(
|
|
8422
|
+
const gatesSatisfied = currentPhase?.canAcceptCompletion ? currentPhase.canAcceptCompletion(
|
|
8423
|
+
state,
|
|
8424
|
+
sessionTrace
|
|
8425
|
+
) : true;
|
|
7728
8426
|
if (gatesSatisfied) {
|
|
7729
8427
|
state.status = "complete";
|
|
7730
8428
|
}
|
|
7731
8429
|
} else if (sessionResult.stopReason === "error") {
|
|
7732
8430
|
if (_AgentsEndpoint.isRetryableSessionError(sessionResult.error) && consecutiveServerNetworkErrors < maxServerNetworkRetries) {
|
|
7733
8431
|
consecutiveServerNetworkErrors++;
|
|
7734
|
-
const delayMs = Math.min(
|
|
7735
|
-
5e3 * Math.pow(2, consecutiveServerNetworkErrors - 1),
|
|
7736
|
-
3e4
|
|
7737
|
-
);
|
|
8432
|
+
const delayMs = Math.min(5e3 * Math.pow(2, consecutiveServerNetworkErrors - 1), 3e4);
|
|
7738
8433
|
const delaySec = Math.round(delayMs / 1e3);
|
|
7739
8434
|
await this.emitContextNotice(options.onContextNotice, {
|
|
7740
8435
|
kind: "server_network_retry",
|
|
7741
8436
|
sessionIndex: session,
|
|
7742
8437
|
message: `Server network error: ${sessionResult.error}. Retrying in ${delaySec}s (attempt ${consecutiveServerNetworkErrors}/${maxServerNetworkRetries})...`
|
|
7743
8438
|
});
|
|
7744
|
-
await
|
|
8439
|
+
await sleepWithAbort(delayMs, options.abortSignal);
|
|
7745
8440
|
} else {
|
|
7746
8441
|
state.status = "error";
|
|
7747
8442
|
}
|
|
@@ -7756,6 +8451,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7756
8451
|
} else if (session + 1 >= maxSessions) {
|
|
7757
8452
|
state.status = "max_sessions";
|
|
7758
8453
|
}
|
|
8454
|
+
if (options.abortSignal?.aborted) {
|
|
8455
|
+
state.status = "paused";
|
|
8456
|
+
}
|
|
7759
8457
|
if (options.trackProgress) {
|
|
7760
8458
|
recordId = await this.syncProgressRecord(state, recordId);
|
|
7761
8459
|
}
|
|
@@ -7832,6 +8530,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7832
8530
|
return 0;
|
|
7833
8531
|
}
|
|
7834
8532
|
}
|
|
8533
|
+
extractDeclaredToolResultChars(value) {
|
|
8534
|
+
return extractDeclaredToolResultChars(value);
|
|
8535
|
+
}
|
|
7835
8536
|
estimateMessageContentTokens(content) {
|
|
7836
8537
|
if (typeof content === "string") return this.estimateTextTokens(content);
|
|
7837
8538
|
return content.reduce((total, part) => {
|
|
@@ -7850,12 +8551,14 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7850
8551
|
0
|
|
7851
8552
|
);
|
|
7852
8553
|
}
|
|
7853
|
-
estimateToolResultTokens(toolResults) {
|
|
8554
|
+
estimateToolResultTokens(toolResults, options) {
|
|
7854
8555
|
if (!toolResults || toolResults.length === 0) return 0;
|
|
7855
|
-
return toolResults.reduce(
|
|
7856
|
-
|
|
7857
|
-
0
|
|
7858
|
-
|
|
8556
|
+
return toolResults.reduce((sum, toolResult) => {
|
|
8557
|
+
const resultTokens = this.estimateUnknownTokens(toolResult.result);
|
|
8558
|
+
const declaredChars = options?.useDeclaredSize ? this.extractDeclaredToolResultChars(toolResult.result) : void 0;
|
|
8559
|
+
const declaredTokens = typeof declaredChars === "number" ? Math.ceil(declaredChars / 4) : 0;
|
|
8560
|
+
return sum + 12 + this.estimateTextTokens(toolResult.toolName) + Math.max(resultTokens, declaredTokens);
|
|
8561
|
+
}, 0);
|
|
7859
8562
|
}
|
|
7860
8563
|
estimateMessageTokens(message) {
|
|
7861
8564
|
return 6 + this.estimateMessageContentTokens(message.content) + this.estimateToolCallTokens(message.toolCalls) + this.estimateToolResultTokens(message.toolResults);
|
|
@@ -7863,13 +8566,15 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7863
8566
|
estimateConversationTokens(messages) {
|
|
7864
8567
|
return messages.reduce((sum, message) => sum + this.estimateMessageTokens(message), 0);
|
|
7865
8568
|
}
|
|
7866
|
-
estimateConversationBreakdown(messages) {
|
|
8569
|
+
estimateConversationBreakdown(messages, options) {
|
|
7867
8570
|
let historyTokens = 0;
|
|
7868
8571
|
let toolOutputTokens = 0;
|
|
7869
8572
|
for (const message of messages) {
|
|
7870
8573
|
const contentTokens = this.estimateMessageContentTokens(message.content);
|
|
7871
8574
|
const toolCallTokens = this.estimateToolCallTokens(message.toolCalls);
|
|
7872
|
-
const toolResultTokens = this.estimateToolResultTokens(message.toolResults
|
|
8575
|
+
const toolResultTokens = this.estimateToolResultTokens(message.toolResults, {
|
|
8576
|
+
useDeclaredSize: options?.useDeclaredToolResultSizes
|
|
8577
|
+
});
|
|
7873
8578
|
const messageTotal = 6 + contentTokens + toolCallTokens + toolResultTokens;
|
|
7874
8579
|
if (message.role === "tool") {
|
|
7875
8580
|
toolOutputTokens += messageTotal;
|
|
@@ -7923,13 +8628,24 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7923
8628
|
const compactInstructions = config.compactInstructions;
|
|
7924
8629
|
return typeof compactInstructions === "string" && compactInstructions.trim() ? compactInstructions.trim() : void 0;
|
|
7925
8630
|
}
|
|
7926
|
-
|
|
8631
|
+
extractArtifactReferencesFromMessages(messages = []) {
|
|
7927
8632
|
const references = /* @__PURE__ */ new Set();
|
|
7928
8633
|
const offloadPrefix = "[Output saved to ";
|
|
7929
|
-
|
|
8634
|
+
const ledgerArtifactPrefix = LEDGER_ARTIFACT_LINE_PREFIX;
|
|
8635
|
+
const savedToPattern = /saved to\s+([^—\]\n]+?)(?:\s+—|\]|\n|$)/gi;
|
|
8636
|
+
for (const message of messages) {
|
|
7930
8637
|
if (!message.toolResults) continue;
|
|
7931
8638
|
for (const toolResult of message.toolResults) {
|
|
7932
8639
|
if (typeof toolResult.result !== "string") continue;
|
|
8640
|
+
for (const line of toolResult.result.split("\n")) {
|
|
8641
|
+
if (line.startsWith(ledgerArtifactPrefix)) {
|
|
8642
|
+
references.add(line.slice(ledgerArtifactPrefix.length).trim());
|
|
8643
|
+
}
|
|
8644
|
+
}
|
|
8645
|
+
for (const match of toolResult.result.matchAll(savedToPattern)) {
|
|
8646
|
+
const pathText = match[1]?.trim();
|
|
8647
|
+
if (pathText) references.add(pathText);
|
|
8648
|
+
}
|
|
7933
8649
|
let startIndex = 0;
|
|
7934
8650
|
while (startIndex < toolResult.result.length) {
|
|
7935
8651
|
const prefixIndex = toolResult.result.indexOf(offloadPrefix, startIndex);
|
|
@@ -7947,6 +8663,13 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7947
8663
|
}
|
|
7948
8664
|
}
|
|
7949
8665
|
}
|
|
8666
|
+
return Array.from(references);
|
|
8667
|
+
}
|
|
8668
|
+
extractArtifactReferences(state, additionalReferences = []) {
|
|
8669
|
+
const references = /* @__PURE__ */ new Set([
|
|
8670
|
+
...this.extractArtifactReferencesFromMessages(state.messages ?? []),
|
|
8671
|
+
...additionalReferences
|
|
8672
|
+
]);
|
|
7950
8673
|
if (state.planPath) {
|
|
7951
8674
|
references.add(state.planPath);
|
|
7952
8675
|
}
|
|
@@ -7954,6 +8677,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7954
8677
|
}
|
|
7955
8678
|
buildContextBudgetBreakdown(details) {
|
|
7956
8679
|
const conversationBreakdown = this.estimateConversationBreakdown(details.historyMessages);
|
|
8680
|
+
const sourceConversationBreakdown = details.sourceHistoryMessages ? this.estimateConversationBreakdown(details.sourceHistoryMessages, {
|
|
8681
|
+
useDeclaredToolResultSizes: true
|
|
8682
|
+
}) : conversationBreakdown;
|
|
7957
8683
|
const currentTurnTokens = this.estimateTextTokens(details.currentTurnContent);
|
|
7958
8684
|
const toolDefinitionTokens = this.estimateToolDefinitionTokens(
|
|
7959
8685
|
details.localTools,
|
|
@@ -7970,15 +8696,26 @@ ${details.summaryText}
|
|
|
7970
8696
|
|
|
7971
8697
|
Do NOT redo any of the above work.`
|
|
7972
8698
|
) : void 0;
|
|
8699
|
+
const sendEstimatedInputTokens = conversationBreakdown.estimatedInputTokens + currentTurnTokens + toolDefinitionTokens;
|
|
8700
|
+
const estimatedInputTokens = sourceConversationBreakdown.estimatedInputTokens + currentTurnTokens + toolDefinitionTokens;
|
|
8701
|
+
const toolOutputReductionTokens = Math.max(
|
|
8702
|
+
0,
|
|
8703
|
+
sourceConversationBreakdown.toolOutputTokens - conversationBreakdown.toolOutputTokens
|
|
8704
|
+
);
|
|
7973
8705
|
return {
|
|
7974
|
-
historyTokens:
|
|
7975
|
-
toolOutputTokens:
|
|
8706
|
+
historyTokens: sourceConversationBreakdown.historyTokens,
|
|
8707
|
+
toolOutputTokens: sourceConversationBreakdown.toolOutputTokens,
|
|
7976
8708
|
currentTurnTokens,
|
|
7977
8709
|
toolDefinitionTokens,
|
|
7978
8710
|
...summaryTokens ? { summaryTokens } : {},
|
|
7979
8711
|
...reservedOutputTokens ? { reservedOutputTokens } : {},
|
|
7980
8712
|
...effectiveInputBudgetTokens ? { effectiveInputBudgetTokens } : {},
|
|
7981
|
-
|
|
8713
|
+
...toolOutputReductionTokens > 0 ? {
|
|
8714
|
+
sendEstimatedInputTokens,
|
|
8715
|
+
sendToolOutputTokens: conversationBreakdown.toolOutputTokens,
|
|
8716
|
+
toolOutputReductionTokens
|
|
8717
|
+
} : {},
|
|
8718
|
+
estimatedInputTokens
|
|
7982
8719
|
};
|
|
7983
8720
|
}
|
|
7984
8721
|
async emitContextCompactionEvent(onContextCompaction, event) {
|
|
@@ -8018,16 +8755,33 @@ Do NOT redo any of the above work.`
|
|
|
8018
8755
|
state,
|
|
8019
8756
|
userContent,
|
|
8020
8757
|
details.compactInstructions,
|
|
8021
|
-
details.mode
|
|
8758
|
+
details.mode,
|
|
8759
|
+
details.artifactReferences
|
|
8022
8760
|
);
|
|
8761
|
+
const summaryMessage = compactMessages[0];
|
|
8762
|
+
if (summaryMessage?.role === "system" && typeof summaryMessage.content === "string") {
|
|
8763
|
+
const existingSummaries = state.contextCompactionSummaries ?? [];
|
|
8764
|
+
state.contextCompactionSummaries = [
|
|
8765
|
+
...existingSummaries,
|
|
8766
|
+
{
|
|
8767
|
+
id: `ctx_${sessionIndex + 1}_${existingSummaries.length + 1}`,
|
|
8768
|
+
sessionIndex: sessionIndex + 1,
|
|
8769
|
+
mode: details.mode,
|
|
8770
|
+
strategy: details.strategy,
|
|
8771
|
+
content: summaryMessage.content,
|
|
8772
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8773
|
+
}
|
|
8774
|
+
].slice(-20);
|
|
8775
|
+
}
|
|
8776
|
+
state.contextWindowBaseIndex = state.messages?.length ?? 0;
|
|
8023
8777
|
await this.emitContextCompactionEvent(details.onContextCompaction, {
|
|
8024
8778
|
phase: "complete",
|
|
8025
8779
|
...baseEvent
|
|
8026
8780
|
});
|
|
8027
8781
|
return compactMessages;
|
|
8028
8782
|
}
|
|
8029
|
-
buildCompactHistoryMessages(state, userContent, compactInstructions, mode = "auto") {
|
|
8030
|
-
const summary = this.generateCompactSummary(state, compactInstructions);
|
|
8783
|
+
buildCompactHistoryMessages(state, userContent, compactInstructions, mode = "auto", artifactReferences) {
|
|
8784
|
+
const summary = this.generateCompactSummary(state, compactInstructions, artifactReferences);
|
|
8031
8785
|
const prefix = mode === "forced" ? this.getForcedCompactionSummaryPrefix(state) : _AgentsEndpoint.AUTO_COMPACT_SUMMARY_PREFIX;
|
|
8032
8786
|
return [
|
|
8033
8787
|
{
|
|
@@ -8044,16 +8798,11 @@ Do NOT redo any of the above work.`
|
|
|
8044
8798
|
}
|
|
8045
8799
|
];
|
|
8046
8800
|
}
|
|
8047
|
-
isCompactHistoryMessageSet(messages) {
|
|
8048
|
-
if (messages.length === 0) return false;
|
|
8049
|
-
const firstMessage = messages[0];
|
|
8050
|
-
return firstMessage?.role === "system" && typeof firstMessage.content === "string" && (firstMessage.content.startsWith(_AgentsEndpoint.AUTO_COMPACT_SUMMARY_PREFIX) || firstMessage.content.startsWith(_AgentsEndpoint.RESUMED_COMPACT_SUMMARY_PREFIX) || firstMessage.content.startsWith(_AgentsEndpoint.COMPLETED_COMPACT_SUMMARY_PREFIX));
|
|
8051
|
-
}
|
|
8052
8801
|
/**
|
|
8053
8802
|
* Generate a compact summary of prior work for continuation context.
|
|
8054
8803
|
* Used when compact mode is enabled to keep token usage low.
|
|
8055
8804
|
*/
|
|
8056
|
-
generateCompactSummary(state, compactInstructions) {
|
|
8805
|
+
generateCompactSummary(state, compactInstructions, additionalArtifactReferences = []) {
|
|
8057
8806
|
const recentSessions = (state.sessions ?? []).slice(-5);
|
|
8058
8807
|
const sessionSummaries = recentSessions.map(
|
|
8059
8808
|
(session) => `- Session ${session.index}: ${session.stopReason} ($${session.cost.toFixed(4)}) ${session.outputPreview.slice(0, 160)}`
|
|
@@ -8067,7 +8816,7 @@ Do NOT redo any of the above work.`
|
|
|
8067
8816
|
)
|
|
8068
8817
|
).slice(0, 8);
|
|
8069
8818
|
const verificationSummary = state.bestCandidateVerified ? "Latest candidate verified." : state.bestCandidateNeedsVerification ? "Latest candidate still needs verification." : state.lastVerificationPassed ? "Latest verification passed." : state.verificationRequired ? "Verification is still required." : "No verification requirement recorded.";
|
|
8070
|
-
const artifactReferences = this.extractArtifactReferences(state);
|
|
8819
|
+
const artifactReferences = this.extractArtifactReferences(state, additionalArtifactReferences);
|
|
8071
8820
|
const pendingNextStep = state.lastStopReason === "complete" ? "Confirm nothing else remains before declaring the task complete." : `Continue the ${state.workflowPhase || "research"} phase without redoing prior work.`;
|
|
8072
8821
|
const instructions = compactInstructions || this.buildDefaultCompactInstructions();
|
|
8073
8822
|
return [
|
|
@@ -8282,14 +9031,23 @@ Do NOT redo any of the above work.`
|
|
|
8282
9031
|
const phaseBlock = ["", this.buildPhaseInstructions(state, wf)].join("\n");
|
|
8283
9032
|
const candidateBlock = wf.buildCandidateBlock?.(state) ?? "";
|
|
8284
9033
|
const multiSessionInstruction = `This is a multi-session task (session ${sessionIndex + 1}/${maxSessions}). When you have fully completed the task, end your response with TASK_COMPLETE on its own line.`;
|
|
8285
|
-
const steeringLines = steeringMessages && steeringMessages.length > 0 ? [
|
|
8286
|
-
"--- User steering (queued during the previous session) ---",
|
|
8287
|
-
...steeringMessages,
|
|
8288
|
-
""
|
|
8289
|
-
] : [];
|
|
9034
|
+
const steeringLines = steeringMessages && steeringMessages.length > 0 ? ["--- User steering (queued during the previous session) ---", ...steeringMessages, ""] : [];
|
|
8290
9035
|
if (continuationContext && sessionIndex === 0) {
|
|
8291
|
-
const
|
|
8292
|
-
|
|
9036
|
+
const resumeWindow = this.resolveWindowReplay(
|
|
9037
|
+
state,
|
|
9038
|
+
continuationContext.previousMessages.length
|
|
9039
|
+
);
|
|
9040
|
+
const sourceReplayHistoryMessages = [
|
|
9041
|
+
...resumeWindow.windowSummaryMessages,
|
|
9042
|
+
...this.sanitizeReplayHistoryMessages(
|
|
9043
|
+
continuationContext.previousMessages.slice(resumeWindow.windowBase)
|
|
9044
|
+
)
|
|
9045
|
+
];
|
|
9046
|
+
const replayHistoryMessages = this.deriveToolContextMessages(
|
|
9047
|
+
sourceReplayHistoryMessages,
|
|
9048
|
+
state.taskName,
|
|
9049
|
+
compactionOptions?.toolContextMode || "hot-tail",
|
|
9050
|
+
compactionOptions?.toolWindow ?? "session"
|
|
8293
9051
|
);
|
|
8294
9052
|
const continuationGuardrail = this.buildContinuationGuardrail(state);
|
|
8295
9053
|
const defaultContinueMessage = "Continue the task. Review your prior work above and proceed with any remaining work. If everything is already complete, respond with TASK_COMPLETE.";
|
|
@@ -8313,9 +9071,15 @@ Do NOT redo any of the above work.`
|
|
|
8313
9071
|
content: userContent
|
|
8314
9072
|
}
|
|
8315
9073
|
];
|
|
8316
|
-
const
|
|
9074
|
+
const replayArtifactReferences = this.extractArtifactReferencesFromMessages(replayHistoryMessages);
|
|
9075
|
+
const summaryText = this.generateCompactSummary(
|
|
9076
|
+
state,
|
|
9077
|
+
compactInstructions,
|
|
9078
|
+
replayArtifactReferences
|
|
9079
|
+
);
|
|
8317
9080
|
const breakdown = this.buildContextBudgetBreakdown({
|
|
8318
9081
|
historyMessages: replayHistoryMessages,
|
|
9082
|
+
sourceHistoryMessages: sourceReplayHistoryMessages,
|
|
8319
9083
|
currentTurnContent: userContent,
|
|
8320
9084
|
localTools: compactionOptions?.localTools,
|
|
8321
9085
|
builtinToolSchemas: compactionOptions?.builtinToolSchemas || [],
|
|
@@ -8341,7 +9105,8 @@ Do NOT redo any of the above work.`
|
|
|
8341
9105
|
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
8342
9106
|
breakdown,
|
|
8343
9107
|
onContextCompaction: compactionOptions?.onContextCompaction,
|
|
8344
|
-
compactInstructions
|
|
9108
|
+
compactInstructions,
|
|
9109
|
+
artifactReferences: replayArtifactReferences
|
|
8345
9110
|
}
|
|
8346
9111
|
),
|
|
8347
9112
|
requestContextManagement
|
|
@@ -8365,7 +9130,8 @@ Do NOT redo any of the above work.`
|
|
|
8365
9130
|
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
8366
9131
|
breakdown,
|
|
8367
9132
|
onContextCompaction: compactionOptions?.onContextCompaction,
|
|
8368
|
-
compactInstructions
|
|
9133
|
+
compactInstructions,
|
|
9134
|
+
artifactReferences: replayArtifactReferences
|
|
8369
9135
|
}
|
|
8370
9136
|
),
|
|
8371
9137
|
requestContextManagement
|
|
@@ -8416,23 +9182,45 @@ Do NOT redo any of the above work.`
|
|
|
8416
9182
|
"Do not redo previous work. If the task is already complete, respond with TASK_COMPLETE."
|
|
8417
9183
|
].join("\n");
|
|
8418
9184
|
const MAX_HISTORY_MESSAGES = 60;
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
9185
|
+
const { windowBase, windowSummaryMessages } = this.resolveWindowReplay(
|
|
9186
|
+
state,
|
|
9187
|
+
state.messages.length
|
|
9188
|
+
);
|
|
9189
|
+
let sourceHistoryMessages = this.sanitizeReplayHistoryMessages(
|
|
9190
|
+
state.messages.slice(windowBase)
|
|
9191
|
+
);
|
|
9192
|
+
if (sourceHistoryMessages.length > MAX_HISTORY_MESSAGES) {
|
|
9193
|
+
const trimmedHistory = this.trimReplayHistoryMessages(
|
|
9194
|
+
sourceHistoryMessages,
|
|
9195
|
+
MAX_HISTORY_MESSAGES
|
|
9196
|
+
);
|
|
9197
|
+
sourceHistoryMessages = trimmedHistory.historyMessages;
|
|
8423
9198
|
if (trimmedHistory.trimmedCount > 0) {
|
|
8424
|
-
|
|
9199
|
+
sourceHistoryMessages = [
|
|
8425
9200
|
{
|
|
8426
9201
|
role: "system",
|
|
8427
9202
|
content: `[${trimmedHistory.trimmedCount} earlier messages trimmed to stay within context limits. Original task: ${(state.originalMessage || originalMessage).slice(0, 500)}]`
|
|
8428
9203
|
},
|
|
8429
|
-
...
|
|
9204
|
+
...sourceHistoryMessages
|
|
8430
9205
|
];
|
|
8431
9206
|
}
|
|
8432
9207
|
}
|
|
8433
|
-
|
|
9208
|
+
sourceHistoryMessages = [...windowSummaryMessages, ...sourceHistoryMessages];
|
|
9209
|
+
const historyMessages = this.deriveToolContextMessages(
|
|
9210
|
+
sourceHistoryMessages,
|
|
9211
|
+
state.taskName,
|
|
9212
|
+
compactionOptions?.toolContextMode || "hot-tail",
|
|
9213
|
+
compactionOptions?.toolWindow ?? "session"
|
|
9214
|
+
);
|
|
9215
|
+
const historyArtifactReferences = this.extractArtifactReferencesFromMessages(historyMessages);
|
|
9216
|
+
const summaryText = this.generateCompactSummary(
|
|
9217
|
+
state,
|
|
9218
|
+
compactInstructions,
|
|
9219
|
+
historyArtifactReferences
|
|
9220
|
+
);
|
|
8434
9221
|
const breakdown = this.buildContextBudgetBreakdown({
|
|
8435
9222
|
historyMessages,
|
|
9223
|
+
sourceHistoryMessages,
|
|
8436
9224
|
currentTurnContent: continuationContent,
|
|
8437
9225
|
localTools: compactionOptions?.localTools,
|
|
8438
9226
|
builtinToolSchemas: compactionOptions?.builtinToolSchemas || [],
|
|
@@ -8459,7 +9247,8 @@ Do NOT redo any of the above work.`
|
|
|
8459
9247
|
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
8460
9248
|
breakdown,
|
|
8461
9249
|
onContextCompaction: compactionOptions?.onContextCompaction,
|
|
8462
|
-
compactInstructions
|
|
9250
|
+
compactInstructions,
|
|
9251
|
+
artifactReferences: historyArtifactReferences
|
|
8463
9252
|
}
|
|
8464
9253
|
),
|
|
8465
9254
|
requestContextManagement
|
|
@@ -8933,6 +9722,52 @@ var BillingEndpoint = class {
|
|
|
8933
9722
|
return this.client.get("/billing/spend-analytics", params);
|
|
8934
9723
|
}
|
|
8935
9724
|
};
|
|
9725
|
+
var AppsEndpoint = class {
|
|
9726
|
+
constructor(client) {
|
|
9727
|
+
this.client = client;
|
|
9728
|
+
}
|
|
9729
|
+
/** List apps for the authenticated owner, newest first. */
|
|
9730
|
+
async list() {
|
|
9731
|
+
return this.client.get("/apps");
|
|
9732
|
+
}
|
|
9733
|
+
/** Get an app by id, including its URL and active version pointer. */
|
|
9734
|
+
async get(id) {
|
|
9735
|
+
return this.client.get(`/apps/${id}`);
|
|
9736
|
+
}
|
|
9737
|
+
/** Create an app. A client token scoped to the app origin is auto-provisioned. */
|
|
9738
|
+
async create(data) {
|
|
9739
|
+
return this.client.post("/apps", data);
|
|
9740
|
+
}
|
|
9741
|
+
/** Update name, description, visibility, or status (suspended serves 410). */
|
|
9742
|
+
async update(id, data) {
|
|
9743
|
+
return this.client.patch(`/apps/${id}`, data);
|
|
9744
|
+
}
|
|
9745
|
+
/** Delete an app, its versions, and its hosting. Irreversible. */
|
|
9746
|
+
async delete(id) {
|
|
9747
|
+
return this.client.delete(`/apps/${id}`);
|
|
9748
|
+
}
|
|
9749
|
+
/** List an app's versions, newest first. */
|
|
9750
|
+
async listVersions(id) {
|
|
9751
|
+
return this.client.get(`/apps/${id}/versions`);
|
|
9752
|
+
}
|
|
9753
|
+
/** Upload a zipped bundle (raw application/zip body) as a new version. */
|
|
9754
|
+
async uploadVersion(id, zipBytes) {
|
|
9755
|
+
return this.client.postBinary(`/apps/${id}/versions`, zipBytes, "application/zip");
|
|
9756
|
+
}
|
|
9757
|
+
/**
|
|
9758
|
+
* Upload a bundle from in-memory file maps (the API zips server-side).
|
|
9759
|
+
* Text files in `files`, binary files base64-encoded in `filesBase64`.
|
|
9760
|
+
*/
|
|
9761
|
+
async uploadVersionFiles(id, data) {
|
|
9762
|
+
return this.client.post(`/apps/${id}/versions`, data);
|
|
9763
|
+
}
|
|
9764
|
+
/** Activate an uploaded version (deploy or rollback). */
|
|
9765
|
+
async activate(id, versionId) {
|
|
9766
|
+
return this.client.post(`/apps/${id}/activate`, {
|
|
9767
|
+
versionId
|
|
9768
|
+
});
|
|
9769
|
+
}
|
|
9770
|
+
};
|
|
8936
9771
|
|
|
8937
9772
|
// src/client.ts
|
|
8938
9773
|
function isObjectRecord(value) {
|
|
@@ -8975,6 +9810,7 @@ var RuntypeClient2 = class {
|
|
|
8975
9810
|
this.clientTokens = new ClientTokensEndpoint(this);
|
|
8976
9811
|
this.agents = new AgentsEndpoint(this);
|
|
8977
9812
|
this.secrets = new SecretsEndpoint(this);
|
|
9813
|
+
this.apps = new AppsEndpoint(this);
|
|
8978
9814
|
this.schedules = new SchedulesEndpoint(this);
|
|
8979
9815
|
this.surfaces = new SurfacesEndpoint(this);
|
|
8980
9816
|
this.conversations = new ConversationsEndpoint(this);
|
|
@@ -9021,7 +9857,7 @@ var RuntypeClient2 = class {
|
|
|
9021
9857
|
clearApiKey() {
|
|
9022
9858
|
delete this.headers.Authorization;
|
|
9023
9859
|
}
|
|
9024
|
-
async runWithLocalTools(
|
|
9860
|
+
async runWithLocalTools(request2, localTools, arg3, arg4) {
|
|
9025
9861
|
const isOptionsObject = (val) => typeof val === "object" && val !== null && "scope" in val;
|
|
9026
9862
|
const callbacks = isOptionsObject(arg3) ? void 0 : arg3;
|
|
9027
9863
|
const options = (isOptionsObject(arg3) ? arg3 : arg4) ?? {};
|
|
@@ -9035,12 +9871,12 @@ var RuntypeClient2 = class {
|
|
|
9035
9871
|
...entry.pageOrigin ? { pageOrigin: entry.pageOrigin } : {}
|
|
9036
9872
|
})) : [];
|
|
9037
9873
|
const modifiedRequest = {
|
|
9038
|
-
...
|
|
9874
|
+
...request2,
|
|
9039
9875
|
...derivedClientTools.length > 0 ? {
|
|
9040
|
-
clientTools: [...
|
|
9876
|
+
clientTools: [...request2.clientTools ?? [], ...derivedClientTools]
|
|
9041
9877
|
} : {},
|
|
9042
9878
|
options: {
|
|
9043
|
-
...
|
|
9879
|
+
...request2.options || {},
|
|
9044
9880
|
streamResponse: isStreaming
|
|
9045
9881
|
}
|
|
9046
9882
|
};
|
|
@@ -9056,13 +9892,12 @@ var RuntypeClient2 = class {
|
|
|
9056
9892
|
onFlowComplete: (event) => callbacks?.onFlowComplete?.(event),
|
|
9057
9893
|
onError: (error) => callbacks?.onError?.(error)
|
|
9058
9894
|
};
|
|
9059
|
-
const { streamEvents: streamEvents2, stepDeltaText: stepDeltaText2, stepDisplayName: stepDisplayName2, flowErrorMessage: flowErrorMessage2 } = await Promise.resolve().then(() => (init_stream_utils(), stream_utils_exports));
|
|
9060
9895
|
const summary = {
|
|
9061
9896
|
results: /* @__PURE__ */ new Map(),
|
|
9062
9897
|
success: true
|
|
9063
9898
|
};
|
|
9064
9899
|
try {
|
|
9065
|
-
for await (const event of
|
|
9900
|
+
for await (const event of streamEvents(response)) {
|
|
9066
9901
|
collectLocalToolAwait(pausedTools, event);
|
|
9067
9902
|
switch (event.type) {
|
|
9068
9903
|
case "flow_start":
|
|
@@ -9072,10 +9907,10 @@ var RuntypeClient2 = class {
|
|
|
9072
9907
|
wrappedCallbacks.onStepStart?.(event);
|
|
9073
9908
|
break;
|
|
9074
9909
|
case "step_delta":
|
|
9075
|
-
wrappedCallbacks.onStepDelta?.(
|
|
9910
|
+
wrappedCallbacks.onStepDelta?.(stepDeltaText(event), event);
|
|
9076
9911
|
break;
|
|
9077
9912
|
case "step_complete": {
|
|
9078
|
-
summary.results?.set(
|
|
9913
|
+
summary.results?.set(stepDisplayName(event), event.result);
|
|
9079
9914
|
wrappedCallbacks.onStepComplete?.(event.result, event);
|
|
9080
9915
|
break;
|
|
9081
9916
|
}
|
|
@@ -9083,7 +9918,7 @@ var RuntypeClient2 = class {
|
|
|
9083
9918
|
wrappedCallbacks.onFlowComplete?.(event);
|
|
9084
9919
|
break;
|
|
9085
9920
|
case "flow_error":
|
|
9086
|
-
wrappedCallbacks.onError?.(new Error(
|
|
9921
|
+
wrappedCallbacks.onError?.(new Error(flowErrorMessage(event)));
|
|
9087
9922
|
break;
|
|
9088
9923
|
}
|
|
9089
9924
|
}
|
|
@@ -9162,7 +9997,8 @@ var RuntypeClient2 = class {
|
|
|
9162
9997
|
return [toolName, await handler(parameters)];
|
|
9163
9998
|
} catch (error) {
|
|
9164
9999
|
throw new Error(
|
|
9165
|
-
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}
|
|
10000
|
+
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`,
|
|
10001
|
+
{ cause: error }
|
|
9166
10002
|
);
|
|
9167
10003
|
}
|
|
9168
10004
|
})
|
|
@@ -9226,6 +10062,21 @@ var RuntypeClient2 = class {
|
|
|
9226
10062
|
});
|
|
9227
10063
|
return transformResponse(response);
|
|
9228
10064
|
}
|
|
10065
|
+
/**
|
|
10066
|
+
* POST request with a raw binary body (e.g. application/zip bundle uploads).
|
|
10067
|
+
*/
|
|
10068
|
+
async postBinary(path, body, contentType) {
|
|
10069
|
+
const url = this.buildUrl(path);
|
|
10070
|
+
const headers = { ...this.headers, "Content-Type": contentType };
|
|
10071
|
+
const response = await this.makeRequest(url, {
|
|
10072
|
+
method: "POST",
|
|
10073
|
+
headers,
|
|
10074
|
+
// TS 5.7 types Uint8Array over ArrayBufferLike, which no longer
|
|
10075
|
+
// overlaps DOM BodyInit; the runtime value is a valid fetch body.
|
|
10076
|
+
body
|
|
10077
|
+
});
|
|
10078
|
+
return transformResponse(response);
|
|
10079
|
+
}
|
|
9229
10080
|
/**
|
|
9230
10081
|
* Generic request that returns raw Response for streaming
|
|
9231
10082
|
*/
|
|
@@ -9326,7 +10177,7 @@ var RuntypeClient2 = class {
|
|
|
9326
10177
|
} catch (error) {
|
|
9327
10178
|
if (timeoutId) clearTimeout(timeoutId);
|
|
9328
10179
|
if (timeoutId && error instanceof Error && error.name === "AbortError") {
|
|
9329
|
-
throw new Error(`Request timeout after ${this.timeout}ms
|
|
10180
|
+
throw new Error(`Request timeout after ${this.timeout}ms`, { cause: error });
|
|
9330
10181
|
}
|
|
9331
10182
|
throw error;
|
|
9332
10183
|
}
|
|
@@ -9335,8 +10186,18 @@ var RuntypeClient2 = class {
|
|
|
9335
10186
|
* Make HTTP request that returns raw Response (for streaming)
|
|
9336
10187
|
*/
|
|
9337
10188
|
async makeRawRequest(url, options) {
|
|
9338
|
-
const
|
|
10189
|
+
const callerSignal = options.signal ?? null;
|
|
10190
|
+
const controller = this.timeout === null && !callerSignal ? null : new AbortController();
|
|
9339
10191
|
const timeoutId = controller && this.timeout !== null ? setTimeout(() => controller.abort(), this.timeout) : null;
|
|
10192
|
+
if (callerSignal && controller) {
|
|
10193
|
+
if (callerSignal.aborted) {
|
|
10194
|
+
controller.abort(callerSignal.reason);
|
|
10195
|
+
} else {
|
|
10196
|
+
callerSignal.addEventListener("abort", () => controller.abort(callerSignal.reason), {
|
|
10197
|
+
once: true
|
|
10198
|
+
});
|
|
10199
|
+
}
|
|
10200
|
+
}
|
|
9340
10201
|
try {
|
|
9341
10202
|
const response = await fetch(url, {
|
|
9342
10203
|
...options,
|
|
@@ -9349,8 +10210,8 @@ var RuntypeClient2 = class {
|
|
|
9349
10210
|
return response;
|
|
9350
10211
|
} catch (error) {
|
|
9351
10212
|
if (timeoutId) clearTimeout(timeoutId);
|
|
9352
|
-
if (timeoutId && error instanceof Error && error.name === "AbortError") {
|
|
9353
|
-
throw new Error(`Request timeout after ${this.timeout}ms
|
|
10213
|
+
if (timeoutId && error instanceof Error && error.name === "AbortError" && !callerSignal?.aborted) {
|
|
10214
|
+
throw new Error(`Request timeout after ${this.timeout}ms`, { cause: error });
|
|
9354
10215
|
}
|
|
9355
10216
|
throw error;
|
|
9356
10217
|
}
|
|
@@ -9396,9 +10257,6 @@ function createClient(config) {
|
|
|
9396
10257
|
return new RuntypeClient2(config);
|
|
9397
10258
|
}
|
|
9398
10259
|
|
|
9399
|
-
// src/index.ts
|
|
9400
|
-
init_stream_utils();
|
|
9401
|
-
|
|
9402
10260
|
// src/batch-builder.ts
|
|
9403
10261
|
var BatchBuilder = class {
|
|
9404
10262
|
constructor() {
|
|
@@ -9456,20 +10314,20 @@ var BatchBuilder = class {
|
|
|
9456
10314
|
if (!this.recordType) {
|
|
9457
10315
|
throw new Error("BatchBuilder: recordType is required. Call .forRecordType(type) first.");
|
|
9458
10316
|
}
|
|
9459
|
-
const
|
|
10317
|
+
const request2 = {
|
|
9460
10318
|
flowId: this.flowId,
|
|
9461
10319
|
recordType: this.recordType
|
|
9462
10320
|
};
|
|
9463
10321
|
if (Object.keys(this.batchOptions).length > 0) {
|
|
9464
|
-
|
|
10322
|
+
request2.options = this.batchOptions;
|
|
9465
10323
|
}
|
|
9466
10324
|
if (this.filterConfig) {
|
|
9467
|
-
|
|
10325
|
+
request2.filter = this.filterConfig;
|
|
9468
10326
|
}
|
|
9469
10327
|
if (this.limitConfig !== void 0) {
|
|
9470
|
-
|
|
10328
|
+
request2.limit = this.limitConfig;
|
|
9471
10329
|
}
|
|
9472
|
-
return
|
|
10330
|
+
return request2;
|
|
9473
10331
|
}
|
|
9474
10332
|
/**
|
|
9475
10333
|
* Execute the batch operation
|
|
@@ -9626,32 +10484,32 @@ var EvalBuilder = class {
|
|
|
9626
10484
|
"EvalBuilder: records are required. Call .forRecordType(type) or .withRecords([...]) first."
|
|
9627
10485
|
);
|
|
9628
10486
|
}
|
|
9629
|
-
const
|
|
10487
|
+
const request2 = {};
|
|
9630
10488
|
if (this.flowId) {
|
|
9631
|
-
|
|
10489
|
+
request2.flowId = this.flowId;
|
|
9632
10490
|
} else if (this.virtualFlow) {
|
|
9633
|
-
|
|
10491
|
+
request2.flow = this.virtualFlow;
|
|
9634
10492
|
}
|
|
9635
10493
|
if (this.recordType) {
|
|
9636
|
-
|
|
10494
|
+
request2.recordType = this.recordType;
|
|
9637
10495
|
} else if (this.inlineRecords) {
|
|
9638
|
-
|
|
10496
|
+
request2.records = this.inlineRecords;
|
|
9639
10497
|
}
|
|
9640
10498
|
if (this.modelOverrides) {
|
|
9641
|
-
|
|
10499
|
+
request2.modelOverrides = this.modelOverrides;
|
|
9642
10500
|
} else if (this.modelConfigs) {
|
|
9643
|
-
|
|
10501
|
+
request2.modelConfigs = this.modelConfigs;
|
|
9644
10502
|
}
|
|
9645
10503
|
if (Object.keys(this.evalOptions).length > 0) {
|
|
9646
|
-
|
|
10504
|
+
request2.options = this.evalOptions;
|
|
9647
10505
|
}
|
|
9648
10506
|
if (this.filterConfig) {
|
|
9649
|
-
|
|
10507
|
+
request2.filter = this.filterConfig;
|
|
9650
10508
|
}
|
|
9651
10509
|
if (this.limitConfig !== void 0) {
|
|
9652
|
-
|
|
10510
|
+
request2.limit = this.limitConfig;
|
|
9653
10511
|
}
|
|
9654
|
-
return
|
|
10512
|
+
return request2;
|
|
9655
10513
|
}
|
|
9656
10514
|
/**
|
|
9657
10515
|
* Execute the evaluation
|
|
@@ -10117,10 +10975,14 @@ var STEP_TYPE_TO_METHOD = {
|
|
|
10117
10975
|
"memory-summary": "memorySummary"
|
|
10118
10976
|
};
|
|
10119
10977
|
export {
|
|
10978
|
+
AgentDriftError,
|
|
10979
|
+
AgentEnsureConflictError,
|
|
10120
10980
|
AgentVersionsEndpoint,
|
|
10121
10981
|
AgentsEndpoint,
|
|
10982
|
+
AgentsNamespace,
|
|
10122
10983
|
AnalyticsEndpoint,
|
|
10123
10984
|
ApiKeysEndpoint,
|
|
10985
|
+
AppsEndpoint,
|
|
10124
10986
|
BatchBuilder,
|
|
10125
10987
|
BatchesNamespace,
|
|
10126
10988
|
BillingEndpoint,
|
|
@@ -10137,12 +10999,15 @@ export {
|
|
|
10137
10999
|
EvalRunner,
|
|
10138
11000
|
EvalsNamespace,
|
|
10139
11001
|
FlowBuilder,
|
|
11002
|
+
FlowDriftError,
|
|
11003
|
+
FlowEnsureConflictError,
|
|
10140
11004
|
FlowResult,
|
|
10141
11005
|
FlowStepsEndpoint,
|
|
10142
11006
|
FlowVersionsEndpoint,
|
|
10143
11007
|
FlowsEndpoint,
|
|
10144
11008
|
FlowsNamespace,
|
|
10145
11009
|
IntegrationsEndpoint,
|
|
11010
|
+
LEDGER_ARTIFACT_LINE_PREFIX,
|
|
10146
11011
|
LogsEndpoint,
|
|
10147
11012
|
ModelConfigsEndpoint,
|
|
10148
11013
|
PromptRunner,
|
|
@@ -10166,19 +11031,29 @@ export {
|
|
|
10166
11031
|
applyGeneratedRuntimeToolProposalToDispatchRequest,
|
|
10167
11032
|
attachRuntimeToolsToDispatchRequest,
|
|
10168
11033
|
buildGeneratedRuntimeToolGateOutput,
|
|
11034
|
+
buildLedgerOffloadReference,
|
|
11035
|
+
buildSendViewOffloadMarker,
|
|
11036
|
+
computeAgentContentHash,
|
|
11037
|
+
computeFlowContentHash,
|
|
10169
11038
|
createClient,
|
|
10170
11039
|
createExternalTool,
|
|
10171
11040
|
defaultWorkflow,
|
|
11041
|
+
defineAgent,
|
|
11042
|
+
defineFlow,
|
|
10172
11043
|
deployWorkflow,
|
|
10173
11044
|
evaluateGeneratedRuntimeToolProposal,
|
|
11045
|
+
extractDeclaredToolResultChars,
|
|
10174
11046
|
gameWorkflow,
|
|
10175
11047
|
getDefaultPlanPath,
|
|
10176
11048
|
getLikelySupportingCandidatePaths,
|
|
10177
11049
|
isDiscoveryToolName,
|
|
10178
11050
|
isMarathonArtifactPath,
|
|
10179
11051
|
isPreservationSensitiveTask,
|
|
11052
|
+
normalizeAgentDefinition,
|
|
10180
11053
|
normalizeCandidatePath,
|
|
10181
11054
|
parseFinalBuffer,
|
|
11055
|
+
parseLedgerArtifactRelativePath,
|
|
11056
|
+
parseOffloadedOutputId,
|
|
10182
11057
|
parseSSEChunk,
|
|
10183
11058
|
processStream,
|
|
10184
11059
|
sanitizeTaskSlug,
|