agentbox-sdk 0.1.318 → 0.1.322
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/agents/index.js +2 -2
- package/dist/{chunk-2DH5OVG4.js → chunk-775FIGGL.js} +153 -24
- package/dist/{chunk-HYHLKO3L.js → chunk-T4AS2WEF.js} +25 -1
- package/dist/{chunk-MDHCTHCY.js → chunk-ZK5PDWOI.js} +129 -43
- package/dist/events/index.js +1 -1
- package/dist/index.js +3 -3
- package/dist/sandboxes/index.js +1 -1
- package/package.json +1 -1
package/dist/agents/index.js
CHANGED
|
@@ -189,9 +189,35 @@ function isRecord(value) {
|
|
|
189
189
|
function clone(value) {
|
|
190
190
|
return JSON.parse(JSON.stringify(value));
|
|
191
191
|
}
|
|
192
|
+
function isCodexNoiseEvent(method) {
|
|
193
|
+
if (!method) return false;
|
|
194
|
+
if (method.startsWith("mcpServer/")) return true;
|
|
195
|
+
return method.toLowerCase().includes("delta");
|
|
196
|
+
}
|
|
192
197
|
var CodexLogAssembler = class {
|
|
193
198
|
byItemId = /* @__PURE__ */ new Map();
|
|
194
199
|
textByItemId = /* @__PURE__ */ new Map();
|
|
200
|
+
// Non-item events (turn/completed usage, error notifications, thread
|
|
201
|
+
// responses). Returned by `process()` for the live channel; tracked here so
|
|
202
|
+
// `getSnapshots()` — the end-of-run persistence source — keeps them too.
|
|
203
|
+
passThroughSnapshots = [];
|
|
204
|
+
// First-seen chronological order across items and passthroughs.
|
|
205
|
+
snapshotOrder = [];
|
|
206
|
+
trackItem(itemId, snapshot) {
|
|
207
|
+
if (!this.byItemId.has(itemId)) {
|
|
208
|
+
this.snapshotOrder.push({ kind: "item", id: itemId });
|
|
209
|
+
}
|
|
210
|
+
this.byItemId.set(itemId, snapshot);
|
|
211
|
+
}
|
|
212
|
+
pushPassThrough(event) {
|
|
213
|
+
const passthrough = clone(event);
|
|
214
|
+
this.snapshotOrder.push({
|
|
215
|
+
kind: "passthrough",
|
|
216
|
+
index: this.passThroughSnapshots.length
|
|
217
|
+
});
|
|
218
|
+
this.passThroughSnapshots.push(passthrough);
|
|
219
|
+
return clone(passthrough);
|
|
220
|
+
}
|
|
195
221
|
process(event) {
|
|
196
222
|
if (!isRecord(event)) {
|
|
197
223
|
return [];
|
|
@@ -201,7 +227,7 @@ var CodexLogAssembler = class {
|
|
|
201
227
|
const item = isRecord(params.item) ? clone(params.item) : null;
|
|
202
228
|
if (method === "item/started" || method === "item/updated" || method === "item/completed") {
|
|
203
229
|
if (item && typeof item.id === "string") {
|
|
204
|
-
this.
|
|
230
|
+
this.trackItem(item.id, clone(event));
|
|
205
231
|
const text = typeof item.text === "string" ? item.text : void 0;
|
|
206
232
|
if (text !== void 0) {
|
|
207
233
|
this.textByItemId.set(item.id, text);
|
|
@@ -247,7 +273,8 @@ var CodexLogAssembler = class {
|
|
|
247
273
|
})
|
|
248
274
|
];
|
|
249
275
|
}
|
|
250
|
-
return [
|
|
276
|
+
if (isCodexNoiseEvent(method)) return [];
|
|
277
|
+
return [this.pushPassThrough(event)];
|
|
251
278
|
}
|
|
252
279
|
/**
|
|
253
280
|
* Repopulate state from a sequence of previously-assembled snapshots so the
|
|
@@ -256,12 +283,24 @@ var CodexLogAssembler = class {
|
|
|
256
283
|
seed(snapshots) {
|
|
257
284
|
this.byItemId.clear();
|
|
258
285
|
this.textByItemId.clear();
|
|
286
|
+
this.passThroughSnapshots.length = 0;
|
|
287
|
+
this.snapshotOrder.length = 0;
|
|
259
288
|
for (const snapshot of snapshots) {
|
|
260
289
|
if (!isRecord(snapshot)) continue;
|
|
261
290
|
const params = isRecord(snapshot.params) ? snapshot.params : {};
|
|
262
291
|
const item = isRecord(params.item) ? params.item : null;
|
|
263
|
-
if (!item || typeof item.id !== "string")
|
|
264
|
-
|
|
292
|
+
if (!item || typeof item.id !== "string") {
|
|
293
|
+
const method = typeof snapshot.method === "string" ? snapshot.method : void 0;
|
|
294
|
+
if (!isCodexNoiseEvent(method)) {
|
|
295
|
+
this.snapshotOrder.push({
|
|
296
|
+
kind: "passthrough",
|
|
297
|
+
index: this.passThroughSnapshots.length
|
|
298
|
+
});
|
|
299
|
+
this.passThroughSnapshots.push(clone(snapshot));
|
|
300
|
+
}
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
this.trackItem(item.id, clone(snapshot));
|
|
265
304
|
const text = typeof item.text === "string" ? item.text : void 0;
|
|
266
305
|
if (text !== void 0) {
|
|
267
306
|
this.textByItemId.set(item.id, text);
|
|
@@ -288,11 +327,16 @@ var CodexLogAssembler = class {
|
|
|
288
327
|
}
|
|
289
328
|
}
|
|
290
329
|
};
|
|
291
|
-
this.
|
|
330
|
+
this.trackItem(itemId, next);
|
|
292
331
|
return clone(next);
|
|
293
332
|
}
|
|
294
333
|
getSnapshots() {
|
|
295
|
-
|
|
334
|
+
const out = [];
|
|
335
|
+
for (const entry of this.snapshotOrder) {
|
|
336
|
+
const snapshot = entry.kind === "item" ? this.byItemId.get(entry.id) : this.passThroughSnapshots[entry.index];
|
|
337
|
+
if (snapshot) out.push(clone(snapshot));
|
|
338
|
+
}
|
|
339
|
+
return out;
|
|
296
340
|
}
|
|
297
341
|
};
|
|
298
342
|
var OpenCodeLogAssembler = class {
|
|
@@ -314,6 +358,39 @@ var OpenCodeLogAssembler = class {
|
|
|
314
358
|
childSessionToTaskCallId = /* @__PURE__ */ new Map();
|
|
315
359
|
childMessageIdToTaskCallId = /* @__PURE__ */ new Map();
|
|
316
360
|
messageIdToSessionId = /* @__PURE__ */ new Map();
|
|
361
|
+
// Part-less events (user `message.updated`, session lifecycle, errors).
|
|
362
|
+
// Returned by `process()` for the live channel; tracked here so
|
|
363
|
+
// `getSnapshots()` — the end-of-run persistence source — keeps them too.
|
|
364
|
+
// `message.updated` events are keyed by info.id (they re-emit on metadata
|
|
365
|
+
// updates, latest wins); everything else appends.
|
|
366
|
+
keyedPassThrough = /* @__PURE__ */ new Map();
|
|
367
|
+
passThroughSnapshots = [];
|
|
368
|
+
// First-seen chronological order across parts and passthroughs.
|
|
369
|
+
snapshotOrder = [];
|
|
370
|
+
trackPart(partId, snapshot) {
|
|
371
|
+
if (!this.byPartId.has(partId)) {
|
|
372
|
+
this.snapshotOrder.push({ kind: "part", id: partId });
|
|
373
|
+
}
|
|
374
|
+
this.byPartId.set(partId, snapshot);
|
|
375
|
+
}
|
|
376
|
+
pushPassThrough(event) {
|
|
377
|
+
const passthrough = clone(event);
|
|
378
|
+
const info = isRecord(event.properties) ? isRecord(event.properties.info) ? event.properties.info : null : null;
|
|
379
|
+
if (event.type === "message.updated" && info && typeof info.id === "string") {
|
|
380
|
+
const key = `message:${info.id}`;
|
|
381
|
+
if (!this.keyedPassThrough.has(key)) {
|
|
382
|
+
this.snapshotOrder.push({ kind: "keyed", key });
|
|
383
|
+
}
|
|
384
|
+
this.keyedPassThrough.set(key, passthrough);
|
|
385
|
+
return clone(passthrough);
|
|
386
|
+
}
|
|
387
|
+
this.snapshotOrder.push({
|
|
388
|
+
kind: "passthrough",
|
|
389
|
+
index: this.passThroughSnapshots.length
|
|
390
|
+
});
|
|
391
|
+
this.passThroughSnapshots.push(passthrough);
|
|
392
|
+
return clone(passthrough);
|
|
393
|
+
}
|
|
317
394
|
process(event) {
|
|
318
395
|
if (!isRecord(event)) {
|
|
319
396
|
return [];
|
|
@@ -356,7 +433,7 @@ var OpenCodeLogAssembler = class {
|
|
|
356
433
|
}
|
|
357
434
|
if (type === "message.updated" && typeof info?.id === "string" && info.role === "user") {
|
|
358
435
|
this.userMessageIds.add(info.id);
|
|
359
|
-
return [
|
|
436
|
+
return [this.pushPassThrough(event)];
|
|
360
437
|
}
|
|
361
438
|
const parentTaskCallId = this.resolveParentTaskCallId(
|
|
362
439
|
effectiveSid,
|
|
@@ -412,10 +489,10 @@ var OpenCodeLogAssembler = class {
|
|
|
412
489
|
);
|
|
413
490
|
}
|
|
414
491
|
}
|
|
415
|
-
this.
|
|
492
|
+
this.trackPart(eventPart.id, enriched);
|
|
416
493
|
return [clone(enriched)];
|
|
417
494
|
}
|
|
418
|
-
return [
|
|
495
|
+
return [this.pushPassThrough(event)];
|
|
419
496
|
}
|
|
420
497
|
seed(snapshots) {
|
|
421
498
|
this.userMessageIds.clear();
|
|
@@ -426,6 +503,9 @@ var OpenCodeLogAssembler = class {
|
|
|
426
503
|
this.childSessionToTaskCallId.clear();
|
|
427
504
|
this.childMessageIdToTaskCallId.clear();
|
|
428
505
|
this.messageIdToSessionId.clear();
|
|
506
|
+
this.keyedPassThrough.clear();
|
|
507
|
+
this.passThroughSnapshots.length = 0;
|
|
508
|
+
this.snapshotOrder.length = 0;
|
|
429
509
|
for (const snapshot of snapshots) {
|
|
430
510
|
if (!isRecord(snapshot)) continue;
|
|
431
511
|
const type = typeof snapshot.type === "string" ? snapshot.type : "";
|
|
@@ -440,11 +520,16 @@ var OpenCodeLogAssembler = class {
|
|
|
440
520
|
}
|
|
441
521
|
if (type === "message.updated" && typeof info?.id === "string" && info.role === "user") {
|
|
442
522
|
this.userMessageIds.add(info.id);
|
|
523
|
+
this.pushPassThrough(snapshot);
|
|
443
524
|
continue;
|
|
444
525
|
}
|
|
445
526
|
const part = isRecord(properties.part) ? properties.part : isRecord(snapshot.part) ? snapshot.part : null;
|
|
527
|
+
if (!part || typeof part.id !== "string") {
|
|
528
|
+
this.pushPassThrough(snapshot);
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
446
531
|
if (part && typeof part.id === "string") {
|
|
447
|
-
this.
|
|
532
|
+
this.trackPart(part.id, clone(snapshot));
|
|
448
533
|
if (typeof part.text === "string") {
|
|
449
534
|
this.textByPartId.set(part.id, part.text);
|
|
450
535
|
}
|
|
@@ -538,13 +623,27 @@ var OpenCodeLogAssembler = class {
|
|
|
538
623
|
part
|
|
539
624
|
}
|
|
540
625
|
};
|
|
541
|
-
this.
|
|
626
|
+
this.trackPart(partId, next);
|
|
542
627
|
return clone(next);
|
|
543
628
|
}
|
|
544
629
|
getSnapshots() {
|
|
545
|
-
|
|
630
|
+
const out = [];
|
|
631
|
+
for (const entry of this.snapshotOrder) {
|
|
632
|
+
const snapshot = entry.kind === "part" ? this.byPartId.get(entry.id) : entry.kind === "keyed" ? this.keyedPassThrough.get(entry.key) : this.passThroughSnapshots[entry.index];
|
|
633
|
+
if (snapshot) out.push(clone(snapshot));
|
|
634
|
+
}
|
|
635
|
+
return out;
|
|
546
636
|
}
|
|
547
637
|
};
|
|
638
|
+
function isClaudeNoiseEvent(event) {
|
|
639
|
+
const type = typeof event.type === "string" ? event.type : "";
|
|
640
|
+
if (type === "rate_limit_event" || type === "tool_progress") return true;
|
|
641
|
+
if (type === "system") {
|
|
642
|
+
const sub = typeof event.subtype === "string" ? event.subtype : "";
|
|
643
|
+
return sub === "status" || sub === "hook_started" || sub === "hook_response" || sub === "hook_progress" || sub === "api_retry" || sub === "auth_status";
|
|
644
|
+
}
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
548
647
|
var ClaudeCodeLogAssembler = class {
|
|
549
648
|
currentMessageId = null;
|
|
550
649
|
textByMessageId = /* @__PURE__ */ new Map();
|
|
@@ -565,6 +664,12 @@ var ClaudeCodeLogAssembler = class {
|
|
|
565
664
|
// insertion order so `getSnapshots()` returns the full trace, not just the
|
|
566
665
|
// deduped assistant messages.
|
|
567
666
|
passThroughSnapshots = [];
|
|
667
|
+
// First-seen chronological order of everything `getSnapshots()` returns:
|
|
668
|
+
// messages anchor at the position of their first event (message_start or
|
|
669
|
+
// first assistant block) and passthroughs at arrival. Without this the
|
|
670
|
+
// persisted trace would list every message first and every tool_result /
|
|
671
|
+
// system event after, scrambling replay order for sequential consumers.
|
|
672
|
+
snapshotOrder = [];
|
|
568
673
|
process(event) {
|
|
569
674
|
if (!isRecord(event)) return [];
|
|
570
675
|
const type = typeof event.type === "string" ? event.type : "";
|
|
@@ -606,24 +711,32 @@ var ClaudeCodeLogAssembler = class {
|
|
|
606
711
|
const message = isRecord(event.message) ? event.message : null;
|
|
607
712
|
const id = message && typeof message.id === "string" ? message.id : null;
|
|
608
713
|
if (!id || !message) {
|
|
609
|
-
|
|
610
|
-
this.passThroughSnapshots.push(passthrough2);
|
|
611
|
-
return [clone(passthrough2)];
|
|
714
|
+
return [this.pushPassThrough(event)];
|
|
612
715
|
}
|
|
613
716
|
this.setParentToolUseId(id, event);
|
|
614
717
|
const final = extractClaudeAssistantContent(message);
|
|
615
|
-
this.textByMessageId.
|
|
616
|
-
if (final.
|
|
718
|
+
const streamedText = this.textByMessageId.get(id) ?? "";
|
|
719
|
+
if (final.text.length > streamedText.length) {
|
|
720
|
+
this.textByMessageId.set(id, final.text);
|
|
721
|
+
}
|
|
722
|
+
const streamedThinking = this.thinkingByMessageId.get(id) ?? "";
|
|
723
|
+
if (final.thinking.length > streamedThinking.length) {
|
|
617
724
|
this.thinkingByMessageId.set(id, final.thinking);
|
|
618
725
|
}
|
|
619
726
|
this.mergeExtraBlocks(id, final.extraBlocks);
|
|
620
|
-
|
|
621
|
-
this.currentMessageId = null;
|
|
622
|
-
return [snapshot];
|
|
727
|
+
return [this.upsertMessage(id)];
|
|
623
728
|
}
|
|
729
|
+
if (isClaudeNoiseEvent(event)) return [];
|
|
730
|
+
return [this.pushPassThrough(event)];
|
|
731
|
+
}
|
|
732
|
+
pushPassThrough(event) {
|
|
624
733
|
const passthrough = clone(event);
|
|
734
|
+
this.snapshotOrder.push({
|
|
735
|
+
kind: "passthrough",
|
|
736
|
+
index: this.passThroughSnapshots.length
|
|
737
|
+
});
|
|
625
738
|
this.passThroughSnapshots.push(passthrough);
|
|
626
|
-
return
|
|
739
|
+
return clone(passthrough);
|
|
627
740
|
}
|
|
628
741
|
seed(snapshots) {
|
|
629
742
|
this.currentMessageId = null;
|
|
@@ -633,15 +746,26 @@ var ClaudeCodeLogAssembler = class {
|
|
|
633
746
|
this.byMessageId.clear();
|
|
634
747
|
this.extraBlocksByMessageId.clear();
|
|
635
748
|
this.passThroughSnapshots.length = 0;
|
|
749
|
+
this.snapshotOrder.length = 0;
|
|
636
750
|
for (const snapshot of snapshots) {
|
|
637
751
|
if (!isRecord(snapshot)) continue;
|
|
638
752
|
if (snapshot.type !== "message.updated") {
|
|
639
|
-
|
|
753
|
+
if (!isClaudeNoiseEvent(snapshot)) {
|
|
754
|
+
this.snapshotOrder.push({
|
|
755
|
+
kind: "passthrough",
|
|
756
|
+
index: this.passThroughSnapshots.length
|
|
757
|
+
});
|
|
758
|
+
this.passThroughSnapshots.push(clone(snapshot));
|
|
759
|
+
}
|
|
640
760
|
continue;
|
|
641
761
|
}
|
|
642
762
|
const messageId = typeof snapshot.messageId === "string" ? snapshot.messageId : null;
|
|
643
763
|
if (!messageId) continue;
|
|
764
|
+
if (!this.byMessageId.has(messageId)) {
|
|
765
|
+
this.snapshotOrder.push({ kind: "message", id: messageId });
|
|
766
|
+
}
|
|
644
767
|
this.byMessageId.set(messageId, clone(snapshot));
|
|
768
|
+
this.currentMessageId = messageId;
|
|
645
769
|
const parentToolUseId = typeof snapshot.parent_tool_use_id === "string" ? snapshot.parent_tool_use_id : null;
|
|
646
770
|
this.parentToolUseIdByMessageId.set(messageId, parentToolUseId);
|
|
647
771
|
const message = isRecord(snapshot.message) ? snapshot.message : null;
|
|
@@ -707,13 +831,18 @@ var ClaudeCodeLogAssembler = class {
|
|
|
707
831
|
content
|
|
708
832
|
}
|
|
709
833
|
};
|
|
834
|
+
if (!this.byMessageId.has(messageId)) {
|
|
835
|
+
this.snapshotOrder.push({ kind: "message", id: messageId });
|
|
836
|
+
}
|
|
710
837
|
this.byMessageId.set(messageId, next);
|
|
711
838
|
return clone(next);
|
|
712
839
|
}
|
|
713
840
|
getSnapshots() {
|
|
714
841
|
const out = [];
|
|
715
|
-
for (const
|
|
716
|
-
|
|
842
|
+
for (const entry of this.snapshotOrder) {
|
|
843
|
+
const snapshot = entry.kind === "message" ? this.byMessageId.get(entry.id) : this.passThroughSnapshots[entry.index];
|
|
844
|
+
if (snapshot) out.push(clone(snapshot));
|
|
845
|
+
}
|
|
717
846
|
return out;
|
|
718
847
|
}
|
|
719
848
|
};
|
|
@@ -254,6 +254,16 @@ function resolveSandboxResources(resources) {
|
|
|
254
254
|
var DaytonaSandboxAdapter = class extends SandboxAdapter {
|
|
255
255
|
client;
|
|
256
256
|
sandbox;
|
|
257
|
+
/**
|
|
258
|
+
* Per-sandbox preview access token, captured from `getPreviewLink`.
|
|
259
|
+
* Daytona's preview proxy now requires this token to reach a sandbox's
|
|
260
|
+
* ports: unauthenticated requests get 307-redirected to an Auth0 login
|
|
261
|
+
* (which surfaces as a 307 on WebSocket upgrades and a 404 on plain GETs).
|
|
262
|
+
* The token is sandbox-level and stable across ports, so caching the most
|
|
263
|
+
* recent one is sufficient — every consumer calls `getPreviewLink` to build
|
|
264
|
+
* the URL right before reading `previewHeaders`. See {@link previewHeaders}.
|
|
265
|
+
*/
|
|
266
|
+
previewToken;
|
|
257
267
|
constructor(options) {
|
|
258
268
|
super(options);
|
|
259
269
|
this.client = new Daytona({
|
|
@@ -494,12 +504,26 @@ var DaytonaSandboxAdapter = class extends SandboxAdapter {
|
|
|
494
504
|
}
|
|
495
505
|
async openPort(port) {
|
|
496
506
|
this.requireProvisioned();
|
|
497
|
-
await this.requireSandbox().getPreviewLink(port);
|
|
507
|
+
const preview = await this.requireSandbox().getPreviewLink(port);
|
|
508
|
+
this.previewToken = preview.token;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Headers callers must attach to HTTP/WebSocket requests against this
|
|
512
|
+
* sandbox's preview URLs. Daytona private sandboxes gate their preview
|
|
513
|
+
* proxy behind `x-daytona-preview-token`; without it the proxy 307-redirects
|
|
514
|
+
* to Auth0, which breaks every provider (claude-code `/start` 404, codex WS
|
|
515
|
+
* "307", opencode `/session` 404). The token is captured lazily from
|
|
516
|
+
* `getPreviewLink`/`openPort`, both of which every consumer calls to build
|
|
517
|
+
* the URL immediately before reading these headers.
|
|
518
|
+
*/
|
|
519
|
+
get previewHeaders() {
|
|
520
|
+
return this.previewToken ? { "x-daytona-preview-token": this.previewToken } : {};
|
|
498
521
|
}
|
|
499
522
|
async getPreviewLink(port) {
|
|
500
523
|
this.requireProvisioned();
|
|
501
524
|
const sandbox = this.requireSandbox();
|
|
502
525
|
const preview = await sandbox.getPreviewLink(port);
|
|
526
|
+
this.previewToken = preview.token;
|
|
503
527
|
return preview.url;
|
|
504
528
|
}
|
|
505
529
|
async uploadFile(content, targetPath) {
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createNormalizedEvent,
|
|
3
3
|
normalizeRawAgentEvent,
|
|
4
4
|
toAISDKStream
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-775FIGGL.js";
|
|
6
6
|
import {
|
|
7
7
|
AgentBoxError,
|
|
8
8
|
AsyncQueue,
|
|
@@ -1244,16 +1244,23 @@ async function preflightSetup(target, setupId, daemon) {
|
|
|
1244
1244
|
);
|
|
1245
1245
|
}
|
|
1246
1246
|
async function markSetupComplete(target, setupId) {
|
|
1247
|
-
await time(
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
)
|
|
1256
|
-
|
|
1247
|
+
await time(debugSetup, `markSetupComplete ${target.provider}`, async () => {
|
|
1248
|
+
const setupIdFile = path5.posix.join(
|
|
1249
|
+
target.layout.rootDir,
|
|
1250
|
+
SETUP_ID_FILENAME
|
|
1251
|
+
);
|
|
1252
|
+
const result = await target.uploadAndRun(
|
|
1253
|
+
[{ path: setupIdFile, content: setupId }],
|
|
1254
|
+
"true"
|
|
1255
|
+
);
|
|
1256
|
+
if (result.exitCode !== 0) {
|
|
1257
|
+
const detail = result.combinedOutput?.trim();
|
|
1258
|
+
throw new Error(
|
|
1259
|
+
`markSetupComplete failed (${result.exitCode})${detail ? `
|
|
1260
|
+
${detail}` : ""}`
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
});
|
|
1257
1264
|
}
|
|
1258
1265
|
function buildInstallScript(rootDir, installCommandsByKey) {
|
|
1259
1266
|
const commandsB64 = Buffer.from(
|
|
@@ -1641,6 +1648,8 @@ var DAEMON_PORT = 43180;
|
|
|
1641
1648
|
var DAEMON_PATH = "/tmp/agentbox/claude-code/daemon.mjs";
|
|
1642
1649
|
var DAEMON_LOG_PATH = "/tmp/agentbox/claude-code/daemon.log";
|
|
1643
1650
|
var DAEMON_PID_PATH = "/tmp/agentbox/claude-code/daemon.pid";
|
|
1651
|
+
var DAEMON_READY_TIMEOUT_MS = 3e4;
|
|
1652
|
+
var DAEMON_READY_POLL_INTERVAL_MS = 250;
|
|
1644
1653
|
function claudeConfigDir(options) {
|
|
1645
1654
|
return path8.join(
|
|
1646
1655
|
agentboxRoot(AgentProvider.ClaudeCode, Boolean(options.sandbox)),
|
|
@@ -2078,16 +2087,44 @@ async function ensureClaudeCodeDaemonUncached(options, env) {
|
|
|
2078
2087
|
`Could not start claude-code daemon: ${launch.stderr || launch.combinedOutput || "(no output)"}`
|
|
2079
2088
|
);
|
|
2080
2089
|
}
|
|
2090
|
+
const deadline = Date.now() + DAEMON_READY_TIMEOUT_MS;
|
|
2091
|
+
let lastProbe = "";
|
|
2092
|
+
while (Date.now() < deadline) {
|
|
2093
|
+
const ready = await sandbox.run(
|
|
2094
|
+
`curl -fsS --max-time 1 http://127.0.0.1:${DAEMON_PORT}/__version 2>/dev/null`,
|
|
2095
|
+
{ cwd: options.cwd, timeoutMs: 1e4 }
|
|
2096
|
+
);
|
|
2097
|
+
lastProbe = ready.combinedOutput.trim();
|
|
2098
|
+
if (ready.exitCode === 0 && lastProbe === DAEMON_PROTOCOL_VERSION) {
|
|
2099
|
+
return;
|
|
2100
|
+
}
|
|
2101
|
+
await sleep(DAEMON_READY_POLL_INTERVAL_MS);
|
|
2102
|
+
}
|
|
2103
|
+
const logTail = await sandbox.run(`tail -n 20 ${shellQuote(DAEMON_LOG_PATH)} 2>/dev/null`, {
|
|
2104
|
+
cwd: options.cwd
|
|
2105
|
+
}).catch(() => void 0);
|
|
2106
|
+
throw new Error(
|
|
2107
|
+
`claude-code daemon did not become ready within ${DAEMON_READY_TIMEOUT_MS}ms` + (lastProbe ? ` (last /__version response: ${lastProbe})` : "") + (logTail?.combinedOutput ? `
|
|
2108
|
+
${logTail.combinedOutput}` : "")
|
|
2109
|
+
);
|
|
2081
2110
|
});
|
|
2082
2111
|
}
|
|
2083
2112
|
var DAEMON_FIRST_REQUEST_RETRY_BUDGET_MS = 3e4;
|
|
2084
2113
|
var DAEMON_FIRST_REQUEST_RETRY_INTERVAL_MS = 250;
|
|
2114
|
+
var TRANSIENT_PROXY_STATUSES = /* @__PURE__ */ new Set([404, 502, 503, 504]);
|
|
2085
2115
|
async function fetchWithDaemonRetry(input, init) {
|
|
2086
2116
|
const deadline = Date.now() + DAEMON_FIRST_REQUEST_RETRY_BUDGET_MS;
|
|
2087
2117
|
let lastError;
|
|
2118
|
+
let lastResponse;
|
|
2088
2119
|
while (Date.now() < deadline) {
|
|
2089
2120
|
try {
|
|
2090
|
-
|
|
2121
|
+
const response = await fetch(input, init);
|
|
2122
|
+
if (TRANSIENT_PROXY_STATUSES.has(response.status)) {
|
|
2123
|
+
lastResponse = response;
|
|
2124
|
+
await sleep(DAEMON_FIRST_REQUEST_RETRY_INTERVAL_MS);
|
|
2125
|
+
continue;
|
|
2126
|
+
}
|
|
2127
|
+
return response;
|
|
2091
2128
|
} catch (error) {
|
|
2092
2129
|
lastError = error;
|
|
2093
2130
|
const aborted = error?.name === "AbortError";
|
|
@@ -2097,6 +2134,9 @@ async function fetchWithDaemonRetry(input, init) {
|
|
|
2097
2134
|
await sleep(DAEMON_FIRST_REQUEST_RETRY_INTERVAL_MS);
|
|
2098
2135
|
}
|
|
2099
2136
|
}
|
|
2137
|
+
if (lastResponse) {
|
|
2138
|
+
return lastResponse;
|
|
2139
|
+
}
|
|
2100
2140
|
throw lastError ?? new Error("claude-code daemon request timed out");
|
|
2101
2141
|
}
|
|
2102
2142
|
async function* parseNdjsonStream(body) {
|
|
@@ -2328,6 +2368,7 @@ var ClaudeCodeAgentAdapter = class {
|
|
|
2328
2368
|
)
|
|
2329
2369
|
);
|
|
2330
2370
|
let accumulatedText = "";
|
|
2371
|
+
let streamedThinkingChars = 0;
|
|
2331
2372
|
let pendingMessages = 1;
|
|
2332
2373
|
let firstStreamEventLogged = false;
|
|
2333
2374
|
let firstTextDeltaLogged = false;
|
|
@@ -2399,8 +2440,15 @@ var ClaudeCodeAgentAdapter = class {
|
|
|
2399
2440
|
);
|
|
2400
2441
|
}
|
|
2401
2442
|
const partial = message;
|
|
2443
|
+
if (partial.parent_tool_use_id) continue;
|
|
2444
|
+
const streamType = partial.event?.type;
|
|
2445
|
+
if (streamType === "message_start") {
|
|
2446
|
+
accumulatedText = "";
|
|
2447
|
+
streamedThinkingChars = 0;
|
|
2448
|
+
}
|
|
2402
2449
|
const { text, thinking } = extractStreamDeltas(partial);
|
|
2403
2450
|
if (thinking) {
|
|
2451
|
+
streamedThinkingChars += thinking.length;
|
|
2404
2452
|
sink.emitEvent(
|
|
2405
2453
|
createNormalizedEvent(
|
|
2406
2454
|
"reasoning.delta",
|
|
@@ -2430,8 +2478,9 @@ var ClaudeCodeAgentAdapter = class {
|
|
|
2430
2478
|
}
|
|
2431
2479
|
if (message.type === "assistant") {
|
|
2432
2480
|
const asst = message;
|
|
2481
|
+
if (asst.parent_tool_use_id) continue;
|
|
2433
2482
|
const thinking = extractAssistantThinking(asst);
|
|
2434
|
-
if (thinking) {
|
|
2483
|
+
if (thinking && streamedThinkingChars === 0) {
|
|
2435
2484
|
sink.emitEvent(
|
|
2436
2485
|
createNormalizedEvent(
|
|
2437
2486
|
"reasoning.delta",
|
|
@@ -4138,42 +4187,79 @@ async function ensureSandboxOpenCodeServer(request) {
|
|
|
4138
4187
|
`disown 2>/dev/null || true`
|
|
4139
4188
|
].join(" ")})`
|
|
4140
4189
|
].join(" && ");
|
|
4141
|
-
|
|
4142
|
-
const
|
|
4190
|
+
const OPENCODE_MAX_LAUNCH_ATTEMPTS = 4;
|
|
4191
|
+
const OPENCODE_RELAUNCH_BACKOFF_MS = 1e3;
|
|
4192
|
+
const readyDeadline = Date.now() + SANDBOX_OPENCODE_READY_TIMEOUT_MS;
|
|
4193
|
+
const pidAlive = `kill -0 "$(cat ${shellQuote(pidFilePath)} 2>/dev/null)" 2>/dev/null`;
|
|
4194
|
+
let lastLog = "";
|
|
4195
|
+
const becameReady = await time(
|
|
4143
4196
|
debugOpencode,
|
|
4144
|
-
"
|
|
4145
|
-
() =>
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4197
|
+
"launch + poll opencode until ready",
|
|
4198
|
+
async () => {
|
|
4199
|
+
for (let attempt = 1; attempt <= OPENCODE_MAX_LAUNCH_ATTEMPTS && Date.now() < readyDeadline; attempt++) {
|
|
4200
|
+
await killSandboxOpenCodeServer(
|
|
4201
|
+
sandbox,
|
|
4202
|
+
pidFilePath,
|
|
4203
|
+
options.cwd,
|
|
4204
|
+
port
|
|
4205
|
+
);
|
|
4206
|
+
const launchResult = await sandbox.run(launchCommand, {
|
|
4207
|
+
cwd: options.cwd,
|
|
4208
|
+
env: serveEnv,
|
|
4209
|
+
timeoutMs: 4e4
|
|
4210
|
+
});
|
|
4211
|
+
if (launchResult.exitCode !== 0) {
|
|
4212
|
+
await target.cleanup().catch(() => void 0);
|
|
4213
|
+
throw new Error(
|
|
4214
|
+
`Could not start OpenCode server: ${launchResult.combinedOutput || launchResult.stderr}`
|
|
4215
|
+
);
|
|
4216
|
+
}
|
|
4217
|
+
while (Date.now() < readyDeadline) {
|
|
4218
|
+
const probe = await sandbox.run(
|
|
4219
|
+
`curl -fsS http://127.0.0.1:${port}/global/health >/dev/null 2>&1`,
|
|
4220
|
+
{ cwd: options.cwd, timeoutMs: 5e3 }
|
|
4221
|
+
);
|
|
4222
|
+
if (probe.exitCode === 0) {
|
|
4223
|
+
debugOpencode("ready on attempt %d", attempt);
|
|
4224
|
+
return true;
|
|
4225
|
+
}
|
|
4226
|
+
const alive = await sandbox.run(pidAlive, {
|
|
4227
|
+
cwd: options.cwd,
|
|
4228
|
+
timeoutMs: 5e3
|
|
4229
|
+
});
|
|
4230
|
+
if (alive.exitCode !== 0) {
|
|
4231
|
+
lastLog = (await sandbox.run(`tail -n 40 ${shellQuote(logFilePath)} 2>/dev/null`, {
|
|
4232
|
+
cwd: options.cwd
|
|
4233
|
+
}).catch(() => void 0))?.combinedOutput?.trim() ?? lastLog;
|
|
4234
|
+
debugOpencode(
|
|
4235
|
+
"opencode died on attempt %d/%d; relaunching. log:\n%s",
|
|
4236
|
+
attempt,
|
|
4237
|
+
OPENCODE_MAX_LAUNCH_ATTEMPTS,
|
|
4238
|
+
lastLog
|
|
4239
|
+
);
|
|
4240
|
+
break;
|
|
4241
|
+
}
|
|
4242
|
+
await sleep(500);
|
|
4243
|
+
}
|
|
4244
|
+
if (Date.now() >= readyDeadline) break;
|
|
4245
|
+
await sleep(OPENCODE_RELAUNCH_BACKOFF_MS);
|
|
4169
4246
|
}
|
|
4170
|
-
|
|
4247
|
+
return false;
|
|
4248
|
+
}
|
|
4249
|
+
);
|
|
4250
|
+
if (!becameReady) {
|
|
4251
|
+
if (!lastLog) {
|
|
4252
|
+
lastLog = (await sandbox.run(`tail -n 40 ${shellQuote(logFilePath)} 2>/dev/null`, {
|
|
4253
|
+
cwd: options.cwd
|
|
4254
|
+
}).catch(() => void 0))?.combinedOutput?.trim() ?? "";
|
|
4171
4255
|
}
|
|
4172
4256
|
await target.cleanup().catch(() => void 0);
|
|
4173
4257
|
throw new Error(
|
|
4174
|
-
`OpenCode server did not become ready within ${SANDBOX_OPENCODE_READY_TIMEOUT_MS}ms.`
|
|
4258
|
+
`OpenCode server did not become ready within ${SANDBOX_OPENCODE_READY_TIMEOUT_MS}ms.` + (lastLog ? `
|
|
4259
|
+
opencode log:
|
|
4260
|
+
${lastLog}` : "")
|
|
4175
4261
|
);
|
|
4176
|
-
}
|
|
4262
|
+
}
|
|
4177
4263
|
await markSetupComplete(target, setupId);
|
|
4178
4264
|
});
|
|
4179
4265
|
}
|
package/dist/events/index.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -2,19 +2,19 @@ import {
|
|
|
2
2
|
Agent,
|
|
3
3
|
agentboxRoot,
|
|
4
4
|
getAgentLayout
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZK5PDWOI.js";
|
|
6
6
|
import {
|
|
7
7
|
ProviderLogAssembler,
|
|
8
8
|
createNormalizedEvent,
|
|
9
9
|
normalizeRawAgentEvent,
|
|
10
10
|
toAISDKEvent,
|
|
11
11
|
toAISDKStream
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-775FIGGL.js";
|
|
13
13
|
import {
|
|
14
14
|
Sandbox,
|
|
15
15
|
SandboxAdapter,
|
|
16
16
|
buildGitCloneCommand
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-T4AS2WEF.js";
|
|
18
18
|
import {
|
|
19
19
|
AGENT_RESERVED_PORTS,
|
|
20
20
|
collectAllAgentReservedPorts
|
package/dist/sandboxes/index.js
CHANGED