@botiverse/oar 0.5.1 → 0.7.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/README.md +10 -33
- package/dist/contracts/records.d.ts +41 -11
- package/dist/contracts/records.d.ts.map +1 -1
- package/dist/contracts/session.d.ts +51 -15
- package/dist/contracts/session.d.ts.map +1 -1
- package/dist/contracts/status.d.ts +25 -0
- package/dist/contracts/status.d.ts.map +1 -0
- package/dist/contracts/status.js +2 -0
- package/dist/contracts/status.js.map +1 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/kernel.d.ts +12 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +11 -0
- package/dist/kernel.js.map +1 -0
- package/dist/observe/agent-status.d.ts +4 -18
- package/dist/observe/agent-status.d.ts.map +1 -1
- package/dist/observe/agent-status.js +41 -0
- package/dist/observe/agent-status.js.map +1 -1
- package/dist/observe/conversation.d.ts +44 -0
- package/dist/observe/conversation.d.ts.map +1 -0
- package/dist/observe/conversation.js +95 -0
- package/dist/observe/conversation.js.map +1 -0
- package/dist/observe/events.d.ts.map +1 -1
- package/dist/observe/events.js +1 -2
- package/dist/observe/events.js.map +1 -1
- package/dist/observe/index.d.ts +7 -3
- package/dist/observe/index.d.ts.map +1 -1
- package/dist/observe/index.js +4 -2
- package/dist/observe/index.js.map +1 -1
- package/dist/observe/session-view-events.d.ts +11 -0
- package/dist/observe/session-view-events.d.ts.map +1 -0
- package/dist/observe/session-view-events.js +228 -0
- package/dist/observe/session-view-events.js.map +1 -0
- package/dist/observe/session-view-fold.d.ts +56 -0
- package/dist/observe/session-view-fold.d.ts.map +1 -0
- package/dist/observe/session-view-fold.js +154 -0
- package/dist/observe/session-view-fold.js.map +1 -0
- package/dist/observe/session-view.d.ts +151 -0
- package/dist/observe/session-view.d.ts.map +1 -0
- package/dist/observe/session-view.js +80 -0
- package/dist/observe/session-view.js.map +1 -0
- package/dist/observe/turns.d.ts +45 -7
- package/dist/observe/turns.d.ts.map +1 -1
- package/dist/observe/turns.js +77 -7
- package/dist/observe/turns.js.map +1 -1
- package/dist/runtimes/claude/projection.d.ts.map +1 -1
- package/dist/runtimes/claude/projection.js +10 -3
- package/dist/runtimes/claude/projection.js.map +1 -1
- package/dist/runtimes/claude/session.d.ts.map +1 -1
- package/dist/runtimes/claude/session.js +17 -16
- package/dist/runtimes/claude/session.js.map +1 -1
- package/dist/runtimes/codex/item-detail.d.ts +2 -0
- package/dist/runtimes/codex/item-detail.d.ts.map +1 -1
- package/dist/runtimes/codex/item-detail.js +12 -5
- package/dist/runtimes/codex/item-detail.js.map +1 -1
- package/dist/runtimes/codex/projection.d.ts.map +1 -1
- package/dist/runtimes/codex/projection.js +20 -5
- package/dist/runtimes/codex/projection.js.map +1 -1
- package/dist/runtimes/codex/session.js +17 -17
- package/dist/runtimes/codex/session.js.map +1 -1
- package/dist/runtimes/pi/installation.d.ts.map +1 -1
- package/dist/runtimes/pi/installation.js +3 -1
- package/dist/runtimes/pi/installation.js.map +1 -1
- package/dist/runtimes/pi/projection.d.ts.map +1 -1
- package/dist/runtimes/pi/projection.js +19 -2
- package/dist/runtimes/pi/projection.js.map +1 -1
- package/dist/runtimes/pi/session.d.ts.map +1 -1
- package/dist/runtimes/pi/session.js +10 -10
- package/dist/runtimes/pi/session.js.map +1 -1
- package/dist/shared/acp/projection.d.ts.map +1 -1
- package/dist/shared/acp/projection.js +30 -1
- package/dist/shared/acp/projection.js.map +1 -1
- package/dist/shared/acp/session.js +6 -6
- package/dist/shared/acp/session.js.map +1 -1
- package/dist/shared/acp/terminal.d.ts.map +1 -1
- package/dist/shared/acp/terminal.js +9 -2
- package/dist/shared/acp/terminal.js.map +1 -1
- package/dist/shared/acp/turns.js +2 -2
- package/dist/shared/acp/turns.js.map +1 -1
- package/dist/shared/executable/index.d.ts +1 -1
- package/dist/shared/executable/index.d.ts.map +1 -1
- package/dist/shared/executable/index.js +1 -1
- package/dist/shared/executable/index.js.map +1 -1
- package/dist/shared/executable/process.d.ts +48 -1
- package/dist/shared/executable/process.d.ts.map +1 -1
- package/dist/shared/executable/process.js +66 -1
- package/dist/shared/executable/process.js.map +1 -1
- package/dist/shared/seal-session.d.ts +14 -6
- package/dist/shared/seal-session.d.ts.map +1 -1
- package/dist/shared/seal-session.js +49 -13
- package/dist/shared/seal-session.js.map +1 -1
- package/dist/shared/session-kernel.d.ts +1 -0
- package/dist/shared/session-kernel.d.ts.map +1 -1
- package/dist/shared/session-kernel.js +3 -3
- package/dist/shared/session-kernel.js.map +1 -1
- package/dist/voyage.d.ts.map +1 -1
- package/dist/voyage.js +2 -1
- package/dist/voyage.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
export function draftOf(state) {
|
|
2
|
+
return {
|
|
3
|
+
messages: [...state.messages],
|
|
4
|
+
openTurn: state.openTurn,
|
|
5
|
+
turn: null,
|
|
6
|
+
pendingRequests: [...state.pendingRequests],
|
|
7
|
+
model: state.model,
|
|
8
|
+
context: state.context,
|
|
9
|
+
exited: state.exited,
|
|
10
|
+
usageByAgent: new Map(state.usageByAgent),
|
|
11
|
+
rootSessionId: state.rootSessionId,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function assemble(draft, conversation, status) {
|
|
15
|
+
const byAgent = [...draft.usageByAgent.values()];
|
|
16
|
+
const total = byAgent.length === 0
|
|
17
|
+
? null
|
|
18
|
+
: byAgent.reduce((sum, entry) => ({
|
|
19
|
+
input: sum.input + entry.tokens.input,
|
|
20
|
+
output: sum.output + entry.tokens.output,
|
|
21
|
+
}), { input: 0, output: 0 });
|
|
22
|
+
const onlyRoot = byAgent.every((entry) => entry.agentPath.length === 0);
|
|
23
|
+
const usage = total === null ? { total: null } : (byAgent.length <= 1 && onlyRoot ? { total } : { total, byAgent });
|
|
24
|
+
return {
|
|
25
|
+
messages: draft.messages,
|
|
26
|
+
openTurn: draft.openTurn,
|
|
27
|
+
status,
|
|
28
|
+
model: draft.model,
|
|
29
|
+
context: draft.context,
|
|
30
|
+
usage,
|
|
31
|
+
pendingRequests: draft.pendingRequests,
|
|
32
|
+
exited: draft.exited,
|
|
33
|
+
conversation,
|
|
34
|
+
rootSessionId: draft.rootSessionId,
|
|
35
|
+
usageByAgent: draft.usageByAgent,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function sameLane(section, sessionId, agentPath) {
|
|
39
|
+
return (section.sessionId === sessionId &&
|
|
40
|
+
section.agentPath.length === agentPath.length &&
|
|
41
|
+
section.agentPath.every((segment, index) => segment === agentPath[index]));
|
|
42
|
+
}
|
|
43
|
+
/** The open turn, cloned for writing at most once per record. */
|
|
44
|
+
export function turnForWrite(draft) {
|
|
45
|
+
if (draft.openTurn === -1) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (draft.turn === null) {
|
|
49
|
+
const current = draft.messages[draft.openTurn];
|
|
50
|
+
if (current?.kind !== "turn") {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const clone = { ...current, sections: [...current.sections] };
|
|
54
|
+
draft.messages[draft.openTurn] = clone;
|
|
55
|
+
draft.turn = clone;
|
|
56
|
+
}
|
|
57
|
+
return draft.turn;
|
|
58
|
+
}
|
|
59
|
+
export function beginTurn(draft, id, openedBy) {
|
|
60
|
+
const turn = {
|
|
61
|
+
kind: "turn",
|
|
62
|
+
id,
|
|
63
|
+
...(openedBy === undefined ? {} : { openedBy }),
|
|
64
|
+
sections: [],
|
|
65
|
+
};
|
|
66
|
+
draft.messages.push(turn);
|
|
67
|
+
draft.openTurn = draft.messages.length - 1;
|
|
68
|
+
draft.turn = turn;
|
|
69
|
+
}
|
|
70
|
+
/** Seal the current segment without an outcome; later content opens a new one. */
|
|
71
|
+
export function sealTurn(draft) {
|
|
72
|
+
draft.openTurn = -1;
|
|
73
|
+
draft.turn = null;
|
|
74
|
+
}
|
|
75
|
+
/** The last section of the open turn when it matches the lane, else a new one. */
|
|
76
|
+
function sectionFor(draft, sessionId, agentPath) {
|
|
77
|
+
const turn = turnForWrite(draft);
|
|
78
|
+
if (turn === null) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const last = turn.sections.at(-1);
|
|
82
|
+
if (last !== undefined && sameLane(last, sessionId, agentPath)) {
|
|
83
|
+
const cloned = { ...last, parts: [...last.parts] };
|
|
84
|
+
turn.sections[turn.sections.length - 1] = cloned;
|
|
85
|
+
return cloned;
|
|
86
|
+
}
|
|
87
|
+
const created = { sessionId, agentPath, parts: [] };
|
|
88
|
+
turn.sections.push(created);
|
|
89
|
+
return created;
|
|
90
|
+
}
|
|
91
|
+
/** Open a segment when none is running, then give the event's lane. */
|
|
92
|
+
export function laneFor(draft, event, streamId) {
|
|
93
|
+
if (draft.openTurn === -1) {
|
|
94
|
+
beginTurn(draft, `turn:${streamId}:${event.sessionId}:${event.seq}`);
|
|
95
|
+
}
|
|
96
|
+
return sectionFor(draft, event.sessionId, event.agentPath);
|
|
97
|
+
}
|
|
98
|
+
export function noticePart(draft, event, streamId, notice) {
|
|
99
|
+
laneFor(draft, event, streamId)?.parts.push({ kind: "notice", notice });
|
|
100
|
+
}
|
|
101
|
+
/** Upsert a user input; a NEW input seals the open segment (seq order is render order). */
|
|
102
|
+
export function upsertInput(draft, input) {
|
|
103
|
+
const id = `in:${input.id}`;
|
|
104
|
+
const index = draft.messages.findIndex((message) => message.id === id);
|
|
105
|
+
const message = { kind: "input", id, input };
|
|
106
|
+
if (index === -1) {
|
|
107
|
+
draft.messages.push(message);
|
|
108
|
+
sealTurn(draft);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
draft.messages[index] = message;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export function markRequestAnswered(draft, requestId) {
|
|
115
|
+
const index = draft.pendingRequests.findIndex((request) => request.requestId === requestId);
|
|
116
|
+
if (index !== -1) {
|
|
117
|
+
draft.pendingRequests.splice(index, 1);
|
|
118
|
+
}
|
|
119
|
+
for (let m = draft.messages.length - 1; m >= 0; m -= 1) {
|
|
120
|
+
const message = draft.messages[m];
|
|
121
|
+
if (message?.kind !== "turn") {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
for (let s = 0; s < message.sections.length; s += 1) {
|
|
125
|
+
const section = message.sections[s];
|
|
126
|
+
const partIndex = section?.parts.findIndex((part) => part.kind === "app_request" && part.requestId === requestId) ?? -1;
|
|
127
|
+
const part = partIndex === -1 ? undefined : section?.parts[partIndex];
|
|
128
|
+
if (section === undefined || part?.kind !== "app_request") {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const parts = [...section.parts];
|
|
132
|
+
parts[partIndex] = { ...part, answered: true };
|
|
133
|
+
const sections = [...message.sections];
|
|
134
|
+
sections[s] = { ...section, parts };
|
|
135
|
+
draft.messages[m] = { ...message, sections };
|
|
136
|
+
if (m === draft.openTurn) {
|
|
137
|
+
draft.turn = null;
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/** Drop a turn the runtime says never began (rejected prompt), when still empty. */
|
|
144
|
+
export function removeEmptyTurn(draft, requestId) {
|
|
145
|
+
if (draft.openTurn === -1) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const message = draft.messages[draft.openTurn];
|
|
149
|
+
if (message?.kind === "turn" && message.openedBy === requestId && message.sections.length === 0) {
|
|
150
|
+
draft.messages.splice(draft.openTurn, 1);
|
|
151
|
+
draft.openTurn = -1;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=session-view-fold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-view-fold.js","sourceRoot":"","sources":["../../src/observe/session-view-fold.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { ContextUsage, ControlAction, Cursor, Event, RawEvent, ReasoningContent, Session, SessionUsage, TokenTotals, TurnOutcome, Unsubscribe } from "../contracts/session.js";
|
|
2
|
+
import { type AgentStatus } from "./agent-status.js";
|
|
3
|
+
import { type ConversationInput, type ConversationState } from "./conversation.js";
|
|
4
|
+
/**
|
|
5
|
+
* The chat-UI projection: one `SessionView` is everything a conversation
|
|
6
|
+
* surface needs — grouped messages, agent status, model/usage/context, and
|
|
7
|
+
* the runtime requests still awaiting an answer. Pure over the record
|
|
8
|
+
* stream (docs/design/chat-ui.md): replayable from a log, no clock, no IO.
|
|
9
|
+
*
|
|
10
|
+
* Grouping rules, all derived never synthesized:
|
|
11
|
+
* - A TURN is a display segment: it opens on its prompt request or on the
|
|
12
|
+
* first turn-content event while none is open (adopted: queued input
|
|
13
|
+
* consumed, mid-turn subscriber, replay slice). A rejected prompt removes
|
|
14
|
+
* its empty turn — the turn never began (same rule as `reduceStatus`).
|
|
15
|
+
* `turn_ended` of the ROOT session stamps the open segment; an input
|
|
16
|
+
* arriving mid-turn seals the current segment so seq order stays the
|
|
17
|
+
* render order, and later content opens a new segment.
|
|
18
|
+
* - A SECTION is a contiguous run of one lane (`sessionId`, `agentPath`)
|
|
19
|
+
* inside a turn. Sub-agent and child-session activity nests inside the
|
|
20
|
+
* parent turn as sections; a child session's own `turn_ended` degrades
|
|
21
|
+
* to a notice part, it never closes the root turn.
|
|
22
|
+
* - An exited stream never stamps a fabricated outcome on an open turn.
|
|
23
|
+
*/
|
|
24
|
+
export type ViewNotice = {
|
|
25
|
+
readonly cause: "compaction_started";
|
|
26
|
+
readonly trigger?: string;
|
|
27
|
+
} | {
|
|
28
|
+
readonly cause: "compaction_ended";
|
|
29
|
+
readonly outcome: "completed" | "aborted" | "failed";
|
|
30
|
+
readonly trigger?: string;
|
|
31
|
+
readonly reason?: string;
|
|
32
|
+
} | {
|
|
33
|
+
readonly cause: "retry";
|
|
34
|
+
readonly attempt: number;
|
|
35
|
+
readonly maxAttempts?: number;
|
|
36
|
+
readonly delayMs?: number;
|
|
37
|
+
readonly reason?: string;
|
|
38
|
+
} | {
|
|
39
|
+
readonly cause: "control_rejected";
|
|
40
|
+
readonly action: ControlAction;
|
|
41
|
+
readonly reason: string;
|
|
42
|
+
} | {
|
|
43
|
+
readonly cause: "child_turn_ended";
|
|
44
|
+
readonly outcome: TurnOutcome;
|
|
45
|
+
} | {
|
|
46
|
+
readonly cause: "exited";
|
|
47
|
+
readonly code: number | null;
|
|
48
|
+
};
|
|
49
|
+
export type ViewPart = {
|
|
50
|
+
readonly kind: "text";
|
|
51
|
+
readonly text: string;
|
|
52
|
+
} | {
|
|
53
|
+
readonly kind: "reasoning";
|
|
54
|
+
readonly content: ReasoningContent;
|
|
55
|
+
} | {
|
|
56
|
+
readonly kind: "tool";
|
|
57
|
+
readonly callId: string;
|
|
58
|
+
readonly tool: string;
|
|
59
|
+
readonly input?: string;
|
|
60
|
+
readonly output?: string;
|
|
61
|
+
readonly result: "running" | "ok" | "failed" | "ended";
|
|
62
|
+
} | {
|
|
63
|
+
readonly kind: "notice";
|
|
64
|
+
readonly notice: ViewNotice;
|
|
65
|
+
} | {
|
|
66
|
+
readonly kind: "app_request";
|
|
67
|
+
readonly requestId: string;
|
|
68
|
+
readonly type: string;
|
|
69
|
+
readonly answered: boolean;
|
|
70
|
+
readonly body?: unknown;
|
|
71
|
+
};
|
|
72
|
+
/** One contiguous lane run inside a turn. */
|
|
73
|
+
export interface ViewSection {
|
|
74
|
+
readonly sessionId: string;
|
|
75
|
+
readonly agentPath: readonly string[];
|
|
76
|
+
readonly parts: readonly ViewPart[];
|
|
77
|
+
}
|
|
78
|
+
export interface ViewTurn {
|
|
79
|
+
readonly kind: "turn";
|
|
80
|
+
readonly id: string;
|
|
81
|
+
/** The prompt request that opened the segment; absent for adopted ones. */
|
|
82
|
+
readonly openedBy?: string;
|
|
83
|
+
readonly sections: readonly ViewSection[];
|
|
84
|
+
/** The runtime's own turn end. Absent on sealed segments and interrupted turns. */
|
|
85
|
+
readonly outcome?: TurnOutcome;
|
|
86
|
+
}
|
|
87
|
+
export type ViewMessage = {
|
|
88
|
+
readonly kind: "input";
|
|
89
|
+
readonly id: string;
|
|
90
|
+
readonly input: ConversationInput;
|
|
91
|
+
} | ViewTurn | {
|
|
92
|
+
readonly kind: "notice";
|
|
93
|
+
readonly id: string;
|
|
94
|
+
readonly notice: ViewNotice;
|
|
95
|
+
};
|
|
96
|
+
/** A runtime→app request still awaiting an answer (or the record of one). */
|
|
97
|
+
export interface PendingRequest {
|
|
98
|
+
readonly requestId: string;
|
|
99
|
+
readonly type: string;
|
|
100
|
+
readonly sessionId: string;
|
|
101
|
+
readonly agentPath: readonly string[];
|
|
102
|
+
readonly seq: number;
|
|
103
|
+
/** The `toApp` request body verbatim; undefined when folded from flat events. */
|
|
104
|
+
readonly body?: unknown;
|
|
105
|
+
}
|
|
106
|
+
export interface AgentTokens {
|
|
107
|
+
readonly agentPath: readonly string[];
|
|
108
|
+
readonly tokens: TokenTotals;
|
|
109
|
+
}
|
|
110
|
+
export interface SessionView {
|
|
111
|
+
readonly messages: readonly ViewMessage[];
|
|
112
|
+
/** Index of the unsealed turn segment in `messages`; -1 when none. */
|
|
113
|
+
readonly openTurn: number;
|
|
114
|
+
readonly status: AgentStatus;
|
|
115
|
+
readonly model: string | null;
|
|
116
|
+
readonly context: ContextUsage | null;
|
|
117
|
+
readonly usage: SessionUsage;
|
|
118
|
+
readonly pendingRequests: readonly PendingRequest[];
|
|
119
|
+
/** The last observed process exit, when the stream recorded one. */
|
|
120
|
+
readonly exited: {
|
|
121
|
+
readonly code: number | null;
|
|
122
|
+
} | null;
|
|
123
|
+
/** The fold internals, exposed like `ConversationState`: all derivable. */
|
|
124
|
+
readonly conversation: ConversationState;
|
|
125
|
+
/** sessionId of the latest prompt request: whose `turn_ended` closes turns. */
|
|
126
|
+
readonly rootSessionId: string | undefined;
|
|
127
|
+
readonly usageByAgent: ReadonlyMap<string, AgentTokens>;
|
|
128
|
+
}
|
|
129
|
+
export declare function initialSessionView(): SessionView;
|
|
130
|
+
/**
|
|
131
|
+
* Fold one record into the view. `streamId` scopes input/request identity the
|
|
132
|
+
* same way it does for `reduceConversation`: one value per native stream,
|
|
133
|
+
* changed across resume so restarted seq domains never collide.
|
|
134
|
+
*/
|
|
135
|
+
export declare function reduceSessionView(previous: SessionView, record: RawEvent, streamId?: string): SessionView;
|
|
136
|
+
/**
|
|
137
|
+
* The same fold for pre-flattened `Event`s — `session.events()` subscribers
|
|
138
|
+
* and logs that predate record envelopes. Input facts do not arrive this way;
|
|
139
|
+
* feed them through `reduceSessionViewInput` or use the record path.
|
|
140
|
+
*/
|
|
141
|
+
export declare function reduceSessionViewEvent(previous: SessionView, event: Event, streamId?: string): SessionView;
|
|
142
|
+
/** Upsert a user input from a non-record source (an app's own submission log). */
|
|
143
|
+
export declare function reduceSessionViewInput(previous: SessionView, input: ConversationInput): SessionView;
|
|
144
|
+
/** Replay a whole record log into a view. One `streamId` per call. */
|
|
145
|
+
export declare function viewOf(records: readonly RawEvent[], streamId?: string): SessionView;
|
|
146
|
+
/**
|
|
147
|
+
* The composed subscriber: folds the retained prefix, pushes the view on
|
|
148
|
+
* every record after `cursor`. Mirrors `observeConversation`.
|
|
149
|
+
*/
|
|
150
|
+
export declare function observeSessionView(session: Session, observer: (view: SessionView) => void, cursor?: Cursor): Unsubscribe;
|
|
151
|
+
//# sourceMappingURL=session-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-view.d.ts","sourceRoot":"","sources":["../../src/observe/session-view.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { initialStatus, reduceStatus } from "./agent-status.js";
|
|
2
|
+
import { initialConversation, reduceConversation, } from "./conversation.js";
|
|
3
|
+
import { assemble, draftOf, upsertInput } from "./session-view-fold.js";
|
|
4
|
+
import { foldEvent, recordFacts } from "./session-view-events.js";
|
|
5
|
+
export function initialSessionView() {
|
|
6
|
+
return {
|
|
7
|
+
messages: [],
|
|
8
|
+
openTurn: -1,
|
|
9
|
+
status: initialStatus,
|
|
10
|
+
model: null,
|
|
11
|
+
context: null,
|
|
12
|
+
usage: { total: null },
|
|
13
|
+
pendingRequests: [],
|
|
14
|
+
exited: null,
|
|
15
|
+
conversation: initialConversation(),
|
|
16
|
+
rootSessionId: undefined,
|
|
17
|
+
usageByAgent: new Map(),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Fold one record into the view. `streamId` scopes input/request identity the
|
|
22
|
+
* same way it does for `reduceConversation`: one value per native stream,
|
|
23
|
+
* changed across resume so restarted seq domains never collide.
|
|
24
|
+
*/
|
|
25
|
+
export function reduceSessionView(previous, record, streamId = "") {
|
|
26
|
+
const draft = draftOf(previous);
|
|
27
|
+
draft.rootSessionId ??= record.sessionId;
|
|
28
|
+
if (record.kind === "request" &&
|
|
29
|
+
record.direction === "toRuntime" &&
|
|
30
|
+
record.body.kind === "prompt") {
|
|
31
|
+
draft.rootSessionId = record.sessionId;
|
|
32
|
+
}
|
|
33
|
+
const status = reduceStatus(previous.status, record, draft.rootSessionId);
|
|
34
|
+
const conversation = reduceConversation(previous.conversation, record, streamId);
|
|
35
|
+
for (const update of conversation.updates) {
|
|
36
|
+
if (update.kind === "input") {
|
|
37
|
+
upsertInput(draft, update.input);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
foldEvent(draft, update.event, streamId);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
recordFacts(draft, record, streamId);
|
|
44
|
+
return assemble(draft, conversation, status);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The same fold for pre-flattened `Event`s — `session.events()` subscribers
|
|
48
|
+
* and logs that predate record envelopes. Input facts do not arrive this way;
|
|
49
|
+
* feed them through `reduceSessionViewInput` or use the record path.
|
|
50
|
+
*/
|
|
51
|
+
export function reduceSessionViewEvent(previous, event, streamId = "") {
|
|
52
|
+
const draft = draftOf(previous);
|
|
53
|
+
draft.rootSessionId ??= event.sessionId;
|
|
54
|
+
foldEvent(draft, event, streamId);
|
|
55
|
+
return assemble(draft, previous.conversation, previous.status);
|
|
56
|
+
}
|
|
57
|
+
/** Upsert a user input from a non-record source (an app's own submission log). */
|
|
58
|
+
export function reduceSessionViewInput(previous, input) {
|
|
59
|
+
const draft = draftOf(previous);
|
|
60
|
+
upsertInput(draft, input);
|
|
61
|
+
return assemble(draft, previous.conversation, previous.status);
|
|
62
|
+
}
|
|
63
|
+
/** Replay a whole record log into a view. One `streamId` per call. */
|
|
64
|
+
export function viewOf(records, streamId = "") {
|
|
65
|
+
return records.reduce((state, record) => reduceSessionView(state, record, streamId), initialSessionView());
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The composed subscriber: folds the retained prefix, pushes the view on
|
|
69
|
+
* every record after `cursor`. Mirrors `observeConversation`.
|
|
70
|
+
*/
|
|
71
|
+
export function observeSessionView(session, observer, cursor) {
|
|
72
|
+
let state = initialSessionView();
|
|
73
|
+
return session.rawEvents((record) => {
|
|
74
|
+
state = reduceSessionView(state, record, session.id);
|
|
75
|
+
if (record.seq > (cursor?.afterSeq ?? -1)) {
|
|
76
|
+
observer(state);
|
|
77
|
+
}
|
|
78
|
+
}, { sessionId: session.id, afterSeq: -1 });
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=session-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-view.js","sourceRoot":"","sources":["../../src/observe/session-view.ts"],"names":[],"mappings":"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"}
|
package/dist/observe/turns.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ControlOutcome, RejectionCode, Session, RawEvent, TurnOutcome } from "../contracts/session.js";
|
|
2
2
|
/**
|
|
3
3
|
* Turn helpers for consumers. A turn is a SPAN on the stream, not a control
|
|
4
4
|
* object: it starts at the prompt request record and ends at the runtime's own
|
|
@@ -23,15 +23,53 @@ export declare function turnEndAfter(records: readonly RawEvent[], afterSeq: num
|
|
|
23
23
|
* A derived child session's turn end never satisfies it.
|
|
24
24
|
*/
|
|
25
25
|
export declare function awaitTurnEnd(session: Session, afterSeq: number): Promise<TurnOutcome>;
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Resolve once the root agent is idle: at once (null) when `session.status()`
|
|
28
|
+
* already says so, otherwise with the outcome of the running turn when it
|
|
29
|
+
* ends. The status is read and the subscription placed through one cursor,
|
|
30
|
+
* so a turn ending in between is not missed. Nothing is prompted here: a
|
|
31
|
+
* runtime that runs a queued input as a turn of its own makes the next
|
|
32
|
+
* prompt `busy`, and this is how a caller waits that out instead of polling.
|
|
33
|
+
*/
|
|
34
|
+
export declare function awaitIdle(session: Session): Promise<TurnOutcome | null>;
|
|
35
|
+
export interface PromptRunOptions {
|
|
36
|
+
/** Abort the turn when it has not ended after this long; the run then reports `interrupted` with the runtime's own outcome. */
|
|
37
|
+
readonly timeoutMs?: number;
|
|
38
|
+
/** Abort the turn when this fires (a caller-side cancel), reported the same way. */
|
|
39
|
+
readonly signal?: AbortSignal;
|
|
40
|
+
}
|
|
41
|
+
export type PromptRun =
|
|
42
|
+
/** The prompt did not begin a turn (busy, dead runtime); nothing was waited for. */
|
|
43
|
+
{
|
|
27
44
|
readonly kind: "rejected";
|
|
28
|
-
readonly result:
|
|
45
|
+
readonly result: ControlOutcome;
|
|
46
|
+
readonly code: RejectionCode;
|
|
29
47
|
readonly reason: string;
|
|
30
|
-
}
|
|
48
|
+
}
|
|
49
|
+
/** The runtime ended the turn on its own. `text` is the root agent's text of this turn, concatenated. */
|
|
50
|
+
| {
|
|
31
51
|
readonly kind: "ended";
|
|
32
|
-
readonly result:
|
|
52
|
+
readonly result: ControlOutcome;
|
|
53
|
+
readonly outcome: TurnOutcome;
|
|
54
|
+
readonly text: string;
|
|
55
|
+
}
|
|
56
|
+
/** The caller's timeout or signal fired first and the abort was taken over; `outcome` is still the runtime's own turn end. */
|
|
57
|
+
| {
|
|
58
|
+
readonly kind: "interrupted";
|
|
59
|
+
readonly by: "timeout" | "signal";
|
|
60
|
+
readonly result: ControlOutcome;
|
|
33
61
|
readonly outcome: TurnOutcome;
|
|
62
|
+
readonly text: string;
|
|
34
63
|
};
|
|
35
|
-
/**
|
|
36
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Prompt, then wait for the runtime to end the turn it opened. A rejected
|
|
66
|
+
* prompt returns without waiting. With `timeoutMs` / `signal`, a turn still
|
|
67
|
+
* running when either fires is aborted; the result is `interrupted` only when
|
|
68
|
+
* that abort was taken over. An abort the runtime refuses because the turn
|
|
69
|
+
* had just ended is the ordinary late-abort race, and the run is `ended`.
|
|
70
|
+
* After an accepted abort the turn's end is awaited with no further limit:
|
|
71
|
+
* the outcome is the runtime's word, and a runtime that never gives it is a
|
|
72
|
+
* liveness problem `observeStalls` reports, not one this helper guesses at.
|
|
73
|
+
*/
|
|
74
|
+
export declare function promptAndWait(session: Session, input: string, options?: PromptRunOptions): Promise<PromptRun>;
|
|
37
75
|
//# sourceMappingURL=turns.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turns.d.ts","sourceRoot":"","sources":["../../src/observe/turns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"turns.d.ts","sourceRoot":"","sources":["../../src/observe/turns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE7G;;;;;;;;;;;GAWG;AAEH;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,WAAW,GAAG,IAAI,CAmBpB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAgB3F;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAO7E;AAED,MAAM,WAAW,gBAAgB;IAC/B,+HAA+H;IAC/H,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,MAAM,SAAS;AACnB,oFAAoF;AAClF;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACvH,yGAAyG;GACvG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACnH,8HAA8H;GAC5H;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,GAAG,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/J;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,CAAC,CA+BvH"}
|
package/dist/observe/turns.js
CHANGED
|
@@ -57,14 +57,84 @@ export async function awaitTurnEnd(session, afterSeq) {
|
|
|
57
57
|
unsubscribe();
|
|
58
58
|
return outcome;
|
|
59
59
|
}
|
|
60
|
-
/**
|
|
61
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Resolve once the root agent is idle: at once (null) when `session.status()`
|
|
62
|
+
* already says so, otherwise with the outcome of the running turn when it
|
|
63
|
+
* ends. The status is read and the subscription placed through one cursor,
|
|
64
|
+
* so a turn ending in between is not missed. Nothing is prompted here: a
|
|
65
|
+
* runtime that runs a queued input as a turn of its own makes the next
|
|
66
|
+
* prompt `busy`, and this is how a caller waits that out instead of polling.
|
|
67
|
+
*/
|
|
68
|
+
export async function awaitIdle(session) {
|
|
69
|
+
const status = session.status();
|
|
70
|
+
if (status.value.kind === "idle") {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const outcome = await awaitTurnEnd(session, status.value.sinceSeq);
|
|
74
|
+
return outcome;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Prompt, then wait for the runtime to end the turn it opened. A rejected
|
|
78
|
+
* prompt returns without waiting. With `timeoutMs` / `signal`, a turn still
|
|
79
|
+
* running when either fires is aborted; the result is `interrupted` only when
|
|
80
|
+
* that abort was taken over. An abort the runtime refuses because the turn
|
|
81
|
+
* had just ended is the ordinary late-abort race, and the run is `ended`.
|
|
82
|
+
* After an accepted abort the turn's end is awaited with no further limit:
|
|
83
|
+
* the outcome is the runtime's word, and a runtime that never gives it is a
|
|
84
|
+
* liveness problem `observeStalls` reports, not one this helper guesses at.
|
|
85
|
+
*/
|
|
86
|
+
export async function promptAndWait(session, input, options = {}) {
|
|
62
87
|
const result = await session.prompt(input);
|
|
63
|
-
if (result.
|
|
64
|
-
|
|
65
|
-
|
|
88
|
+
if (result.kind === "rejected") {
|
|
89
|
+
return { kind: "rejected", result, code: result.code, reason: result.reason };
|
|
90
|
+
}
|
|
91
|
+
let text = "";
|
|
92
|
+
const stopReading = session.rawEvents((record) => {
|
|
93
|
+
if (record.kind === "frame" && record.agentPath.length === 0 && record.sessionId === session.id) {
|
|
94
|
+
for (const event of record.body.events) {
|
|
95
|
+
if (event.kind === "text_delta") {
|
|
96
|
+
text += event.text;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}, { sessionId: session.id, afterSeq: result.seq });
|
|
101
|
+
const limit = armLimits(options);
|
|
102
|
+
try {
|
|
103
|
+
const ended = awaitTurnEnd(session, result.seq);
|
|
104
|
+
const first = await Promise.race([ended, limit.fired]);
|
|
105
|
+
if (typeof first !== "string") {
|
|
106
|
+
return { kind: "ended", result, outcome: first, text };
|
|
107
|
+
}
|
|
108
|
+
const abort = await session.abort();
|
|
109
|
+
const outcome = await ended;
|
|
110
|
+
return abort.kind === "accepted"
|
|
111
|
+
? { kind: "interrupted", by: first, result, outcome, text }
|
|
112
|
+
: { kind: "ended", result, outcome, text };
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
limit.disarm();
|
|
116
|
+
stopReading();
|
|
66
117
|
}
|
|
67
|
-
|
|
68
|
-
|
|
118
|
+
}
|
|
119
|
+
/** The caller's limits as one promise that settles with whichever fires first (never, when none is set), and the disarm for when the turn ends first. */
|
|
120
|
+
function armLimits(options) {
|
|
121
|
+
const { promise: fired, resolve } = Promise.withResolvers();
|
|
122
|
+
const timer = options.timeoutMs === undefined ? null : setTimeout(() => { resolve("timeout"); }, options.timeoutMs);
|
|
123
|
+
const onAbort = () => { resolve("signal"); };
|
|
124
|
+
if (options.signal?.aborted === true) {
|
|
125
|
+
onAbort();
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
fired,
|
|
132
|
+
disarm: () => {
|
|
133
|
+
if (timer !== null) {
|
|
134
|
+
clearTimeout(timer);
|
|
135
|
+
}
|
|
136
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
137
|
+
},
|
|
138
|
+
};
|
|
69
139
|
}
|
|
70
140
|
//# sourceMappingURL=turns.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turns.js","sourceRoot":"","sources":["../../src/observe/turns.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,OAA4B,EAC5B,QAAgB,EAChB,SAAkB;IAElB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,GAAG,IAAI,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1D,SAAS;QACX,CAAC;QACD,IAAI,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAC9D,SAAS;QACX,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;YAC9E,IAAI,KAAK,EAAE,IAAI,KAAK,YAAY,EAAE,CAAC;gBACjC,OAAO,KAAK,CAAC,OAAO,CAAC;YACvB,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;QACjF,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAgB,EAAE,QAAgB;IACnE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,EAAe,CAAC;IAClE,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;QAC/C,IAAI,IAAI,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,GAAG,IAAI,CAAC;YACZ,OAAO,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;IAC9B,WAAW,EAAE,CAAC;IACd,OAAO,OAAO,CAAC;AACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"turns.js","sourceRoot":"","sources":["../../src/observe/turns.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../../src/runtimes/claude/projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAET,YAAY,EACZ,WAAW,EAEZ,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAG3E;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE;AAC7F,sGAAsG;GACpG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE;AACvF,uFAAuF;GACrF;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAErG;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IACxD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACnD;AAED,eAAO,MAAM,uBAAuB,EAAE,qBAIrC,CAAC;AAEF,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,qBAAqB,CAElF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,qBAAqB,GAAG,qBAAqB,CAExF;AAkID,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE,UAAU,GAClB;IAAE,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../../src/runtimes/claude/projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAET,YAAY,EACZ,WAAW,EAEZ,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAG3E;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE;AAC7F,sGAAsG;GACpG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE;AACvF,uFAAuF;GACrF;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAErG;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IACxD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACnD;AAED,eAAO,MAAM,uBAAuB,EAAE,qBAIrC,CAAC;AAEF,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,qBAAqB,CAElF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,qBAAqB,GAAG,qBAAqB,CAExF;AAkID,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE,UAAU,GAClB;IAAE,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE,CA4E5F"}
|
|
@@ -140,8 +140,15 @@ export function foldClaudeStdout(state, message) {
|
|
|
140
140
|
switch (String(message.type)) {
|
|
141
141
|
case "assistant":
|
|
142
142
|
return event({ events: assistantViews(message) }, rememberToolUses(state, message, agentPath));
|
|
143
|
-
case "user":
|
|
144
|
-
|
|
143
|
+
case "user": {
|
|
144
|
+
const views = [...toolResultViews(message)];
|
|
145
|
+
const body = asRecord(message.message);
|
|
146
|
+
if (message.isReplay === true && typeof message.uuid === "string" && Array.isArray(body?.content)) {
|
|
147
|
+
const input = body.content.map((part) => asRecord(part)).filter((part) => part?.type === "text").map((part) => typeof part?.text === "string" ? part.text : "").join("");
|
|
148
|
+
views.push({ kind: "user_message", input, inputId: message.uuid, nativeMessageId: message.uuid, evidence: "acknowledged" });
|
|
149
|
+
}
|
|
150
|
+
return event({ events: views });
|
|
151
|
+
}
|
|
145
152
|
case "result": {
|
|
146
153
|
const events = [{ kind: "turn_ended", outcome: resultOutcome(state, message) }];
|
|
147
154
|
const accumulated = accumulate(state, agentPath, message);
|
|
@@ -180,7 +187,7 @@ export function foldClaudeStdout(state, message) {
|
|
|
180
187
|
kind: "respond",
|
|
181
188
|
requestId,
|
|
182
189
|
body: response?.subtype === "error" || error !== null
|
|
183
|
-
? { kind: "rejected", reason: error ?? "control request failed", native: message }
|
|
190
|
+
? { kind: "rejected", code: "runtime_refused", reason: error ?? "control request failed", native: message }
|
|
184
191
|
: { kind: "accepted", native: message },
|
|
185
192
|
}] };
|
|
186
193
|
}
|