@byok-sdk/client 0.4.1 → 0.5.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/README.md +18 -0
- package/dist/adapters/index.js +83 -16
- package/dist/adapters/index.js.map +1 -1
- package/dist/bin/byok-agent.js +134 -17
- package/dist/bin/byok-agent.js.map +1 -1
- package/dist/daemon/create-daemon.d.ts +9 -2
- package/dist/daemon/progress-batcher.d.ts +13 -0
- package/dist/daemon/task-runner.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +134 -17
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/bin/byok-agent.js
CHANGED
|
@@ -931,6 +931,24 @@ function mapPermissionPolicyToPiArgs(policy) {
|
|
|
931
931
|
}
|
|
932
932
|
|
|
933
933
|
// src/adapters/pi/events.ts
|
|
934
|
+
function requireToolCallId(msg) {
|
|
935
|
+
if (typeof msg.toolCallId === "string" && msg.toolCallId.trim().length > 0) return msg.toolCallId;
|
|
936
|
+
throw new RuntimeExecutionFailure({
|
|
937
|
+
phase: "run",
|
|
938
|
+
category: "authority",
|
|
939
|
+
retry: "non-retryable",
|
|
940
|
+
reason: `pi ${msg.type} frame had no authoritative tool call id`
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
function requireToolResultOutcome(msg) {
|
|
944
|
+
if (typeof msg.isError === "boolean") return msg.isError;
|
|
945
|
+
throw new RuntimeExecutionFailure({
|
|
946
|
+
phase: "run",
|
|
947
|
+
category: "authority",
|
|
948
|
+
retry: "non-retryable",
|
|
949
|
+
reason: "pi tool_execution_end frame had no authoritative isError outcome"
|
|
950
|
+
});
|
|
951
|
+
}
|
|
934
952
|
function mapPiMessageToAgentEvent(msg) {
|
|
935
953
|
switch (msg.type) {
|
|
936
954
|
case "message_update": {
|
|
@@ -941,16 +959,22 @@ function mapPiMessageToAgentEvent(msg) {
|
|
|
941
959
|
return void 0;
|
|
942
960
|
}
|
|
943
961
|
case "tool_execution_start": {
|
|
962
|
+
const toolCallId = requireToolCallId(msg);
|
|
944
963
|
if (typeof msg.toolName !== "string") return void 0;
|
|
945
|
-
return { type: "tool_use", tool: msg.toolName, input: msg.args };
|
|
964
|
+
return { type: "tool_use", tool: msg.toolName, input: msg.args, toolCallId };
|
|
946
965
|
}
|
|
947
966
|
case "tool_execution_end": {
|
|
967
|
+
const toolCallId = requireToolCallId(msg);
|
|
968
|
+
const isError = requireToolResultOutcome(msg);
|
|
948
969
|
if (typeof msg.toolName !== "string") return void 0;
|
|
949
|
-
|
|
970
|
+
const event = {
|
|
950
971
|
type: "tool_result",
|
|
951
972
|
tool: msg.toolName,
|
|
952
|
-
output: { result: msg.result
|
|
973
|
+
output: { result: msg.result },
|
|
974
|
+
toolCallId,
|
|
975
|
+
isError
|
|
953
976
|
};
|
|
977
|
+
return event;
|
|
954
978
|
}
|
|
955
979
|
case "agent_settled":
|
|
956
980
|
return { type: "turn_end" };
|
|
@@ -1962,6 +1986,17 @@ function subtractDenied(tools, denyTools) {
|
|
|
1962
1986
|
function createToolUseCorrelation() {
|
|
1963
1987
|
return { toolNameByUseId: /* @__PURE__ */ new Map() };
|
|
1964
1988
|
}
|
|
1989
|
+
function missingToolCallIdFailure(frame) {
|
|
1990
|
+
return new RuntimeExecutionFailure({
|
|
1991
|
+
phase: "run",
|
|
1992
|
+
category: "authority",
|
|
1993
|
+
retry: "non-retryable",
|
|
1994
|
+
reason: `claude ${frame} frame had no authoritative tool call id`
|
|
1995
|
+
});
|
|
1996
|
+
}
|
|
1997
|
+
function isAuthoritativeToolCallId(value) {
|
|
1998
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
1999
|
+
}
|
|
1965
2000
|
var ROUTINE_CLAUDE_SYSTEM_SUBTYPES = /* @__PURE__ */ new Set([
|
|
1966
2001
|
"init",
|
|
1967
2002
|
"hook_started",
|
|
@@ -2005,9 +2040,12 @@ function mapAssistant(msg, correlation) {
|
|
|
2005
2040
|
}
|
|
2006
2041
|
break;
|
|
2007
2042
|
case "tool_use":
|
|
2008
|
-
if (
|
|
2043
|
+
if (!isAuthoritativeToolCallId(block.id)) {
|
|
2044
|
+
return { events: [], terminalFailure: missingToolCallIdFailure("tool_use") };
|
|
2045
|
+
}
|
|
2046
|
+
if (typeof block.name === "string") {
|
|
2009
2047
|
correlation.toolNameByUseId.set(block.id, block.name);
|
|
2010
|
-
events.push({ type: "tool_use", tool: block.name, input: block.input });
|
|
2048
|
+
events.push({ type: "tool_use", tool: block.name, input: block.input, toolCallId: block.id });
|
|
2011
2049
|
}
|
|
2012
2050
|
break;
|
|
2013
2051
|
// Deliberately NOT mapped to `progress` — mirrors pi's own choice to
|
|
@@ -2043,11 +2081,20 @@ function mapUser(msg, correlation, options) {
|
|
|
2043
2081
|
unmappedLabel = unmappedLabel ?? `user-block:${String(block.type)}`;
|
|
2044
2082
|
continue;
|
|
2045
2083
|
}
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2084
|
+
if (!isAuthoritativeToolCallId(block.tool_use_id)) {
|
|
2085
|
+
return { events: [], terminalFailure: missingToolCallIdFailure("tool_result") };
|
|
2086
|
+
}
|
|
2087
|
+
const tool = correlation.toolNameByUseId.get(block.tool_use_id) ?? "unknown";
|
|
2088
|
+
const isError = typeof block.is_error === "boolean" ? block.is_error : void 0;
|
|
2089
|
+
const event = {
|
|
2090
|
+
type: "tool_result",
|
|
2091
|
+
tool,
|
|
2092
|
+
output: { content: block.content },
|
|
2093
|
+
toolCallId: block.tool_use_id
|
|
2094
|
+
};
|
|
2095
|
+
if (isError !== void 0) event.isError = isError;
|
|
2096
|
+
events.push(event);
|
|
2097
|
+
if (isError === false && FILE_WRITING_TOOLS.has(tool)) {
|
|
2051
2098
|
const artifact = tryBuildArtifactEvent(msg, options.workspaceDir);
|
|
2052
2099
|
if (artifact) events.push(artifact);
|
|
2053
2100
|
}
|
|
@@ -2670,8 +2717,8 @@ var ClaudeSession = class {
|
|
|
2670
2717
|
for (; ; ) {
|
|
2671
2718
|
const buffered = pending.shift();
|
|
2672
2719
|
if (buffered) return { value: buffered, done: false };
|
|
2720
|
+
if (terminalFailure) throw terminalFailure;
|
|
2673
2721
|
if (turnSettled) {
|
|
2674
|
-
if (terminalFailure) throw terminalFailure;
|
|
2675
2722
|
return { value: void 0, done: true };
|
|
2676
2723
|
}
|
|
2677
2724
|
let raw;
|
|
@@ -2873,6 +2920,15 @@ function extractCodexUsageEvent(rawUsage) {
|
|
|
2873
2920
|
function toNonNegativeInt2(value) {
|
|
2874
2921
|
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
2875
2922
|
}
|
|
2923
|
+
function requireToolCallId2(item) {
|
|
2924
|
+
if (typeof item.id === "string" && item.id.trim().length > 0) return item.id;
|
|
2925
|
+
throw new RuntimeExecutionFailure({
|
|
2926
|
+
phase: "run",
|
|
2927
|
+
category: "authority",
|
|
2928
|
+
retry: "non-retryable",
|
|
2929
|
+
reason: "codex tool item had no authoritative tool call id"
|
|
2930
|
+
});
|
|
2931
|
+
}
|
|
2876
2932
|
function mapItem(rawItem, phase, workspaceDir) {
|
|
2877
2933
|
if (!rawItem || typeof rawItem !== "object") return [];
|
|
2878
2934
|
const item = rawItem;
|
|
@@ -2883,9 +2939,10 @@ function mapItem(rawItem, phase, workspaceDir) {
|
|
|
2883
2939
|
return typeof item.text === "string" ? [{ type: "progress", text: item.text }] : [];
|
|
2884
2940
|
}
|
|
2885
2941
|
case "command_execution": {
|
|
2942
|
+
const toolCallId = requireToolCallId2(item);
|
|
2886
2943
|
const command = typeof item.command === "string" ? item.command : void 0;
|
|
2887
2944
|
if (phase === "started") {
|
|
2888
|
-
return command !== void 0 ? [{ type: "tool_use", tool: "command_execution", input: { command } }] : [];
|
|
2945
|
+
return command !== void 0 ? [{ type: "tool_use", tool: "command_execution", input: { command }, toolCallId }] : [];
|
|
2889
2946
|
}
|
|
2890
2947
|
return [
|
|
2891
2948
|
{
|
|
@@ -2896,17 +2953,19 @@ function mapItem(rawItem, phase, workspaceDir) {
|
|
|
2896
2953
|
aggregatedOutput: item.aggregated_output,
|
|
2897
2954
|
exitCode: item.exit_code,
|
|
2898
2955
|
status: item.status
|
|
2899
|
-
}
|
|
2956
|
+
},
|
|
2957
|
+
toolCallId
|
|
2900
2958
|
}
|
|
2901
2959
|
];
|
|
2902
2960
|
}
|
|
2903
2961
|
case "file_change": {
|
|
2962
|
+
const toolCallId = requireToolCallId2(item);
|
|
2904
2963
|
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
2905
2964
|
if (phase === "started") {
|
|
2906
|
-
return [{ type: "tool_use", tool: "file_change", input: { changes } }];
|
|
2965
|
+
return [{ type: "tool_use", tool: "file_change", input: { changes }, toolCallId }];
|
|
2907
2966
|
}
|
|
2908
2967
|
return [
|
|
2909
|
-
{ type: "tool_result", tool: "file_change", output: { changes, status: item.status } },
|
|
2968
|
+
{ type: "tool_result", tool: "file_change", output: { changes, status: item.status }, toolCallId },
|
|
2910
2969
|
...extractArtifactEvents(changes, workspaceDir)
|
|
2911
2970
|
];
|
|
2912
2971
|
}
|
|
@@ -3329,7 +3388,15 @@ async function runCodexTurn(params) {
|
|
|
3329
3388
|
}
|
|
3330
3389
|
return;
|
|
3331
3390
|
}
|
|
3332
|
-
|
|
3391
|
+
let mapped;
|
|
3392
|
+
try {
|
|
3393
|
+
mapped = mapCodexEventToAgentEvents(evt, params.workspaceDir);
|
|
3394
|
+
} catch (cause) {
|
|
3395
|
+
if (!isRuntimeExecutionFailure(cause)) throw cause;
|
|
3396
|
+
params.terminal.failure = cause;
|
|
3397
|
+
params.queue.end();
|
|
3398
|
+
return;
|
|
3399
|
+
}
|
|
3333
3400
|
for (const agentEvent of mapped) {
|
|
3334
3401
|
if (agentEvent.type === "turn_end") turnEnded = true;
|
|
3335
3402
|
params.queue.push(agentEvent);
|
|
@@ -8208,6 +8275,11 @@ function createStatfsFreeBytesProvider(dir) {
|
|
|
8208
8275
|
var BASE_PLATFORM_ALLOWLIST = [
|
|
8209
8276
|
"PATH",
|
|
8210
8277
|
"HOME",
|
|
8278
|
+
// macOS credential-store discovery used by subscription-authenticated
|
|
8279
|
+
// agent CLIs depends on the login account name as well as HOME. Omitting
|
|
8280
|
+
// USER makes `claude auth status` report logged out under the filtered
|
|
8281
|
+
// child environment even when the host CLI is logged in.
|
|
8282
|
+
"USER",
|
|
8211
8283
|
"USERPROFILE",
|
|
8212
8284
|
"TMPDIR",
|
|
8213
8285
|
"TEMP",
|
|
@@ -8315,11 +8387,37 @@ function computeEffectivePolicy(offered, ceiling) {
|
|
|
8315
8387
|
}
|
|
8316
8388
|
|
|
8317
8389
|
// src/daemon/progress-batcher.ts
|
|
8390
|
+
var ProgressEventTooLargeError = class extends Error {
|
|
8391
|
+
constructor(actualBytes, maxBatchBytes) {
|
|
8392
|
+
super(`Progress event requires ${actualBytes} UTF-8 bytes, exceeding maxBatchBytes ${maxBatchBytes}.`);
|
|
8393
|
+
this.actualBytes = actualBytes;
|
|
8394
|
+
this.maxBatchBytes = maxBatchBytes;
|
|
8395
|
+
this.name = "ProgressEventTooLargeError";
|
|
8396
|
+
}
|
|
8397
|
+
actualBytes;
|
|
8398
|
+
maxBatchBytes;
|
|
8399
|
+
};
|
|
8400
|
+
var encoder = new TextEncoder();
|
|
8401
|
+
function assertPositiveSafeInteger(value, name) {
|
|
8402
|
+
if (value !== void 0 && (!Number.isSafeInteger(value) || value <= 0)) {
|
|
8403
|
+
throw new TypeError(`${name} must be a positive safe integer when configured.`);
|
|
8404
|
+
}
|
|
8405
|
+
}
|
|
8406
|
+
function validateProgressBatcherOptions(options = {}) {
|
|
8407
|
+
assertPositiveSafeInteger(options.maxBatchSize, "maxBatchSize");
|
|
8408
|
+
assertPositiveSafeInteger(options.flushIntervalMs, "flushIntervalMs");
|
|
8409
|
+
assertPositiveSafeInteger(options.maxBatchBytes, "maxBatchBytes");
|
|
8410
|
+
}
|
|
8411
|
+
function encodedEventsBytes(events) {
|
|
8412
|
+
return encoder.encode(JSON.stringify(events)).length;
|
|
8413
|
+
}
|
|
8318
8414
|
var ProgressBatcher = class {
|
|
8319
8415
|
constructor(emit, options = {}) {
|
|
8320
8416
|
this.emit = emit;
|
|
8417
|
+
validateProgressBatcherOptions(options);
|
|
8321
8418
|
this.maxBatchSize = options.maxBatchSize ?? 10;
|
|
8322
8419
|
this.flushIntervalMs = options.flushIntervalMs ?? 250;
|
|
8420
|
+
this.maxBatchBytes = options.maxBatchBytes;
|
|
8323
8421
|
}
|
|
8324
8422
|
emit;
|
|
8325
8423
|
buffer = [];
|
|
@@ -8327,7 +8425,17 @@ var ProgressBatcher = class {
|
|
|
8327
8425
|
timer;
|
|
8328
8426
|
maxBatchSize;
|
|
8329
8427
|
flushIntervalMs;
|
|
8428
|
+
maxBatchBytes;
|
|
8330
8429
|
push(event) {
|
|
8430
|
+
if (this.maxBatchBytes !== void 0) {
|
|
8431
|
+
const eventBytes = encodedEventsBytes([event]);
|
|
8432
|
+
if (eventBytes > this.maxBatchBytes) {
|
|
8433
|
+
throw new ProgressEventTooLargeError(eventBytes, this.maxBatchBytes);
|
|
8434
|
+
}
|
|
8435
|
+
if (this.buffer.length > 0 && encodedEventsBytes([...this.buffer, event]) > this.maxBatchBytes) {
|
|
8436
|
+
this.flush();
|
|
8437
|
+
}
|
|
8438
|
+
}
|
|
8331
8439
|
this.buffer.push(event);
|
|
8332
8440
|
if (this.buffer.length >= this.maxBatchSize) {
|
|
8333
8441
|
this.flush();
|
|
@@ -8380,6 +8488,7 @@ var MAX_INLINE_ARTIFACT_BYTES = 64 * 1024;
|
|
|
8380
8488
|
var MAX_TRACKED_TASK_IDS = 2e3;
|
|
8381
8489
|
var MAX_DURATION_EXCEEDED_REASON_PREFIX = "resource limit exceeded: maxDurationMs";
|
|
8382
8490
|
var MAX_OUTPUT_BYTES_EXCEEDED_REASON_PREFIX = "resource limit exceeded: maxTaskOutputBytes";
|
|
8491
|
+
var MAX_PROGRESS_BATCH_BYTES_EXCEEDED_REASON_PREFIX = "resource limit exceeded: progressBatch.maxBatchBytes";
|
|
8383
8492
|
var RESULT_DOCUMENT_UNDELIVERABLE_REASON_PREFIX = "result document undeliverable";
|
|
8384
8493
|
function resultDocumentRejectionDetail(check) {
|
|
8385
8494
|
switch (check.reason) {
|
|
@@ -9236,6 +9345,13 @@ var TaskRunner = class {
|
|
|
9236
9345
|
} catch (err) {
|
|
9237
9346
|
if (this.tasks.get(active.taskId) !== active || active.beingTornDown) return;
|
|
9238
9347
|
active.batcher.flush();
|
|
9348
|
+
if (err instanceof ProgressEventTooLargeError) {
|
|
9349
|
+
await this.failActiveTaskForResourceLimit(
|
|
9350
|
+
active.taskId,
|
|
9351
|
+
`${MAX_PROGRESS_BATCH_BYTES_EXCEEDED_REASON_PREFIX}: event requires ${err.actualBytes} UTF-8 bytes, exceeding the configured limit of ${err.maxBatchBytes} bytes`
|
|
9352
|
+
);
|
|
9353
|
+
return;
|
|
9354
|
+
}
|
|
9239
9355
|
const failure = projectRuntimeBoundaryFailure(err, "run");
|
|
9240
9356
|
if (failure.contractViolation) {
|
|
9241
9357
|
console.error("[byok/client] runtime adapter events iterable returned an untyped failure", err);
|
|
@@ -10322,6 +10438,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
10322
10438
|
`DaemonConfig.maxTaskOutputBytes must be a positive number (or omitted to use the ${DEFAULT_MAX_TASK_OUTPUT_BYTES}-byte default) \u2014 got ${config.maxTaskOutputBytes}. Pass Number.POSITIVE_INFINITY to explicitly disable the cap; 0 or a negative number is rejected rather than silently treated as "disabled".`
|
|
10323
10439
|
);
|
|
10324
10440
|
}
|
|
10441
|
+
validateProgressBatcherOptions(config.progressBatch);
|
|
10325
10442
|
const presenceCadence = {
|
|
10326
10443
|
intervalMs: config.presence?.intervalMs ?? DEFAULT_PRESENCE_HEARTBEAT_INTERVAL_MS,
|
|
10327
10444
|
ttlMs: config.presence?.ttlMs ?? DEFAULT_PRESENCE_TTL_MS,
|
|
@@ -10607,7 +10724,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
10607
10724
|
// untouched. See `observer.ts`'s module doc comment.
|
|
10608
10725
|
send: sendEnvelope,
|
|
10609
10726
|
blobClient,
|
|
10610
|
-
batcherOptions:
|
|
10727
|
+
batcherOptions: config.progressBatch,
|
|
10611
10728
|
sessionWorkspaces,
|
|
10612
10729
|
gitWorkspaceManager,
|
|
10613
10730
|
gitWorkspaceStore,
|