@astralform/js 3.0.0 → 3.0.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 +16 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -6
- package/dist/index.d.ts +17 -6
- package/dist/index.js +16 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -988,10 +988,11 @@ declare class ChatSession {
|
|
|
988
988
|
switchConversation(id: string, jobId?: string,
|
|
989
989
|
/**
|
|
990
990
|
* User prompt that triggered this job, if known. Emitted as a
|
|
991
|
-
* synthetic ``user_message`` ChatEvent
|
|
992
|
-
*
|
|
993
|
-
*
|
|
994
|
-
*
|
|
991
|
+
* synthetic ``user_message`` ChatEvent at the START of the replay —
|
|
992
|
+
* a completed job maps to exactly one user turn, so every event in it
|
|
993
|
+
* belongs beneath that prompt. User messages aren't persisted in
|
|
994
|
+
* ``job_events``, so without this the restored conversation would show
|
|
995
|
+
* the agent response with no visible prompt above it.
|
|
995
996
|
*/
|
|
996
997
|
userMessageContent?: string): Promise<void>;
|
|
997
998
|
deleteConversation(id: string): Promise<void>;
|
|
@@ -1145,8 +1146,18 @@ interface RawSseEvent {
|
|
|
1145
1146
|
declare function mapSseToChat(raw: RawSseEvent): ChatEvent[];
|
|
1146
1147
|
/**
|
|
1147
1148
|
* Replay persisted SSE events through the provided handler, interleaving
|
|
1148
|
-
* user messages from session.messages at the
|
|
1149
|
-
*
|
|
1149
|
+
* user messages from session.messages at the START of each turn (user
|
|
1150
|
+
* messages aren't persisted in job_events).
|
|
1151
|
+
*
|
|
1152
|
+
* The turn boundary is a change of ``job_id``, NOT ``message_start`` or
|
|
1153
|
+
* ``message_stop``. A completed job maps to exactly one user turn — but a
|
|
1154
|
+
* single job can contain several ``message_start``/``message_stop`` pairs (a
|
|
1155
|
+
* tool-use loop: LLM call → tool result → LLM call again), so neither event
|
|
1156
|
+
* reliably delimits turns. And within a job some events precede the first
|
|
1157
|
+
* ``message_start`` (e.g. ``memory_recall``, emitted during prompt prep), so
|
|
1158
|
+
* gating the user block on ``message_start`` would replay them above the
|
|
1159
|
+
* user's own message. Keying off ``job_id`` injects the prompt once per job,
|
|
1160
|
+
* before its first event — matching ``session.ts#switchConversation``.
|
|
1150
1161
|
*/
|
|
1151
1162
|
declare function replayEvents(sseEvents: RawSseEvent[], userMessages: {
|
|
1152
1163
|
role: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -988,10 +988,11 @@ declare class ChatSession {
|
|
|
988
988
|
switchConversation(id: string, jobId?: string,
|
|
989
989
|
/**
|
|
990
990
|
* User prompt that triggered this job, if known. Emitted as a
|
|
991
|
-
* synthetic ``user_message`` ChatEvent
|
|
992
|
-
*
|
|
993
|
-
*
|
|
994
|
-
*
|
|
991
|
+
* synthetic ``user_message`` ChatEvent at the START of the replay —
|
|
992
|
+
* a completed job maps to exactly one user turn, so every event in it
|
|
993
|
+
* belongs beneath that prompt. User messages aren't persisted in
|
|
994
|
+
* ``job_events``, so without this the restored conversation would show
|
|
995
|
+
* the agent response with no visible prompt above it.
|
|
995
996
|
*/
|
|
996
997
|
userMessageContent?: string): Promise<void>;
|
|
997
998
|
deleteConversation(id: string): Promise<void>;
|
|
@@ -1145,8 +1146,18 @@ interface RawSseEvent {
|
|
|
1145
1146
|
declare function mapSseToChat(raw: RawSseEvent): ChatEvent[];
|
|
1146
1147
|
/**
|
|
1147
1148
|
* Replay persisted SSE events through the provided handler, interleaving
|
|
1148
|
-
* user messages from session.messages at the
|
|
1149
|
-
*
|
|
1149
|
+
* user messages from session.messages at the START of each turn (user
|
|
1150
|
+
* messages aren't persisted in job_events).
|
|
1151
|
+
*
|
|
1152
|
+
* The turn boundary is a change of ``job_id``, NOT ``message_start`` or
|
|
1153
|
+
* ``message_stop``. A completed job maps to exactly one user turn — but a
|
|
1154
|
+
* single job can contain several ``message_start``/``message_stop`` pairs (a
|
|
1155
|
+
* tool-use loop: LLM call → tool result → LLM call again), so neither event
|
|
1156
|
+
* reliably delimits turns. And within a job some events precede the first
|
|
1157
|
+
* ``message_start`` (e.g. ``memory_recall``, emitted during prompt prep), so
|
|
1158
|
+
* gating the user block on ``message_start`` would replay them above the
|
|
1159
|
+
* user's own message. Keying off ``job_id`` injects the prompt once per job,
|
|
1160
|
+
* before its first event — matching ``session.ts#switchConversation``.
|
|
1150
1161
|
*/
|
|
1151
1162
|
declare function replayEvents(sseEvents: RawSseEvent[], userMessages: {
|
|
1152
1163
|
role: string;
|
package/dist/index.js
CHANGED
|
@@ -1628,17 +1628,12 @@ var ChatSession = class {
|
|
|
1628
1628
|
]);
|
|
1629
1629
|
this.messages = messagesResult.status === "fulfilled" ? messagesResult.value : [];
|
|
1630
1630
|
if (eventsResult.status === "fulfilled") {
|
|
1631
|
-
|
|
1631
|
+
if (userMessageContent) {
|
|
1632
|
+
this.emit({ type: "user_message", content: userMessageContent });
|
|
1633
|
+
}
|
|
1632
1634
|
for (const ev of eventsResult.value) {
|
|
1633
1635
|
const type = ev.data.type || ev.event;
|
|
1634
1636
|
if (!type || type === "done") continue;
|
|
1635
|
-
if (!userMessageEmitted && type === "message_start") {
|
|
1636
|
-
this.emit({
|
|
1637
|
-
type: "user_message",
|
|
1638
|
-
content: userMessageContent
|
|
1639
|
-
});
|
|
1640
|
-
userMessageEmitted = true;
|
|
1641
|
-
}
|
|
1642
1637
|
const wire = { ...ev.data, type };
|
|
1643
1638
|
try {
|
|
1644
1639
|
await this.dispatchWireEvent(
|
|
@@ -1947,21 +1942,21 @@ function mapSseToChat(raw) {
|
|
|
1947
1942
|
function replayEvents(sseEvents, userMessages, handleEvent, addBlock) {
|
|
1948
1943
|
const userMsgs = userMessages.filter((m) => m.role === "user");
|
|
1949
1944
|
let userIdx = 0;
|
|
1950
|
-
let
|
|
1945
|
+
let currentJobId = null;
|
|
1951
1946
|
for (const raw of sseEvents) {
|
|
1952
1947
|
const type = raw.data.type || raw.event;
|
|
1953
|
-
if (type === "
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1948
|
+
if (!type || type === "done") continue;
|
|
1949
|
+
const jobId = raw.data.job_id ?? null;
|
|
1950
|
+
if (jobId !== null && jobId !== currentJobId) {
|
|
1951
|
+
currentJobId = jobId;
|
|
1952
|
+
if (userIdx < userMsgs.length) {
|
|
1953
|
+
addBlock({
|
|
1954
|
+
type: "user",
|
|
1955
|
+
id: `replay_user_${userIdx}`,
|
|
1956
|
+
content: userMsgs[userIdx].content
|
|
1957
|
+
});
|
|
1958
|
+
userIdx++;
|
|
1959
|
+
}
|
|
1965
1960
|
}
|
|
1966
1961
|
for (const ce of mapSseToChat(raw)) {
|
|
1967
1962
|
handleEvent(ce);
|