@runtypelabs/sdk 9.2.1 → 9.3.1
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/CHANGELOG.md +3441 -0
- package/dist/index.cjs +222 -89
- package/dist/index.d.cts +384 -631
- package/dist/index.d.ts +384 -631
- package/dist/index.mjs +219 -89
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -180,10 +180,7 @@ function createFlowEventTranslator() {
|
|
|
180
180
|
pageOrigin: data.pageOrigin
|
|
181
181
|
})
|
|
182
182
|
];
|
|
183
|
-
//
|
|
184
|
-
// flow consumer never read → no callback event. (A non-terminal `error` is
|
|
185
|
-
// only produced on agent streams; dropping it here avoids a false
|
|
186
|
-
// flow_error.)
|
|
183
|
+
// WHY(docs/why/packages/client/src.md#default-case-drops-events-the-flow-consumer-neve): Default case drops events the flow consumer never reads; a non-terminal error is agent-only, dropped here.
|
|
187
184
|
default:
|
|
188
185
|
return [];
|
|
189
186
|
}
|
|
@@ -355,9 +352,7 @@ function createAgentEventTranslator() {
|
|
|
355
352
|
toolName: data.toolName,
|
|
356
353
|
success: data.success,
|
|
357
354
|
result: data.result,
|
|
358
|
-
// A failure's reason travels on the
|
|
359
|
-
// only carrier for complete-only failures like the MCP discovery
|
|
360
|
-
// connection pseudo-tool, which no longer emits an `error` frame.
|
|
355
|
+
// WHY(docs/why/packages/client/src.md#a-failures-reason-travels-on-error-the-only-carr): A failure's reason travels on `error`, the only carrier for complete-only MCP discovery failures.
|
|
361
356
|
error: str(data.error),
|
|
362
357
|
executionTime: data.executionTime
|
|
363
358
|
})
|
|
@@ -494,10 +489,7 @@ function createAgentEventTranslator() {
|
|
|
494
489
|
];
|
|
495
490
|
case "ping":
|
|
496
491
|
return [compact({ type: "agent_ping", executionId, seq, timestamp: data.timestamp })];
|
|
497
|
-
//
|
|
498
|
-
// state_snapshot/state_delta (agent-state channel with no stable SDK
|
|
499
|
-
// callback), custom (fallback beat / routing), and the skill-fold result
|
|
500
|
-
// envelope the SDK never consumed → no callback event.
|
|
492
|
+
// WHY(docs/why/packages/client/src.md#default-case-lists-every-channel-type-the-sdk-ca): Default case lists every channel type the SDK callback surface never consumed, so it maps to nothing.
|
|
501
493
|
default:
|
|
502
494
|
return [];
|
|
503
495
|
}
|
|
@@ -1052,9 +1044,6 @@ var FlowBuilder = class {
|
|
|
1052
1044
|
);
|
|
1053
1045
|
return this;
|
|
1054
1046
|
}
|
|
1055
|
-
// ============================================================================
|
|
1056
|
-
// Step Methods
|
|
1057
|
-
// ============================================================================
|
|
1058
1047
|
/**
|
|
1059
1048
|
* Add a prompt step
|
|
1060
1049
|
*/
|
|
@@ -1553,9 +1542,6 @@ var FlowBuilder = class {
|
|
|
1553
1542
|
memorySummary(config) {
|
|
1554
1543
|
return this.addRawStep("memory-summary", config);
|
|
1555
1544
|
}
|
|
1556
|
-
// ============================================================================
|
|
1557
|
-
// Subagent Helpers
|
|
1558
|
-
// ============================================================================
|
|
1559
1545
|
/**
|
|
1560
1546
|
* Attach a subagent runtime tool to the most recent prompt step.
|
|
1561
1547
|
*
|
|
@@ -1650,9 +1636,6 @@ var FlowBuilder = class {
|
|
|
1650
1636
|
lastStep.config.tools = { ...existingTools, subagentConfig: opts };
|
|
1651
1637
|
return this;
|
|
1652
1638
|
}
|
|
1653
|
-
// ============================================================================
|
|
1654
|
-
// Build Method
|
|
1655
|
-
// ============================================================================
|
|
1656
1639
|
/**
|
|
1657
1640
|
* Build the final dispatch request configuration
|
|
1658
1641
|
*/
|
|
@@ -1743,9 +1726,6 @@ var FlowBuilder = class {
|
|
|
1743
1726
|
if (lastStep) lastStep.when = expression;
|
|
1744
1727
|
return this;
|
|
1745
1728
|
}
|
|
1746
|
-
// ============================================================================
|
|
1747
|
-
// Private Helpers
|
|
1748
|
-
// ============================================================================
|
|
1749
1729
|
addRawStep(type, config) {
|
|
1750
1730
|
const { name, enabled, when, ...stepConfig } = config;
|
|
1751
1731
|
this.addStep(type, name, stepConfig, enabled, when);
|
|
@@ -1949,7 +1929,6 @@ var CHECK_GRADER_KINDS = /* @__PURE__ */ new Set([
|
|
|
1949
1929
|
"length",
|
|
1950
1930
|
"latency",
|
|
1951
1931
|
"no_error",
|
|
1952
|
-
// Trace checks.
|
|
1953
1932
|
"called_tool",
|
|
1954
1933
|
"not_called_tool",
|
|
1955
1934
|
"used_no_tools",
|
|
@@ -2233,7 +2212,8 @@ function normalizeCaseInput(input, where) {
|
|
|
2233
2212
|
const mock = { toolName: m.toolName, output: m.output };
|
|
2234
2213
|
if (m.input !== void 0) mock.input = m.input;
|
|
2235
2214
|
if (typeof m.isError === "boolean") mock.isError = m.isError;
|
|
2236
|
-
if (typeof m.sourceToolExecutionId === "string")
|
|
2215
|
+
if (typeof m.sourceToolExecutionId === "string")
|
|
2216
|
+
mock.sourceToolExecutionId = m.sourceToolExecutionId;
|
|
2237
2217
|
if (typeof m.truncated === "boolean") mock.truncated = m.truncated;
|
|
2238
2218
|
return mock;
|
|
2239
2219
|
});
|
|
@@ -2338,7 +2318,7 @@ async function computeEvalContentHash(definition) {
|
|
|
2338
2318
|
name: c.name,
|
|
2339
2319
|
input: normalizeForHash(c.input),
|
|
2340
2320
|
...c.expected !== void 0 ? { expected: normalizeForHash(c.expected) } : {},
|
|
2341
|
-
// Grader order preserved on purpose
|
|
2321
|
+
// INVARIANT: Grader order is preserved on purpose; it maps to the result index.
|
|
2342
2322
|
expect: c.expect.map((g) => normalizeForHash(g))
|
|
2343
2323
|
}))
|
|
2344
2324
|
};
|
|
@@ -2544,8 +2524,7 @@ function defineFlow(input) {
|
|
|
2544
2524
|
return {
|
|
2545
2525
|
type: step.type,
|
|
2546
2526
|
name: step.name,
|
|
2547
|
-
// Explicit 1-based order
|
|
2548
|
-
// probe hash agrees with the server's persisted step order.
|
|
2527
|
+
// WHY(docs/why/packages/client/src.md#explicit-1-based-order-matches-the-flow-builders): Explicit 1-based order matches the flow builder's convention so the local hash agrees with the server
|
|
2549
2528
|
order: typeof step.order === "number" ? step.order : index + 1,
|
|
2550
2529
|
...step.enabled !== void 0 ? { enabled: step.enabled } : {},
|
|
2551
2530
|
...typeof step.when === "string" ? { when: step.when } : {},
|
|
@@ -2847,9 +2826,6 @@ var RuntypeFlowBuilder = class {
|
|
|
2847
2826
|
this.flowConfig = { name: "Untitled Flow" };
|
|
2848
2827
|
}
|
|
2849
2828
|
}
|
|
2850
|
-
// ============================================================================
|
|
2851
|
-
// Configuration Methods
|
|
2852
|
-
// ============================================================================
|
|
2853
2829
|
/**
|
|
2854
2830
|
* Set the record configuration
|
|
2855
2831
|
*/
|
|
@@ -2893,9 +2869,6 @@ var RuntypeFlowBuilder = class {
|
|
|
2893
2869
|
);
|
|
2894
2870
|
return this;
|
|
2895
2871
|
}
|
|
2896
|
-
// ============================================================================
|
|
2897
|
-
// Step Methods
|
|
2898
|
-
// ============================================================================
|
|
2899
2872
|
/**
|
|
2900
2873
|
* Add a prompt step
|
|
2901
2874
|
*/
|
|
@@ -3679,9 +3652,6 @@ var RuntypeFlowBuilder = class {
|
|
|
3679
3652
|
"Use Runtype.flows.virtual(...) or Runtype.flows.upsert(...) with inline steps to validate a flow before saving."
|
|
3680
3653
|
);
|
|
3681
3654
|
}
|
|
3682
|
-
// ============================================================================
|
|
3683
|
-
// Private Helpers
|
|
3684
|
-
// ============================================================================
|
|
3685
3655
|
/**
|
|
3686
3656
|
* Persisted flow protocol (APQ-style): send hash-only first, retry with
|
|
3687
3657
|
* full definition on FLOW_DEFINITION_REQUIRED. For non-upsert modes,
|
|
@@ -4757,7 +4727,8 @@ var AGENT_CONFIG_KEYS = [
|
|
|
4757
4727
|
"temporal",
|
|
4758
4728
|
"memory",
|
|
4759
4729
|
"sandbox",
|
|
4760
|
-
"tenancyStrategy"
|
|
4730
|
+
"tenancyStrategy",
|
|
4731
|
+
"durability"
|
|
4761
4732
|
];
|
|
4762
4733
|
var AGENT_CONFIG_KEY_LIST = [...AGENT_CONFIG_KEYS].sort();
|
|
4763
4734
|
function isPlainObject2(value) {
|
|
@@ -6043,9 +6014,6 @@ var RuntypeClient = class {
|
|
|
6043
6014
|
}
|
|
6044
6015
|
};
|
|
6045
6016
|
var Runtype = class {
|
|
6046
|
-
// ============================================================================
|
|
6047
|
-
// Global Configuration
|
|
6048
|
-
// ============================================================================
|
|
6049
6017
|
/**
|
|
6050
6018
|
* Configure the global Runtype client
|
|
6051
6019
|
*
|
|
@@ -6083,9 +6051,6 @@ var Runtype = class {
|
|
|
6083
6051
|
static createClient(config) {
|
|
6084
6052
|
return new RuntypeClient({ ...globalConfig, ...config });
|
|
6085
6053
|
}
|
|
6086
|
-
// ============================================================================
|
|
6087
|
-
// Static Namespaces
|
|
6088
|
-
// ============================================================================
|
|
6089
6054
|
/**
|
|
6090
6055
|
* Flows namespace - Build and execute flows
|
|
6091
6056
|
*
|
|
@@ -6327,10 +6292,150 @@ var Runtype = class {
|
|
|
6327
6292
|
|
|
6328
6293
|
// src/version.ts
|
|
6329
6294
|
var FALLBACK_VERSION = "0.0.0";
|
|
6330
|
-
var SDK_VERSION = "9.
|
|
6295
|
+
var SDK_VERSION = "9.3.1".length > 0 ? "9.3.1" : FALLBACK_VERSION;
|
|
6331
6296
|
var RUNTYPE_CLIENT_KIND = "sdk";
|
|
6332
6297
|
var SDK_USER_AGENT = `runtype-sdk/${SDK_VERSION} (typescript)`;
|
|
6333
6298
|
|
|
6299
|
+
// src/detached-reconnect.ts
|
|
6300
|
+
var TERMINAL_EVENTS = /* @__PURE__ */ new Set(["execution_complete", "execution_error"]);
|
|
6301
|
+
var DEFAULT_MAX_DETACHED_RECONNECTS = 12;
|
|
6302
|
+
function observeBlock(block, into) {
|
|
6303
|
+
let eventName = null;
|
|
6304
|
+
for (const line of block.split("\n")) {
|
|
6305
|
+
if (line.startsWith("id:")) {
|
|
6306
|
+
into.lastId = line.slice(3).trim();
|
|
6307
|
+
continue;
|
|
6308
|
+
}
|
|
6309
|
+
if (line.startsWith("event:")) {
|
|
6310
|
+
eventName = line.slice(6).trim();
|
|
6311
|
+
continue;
|
|
6312
|
+
}
|
|
6313
|
+
if (!line.startsWith("data:")) continue;
|
|
6314
|
+
const raw = line.slice(5).trim();
|
|
6315
|
+
if (!raw || raw === "[DONE]") continue;
|
|
6316
|
+
let payload;
|
|
6317
|
+
try {
|
|
6318
|
+
const parsed = JSON.parse(raw);
|
|
6319
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) continue;
|
|
6320
|
+
payload = parsed;
|
|
6321
|
+
} catch {
|
|
6322
|
+
continue;
|
|
6323
|
+
}
|
|
6324
|
+
if (typeof payload.executionId === "string") into.executionId = payload.executionId;
|
|
6325
|
+
const type = typeof payload.type === "string" ? payload.type : eventName;
|
|
6326
|
+
if (type && TERMINAL_EVENTS.has(type)) into.sawTerminal = true;
|
|
6327
|
+
if (type === "await" && payload.awaitReason === "detached") into.sawDetach = true;
|
|
6328
|
+
}
|
|
6329
|
+
}
|
|
6330
|
+
function withDetachedReconnect(response, reattach, options = {}) {
|
|
6331
|
+
if (options.autoReconnect === false) return response;
|
|
6332
|
+
if (!response.ok || !response.body) return response;
|
|
6333
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
6334
|
+
if (!contentType.includes("text/event-stream")) return response;
|
|
6335
|
+
const maxReconnects = options.maxReconnects ?? DEFAULT_MAX_DETACHED_RECONNECTS;
|
|
6336
|
+
const reconnectDelayMs = options.reconnectDelayMs ?? 0;
|
|
6337
|
+
const encoder = new TextEncoder();
|
|
6338
|
+
const decoder = new TextDecoder();
|
|
6339
|
+
const abort = new AbortController();
|
|
6340
|
+
let cancelled = false;
|
|
6341
|
+
let activeReader = null;
|
|
6342
|
+
const stream = new ReadableStream({
|
|
6343
|
+
async start(controller) {
|
|
6344
|
+
const observed = {
|
|
6345
|
+
lastId: null,
|
|
6346
|
+
executionId: null,
|
|
6347
|
+
sawTerminal: false,
|
|
6348
|
+
sawDetach: false
|
|
6349
|
+
};
|
|
6350
|
+
let current = response;
|
|
6351
|
+
let legs = 0;
|
|
6352
|
+
const enqueue = (chunk) => {
|
|
6353
|
+
if (cancelled) return;
|
|
6354
|
+
controller.enqueue(chunk);
|
|
6355
|
+
};
|
|
6356
|
+
try {
|
|
6357
|
+
while (!cancelled && current?.body) {
|
|
6358
|
+
const reader = current.body.getReader();
|
|
6359
|
+
activeReader = reader;
|
|
6360
|
+
let buffer = "";
|
|
6361
|
+
observed.sawDetach = false;
|
|
6362
|
+
for (; ; ) {
|
|
6363
|
+
const { value, done } = await reader.read();
|
|
6364
|
+
if (cancelled) break;
|
|
6365
|
+
if (value) {
|
|
6366
|
+
enqueue(value);
|
|
6367
|
+
buffer += decoder.decode(value, { stream: !done });
|
|
6368
|
+
let boundary = buffer.indexOf("\n\n");
|
|
6369
|
+
while (boundary >= 0) {
|
|
6370
|
+
observeBlock(buffer.slice(0, boundary), observed);
|
|
6371
|
+
buffer = buffer.slice(boundary + 2);
|
|
6372
|
+
boundary = buffer.indexOf("\n\n");
|
|
6373
|
+
}
|
|
6374
|
+
}
|
|
6375
|
+
if (done) break;
|
|
6376
|
+
}
|
|
6377
|
+
activeReader = null;
|
|
6378
|
+
if (cancelled) break;
|
|
6379
|
+
if (buffer.trim()) observeBlock(buffer, observed);
|
|
6380
|
+
if (observed.sawTerminal || !observed.sawDetach) break;
|
|
6381
|
+
if (!observed.executionId || legs >= maxReconnects) break;
|
|
6382
|
+
legs += 1;
|
|
6383
|
+
if (reconnectDelayMs > 0) {
|
|
6384
|
+
await new Promise((resolve) => setTimeout(resolve, reconnectDelayMs));
|
|
6385
|
+
}
|
|
6386
|
+
if (cancelled) break;
|
|
6387
|
+
current = await reattach({
|
|
6388
|
+
executionId: observed.executionId,
|
|
6389
|
+
// WHY(docs/why/packages/client/src.md#0-replays-the-whole-turn-the-fail-open-answer-fo): '0' replays the whole turn, the fail-open answer for a leg that produced no cursor.
|
|
6390
|
+
after: observed.lastId ?? "0",
|
|
6391
|
+
signal: abort.signal
|
|
6392
|
+
});
|
|
6393
|
+
if (cancelled) {
|
|
6394
|
+
await current?.body?.cancel().catch(() => {
|
|
6395
|
+
});
|
|
6396
|
+
break;
|
|
6397
|
+
}
|
|
6398
|
+
if (!current || !current.ok || !current.body) {
|
|
6399
|
+
enqueue(
|
|
6400
|
+
encoder.encode(
|
|
6401
|
+
`event: error
|
|
6402
|
+
data: ${JSON.stringify({
|
|
6403
|
+
type: "error",
|
|
6404
|
+
executionId: observed.executionId,
|
|
6405
|
+
error: {
|
|
6406
|
+
code: "detached_reconnect_failed",
|
|
6407
|
+
message: "The agent detached and this client could not rejoin its stream. The execution is still running; reattach with the events route."
|
|
6408
|
+
},
|
|
6409
|
+
recoverable: false
|
|
6410
|
+
})}
|
|
6411
|
+
|
|
6412
|
+
`
|
|
6413
|
+
)
|
|
6414
|
+
);
|
|
6415
|
+
break;
|
|
6416
|
+
}
|
|
6417
|
+
}
|
|
6418
|
+
} finally {
|
|
6419
|
+
activeReader = null;
|
|
6420
|
+
if (!cancelled) controller.close();
|
|
6421
|
+
}
|
|
6422
|
+
},
|
|
6423
|
+
async cancel(reason) {
|
|
6424
|
+
cancelled = true;
|
|
6425
|
+
abort.abort(reason);
|
|
6426
|
+
const reader = activeReader;
|
|
6427
|
+
activeReader = null;
|
|
6428
|
+
if (reader) await reader.cancel(reason).catch(() => {
|
|
6429
|
+
});
|
|
6430
|
+
}
|
|
6431
|
+
});
|
|
6432
|
+
return new Response(stream, {
|
|
6433
|
+
status: response.status,
|
|
6434
|
+
statusText: response.statusText,
|
|
6435
|
+
headers: response.headers
|
|
6436
|
+
});
|
|
6437
|
+
}
|
|
6438
|
+
|
|
6334
6439
|
// src/generated-tool-gate.ts
|
|
6335
6440
|
var TOOL_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]{1,63}$/;
|
|
6336
6441
|
var DEFAULT_MAX_CODE_LENGTH = 12e3;
|
|
@@ -6602,11 +6707,7 @@ function attachRuntimeToolsToDispatchRequest(request6, runtimeTools, options = {
|
|
|
6602
6707
|
...request6,
|
|
6603
6708
|
flow: {
|
|
6604
6709
|
...flow,
|
|
6605
|
-
//
|
|
6606
|
-
// `FlowStepDefinition[]`); only the prompt step's `config.tools` was
|
|
6607
|
-
// merged, so every step's `type` discriminant is preserved. The clone is
|
|
6608
|
-
// intentionally built as loose records to merge tool config opaquely, so
|
|
6609
|
-
// re-narrow to the typed step shape at this boundary.
|
|
6710
|
+
// WHY(docs/why/packages/client/src.md#clonedsteps-preserves-each-steps-type-discrimina): clonedSteps preserves each step's type discriminant; re-narrow from loose records here
|
|
6610
6711
|
steps: clonedSteps
|
|
6611
6712
|
}
|
|
6612
6713
|
};
|
|
@@ -7870,13 +7971,7 @@ function ensureDefaultWorkflowHooks() {
|
|
|
7870
7971
|
}
|
|
7871
7972
|
var defaultWorkflowConfig = {
|
|
7872
7973
|
name: "default",
|
|
7873
|
-
//
|
|
7874
|
-
// narration-only sessions ("I'll create the files now" with no tool calls)
|
|
7875
|
-
// escalate here even though the phase recovery conditions keyed on
|
|
7876
|
-
// hadTextOutput skip them: nudge after the first actionless session, signal
|
|
7877
|
-
// model escalation after the second (a no-op unless the caller configured a
|
|
7878
|
-
// fallback model), and stop as 'stalled' after the third — the same total
|
|
7879
|
-
// session budget as before stallPolicy existed.
|
|
7974
|
+
// WHY(docs/why/packages/client/src/workflows.md#empty-session-escalation-preserves-legacy-behavi): empty-session escalation preserves legacy behavior: nudge, then escalate, then stall after three
|
|
7880
7975
|
stallPolicy: { nudgeAfter: 1, escalateModelAfter: 2, stopAfter: 3 },
|
|
7881
7976
|
classifyVariant: "builtin:classify-task-variant",
|
|
7882
7977
|
bootstrap: "builtin:repo-bootstrap-discovery",
|
|
@@ -7904,16 +7999,14 @@ var defaultWorkflowConfig = {
|
|
|
7904
7999
|
transitionSummary: "builtin:planning-transition-summary",
|
|
7905
8000
|
recovery: "builtin:planning-recovery",
|
|
7906
8001
|
forceEndTurn: "builtin:planning-force-end-turn"
|
|
7907
|
-
// canAcceptCompletion intentionally absent
|
|
7908
|
-
// phase never defined it, and the SDK accepts completion when the slot
|
|
7909
|
-
// is undefined. Keep parity.
|
|
8002
|
+
// WHY(docs/why/packages/client/src/workflows.md#canacceptcompletion-is-intentionally-absent-for): canAcceptCompletion is intentionally absent for planning to keep parity with the hand-written phase
|
|
7910
8003
|
},
|
|
7911
8004
|
{
|
|
7912
8005
|
name: "execution",
|
|
7913
8006
|
description: "Execute the plan by editing target files",
|
|
7914
8007
|
instructions: "builtin:execution-instructions",
|
|
7915
8008
|
toolGuidance: "builtin:execution-tool-guidance",
|
|
7916
|
-
//
|
|
8009
|
+
// WHY(needs-review): execution never auto-advances; completion is agent-driven via TASK_COMPLETE
|
|
7917
8010
|
completionCriteria: { type: "never" },
|
|
7918
8011
|
intercept: "builtin:execution-guard",
|
|
7919
8012
|
recovery: "builtin:execution-recovery",
|
|
@@ -8083,11 +8176,11 @@ var deployWorkflow = {
|
|
|
8083
8176
|
name: "deploy",
|
|
8084
8177
|
phases: [scaffoldPhase, deployPhase],
|
|
8085
8178
|
classifyVariant: classifyVariant2,
|
|
8086
|
-
//
|
|
8179
|
+
// WHY(needs-review): no bootstrap context needed; this workflow doesn't search the repo
|
|
8087
8180
|
async generateBootstrapContext() {
|
|
8088
8181
|
return void 0;
|
|
8089
8182
|
},
|
|
8090
|
-
//
|
|
8183
|
+
// WHY(needs-review): no candidate block; this workflow doesn't edit repo files
|
|
8091
8184
|
buildCandidateBlock() {
|
|
8092
8185
|
return "";
|
|
8093
8186
|
}
|
|
@@ -9458,9 +9551,7 @@ var ClientTokensEndpoint = class {
|
|
|
9458
9551
|
if (params?.limit !== void 0) {
|
|
9459
9552
|
return {
|
|
9460
9553
|
clientTokens: response.clientTokens,
|
|
9461
|
-
// The
|
|
9462
|
-
// fallback mirrors the server's own envelope math so the paged
|
|
9463
|
-
// overload stays total against older API deployments.
|
|
9554
|
+
// WHY(docs/why/packages/client/src.md#the-fallback-mirrors-the-servers-own-envelope-ma): The fallback mirrors the server's own envelope math so paging stays correct against older API deployments.
|
|
9464
9555
|
pagination: response.pagination ?? {
|
|
9465
9556
|
limit: params.limit,
|
|
9466
9557
|
offset: params.offset ?? 0,
|
|
@@ -9711,6 +9802,14 @@ function appendRuntimeToolsToAgentRequest(request6, runtimeTools) {
|
|
|
9711
9802
|
}
|
|
9712
9803
|
};
|
|
9713
9804
|
}
|
|
9805
|
+
function buildAgentAdmissionHeaders(options) {
|
|
9806
|
+
if (!options) return {};
|
|
9807
|
+
const headers = {};
|
|
9808
|
+
if (options.concurrency) headers["x-runtype-concurrency"] = options.concurrency;
|
|
9809
|
+
if (options.coalesce) headers["x-runtype-coalesce"] = "true";
|
|
9810
|
+
if (options.idempotencyKey) headers["idempotency-key"] = options.idempotencyKey;
|
|
9811
|
+
return headers;
|
|
9812
|
+
}
|
|
9714
9813
|
var _AgentsEndpoint = class _AgentsEndpoint {
|
|
9715
9814
|
constructor(client) {
|
|
9716
9815
|
this.client = client;
|
|
@@ -9802,18 +9901,22 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
9802
9901
|
/**
|
|
9803
9902
|
* Execute an agent (non-streaming)
|
|
9804
9903
|
*/
|
|
9805
|
-
async execute(id, data) {
|
|
9806
|
-
return this.client.post(
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9904
|
+
async execute(id, data, options) {
|
|
9905
|
+
return this.client.post(
|
|
9906
|
+
`/agents/${id}/execute`,
|
|
9907
|
+
{
|
|
9908
|
+
...data,
|
|
9909
|
+
streamResponse: false
|
|
9910
|
+
},
|
|
9911
|
+
buildAgentAdmissionHeaders(options)
|
|
9912
|
+
);
|
|
9810
9913
|
}
|
|
9811
9914
|
/** Start an agent execution and return its durable handle immediately. */
|
|
9812
|
-
async executeAsync(id, data) {
|
|
9915
|
+
async executeAsync(id, data, options) {
|
|
9813
9916
|
return this.client.post(
|
|
9814
9917
|
`/agents/${id}/execute`,
|
|
9815
9918
|
{ ...data, streamResponse: false },
|
|
9816
|
-
{ Prefer: "respond-async" }
|
|
9919
|
+
{ Prefer: "respond-async", ...buildAgentAdmissionHeaders(options) }
|
|
9817
9920
|
);
|
|
9818
9921
|
}
|
|
9819
9922
|
/**
|
|
@@ -9835,14 +9938,42 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
9835
9938
|
* ```
|
|
9836
9939
|
*/
|
|
9837
9940
|
async executeStream(id, data, init) {
|
|
9838
|
-
|
|
9941
|
+
const admissionHeaders = buildAgentAdmissionHeaders(init);
|
|
9942
|
+
const response = await this.client.requestStream(`/agents/${id}/execute`, {
|
|
9839
9943
|
method: "POST",
|
|
9840
9944
|
body: JSON.stringify({
|
|
9841
9945
|
...data,
|
|
9842
9946
|
streamResponse: true
|
|
9843
9947
|
}),
|
|
9948
|
+
...Object.keys(admissionHeaders).length > 0 ? { headers: admissionHeaders } : {},
|
|
9844
9949
|
...init?.signal ? { signal: init.signal } : {}
|
|
9845
9950
|
});
|
|
9951
|
+
return withDetachedReconnect(
|
|
9952
|
+
response,
|
|
9953
|
+
this.buildDetachedReattach(id, data, init?.signal),
|
|
9954
|
+
init ?? {}
|
|
9955
|
+
);
|
|
9956
|
+
}
|
|
9957
|
+
/**
|
|
9958
|
+
* The `?after=` reattach leg every durable agent stream is followed with.
|
|
9959
|
+
*
|
|
9960
|
+
* Shared by `executeStream` and by the local-tool loop's RESUME leg: a
|
|
9961
|
+
* durable resume answers on the same watch-lease contract as the original
|
|
9962
|
+
* execute, so its socket can close on `awaitReason: 'detached'` too. Building
|
|
9963
|
+
* it once is what keeps the two from drifting into different cursor or
|
|
9964
|
+
* conversation-key behavior.
|
|
9965
|
+
*/
|
|
9966
|
+
buildDetachedReattach(id, data, signal) {
|
|
9967
|
+
return async ({ executionId, after }) => {
|
|
9968
|
+
const named = data?.conversationId;
|
|
9969
|
+
const conversationId = typeof named === "string" ? named : "";
|
|
9970
|
+
const query = new URLSearchParams({ after });
|
|
9971
|
+
if (conversationId) query.set("conversationId", conversationId);
|
|
9972
|
+
return this.client.requestStream(`/agents/${id}/executions/${executionId}/events?${query.toString()}`, {
|
|
9973
|
+
method: "GET",
|
|
9974
|
+
...signal ? { signal } : {}
|
|
9975
|
+
}).catch(() => null);
|
|
9976
|
+
};
|
|
9846
9977
|
}
|
|
9847
9978
|
/**
|
|
9848
9979
|
* Execute an agent with streaming and callbacks
|
|
@@ -10006,7 +10137,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
10006
10137
|
callbacks?.onTurnComplete?.(event);
|
|
10007
10138
|
},
|
|
10008
10139
|
onAgentPaused: (event) => {
|
|
10009
|
-
pausedEvent = event;
|
|
10140
|
+
if (event.awaitReason !== "detached") pausedEvent = event;
|
|
10010
10141
|
callbacks?.onAgentPaused?.(event);
|
|
10011
10142
|
},
|
|
10012
10143
|
onAgentComplete: (event) => {
|
|
@@ -10172,8 +10303,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
10172
10303
|
iterations: 1,
|
|
10173
10304
|
stopReason: "end_turn",
|
|
10174
10305
|
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10175
|
-
//
|
|
10176
|
-
// cost still lands in marathon totals and budget accounting
|
|
10306
|
+
// WHY(docs/why/packages/client/src.md#carries-accumulated-spend-so-an-interrupted-sess): Carries accumulated spend so an interrupted session's cost still lands in totals
|
|
10177
10307
|
totalCost: lastKnownCost,
|
|
10178
10308
|
...lastKnownTokens ? { totalTokens: lastKnownTokens } : {},
|
|
10179
10309
|
finalOutput: [
|
|
@@ -10187,7 +10317,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
10187
10317
|
}
|
|
10188
10318
|
let resumeResponse;
|
|
10189
10319
|
try {
|
|
10190
|
-
|
|
10320
|
+
const rawResumeResponse = await this.client.requestStream(`/agents/${id}/resume`, {
|
|
10191
10321
|
method: "POST",
|
|
10192
10322
|
body: JSON.stringify({
|
|
10193
10323
|
executionId,
|
|
@@ -10197,6 +10327,11 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
10197
10327
|
}),
|
|
10198
10328
|
...abortSignal ? { signal: abortSignal } : {}
|
|
10199
10329
|
});
|
|
10330
|
+
resumeResponse = withDetachedReconnect(
|
|
10331
|
+
rawResumeResponse,
|
|
10332
|
+
this.buildDetachedReattach(id, data, abortSignal),
|
|
10333
|
+
{}
|
|
10334
|
+
);
|
|
10200
10335
|
} catch (error) {
|
|
10201
10336
|
if (abortSignal?.aborted) return finishAborted(executionId);
|
|
10202
10337
|
throw error;
|
|
@@ -10222,7 +10357,6 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
10222
10357
|
return null;
|
|
10223
10358
|
}
|
|
10224
10359
|
}
|
|
10225
|
-
// ─── Long-Task Agent Execution ───────────────────────────────────────
|
|
10226
10360
|
createEmptyToolTrace() {
|
|
10227
10361
|
return {
|
|
10228
10362
|
entries: [],
|
|
@@ -12997,12 +13131,7 @@ var RuntypeClient2 = class {
|
|
|
12997
13131
|
this.timeout = config.timeout === void 0 ? 3e4 : config.timeout;
|
|
12998
13132
|
this.headers = {
|
|
12999
13133
|
"Content-Type": "application/json",
|
|
13000
|
-
//
|
|
13001
|
-
// (see detectActorSource in apps/api/src/lib/audit-log.ts). Defaults come
|
|
13002
|
-
// first so callers that wrap this client with their own attribution — the
|
|
13003
|
-
// CLI sends `X-Runtype-Client: cli` + `runtype-cli/<v>` — override them.
|
|
13004
|
-
// `User-Agent` is a forbidden header in browsers and is silently dropped
|
|
13005
|
-
// there; `X-Runtype-Client` is the reliable cross-environment signal.
|
|
13134
|
+
// WHY(docs/why/packages/client/src.md#user-agent-is-a-forbidden-header-in-browsers-and): User-Agent is a forbidden header in browsers and is silently dropped; X-Runtype-Client is the reliable
|
|
13006
13135
|
"X-Runtype-Client": RUNTYPE_CLIENT_KIND,
|
|
13007
13136
|
"User-Agent": SDK_USER_AGENT,
|
|
13008
13137
|
...config.headers || {}
|
|
@@ -13063,8 +13192,7 @@ var RuntypeClient2 = class {
|
|
|
13063
13192
|
{
|
|
13064
13193
|
dispatch: (config) => this.dispatch.executeStream(config),
|
|
13065
13194
|
runWithLocalTools: (config, tools, callbacks, opts) => this.runWithLocalTools(config, tools, callbacks, opts),
|
|
13066
|
-
//
|
|
13067
|
-
// client's JSON POST transport (zero new HTTP plumbing).
|
|
13195
|
+
// WHY(docs/why/packages/client/src.md#clientflowbuilder-validate-reuses-the-clients-js): ClientFlowBuilder.validate() reuses the client's JSON POST transport instead of new HTTP plumbing.
|
|
13068
13196
|
post: (path, data) => this.post(path, data)
|
|
13069
13197
|
},
|
|
13070
13198
|
name
|
|
@@ -13318,8 +13446,7 @@ var RuntypeClient2 = class {
|
|
|
13318
13446
|
const response = await this.makeRequest(url, {
|
|
13319
13447
|
method: "POST",
|
|
13320
13448
|
headers,
|
|
13321
|
-
// TS 5.7 types Uint8Array over ArrayBufferLike, which no longer
|
|
13322
|
-
// overlaps DOM BodyInit; the runtime value is a valid fetch body.
|
|
13449
|
+
// WORKAROUND(docs/why/packages/client/src.md#ts-5-7-types-uint8array-over-arraybufferlike-whi): TS 5.7 types Uint8Array over ArrayBufferLike, which no longer overlaps DOM BodyInit, though the
|
|
13323
13450
|
body
|
|
13324
13451
|
});
|
|
13325
13452
|
return transformResponse(response);
|
|
@@ -14258,6 +14385,7 @@ export {
|
|
|
14258
14385
|
CollectionsEndpoint,
|
|
14259
14386
|
ContextTemplatesEndpoint,
|
|
14260
14387
|
ConversationsEndpoint,
|
|
14388
|
+
DEFAULT_MAX_DETACHED_RECONNECTS,
|
|
14261
14389
|
DEFAULT_RECOVERY_AFTER_EMPTY_SESSIONS,
|
|
14262
14390
|
DEFAULT_STALL_STOP_AFTER,
|
|
14263
14391
|
DispatchEndpoint,
|
|
@@ -14316,6 +14444,7 @@ export {
|
|
|
14316
14444
|
UsersEndpoint,
|
|
14317
14445
|
applyGeneratedRuntimeToolProposalToDispatchRequest,
|
|
14318
14446
|
attachRuntimeToolsToDispatchRequest,
|
|
14447
|
+
buildAgentAdmissionHeaders,
|
|
14319
14448
|
buildEmptySessionNudge,
|
|
14320
14449
|
buildGeneratedRuntimeToolGateOutput,
|
|
14321
14450
|
buildLedgerOffloadReference,
|
|
@@ -14405,5 +14534,6 @@ export {
|
|
|
14405
14534
|
unregisterWorkflowHook,
|
|
14406
14535
|
usedNoTools,
|
|
14407
14536
|
validJson,
|
|
14537
|
+
withDetachedReconnect,
|
|
14408
14538
|
withUnifiedEvents
|
|
14409
14539
|
};
|
package/package.json
CHANGED