@astralform/js 0.2.1 → 0.2.2

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.js CHANGED
@@ -332,6 +332,8 @@ var BlockBuilder = class {
332
332
  this.activeTextId = null;
333
333
  this.activeThinkingId = null;
334
334
  this.thinkingStartMs = null;
335
+ this.activeEditorId = null;
336
+ this.activeTodoId = null;
335
337
  }
336
338
  // ── Registration ──────────────────────────────────────────────
337
339
  on(eventType, handler) {
@@ -358,6 +360,8 @@ var BlockBuilder = class {
358
360
  this.activeTextId = null;
359
361
  this.activeThinkingId = null;
360
362
  this.thinkingStartMs = null;
363
+ this.activeEditorId = null;
364
+ this.activeTodoId = null;
361
365
  }
362
366
  setOnChange(fn) {
363
367
  this._onChange = fn;
@@ -583,7 +587,6 @@ var ChatSession = class {
583
587
  this.thinkingContent = "";
584
588
  this.isThinking = false;
585
589
  this.activeSubagents = /* @__PURE__ */ new Map();
586
- this.sources = [];
587
590
  this.capsuleOutputs = [];
588
591
  this.todos = [];
589
592
  this.activeTools = /* @__PURE__ */ new Map();
@@ -687,7 +690,6 @@ var ChatSession = class {
687
690
  this.thinkingContent = "";
688
691
  this.isThinking = false;
689
692
  this.activeSubagents.clear();
690
- this.sources = [];
691
693
  this.capsuleOutputs = [];
692
694
  this.todos = [];
693
695
  this.activeTools.clear();
@@ -699,10 +701,12 @@ var ChatSession = class {
699
701
  try {
700
702
  await this.consumeJobStream(request);
701
703
  } catch (err) {
702
- this.emit({
703
- type: "error",
704
- error: err instanceof Error ? err : new ConnectionError(String(err))
705
- });
704
+ if (!(err instanceof DOMException && err.name === "AbortError")) {
705
+ this.emit({
706
+ type: "error",
707
+ error: err instanceof Error ? err : new ConnectionError(String(err))
708
+ });
709
+ }
706
710
  } finally {
707
711
  this.isStreaming = false;
708
712
  this.executingTool = null;
@@ -855,11 +859,24 @@ var ChatSession = class {
855
859
  applyEvent(event) {
856
860
  switch (event.type) {
857
861
  case "user_message":
858
- this.emit({ type: "user_message", content: event.content });
862
+ this.emit({
863
+ type: "user_message",
864
+ content: event.content,
865
+ createdAt: event.created_at
866
+ });
859
867
  break;
860
- case "title_generated":
868
+ case "title_generated": {
869
+ if (this.conversationId && event.title) {
870
+ const conv = this.conversations.find(
871
+ (c) => c.id === this.conversationId
872
+ );
873
+ if (conv) {
874
+ conv.title = event.title;
875
+ }
876
+ }
861
877
  this.emit({ type: "title_generated", title: event.title });
862
878
  break;
879
+ }
863
880
  case "message_start":
864
881
  if (event.conversation_id && !this.conversationId) {
865
882
  this.conversationId = event.conversation_id;
@@ -882,6 +899,23 @@ var ChatSession = class {
882
899
  this.isThinking = false;
883
900
  this.emit({ type: "thinking_complete" });
884
901
  break;
902
+ case "tool_executing":
903
+ this.emit({
904
+ type: "tool_executing",
905
+ name: event.tool,
906
+ call_id: event.call_id
907
+ });
908
+ break;
909
+ case "tool_progress":
910
+ this.emit({
911
+ type: "tool_progress",
912
+ callId: event.call_id,
913
+ tool: event.tool,
914
+ index: event.index,
915
+ total: event.total,
916
+ item: event.item
917
+ });
918
+ break;
885
919
  case "message_stop":
886
920
  this.emit({
887
921
  type: "complete",
@@ -991,10 +1025,6 @@ var ChatSession = class {
991
1025
  result: event.result
992
1026
  });
993
1027
  break;
994
- case "sources":
995
- this.sources.push(...event.sources);
996
- this.emit({ type: "sources", sources: event.sources });
997
- break;
998
1028
  case "capsule_output": {
999
1029
  const capsule = {
1000
1030
  toolName: event.tool_name,
@@ -1030,27 +1060,6 @@ var ChatSession = class {
1030
1060
  sizeBytes: event.size_bytes
1031
1061
  });
1032
1062
  break;
1033
- case "timeline_entry":
1034
- this.emit({
1035
- type: "timeline_entry",
1036
- id: event.id,
1037
- status: event.status,
1038
- kind: event.kind,
1039
- agent_name: event.agent_name,
1040
- tool_name: event.tool_name,
1041
- display_name: event.display_name,
1042
- tool_category: event.tool_category,
1043
- viewer: event.viewer,
1044
- call_id: event.call_id,
1045
- detail: event.detail,
1046
- started_at: event.started_at,
1047
- duration_ms: event.duration_ms,
1048
- output_summary: event.output_summary,
1049
- sources: event.sources,
1050
- parent_id: event.parent_id,
1051
- structured_output: event.structured_output
1052
- });
1053
- break;
1054
1063
  case "editor_content_start":
1055
1064
  this.emit({
1056
1065
  type: "editor_content_start",
@@ -1172,19 +1181,26 @@ var ChatSession = class {
1172
1181
  this.abortController = null;
1173
1182
  }
1174
1183
  }
1175
- disconnect() {
1176
- if (this.currentJobId) {
1177
- this.client.cancelJob(this.currentJobId).catch(() => {
1178
- });
1179
- this.currentJobId = null;
1180
- }
1184
+ /** Detach from the SSE stream without cancelling the job.
1185
+ * The backend job keeps running — caller can reconnect later. */
1186
+ detach() {
1181
1187
  this.abortController?.abort();
1182
1188
  this.abortController = null;
1183
1189
  this.isStreaming = false;
1184
1190
  this.streamingContent = "";
1185
1191
  this.executingTool = null;
1192
+ this.blockBuilder.reset();
1186
1193
  this.emit({ type: "disconnected" });
1187
1194
  }
1195
+ /** Stop the job and disconnect (explicit user action). */
1196
+ disconnect() {
1197
+ if (this.currentJobId) {
1198
+ this.client.cancelJob(this.currentJobId).catch(() => {
1199
+ });
1200
+ }
1201
+ this.detach();
1202
+ this.currentJobId = null;
1203
+ }
1188
1204
  async createNewConversation() {
1189
1205
  const id = generateId();
1190
1206
  const conversation = await this.storage.createConversation(
@@ -1252,10 +1268,31 @@ function finalizeThinking(builder) {
1252
1268
  builder.thinkingStartMs = null;
1253
1269
  }
1254
1270
  }
1271
+ function finalizeEditor(builder) {
1272
+ if (builder.activeEditorId) {
1273
+ builder.patchBlock(builder.activeEditorId, {
1274
+ isStreaming: false
1275
+ });
1276
+ builder.activeEditorId = null;
1277
+ }
1278
+ }
1255
1279
  var handleUserMessage = (event, builder) => {
1256
- if (builder.findBlock((b) => b.type === "user")) return;
1257
1280
  const e = event;
1258
- builder.addBlock({ type: "user", id: builder.nextId(), content: e.content });
1281
+ const existing = builder.findBlock((b) => b.type === "user");
1282
+ if (existing) {
1283
+ if (e.createdAt) {
1284
+ builder.patchBlock(existing.id, {
1285
+ createdAt: e.createdAt
1286
+ });
1287
+ }
1288
+ return;
1289
+ }
1290
+ builder.addBlock({
1291
+ type: "user",
1292
+ id: builder.nextId(),
1293
+ content: e.content,
1294
+ createdAt: e.createdAt
1295
+ });
1259
1296
  };
1260
1297
  var handleChunk = (event, builder) => {
1261
1298
  const e = event;
@@ -1297,12 +1334,26 @@ var handleToolCall = (event, builder) => {
1297
1334
  var handleToolExecuting = (event, builder) => {
1298
1335
  const e = event;
1299
1336
  const block = builder.findBlock(
1300
- (b) => b.type === "tool" && b.toolName === e.name && b.status === "calling"
1337
+ (b) => b.type === "tool" && (e.call_id ? b.callId === e.call_id : b.toolName === e.name) && b.status === "calling"
1301
1338
  );
1302
1339
  if (block) {
1303
1340
  builder.patchBlock(block.id, { status: "executing" });
1304
1341
  }
1305
1342
  };
1343
+ var handleToolProgress = (event, builder) => {
1344
+ const e = event;
1345
+ const block = builder.findBlock(
1346
+ (b) => b.type === "tool" && b.callId === e.callId
1347
+ );
1348
+ if (block && block.type === "tool") {
1349
+ const sources = block.sources ? [...block.sources] : [];
1350
+ sources.push(e.item);
1351
+ builder.patchBlock(block.id, {
1352
+ sources,
1353
+ status: "executing"
1354
+ });
1355
+ }
1356
+ };
1306
1357
  var handleToolEnd = (event, builder) => {
1307
1358
  const e = event;
1308
1359
  const callId = e.type === "tool_end" ? e.callId : void 0;
@@ -1415,6 +1466,7 @@ var handleSubagentEnd = (event, builder) => {
1415
1466
  var handleComplete = (_event, builder) => {
1416
1467
  finalizeText(builder);
1417
1468
  finalizeThinking(builder);
1469
+ finalizeEditor(builder);
1418
1470
  for (const b of builder.getBlocks()) {
1419
1471
  if (b.type === "tool" && b.status !== "completed") {
1420
1472
  builder.patchBlock(b.id, { status: "completed" });
@@ -1434,30 +1486,421 @@ var handleError = (event, builder) => {
1434
1486
  var handleDisconnected = (_event, builder) => {
1435
1487
  finalizeText(builder);
1436
1488
  finalizeThinking(builder);
1489
+ finalizeEditor(builder);
1490
+ };
1491
+ var handleCapsuleOutputChunk = (event, builder) => {
1492
+ const e = event;
1493
+ const block = builder.findBlock(
1494
+ (b) => b.type === "capsule" && b.callId === e.callId
1495
+ );
1496
+ if (block && block.type === "capsule") {
1497
+ builder.patchBlock(block.id, {
1498
+ output: block.output + e.chunk
1499
+ });
1500
+ } else {
1501
+ builder.addBlock({
1502
+ type: "capsule",
1503
+ id: builder.nextId(),
1504
+ callId: e.callId,
1505
+ toolName: "",
1506
+ output: e.chunk,
1507
+ isActive: true
1508
+ });
1509
+ }
1510
+ };
1511
+ var handleCapsuleOutput = (event, builder) => {
1512
+ const e = event;
1513
+ const block = builder.findBlock(
1514
+ (b) => b.type === "capsule" && b.callId === (e.callId ?? "")
1515
+ );
1516
+ if (block) {
1517
+ builder.patchBlock(block.id, {
1518
+ output: e.output,
1519
+ command: e.command,
1520
+ toolName: e.toolName,
1521
+ durationMs: e.durationMs,
1522
+ isActive: false
1523
+ });
1524
+ } else {
1525
+ builder.addBlock({
1526
+ type: "capsule",
1527
+ id: builder.nextId(),
1528
+ callId: e.callId ?? "",
1529
+ toolName: e.toolName,
1530
+ command: e.command,
1531
+ output: e.output,
1532
+ durationMs: e.durationMs,
1533
+ isActive: false
1534
+ });
1535
+ }
1536
+ };
1537
+ var handleAssetCreated = (event, builder) => {
1538
+ const e = event;
1539
+ builder.addBlock({
1540
+ type: "asset",
1541
+ id: builder.nextId(),
1542
+ assetId: e.assetId,
1543
+ name: e.name,
1544
+ url: e.url,
1545
+ mediaType: e.mediaType,
1546
+ sizeBytes: e.sizeBytes
1547
+ });
1548
+ };
1549
+ var handleTodoUpdate = (event, builder) => {
1550
+ const e = event;
1551
+ if (builder.activeTodoId) {
1552
+ builder.patchBlock(builder.activeTodoId, {
1553
+ todos: e.todos
1554
+ });
1555
+ } else {
1556
+ const id = builder.nextId();
1557
+ builder.activeTodoId = id;
1558
+ builder.addBlock({
1559
+ type: "todo",
1560
+ id,
1561
+ todos: e.todos
1562
+ });
1563
+ }
1564
+ };
1565
+ var handleEditorContentStart = (event, builder) => {
1566
+ const e = event;
1567
+ const id = builder.nextId();
1568
+ builder.activeEditorId = id;
1569
+ builder.addBlock({
1570
+ type: "editor",
1571
+ id,
1572
+ callId: e.callId,
1573
+ path: e.path,
1574
+ language: e.language,
1575
+ content: "",
1576
+ isStreaming: true
1577
+ });
1578
+ };
1579
+ var handleEditorContentDelta = (event, builder) => {
1580
+ const e = event;
1581
+ const block = builder.findBlock(
1582
+ (b) => b.type === "editor" && b.callId === e.callId
1583
+ );
1584
+ if (block && block.type === "editor") {
1585
+ builder.patchBlock(block.id, {
1586
+ content: block.content + e.delta
1587
+ });
1588
+ }
1589
+ };
1590
+ var handleEditorContentEnd = (event, builder) => {
1591
+ const e = event;
1592
+ const block = builder.findBlock(
1593
+ (b) => b.type === "editor" && b.callId === e.callId
1594
+ );
1595
+ if (block) {
1596
+ builder.patchBlock(block.id, {
1597
+ isStreaming: false
1598
+ });
1599
+ }
1600
+ builder.activeEditorId = null;
1601
+ };
1602
+ var noop = () => {
1437
1603
  };
1438
1604
  var standardHandlers = {
1439
1605
  user_message: handleUserMessage,
1440
1606
  chunk: handleChunk,
1441
1607
  tool_call: handleToolCall,
1442
1608
  tool_executing: handleToolExecuting,
1609
+ tool_progress: handleToolProgress,
1443
1610
  tool_completed: handleToolEnd,
1444
1611
  tool_end: handleToolEnd,
1445
1612
  agent_start: handleAgentStart,
1613
+ agent_end: noop,
1446
1614
  thinking_delta: handleThinkingDelta,
1447
1615
  thinking_complete: handleThinkingComplete,
1448
1616
  subagent_start: handleSubagentStart,
1449
1617
  subagent_chunk: handleSubagentChunk,
1450
1618
  subagent_update: handleSubagentUpdate,
1451
1619
  subagent_end: handleSubagentEnd,
1620
+ subagent_tool_use: noop,
1621
+ capsule_output: handleCapsuleOutput,
1622
+ capsule_output_chunk: handleCapsuleOutputChunk,
1623
+ asset_created: handleAssetCreated,
1624
+ todo_update: handleTodoUpdate,
1625
+ editor_content_start: handleEditorContentStart,
1626
+ editor_content_delta: handleEditorContentDelta,
1627
+ editor_content_end: handleEditorContentEnd,
1628
+ retry: noop,
1452
1629
  complete: handleComplete,
1453
1630
  error: handleError,
1454
1631
  disconnected: handleDisconnected
1455
1632
  };
1633
+
1634
+ // src/types.ts
1635
+ var ChatEventType = {
1636
+ Connected: "connected",
1637
+ BlocksChanged: "blocks_changed",
1638
+ UserMessage: "user_message",
1639
+ TitleGenerated: "title_generated",
1640
+ ModelInfo: "model_info",
1641
+ Chunk: "chunk",
1642
+ ToolCall: "tool_call",
1643
+ ToolExecuting: "tool_executing",
1644
+ ToolProgress: "tool_progress",
1645
+ ToolCompleted: "tool_completed",
1646
+ ToolEnd: "tool_end",
1647
+ AgentStart: "agent_start",
1648
+ AgentEnd: "agent_end",
1649
+ ThinkingDelta: "thinking_delta",
1650
+ ThinkingComplete: "thinking_complete",
1651
+ SubagentStart: "subagent_start",
1652
+ SubagentChunk: "subagent_chunk",
1653
+ SubagentUpdate: "subagent_update",
1654
+ SubagentEnd: "subagent_end",
1655
+ SubagentToolUse: "subagent_tool_use",
1656
+ CapsuleOutput: "capsule_output",
1657
+ CapsuleOutputChunk: "capsule_output_chunk",
1658
+ AssetCreated: "asset_created",
1659
+ TodoUpdate: "todo_update",
1660
+ EditorContentStart: "editor_content_start",
1661
+ EditorContentDelta: "editor_content_delta",
1662
+ EditorContentEnd: "editor_content_end",
1663
+ Complete: "complete",
1664
+ Error: "error",
1665
+ Disconnected: "disconnected",
1666
+ Retry: "retry"
1667
+ };
1668
+
1669
+ // src/stream-manager.ts
1670
+ var StreamManager = class {
1671
+ constructor(session) {
1672
+ this._state = "idle";
1673
+ this._activeConversationId = null;
1674
+ this._backgroundJobs = /* @__PURE__ */ new Map();
1675
+ this.handlers = [];
1676
+ this.unsub = null;
1677
+ this.session = session;
1678
+ this.attach();
1679
+ }
1680
+ // ── Public state ──────────────────────────────────────────────
1681
+ get state() {
1682
+ return this._state;
1683
+ }
1684
+ get activeConversationId() {
1685
+ return this._activeConversationId;
1686
+ }
1687
+ get backgroundJobs() {
1688
+ return this._backgroundJobs;
1689
+ }
1690
+ // ── Event subscription ────────────────────────────────────────
1691
+ on(handler) {
1692
+ this.handlers.push(handler);
1693
+ return () => {
1694
+ this.handlers = this.handlers.filter((h) => h !== handler);
1695
+ };
1696
+ }
1697
+ emit(event) {
1698
+ for (const handler of this.handlers) {
1699
+ try {
1700
+ handler(event);
1701
+ } catch {
1702
+ }
1703
+ }
1704
+ }
1705
+ setState(state) {
1706
+ this._state = state;
1707
+ this.emit({
1708
+ type: "stateChange",
1709
+ state,
1710
+ conversationId: this._activeConversationId
1711
+ });
1712
+ }
1713
+ // ── Session event wiring ──────────────────────────────────────
1714
+ attach() {
1715
+ this.unsub = this.session.on((event) => {
1716
+ this.onSessionEvent(event);
1717
+ });
1718
+ }
1719
+ onSessionEvent(event) {
1720
+ const convId = this.session.conversationId;
1721
+ if (event.type === ChatEventType.BlocksChanged) {
1722
+ if (this._state === "streaming" && convId) {
1723
+ this.emit({
1724
+ type: "blocksChanged",
1725
+ conversationId: convId,
1726
+ blocks: event.blocks
1727
+ });
1728
+ }
1729
+ return;
1730
+ }
1731
+ this.emit({
1732
+ type: "event",
1733
+ conversationId: convId,
1734
+ event
1735
+ });
1736
+ if (event.type === ChatEventType.Complete) {
1737
+ if (this._state === "streaming") {
1738
+ this.setState("idle");
1739
+ }
1740
+ }
1741
+ }
1742
+ // ── Send ──────────────────────────────────────────────────────
1743
+ async send(content, options) {
1744
+ if (this._state === "streaming") return;
1745
+ if (!this._activeConversationId) {
1746
+ const id = await this.session.createNewConversation();
1747
+ this.setActiveConversation(id);
1748
+ }
1749
+ this.prepareUserBlock(content);
1750
+ this.setState("streaming");
1751
+ try {
1752
+ await this.session.send(content, {
1753
+ enableSearch: options?.enableSearch,
1754
+ agentName: options?.agentName,
1755
+ uploadIds: options?.uploadIds
1756
+ });
1757
+ } catch {
1758
+ }
1759
+ this.finalizeStream();
1760
+ }
1761
+ // ── Regenerate ────────────────────────────────────────────────
1762
+ async regenerate() {
1763
+ if (this._state === "streaming") return;
1764
+ const userMsgs = this.session.messages.filter(
1765
+ (m) => m.role === "user"
1766
+ );
1767
+ const lastUserMsg = userMsgs[userMsgs.length - 1];
1768
+ if (!lastUserMsg) return;
1769
+ this.prepareUserBlock(lastUserMsg.content);
1770
+ this.setState("streaming");
1771
+ try {
1772
+ await this.session.resendFromCheckpoint(
1773
+ lastUserMsg.id,
1774
+ lastUserMsg.content
1775
+ );
1776
+ } catch {
1777
+ }
1778
+ this.finalizeStream();
1779
+ }
1780
+ // ── Switch conversation ───────────────────────────────────────
1781
+ async switchTo(conversationId) {
1782
+ if (conversationId === this._activeConversationId) return;
1783
+ if (this._state === "streaming") {
1784
+ const oldConvId = this._activeConversationId;
1785
+ const jobId = this.session.currentJobId;
1786
+ if (oldConvId && jobId) {
1787
+ this._backgroundJobs.set(oldConvId, jobId);
1788
+ this.emit({
1789
+ type: "backgroundJobsChanged",
1790
+ jobs: this._backgroundJobs
1791
+ });
1792
+ }
1793
+ this.session.detach();
1794
+ }
1795
+ if (this._backgroundJobs.has(conversationId)) {
1796
+ this._backgroundJobs.delete(conversationId);
1797
+ this.emit({
1798
+ type: "backgroundJobsChanged",
1799
+ jobs: this._backgroundJobs
1800
+ });
1801
+ }
1802
+ this.setActiveConversation(conversationId);
1803
+ await this.restore(conversationId);
1804
+ }
1805
+ // ── Create / delete conversation ──────────────────────────────
1806
+ async createConversation() {
1807
+ const id = await this.session.createNewConversation();
1808
+ this.setActiveConversation(id);
1809
+ return id;
1810
+ }
1811
+ async deleteConversation(id) {
1812
+ await this.session.deleteConversation(id);
1813
+ this._backgroundJobs.delete(id);
1814
+ if (this._activeConversationId === id) {
1815
+ this._activeConversationId = null;
1816
+ this.emit({ type: "conversationChanged", conversationId: null });
1817
+ }
1818
+ }
1819
+ // ── Stop (explicit cancel) ────────────────────────────────────
1820
+ stop() {
1821
+ this.session.disconnect();
1822
+ this.setState("idle");
1823
+ }
1824
+ // ── Cleanup ───────────────────────────────────────────────────
1825
+ destroy() {
1826
+ if (this.unsub) {
1827
+ this.unsub();
1828
+ this.unsub = null;
1829
+ }
1830
+ this.handlers = [];
1831
+ }
1832
+ // ── Internal: helpers ──────────────────────────────────────────
1833
+ prepareUserBlock(content) {
1834
+ this.session.blockBuilder.reset();
1835
+ this.session.blockBuilder.addBlock({
1836
+ type: "user",
1837
+ id: this.session.blockBuilder.nextId(),
1838
+ content
1839
+ });
1840
+ }
1841
+ finalizeStream() {
1842
+ if (this._state === "streaming") {
1843
+ this.setState("idle");
1844
+ }
1845
+ }
1846
+ // ── Internal: restore ─────────────────────────────────────────
1847
+ async restore(conversationId) {
1848
+ this.setState("restoring");
1849
+ let activeJobId = null;
1850
+ try {
1851
+ const res = await this.session.client.get(`/v1/conversations/${encodeURIComponent(conversationId)}/active-job`);
1852
+ activeJobId = res.job_id ?? null;
1853
+ } catch {
1854
+ }
1855
+ if (activeJobId) {
1856
+ await this.session.loadConversation(conversationId);
1857
+ this.setState("streaming");
1858
+ try {
1859
+ await this.session.reconnectToJob(activeJobId);
1860
+ } catch {
1861
+ }
1862
+ if (this._state === "streaming") {
1863
+ this.setState("idle");
1864
+ }
1865
+ } else {
1866
+ await this.session.loadConversation(conversationId);
1867
+ try {
1868
+ const jobs = await this.session.client.get(`/v1/conversations/${encodeURIComponent(conversationId)}/jobs`);
1869
+ const completedJobs = jobs.filter(
1870
+ (j) => j.status === "completed"
1871
+ );
1872
+ for (const job of completedJobs) {
1873
+ await this.session.switchConversation(conversationId, job.job_id);
1874
+ }
1875
+ if (completedJobs.length > 0) {
1876
+ this.emit({
1877
+ type: "blocksChanged",
1878
+ conversationId,
1879
+ blocks: this.session.blockBuilder.getBlocks()
1880
+ });
1881
+ this.emit({
1882
+ type: "versionsReady",
1883
+ conversationId,
1884
+ count: completedJobs.length
1885
+ });
1886
+ }
1887
+ } catch {
1888
+ }
1889
+ this.setState("idle");
1890
+ }
1891
+ }
1892
+ // ── Internal: set active conversation ─────────────────────────
1893
+ setActiveConversation(id) {
1894
+ this._activeConversationId = id;
1895
+ this.emit({ type: "conversationChanged", conversationId: id });
1896
+ }
1897
+ };
1456
1898
  export {
1457
1899
  AstralformClient,
1458
1900
  AstralformError,
1459
1901
  AuthenticationError,
1460
1902
  BlockBuilder,
1903
+ ChatEventType,
1461
1904
  ChatSession,
1462
1905
  ConnectionError,
1463
1906
  InMemoryStorage,
@@ -1465,6 +1908,7 @@ export {
1465
1908
  RateLimitError,
1466
1909
  ServerError,
1467
1910
  StreamAbortedError,
1911
+ StreamManager,
1468
1912
  ToolRegistry,
1469
1913
  generateId,
1470
1914
  standardHandlers,