@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 +459 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +198 -26
- package/dist/index.d.ts +198 -26
- package/dist/index.js +457 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -247,10 +247,10 @@ var AstralformClient = class {
|
|
|
247
247
|
isEnabled: s.is_enabled
|
|
248
248
|
}));
|
|
249
249
|
}
|
|
250
|
-
async getConversationEvents(conversationId) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
);
|
|
250
|
+
async getConversationEvents(conversationId, jobId) {
|
|
251
|
+
let url = `/v1/conversations/${encodeURIComponent(conversationId)}/events`;
|
|
252
|
+
if (jobId) url += `?job_id=${encodeURIComponent(jobId)}`;
|
|
253
|
+
return this.get(url);
|
|
254
254
|
}
|
|
255
255
|
async submitToolResult(request) {
|
|
256
256
|
await this.post("/v1/tool-result", request);
|
|
@@ -321,6 +321,87 @@ var AstralformClient = class {
|
|
|
321
321
|
}
|
|
322
322
|
};
|
|
323
323
|
|
|
324
|
+
// src/block-builder.ts
|
|
325
|
+
var _idCounter = 0;
|
|
326
|
+
var BlockBuilder = class {
|
|
327
|
+
constructor() {
|
|
328
|
+
this._blocks = [];
|
|
329
|
+
this._handlers = /* @__PURE__ */ new Map();
|
|
330
|
+
this._onChange = null;
|
|
331
|
+
// Active block refs — public so handlers can read/write them
|
|
332
|
+
this.activeTextId = null;
|
|
333
|
+
this.activeThinkingId = null;
|
|
334
|
+
this.thinkingStartMs = null;
|
|
335
|
+
}
|
|
336
|
+
// ── Registration ──────────────────────────────────────────────
|
|
337
|
+
on(eventType, handler) {
|
|
338
|
+
this._handlers.set(eventType, handler);
|
|
339
|
+
}
|
|
340
|
+
registerHandlers(handlers) {
|
|
341
|
+
for (const [type, handler] of Object.entries(handlers)) {
|
|
342
|
+
this._handlers.set(type, handler);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// ── Event processing ──────────────────────────────────────────
|
|
346
|
+
processEvent(event) {
|
|
347
|
+
const handler = this._handlers.get(event.type);
|
|
348
|
+
if (handler === null) return;
|
|
349
|
+
if (!handler) return;
|
|
350
|
+
handler(event, this);
|
|
351
|
+
}
|
|
352
|
+
// ── State ─────────────────────────────────────────────────────
|
|
353
|
+
getBlocks() {
|
|
354
|
+
return [...this._blocks];
|
|
355
|
+
}
|
|
356
|
+
reset() {
|
|
357
|
+
this._blocks = [];
|
|
358
|
+
this.activeTextId = null;
|
|
359
|
+
this.activeThinkingId = null;
|
|
360
|
+
this.thinkingStartMs = null;
|
|
361
|
+
}
|
|
362
|
+
setOnChange(fn) {
|
|
363
|
+
this._onChange = fn;
|
|
364
|
+
}
|
|
365
|
+
// ── Block manipulation (used by handlers) ─────────────────────
|
|
366
|
+
addBlock(block) {
|
|
367
|
+
this._blocks = [...this._blocks, block];
|
|
368
|
+
this._notify();
|
|
369
|
+
}
|
|
370
|
+
updateBlock(id, updater) {
|
|
371
|
+
let changed = false;
|
|
372
|
+
this._blocks = this._blocks.map((b) => {
|
|
373
|
+
if (b.id !== id) return b;
|
|
374
|
+
changed = true;
|
|
375
|
+
return updater(b);
|
|
376
|
+
});
|
|
377
|
+
if (changed) this._notify();
|
|
378
|
+
}
|
|
379
|
+
/** Update any block by id with a partial update (type-loose for handlers). */
|
|
380
|
+
patchBlock(id, patch) {
|
|
381
|
+
let changed = false;
|
|
382
|
+
this._blocks = this._blocks.map((b) => {
|
|
383
|
+
if (b.id !== id) return b;
|
|
384
|
+
changed = true;
|
|
385
|
+
return { ...b, ...patch };
|
|
386
|
+
});
|
|
387
|
+
if (changed) this._notify();
|
|
388
|
+
}
|
|
389
|
+
findBlock(predicate) {
|
|
390
|
+
for (let i = this._blocks.length - 1; i >= 0; i--) {
|
|
391
|
+
const block = this._blocks[i];
|
|
392
|
+
if (block && predicate(block)) return block;
|
|
393
|
+
}
|
|
394
|
+
return void 0;
|
|
395
|
+
}
|
|
396
|
+
nextId() {
|
|
397
|
+
return `blk_${++_idCounter}`;
|
|
398
|
+
}
|
|
399
|
+
// ── Internal ──────────────────────────────────────────────────
|
|
400
|
+
_notify() {
|
|
401
|
+
this._onChange?.();
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
|
|
324
405
|
// src/storage.ts
|
|
325
406
|
var InMemoryStorage = class {
|
|
326
407
|
constructor() {
|
|
@@ -485,7 +566,7 @@ function generateId() {
|
|
|
485
566
|
|
|
486
567
|
// src/session.ts
|
|
487
568
|
var ChatSession = class {
|
|
488
|
-
constructor(config, storage) {
|
|
569
|
+
constructor(config, storage, blockBuilder) {
|
|
489
570
|
// State
|
|
490
571
|
this.conversationId = null;
|
|
491
572
|
this.conversations = [];
|
|
@@ -515,6 +596,13 @@ var ChatSession = class {
|
|
|
515
596
|
this.client = new AstralformClient(config);
|
|
516
597
|
this.toolRegistry = new ToolRegistry();
|
|
517
598
|
this.storage = storage ?? new InMemoryStorage();
|
|
599
|
+
this.blockBuilder = blockBuilder ?? new BlockBuilder();
|
|
600
|
+
this.blockBuilder.setOnChange(() => {
|
|
601
|
+
this.emit({
|
|
602
|
+
type: "blocks_changed",
|
|
603
|
+
blocks: this.blockBuilder.getBlocks()
|
|
604
|
+
});
|
|
605
|
+
});
|
|
518
606
|
}
|
|
519
607
|
on(handler) {
|
|
520
608
|
this.handlers.add(handler);
|
|
@@ -523,6 +611,9 @@ var ChatSession = class {
|
|
|
523
611
|
};
|
|
524
612
|
}
|
|
525
613
|
emit(event) {
|
|
614
|
+
if (event.type !== "blocks_changed" && event.type !== "connected") {
|
|
615
|
+
this.blockBuilder.processEvent(event);
|
|
616
|
+
}
|
|
526
617
|
for (const handler of this.handlers) {
|
|
527
618
|
try {
|
|
528
619
|
handler(event);
|
|
@@ -579,14 +670,15 @@ var ChatSession = class {
|
|
|
579
670
|
};
|
|
580
671
|
await this.processStream(request);
|
|
581
672
|
}
|
|
582
|
-
async resendFromCheckpoint(messageId, newContent) {
|
|
673
|
+
async resendFromCheckpoint(messageId, newContent, options) {
|
|
583
674
|
if (this.isStreaming) return;
|
|
584
675
|
const request = {
|
|
585
676
|
message: newContent,
|
|
586
677
|
conversation_id: this.conversationId ?? void 0,
|
|
587
678
|
resend_from: messageId,
|
|
588
679
|
mcp_manifest: this.toolRegistry.getManifest(),
|
|
589
|
-
enabled_mcp: Array.from(this.enabledClientTools)
|
|
680
|
+
enabled_mcp: Array.from(this.enabledClientTools),
|
|
681
|
+
enable_search: options?.enableSearch
|
|
590
682
|
};
|
|
591
683
|
await this.processStream(request);
|
|
592
684
|
}
|
|
@@ -626,12 +718,23 @@ var ChatSession = class {
|
|
|
626
718
|
}
|
|
627
719
|
const messageId = job.message_id;
|
|
628
720
|
this.lastSeq = -1;
|
|
629
|
-
let stopTitle;
|
|
630
721
|
const stream = this.client.streamJobEvents(
|
|
631
722
|
job.job_id,
|
|
632
723
|
this.lastSeq,
|
|
633
724
|
this.abortController?.signal
|
|
634
725
|
);
|
|
726
|
+
await this.consumeEventStream(
|
|
727
|
+
stream,
|
|
728
|
+
conversationId,
|
|
729
|
+
messageId,
|
|
730
|
+
true
|
|
731
|
+
// executeClientTools
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Shared event consumption loop used by both consumeJobStream and reconnectToJob.
|
|
736
|
+
*/
|
|
737
|
+
async consumeEventStream(stream, conversationId, messageId, executeClientTools) {
|
|
635
738
|
for await (const raw of stream) {
|
|
636
739
|
let parsed;
|
|
637
740
|
try {
|
|
@@ -655,6 +758,9 @@ var ChatSession = class {
|
|
|
655
758
|
if (!this.conversationId) {
|
|
656
759
|
this.conversationId = conversationId;
|
|
657
760
|
}
|
|
761
|
+
if (parsed.message_id) {
|
|
762
|
+
messageId = parsed.message_id;
|
|
763
|
+
}
|
|
658
764
|
if (parsed.model_display_name) {
|
|
659
765
|
this.modelDisplayName = parsed.model_display_name;
|
|
660
766
|
this.emit({
|
|
@@ -669,7 +775,7 @@ var ChatSession = class {
|
|
|
669
775
|
break;
|
|
670
776
|
case "tool_use_start": {
|
|
671
777
|
this.applyEvent(parsed);
|
|
672
|
-
if (parsed.is_client_tool) {
|
|
778
|
+
if (executeClientTools && parsed.is_client_tool) {
|
|
673
779
|
const results = await this.executeClientTools([
|
|
674
780
|
{
|
|
675
781
|
callId: parsed.call_id,
|
|
@@ -721,7 +827,15 @@ var ChatSession = class {
|
|
|
721
827
|
});
|
|
722
828
|
break;
|
|
723
829
|
case "message_stop":
|
|
724
|
-
|
|
830
|
+
await this.completeStream(
|
|
831
|
+
conversationId,
|
|
832
|
+
messageId,
|
|
833
|
+
parsed.title,
|
|
834
|
+
parsed.metrics,
|
|
835
|
+
parsed.job_id
|
|
836
|
+
);
|
|
837
|
+
this.isStreaming = false;
|
|
838
|
+
this.currentJobId = null;
|
|
725
839
|
break;
|
|
726
840
|
case "error":
|
|
727
841
|
this.emit({
|
|
@@ -733,8 +847,6 @@ var ChatSession = class {
|
|
|
733
847
|
this.applyEvent(parsed);
|
|
734
848
|
}
|
|
735
849
|
}
|
|
736
|
-
this.currentJobId = null;
|
|
737
|
-
await this.completeStream(conversationId, messageId, stopTitle);
|
|
738
850
|
}
|
|
739
851
|
/**
|
|
740
852
|
* Apply a single SSE event to session state and notify consumers.
|
|
@@ -742,6 +854,45 @@ var ChatSession = class {
|
|
|
742
854
|
*/
|
|
743
855
|
applyEvent(event) {
|
|
744
856
|
switch (event.type) {
|
|
857
|
+
case "user_message":
|
|
858
|
+
this.emit({ type: "user_message", content: event.content });
|
|
859
|
+
break;
|
|
860
|
+
case "title_generated":
|
|
861
|
+
this.emit({ type: "title_generated", title: event.title });
|
|
862
|
+
break;
|
|
863
|
+
case "message_start":
|
|
864
|
+
if (event.conversation_id && !this.conversationId) {
|
|
865
|
+
this.conversationId = event.conversation_id;
|
|
866
|
+
}
|
|
867
|
+
if (event.model_display_name) {
|
|
868
|
+
this.modelDisplayName = event.model_display_name;
|
|
869
|
+
this.emit({ type: "model_info", name: event.model_display_name });
|
|
870
|
+
}
|
|
871
|
+
break;
|
|
872
|
+
case "content_block_delta":
|
|
873
|
+
this.streamingContent += event.delta.text;
|
|
874
|
+
this.emit({ type: "chunk", text: event.delta.text });
|
|
875
|
+
break;
|
|
876
|
+
case "thinking_delta":
|
|
877
|
+
this.thinkingContent += event.delta.text;
|
|
878
|
+
this.isThinking = true;
|
|
879
|
+
this.emit({ type: "thinking_delta", text: event.delta.text });
|
|
880
|
+
break;
|
|
881
|
+
case "thinking_complete":
|
|
882
|
+
this.isThinking = false;
|
|
883
|
+
this.emit({ type: "thinking_complete" });
|
|
884
|
+
break;
|
|
885
|
+
case "message_stop":
|
|
886
|
+
this.emit({
|
|
887
|
+
type: "complete",
|
|
888
|
+
content: this.streamingContent,
|
|
889
|
+
conversationId: this.conversationId ?? "",
|
|
890
|
+
messageId: event.job_id ?? "",
|
|
891
|
+
title: event.title,
|
|
892
|
+
metrics: event.metrics,
|
|
893
|
+
job_id: event.job_id
|
|
894
|
+
});
|
|
895
|
+
break;
|
|
745
896
|
case "tool_use_start": {
|
|
746
897
|
const request = {
|
|
747
898
|
callId: event.call_id,
|
|
@@ -769,7 +920,9 @@ var ChatSession = class {
|
|
|
769
920
|
type: "tool_end",
|
|
770
921
|
callId: event.call_id,
|
|
771
922
|
toolName: event.tool,
|
|
772
|
-
result: event.result
|
|
923
|
+
result: event.result,
|
|
924
|
+
sources: event.sources,
|
|
925
|
+
durationMs: event.duration_ms
|
|
773
926
|
});
|
|
774
927
|
break;
|
|
775
928
|
}
|
|
@@ -877,18 +1030,25 @@ var ChatSession = class {
|
|
|
877
1030
|
sizeBytes: event.size_bytes
|
|
878
1031
|
});
|
|
879
1032
|
break;
|
|
880
|
-
case "
|
|
1033
|
+
case "timeline_entry":
|
|
881
1034
|
this.emit({
|
|
882
|
-
type: "
|
|
883
|
-
|
|
1035
|
+
type: "timeline_entry",
|
|
1036
|
+
id: event.id,
|
|
884
1037
|
status: event.status,
|
|
885
|
-
|
|
886
|
-
|
|
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,
|
|
887
1045
|
detail: event.detail,
|
|
1046
|
+
started_at: event.started_at,
|
|
1047
|
+
duration_ms: event.duration_ms,
|
|
1048
|
+
output_summary: event.output_summary,
|
|
888
1049
|
sources: event.sources,
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
durationMs: event.duration_ms
|
|
1050
|
+
parent_id: event.parent_id,
|
|
1051
|
+
structured_output: event.structured_output
|
|
892
1052
|
});
|
|
893
1053
|
break;
|
|
894
1054
|
case "editor_content_start":
|
|
@@ -938,7 +1098,7 @@ var ChatSession = class {
|
|
|
938
1098
|
this.executingTool = null;
|
|
939
1099
|
return results;
|
|
940
1100
|
}
|
|
941
|
-
async completeStream(conversationId, messageId, title) {
|
|
1101
|
+
async completeStream(conversationId, messageId, title, metrics, jobId) {
|
|
942
1102
|
const assistantMessage = {
|
|
943
1103
|
id: messageId || generateId(),
|
|
944
1104
|
conversationId,
|
|
@@ -961,9 +1121,57 @@ var ChatSession = class {
|
|
|
961
1121
|
content: this.streamingContent,
|
|
962
1122
|
conversationId,
|
|
963
1123
|
messageId: assistantMessage.id,
|
|
964
|
-
title
|
|
1124
|
+
title,
|
|
1125
|
+
metrics,
|
|
1126
|
+
job_id: jobId
|
|
965
1127
|
});
|
|
966
1128
|
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Load conversation context (messages) without replaying events.
|
|
1131
|
+
* Used before reconnectToJob — SSE replay handles event replay.
|
|
1132
|
+
*/
|
|
1133
|
+
async loadConversation(id) {
|
|
1134
|
+
this.conversationId = id;
|
|
1135
|
+
this.resetStreamingState();
|
|
1136
|
+
this.blockBuilder.reset();
|
|
1137
|
+
this.messages = await this.client.getMessages(id).catch(() => this.storage.fetchMessages(id));
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Reconnect to a running job's SSE stream (e.g. after page reload).
|
|
1141
|
+
* Replays all events from the beginning and continues live.
|
|
1142
|
+
* Does NOT reset BlockBuilder — caller controls reset.
|
|
1143
|
+
*/
|
|
1144
|
+
async reconnectToJob(jobId) {
|
|
1145
|
+
if (this.isStreaming) return;
|
|
1146
|
+
this.isStreaming = true;
|
|
1147
|
+
this.currentJobId = jobId;
|
|
1148
|
+
this.lastSeq = -1;
|
|
1149
|
+
this.resetStreamingState();
|
|
1150
|
+
this.abortController = new AbortController();
|
|
1151
|
+
try {
|
|
1152
|
+
const stream = this.client.streamJobEvents(
|
|
1153
|
+
jobId,
|
|
1154
|
+
this.lastSeq,
|
|
1155
|
+
this.abortController?.signal
|
|
1156
|
+
);
|
|
1157
|
+
await this.consumeEventStream(
|
|
1158
|
+
stream,
|
|
1159
|
+
this.conversationId ?? "",
|
|
1160
|
+
"",
|
|
1161
|
+
false
|
|
1162
|
+
// don't execute client tools on reconnect
|
|
1163
|
+
);
|
|
1164
|
+
} catch (err) {
|
|
1165
|
+
this.emit({
|
|
1166
|
+
type: "error",
|
|
1167
|
+
error: err instanceof Error ? err : new ConnectionError(String(err))
|
|
1168
|
+
});
|
|
1169
|
+
} finally {
|
|
1170
|
+
this.isStreaming = false;
|
|
1171
|
+
this.executingTool = null;
|
|
1172
|
+
this.abortController = null;
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
967
1175
|
disconnect() {
|
|
968
1176
|
if (this.currentJobId) {
|
|
969
1177
|
this.client.cancelJob(this.currentJobId).catch(() => {
|
|
@@ -989,30 +1197,21 @@ var ChatSession = class {
|
|
|
989
1197
|
this.streamingContent = "";
|
|
990
1198
|
return id;
|
|
991
1199
|
}
|
|
992
|
-
async switchConversation(id) {
|
|
1200
|
+
async switchConversation(id, jobId) {
|
|
993
1201
|
this.conversationId = id;
|
|
994
1202
|
this.resetStreamingState();
|
|
1203
|
+
this.blockBuilder.reset();
|
|
995
1204
|
const [messagesResult, eventsResult] = await Promise.allSettled([
|
|
996
1205
|
this.client.getMessages(id).catch(() => this.storage.fetchMessages(id)),
|
|
997
|
-
this.client.getConversationEvents(id)
|
|
1206
|
+
this.client.getConversationEvents(id, jobId)
|
|
998
1207
|
]);
|
|
999
1208
|
this.messages = messagesResult.status === "fulfilled" ? messagesResult.value : [];
|
|
1000
1209
|
if (eventsResult.status === "fulfilled") {
|
|
1001
1210
|
for (const ev of eventsResult.value) {
|
|
1002
|
-
this.
|
|
1211
|
+
this.applyEvent({ type: ev.event, ...ev.data });
|
|
1003
1212
|
}
|
|
1004
1213
|
}
|
|
1005
1214
|
}
|
|
1006
|
-
/**
|
|
1007
|
-
* Replay a single persisted event to reconstruct session state.
|
|
1008
|
-
* Skips text deltas (final content is already in messages[]).
|
|
1009
|
-
*/
|
|
1010
|
-
replayEvent(eventType, data) {
|
|
1011
|
-
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") {
|
|
1012
|
-
return;
|
|
1013
|
-
}
|
|
1014
|
-
this.applyEvent({ type: eventType, ...data });
|
|
1015
|
-
}
|
|
1016
1215
|
async deleteConversation(id) {
|
|
1017
1216
|
try {
|
|
1018
1217
|
await this.client.deleteConversation(id);
|
|
@@ -1034,10 +1233,231 @@ var ChatSession = class {
|
|
|
1034
1233
|
return true;
|
|
1035
1234
|
}
|
|
1036
1235
|
};
|
|
1236
|
+
|
|
1237
|
+
// src/standard-handlers.ts
|
|
1238
|
+
function finalizeText(builder) {
|
|
1239
|
+
if (builder.activeTextId) {
|
|
1240
|
+
builder.patchBlock(builder.activeTextId, {
|
|
1241
|
+
isStreaming: false
|
|
1242
|
+
});
|
|
1243
|
+
builder.activeTextId = null;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
function finalizeThinking(builder) {
|
|
1247
|
+
if (builder.activeThinkingId) {
|
|
1248
|
+
builder.patchBlock(builder.activeThinkingId, {
|
|
1249
|
+
isActive: false
|
|
1250
|
+
});
|
|
1251
|
+
builder.activeThinkingId = null;
|
|
1252
|
+
builder.thinkingStartMs = null;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
var handleUserMessage = (event, builder) => {
|
|
1256
|
+
if (builder.findBlock((b) => b.type === "user")) return;
|
|
1257
|
+
const e = event;
|
|
1258
|
+
builder.addBlock({ type: "user", id: builder.nextId(), content: e.content });
|
|
1259
|
+
};
|
|
1260
|
+
var handleChunk = (event, builder) => {
|
|
1261
|
+
const e = event;
|
|
1262
|
+
if (!builder.activeTextId) {
|
|
1263
|
+
const id = builder.nextId();
|
|
1264
|
+
builder.activeTextId = id;
|
|
1265
|
+
builder.addBlock({
|
|
1266
|
+
type: "text",
|
|
1267
|
+
id,
|
|
1268
|
+
content: e.text,
|
|
1269
|
+
isStreaming: true
|
|
1270
|
+
});
|
|
1271
|
+
} else {
|
|
1272
|
+
const id = builder.activeTextId;
|
|
1273
|
+
const existing = builder.findBlock((b) => b.id === id);
|
|
1274
|
+
if (existing && existing.type === "text") {
|
|
1275
|
+
builder.patchBlock(id, {
|
|
1276
|
+
content: existing.content + e.text
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1281
|
+
var handleToolCall = (event, builder) => {
|
|
1282
|
+
const e = event;
|
|
1283
|
+
finalizeText(builder);
|
|
1284
|
+
builder.addBlock({
|
|
1285
|
+
type: "tool",
|
|
1286
|
+
id: builder.nextId(),
|
|
1287
|
+
callId: e.request.callId,
|
|
1288
|
+
toolName: e.request.toolName,
|
|
1289
|
+
displayName: e.request.displayName,
|
|
1290
|
+
description: e.request.description,
|
|
1291
|
+
arguments: e.request.arguments,
|
|
1292
|
+
toolCategory: e.request.toolCategory,
|
|
1293
|
+
iconUrl: e.request.iconUrl,
|
|
1294
|
+
status: "calling"
|
|
1295
|
+
});
|
|
1296
|
+
};
|
|
1297
|
+
var handleToolExecuting = (event, builder) => {
|
|
1298
|
+
const e = event;
|
|
1299
|
+
const block = builder.findBlock(
|
|
1300
|
+
(b) => b.type === "tool" && b.toolName === e.name && b.status === "calling"
|
|
1301
|
+
);
|
|
1302
|
+
if (block) {
|
|
1303
|
+
builder.patchBlock(block.id, { status: "executing" });
|
|
1304
|
+
}
|
|
1305
|
+
};
|
|
1306
|
+
var handleToolEnd = (event, builder) => {
|
|
1307
|
+
const e = event;
|
|
1308
|
+
const callId = e.type === "tool_end" ? e.callId : void 0;
|
|
1309
|
+
const name = e.type === "tool_end" ? e.toolName : e.name;
|
|
1310
|
+
const block = builder.findBlock(
|
|
1311
|
+
(b) => b.type === "tool" && (callId ? b.callId === callId : b.toolName === name) && b.status !== "completed"
|
|
1312
|
+
);
|
|
1313
|
+
if (block) {
|
|
1314
|
+
const toolEnd = e.type === "tool_end" ? e : null;
|
|
1315
|
+
builder.patchBlock(block.id, {
|
|
1316
|
+
status: "completed",
|
|
1317
|
+
...toolEnd?.sources ? { sources: toolEnd.sources } : {},
|
|
1318
|
+
...toolEnd?.durationMs != null ? { durationMs: toolEnd.durationMs } : {},
|
|
1319
|
+
...toolEnd?.result ? { result: toolEnd.result } : {}
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
};
|
|
1323
|
+
var handleAgentStart = (event, builder) => {
|
|
1324
|
+
const e = event;
|
|
1325
|
+
finalizeText(builder);
|
|
1326
|
+
builder.addBlock({
|
|
1327
|
+
type: "agent",
|
|
1328
|
+
id: builder.nextId(),
|
|
1329
|
+
agentName: e.agentName,
|
|
1330
|
+
displayName: e.agentDisplayName,
|
|
1331
|
+
avatarUrl: e.avatarUrl
|
|
1332
|
+
});
|
|
1333
|
+
};
|
|
1334
|
+
var handleThinkingDelta = (event, builder) => {
|
|
1335
|
+
const e = event;
|
|
1336
|
+
if (!builder.activeThinkingId) {
|
|
1337
|
+
const id = builder.nextId();
|
|
1338
|
+
builder.activeThinkingId = id;
|
|
1339
|
+
builder.thinkingStartMs = Date.now();
|
|
1340
|
+
builder.addBlock({
|
|
1341
|
+
type: "thinking",
|
|
1342
|
+
id,
|
|
1343
|
+
content: e.text,
|
|
1344
|
+
isActive: true
|
|
1345
|
+
});
|
|
1346
|
+
} else {
|
|
1347
|
+
const id = builder.activeThinkingId;
|
|
1348
|
+
const existing = builder.findBlock((b) => b.id === id);
|
|
1349
|
+
if (existing && existing.type === "thinking") {
|
|
1350
|
+
builder.patchBlock(id, {
|
|
1351
|
+
content: existing.content + e.text
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
var handleThinkingComplete = (_event, builder) => {
|
|
1357
|
+
if (builder.activeThinkingId) {
|
|
1358
|
+
const durationMs = builder.thinkingStartMs ? Math.max(0, Date.now() - builder.thinkingStartMs) : void 0;
|
|
1359
|
+
builder.patchBlock(builder.activeThinkingId, {
|
|
1360
|
+
isActive: false,
|
|
1361
|
+
durationMs
|
|
1362
|
+
});
|
|
1363
|
+
builder.activeThinkingId = null;
|
|
1364
|
+
builder.thinkingStartMs = null;
|
|
1365
|
+
}
|
|
1366
|
+
};
|
|
1367
|
+
var handleSubagentStart = (event, builder) => {
|
|
1368
|
+
const e = event;
|
|
1369
|
+
finalizeText(builder);
|
|
1370
|
+
builder.addBlock({
|
|
1371
|
+
type: "subagent",
|
|
1372
|
+
id: builder.nextId(),
|
|
1373
|
+
agentName: e.agentName,
|
|
1374
|
+
displayName: e.displayName,
|
|
1375
|
+
toolCallId: e.toolCallId,
|
|
1376
|
+
avatarUrl: e.avatarUrl,
|
|
1377
|
+
description: e.description,
|
|
1378
|
+
content: "",
|
|
1379
|
+
isActive: true
|
|
1380
|
+
});
|
|
1381
|
+
};
|
|
1382
|
+
var handleSubagentChunk = (event, builder) => {
|
|
1383
|
+
const e = event;
|
|
1384
|
+
const block = builder.findBlock(
|
|
1385
|
+
(b) => b.type === "subagent" && b.toolCallId === e.toolCallId
|
|
1386
|
+
);
|
|
1387
|
+
if (block && block.type === "subagent") {
|
|
1388
|
+
builder.patchBlock(block.id, {
|
|
1389
|
+
content: block.content + e.text
|
|
1390
|
+
});
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1393
|
+
var handleSubagentUpdate = (event, builder) => {
|
|
1394
|
+
const e = event;
|
|
1395
|
+
const block = builder.findBlock(
|
|
1396
|
+
(b) => b.type === "subagent" && b.toolCallId === e.toolCallId
|
|
1397
|
+
);
|
|
1398
|
+
if (block) {
|
|
1399
|
+
builder.patchBlock(block.id, {
|
|
1400
|
+
displayName: e.displayName
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
var handleSubagentEnd = (event, builder) => {
|
|
1405
|
+
const e = event;
|
|
1406
|
+
const block = builder.findBlock(
|
|
1407
|
+
(b) => b.type === "subagent" && b.toolCallId === e.toolCallId
|
|
1408
|
+
);
|
|
1409
|
+
if (block) {
|
|
1410
|
+
builder.patchBlock(block.id, {
|
|
1411
|
+
isActive: false
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1414
|
+
};
|
|
1415
|
+
var handleComplete = (_event, builder) => {
|
|
1416
|
+
finalizeText(builder);
|
|
1417
|
+
finalizeThinking(builder);
|
|
1418
|
+
for (const b of builder.getBlocks()) {
|
|
1419
|
+
if (b.type === "tool" && b.status !== "completed") {
|
|
1420
|
+
builder.patchBlock(b.id, { status: "completed" });
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
};
|
|
1424
|
+
var handleError = (event, builder) => {
|
|
1425
|
+
const e = event;
|
|
1426
|
+
finalizeText(builder);
|
|
1427
|
+
finalizeThinking(builder);
|
|
1428
|
+
builder.addBlock({
|
|
1429
|
+
type: "error",
|
|
1430
|
+
id: builder.nextId(),
|
|
1431
|
+
message: e.error.message
|
|
1432
|
+
});
|
|
1433
|
+
};
|
|
1434
|
+
var handleDisconnected = (_event, builder) => {
|
|
1435
|
+
finalizeText(builder);
|
|
1436
|
+
finalizeThinking(builder);
|
|
1437
|
+
};
|
|
1438
|
+
var standardHandlers = {
|
|
1439
|
+
user_message: handleUserMessage,
|
|
1440
|
+
chunk: handleChunk,
|
|
1441
|
+
tool_call: handleToolCall,
|
|
1442
|
+
tool_executing: handleToolExecuting,
|
|
1443
|
+
tool_completed: handleToolEnd,
|
|
1444
|
+
tool_end: handleToolEnd,
|
|
1445
|
+
agent_start: handleAgentStart,
|
|
1446
|
+
thinking_delta: handleThinkingDelta,
|
|
1447
|
+
thinking_complete: handleThinkingComplete,
|
|
1448
|
+
subagent_start: handleSubagentStart,
|
|
1449
|
+
subagent_chunk: handleSubagentChunk,
|
|
1450
|
+
subagent_update: handleSubagentUpdate,
|
|
1451
|
+
subagent_end: handleSubagentEnd,
|
|
1452
|
+
complete: handleComplete,
|
|
1453
|
+
error: handleError,
|
|
1454
|
+
disconnected: handleDisconnected
|
|
1455
|
+
};
|
|
1037
1456
|
export {
|
|
1038
1457
|
AstralformClient,
|
|
1039
1458
|
AstralformError,
|
|
1040
1459
|
AuthenticationError,
|
|
1460
|
+
BlockBuilder,
|
|
1041
1461
|
ChatSession,
|
|
1042
1462
|
ConnectionError,
|
|
1043
1463
|
InMemoryStorage,
|
|
@@ -1047,6 +1467,7 @@ export {
|
|
|
1047
1467
|
StreamAbortedError,
|
|
1048
1468
|
ToolRegistry,
|
|
1049
1469
|
generateId,
|
|
1470
|
+
standardHandlers,
|
|
1050
1471
|
streamJobSSE
|
|
1051
1472
|
};
|
|
1052
1473
|
//# sourceMappingURL=index.js.map
|