@astralform/js 0.1.0 → 0.1.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 +184 -140
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -2
- package/dist/index.d.ts +35 -2
- package/dist/index.js +184 -140
- package/dist/index.js.map +1 -1
- package/package.json +11 -12
package/dist/index.cjs
CHANGED
|
@@ -285,6 +285,11 @@ var AstralformClient = class {
|
|
|
285
285
|
isEnabled: s.is_enabled
|
|
286
286
|
}));
|
|
287
287
|
}
|
|
288
|
+
async getConversationEvents(conversationId) {
|
|
289
|
+
return this.get(
|
|
290
|
+
`/v1/conversations/${encodeURIComponent(conversationId)}/events`
|
|
291
|
+
);
|
|
292
|
+
}
|
|
288
293
|
async submitToolResult(request) {
|
|
289
294
|
await this.post("/v1/tool-result", request);
|
|
290
295
|
}
|
|
@@ -622,8 +627,7 @@ var ChatSession = class {
|
|
|
622
627
|
};
|
|
623
628
|
await this.processStream(request);
|
|
624
629
|
}
|
|
625
|
-
|
|
626
|
-
this.isStreaming = true;
|
|
630
|
+
resetStreamingState() {
|
|
627
631
|
this.streamingContent = "";
|
|
628
632
|
this.thinkingContent = "";
|
|
629
633
|
this.isThinking = false;
|
|
@@ -632,6 +636,10 @@ var ChatSession = class {
|
|
|
632
636
|
this.capsuleOutputs = [];
|
|
633
637
|
this.todos = [];
|
|
634
638
|
this.activeTools.clear();
|
|
639
|
+
}
|
|
640
|
+
async processStream(request) {
|
|
641
|
+
this.isStreaming = true;
|
|
642
|
+
this.resetStreamingState();
|
|
635
643
|
this.abortController = new AbortController();
|
|
636
644
|
try {
|
|
637
645
|
await this.consumeJobStream(request);
|
|
@@ -691,39 +699,24 @@ var ChatSession = class {
|
|
|
691
699
|
name: parsed.model_display_name
|
|
692
700
|
});
|
|
693
701
|
}
|
|
694
|
-
if (parsed.agent_name) {
|
|
695
|
-
this.emit({
|
|
696
|
-
type: "agent_start",
|
|
697
|
-
agentName: parsed.agent_name,
|
|
698
|
-
agentDisplayName: parsed.agent_display_name
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
702
|
break;
|
|
702
703
|
case "content_block_delta":
|
|
703
704
|
this.streamingContent += parsed.delta.text;
|
|
704
705
|
this.emit({ type: "chunk", text: parsed.delta.text });
|
|
705
706
|
break;
|
|
706
707
|
case "tool_use_start": {
|
|
707
|
-
|
|
708
|
-
callId: parsed.call_id,
|
|
709
|
-
toolName: parsed.tool,
|
|
710
|
-
displayName: parsed.display_name,
|
|
711
|
-
description: parsed.description,
|
|
712
|
-
arguments: parsed.arguments,
|
|
713
|
-
isClientTool: parsed.is_client_tool
|
|
714
|
-
};
|
|
715
|
-
this.activeTools.set(parsed.call_id, {
|
|
716
|
-
toolName: parsed.tool,
|
|
717
|
-
displayName: parsed.display_name,
|
|
718
|
-
description: parsed.description,
|
|
719
|
-
arguments: parsed.arguments,
|
|
720
|
-
callId: parsed.call_id,
|
|
721
|
-
status: parsed.is_client_tool ? "calling" : "executing",
|
|
722
|
-
isClientTool: parsed.is_client_tool
|
|
723
|
-
});
|
|
724
|
-
this.emit({ type: "tool_call", request: toolCall });
|
|
708
|
+
this.applyEvent(parsed);
|
|
725
709
|
if (parsed.is_client_tool) {
|
|
726
|
-
const results = await this.executeClientTools([
|
|
710
|
+
const results = await this.executeClientTools([
|
|
711
|
+
{
|
|
712
|
+
callId: parsed.call_id,
|
|
713
|
+
toolName: parsed.tool,
|
|
714
|
+
displayName: parsed.display_name,
|
|
715
|
+
description: parsed.description,
|
|
716
|
+
arguments: parsed.arguments,
|
|
717
|
+
isClientTool: parsed.is_client_tool
|
|
718
|
+
}
|
|
719
|
+
]);
|
|
727
720
|
await this.client.submitToolResult({
|
|
728
721
|
conversation_id: conversationId,
|
|
729
722
|
message_id: messageId,
|
|
@@ -732,61 +725,6 @@ var ChatSession = class {
|
|
|
732
725
|
}
|
|
733
726
|
break;
|
|
734
727
|
}
|
|
735
|
-
case "tool_use_end": {
|
|
736
|
-
const toolState = this.activeTools.get(parsed.call_id);
|
|
737
|
-
if (toolState) {
|
|
738
|
-
toolState.status = "completed";
|
|
739
|
-
}
|
|
740
|
-
this.emit({
|
|
741
|
-
type: "tool_end",
|
|
742
|
-
callId: parsed.call_id,
|
|
743
|
-
toolName: parsed.tool
|
|
744
|
-
});
|
|
745
|
-
break;
|
|
746
|
-
}
|
|
747
|
-
case "agent_start":
|
|
748
|
-
this.emit({
|
|
749
|
-
type: "agent_start",
|
|
750
|
-
agentName: parsed.agent_name,
|
|
751
|
-
agentDisplayName: parsed.agent_display_name,
|
|
752
|
-
avatarUrl: parsed.avatar_url
|
|
753
|
-
});
|
|
754
|
-
break;
|
|
755
|
-
case "agent_end":
|
|
756
|
-
this.emit({ type: "agent_end", agentName: parsed.agent_name });
|
|
757
|
-
break;
|
|
758
|
-
case "subagent_start":
|
|
759
|
-
this.activeSubagents.set(parsed.tool_call_id, {
|
|
760
|
-
agentName: parsed.agent_name,
|
|
761
|
-
displayName: parsed.display_name,
|
|
762
|
-
avatarUrl: parsed.avatar_url,
|
|
763
|
-
description: parsed.description,
|
|
764
|
-
content: "",
|
|
765
|
-
isActive: true
|
|
766
|
-
});
|
|
767
|
-
this.emit({
|
|
768
|
-
type: "subagent_start",
|
|
769
|
-
agentName: parsed.agent_name,
|
|
770
|
-
displayName: parsed.display_name,
|
|
771
|
-
toolCallId: parsed.tool_call_id,
|
|
772
|
-
avatarUrl: parsed.avatar_url,
|
|
773
|
-
description: parsed.description
|
|
774
|
-
});
|
|
775
|
-
break;
|
|
776
|
-
case "subagent_update": {
|
|
777
|
-
const sub = this.activeSubagents.get(parsed.tool_call_id);
|
|
778
|
-
if (sub) {
|
|
779
|
-
sub.agentName = parsed.agent_name;
|
|
780
|
-
sub.displayName = parsed.display_name;
|
|
781
|
-
}
|
|
782
|
-
this.emit({
|
|
783
|
-
type: "subagent_update",
|
|
784
|
-
agentName: parsed.agent_name,
|
|
785
|
-
displayName: parsed.display_name,
|
|
786
|
-
toolCallId: parsed.tool_call_id
|
|
787
|
-
});
|
|
788
|
-
break;
|
|
789
|
-
}
|
|
790
728
|
case "subagent_content_delta": {
|
|
791
729
|
const subagent = this.activeSubagents.get(parsed.tool_call_id);
|
|
792
730
|
if (subagent) {
|
|
@@ -800,19 +738,6 @@ var ChatSession = class {
|
|
|
800
738
|
});
|
|
801
739
|
break;
|
|
802
740
|
}
|
|
803
|
-
case "subagent_end": {
|
|
804
|
-
const sub = this.activeSubagents.get(parsed.tool_call_id);
|
|
805
|
-
if (sub) {
|
|
806
|
-
sub.isActive = false;
|
|
807
|
-
}
|
|
808
|
-
this.emit({
|
|
809
|
-
type: "subagent_end",
|
|
810
|
-
agentName: parsed.agent_name,
|
|
811
|
-
displayName: parsed.display_name,
|
|
812
|
-
toolCallId: parsed.tool_call_id
|
|
813
|
-
});
|
|
814
|
-
break;
|
|
815
|
-
}
|
|
816
741
|
case "thinking_delta":
|
|
817
742
|
this.thinkingContent += parsed.delta.text;
|
|
818
743
|
this.isThinking = true;
|
|
@@ -822,45 +747,6 @@ var ChatSession = class {
|
|
|
822
747
|
this.isThinking = false;
|
|
823
748
|
this.emit({ type: "thinking_complete" });
|
|
824
749
|
break;
|
|
825
|
-
case "sources":
|
|
826
|
-
this.sources.push(...parsed.sources);
|
|
827
|
-
this.emit({ type: "sources", sources: parsed.sources });
|
|
828
|
-
break;
|
|
829
|
-
case "capsule_output": {
|
|
830
|
-
const capsule = {
|
|
831
|
-
toolName: parsed.tool_name,
|
|
832
|
-
agentName: parsed.agent_name,
|
|
833
|
-
command: parsed.command,
|
|
834
|
-
output: parsed.output,
|
|
835
|
-
durationMs: parsed.duration_ms
|
|
836
|
-
};
|
|
837
|
-
this.capsuleOutputs.push(capsule);
|
|
838
|
-
this.emit({ type: "capsule_output", ...capsule });
|
|
839
|
-
break;
|
|
840
|
-
}
|
|
841
|
-
case "todo_update":
|
|
842
|
-
this.todos = parsed.todos;
|
|
843
|
-
this.emit({ type: "todo_update", todos: parsed.todos });
|
|
844
|
-
break;
|
|
845
|
-
case "subagent_tool_use":
|
|
846
|
-
this.emit({
|
|
847
|
-
type: "subagent_tool_use",
|
|
848
|
-
agentName: parsed.agent_name,
|
|
849
|
-
toolName: parsed.tool,
|
|
850
|
-
toolCallId: parsed.tool_call_id,
|
|
851
|
-
result: parsed.result
|
|
852
|
-
});
|
|
853
|
-
break;
|
|
854
|
-
case "asset_created":
|
|
855
|
-
this.emit({
|
|
856
|
-
type: "asset_created",
|
|
857
|
-
assetId: parsed.asset_id,
|
|
858
|
-
name: parsed.name,
|
|
859
|
-
url: parsed.url,
|
|
860
|
-
mediaType: parsed.media_type,
|
|
861
|
-
sizeBytes: parsed.size_bytes
|
|
862
|
-
});
|
|
863
|
-
break;
|
|
864
750
|
case "retry":
|
|
865
751
|
this.emit({
|
|
866
752
|
type: "retry",
|
|
@@ -878,11 +764,154 @@ var ChatSession = class {
|
|
|
878
764
|
error: new AstralformError(parsed.message, parsed.code)
|
|
879
765
|
});
|
|
880
766
|
break;
|
|
767
|
+
default:
|
|
768
|
+
this.applyEvent(parsed);
|
|
881
769
|
}
|
|
882
770
|
}
|
|
883
771
|
this.currentJobId = null;
|
|
884
772
|
await this.completeStream(conversationId, messageId, stopTitle);
|
|
885
773
|
}
|
|
774
|
+
/**
|
|
775
|
+
* Apply a single SSE event to session state and notify consumers.
|
|
776
|
+
* Shared between live streaming and historical event replay.
|
|
777
|
+
*/
|
|
778
|
+
applyEvent(event) {
|
|
779
|
+
switch (event.type) {
|
|
780
|
+
case "tool_use_start": {
|
|
781
|
+
const request = {
|
|
782
|
+
callId: event.call_id,
|
|
783
|
+
toolName: event.tool,
|
|
784
|
+
displayName: event.display_name,
|
|
785
|
+
description: event.description,
|
|
786
|
+
arguments: event.arguments,
|
|
787
|
+
isClientTool: event.is_client_tool
|
|
788
|
+
};
|
|
789
|
+
this.activeTools.set(event.call_id, {
|
|
790
|
+
...request,
|
|
791
|
+
status: event.is_client_tool ? "calling" : "executing"
|
|
792
|
+
});
|
|
793
|
+
this.emit({ type: "tool_call", request });
|
|
794
|
+
break;
|
|
795
|
+
}
|
|
796
|
+
case "tool_use_end": {
|
|
797
|
+
const toolState = this.activeTools.get(event.call_id);
|
|
798
|
+
if (toolState) {
|
|
799
|
+
toolState.status = "completed";
|
|
800
|
+
}
|
|
801
|
+
this.emit({
|
|
802
|
+
type: "tool_end",
|
|
803
|
+
callId: event.call_id,
|
|
804
|
+
toolName: event.tool,
|
|
805
|
+
result: event.result
|
|
806
|
+
});
|
|
807
|
+
break;
|
|
808
|
+
}
|
|
809
|
+
case "agent_start":
|
|
810
|
+
this.emit({
|
|
811
|
+
type: "agent_start",
|
|
812
|
+
agentName: event.agent_name,
|
|
813
|
+
agentDisplayName: event.agent_display_name,
|
|
814
|
+
avatarUrl: event.avatar_url
|
|
815
|
+
});
|
|
816
|
+
break;
|
|
817
|
+
case "agent_end":
|
|
818
|
+
this.emit({ type: "agent_end", agentName: event.agent_name });
|
|
819
|
+
break;
|
|
820
|
+
case "subagent_start":
|
|
821
|
+
this.activeSubagents.set(event.tool_call_id, {
|
|
822
|
+
agentName: event.agent_name,
|
|
823
|
+
displayName: event.display_name,
|
|
824
|
+
avatarUrl: event.avatar_url,
|
|
825
|
+
description: event.description,
|
|
826
|
+
content: "",
|
|
827
|
+
isActive: true
|
|
828
|
+
});
|
|
829
|
+
this.emit({
|
|
830
|
+
type: "subagent_start",
|
|
831
|
+
agentName: event.agent_name,
|
|
832
|
+
displayName: event.display_name,
|
|
833
|
+
toolCallId: event.tool_call_id,
|
|
834
|
+
avatarUrl: event.avatar_url,
|
|
835
|
+
description: event.description
|
|
836
|
+
});
|
|
837
|
+
break;
|
|
838
|
+
case "subagent_update": {
|
|
839
|
+
const sub = this.activeSubagents.get(event.tool_call_id);
|
|
840
|
+
if (sub) {
|
|
841
|
+
sub.agentName = event.agent_name;
|
|
842
|
+
sub.displayName = event.display_name;
|
|
843
|
+
}
|
|
844
|
+
this.emit({
|
|
845
|
+
type: "subagent_update",
|
|
846
|
+
agentName: event.agent_name,
|
|
847
|
+
displayName: event.display_name,
|
|
848
|
+
toolCallId: event.tool_call_id
|
|
849
|
+
});
|
|
850
|
+
break;
|
|
851
|
+
}
|
|
852
|
+
case "subagent_end": {
|
|
853
|
+
const sub = this.activeSubagents.get(event.tool_call_id);
|
|
854
|
+
if (sub) {
|
|
855
|
+
sub.isActive = false;
|
|
856
|
+
}
|
|
857
|
+
this.emit({
|
|
858
|
+
type: "subagent_end",
|
|
859
|
+
agentName: event.agent_name,
|
|
860
|
+
displayName: event.display_name,
|
|
861
|
+
toolCallId: event.tool_call_id
|
|
862
|
+
});
|
|
863
|
+
break;
|
|
864
|
+
}
|
|
865
|
+
case "subagent_tool_use":
|
|
866
|
+
this.emit({
|
|
867
|
+
type: "subagent_tool_use",
|
|
868
|
+
agentName: event.agent_name,
|
|
869
|
+
toolName: event.tool,
|
|
870
|
+
toolCallId: event.tool_call_id,
|
|
871
|
+
result: event.result
|
|
872
|
+
});
|
|
873
|
+
break;
|
|
874
|
+
case "sources":
|
|
875
|
+
this.sources.push(...event.sources);
|
|
876
|
+
this.emit({ type: "sources", sources: event.sources });
|
|
877
|
+
break;
|
|
878
|
+
case "capsule_output": {
|
|
879
|
+
const capsule = {
|
|
880
|
+
toolName: event.tool_name,
|
|
881
|
+
agentName: event.agent_name,
|
|
882
|
+
command: event.command,
|
|
883
|
+
output: event.output,
|
|
884
|
+
durationMs: event.duration_ms,
|
|
885
|
+
callId: event.call_id
|
|
886
|
+
};
|
|
887
|
+
this.capsuleOutputs.push(capsule);
|
|
888
|
+
this.emit({ type: "capsule_output", ...capsule });
|
|
889
|
+
break;
|
|
890
|
+
}
|
|
891
|
+
case "capsule_output_chunk":
|
|
892
|
+
this.emit({
|
|
893
|
+
type: "capsule_output_chunk",
|
|
894
|
+
callId: event.call_id,
|
|
895
|
+
stream: event.stream,
|
|
896
|
+
chunk: event.chunk
|
|
897
|
+
});
|
|
898
|
+
break;
|
|
899
|
+
case "todo_update":
|
|
900
|
+
this.todos = event.todos;
|
|
901
|
+
this.emit({ type: "todo_update", todos: event.todos });
|
|
902
|
+
break;
|
|
903
|
+
case "asset_created":
|
|
904
|
+
this.emit({
|
|
905
|
+
type: "asset_created",
|
|
906
|
+
assetId: event.asset_id,
|
|
907
|
+
name: event.name,
|
|
908
|
+
url: event.url,
|
|
909
|
+
mediaType: event.media_type,
|
|
910
|
+
sizeBytes: event.size_bytes
|
|
911
|
+
});
|
|
912
|
+
break;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
886
915
|
async executeClientTools(toolCalls) {
|
|
887
916
|
const results = [];
|
|
888
917
|
for (const call of toolCalls) {
|
|
@@ -959,12 +988,27 @@ var ChatSession = class {
|
|
|
959
988
|
}
|
|
960
989
|
async switchConversation(id) {
|
|
961
990
|
this.conversationId = id;
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
this.
|
|
991
|
+
this.resetStreamingState();
|
|
992
|
+
const [messagesResult, eventsResult] = await Promise.allSettled([
|
|
993
|
+
this.client.getMessages(id).catch(() => this.storage.fetchMessages(id)),
|
|
994
|
+
this.client.getConversationEvents(id)
|
|
995
|
+
]);
|
|
996
|
+
this.messages = messagesResult.status === "fulfilled" ? messagesResult.value : [];
|
|
997
|
+
if (eventsResult.status === "fulfilled") {
|
|
998
|
+
for (const ev of eventsResult.value) {
|
|
999
|
+
this.replayEvent(ev.event, ev.data);
|
|
1000
|
+
}
|
|
966
1001
|
}
|
|
967
|
-
|
|
1002
|
+
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Replay a single persisted event to reconstruct session state.
|
|
1005
|
+
* Skips text deltas (final content is already in messages[]).
|
|
1006
|
+
*/
|
|
1007
|
+
replayEvent(eventType, data) {
|
|
1008
|
+
if (eventType === "content_block_delta" || eventType === "thinking_delta" || eventType === "subagent_content_delta" || eventType === "thinking_complete") {
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
this.applyEvent({ type: eventType, ...data });
|
|
968
1012
|
}
|
|
969
1013
|
async deleteConversation(id) {
|
|
970
1014
|
try {
|