@astralform/js 0.1.3 → 0.2.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/dist/index.cjs CHANGED
@@ -23,6 +23,7 @@ __export(index_exports, {
23
23
  AstralformClient: () => AstralformClient,
24
24
  AstralformError: () => AstralformError,
25
25
  AuthenticationError: () => AuthenticationError,
26
+ BlockBuilder: () => BlockBuilder,
26
27
  ChatSession: () => ChatSession,
27
28
  ConnectionError: () => ConnectionError,
28
29
  InMemoryStorage: () => InMemoryStorage,
@@ -32,6 +33,7 @@ __export(index_exports, {
32
33
  StreamAbortedError: () => StreamAbortedError,
33
34
  ToolRegistry: () => ToolRegistry,
34
35
  generateId: () => generateId,
36
+ standardHandlers: () => standardHandlers,
35
37
  streamJobSSE: () => streamJobSSE
36
38
  });
37
39
  module.exports = __toCommonJS(index_exports);
@@ -285,10 +287,10 @@ var AstralformClient = class {
285
287
  isEnabled: s.is_enabled
286
288
  }));
287
289
  }
288
- async getConversationEvents(conversationId) {
289
- return this.get(
290
- `/v1/conversations/${encodeURIComponent(conversationId)}/events`
291
- );
290
+ async getConversationEvents(conversationId, jobId) {
291
+ let url = `/v1/conversations/${encodeURIComponent(conversationId)}/events`;
292
+ if (jobId) url += `?job_id=${encodeURIComponent(jobId)}`;
293
+ return this.get(url);
292
294
  }
293
295
  async submitToolResult(request) {
294
296
  await this.post("/v1/tool-result", request);
@@ -359,6 +361,87 @@ var AstralformClient = class {
359
361
  }
360
362
  };
361
363
 
364
+ // src/block-builder.ts
365
+ var _idCounter = 0;
366
+ var BlockBuilder = class {
367
+ constructor() {
368
+ this._blocks = [];
369
+ this._handlers = /* @__PURE__ */ new Map();
370
+ this._onChange = null;
371
+ // Active block refs — public so handlers can read/write them
372
+ this.activeTextId = null;
373
+ this.activeThinkingId = null;
374
+ this.thinkingStartMs = null;
375
+ }
376
+ // ── Registration ──────────────────────────────────────────────
377
+ on(eventType, handler) {
378
+ this._handlers.set(eventType, handler);
379
+ }
380
+ registerHandlers(handlers) {
381
+ for (const [type, handler] of Object.entries(handlers)) {
382
+ this._handlers.set(type, handler);
383
+ }
384
+ }
385
+ // ── Event processing ──────────────────────────────────────────
386
+ processEvent(event) {
387
+ const handler = this._handlers.get(event.type);
388
+ if (handler === null) return;
389
+ if (!handler) return;
390
+ handler(event, this);
391
+ }
392
+ // ── State ─────────────────────────────────────────────────────
393
+ getBlocks() {
394
+ return [...this._blocks];
395
+ }
396
+ reset() {
397
+ this._blocks = [];
398
+ this.activeTextId = null;
399
+ this.activeThinkingId = null;
400
+ this.thinkingStartMs = null;
401
+ }
402
+ setOnChange(fn) {
403
+ this._onChange = fn;
404
+ }
405
+ // ── Block manipulation (used by handlers) ─────────────────────
406
+ addBlock(block) {
407
+ this._blocks = [...this._blocks, block];
408
+ this._notify();
409
+ }
410
+ updateBlock(id, updater) {
411
+ let changed = false;
412
+ this._blocks = this._blocks.map((b) => {
413
+ if (b.id !== id) return b;
414
+ changed = true;
415
+ return updater(b);
416
+ });
417
+ if (changed) this._notify();
418
+ }
419
+ /** Update any block by id with a partial update (type-loose for handlers). */
420
+ patchBlock(id, patch) {
421
+ let changed = false;
422
+ this._blocks = this._blocks.map((b) => {
423
+ if (b.id !== id) return b;
424
+ changed = true;
425
+ return { ...b, ...patch };
426
+ });
427
+ if (changed) this._notify();
428
+ }
429
+ findBlock(predicate) {
430
+ for (let i = this._blocks.length - 1; i >= 0; i--) {
431
+ const block = this._blocks[i];
432
+ if (block && predicate(block)) return block;
433
+ }
434
+ return void 0;
435
+ }
436
+ nextId() {
437
+ return `blk_${++_idCounter}`;
438
+ }
439
+ // ── Internal ──────────────────────────────────────────────────
440
+ _notify() {
441
+ this._onChange?.();
442
+ }
443
+ };
444
+
362
445
  // src/storage.ts
363
446
  var InMemoryStorage = class {
364
447
  constructor() {
@@ -523,7 +606,7 @@ function generateId() {
523
606
 
524
607
  // src/session.ts
525
608
  var ChatSession = class {
526
- constructor(config, storage) {
609
+ constructor(config, storage, blockBuilder) {
527
610
  // State
528
611
  this.conversationId = null;
529
612
  this.conversations = [];
@@ -553,6 +636,13 @@ var ChatSession = class {
553
636
  this.client = new AstralformClient(config);
554
637
  this.toolRegistry = new ToolRegistry();
555
638
  this.storage = storage ?? new InMemoryStorage();
639
+ this.blockBuilder = blockBuilder ?? new BlockBuilder();
640
+ this.blockBuilder.setOnChange(() => {
641
+ this.emit({
642
+ type: "blocks_changed",
643
+ blocks: this.blockBuilder.getBlocks()
644
+ });
645
+ });
556
646
  }
557
647
  on(handler) {
558
648
  this.handlers.add(handler);
@@ -561,6 +651,9 @@ var ChatSession = class {
561
651
  };
562
652
  }
563
653
  emit(event) {
654
+ if (event.type !== "blocks_changed" && event.type !== "connected") {
655
+ this.blockBuilder.processEvent(event);
656
+ }
564
657
  for (const handler of this.handlers) {
565
658
  try {
566
659
  handler(event);
@@ -617,14 +710,15 @@ var ChatSession = class {
617
710
  };
618
711
  await this.processStream(request);
619
712
  }
620
- async resendFromCheckpoint(messageId, newContent) {
713
+ async resendFromCheckpoint(messageId, newContent, options) {
621
714
  if (this.isStreaming) return;
622
715
  const request = {
623
716
  message: newContent,
624
717
  conversation_id: this.conversationId ?? void 0,
625
718
  resend_from: messageId,
626
719
  mcp_manifest: this.toolRegistry.getManifest(),
627
- enabled_mcp: Array.from(this.enabledClientTools)
720
+ enabled_mcp: Array.from(this.enabledClientTools),
721
+ enable_search: options?.enableSearch
628
722
  };
629
723
  await this.processStream(request);
630
724
  }
@@ -664,12 +758,23 @@ var ChatSession = class {
664
758
  }
665
759
  const messageId = job.message_id;
666
760
  this.lastSeq = -1;
667
- let stopTitle;
668
761
  const stream = this.client.streamJobEvents(
669
762
  job.job_id,
670
763
  this.lastSeq,
671
764
  this.abortController?.signal
672
765
  );
766
+ await this.consumeEventStream(
767
+ stream,
768
+ conversationId,
769
+ messageId,
770
+ true
771
+ // executeClientTools
772
+ );
773
+ }
774
+ /**
775
+ * Shared event consumption loop used by both consumeJobStream and reconnectToJob.
776
+ */
777
+ async consumeEventStream(stream, conversationId, messageId, executeClientTools) {
673
778
  for await (const raw of stream) {
674
779
  let parsed;
675
780
  try {
@@ -693,6 +798,9 @@ var ChatSession = class {
693
798
  if (!this.conversationId) {
694
799
  this.conversationId = conversationId;
695
800
  }
801
+ if (parsed.message_id) {
802
+ messageId = parsed.message_id;
803
+ }
696
804
  if (parsed.model_display_name) {
697
805
  this.modelDisplayName = parsed.model_display_name;
698
806
  this.emit({
@@ -707,7 +815,7 @@ var ChatSession = class {
707
815
  break;
708
816
  case "tool_use_start": {
709
817
  this.applyEvent(parsed);
710
- if (parsed.is_client_tool) {
818
+ if (executeClientTools && parsed.is_client_tool) {
711
819
  const results = await this.executeClientTools([
712
820
  {
713
821
  callId: parsed.call_id,
@@ -759,7 +867,15 @@ var ChatSession = class {
759
867
  });
760
868
  break;
761
869
  case "message_stop":
762
- stopTitle = parsed.title;
870
+ await this.completeStream(
871
+ conversationId,
872
+ messageId,
873
+ parsed.title,
874
+ parsed.metrics,
875
+ parsed.job_id
876
+ );
877
+ this.isStreaming = false;
878
+ this.currentJobId = null;
763
879
  break;
764
880
  case "error":
765
881
  this.emit({
@@ -771,8 +887,6 @@ var ChatSession = class {
771
887
  this.applyEvent(parsed);
772
888
  }
773
889
  }
774
- this.currentJobId = null;
775
- await this.completeStream(conversationId, messageId, stopTitle);
776
890
  }
777
891
  /**
778
892
  * Apply a single SSE event to session state and notify consumers.
@@ -780,6 +894,45 @@ var ChatSession = class {
780
894
  */
781
895
  applyEvent(event) {
782
896
  switch (event.type) {
897
+ case "user_message":
898
+ this.emit({ type: "user_message", content: event.content });
899
+ break;
900
+ case "title_generated":
901
+ this.emit({ type: "title_generated", title: event.title });
902
+ break;
903
+ case "message_start":
904
+ if (event.conversation_id && !this.conversationId) {
905
+ this.conversationId = event.conversation_id;
906
+ }
907
+ if (event.model_display_name) {
908
+ this.modelDisplayName = event.model_display_name;
909
+ this.emit({ type: "model_info", name: event.model_display_name });
910
+ }
911
+ break;
912
+ case "content_block_delta":
913
+ this.streamingContent += event.delta.text;
914
+ this.emit({ type: "chunk", text: event.delta.text });
915
+ break;
916
+ case "thinking_delta":
917
+ this.thinkingContent += event.delta.text;
918
+ this.isThinking = true;
919
+ this.emit({ type: "thinking_delta", text: event.delta.text });
920
+ break;
921
+ case "thinking_complete":
922
+ this.isThinking = false;
923
+ this.emit({ type: "thinking_complete" });
924
+ break;
925
+ case "message_stop":
926
+ this.emit({
927
+ type: "complete",
928
+ content: this.streamingContent,
929
+ conversationId: this.conversationId ?? "",
930
+ messageId: event.job_id ?? "",
931
+ title: event.title,
932
+ metrics: event.metrics,
933
+ job_id: event.job_id
934
+ });
935
+ break;
783
936
  case "tool_use_start": {
784
937
  const request = {
785
938
  callId: event.call_id,
@@ -807,7 +960,9 @@ var ChatSession = class {
807
960
  type: "tool_end",
808
961
  callId: event.call_id,
809
962
  toolName: event.tool,
810
- result: event.result
963
+ result: event.result,
964
+ sources: event.sources,
965
+ durationMs: event.duration_ms
811
966
  });
812
967
  break;
813
968
  }
@@ -915,18 +1070,25 @@ var ChatSession = class {
915
1070
  sizeBytes: event.size_bytes
916
1071
  });
917
1072
  break;
918
- case "activity":
1073
+ case "timeline_entry":
919
1074
  this.emit({
920
- type: "activity",
921
- activityId: event.activity_id,
1075
+ type: "timeline_entry",
1076
+ id: event.id,
922
1077
  status: event.status,
923
- category: event.category,
924
- title: event.title,
1078
+ kind: event.kind,
1079
+ agent_name: event.agent_name,
1080
+ tool_name: event.tool_name,
1081
+ display_name: event.display_name,
1082
+ tool_category: event.tool_category,
1083
+ viewer: event.viewer,
1084
+ call_id: event.call_id,
925
1085
  detail: event.detail,
1086
+ started_at: event.started_at,
1087
+ duration_ms: event.duration_ms,
1088
+ output_summary: event.output_summary,
926
1089
  sources: event.sources,
927
- toolName: event.tool_name,
928
- agentName: event.agent_name,
929
- durationMs: event.duration_ms
1090
+ parent_id: event.parent_id,
1091
+ structured_output: event.structured_output
930
1092
  });
931
1093
  break;
932
1094
  case "editor_content_start":
@@ -976,7 +1138,7 @@ var ChatSession = class {
976
1138
  this.executingTool = null;
977
1139
  return results;
978
1140
  }
979
- async completeStream(conversationId, messageId, title) {
1141
+ async completeStream(conversationId, messageId, title, metrics, jobId) {
980
1142
  const assistantMessage = {
981
1143
  id: messageId || generateId(),
982
1144
  conversationId,
@@ -999,9 +1161,57 @@ var ChatSession = class {
999
1161
  content: this.streamingContent,
1000
1162
  conversationId,
1001
1163
  messageId: assistantMessage.id,
1002
- title
1164
+ title,
1165
+ metrics,
1166
+ job_id: jobId
1003
1167
  });
1004
1168
  }
1169
+ /**
1170
+ * Load conversation context (messages) without replaying events.
1171
+ * Used before reconnectToJob — SSE replay handles event replay.
1172
+ */
1173
+ async loadConversation(id) {
1174
+ this.conversationId = id;
1175
+ this.resetStreamingState();
1176
+ this.blockBuilder.reset();
1177
+ this.messages = await this.client.getMessages(id).catch(() => this.storage.fetchMessages(id));
1178
+ }
1179
+ /**
1180
+ * Reconnect to a running job's SSE stream (e.g. after page reload).
1181
+ * Replays all events from the beginning and continues live.
1182
+ * Does NOT reset BlockBuilder — caller controls reset.
1183
+ */
1184
+ async reconnectToJob(jobId) {
1185
+ if (this.isStreaming) return;
1186
+ this.isStreaming = true;
1187
+ this.currentJobId = jobId;
1188
+ this.lastSeq = -1;
1189
+ this.resetStreamingState();
1190
+ this.abortController = new AbortController();
1191
+ try {
1192
+ const stream = this.client.streamJobEvents(
1193
+ jobId,
1194
+ this.lastSeq,
1195
+ this.abortController?.signal
1196
+ );
1197
+ await this.consumeEventStream(
1198
+ stream,
1199
+ this.conversationId ?? "",
1200
+ "",
1201
+ false
1202
+ // don't execute client tools on reconnect
1203
+ );
1204
+ } catch (err) {
1205
+ this.emit({
1206
+ type: "error",
1207
+ error: err instanceof Error ? err : new ConnectionError(String(err))
1208
+ });
1209
+ } finally {
1210
+ this.isStreaming = false;
1211
+ this.executingTool = null;
1212
+ this.abortController = null;
1213
+ }
1214
+ }
1005
1215
  disconnect() {
1006
1216
  if (this.currentJobId) {
1007
1217
  this.client.cancelJob(this.currentJobId).catch(() => {
@@ -1027,30 +1237,21 @@ var ChatSession = class {
1027
1237
  this.streamingContent = "";
1028
1238
  return id;
1029
1239
  }
1030
- async switchConversation(id) {
1240
+ async switchConversation(id, jobId) {
1031
1241
  this.conversationId = id;
1032
1242
  this.resetStreamingState();
1243
+ this.blockBuilder.reset();
1033
1244
  const [messagesResult, eventsResult] = await Promise.allSettled([
1034
1245
  this.client.getMessages(id).catch(() => this.storage.fetchMessages(id)),
1035
- this.client.getConversationEvents(id)
1246
+ this.client.getConversationEvents(id, jobId)
1036
1247
  ]);
1037
1248
  this.messages = messagesResult.status === "fulfilled" ? messagesResult.value : [];
1038
1249
  if (eventsResult.status === "fulfilled") {
1039
1250
  for (const ev of eventsResult.value) {
1040
- this.replayEvent(ev.event, ev.data);
1251
+ this.applyEvent({ type: ev.event, ...ev.data });
1041
1252
  }
1042
1253
  }
1043
1254
  }
1044
- /**
1045
- * Replay a single persisted event to reconstruct session state.
1046
- * Skips text deltas (final content is already in messages[]).
1047
- */
1048
- replayEvent(eventType, data) {
1049
- if (eventType === "content_block_delta" || eventType === "thinking_delta" || eventType === "subagent_content_delta" || eventType === "thinking_complete" || eventType === "editor_content_start" || eventType === "editor_content_delta" || eventType === "editor_content_end") {
1050
- return;
1051
- }
1052
- this.applyEvent({ type: eventType, ...data });
1053
- }
1054
1255
  async deleteConversation(id) {
1055
1256
  try {
1056
1257
  await this.client.deleteConversation(id);
@@ -1072,11 +1273,232 @@ var ChatSession = class {
1072
1273
  return true;
1073
1274
  }
1074
1275
  };
1276
+
1277
+ // src/standard-handlers.ts
1278
+ function finalizeText(builder) {
1279
+ if (builder.activeTextId) {
1280
+ builder.patchBlock(builder.activeTextId, {
1281
+ isStreaming: false
1282
+ });
1283
+ builder.activeTextId = null;
1284
+ }
1285
+ }
1286
+ function finalizeThinking(builder) {
1287
+ if (builder.activeThinkingId) {
1288
+ builder.patchBlock(builder.activeThinkingId, {
1289
+ isActive: false
1290
+ });
1291
+ builder.activeThinkingId = null;
1292
+ builder.thinkingStartMs = null;
1293
+ }
1294
+ }
1295
+ var handleUserMessage = (event, builder) => {
1296
+ if (builder.findBlock((b) => b.type === "user")) return;
1297
+ const e = event;
1298
+ builder.addBlock({ type: "user", id: builder.nextId(), content: e.content });
1299
+ };
1300
+ var handleChunk = (event, builder) => {
1301
+ const e = event;
1302
+ if (!builder.activeTextId) {
1303
+ const id = builder.nextId();
1304
+ builder.activeTextId = id;
1305
+ builder.addBlock({
1306
+ type: "text",
1307
+ id,
1308
+ content: e.text,
1309
+ isStreaming: true
1310
+ });
1311
+ } else {
1312
+ const id = builder.activeTextId;
1313
+ const existing = builder.findBlock((b) => b.id === id);
1314
+ if (existing && existing.type === "text") {
1315
+ builder.patchBlock(id, {
1316
+ content: existing.content + e.text
1317
+ });
1318
+ }
1319
+ }
1320
+ };
1321
+ var handleToolCall = (event, builder) => {
1322
+ const e = event;
1323
+ finalizeText(builder);
1324
+ builder.addBlock({
1325
+ type: "tool",
1326
+ id: builder.nextId(),
1327
+ callId: e.request.callId,
1328
+ toolName: e.request.toolName,
1329
+ displayName: e.request.displayName,
1330
+ description: e.request.description,
1331
+ arguments: e.request.arguments,
1332
+ toolCategory: e.request.toolCategory,
1333
+ iconUrl: e.request.iconUrl,
1334
+ status: "calling"
1335
+ });
1336
+ };
1337
+ var handleToolExecuting = (event, builder) => {
1338
+ const e = event;
1339
+ const block = builder.findBlock(
1340
+ (b) => b.type === "tool" && b.toolName === e.name && b.status === "calling"
1341
+ );
1342
+ if (block) {
1343
+ builder.patchBlock(block.id, { status: "executing" });
1344
+ }
1345
+ };
1346
+ var handleToolEnd = (event, builder) => {
1347
+ const e = event;
1348
+ const callId = e.type === "tool_end" ? e.callId : void 0;
1349
+ const name = e.type === "tool_end" ? e.toolName : e.name;
1350
+ const block = builder.findBlock(
1351
+ (b) => b.type === "tool" && (callId ? b.callId === callId : b.toolName === name) && b.status !== "completed"
1352
+ );
1353
+ if (block) {
1354
+ const toolEnd = e.type === "tool_end" ? e : null;
1355
+ builder.patchBlock(block.id, {
1356
+ status: "completed",
1357
+ ...toolEnd?.sources ? { sources: toolEnd.sources } : {},
1358
+ ...toolEnd?.durationMs != null ? { durationMs: toolEnd.durationMs } : {},
1359
+ ...toolEnd?.result ? { result: toolEnd.result } : {}
1360
+ });
1361
+ }
1362
+ };
1363
+ var handleAgentStart = (event, builder) => {
1364
+ const e = event;
1365
+ finalizeText(builder);
1366
+ builder.addBlock({
1367
+ type: "agent",
1368
+ id: builder.nextId(),
1369
+ agentName: e.agentName,
1370
+ displayName: e.agentDisplayName,
1371
+ avatarUrl: e.avatarUrl
1372
+ });
1373
+ };
1374
+ var handleThinkingDelta = (event, builder) => {
1375
+ const e = event;
1376
+ if (!builder.activeThinkingId) {
1377
+ const id = builder.nextId();
1378
+ builder.activeThinkingId = id;
1379
+ builder.thinkingStartMs = Date.now();
1380
+ builder.addBlock({
1381
+ type: "thinking",
1382
+ id,
1383
+ content: e.text,
1384
+ isActive: true
1385
+ });
1386
+ } else {
1387
+ const id = builder.activeThinkingId;
1388
+ const existing = builder.findBlock((b) => b.id === id);
1389
+ if (existing && existing.type === "thinking") {
1390
+ builder.patchBlock(id, {
1391
+ content: existing.content + e.text
1392
+ });
1393
+ }
1394
+ }
1395
+ };
1396
+ var handleThinkingComplete = (_event, builder) => {
1397
+ if (builder.activeThinkingId) {
1398
+ const durationMs = builder.thinkingStartMs ? Math.max(0, Date.now() - builder.thinkingStartMs) : void 0;
1399
+ builder.patchBlock(builder.activeThinkingId, {
1400
+ isActive: false,
1401
+ durationMs
1402
+ });
1403
+ builder.activeThinkingId = null;
1404
+ builder.thinkingStartMs = null;
1405
+ }
1406
+ };
1407
+ var handleSubagentStart = (event, builder) => {
1408
+ const e = event;
1409
+ finalizeText(builder);
1410
+ builder.addBlock({
1411
+ type: "subagent",
1412
+ id: builder.nextId(),
1413
+ agentName: e.agentName,
1414
+ displayName: e.displayName,
1415
+ toolCallId: e.toolCallId,
1416
+ avatarUrl: e.avatarUrl,
1417
+ description: e.description,
1418
+ content: "",
1419
+ isActive: true
1420
+ });
1421
+ };
1422
+ var handleSubagentChunk = (event, builder) => {
1423
+ const e = event;
1424
+ const block = builder.findBlock(
1425
+ (b) => b.type === "subagent" && b.toolCallId === e.toolCallId
1426
+ );
1427
+ if (block && block.type === "subagent") {
1428
+ builder.patchBlock(block.id, {
1429
+ content: block.content + e.text
1430
+ });
1431
+ }
1432
+ };
1433
+ var handleSubagentUpdate = (event, builder) => {
1434
+ const e = event;
1435
+ const block = builder.findBlock(
1436
+ (b) => b.type === "subagent" && b.toolCallId === e.toolCallId
1437
+ );
1438
+ if (block) {
1439
+ builder.patchBlock(block.id, {
1440
+ displayName: e.displayName
1441
+ });
1442
+ }
1443
+ };
1444
+ var handleSubagentEnd = (event, builder) => {
1445
+ const e = event;
1446
+ const block = builder.findBlock(
1447
+ (b) => b.type === "subagent" && b.toolCallId === e.toolCallId
1448
+ );
1449
+ if (block) {
1450
+ builder.patchBlock(block.id, {
1451
+ isActive: false
1452
+ });
1453
+ }
1454
+ };
1455
+ var handleComplete = (_event, builder) => {
1456
+ finalizeText(builder);
1457
+ finalizeThinking(builder);
1458
+ for (const b of builder.getBlocks()) {
1459
+ if (b.type === "tool" && b.status !== "completed") {
1460
+ builder.patchBlock(b.id, { status: "completed" });
1461
+ }
1462
+ }
1463
+ };
1464
+ var handleError = (event, builder) => {
1465
+ const e = event;
1466
+ finalizeText(builder);
1467
+ finalizeThinking(builder);
1468
+ builder.addBlock({
1469
+ type: "error",
1470
+ id: builder.nextId(),
1471
+ message: e.error.message
1472
+ });
1473
+ };
1474
+ var handleDisconnected = (_event, builder) => {
1475
+ finalizeText(builder);
1476
+ finalizeThinking(builder);
1477
+ };
1478
+ var standardHandlers = {
1479
+ user_message: handleUserMessage,
1480
+ chunk: handleChunk,
1481
+ tool_call: handleToolCall,
1482
+ tool_executing: handleToolExecuting,
1483
+ tool_completed: handleToolEnd,
1484
+ tool_end: handleToolEnd,
1485
+ agent_start: handleAgentStart,
1486
+ thinking_delta: handleThinkingDelta,
1487
+ thinking_complete: handleThinkingComplete,
1488
+ subagent_start: handleSubagentStart,
1489
+ subagent_chunk: handleSubagentChunk,
1490
+ subagent_update: handleSubagentUpdate,
1491
+ subagent_end: handleSubagentEnd,
1492
+ complete: handleComplete,
1493
+ error: handleError,
1494
+ disconnected: handleDisconnected
1495
+ };
1075
1496
  // Annotate the CommonJS export names for ESM import in node:
1076
1497
  0 && (module.exports = {
1077
1498
  AstralformClient,
1078
1499
  AstralformError,
1079
1500
  AuthenticationError,
1501
+ BlockBuilder,
1080
1502
  ChatSession,
1081
1503
  ConnectionError,
1082
1504
  InMemoryStorage,
@@ -1086,6 +1508,7 @@ var ChatSession = class {
1086
1508
  StreamAbortedError,
1087
1509
  ToolRegistry,
1088
1510
  generateId,
1511
+ standardHandlers,
1089
1512
  streamJobSSE
1090
1513
  });
1091
1514
  //# sourceMappingURL=index.cjs.map