@runtypelabs/sdk 4.8.1 → 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 +1244 -290
- package/dist/index.d.cts +2626 -180
- package/dist/index.d.ts +2626 -180
- package/dist/index.mjs +1159 -229
- 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
|
+
}
|
|
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 });
|
|
1421
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,45 +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 = "";
|
|
6789
|
+
let lastKnownCost = 0;
|
|
6790
|
+
let lastKnownTokens;
|
|
6791
|
+
let lastSeenExecutionId = "";
|
|
6220
6792
|
let pauseCount = 0;
|
|
6221
6793
|
let discoveryPauseCount = 0;
|
|
6222
6794
|
let consecutiveDiscoveryPauseCount = 0;
|
|
6223
6795
|
const toolNameCounts = {};
|
|
6224
6796
|
let recentActionKeys = [];
|
|
6225
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;
|
|
6226
6830
|
while (true) {
|
|
6227
6831
|
let pausedEvent = null;
|
|
6228
6832
|
let completeEvent = null;
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
event.
|
|
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);
|
|
6244
6865
|
}
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6866
|
+
});
|
|
6867
|
+
} catch (error) {
|
|
6868
|
+
if (abortSignal?.aborted) return finishAborted(lastSeenExecutionId);
|
|
6869
|
+
throw error;
|
|
6870
|
+
}
|
|
6249
6871
|
if (completeEvent) return { completeEvent, toolMessages };
|
|
6250
6872
|
if (pausedEvent) {
|
|
6251
6873
|
const { toolName, toolId, parameters, executionId } = pausedEvent;
|
|
6874
|
+
lastSeenExecutionId = executionId;
|
|
6252
6875
|
const toolDef = localTools[toolName];
|
|
6253
6876
|
if (!toolDef) {
|
|
6254
6877
|
throw new Error(`Local tool "${toolName}" required but not provided`);
|
|
@@ -6363,15 +6986,68 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6363
6986
|
callbacks?.onAgentComplete?.(forcedCompleteEvent);
|
|
6364
6987
|
return { completeEvent: forcedCompleteEvent, toolMessages };
|
|
6365
6988
|
}
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
body: JSON.stringify({
|
|
6989
|
+
if (abortSignal?.aborted) {
|
|
6990
|
+
callbacks?.onLocalToolExecutionComplete?.({
|
|
6369
6991
|
executionId,
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
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
|
+
}
|
|
7002
|
+
if (options?.shouldInterrupt?.()) {
|
|
7003
|
+
callbacks?.onLocalToolExecutionComplete?.({
|
|
7004
|
+
executionId,
|
|
7005
|
+
toolCallId: toolId,
|
|
7006
|
+
toolName,
|
|
7007
|
+
parameters: parsedParams,
|
|
7008
|
+
result: toolResult,
|
|
7009
|
+
success: true,
|
|
7010
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7011
|
+
durationMs: Date.now() - localExecutionStartedAtMs
|
|
7012
|
+
});
|
|
7013
|
+
const interruptCompleteEvent = {
|
|
7014
|
+
type: "agent_complete",
|
|
7015
|
+
executionId,
|
|
7016
|
+
seq: 0,
|
|
7017
|
+
agentId: id,
|
|
7018
|
+
success: true,
|
|
7019
|
+
iterations: 1,
|
|
7020
|
+
stopReason: "end_turn",
|
|
7021
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7022
|
+
// Carry the spend observed so far so the interrupted session's
|
|
7023
|
+
// cost still lands in marathon totals and budget accounting
|
|
7024
|
+
totalCost: lastKnownCost,
|
|
7025
|
+
...lastKnownTokens ? { totalTokens: lastKnownTokens } : {},
|
|
7026
|
+
finalOutput: [
|
|
7027
|
+
accumulatedOutput.trim(),
|
|
7028
|
+
"Session ended early: user steering was queued and will be delivered at the start of the next session."
|
|
7029
|
+
].filter(Boolean).join("\n\n"),
|
|
7030
|
+
duration: 0
|
|
7031
|
+
};
|
|
7032
|
+
callbacks?.onAgentComplete?.(interruptCompleteEvent);
|
|
7033
|
+
return { completeEvent: interruptCompleteEvent, toolMessages };
|
|
7034
|
+
}
|
|
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
|
+
}
|
|
6375
7051
|
if (!resumeResponse.ok) {
|
|
6376
7052
|
const error = await resumeResponse.json().catch(() => ({ error: "Unknown error" }));
|
|
6377
7053
|
throw new Error(error.error || `HTTP ${resumeResponse.status}`);
|
|
@@ -6389,6 +7065,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6389
7065
|
currentBody = resumeResponse.body;
|
|
6390
7066
|
continue;
|
|
6391
7067
|
}
|
|
7068
|
+
if (abortSignal?.aborted) return finishAborted(lastSeenExecutionId);
|
|
6392
7069
|
return null;
|
|
6393
7070
|
}
|
|
6394
7071
|
}
|
|
@@ -6660,7 +7337,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6660
7337
|
reasons.push("Best candidate file has not been verified (read back after writing)");
|
|
6661
7338
|
}
|
|
6662
7339
|
if (state.verificationRequired && !state.lastVerificationPassed && !trace.verificationPassed) {
|
|
6663
|
-
reasons.push(
|
|
7340
|
+
reasons.push(
|
|
7341
|
+
"Verification has not passed \u2014 run a verification command (run_check) before completing"
|
|
7342
|
+
);
|
|
6664
7343
|
}
|
|
6665
7344
|
return reasons.length > 0 ? reasons.join("; ") : "Completion gates not satisfied for the current workflow phase";
|
|
6666
7345
|
}
|
|
@@ -6703,32 +7382,71 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6703
7382
|
);
|
|
6704
7383
|
}
|
|
6705
7384
|
/**
|
|
6706
|
-
*
|
|
6707
|
-
*
|
|
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.
|
|
7392
|
+
*/
|
|
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.
|
|
6708
7412
|
*/
|
|
6709
|
-
|
|
6710
|
-
if (mode === "full-inline") return;
|
|
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];
|
|
6711
7420
|
if (window === "session") {
|
|
6712
|
-
|
|
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;
|
|
6713
7429
|
if (msg.role === "tool" && msg.toolResults) {
|
|
6714
|
-
|
|
7430
|
+
view[index] = maskMessage(msg);
|
|
6715
7431
|
}
|
|
6716
7432
|
}
|
|
6717
7433
|
} else {
|
|
6718
|
-
const newToolResultCount = newToolMessages.filter((m) => m.role === "tool").length;
|
|
6719
|
-
const keepInlineFromExisting = Math.max(0, window - newToolResultCount);
|
|
6720
7434
|
const toolResultIndices = [];
|
|
6721
|
-
for (let i = 0; i <
|
|
6722
|
-
|
|
7435
|
+
for (let i = 0; i < view.length; i++) {
|
|
7436
|
+
const message = view[i];
|
|
7437
|
+
if (message?.role === "tool" && message.toolResults) {
|
|
6723
7438
|
toolResultIndices.push(i);
|
|
6724
7439
|
}
|
|
6725
7440
|
}
|
|
6726
|
-
const compactUpTo = toolResultIndices.length -
|
|
7441
|
+
const compactUpTo = toolResultIndices.length - window;
|
|
6727
7442
|
for (let j = 0; j < compactUpTo && j < toolResultIndices.length; j++) {
|
|
6728
|
-
const
|
|
6729
|
-
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);
|
|
6730
7447
|
}
|
|
6731
7448
|
}
|
|
7449
|
+
return view;
|
|
6732
7450
|
}
|
|
6733
7451
|
compactOneResult(tr, taskName, mode) {
|
|
6734
7452
|
if (typeof tr.result === "string" && tr.result.startsWith("[")) return tr;
|
|
@@ -6764,10 +7482,20 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6764
7482
|
}
|
|
6765
7483
|
const slug = this.sanitizeTaskSlug(taskName || "task");
|
|
6766
7484
|
const dir = `.runtype/marathons/${slug}/tool-outputs`;
|
|
6767
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
6768
7485
|
const filePath = `${dir}/${toolCallId}.txt`;
|
|
6769
|
-
|
|
6770
|
-
|
|
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
|
+
});
|
|
6771
7499
|
}
|
|
6772
7500
|
getDefaultPlanPath(taskName) {
|
|
6773
7501
|
return getDefaultPlanPath(taskName);
|
|
@@ -6889,6 +7617,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6889
7617
|
const migratedPlanPath = workflowVariant === "external" && planPath === this.getDefaultPlanPath(taskName) ? this.getDefaultExternalReportPath(taskName) : planPath;
|
|
6890
7618
|
const candidatePaths = this.dedupeNormalizedCandidatePaths(resumeState.candidatePaths);
|
|
6891
7619
|
const recentReadPaths = this.dedupeNormalizedCandidatePaths(resumeState.recentReadPaths);
|
|
7620
|
+
const contextCompactionSummaries = (resumeState.contextCompactionSummaries ?? []).slice(-20);
|
|
6892
7621
|
const normalizedBestCandidatePath = typeof resumeState.bestCandidatePath === "string" && resumeState.bestCandidatePath.trim() ? this.normalizeCandidatePath(resumeState.bestCandidatePath) : void 0;
|
|
6893
7622
|
const bestCandidatePath = normalizedBestCandidatePath && !this.isMarathonArtifactPath(normalizedBestCandidatePath) ? normalizedBestCandidatePath : [...candidatePaths, ...recentReadPaths].sort(
|
|
6894
7623
|
(left, right) => this.scoreCandidatePath(right) - this.scoreCandidatePath(left)
|
|
@@ -6908,10 +7637,14 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6908
7637
|
bestCandidateVerified: Boolean(resumeState.bestCandidateVerified),
|
|
6909
7638
|
...resumeState.verificationRequired !== void 0 ? { verificationRequired: resumeState.verificationRequired } : {},
|
|
6910
7639
|
lastVerificationPassed: Boolean(resumeState.lastVerificationPassed),
|
|
6911
|
-
...resumeState.consecutiveBlockedVerificationSessions !== void 0 ? {
|
|
7640
|
+
...resumeState.consecutiveBlockedVerificationSessions !== void 0 ? {
|
|
7641
|
+
consecutiveBlockedVerificationSessions: resumeState.consecutiveBlockedVerificationSessions
|
|
7642
|
+
} : {},
|
|
6912
7643
|
...resumeState.isCreationTask !== void 0 ? { isCreationTask: resumeState.isCreationTask } : {},
|
|
6913
7644
|
...resumeState.workflowVariant !== void 0 ? { workflowVariant: resumeState.workflowVariant } : {},
|
|
6914
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) } : {},
|
|
6915
7648
|
...typeof resumeState.outputRoot === "string" && resumeState.outputRoot.trim() ? { outputRoot: resumeState.outputRoot.trim().replace(/\\/g, "/").replace(/\/+/g, "/") } : {}
|
|
6916
7649
|
};
|
|
6917
7650
|
}
|
|
@@ -7377,8 +8110,13 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7377
8110
|
} : {},
|
|
7378
8111
|
...seededResumeState?.candidatePaths ? { candidatePaths: seededResumeState.candidatePaths } : {},
|
|
7379
8112
|
...seededResumeState?.recentReadPaths ? { recentReadPaths: seededResumeState.recentReadPaths } : {},
|
|
7380
|
-
...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 } : {}
|
|
7381
8116
|
};
|
|
8117
|
+
if (options.previousMessages && options.previousMessages.length > 0) {
|
|
8118
|
+
state.messages = options.previousMessages.map((message) => structuredClone(message));
|
|
8119
|
+
}
|
|
7382
8120
|
state.workflowVariant = classifiedVariant;
|
|
7383
8121
|
state.isCreationTask = seededResumeState?.isCreationTask ?? state.workflowVariant === "create";
|
|
7384
8122
|
state.outputRoot = seededResumeState?.outputRoot ?? (state.isCreationTask ? "public/" : void 0);
|
|
@@ -7411,6 +8149,10 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7411
8149
|
}
|
|
7412
8150
|
}
|
|
7413
8151
|
for (let session = 0; session < maxSessions; session++) {
|
|
8152
|
+
if (options.abortSignal?.aborted) {
|
|
8153
|
+
state.status = "paused";
|
|
8154
|
+
break;
|
|
8155
|
+
}
|
|
7414
8156
|
const phaseAtSessionStart = state.workflowPhase;
|
|
7415
8157
|
const sessionTrace = this.createEmptyToolTrace();
|
|
7416
8158
|
const sessionLocalTools = this.wrapLocalToolsForTrace(
|
|
@@ -7428,6 +8170,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7428
8170
|
if (session === 0 && !options.previousMessages) {
|
|
7429
8171
|
state.originalMessage = options.message;
|
|
7430
8172
|
}
|
|
8173
|
+
const queuedSteeringMessages = options.getQueuedUserMessages?.() ?? [];
|
|
7431
8174
|
const preparedSession = await this.prepareSessionContext(
|
|
7432
8175
|
options.message,
|
|
7433
8176
|
state,
|
|
@@ -7446,8 +8189,11 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7446
8189
|
localTools: options.localTools,
|
|
7447
8190
|
builtinToolSchemas,
|
|
7448
8191
|
onContextCompaction: options.onContextCompaction,
|
|
7449
|
-
onContextNotice: options.onContextNotice
|
|
7450
|
-
|
|
8192
|
+
onContextNotice: options.onContextNotice,
|
|
8193
|
+
toolContextMode: options.toolContextMode || "hot-tail",
|
|
8194
|
+
toolWindow: options.toolWindow ?? "session"
|
|
8195
|
+
},
|
|
8196
|
+
queuedSteeringMessages
|
|
7451
8197
|
);
|
|
7452
8198
|
const { messages, requestContextManagement, pendingNativeCompactionEvent } = preparedSession;
|
|
7453
8199
|
let sessionResult;
|
|
@@ -7474,7 +8220,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7474
8220
|
sessionLocalTools || options.localTools,
|
|
7475
8221
|
sessionCallbacks,
|
|
7476
8222
|
{
|
|
7477
|
-
onLocalToolResult: this.createLocalToolLoopGuard(state, sessionTrace, workflow)
|
|
8223
|
+
onLocalToolResult: this.createLocalToolLoopGuard(state, sessionTrace, workflow),
|
|
8224
|
+
shouldInterrupt: options.hasQueuedUserMessages,
|
|
8225
|
+
...options.abortSignal ? { abortSignal: options.abortSignal } : {}
|
|
7478
8226
|
},
|
|
7479
8227
|
state.taskName
|
|
7480
8228
|
);
|
|
@@ -7623,22 +8371,13 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7623
8371
|
}
|
|
7624
8372
|
}
|
|
7625
8373
|
if (!state.messages) state.messages = [];
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
state.messages.push(...newMessages);
|
|
7631
|
-
} 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) {
|
|
7632
8378
|
state.messages.push(...messages);
|
|
7633
8379
|
}
|
|
7634
8380
|
if (sessionToolMessages.length > 0) {
|
|
7635
|
-
this.compactToolResults(
|
|
7636
|
-
state.messages,
|
|
7637
|
-
sessionToolMessages,
|
|
7638
|
-
state.taskName,
|
|
7639
|
-
options.toolContextMode || "hot-tail",
|
|
7640
|
-
options.toolWindow ?? "session"
|
|
7641
|
-
);
|
|
7642
8381
|
state.messages.push(...sessionToolMessages);
|
|
7643
8382
|
}
|
|
7644
8383
|
const assistantContent = effectiveSessionOutput || `[Session ${session + 1} completed (${sessionResult.stopReason}). No text output captured.]`;
|
|
@@ -7658,7 +8397,10 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7658
8397
|
workflow
|
|
7659
8398
|
);
|
|
7660
8399
|
if (detectedTaskCompletion && !acceptedTaskCompletion) {
|
|
7661
|
-
state.lastCompletionRejectionReason = this.computeCompletionRejectionReason(
|
|
8400
|
+
state.lastCompletionRejectionReason = this.computeCompletionRejectionReason(
|
|
8401
|
+
state,
|
|
8402
|
+
sessionTrace
|
|
8403
|
+
);
|
|
7662
8404
|
if (state.verificationRequired && !state.lastVerificationPassed && !sessionTrace.verificationPassed && !sessionTrace.verificationAttempted) {
|
|
7663
8405
|
state.consecutiveBlockedVerificationSessions = (state.consecutiveBlockedVerificationSessions || 0) + 1;
|
|
7664
8406
|
if ((state.consecutiveBlockedVerificationSessions || 0) >= 2) {
|
|
@@ -7677,24 +8419,24 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7677
8419
|
}
|
|
7678
8420
|
if (sessionResult.stopReason === "complete" && !detectedTaskCompletion) {
|
|
7679
8421
|
const currentPhase = workflow.phases.find((p) => p.name === state.workflowPhase);
|
|
7680
|
-
const gatesSatisfied = currentPhase?.canAcceptCompletion ? currentPhase.canAcceptCompletion(
|
|
8422
|
+
const gatesSatisfied = currentPhase?.canAcceptCompletion ? currentPhase.canAcceptCompletion(
|
|
8423
|
+
state,
|
|
8424
|
+
sessionTrace
|
|
8425
|
+
) : true;
|
|
7681
8426
|
if (gatesSatisfied) {
|
|
7682
8427
|
state.status = "complete";
|
|
7683
8428
|
}
|
|
7684
8429
|
} else if (sessionResult.stopReason === "error") {
|
|
7685
8430
|
if (_AgentsEndpoint.isRetryableSessionError(sessionResult.error) && consecutiveServerNetworkErrors < maxServerNetworkRetries) {
|
|
7686
8431
|
consecutiveServerNetworkErrors++;
|
|
7687
|
-
const delayMs = Math.min(
|
|
7688
|
-
5e3 * Math.pow(2, consecutiveServerNetworkErrors - 1),
|
|
7689
|
-
3e4
|
|
7690
|
-
);
|
|
8432
|
+
const delayMs = Math.min(5e3 * Math.pow(2, consecutiveServerNetworkErrors - 1), 3e4);
|
|
7691
8433
|
const delaySec = Math.round(delayMs / 1e3);
|
|
7692
8434
|
await this.emitContextNotice(options.onContextNotice, {
|
|
7693
8435
|
kind: "server_network_retry",
|
|
7694
8436
|
sessionIndex: session,
|
|
7695
8437
|
message: `Server network error: ${sessionResult.error}. Retrying in ${delaySec}s (attempt ${consecutiveServerNetworkErrors}/${maxServerNetworkRetries})...`
|
|
7696
8438
|
});
|
|
7697
|
-
await
|
|
8439
|
+
await sleepWithAbort(delayMs, options.abortSignal);
|
|
7698
8440
|
} else {
|
|
7699
8441
|
state.status = "error";
|
|
7700
8442
|
}
|
|
@@ -7709,6 +8451,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7709
8451
|
} else if (session + 1 >= maxSessions) {
|
|
7710
8452
|
state.status = "max_sessions";
|
|
7711
8453
|
}
|
|
8454
|
+
if (options.abortSignal?.aborted) {
|
|
8455
|
+
state.status = "paused";
|
|
8456
|
+
}
|
|
7712
8457
|
if (options.trackProgress) {
|
|
7713
8458
|
recordId = await this.syncProgressRecord(state, recordId);
|
|
7714
8459
|
}
|
|
@@ -7785,6 +8530,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7785
8530
|
return 0;
|
|
7786
8531
|
}
|
|
7787
8532
|
}
|
|
8533
|
+
extractDeclaredToolResultChars(value) {
|
|
8534
|
+
return extractDeclaredToolResultChars(value);
|
|
8535
|
+
}
|
|
7788
8536
|
estimateMessageContentTokens(content) {
|
|
7789
8537
|
if (typeof content === "string") return this.estimateTextTokens(content);
|
|
7790
8538
|
return content.reduce((total, part) => {
|
|
@@ -7803,12 +8551,14 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7803
8551
|
0
|
|
7804
8552
|
);
|
|
7805
8553
|
}
|
|
7806
|
-
estimateToolResultTokens(toolResults) {
|
|
8554
|
+
estimateToolResultTokens(toolResults, options) {
|
|
7807
8555
|
if (!toolResults || toolResults.length === 0) return 0;
|
|
7808
|
-
return toolResults.reduce(
|
|
7809
|
-
|
|
7810
|
-
0
|
|
7811
|
-
|
|
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);
|
|
7812
8562
|
}
|
|
7813
8563
|
estimateMessageTokens(message) {
|
|
7814
8564
|
return 6 + this.estimateMessageContentTokens(message.content) + this.estimateToolCallTokens(message.toolCalls) + this.estimateToolResultTokens(message.toolResults);
|
|
@@ -7816,13 +8566,15 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7816
8566
|
estimateConversationTokens(messages) {
|
|
7817
8567
|
return messages.reduce((sum, message) => sum + this.estimateMessageTokens(message), 0);
|
|
7818
8568
|
}
|
|
7819
|
-
estimateConversationBreakdown(messages) {
|
|
8569
|
+
estimateConversationBreakdown(messages, options) {
|
|
7820
8570
|
let historyTokens = 0;
|
|
7821
8571
|
let toolOutputTokens = 0;
|
|
7822
8572
|
for (const message of messages) {
|
|
7823
8573
|
const contentTokens = this.estimateMessageContentTokens(message.content);
|
|
7824
8574
|
const toolCallTokens = this.estimateToolCallTokens(message.toolCalls);
|
|
7825
|
-
const toolResultTokens = this.estimateToolResultTokens(message.toolResults
|
|
8575
|
+
const toolResultTokens = this.estimateToolResultTokens(message.toolResults, {
|
|
8576
|
+
useDeclaredSize: options?.useDeclaredToolResultSizes
|
|
8577
|
+
});
|
|
7826
8578
|
const messageTotal = 6 + contentTokens + toolCallTokens + toolResultTokens;
|
|
7827
8579
|
if (message.role === "tool") {
|
|
7828
8580
|
toolOutputTokens += messageTotal;
|
|
@@ -7876,13 +8628,24 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7876
8628
|
const compactInstructions = config.compactInstructions;
|
|
7877
8629
|
return typeof compactInstructions === "string" && compactInstructions.trim() ? compactInstructions.trim() : void 0;
|
|
7878
8630
|
}
|
|
7879
|
-
|
|
8631
|
+
extractArtifactReferencesFromMessages(messages = []) {
|
|
7880
8632
|
const references = /* @__PURE__ */ new Set();
|
|
7881
8633
|
const offloadPrefix = "[Output saved to ";
|
|
7882
|
-
|
|
8634
|
+
const ledgerArtifactPrefix = LEDGER_ARTIFACT_LINE_PREFIX;
|
|
8635
|
+
const savedToPattern = /saved to\s+([^—\]\n]+?)(?:\s+—|\]|\n|$)/gi;
|
|
8636
|
+
for (const message of messages) {
|
|
7883
8637
|
if (!message.toolResults) continue;
|
|
7884
8638
|
for (const toolResult of message.toolResults) {
|
|
7885
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
|
+
}
|
|
7886
8649
|
let startIndex = 0;
|
|
7887
8650
|
while (startIndex < toolResult.result.length) {
|
|
7888
8651
|
const prefixIndex = toolResult.result.indexOf(offloadPrefix, startIndex);
|
|
@@ -7900,6 +8663,13 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7900
8663
|
}
|
|
7901
8664
|
}
|
|
7902
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
|
+
]);
|
|
7903
8673
|
if (state.planPath) {
|
|
7904
8674
|
references.add(state.planPath);
|
|
7905
8675
|
}
|
|
@@ -7907,6 +8677,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7907
8677
|
}
|
|
7908
8678
|
buildContextBudgetBreakdown(details) {
|
|
7909
8679
|
const conversationBreakdown = this.estimateConversationBreakdown(details.historyMessages);
|
|
8680
|
+
const sourceConversationBreakdown = details.sourceHistoryMessages ? this.estimateConversationBreakdown(details.sourceHistoryMessages, {
|
|
8681
|
+
useDeclaredToolResultSizes: true
|
|
8682
|
+
}) : conversationBreakdown;
|
|
7910
8683
|
const currentTurnTokens = this.estimateTextTokens(details.currentTurnContent);
|
|
7911
8684
|
const toolDefinitionTokens = this.estimateToolDefinitionTokens(
|
|
7912
8685
|
details.localTools,
|
|
@@ -7923,15 +8696,26 @@ ${details.summaryText}
|
|
|
7923
8696
|
|
|
7924
8697
|
Do NOT redo any of the above work.`
|
|
7925
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
|
+
);
|
|
7926
8705
|
return {
|
|
7927
|
-
historyTokens:
|
|
7928
|
-
toolOutputTokens:
|
|
8706
|
+
historyTokens: sourceConversationBreakdown.historyTokens,
|
|
8707
|
+
toolOutputTokens: sourceConversationBreakdown.toolOutputTokens,
|
|
7929
8708
|
currentTurnTokens,
|
|
7930
8709
|
toolDefinitionTokens,
|
|
7931
8710
|
...summaryTokens ? { summaryTokens } : {},
|
|
7932
8711
|
...reservedOutputTokens ? { reservedOutputTokens } : {},
|
|
7933
8712
|
...effectiveInputBudgetTokens ? { effectiveInputBudgetTokens } : {},
|
|
7934
|
-
|
|
8713
|
+
...toolOutputReductionTokens > 0 ? {
|
|
8714
|
+
sendEstimatedInputTokens,
|
|
8715
|
+
sendToolOutputTokens: conversationBreakdown.toolOutputTokens,
|
|
8716
|
+
toolOutputReductionTokens
|
|
8717
|
+
} : {},
|
|
8718
|
+
estimatedInputTokens
|
|
7935
8719
|
};
|
|
7936
8720
|
}
|
|
7937
8721
|
async emitContextCompactionEvent(onContextCompaction, event) {
|
|
@@ -7971,16 +8755,33 @@ Do NOT redo any of the above work.`
|
|
|
7971
8755
|
state,
|
|
7972
8756
|
userContent,
|
|
7973
8757
|
details.compactInstructions,
|
|
7974
|
-
details.mode
|
|
8758
|
+
details.mode,
|
|
8759
|
+
details.artifactReferences
|
|
7975
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;
|
|
7976
8777
|
await this.emitContextCompactionEvent(details.onContextCompaction, {
|
|
7977
8778
|
phase: "complete",
|
|
7978
8779
|
...baseEvent
|
|
7979
8780
|
});
|
|
7980
8781
|
return compactMessages;
|
|
7981
8782
|
}
|
|
7982
|
-
buildCompactHistoryMessages(state, userContent, compactInstructions, mode = "auto") {
|
|
7983
|
-
const summary = this.generateCompactSummary(state, compactInstructions);
|
|
8783
|
+
buildCompactHistoryMessages(state, userContent, compactInstructions, mode = "auto", artifactReferences) {
|
|
8784
|
+
const summary = this.generateCompactSummary(state, compactInstructions, artifactReferences);
|
|
7984
8785
|
const prefix = mode === "forced" ? this.getForcedCompactionSummaryPrefix(state) : _AgentsEndpoint.AUTO_COMPACT_SUMMARY_PREFIX;
|
|
7985
8786
|
return [
|
|
7986
8787
|
{
|
|
@@ -7997,16 +8798,11 @@ Do NOT redo any of the above work.`
|
|
|
7997
8798
|
}
|
|
7998
8799
|
];
|
|
7999
8800
|
}
|
|
8000
|
-
isCompactHistoryMessageSet(messages) {
|
|
8001
|
-
if (messages.length === 0) return false;
|
|
8002
|
-
const firstMessage = messages[0];
|
|
8003
|
-
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));
|
|
8004
|
-
}
|
|
8005
8801
|
/**
|
|
8006
8802
|
* Generate a compact summary of prior work for continuation context.
|
|
8007
8803
|
* Used when compact mode is enabled to keep token usage low.
|
|
8008
8804
|
*/
|
|
8009
|
-
generateCompactSummary(state, compactInstructions) {
|
|
8805
|
+
generateCompactSummary(state, compactInstructions, additionalArtifactReferences = []) {
|
|
8010
8806
|
const recentSessions = (state.sessions ?? []).slice(-5);
|
|
8011
8807
|
const sessionSummaries = recentSessions.map(
|
|
8012
8808
|
(session) => `- Session ${session.index}: ${session.stopReason} ($${session.cost.toFixed(4)}) ${session.outputPreview.slice(0, 160)}`
|
|
@@ -8020,7 +8816,7 @@ Do NOT redo any of the above work.`
|
|
|
8020
8816
|
)
|
|
8021
8817
|
).slice(0, 8);
|
|
8022
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.";
|
|
8023
|
-
const artifactReferences = this.extractArtifactReferences(state);
|
|
8819
|
+
const artifactReferences = this.extractArtifactReferences(state, additionalArtifactReferences);
|
|
8024
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.`;
|
|
8025
8821
|
const instructions = compactInstructions || this.buildDefaultCompactInstructions();
|
|
8026
8822
|
return [
|
|
@@ -8150,7 +8946,7 @@ Do NOT redo any of the above work.`
|
|
|
8150
8946
|
);
|
|
8151
8947
|
return prepared.messages;
|
|
8152
8948
|
}
|
|
8153
|
-
async prepareSessionContext(originalMessage, state, sessionIndex, maxSessions, localToolNames, continuationContext, workflow, builtinToolIds, compactionOptions) {
|
|
8949
|
+
async prepareSessionContext(originalMessage, state, sessionIndex, maxSessions, localToolNames, continuationContext, workflow, builtinToolIds, compactionOptions, steeringMessages) {
|
|
8154
8950
|
const wf = workflow ?? defaultWorkflow;
|
|
8155
8951
|
const compactInstructions = compactionOptions?.compactInstructions;
|
|
8156
8952
|
const resolvedStrategy = continuationContext?.compact ? "summary_fallback" : this.resolveCompactStrategy(compactionOptions?.compactStrategy, compactionOptions?.model);
|
|
@@ -8235,9 +9031,23 @@ Do NOT redo any of the above work.`
|
|
|
8235
9031
|
const phaseBlock = ["", this.buildPhaseInstructions(state, wf)].join("\n");
|
|
8236
9032
|
const candidateBlock = wf.buildCandidateBlock?.(state) ?? "";
|
|
8237
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.`;
|
|
9034
|
+
const steeringLines = steeringMessages && steeringMessages.length > 0 ? ["--- User steering (queued during the previous session) ---", ...steeringMessages, ""] : [];
|
|
8238
9035
|
if (continuationContext && sessionIndex === 0) {
|
|
8239
|
-
const
|
|
8240
|
-
|
|
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"
|
|
8241
9051
|
);
|
|
8242
9052
|
const continuationGuardrail = this.buildContinuationGuardrail(state);
|
|
8243
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.";
|
|
@@ -8245,6 +9055,7 @@ Do NOT redo any of the above work.`
|
|
|
8245
9055
|
const userContent = [
|
|
8246
9056
|
continuationGuardrail,
|
|
8247
9057
|
"",
|
|
9058
|
+
...steeringLines,
|
|
8248
9059
|
userMessage,
|
|
8249
9060
|
phaseBlock,
|
|
8250
9061
|
toolsBlock,
|
|
@@ -8260,9 +9071,15 @@ Do NOT redo any of the above work.`
|
|
|
8260
9071
|
content: userContent
|
|
8261
9072
|
}
|
|
8262
9073
|
];
|
|
8263
|
-
const
|
|
9074
|
+
const replayArtifactReferences = this.extractArtifactReferencesFromMessages(replayHistoryMessages);
|
|
9075
|
+
const summaryText = this.generateCompactSummary(
|
|
9076
|
+
state,
|
|
9077
|
+
compactInstructions,
|
|
9078
|
+
replayArtifactReferences
|
|
9079
|
+
);
|
|
8264
9080
|
const breakdown = this.buildContextBudgetBreakdown({
|
|
8265
9081
|
historyMessages: replayHistoryMessages,
|
|
9082
|
+
sourceHistoryMessages: sourceReplayHistoryMessages,
|
|
8266
9083
|
currentTurnContent: userContent,
|
|
8267
9084
|
localTools: compactionOptions?.localTools,
|
|
8268
9085
|
builtinToolSchemas: compactionOptions?.builtinToolSchemas || [],
|
|
@@ -8288,7 +9105,8 @@ Do NOT redo any of the above work.`
|
|
|
8288
9105
|
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
8289
9106
|
breakdown,
|
|
8290
9107
|
onContextCompaction: compactionOptions?.onContextCompaction,
|
|
8291
|
-
compactInstructions
|
|
9108
|
+
compactInstructions,
|
|
9109
|
+
artifactReferences: replayArtifactReferences
|
|
8292
9110
|
}
|
|
8293
9111
|
),
|
|
8294
9112
|
requestContextManagement
|
|
@@ -8312,7 +9130,8 @@ Do NOT redo any of the above work.`
|
|
|
8312
9130
|
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
8313
9131
|
breakdown,
|
|
8314
9132
|
onContextCompaction: compactionOptions?.onContextCompaction,
|
|
8315
|
-
compactInstructions
|
|
9133
|
+
compactInstructions,
|
|
9134
|
+
artifactReferences: replayArtifactReferences
|
|
8316
9135
|
}
|
|
8317
9136
|
),
|
|
8318
9137
|
requestContextManagement
|
|
@@ -8347,6 +9166,7 @@ Do NOT redo any of the above work.`
|
|
|
8347
9166
|
const recoveryMessage2 = this.buildStuckTurnRecoveryMessage(state, wf);
|
|
8348
9167
|
const rejectionNotice = state.lastCompletionRejectionReason ? `TASK_COMPLETE was rejected because: ${state.lastCompletionRejectionReason}. Address this before signaling completion again.` : void 0;
|
|
8349
9168
|
const continuationContent = [
|
|
9169
|
+
...steeringLines,
|
|
8350
9170
|
"Continue the task.",
|
|
8351
9171
|
phaseBlock,
|
|
8352
9172
|
toolsBlock,
|
|
@@ -8362,23 +9182,45 @@ Do NOT redo any of the above work.`
|
|
|
8362
9182
|
"Do not redo previous work. If the task is already complete, respond with TASK_COMPLETE."
|
|
8363
9183
|
].join("\n");
|
|
8364
9184
|
const MAX_HISTORY_MESSAGES = 60;
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
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;
|
|
8369
9198
|
if (trimmedHistory.trimmedCount > 0) {
|
|
8370
|
-
|
|
9199
|
+
sourceHistoryMessages = [
|
|
8371
9200
|
{
|
|
8372
9201
|
role: "system",
|
|
8373
9202
|
content: `[${trimmedHistory.trimmedCount} earlier messages trimmed to stay within context limits. Original task: ${(state.originalMessage || originalMessage).slice(0, 500)}]`
|
|
8374
9203
|
},
|
|
8375
|
-
...
|
|
9204
|
+
...sourceHistoryMessages
|
|
8376
9205
|
];
|
|
8377
9206
|
}
|
|
8378
9207
|
}
|
|
8379
|
-
|
|
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
|
+
);
|
|
8380
9221
|
const breakdown = this.buildContextBudgetBreakdown({
|
|
8381
9222
|
historyMessages,
|
|
9223
|
+
sourceHistoryMessages,
|
|
8382
9224
|
currentTurnContent: continuationContent,
|
|
8383
9225
|
localTools: compactionOptions?.localTools,
|
|
8384
9226
|
builtinToolSchemas: compactionOptions?.builtinToolSchemas || [],
|
|
@@ -8405,7 +9247,8 @@ Do NOT redo any of the above work.`
|
|
|
8405
9247
|
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
8406
9248
|
breakdown,
|
|
8407
9249
|
onContextCompaction: compactionOptions?.onContextCompaction,
|
|
8408
|
-
compactInstructions
|
|
9250
|
+
compactInstructions,
|
|
9251
|
+
artifactReferences: historyArtifactReferences
|
|
8409
9252
|
}
|
|
8410
9253
|
),
|
|
8411
9254
|
requestContextManagement
|
|
@@ -8420,6 +9263,7 @@ Do NOT redo any of the above work.`
|
|
|
8420
9263
|
const recoveryMessage = this.buildStuckTurnRecoveryMessage(state, wf);
|
|
8421
9264
|
const fallbackRejectionNotice = state.lastCompletionRejectionReason ? `TASK_COMPLETE was rejected because: ${state.lastCompletionRejectionReason}. Address this before signaling completion again.` : void 0;
|
|
8422
9265
|
const content = [
|
|
9266
|
+
...steeringLines,
|
|
8423
9267
|
originalMessage,
|
|
8424
9268
|
phaseBlock,
|
|
8425
9269
|
toolsBlock,
|
|
@@ -8878,6 +9722,52 @@ var BillingEndpoint = class {
|
|
|
8878
9722
|
return this.client.get("/billing/spend-analytics", params);
|
|
8879
9723
|
}
|
|
8880
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
|
+
};
|
|
8881
9771
|
|
|
8882
9772
|
// src/client.ts
|
|
8883
9773
|
function isObjectRecord(value) {
|
|
@@ -8920,6 +9810,7 @@ var RuntypeClient2 = class {
|
|
|
8920
9810
|
this.clientTokens = new ClientTokensEndpoint(this);
|
|
8921
9811
|
this.agents = new AgentsEndpoint(this);
|
|
8922
9812
|
this.secrets = new SecretsEndpoint(this);
|
|
9813
|
+
this.apps = new AppsEndpoint(this);
|
|
8923
9814
|
this.schedules = new SchedulesEndpoint(this);
|
|
8924
9815
|
this.surfaces = new SurfacesEndpoint(this);
|
|
8925
9816
|
this.conversations = new ConversationsEndpoint(this);
|
|
@@ -8966,7 +9857,7 @@ var RuntypeClient2 = class {
|
|
|
8966
9857
|
clearApiKey() {
|
|
8967
9858
|
delete this.headers.Authorization;
|
|
8968
9859
|
}
|
|
8969
|
-
async runWithLocalTools(
|
|
9860
|
+
async runWithLocalTools(request2, localTools, arg3, arg4) {
|
|
8970
9861
|
const isOptionsObject = (val) => typeof val === "object" && val !== null && "scope" in val;
|
|
8971
9862
|
const callbacks = isOptionsObject(arg3) ? void 0 : arg3;
|
|
8972
9863
|
const options = (isOptionsObject(arg3) ? arg3 : arg4) ?? {};
|
|
@@ -8980,12 +9871,12 @@ var RuntypeClient2 = class {
|
|
|
8980
9871
|
...entry.pageOrigin ? { pageOrigin: entry.pageOrigin } : {}
|
|
8981
9872
|
})) : [];
|
|
8982
9873
|
const modifiedRequest = {
|
|
8983
|
-
...
|
|
9874
|
+
...request2,
|
|
8984
9875
|
...derivedClientTools.length > 0 ? {
|
|
8985
|
-
clientTools: [...
|
|
9876
|
+
clientTools: [...request2.clientTools ?? [], ...derivedClientTools]
|
|
8986
9877
|
} : {},
|
|
8987
9878
|
options: {
|
|
8988
|
-
...
|
|
9879
|
+
...request2.options || {},
|
|
8989
9880
|
streamResponse: isStreaming
|
|
8990
9881
|
}
|
|
8991
9882
|
};
|
|
@@ -9001,13 +9892,12 @@ var RuntypeClient2 = class {
|
|
|
9001
9892
|
onFlowComplete: (event) => callbacks?.onFlowComplete?.(event),
|
|
9002
9893
|
onError: (error) => callbacks?.onError?.(error)
|
|
9003
9894
|
};
|
|
9004
|
-
const { streamEvents: streamEvents2, stepDeltaText: stepDeltaText2, stepDisplayName: stepDisplayName2, flowErrorMessage: flowErrorMessage2 } = await Promise.resolve().then(() => (init_stream_utils(), stream_utils_exports));
|
|
9005
9895
|
const summary = {
|
|
9006
9896
|
results: /* @__PURE__ */ new Map(),
|
|
9007
9897
|
success: true
|
|
9008
9898
|
};
|
|
9009
9899
|
try {
|
|
9010
|
-
for await (const event of
|
|
9900
|
+
for await (const event of streamEvents(response)) {
|
|
9011
9901
|
collectLocalToolAwait(pausedTools, event);
|
|
9012
9902
|
switch (event.type) {
|
|
9013
9903
|
case "flow_start":
|
|
@@ -9017,10 +9907,10 @@ var RuntypeClient2 = class {
|
|
|
9017
9907
|
wrappedCallbacks.onStepStart?.(event);
|
|
9018
9908
|
break;
|
|
9019
9909
|
case "step_delta":
|
|
9020
|
-
wrappedCallbacks.onStepDelta?.(
|
|
9910
|
+
wrappedCallbacks.onStepDelta?.(stepDeltaText(event), event);
|
|
9021
9911
|
break;
|
|
9022
9912
|
case "step_complete": {
|
|
9023
|
-
summary.results?.set(
|
|
9913
|
+
summary.results?.set(stepDisplayName(event), event.result);
|
|
9024
9914
|
wrappedCallbacks.onStepComplete?.(event.result, event);
|
|
9025
9915
|
break;
|
|
9026
9916
|
}
|
|
@@ -9028,7 +9918,7 @@ var RuntypeClient2 = class {
|
|
|
9028
9918
|
wrappedCallbacks.onFlowComplete?.(event);
|
|
9029
9919
|
break;
|
|
9030
9920
|
case "flow_error":
|
|
9031
|
-
wrappedCallbacks.onError?.(new Error(
|
|
9921
|
+
wrappedCallbacks.onError?.(new Error(flowErrorMessage(event)));
|
|
9032
9922
|
break;
|
|
9033
9923
|
}
|
|
9034
9924
|
}
|
|
@@ -9107,7 +9997,8 @@ var RuntypeClient2 = class {
|
|
|
9107
9997
|
return [toolName, await handler(parameters)];
|
|
9108
9998
|
} catch (error) {
|
|
9109
9999
|
throw new Error(
|
|
9110
|
-
`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 }
|
|
9111
10002
|
);
|
|
9112
10003
|
}
|
|
9113
10004
|
})
|
|
@@ -9171,6 +10062,21 @@ var RuntypeClient2 = class {
|
|
|
9171
10062
|
});
|
|
9172
10063
|
return transformResponse(response);
|
|
9173
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
|
+
}
|
|
9174
10080
|
/**
|
|
9175
10081
|
* Generic request that returns raw Response for streaming
|
|
9176
10082
|
*/
|
|
@@ -9271,7 +10177,7 @@ var RuntypeClient2 = class {
|
|
|
9271
10177
|
} catch (error) {
|
|
9272
10178
|
if (timeoutId) clearTimeout(timeoutId);
|
|
9273
10179
|
if (timeoutId && error instanceof Error && error.name === "AbortError") {
|
|
9274
|
-
throw new Error(`Request timeout after ${this.timeout}ms
|
|
10180
|
+
throw new Error(`Request timeout after ${this.timeout}ms`, { cause: error });
|
|
9275
10181
|
}
|
|
9276
10182
|
throw error;
|
|
9277
10183
|
}
|
|
@@ -9280,8 +10186,18 @@ var RuntypeClient2 = class {
|
|
|
9280
10186
|
* Make HTTP request that returns raw Response (for streaming)
|
|
9281
10187
|
*/
|
|
9282
10188
|
async makeRawRequest(url, options) {
|
|
9283
|
-
const
|
|
10189
|
+
const callerSignal = options.signal ?? null;
|
|
10190
|
+
const controller = this.timeout === null && !callerSignal ? null : new AbortController();
|
|
9284
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
|
+
}
|
|
9285
10201
|
try {
|
|
9286
10202
|
const response = await fetch(url, {
|
|
9287
10203
|
...options,
|
|
@@ -9294,8 +10210,8 @@ var RuntypeClient2 = class {
|
|
|
9294
10210
|
return response;
|
|
9295
10211
|
} catch (error) {
|
|
9296
10212
|
if (timeoutId) clearTimeout(timeoutId);
|
|
9297
|
-
if (timeoutId && error instanceof Error && error.name === "AbortError") {
|
|
9298
|
-
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 });
|
|
9299
10215
|
}
|
|
9300
10216
|
throw error;
|
|
9301
10217
|
}
|
|
@@ -9341,9 +10257,6 @@ function createClient(config) {
|
|
|
9341
10257
|
return new RuntypeClient2(config);
|
|
9342
10258
|
}
|
|
9343
10259
|
|
|
9344
|
-
// src/index.ts
|
|
9345
|
-
init_stream_utils();
|
|
9346
|
-
|
|
9347
10260
|
// src/batch-builder.ts
|
|
9348
10261
|
var BatchBuilder = class {
|
|
9349
10262
|
constructor() {
|
|
@@ -9401,20 +10314,20 @@ var BatchBuilder = class {
|
|
|
9401
10314
|
if (!this.recordType) {
|
|
9402
10315
|
throw new Error("BatchBuilder: recordType is required. Call .forRecordType(type) first.");
|
|
9403
10316
|
}
|
|
9404
|
-
const
|
|
10317
|
+
const request2 = {
|
|
9405
10318
|
flowId: this.flowId,
|
|
9406
10319
|
recordType: this.recordType
|
|
9407
10320
|
};
|
|
9408
10321
|
if (Object.keys(this.batchOptions).length > 0) {
|
|
9409
|
-
|
|
10322
|
+
request2.options = this.batchOptions;
|
|
9410
10323
|
}
|
|
9411
10324
|
if (this.filterConfig) {
|
|
9412
|
-
|
|
10325
|
+
request2.filter = this.filterConfig;
|
|
9413
10326
|
}
|
|
9414
10327
|
if (this.limitConfig !== void 0) {
|
|
9415
|
-
|
|
10328
|
+
request2.limit = this.limitConfig;
|
|
9416
10329
|
}
|
|
9417
|
-
return
|
|
10330
|
+
return request2;
|
|
9418
10331
|
}
|
|
9419
10332
|
/**
|
|
9420
10333
|
* Execute the batch operation
|
|
@@ -9571,32 +10484,32 @@ var EvalBuilder = class {
|
|
|
9571
10484
|
"EvalBuilder: records are required. Call .forRecordType(type) or .withRecords([...]) first."
|
|
9572
10485
|
);
|
|
9573
10486
|
}
|
|
9574
|
-
const
|
|
10487
|
+
const request2 = {};
|
|
9575
10488
|
if (this.flowId) {
|
|
9576
|
-
|
|
10489
|
+
request2.flowId = this.flowId;
|
|
9577
10490
|
} else if (this.virtualFlow) {
|
|
9578
|
-
|
|
10491
|
+
request2.flow = this.virtualFlow;
|
|
9579
10492
|
}
|
|
9580
10493
|
if (this.recordType) {
|
|
9581
|
-
|
|
10494
|
+
request2.recordType = this.recordType;
|
|
9582
10495
|
} else if (this.inlineRecords) {
|
|
9583
|
-
|
|
10496
|
+
request2.records = this.inlineRecords;
|
|
9584
10497
|
}
|
|
9585
10498
|
if (this.modelOverrides) {
|
|
9586
|
-
|
|
10499
|
+
request2.modelOverrides = this.modelOverrides;
|
|
9587
10500
|
} else if (this.modelConfigs) {
|
|
9588
|
-
|
|
10501
|
+
request2.modelConfigs = this.modelConfigs;
|
|
9589
10502
|
}
|
|
9590
10503
|
if (Object.keys(this.evalOptions).length > 0) {
|
|
9591
|
-
|
|
10504
|
+
request2.options = this.evalOptions;
|
|
9592
10505
|
}
|
|
9593
10506
|
if (this.filterConfig) {
|
|
9594
|
-
|
|
10507
|
+
request2.filter = this.filterConfig;
|
|
9595
10508
|
}
|
|
9596
10509
|
if (this.limitConfig !== void 0) {
|
|
9597
|
-
|
|
10510
|
+
request2.limit = this.limitConfig;
|
|
9598
10511
|
}
|
|
9599
|
-
return
|
|
10512
|
+
return request2;
|
|
9600
10513
|
}
|
|
9601
10514
|
/**
|
|
9602
10515
|
* Execute the evaluation
|
|
@@ -10062,10 +10975,14 @@ var STEP_TYPE_TO_METHOD = {
|
|
|
10062
10975
|
"memory-summary": "memorySummary"
|
|
10063
10976
|
};
|
|
10064
10977
|
export {
|
|
10978
|
+
AgentDriftError,
|
|
10979
|
+
AgentEnsureConflictError,
|
|
10065
10980
|
AgentVersionsEndpoint,
|
|
10066
10981
|
AgentsEndpoint,
|
|
10982
|
+
AgentsNamespace,
|
|
10067
10983
|
AnalyticsEndpoint,
|
|
10068
10984
|
ApiKeysEndpoint,
|
|
10985
|
+
AppsEndpoint,
|
|
10069
10986
|
BatchBuilder,
|
|
10070
10987
|
BatchesNamespace,
|
|
10071
10988
|
BillingEndpoint,
|
|
@@ -10082,12 +10999,15 @@ export {
|
|
|
10082
10999
|
EvalRunner,
|
|
10083
11000
|
EvalsNamespace,
|
|
10084
11001
|
FlowBuilder,
|
|
11002
|
+
FlowDriftError,
|
|
11003
|
+
FlowEnsureConflictError,
|
|
10085
11004
|
FlowResult,
|
|
10086
11005
|
FlowStepsEndpoint,
|
|
10087
11006
|
FlowVersionsEndpoint,
|
|
10088
11007
|
FlowsEndpoint,
|
|
10089
11008
|
FlowsNamespace,
|
|
10090
11009
|
IntegrationsEndpoint,
|
|
11010
|
+
LEDGER_ARTIFACT_LINE_PREFIX,
|
|
10091
11011
|
LogsEndpoint,
|
|
10092
11012
|
ModelConfigsEndpoint,
|
|
10093
11013
|
PromptRunner,
|
|
@@ -10111,19 +11031,29 @@ export {
|
|
|
10111
11031
|
applyGeneratedRuntimeToolProposalToDispatchRequest,
|
|
10112
11032
|
attachRuntimeToolsToDispatchRequest,
|
|
10113
11033
|
buildGeneratedRuntimeToolGateOutput,
|
|
11034
|
+
buildLedgerOffloadReference,
|
|
11035
|
+
buildSendViewOffloadMarker,
|
|
11036
|
+
computeAgentContentHash,
|
|
11037
|
+
computeFlowContentHash,
|
|
10114
11038
|
createClient,
|
|
10115
11039
|
createExternalTool,
|
|
10116
11040
|
defaultWorkflow,
|
|
11041
|
+
defineAgent,
|
|
11042
|
+
defineFlow,
|
|
10117
11043
|
deployWorkflow,
|
|
10118
11044
|
evaluateGeneratedRuntimeToolProposal,
|
|
11045
|
+
extractDeclaredToolResultChars,
|
|
10119
11046
|
gameWorkflow,
|
|
10120
11047
|
getDefaultPlanPath,
|
|
10121
11048
|
getLikelySupportingCandidatePaths,
|
|
10122
11049
|
isDiscoveryToolName,
|
|
10123
11050
|
isMarathonArtifactPath,
|
|
10124
11051
|
isPreservationSensitiveTask,
|
|
11052
|
+
normalizeAgentDefinition,
|
|
10125
11053
|
normalizeCandidatePath,
|
|
10126
11054
|
parseFinalBuffer,
|
|
11055
|
+
parseLedgerArtifactRelativePath,
|
|
11056
|
+
parseOffloadedOutputId,
|
|
10127
11057
|
parseSSEChunk,
|
|
10128
11058
|
processStream,
|
|
10129
11059
|
sanitizeTaskSlug,
|