@astralform/js 4.3.0 → 4.5.0
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 +100 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -22
- package/dist/index.d.ts +24 -22
- package/dist/index.js +100 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -420,6 +420,12 @@ type ChatEvent = {
|
|
|
420
420
|
type: "user_message";
|
|
421
421
|
content: string;
|
|
422
422
|
createdAt?: number;
|
|
423
|
+
id?: string;
|
|
424
|
+
/** This message was steered into a run already in flight — it started
|
|
425
|
+
* no turn of its own. Consumers that badge a steer (a "waiting to be
|
|
426
|
+
* read" notice) key off this; without it a replayed steer is
|
|
427
|
+
* indistinguishable from an ordinary prompt. */
|
|
428
|
+
steer?: boolean;
|
|
423
429
|
} | {
|
|
424
430
|
type: "title_generated";
|
|
425
431
|
title: string;
|
|
@@ -546,6 +552,12 @@ interface UIComponentsConfig {
|
|
|
546
552
|
/** MIME type to match against embedded resources (e.g. "application/json+a2ui"). */
|
|
547
553
|
mimeType: string | null;
|
|
548
554
|
}
|
|
555
|
+
/** One capability the agent either has or does not, right now. */
|
|
556
|
+
interface AgentCapability {
|
|
557
|
+
/** Stable key, e.g. `"image"`, `"web"`, `"skills"`. */
|
|
558
|
+
key: string;
|
|
559
|
+
enabled: boolean;
|
|
560
|
+
}
|
|
549
561
|
interface AgentStatus {
|
|
550
562
|
isReady: boolean;
|
|
551
563
|
llmConfigured: boolean;
|
|
@@ -553,6 +565,16 @@ interface AgentStatus {
|
|
|
553
565
|
llmModel?: string;
|
|
554
566
|
message: string;
|
|
555
567
|
uiComponents: UIComponentsConfig;
|
|
568
|
+
/**
|
|
569
|
+
* What the agent can do right now, so a client can offer a capability only
|
|
570
|
+
* where it will actually work rather than failing on send.
|
|
571
|
+
*
|
|
572
|
+
* Empty when the backend does not report it (older servers) or when the agent
|
|
573
|
+
* is not ready — treat an ABSENT key as "not reported", never as disabled.
|
|
574
|
+
* Only capabilities with a real per-agent gate appear; always-on ones do not,
|
|
575
|
+
* because a constant tells a client nothing.
|
|
576
|
+
*/
|
|
577
|
+
capabilities: AgentCapability[];
|
|
556
578
|
}
|
|
557
579
|
interface AgentInfo {
|
|
558
580
|
name: string;
|
|
@@ -1139,7 +1161,7 @@ declare class ChatSession {
|
|
|
1139
1161
|
* ``message_start`` in the stream (e.g. ``memory_recall`` from prompt prep),
|
|
1140
1162
|
* so leading with the prompt keeps the turn in order.
|
|
1141
1163
|
*/
|
|
1142
|
-
replayTurn(id: string, events: ConversationEvent[], userMessageContent?: string): void;
|
|
1164
|
+
replayTurn(id: string, events: ConversationEvent[], userMessageContent?: string, userMessageId?: string, isSteer?: boolean): void;
|
|
1143
1165
|
/**
|
|
1144
1166
|
* Load a conversation's messages and replay its persisted history.
|
|
1145
1167
|
*
|
|
@@ -1236,26 +1258,6 @@ declare function generateId(): string;
|
|
|
1236
1258
|
*/
|
|
1237
1259
|
declare function streamJobSSE(options: StreamJobSSEOptions): AsyncGenerator<ChatStreamEvent>;
|
|
1238
1260
|
|
|
1239
|
-
/**
|
|
1240
|
-
* StreamManager — high-level conversation lifecycle coordinator.
|
|
1241
|
-
*
|
|
1242
|
-
* Sits on top of ChatSession and manages the state machine for
|
|
1243
|
-
* multi-conversation SSE streaming. Framework-agnostic: emits
|
|
1244
|
-
* typed events to registered handlers. Block construction is NOT
|
|
1245
|
-
* the SDK's concern — consumers build their own block tree from
|
|
1246
|
-
* the forwarded ``ChatEvent`` instances.
|
|
1247
|
-
*
|
|
1248
|
-
* import { ChatSession, StreamManager } from "@astralform/js";
|
|
1249
|
-
* const session = new ChatSession({ ... });
|
|
1250
|
-
* const manager = new StreamManager(session);
|
|
1251
|
-
* manager.on((event) => {
|
|
1252
|
-
* if (event.type === "event") {
|
|
1253
|
-
* // event.event is a typed ChatEvent — dispatch to your reducer
|
|
1254
|
-
* }
|
|
1255
|
-
* });
|
|
1256
|
-
* await manager.send("Hello");
|
|
1257
|
-
*/
|
|
1258
|
-
|
|
1259
1261
|
type StreamState = "idle" | "streaming" | "restoring" | "detached";
|
|
1260
1262
|
interface SendOptions extends ModelChoiceOptions {
|
|
1261
1263
|
agentName?: string;
|
|
@@ -1418,4 +1420,4 @@ declare function isEmbeddedResource(value: unknown): value is {
|
|
|
1418
1420
|
*/
|
|
1419
1421
|
declare function parseEmbeddedResource(value: unknown): EmbeddedResource | null;
|
|
1420
1422
|
|
|
1421
|
-
export { type ActiveJob, type AgentIdentity, type AgentInfo, type AgentStatus, type AssetCreatedPayload, type AstralformApiKeyConfig, AstralformClient, type AstralformConfig, AstralformError, type AstralformUserTokenConfig, type AttachmentStagedPayload, AuthenticationError, type BlockDeltaPayload, CONVERSATION_PAGE_SIZE, type ChatEvent, ChatEventType, type ChatEventTypeValue, ChatSession, type ChatStorage, type ChatStreamEvent, type ChatStreamRequest, ConnectionError, type ContextUpdatePayload, type ContextWarningPayload, type Conversation, type ConversationAsset, type ConversationEvent, type DesktopStreamPayload, type EmbeddedResource, type FeedbackRequest, type FeedbackResponse, InMemoryStorage, type JobCreateResponse, type JobStatus, type JobSummary, LLMNotConfiguredError, type MemoryRecallPayload, type MemoryRecord, type MemoryUpdatePayload, type Message, type ModelChoiceOptions, type ModelOption, type MyToolGrantsPage, type PromptSuggestionPayload, type ProtocolAdapter, ProtocolRegistry, RateLimitError, type RateLimitErrorDetails, type RawSseEvent, type ReasoningEffort, type SendOptions, ServerError, type SkillInfo, StreamAbortedError, type StreamJobSSEOptions, StreamManager, type StreamManagerEvent, type StreamState, type SubagentStartPayload, type SubagentStopPayload, type TaskStatus, type TeamAgentSummary, type TeamSummary, type TitleGeneratedPayload, type TodoItem, type TodoUpdatePayload, type ToolApprovalDecision, type ToolApprovalGrantedPayload, type ToolApprovalRequest, type ToolApprovalRequestedPayload, type ToolApprovalScope, type ToolCallRequest, type ToolDefinition, type ToolGrant, type ToolHandler, type ToolHarnessWarningPayload, type ToolPermissionDeniedPayload, ToolRegistry, type ToolResult, type ToolResultRequest, type TurnUsage, type UIComponentsConfig, type UserUnavailablePayload, type WireBlockDelta, type WireBlockDeltaPayload, type WireBlockKind, type WireBlockStart, type WireBlockStatus, type WireBlockStop, type WireCustomEvent, type WireErrorEvent, type WireEvent, type WireInputArgDelta, type WireInputDelta, type WireKeepalive, type WireMessageStart, type WireMessageStop, type WireOutputDelta, type WireRetryEvent, type WireSignatureDelta, type WireStallWarning, type WireStatusDelta, type WireStopReason, type WireTextDelta, type WireThinkingDelta, type WorkspaceReadyPayload, generateId, isEmbeddedResource, mapSseToChat, parseEmbeddedResource, replayEvents, streamJobSSE, translateDelta };
|
|
1423
|
+
export { type ActiveJob, type AgentCapability, type AgentIdentity, type AgentInfo, type AgentStatus, type AssetCreatedPayload, type AstralformApiKeyConfig, AstralformClient, type AstralformConfig, AstralformError, type AstralformUserTokenConfig, type AttachmentStagedPayload, AuthenticationError, type BlockDeltaPayload, CONVERSATION_PAGE_SIZE, type ChatEvent, ChatEventType, type ChatEventTypeValue, ChatSession, type ChatStorage, type ChatStreamEvent, type ChatStreamRequest, ConnectionError, type ContextUpdatePayload, type ContextWarningPayload, type Conversation, type ConversationAsset, type ConversationEvent, type DesktopStreamPayload, type EmbeddedResource, type FeedbackRequest, type FeedbackResponse, InMemoryStorage, type JobCreateResponse, type JobStatus, type JobSummary, LLMNotConfiguredError, type MemoryRecallPayload, type MemoryRecord, type MemoryUpdatePayload, type Message, type ModelChoiceOptions, type ModelOption, type MyToolGrantsPage, type PromptSuggestionPayload, type ProtocolAdapter, ProtocolRegistry, RateLimitError, type RateLimitErrorDetails, type RawSseEvent, type ReasoningEffort, type SendOptions, ServerError, type SkillInfo, StreamAbortedError, type StreamJobSSEOptions, StreamManager, type StreamManagerEvent, type StreamState, type SubagentStartPayload, type SubagentStopPayload, type TaskStatus, type TeamAgentSummary, type TeamSummary, type TitleGeneratedPayload, type TodoItem, type TodoUpdatePayload, type ToolApprovalDecision, type ToolApprovalGrantedPayload, type ToolApprovalRequest, type ToolApprovalRequestedPayload, type ToolApprovalScope, type ToolCallRequest, type ToolDefinition, type ToolGrant, type ToolHandler, type ToolHarnessWarningPayload, type ToolPermissionDeniedPayload, ToolRegistry, type ToolResult, type ToolResultRequest, type TurnUsage, type UIComponentsConfig, type UserUnavailablePayload, type WireBlockDelta, type WireBlockDeltaPayload, type WireBlockKind, type WireBlockStart, type WireBlockStatus, type WireBlockStop, type WireCustomEvent, type WireErrorEvent, type WireEvent, type WireInputArgDelta, type WireInputDelta, type WireKeepalive, type WireMessageStart, type WireMessageStop, type WireOutputDelta, type WireRetryEvent, type WireSignatureDelta, type WireStallWarning, type WireStatusDelta, type WireStopReason, type WireTextDelta, type WireThinkingDelta, type WorkspaceReadyPayload, generateId, isEmbeddedResource, mapSseToChat, parseEmbeddedResource, replayEvents, streamJobSSE, translateDelta };
|
package/dist/index.d.ts
CHANGED
|
@@ -420,6 +420,12 @@ type ChatEvent = {
|
|
|
420
420
|
type: "user_message";
|
|
421
421
|
content: string;
|
|
422
422
|
createdAt?: number;
|
|
423
|
+
id?: string;
|
|
424
|
+
/** This message was steered into a run already in flight — it started
|
|
425
|
+
* no turn of its own. Consumers that badge a steer (a "waiting to be
|
|
426
|
+
* read" notice) key off this; without it a replayed steer is
|
|
427
|
+
* indistinguishable from an ordinary prompt. */
|
|
428
|
+
steer?: boolean;
|
|
423
429
|
} | {
|
|
424
430
|
type: "title_generated";
|
|
425
431
|
title: string;
|
|
@@ -546,6 +552,12 @@ interface UIComponentsConfig {
|
|
|
546
552
|
/** MIME type to match against embedded resources (e.g. "application/json+a2ui"). */
|
|
547
553
|
mimeType: string | null;
|
|
548
554
|
}
|
|
555
|
+
/** One capability the agent either has or does not, right now. */
|
|
556
|
+
interface AgentCapability {
|
|
557
|
+
/** Stable key, e.g. `"image"`, `"web"`, `"skills"`. */
|
|
558
|
+
key: string;
|
|
559
|
+
enabled: boolean;
|
|
560
|
+
}
|
|
549
561
|
interface AgentStatus {
|
|
550
562
|
isReady: boolean;
|
|
551
563
|
llmConfigured: boolean;
|
|
@@ -553,6 +565,16 @@ interface AgentStatus {
|
|
|
553
565
|
llmModel?: string;
|
|
554
566
|
message: string;
|
|
555
567
|
uiComponents: UIComponentsConfig;
|
|
568
|
+
/**
|
|
569
|
+
* What the agent can do right now, so a client can offer a capability only
|
|
570
|
+
* where it will actually work rather than failing on send.
|
|
571
|
+
*
|
|
572
|
+
* Empty when the backend does not report it (older servers) or when the agent
|
|
573
|
+
* is not ready — treat an ABSENT key as "not reported", never as disabled.
|
|
574
|
+
* Only capabilities with a real per-agent gate appear; always-on ones do not,
|
|
575
|
+
* because a constant tells a client nothing.
|
|
576
|
+
*/
|
|
577
|
+
capabilities: AgentCapability[];
|
|
556
578
|
}
|
|
557
579
|
interface AgentInfo {
|
|
558
580
|
name: string;
|
|
@@ -1139,7 +1161,7 @@ declare class ChatSession {
|
|
|
1139
1161
|
* ``message_start`` in the stream (e.g. ``memory_recall`` from prompt prep),
|
|
1140
1162
|
* so leading with the prompt keeps the turn in order.
|
|
1141
1163
|
*/
|
|
1142
|
-
replayTurn(id: string, events: ConversationEvent[], userMessageContent?: string): void;
|
|
1164
|
+
replayTurn(id: string, events: ConversationEvent[], userMessageContent?: string, userMessageId?: string, isSteer?: boolean): void;
|
|
1143
1165
|
/**
|
|
1144
1166
|
* Load a conversation's messages and replay its persisted history.
|
|
1145
1167
|
*
|
|
@@ -1236,26 +1258,6 @@ declare function generateId(): string;
|
|
|
1236
1258
|
*/
|
|
1237
1259
|
declare function streamJobSSE(options: StreamJobSSEOptions): AsyncGenerator<ChatStreamEvent>;
|
|
1238
1260
|
|
|
1239
|
-
/**
|
|
1240
|
-
* StreamManager — high-level conversation lifecycle coordinator.
|
|
1241
|
-
*
|
|
1242
|
-
* Sits on top of ChatSession and manages the state machine for
|
|
1243
|
-
* multi-conversation SSE streaming. Framework-agnostic: emits
|
|
1244
|
-
* typed events to registered handlers. Block construction is NOT
|
|
1245
|
-
* the SDK's concern — consumers build their own block tree from
|
|
1246
|
-
* the forwarded ``ChatEvent`` instances.
|
|
1247
|
-
*
|
|
1248
|
-
* import { ChatSession, StreamManager } from "@astralform/js";
|
|
1249
|
-
* const session = new ChatSession({ ... });
|
|
1250
|
-
* const manager = new StreamManager(session);
|
|
1251
|
-
* manager.on((event) => {
|
|
1252
|
-
* if (event.type === "event") {
|
|
1253
|
-
* // event.event is a typed ChatEvent — dispatch to your reducer
|
|
1254
|
-
* }
|
|
1255
|
-
* });
|
|
1256
|
-
* await manager.send("Hello");
|
|
1257
|
-
*/
|
|
1258
|
-
|
|
1259
1261
|
type StreamState = "idle" | "streaming" | "restoring" | "detached";
|
|
1260
1262
|
interface SendOptions extends ModelChoiceOptions {
|
|
1261
1263
|
agentName?: string;
|
|
@@ -1418,4 +1420,4 @@ declare function isEmbeddedResource(value: unknown): value is {
|
|
|
1418
1420
|
*/
|
|
1419
1421
|
declare function parseEmbeddedResource(value: unknown): EmbeddedResource | null;
|
|
1420
1422
|
|
|
1421
|
-
export { type ActiveJob, type AgentIdentity, type AgentInfo, type AgentStatus, type AssetCreatedPayload, type AstralformApiKeyConfig, AstralformClient, type AstralformConfig, AstralformError, type AstralformUserTokenConfig, type AttachmentStagedPayload, AuthenticationError, type BlockDeltaPayload, CONVERSATION_PAGE_SIZE, type ChatEvent, ChatEventType, type ChatEventTypeValue, ChatSession, type ChatStorage, type ChatStreamEvent, type ChatStreamRequest, ConnectionError, type ContextUpdatePayload, type ContextWarningPayload, type Conversation, type ConversationAsset, type ConversationEvent, type DesktopStreamPayload, type EmbeddedResource, type FeedbackRequest, type FeedbackResponse, InMemoryStorage, type JobCreateResponse, type JobStatus, type JobSummary, LLMNotConfiguredError, type MemoryRecallPayload, type MemoryRecord, type MemoryUpdatePayload, type Message, type ModelChoiceOptions, type ModelOption, type MyToolGrantsPage, type PromptSuggestionPayload, type ProtocolAdapter, ProtocolRegistry, RateLimitError, type RateLimitErrorDetails, type RawSseEvent, type ReasoningEffort, type SendOptions, ServerError, type SkillInfo, StreamAbortedError, type StreamJobSSEOptions, StreamManager, type StreamManagerEvent, type StreamState, type SubagentStartPayload, type SubagentStopPayload, type TaskStatus, type TeamAgentSummary, type TeamSummary, type TitleGeneratedPayload, type TodoItem, type TodoUpdatePayload, type ToolApprovalDecision, type ToolApprovalGrantedPayload, type ToolApprovalRequest, type ToolApprovalRequestedPayload, type ToolApprovalScope, type ToolCallRequest, type ToolDefinition, type ToolGrant, type ToolHandler, type ToolHarnessWarningPayload, type ToolPermissionDeniedPayload, ToolRegistry, type ToolResult, type ToolResultRequest, type TurnUsage, type UIComponentsConfig, type UserUnavailablePayload, type WireBlockDelta, type WireBlockDeltaPayload, type WireBlockKind, type WireBlockStart, type WireBlockStatus, type WireBlockStop, type WireCustomEvent, type WireErrorEvent, type WireEvent, type WireInputArgDelta, type WireInputDelta, type WireKeepalive, type WireMessageStart, type WireMessageStop, type WireOutputDelta, type WireRetryEvent, type WireSignatureDelta, type WireStallWarning, type WireStatusDelta, type WireStopReason, type WireTextDelta, type WireThinkingDelta, type WorkspaceReadyPayload, generateId, isEmbeddedResource, mapSseToChat, parseEmbeddedResource, replayEvents, streamJobSSE, translateDelta };
|
|
1423
|
+
export { type ActiveJob, type AgentCapability, type AgentIdentity, type AgentInfo, type AgentStatus, type AssetCreatedPayload, type AstralformApiKeyConfig, AstralformClient, type AstralformConfig, AstralformError, type AstralformUserTokenConfig, type AttachmentStagedPayload, AuthenticationError, type BlockDeltaPayload, CONVERSATION_PAGE_SIZE, type ChatEvent, ChatEventType, type ChatEventTypeValue, ChatSession, type ChatStorage, type ChatStreamEvent, type ChatStreamRequest, ConnectionError, type ContextUpdatePayload, type ContextWarningPayload, type Conversation, type ConversationAsset, type ConversationEvent, type DesktopStreamPayload, type EmbeddedResource, type FeedbackRequest, type FeedbackResponse, InMemoryStorage, type JobCreateResponse, type JobStatus, type JobSummary, LLMNotConfiguredError, type MemoryRecallPayload, type MemoryRecord, type MemoryUpdatePayload, type Message, type ModelChoiceOptions, type ModelOption, type MyToolGrantsPage, type PromptSuggestionPayload, type ProtocolAdapter, ProtocolRegistry, RateLimitError, type RateLimitErrorDetails, type RawSseEvent, type ReasoningEffort, type SendOptions, ServerError, type SkillInfo, StreamAbortedError, type StreamJobSSEOptions, StreamManager, type StreamManagerEvent, type StreamState, type SubagentStartPayload, type SubagentStopPayload, type TaskStatus, type TeamAgentSummary, type TeamSummary, type TitleGeneratedPayload, type TodoItem, type TodoUpdatePayload, type ToolApprovalDecision, type ToolApprovalGrantedPayload, type ToolApprovalRequest, type ToolApprovalRequestedPayload, type ToolApprovalScope, type ToolCallRequest, type ToolDefinition, type ToolGrant, type ToolHandler, type ToolHarnessWarningPayload, type ToolPermissionDeniedPayload, ToolRegistry, type ToolResult, type ToolResultRequest, type TurnUsage, type UIComponentsConfig, type UserUnavailablePayload, type WireBlockDelta, type WireBlockDeltaPayload, type WireBlockKind, type WireBlockStart, type WireBlockStatus, type WireBlockStop, type WireCustomEvent, type WireErrorEvent, type WireEvent, type WireInputArgDelta, type WireInputDelta, type WireKeepalive, type WireMessageStart, type WireMessageStop, type WireOutputDelta, type WireRetryEvent, type WireSignatureDelta, type WireStallWarning, type WireStatusDelta, type WireStopReason, type WireTextDelta, type WireThinkingDelta, type WorkspaceReadyPayload, generateId, isEmbeddedResource, mapSseToChat, parseEmbeddedResource, replayEvents, streamJobSSE, translateDelta };
|
package/dist/index.js
CHANGED
|
@@ -491,6 +491,14 @@ var AstralformClient = class {
|
|
|
491
491
|
llmProvider: raw.llm_provider,
|
|
492
492
|
llmModel: raw.llm_model,
|
|
493
493
|
message: raw.message,
|
|
494
|
+
// Defaults to [] rather than undefined so a caller can iterate without a
|
|
495
|
+
// guard, and so a server that predates the field behaves as "reports
|
|
496
|
+
// nothing" instead of throwing. Entries missing a key are dropped: a
|
|
497
|
+
// capability with no name cannot be matched against and would render as
|
|
498
|
+
// an unlabelled row.
|
|
499
|
+
capabilities: (raw.capabilities ?? []).flatMap(
|
|
500
|
+
(c) => typeof c?.key === "string" && c.key.length > 0 ? [{ key: c.key, enabled: Boolean(c.enabled) }] : []
|
|
501
|
+
),
|
|
494
502
|
uiComponents: {
|
|
495
503
|
enabled: Boolean(ui.enabled),
|
|
496
504
|
protocol: ui.protocol ?? null,
|
|
@@ -1773,11 +1781,16 @@ var ChatSession = class {
|
|
|
1773
1781
|
* ``message_start`` in the stream (e.g. ``memory_recall`` from prompt prep),
|
|
1774
1782
|
* so leading with the prompt keeps the turn in order.
|
|
1775
1783
|
*/
|
|
1776
|
-
replayTurn(id, events, userMessageContent) {
|
|
1784
|
+
replayTurn(id, events, userMessageContent, userMessageId, isSteer = false) {
|
|
1777
1785
|
this.conversationId = id;
|
|
1778
1786
|
this.resetStreamingState();
|
|
1779
1787
|
if (userMessageContent) {
|
|
1780
|
-
this.emit({
|
|
1788
|
+
this.emit({
|
|
1789
|
+
type: "user_message",
|
|
1790
|
+
content: userMessageContent,
|
|
1791
|
+
...userMessageId ? { id: userMessageId } : {},
|
|
1792
|
+
...isSteer ? { steer: true } : {}
|
|
1793
|
+
});
|
|
1781
1794
|
}
|
|
1782
1795
|
for (const ev of events) {
|
|
1783
1796
|
const type = ev.data.type || ev.event;
|
|
@@ -1890,6 +1903,64 @@ var ChatSession = class {
|
|
|
1890
1903
|
}
|
|
1891
1904
|
};
|
|
1892
1905
|
|
|
1906
|
+
// src/restore-plan.ts
|
|
1907
|
+
function planRestore(args) {
|
|
1908
|
+
const { completedJobs, userMessages } = args;
|
|
1909
|
+
const byId = /* @__PURE__ */ new Map();
|
|
1910
|
+
userMessages.forEach((m, i) => {
|
|
1911
|
+
if (m.id) byId.set(m.id, i);
|
|
1912
|
+
});
|
|
1913
|
+
const linkOf = (j) => j.message_id ? byId.get(j.message_id) : void 0;
|
|
1914
|
+
const positional = (jobs, msgs) => jobs.map((job, i) => ({
|
|
1915
|
+
kind: "turn",
|
|
1916
|
+
jobId: job.job_id,
|
|
1917
|
+
content: msgs[i]?.content,
|
|
1918
|
+
messageId: msgs[i]?.id
|
|
1919
|
+
}));
|
|
1920
|
+
const firstLinked = completedJobs.findIndex((j) => linkOf(j) !== void 0);
|
|
1921
|
+
if (firstLinked === -1) {
|
|
1922
|
+
return positional(completedJobs, userMessages);
|
|
1923
|
+
}
|
|
1924
|
+
const cutover = linkOf(completedJobs[firstLinked]);
|
|
1925
|
+
const steps = positional(
|
|
1926
|
+
completedJobs.slice(0, firstLinked),
|
|
1927
|
+
userMessages.slice(0, cutover)
|
|
1928
|
+
);
|
|
1929
|
+
let cursor = cutover;
|
|
1930
|
+
const isSteer = (m) => !!m?.id && !completedJobs.some((j) => j.message_id === m.id);
|
|
1931
|
+
const drainTo = (stopAt) => {
|
|
1932
|
+
while (cursor < stopAt) {
|
|
1933
|
+
const m = userMessages[cursor++];
|
|
1934
|
+
if (isSteer(m)) {
|
|
1935
|
+
steps.push({ kind: "steer", content: m.content, messageId: m.id });
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
cursor = stopAt + 1;
|
|
1939
|
+
};
|
|
1940
|
+
for (const job of completedJobs.slice(firstLinked)) {
|
|
1941
|
+
const at = linkOf(job);
|
|
1942
|
+
if (at !== void 0) {
|
|
1943
|
+
drainTo(at);
|
|
1944
|
+
const prompt = userMessages[at];
|
|
1945
|
+
steps.push({
|
|
1946
|
+
kind: "turn",
|
|
1947
|
+
jobId: job.job_id,
|
|
1948
|
+
content: prompt.content,
|
|
1949
|
+
messageId: prompt.id
|
|
1950
|
+
});
|
|
1951
|
+
continue;
|
|
1952
|
+
}
|
|
1953
|
+
steps.push({ kind: "turn", jobId: job.job_id });
|
|
1954
|
+
}
|
|
1955
|
+
for (let i = cursor; i < userMessages.length; i++) {
|
|
1956
|
+
const m = userMessages[i];
|
|
1957
|
+
if (isSteer(m)) {
|
|
1958
|
+
steps.push({ kind: "steer", content: m.content, messageId: m.id });
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
return steps;
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1893
1964
|
// src/types.ts
|
|
1894
1965
|
var ChatEventType = {
|
|
1895
1966
|
// Connection lifecycle (SDK-local, not wire)
|
|
@@ -2158,16 +2229,40 @@ var StreamManager = class {
|
|
|
2158
2229
|
const userMessages = this.session.messages.filter(
|
|
2159
2230
|
(m) => m.role === "user"
|
|
2160
2231
|
);
|
|
2232
|
+
const plan = planRestore({
|
|
2233
|
+
completedJobs: completedJobs.map((j) => ({
|
|
2234
|
+
job_id: j.job_id,
|
|
2235
|
+
message_id: j.message_id
|
|
2236
|
+
})),
|
|
2237
|
+
userMessages: userMessages.map((m) => ({
|
|
2238
|
+
id: m.id,
|
|
2239
|
+
content: m.content
|
|
2240
|
+
}))
|
|
2241
|
+
});
|
|
2161
2242
|
const eventLists = await Promise.all(
|
|
2162
2243
|
completedJobs.map(
|
|
2163
2244
|
(job) => this.session.client.getConversationEvents(conversationId, job.job_id).catch(() => [])
|
|
2164
2245
|
)
|
|
2165
2246
|
);
|
|
2166
|
-
|
|
2247
|
+
const eventsByJobId = new Map(
|
|
2248
|
+
completedJobs.map((job, i) => [job.job_id, eventLists[i] ?? []])
|
|
2249
|
+
);
|
|
2250
|
+
for (const step of plan) {
|
|
2251
|
+
if (step.kind === "steer") {
|
|
2252
|
+
this.session.replayTurn(
|
|
2253
|
+
conversationId,
|
|
2254
|
+
[],
|
|
2255
|
+
step.content,
|
|
2256
|
+
step.messageId,
|
|
2257
|
+
true
|
|
2258
|
+
);
|
|
2259
|
+
continue;
|
|
2260
|
+
}
|
|
2167
2261
|
this.session.replayTurn(
|
|
2168
2262
|
conversationId,
|
|
2169
|
-
|
|
2170
|
-
|
|
2263
|
+
eventsByJobId.get(step.jobId) ?? [],
|
|
2264
|
+
step.content,
|
|
2265
|
+
step.messageId
|
|
2171
2266
|
);
|
|
2172
2267
|
}
|
|
2173
2268
|
if (completedJobs.length > 0) {
|