agentbox-sdk 0.1.0 → 0.1.3

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.
@@ -0,0 +1,476 @@
1
+ import {
2
+ AgentProvider
3
+ } from "./chunk-GOFJNFAD.js";
4
+
5
+ // src/events/normalized.ts
6
+ function createNormalizedEvent(type, base, extra) {
7
+ return {
8
+ type,
9
+ provider: base.provider,
10
+ runId: base.runId,
11
+ timestamp: base.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
12
+ raw: base.raw,
13
+ meta: base.meta,
14
+ ...extra ?? {}
15
+ };
16
+ }
17
+ function normalizeRawAgentEvent(event) {
18
+ const payload = event.payload;
19
+ const common = {
20
+ provider: event.provider,
21
+ runId: event.runId,
22
+ raw: event,
23
+ timestamp: event.timestamp
24
+ };
25
+ if (event.type === "assistant" && Array.isArray(
26
+ payload?.message?.content
27
+ )) {
28
+ const blocks = (payload?.message).content;
29
+ const text = blocks.filter((block) => block.type === "text").map((block) => String(block.text ?? "")).join("");
30
+ return [
31
+ createNormalizedEvent("message.started", common),
32
+ ...text ? [createNormalizedEvent("text.delta", common, { delta: text })] : [],
33
+ createNormalizedEvent("message.completed", common, { text }),
34
+ createNormalizedEvent("run.completed", common, { text })
35
+ ];
36
+ }
37
+ if (event.type.includes("delta")) {
38
+ const delta = String(
39
+ payload?.delta ?? payload?.text ?? payload?.["content"] ?? ""
40
+ );
41
+ const normalizedType = event.type.includes("reasoning") ? "reasoning.delta" : "text.delta";
42
+ return [createNormalizedEvent(normalizedType, common, { delta })];
43
+ }
44
+ if (event.type.includes("tool")) {
45
+ const toolName = String(payload?.toolName ?? payload?.tool_name ?? "tool");
46
+ if (event.type.includes("completed") || event.type.includes("summary")) {
47
+ return [
48
+ createNormalizedEvent("tool.call.completed", common, {
49
+ toolName,
50
+ callId: payload?.callId ?? payload?.tool_use_id,
51
+ output: payload?.output ?? payload?.result
52
+ })
53
+ ];
54
+ }
55
+ return [
56
+ createNormalizedEvent("tool.call.started", common, {
57
+ toolName,
58
+ callId: payload?.callId ?? payload?.tool_use_id,
59
+ input: payload?.input
60
+ })
61
+ ];
62
+ }
63
+ if (event.type === "result") {
64
+ const text = String(payload?.result ?? payload?.text ?? "");
65
+ return [createNormalizedEvent("run.completed", common, { text })];
66
+ }
67
+ if (event.type === "error") {
68
+ return [
69
+ createNormalizedEvent("run.error", common, {
70
+ error: String(
71
+ payload?.message ?? payload?.error ?? "Unknown agent error"
72
+ )
73
+ })
74
+ ];
75
+ }
76
+ return [];
77
+ }
78
+
79
+ // src/events/ai-sdk.ts
80
+ function toAISDKEvent(event) {
81
+ switch (event.type) {
82
+ case "run.started":
83
+ return {
84
+ type: "response-start",
85
+ id: event.runId,
86
+ provider: event.provider
87
+ };
88
+ case "message.injected":
89
+ return {
90
+ type: "message-injected",
91
+ id: event.runId,
92
+ provider: event.provider,
93
+ content: event.content
94
+ };
95
+ case "text.delta":
96
+ return {
97
+ type: "text-delta",
98
+ id: event.runId,
99
+ provider: event.provider,
100
+ textDelta: event.delta
101
+ };
102
+ case "reasoning.delta":
103
+ return {
104
+ type: "reasoning-delta",
105
+ id: event.runId,
106
+ provider: event.provider,
107
+ textDelta: event.delta
108
+ };
109
+ case "tool.call.started":
110
+ return {
111
+ type: "tool-input-start",
112
+ id: event.runId,
113
+ provider: event.provider,
114
+ toolName: event.toolName,
115
+ callId: event.callId
116
+ };
117
+ case "tool.call.delta":
118
+ return {
119
+ type: "tool-input-delta",
120
+ id: event.runId,
121
+ provider: event.provider,
122
+ toolName: event.toolName,
123
+ callId: event.callId,
124
+ inputTextDelta: event.delta
125
+ };
126
+ case "tool.call.completed":
127
+ return {
128
+ type: "tool-output-available",
129
+ id: event.runId,
130
+ provider: event.provider,
131
+ toolName: event.toolName,
132
+ callId: event.callId,
133
+ output: event.output
134
+ };
135
+ case "permission.requested":
136
+ return {
137
+ type: "permission-requested",
138
+ id: event.runId,
139
+ provider: event.provider,
140
+ requestId: event.requestId,
141
+ kind: event.kind,
142
+ title: event.title,
143
+ message: event.message,
144
+ input: event.input,
145
+ canRemember: event.canRemember
146
+ };
147
+ case "permission.resolved":
148
+ return {
149
+ type: "permission-resolved",
150
+ id: event.runId,
151
+ provider: event.provider,
152
+ requestId: event.requestId,
153
+ decision: event.decision,
154
+ remember: event.remember
155
+ };
156
+ case "message.completed":
157
+ case "run.completed":
158
+ return {
159
+ type: "response-finish",
160
+ id: event.runId,
161
+ provider: event.provider,
162
+ text: event.text
163
+ };
164
+ case "run.error":
165
+ return {
166
+ type: "response-error",
167
+ id: event.runId,
168
+ provider: event.provider,
169
+ error: event.error
170
+ };
171
+ default:
172
+ return null;
173
+ }
174
+ }
175
+ async function* toAISDKStream(events) {
176
+ for await (const event of events) {
177
+ const mapped = toAISDKEvent(event);
178
+ if (mapped) {
179
+ yield mapped;
180
+ }
181
+ }
182
+ }
183
+
184
+ // src/events/log-assembler.ts
185
+ function isRecord(value) {
186
+ return value !== null && typeof value === "object" && !Array.isArray(value);
187
+ }
188
+ function clone(value) {
189
+ return JSON.parse(JSON.stringify(value));
190
+ }
191
+ var CodexLogAssembler = class {
192
+ byItemId = /* @__PURE__ */ new Map();
193
+ textByItemId = /* @__PURE__ */ new Map();
194
+ process(event) {
195
+ if (!isRecord(event)) {
196
+ return [];
197
+ }
198
+ const method = typeof event.method === "string" ? event.method : void 0;
199
+ const params = isRecord(event.params) ? event.params : {};
200
+ const item = isRecord(params.item) ? clone(params.item) : null;
201
+ if (method === "item/started" || method === "item/updated" || method === "item/completed") {
202
+ if (item && typeof item.id === "string") {
203
+ this.byItemId.set(item.id, clone(event));
204
+ const text = typeof item.text === "string" ? item.text : void 0;
205
+ if (text !== void 0) {
206
+ this.textByItemId.set(item.id, text);
207
+ }
208
+ const aggregated = typeof item.aggregated_output === "string" ? item.aggregated_output : void 0;
209
+ if (aggregated !== void 0) {
210
+ this.textByItemId.set(item.id, aggregated);
211
+ }
212
+ }
213
+ return [clone(event)];
214
+ }
215
+ if (method === "item/agentMessage/delta") {
216
+ const itemId = typeof params.itemId === "string" ? params.itemId : null;
217
+ const delta = typeof params.delta === "string" ? params.delta : "";
218
+ if (!itemId || !delta) return [];
219
+ const text = (this.textByItemId.get(itemId) ?? "") + delta;
220
+ this.textByItemId.set(itemId, text);
221
+ return [this.upsertItem(itemId, "agentMessage", { text })];
222
+ }
223
+ if (method === "item/reasoning/summaryTextDelta" || method === "item/reasoning/textDelta") {
224
+ const itemId = typeof params.itemId === "string" ? params.itemId : null;
225
+ const delta = typeof params.delta === "string" ? params.delta : typeof params.text === "string" ? params.text : "";
226
+ if (!itemId || !delta) return [];
227
+ const text = (this.textByItemId.get(itemId) ?? "") + delta;
228
+ this.textByItemId.set(itemId, text);
229
+ return [
230
+ this.upsertItem(itemId, "reasoning", {
231
+ summary: text,
232
+ text
233
+ })
234
+ ];
235
+ }
236
+ if (method === "item/commandExecution/outputDelta") {
237
+ const itemId = typeof params.itemId === "string" ? params.itemId : null;
238
+ const chunk = typeof params.chunk === "string" ? params.chunk : typeof params.delta === "string" ? params.delta : typeof params.text === "string" ? params.text : "";
239
+ if (!itemId || !chunk) return [];
240
+ const text = (this.textByItemId.get(itemId) ?? "") + chunk;
241
+ this.textByItemId.set(itemId, text);
242
+ return [
243
+ this.upsertItem(itemId, "commandExecution", {
244
+ aggregatedOutput: text,
245
+ status: "inProgress"
246
+ })
247
+ ];
248
+ }
249
+ return [clone(event)];
250
+ }
251
+ /**
252
+ * Repopulate state from a sequence of previously-assembled snapshots so the
253
+ * assembler can resume mid-run (used by reconnecting UI clients).
254
+ */
255
+ seed(snapshots) {
256
+ this.byItemId.clear();
257
+ this.textByItemId.clear();
258
+ for (const snapshot of snapshots) {
259
+ if (!isRecord(snapshot)) continue;
260
+ const params = isRecord(snapshot.params) ? snapshot.params : {};
261
+ const item = isRecord(params.item) ? params.item : null;
262
+ if (!item || typeof item.id !== "string") continue;
263
+ this.byItemId.set(item.id, clone(snapshot));
264
+ const text = typeof item.text === "string" ? item.text : void 0;
265
+ if (text !== void 0) {
266
+ this.textByItemId.set(item.id, text);
267
+ }
268
+ const aggregated = typeof item.aggregated_output === "string" ? item.aggregated_output : void 0;
269
+ if (aggregated !== void 0) {
270
+ this.textByItemId.set(item.id, aggregated);
271
+ }
272
+ }
273
+ }
274
+ upsertItem(itemId, itemType, patch) {
275
+ const existing = this.byItemId.get(itemId);
276
+ const existingParams = isRecord(existing?.params) ? existing.params : {};
277
+ const existingItem = isRecord(existingParams.item) ? existingParams.item : {};
278
+ const next = {
279
+ method: "item/updated",
280
+ params: {
281
+ ...existingParams,
282
+ item: {
283
+ ...existingItem,
284
+ id: itemId,
285
+ type: itemType,
286
+ ...patch
287
+ }
288
+ }
289
+ };
290
+ this.byItemId.set(itemId, next);
291
+ return clone(next);
292
+ }
293
+ };
294
+ var OpenCodeLogAssembler = class {
295
+ userMessageIds = /* @__PURE__ */ new Set();
296
+ textByPartId = /* @__PURE__ */ new Map();
297
+ byPartId = /* @__PURE__ */ new Map();
298
+ process(event) {
299
+ if (!isRecord(event)) {
300
+ return [];
301
+ }
302
+ const type = typeof event.type === "string" ? event.type : "";
303
+ const properties = isRecord(event.properties) ? event.properties : {};
304
+ const info = isRecord(properties.info) ? properties.info : null;
305
+ if (type === "message.updated" && typeof info?.id === "string" && info.role === "user") {
306
+ this.userMessageIds.add(info.id);
307
+ return [clone(event)];
308
+ }
309
+ if (type === "message.part.delta") {
310
+ const partId = typeof properties.partID === "string" ? properties.partID : null;
311
+ const messageId = typeof properties.messageID === "string" ? properties.messageID : null;
312
+ const delta = typeof properties.delta === "string" ? properties.delta : "";
313
+ if (!partId || !delta || properties.field !== "text" || messageId && this.userMessageIds.has(messageId)) {
314
+ return [];
315
+ }
316
+ const text = (this.textByPartId.get(partId) ?? "") + delta;
317
+ this.textByPartId.set(partId, text);
318
+ return [
319
+ this.upsertPart(partId, {
320
+ id: partId,
321
+ messageID: messageId ?? void 0,
322
+ type: "text",
323
+ text
324
+ })
325
+ ];
326
+ }
327
+ const part = isRecord(properties.part) ? properties.part : isRecord(event.part) ? event.part : null;
328
+ if (part && typeof part.id === "string") {
329
+ if (part.messageID && this.userMessageIds.has(String(part.messageID))) {
330
+ return [];
331
+ }
332
+ const previous = this.byPartId.get(part.id);
333
+ if (part.type === "text" && previous && isRecord(previous.properties?.part)) {
334
+ const previousPart = previous.properties.part;
335
+ const previousText = typeof previousPart.text === "string" ? previousPart.text : "";
336
+ const nextText = typeof part.text === "string" ? part.text : "";
337
+ if (nextText.length < previousText.length) {
338
+ return [clone(previous)];
339
+ }
340
+ }
341
+ this.byPartId.set(part.id, clone(event));
342
+ }
343
+ return [clone(event)];
344
+ }
345
+ seed(snapshots) {
346
+ this.userMessageIds.clear();
347
+ this.textByPartId.clear();
348
+ this.byPartId.clear();
349
+ for (const snapshot of snapshots) {
350
+ if (!isRecord(snapshot)) continue;
351
+ const type = typeof snapshot.type === "string" ? snapshot.type : "";
352
+ const properties = isRecord(snapshot.properties) ? snapshot.properties : {};
353
+ const info = isRecord(properties.info) ? properties.info : null;
354
+ if (type === "message.updated" && typeof info?.id === "string" && info.role === "user") {
355
+ this.userMessageIds.add(info.id);
356
+ continue;
357
+ }
358
+ const part = isRecord(properties.part) ? properties.part : isRecord(snapshot.part) ? snapshot.part : null;
359
+ if (part && typeof part.id === "string") {
360
+ this.byPartId.set(part.id, clone(snapshot));
361
+ if (typeof part.text === "string") {
362
+ this.textByPartId.set(part.id, part.text);
363
+ }
364
+ }
365
+ }
366
+ }
367
+ upsertPart(partId, part) {
368
+ const next = {
369
+ type: "message.part.updated",
370
+ properties: {
371
+ partID: partId,
372
+ part
373
+ }
374
+ };
375
+ this.byPartId.set(partId, next);
376
+ return clone(next);
377
+ }
378
+ };
379
+ var ProviderLogAssembler = class {
380
+ codex = new CodexLogAssembler();
381
+ openCode = new OpenCodeLogAssembler();
382
+ /**
383
+ * Process a raw provider event and return any newly-produced assembled
384
+ * snapshots. May return an empty array when the event is non-stateful (e.g.
385
+ * a delta with no payload) or already represented by a previous snapshot.
386
+ */
387
+ process(provider, event) {
388
+ if (provider === AgentProvider.Codex || provider === "codex") {
389
+ return this.codex.process(event);
390
+ }
391
+ if (provider === AgentProvider.OpenCode || provider === "opencode") {
392
+ return this.openCode.process(event);
393
+ }
394
+ if (isRecord(event)) {
395
+ return [clone(event)];
396
+ }
397
+ return [];
398
+ }
399
+ /**
400
+ * Re-seed the assembler from a sequence of previously-assembled snapshots
401
+ * so that subsequent `process()` calls produce snapshots consistent with
402
+ * the server-side state. Used by reconnecting UI clients after they replay
403
+ * the persisted history.
404
+ */
405
+ seedFromSnapshots(provider, snapshots) {
406
+ if (provider === AgentProvider.Codex || provider === "codex") {
407
+ this.codex.seed(snapshots);
408
+ return;
409
+ }
410
+ if (provider === AgentProvider.OpenCode || provider === "opencode") {
411
+ this.openCode.seed(snapshots);
412
+ return;
413
+ }
414
+ }
415
+ /**
416
+ * Given a sequence of assembled snapshots (typically the persisted history
417
+ * for a run), return one entry per item / part with the latest snapshot
418
+ * winning, preserving first-seen order.
419
+ *
420
+ * For providers that don't have a stateful item model (Claude Code), or
421
+ * for unrecognized snapshot shapes, entries are returned in original order
422
+ * with no dedup.
423
+ */
424
+ static dedupeSnapshots(provider, snapshots) {
425
+ if (provider === AgentProvider.Codex || provider === "codex") {
426
+ return dedupeByKey(snapshots, (snapshot) => {
427
+ const params = isRecord(snapshot.params) ? snapshot.params : null;
428
+ const item = params && isRecord(params.item) ? params.item : null;
429
+ return item && typeof item.id === "string" ? `item:${item.id}` : null;
430
+ });
431
+ }
432
+ if (provider === AgentProvider.OpenCode || provider === "opencode") {
433
+ return dedupeByKey(snapshots, (snapshot) => {
434
+ const properties = isRecord(snapshot.properties) ? snapshot.properties : null;
435
+ const part = properties && isRecord(properties.part) ? properties.part : isRecord(snapshot.part) ? snapshot.part : null;
436
+ if (part && typeof part.id === "string") {
437
+ return `part:${part.id}`;
438
+ }
439
+ const info = properties && isRecord(properties.info) ? properties.info : null;
440
+ if (info && typeof info.id === "string") {
441
+ return `message:${info.id}`;
442
+ }
443
+ return null;
444
+ });
445
+ }
446
+ return snapshots.map(clone);
447
+ }
448
+ };
449
+ function dedupeByKey(snapshots, keyOf) {
450
+ const order = [];
451
+ const latestByKey = /* @__PURE__ */ new Map();
452
+ const passthrough = [];
453
+ snapshots.forEach((snapshot, index) => {
454
+ if (!isRecord(snapshot)) return;
455
+ const key = keyOf(snapshot);
456
+ if (!key) {
457
+ passthrough.push(clone(snapshot));
458
+ order.push(`pt:${index}`);
459
+ latestByKey.set(`pt:${index}`, clone(snapshot));
460
+ return;
461
+ }
462
+ if (!latestByKey.has(key)) {
463
+ order.push(key);
464
+ }
465
+ latestByKey.set(key, clone(snapshot));
466
+ });
467
+ return order.map((key) => latestByKey.get(key)).filter(Boolean);
468
+ }
469
+
470
+ export {
471
+ createNormalizedEvent,
472
+ normalizeRawAgentEvent,
473
+ toAISDKEvent,
474
+ toAISDKStream,
475
+ ProviderLogAssembler
476
+ };
package/dist/cli.js CHANGED
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  toShellCommand
4
- } from "./chunk-JFDP556Q.js";
4
+ } from "./chunk-NSJM57Z4.js";
5
+ import {
6
+ SandboxProvider
7
+ } from "./chunk-GOFJNFAD.js";
5
8
 
6
9
  // src/sandbox-images/build.ts
7
10
  import { existsSync } from "fs";
@@ -77,14 +80,18 @@ async function buildSandboxImage(options) {
77
80
  options.cwd
78
81
  );
79
82
  switch (options.provider) {
80
- case "local-docker":
83
+ case SandboxProvider.LocalDocker:
81
84
  return buildLocalDockerImage(definition, options);
82
- case "modal":
85
+ case SandboxProvider.Modal:
83
86
  return buildModalImage(definition, options);
84
- case "daytona":
87
+ case SandboxProvider.Daytona:
85
88
  return buildDaytonaSnapshot(definition, options);
86
- case "e2b":
89
+ case SandboxProvider.E2B:
87
90
  return buildE2bTemplate(definition, options);
91
+ default:
92
+ throw new Error(
93
+ `Image building is not supported for provider "${options.provider}". Vercel sandboxes use runtime snapshots instead \u2014 see Sandbox.snapshot().`
94
+ );
88
95
  }
89
96
  }
90
97
  async function loadSandboxImageDefinition(preset, file, cwd = process.cwd()) {
@@ -371,7 +378,7 @@ function parseOptions(args) {
371
378
  return options;
372
379
  }
373
380
  function isSandboxProviderName(value) {
374
- return value === "local-docker" || value === "modal" || value === "daytona" || value === "e2b";
381
+ return Object.values(SandboxProvider).includes(value);
375
382
  }
376
383
  function isBuiltInImageName(value) {
377
384
  return value === "browser-agent" || value === "computer-use";
@@ -380,8 +387,8 @@ function printHelp() {
380
387
  process.stdout.write(`agentbox
381
388
 
382
389
  Usage:
383
- agentbox image build --provider <local-docker|modal|daytona|e2b> --preset <browser-agent|computer-use>
384
- agentbox image build --provider <local-docker|modal|daytona|e2b> --file <path>
390
+ agentbox image build --provider <local-docker|modal|daytona|vercel|e2b> --preset <browser-agent|computer-use>
391
+ agentbox image build --provider <local-docker|modal|daytona|vercel|e2b> --file <path>
385
392
 
386
393
  Options:
387
394
  --image-name <name> Override the built artifact name
@@ -390,6 +397,7 @@ Options:
390
397
  Environment:
391
398
  Modal: MODAL_TOKEN_ID, MODAL_TOKEN_SECRET, MODAL_ENVIRONMENT?, MODAL_ENDPOINT?
392
399
  Daytona: DAYTONA_API_KEY or DAYTONA_JWT_TOKEN, DAYTONA_ORGANIZATION_ID?, DAYTONA_API_URL?, DAYTONA_TARGET?
400
+ Vercel: VERCEL_TOKEN, VERCEL_TEAM_ID, VERCEL_PROJECT_ID
393
401
  E2B: E2B_API_KEY, E2B_DOMAIN?, E2B_ACCESS_TOKEN?
394
402
  `);
395
403
  }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Pure value-level provider enums.
3
+ *
4
+ * This file MUST NOT import anything from the rest of the SDK. It is used as
5
+ * a standalone tsup entry (`agentbox-sdk/enums`) so that client-side bundles
6
+ * in Next.js/browser contexts can reference `AgentProvider`/`SandboxProvider`
7
+ * without pulling in server-only modules like `net`, `crypto`, or the sandbox
8
+ * provider adapters.
9
+ */
10
+ declare const AgentProvider: {
11
+ readonly ClaudeCode: "claude-code";
12
+ readonly OpenCode: "open-code";
13
+ readonly Codex: "codex";
14
+ };
15
+ type AgentProvider = (typeof AgentProvider)[keyof typeof AgentProvider];
16
+ declare const SandboxProvider: {
17
+ readonly LocalDocker: "local-docker";
18
+ readonly Modal: "modal";
19
+ readonly Daytona: "daytona";
20
+ readonly Vercel: "vercel";
21
+ readonly E2B: "e2b";
22
+ };
23
+ type SandboxProvider = (typeof SandboxProvider)[keyof typeof SandboxProvider];
24
+
25
+ export { AgentProvider, SandboxProvider };
package/dist/enums.js ADDED
@@ -0,0 +1,8 @@
1
+ import {
2
+ AgentProvider,
3
+ SandboxProvider
4
+ } from "./chunk-GOFJNFAD.js";
5
+ export {
6
+ AgentProvider,
7
+ SandboxProvider
8
+ };
@@ -1,6 +1,90 @@
1
- export { A as AISDKEvent, M as MessageCompletedEvent, N as MessageInjectedEvent, O as MessageStartedEvent, P as NormalizedAgentEvent, Q as NormalizedAgentEventBase, R as NormalizedAgentEventType, X as PermissionRequestedEvent, Y as PermissionResolvedEvent, Z as RawAgentEvent, _ as ReasoningDeltaEvent, a0 as RunCompletedEvent, a1 as RunErrorEvent, a2 as RunStartedEvent, a3 as TextDeltaEvent, a5 as ToolCallCompletedEvent, a6 as ToolCallDeltaEvent, a7 as ToolCallStartedEvent, aa as createNormalizedEvent, ab as normalizeRawAgentEvent, ac as toAISDKEvent, ad as toAISDKStream } from '../types-BwcoN0n-.js';
2
- import '../Sandbox-DTprxRZf.js';
1
+ export { A as AISDKEvent, S as MessageCompletedEvent, T as MessageInjectedEvent, U as MessageStartedEvent, V as NormalizedAgentEvent, W as NormalizedAgentEventBase, X as NormalizedAgentEventType, a1 as PermissionRequestedEvent, a2 as PermissionResolvedEvent, a3 as RawAgentEvent, a4 as ReasoningDeltaEvent, a6 as RunCompletedEvent, a7 as RunErrorEvent, a8 as RunStartedEvent, a9 as TextDeltaEvent, ab as ToolCallCompletedEvent, ac as ToolCallDeltaEvent, ad as ToolCallStartedEvent, ag as createNormalizedEvent, ah as normalizeRawAgentEvent, ai as toAISDKEvent, aj as toAISDKStream } from '../types-B3N-Qo2q.js';
2
+ import { AgentProvider } from '../enums.js';
3
+ import '../Sandbox-CByFJI8X.js';
3
4
  import 'e2b';
5
+ import '@vercel/sandbox';
4
6
  import '@daytonaio/sdk';
5
7
  import 'modal';
6
8
  import 'dockerode';
9
+
10
+ /**
11
+ * Provider-aware log assembler for agentbox runs.
12
+ *
13
+ * Agentbox streams a sequence of raw provider events (deltas of text /
14
+ * reasoning / tool calls) for each `AgentRun` via `run.rawEvents()`. Most UIs
15
+ * ultimately want a stable "snapshot per item" view (one box per assistant
16
+ * message, one box per shell command, etc.) instead of the raw delta stream.
17
+ *
18
+ * This module converts deltas into snapshots while remaining transport- and
19
+ * persistence-agnostic so it can run in any environment that consumes the
20
+ * SDK's raw event stream:
21
+ *
22
+ * - Server processes (e.g. orchestrators, log persisters) can call
23
+ * `process()` to derive snapshots they push into a history store, then
24
+ * persist a deduped view at end of run via the static `dedupeSnapshots`.
25
+ * - Browser/UI clients can `seedFromSnapshots()` from a replayed history
26
+ * and re-run `process()` over live deltas to keep state aligned with the
27
+ * server without duplicating normalization logic.
28
+ *
29
+ * Constraints:
30
+ * - No Node-only imports; this module must run in the browser. The
31
+ * `agentbox-sdk/events` entrypoint is therefore safe for client bundles.
32
+ * - Pure logic; transports (Redis, SSE, websockets, files, …) are entirely
33
+ * the responsibility of the caller.
34
+ */
35
+
36
+ type JsonRecord = Record<string, unknown>;
37
+ /**
38
+ * Provider-aware assembler that routes raw events through the right
39
+ * per-provider implementation. Stateful: holds dedup/text maps so it can
40
+ * incrementally combine deltas into snapshots.
41
+ *
42
+ * @example Server-side use during an `AgentRun`:
43
+ * ```ts
44
+ * const assembler = new ProviderLogAssembler();
45
+ * for await (const raw of run.rawEvents()) {
46
+ * const snapshots = assembler.process(raw.provider, raw.payload);
47
+ * for (const snapshot of snapshots) historyStore.append(snapshot);
48
+ * }
49
+ * ```
50
+ *
51
+ * @example Reconnecting UI client:
52
+ * ```ts
53
+ * const assembler = new ProviderLogAssembler();
54
+ * const history = await fetchHistorySnapshots();
55
+ * assembler.seedFromSnapshots(provider, history);
56
+ * subscribeRawDeltas((event) => {
57
+ * const snapshots = assembler.process(provider, event);
58
+ * render(snapshots);
59
+ * });
60
+ * ```
61
+ */
62
+ declare class ProviderLogAssembler {
63
+ private readonly codex;
64
+ private readonly openCode;
65
+ /**
66
+ * Process a raw provider event and return any newly-produced assembled
67
+ * snapshots. May return an empty array when the event is non-stateful (e.g.
68
+ * a delta with no payload) or already represented by a previous snapshot.
69
+ */
70
+ process(provider: AgentProvider | string | null | undefined, event: unknown): JsonRecord[];
71
+ /**
72
+ * Re-seed the assembler from a sequence of previously-assembled snapshots
73
+ * so that subsequent `process()` calls produce snapshots consistent with
74
+ * the server-side state. Used by reconnecting UI clients after they replay
75
+ * the persisted history.
76
+ */
77
+ seedFromSnapshots(provider: AgentProvider | string | null | undefined, snapshots: JsonRecord[]): void;
78
+ /**
79
+ * Given a sequence of assembled snapshots (typically the persisted history
80
+ * for a run), return one entry per item / part with the latest snapshot
81
+ * winning, preserving first-seen order.
82
+ *
83
+ * For providers that don't have a stateful item model (Claude Code), or
84
+ * for unrecognized snapshot shapes, entries are returned in original order
85
+ * with no dedup.
86
+ */
87
+ static dedupeSnapshots(provider: AgentProvider | string | null | undefined, snapshots: JsonRecord[]): JsonRecord[];
88
+ }
89
+
90
+ export { ProviderLogAssembler };
@@ -1,10 +1,13 @@
1
1
  import {
2
+ ProviderLogAssembler,
2
3
  createNormalizedEvent,
3
4
  normalizeRawAgentEvent,
4
5
  toAISDKEvent,
5
6
  toAISDKStream
6
- } from "../chunk-7FLLQJ6J.js";
7
+ } from "../chunk-ZOWBRUQR.js";
8
+ import "../chunk-GOFJNFAD.js";
7
9
  export {
10
+ ProviderLogAssembler,
8
11
  createNormalizedEvent,
9
12
  normalizeRawAgentEvent,
10
13
  toAISDKEvent,