@athenaintel/react 0.55.0 → 0.56.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 +13 -0
- package/dist/agent-runtime/src/answer-label.cjs +8 -2
- package/dist/agent-runtime/src/answer-label.cjs.map +1 -1
- package/dist/agent-runtime/src/answer-label.d.ts +10 -4
- package/dist/agent-runtime/src/answer-label.js +8 -2
- package/dist/agent-runtime/src/answer-label.js.map +1 -1
- package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +6 -3
- package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
- package/dist/agent-runtime/src/deep-agent-transport-recipe.js +6 -3
- package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
- package/dist/agent-runtime/src/edit-command.cjs +40 -19
- package/dist/agent-runtime/src/edit-command.cjs.map +1 -1
- package/dist/agent-runtime/src/edit-command.d.ts +2 -0
- package/dist/agent-runtime/src/edit-command.js +41 -20
- package/dist/agent-runtime/src/edit-command.js.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs +8 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +9 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.js +8 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
- package/dist/agent-runtime/src/history-store.cjs +426 -0
- package/dist/agent-runtime/src/history-store.cjs.map +1 -0
- package/dist/agent-runtime/src/history-store.d.ts +282 -0
- package/dist/agent-runtime/src/history-store.js +426 -0
- package/dist/agent-runtime/src/history-store.js.map +1 -0
- package/dist/agent-runtime/src/index.d.ts +4 -4
- package/dist/agent-runtime/src/message-window.cjs +43 -5
- package/dist/agent-runtime/src/message-window.cjs.map +1 -1
- package/dist/agent-runtime/src/message-window.d.ts +26 -2
- package/dist/agent-runtime/src/message-window.js +44 -6
- package/dist/agent-runtime/src/message-window.js.map +1 -1
- package/dist/agent-runtime/src/offline-status.cjs.map +1 -1
- package/dist/agent-runtime/src/offline-status.d.ts +85 -4
- package/dist/agent-runtime/src/offline-status.js.map +1 -1
- package/dist/agent-runtime/src/runtime.d.ts +1 -0
- package/dist/agent-runtime/src/tool-metadata.cjs +8 -0
- package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
- package/dist/agent-runtime/src/tool-metadata.js +8 -0
- package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs +8 -16
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +1 -9
- package/dist/agent-runtime/src/use-deep-agent-thread.js +9 -17
- package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs +86 -79
- package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-window-sync.d.ts +2 -27
- package/dist/agent-runtime/src/use-deep-agent-window-sync.js +89 -82
- package/dist/agent-runtime/src/use-deep-agent-window-sync.js.map +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.cjs +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.d.ts +6 -5
- package/dist/chat/super-grouping/CollapsibleGroup.js +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.js.map +1 -1
- package/dist/chat/super-grouping/earlier-steps-button.cjs +5 -6
- package/dist/chat/super-grouping/earlier-steps-button.cjs.map +1 -1
- package/dist/chat/super-grouping/earlier-steps-button.d.ts +6 -6
- package/dist/chat/super-grouping/earlier-steps-button.js +5 -6
- package/dist/chat/super-grouping/earlier-steps-button.js.map +1 -1
- package/dist/chat/super-grouping/toolkit-map.cjs +1 -0
- package/dist/chat/super-grouping/toolkit-map.cjs.map +1 -1
- package/dist/chat/super-grouping/toolkit-map.js +1 -0
- package/dist/chat/super-grouping/toolkit-map.js.map +1 -1
- package/dist/chat/super-grouping/use-turn-steps.cjs +3 -3
- package/dist/chat/super-grouping/use-turn-steps.js +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.cjs +0 -4
- package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.d.ts +5 -7
- package/dist/chat-ui/thread/statewire-history-edge.js +1 -5
- package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
- package/dist/provider/AthenaProvider.cjs +12 -11
- package/dist/provider/AthenaProvider.cjs.map +1 -1
- package/dist/provider/AthenaProvider.js +11 -10
- package/dist/provider/AthenaProvider.js.map +1 -1
- package/dist/provider/statewire-window-context.cjs.map +1 -1
- package/dist/provider/statewire-window-context.d.ts +8 -8
- package/dist/provider/statewire-window-context.js.map +1 -1
- package/dist/react/package.json.cjs +1 -1
- package/dist/react/package.json.js +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.cjs +0 -2
- package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.d.ts +5 -5
- package/dist/runtime/useAthenaStatewireRuntime.js +0 -2
- package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
- package/package.json +1 -1
- package/dist/agent-runtime/src/history-pages.cjs +0 -279
- package/dist/agent-runtime/src/history-pages.cjs.map +0 -1
- package/dist/agent-runtime/src/history-pages.d.ts +0 -252
- package/dist/agent-runtime/src/history-pages.js +0 -279
- package/dist/agent-runtime/src/history-pages.js.map +0 -1
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
import type { LangChainMessage } from '@assistant-ui/react-langgraph';
|
|
2
|
-
import { DEEP_AGENT_HISTORY_PAGE_COMMAND } from './generated/runconfig-contract';
|
|
3
|
-
/**
|
|
4
|
-
* Older history by command, a turn at a time — the client half of agora's
|
|
5
|
-
* `history_page.py` (protocol 3, `docs/plans/2026-11-03-history-by-command-plan.md`).
|
|
6
|
-
*
|
|
7
|
-
* A host advertising `DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION` answers
|
|
8
|
-
* `history/page` with whole turns older than a message the client holds, as a
|
|
9
|
-
* command result: nothing is mounted in the attach's view, so no interest
|
|
10
|
-
* document grows with how far back a reader goes, and a re-attach restates
|
|
11
|
-
* nothing it paged. The client keeps the answers in a
|
|
12
|
-
* {@link DeepAgentHistoryStore} and joins them in front of the live window
|
|
13
|
-
* ({@link joinDeepAgentHistory}).
|
|
14
|
-
*
|
|
15
|
-
* A turn longer than the host's whole-turn limit rides as its prompt and its
|
|
16
|
-
* answer, with `steps` counting what it left out; `history/page` with a
|
|
17
|
-
* `turn` pages those steps newest first. The join marks each summarized turn
|
|
18
|
-
* on a source message ({@link DEEP_AGENT_TURN_STEPS_KEY}) so a renderer reads
|
|
19
|
-
* the turn's exact counts, and inserts the steps fetched so far between the
|
|
20
|
-
* prompt and the answer.
|
|
21
|
-
*/
|
|
22
|
-
/** Turns one `history/page` asks for. */
|
|
23
|
-
export declare const DEEP_AGENT_HISTORY_PAGE_TURNS = 10;
|
|
24
|
-
/** Steps of one turn one `history/page` asks for. */
|
|
25
|
-
export declare const DEEP_AGENT_TURN_STEPS_PAGE = 100;
|
|
26
|
-
/** `additional_kwargs` key the join marks a summarized turn's first reply message with. */
|
|
27
|
-
export declare const DEEP_AGENT_TURN_STEPS_KEY = "athena_turn_steps";
|
|
28
|
-
/**
|
|
29
|
-
* Key on the composed thread state (`useDeepAgentThread`'s converter) set when
|
|
30
|
-
* the paged turns joined in front of the window reach the transcript's start:
|
|
31
|
-
* the live window's own `hasOlder` still says older messages exist, so an
|
|
32
|
-
* edit's anchor search reads this to know the first message has no parent.
|
|
33
|
-
*/
|
|
34
|
-
export declare const DEEP_AGENT_HISTORY_START_KEY = "athenaHistoryStart";
|
|
35
|
-
/** Whether a composed thread state says its messages start at the transcript's start. */
|
|
36
|
-
export declare function isDeepAgentHistoryAtStart(state: unknown): boolean;
|
|
37
|
-
/** What a summarized turn's page left out (the host's `steps`). */
|
|
38
|
-
export interface DeepAgentHistoryTurnSteps {
|
|
39
|
-
/** Messages left out. */
|
|
40
|
-
count: number;
|
|
41
|
-
/** Tool calls among the messages left out (a renderer adds the ones it holds). */
|
|
42
|
-
tools: number;
|
|
43
|
-
/** Of which `task` delegations. */
|
|
44
|
-
delegations: number;
|
|
45
|
-
first: string | null;
|
|
46
|
-
last: string | null;
|
|
47
|
-
}
|
|
48
|
-
/** One turn of a `history/page` answer. */
|
|
49
|
-
export interface DeepAgentHistoryTurn {
|
|
50
|
-
/** The turn's first message (its prompt), the id its steps are paged by. */
|
|
51
|
-
id: string;
|
|
52
|
-
/** What the page shows of it, oldest first: the prompt and the answer, or the whole turn. */
|
|
53
|
-
messages: LangChainMessage[];
|
|
54
|
-
/** What it left out, or `null` when the turn rides whole. */
|
|
55
|
-
steps: DeepAgentHistoryTurnSteps | null;
|
|
56
|
-
}
|
|
57
|
-
export interface DeepAgentHistoryPageAnswer {
|
|
58
|
-
turns: DeepAgentHistoryTurn[];
|
|
59
|
-
more: {
|
|
60
|
-
before: boolean;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
export interface DeepAgentTurnStepsAnswer {
|
|
64
|
-
turn: string;
|
|
65
|
-
/** Steps, oldest first. */
|
|
66
|
-
messages: LangChainMessage[];
|
|
67
|
-
more: {
|
|
68
|
-
before: boolean;
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
/** The `history/page` command asking for turns older than `before`. */
|
|
72
|
-
export interface HistoryPageCommand {
|
|
73
|
-
readonly type: typeof DEEP_AGENT_HISTORY_PAGE_COMMAND;
|
|
74
|
-
readonly before: string;
|
|
75
|
-
readonly turns: number;
|
|
76
|
-
}
|
|
77
|
-
/** The `history/page` command asking for one turn's steps older than `before`. */
|
|
78
|
-
export interface TurnStepsCommand {
|
|
79
|
-
readonly type: typeof DEEP_AGENT_HISTORY_PAGE_COMMAND;
|
|
80
|
-
readonly turn: string;
|
|
81
|
-
readonly before?: string;
|
|
82
|
-
readonly steps: number;
|
|
83
|
-
}
|
|
84
|
-
declare module '@assistant-ui/core' {
|
|
85
|
-
namespace Assistant {
|
|
86
|
-
interface Commands {
|
|
87
|
-
/** Older turns, outside the attach's view. */
|
|
88
|
-
historyPage: HistoryPageCommand;
|
|
89
|
-
/** One summarized turn's steps. */
|
|
90
|
-
historyTurnSteps: TurnStepsCommand;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
export declare function buildHistoryPageCommand({ before, turns, }: {
|
|
95
|
-
before: string;
|
|
96
|
-
turns?: number;
|
|
97
|
-
}): HistoryPageCommand;
|
|
98
|
-
export declare function buildTurnStepsCommand({ turn, before, steps, }: {
|
|
99
|
-
turn: string;
|
|
100
|
-
before?: string | undefined;
|
|
101
|
-
steps?: number;
|
|
102
|
-
}): TurnStepsCommand;
|
|
103
|
-
/** A `history/page` answer to `{before, turns}`, or `null` when it is malformed. */
|
|
104
|
-
export declare function readHistoryPageAnswer(payload: unknown): DeepAgentHistoryPageAnswer | null;
|
|
105
|
-
/** A `history/page` answer to `{turn, before?, steps}`, or `null` when it is malformed. */
|
|
106
|
-
export declare function readTurnStepsAnswer(payload: unknown): DeepAgentTurnStepsAnswer | null;
|
|
107
|
-
/** The steps of one summarized turn fetched so far, oldest first. */
|
|
108
|
-
export interface DeepAgentHistoryTurnStepsLoaded {
|
|
109
|
-
messages: LangChainMessage[];
|
|
110
|
-
/** Older steps of the turn remain. */
|
|
111
|
-
more: boolean;
|
|
112
|
-
}
|
|
113
|
-
/** The turns one conversation has paged in, in front of its live window. */
|
|
114
|
-
export interface DeepAgentHistorySnapshot {
|
|
115
|
-
/** The conversation they belong to. */
|
|
116
|
-
threadId: string;
|
|
117
|
-
/** The message the first page was asked `before`: the live window's first message then. */
|
|
118
|
-
anchor: string;
|
|
119
|
-
/** Whether the anchor is a reply rather than a prompt: the newest turn's rest is in the live window. */
|
|
120
|
-
anchorInsideTurn: boolean;
|
|
121
|
-
/** Turns, oldest first. */
|
|
122
|
-
turns: DeepAgentHistoryTurn[];
|
|
123
|
-
/** Older turns remain beyond the first. */
|
|
124
|
-
more: boolean;
|
|
125
|
-
/** Steps fetched per summarized turn id. */
|
|
126
|
-
steps: ReadonlyMap<string, DeepAgentHistoryTurnStepsLoaded>;
|
|
127
|
-
}
|
|
128
|
-
/** How a store asks the host: the thread's `sendCommand` (its answer, the command's payload). */
|
|
129
|
-
export type DeepAgentHistorySend = (command: HistoryPageCommand | TurnStepsCommand) => unknown;
|
|
130
|
-
/**
|
|
131
|
-
* The history paged in for the open conversation: a subscribable store the
|
|
132
|
-
* thread's converter joins in front of its live window and the window sync
|
|
133
|
-
* fills. One per provider, like the tool-output store; it holds one
|
|
134
|
-
* conversation at a time and resets when another one pages.
|
|
135
|
-
*
|
|
136
|
-
* Everything history pages do runs through the store's methods, so a surface
|
|
137
|
-
* that creates no store (it never pages by command) bundles none of it: the
|
|
138
|
-
* shared thread and window sync only call `historyPages?.…`.
|
|
139
|
-
*/
|
|
140
|
-
export interface DeepAgentHistoryStore {
|
|
141
|
-
/** The current snapshot (a new object on every change), or `null` when empty. */
|
|
142
|
-
getSnapshot(): DeepAgentHistorySnapshot | null;
|
|
143
|
-
subscribe(listener: () => void): () => void;
|
|
144
|
-
/**
|
|
145
|
-
* Adds a page asked `before` a message. A page for another conversation, or
|
|
146
|
-
* asked before a message other than the oldest turn held, starts over.
|
|
147
|
-
*/
|
|
148
|
-
addPage(page: {
|
|
149
|
-
threadId: string;
|
|
150
|
-
before: string;
|
|
151
|
-
beforeIsPrompt: boolean;
|
|
152
|
-
answer: DeepAgentHistoryPageAnswer;
|
|
153
|
-
}): void;
|
|
154
|
-
/** Adds one summarized turn's older steps. */
|
|
155
|
-
addSteps(steps: {
|
|
156
|
-
threadId: string;
|
|
157
|
-
answer: DeepAgentTurnStepsAnswer;
|
|
158
|
-
}): void;
|
|
159
|
-
/** Whether a steps request for the turn is in flight — the loader's dedupe. */
|
|
160
|
-
isLoadingSteps(turn: string): boolean;
|
|
161
|
-
setLoadingSteps(turn: string, loading: boolean): void;
|
|
162
|
-
clear(): void;
|
|
163
|
-
/**
|
|
164
|
-
* The transcript to render: the held turns joined in front of the live
|
|
165
|
-
* window ({@link joinDeepAgentHistory}), and whether they reach the
|
|
166
|
-
* transcript's start (`more.before` false). `live` alone, `atStart` false,
|
|
167
|
-
* while nothing held meets the window.
|
|
168
|
-
*/
|
|
169
|
-
join(options: {
|
|
170
|
-
threadId: string | undefined;
|
|
171
|
-
live: LangChainMessage[];
|
|
172
|
-
liveIds: ReadonlySet<string>;
|
|
173
|
-
}): {
|
|
174
|
-
messages: LangChainMessage[];
|
|
175
|
-
atStart: boolean;
|
|
176
|
-
};
|
|
177
|
-
/** Whether the held turns no longer meet the live window ({@link isDeepAgentHistoryDetached}). */
|
|
178
|
-
isDetached(options: {
|
|
179
|
-
threadId: string | undefined;
|
|
180
|
-
liveIds: ReadonlySet<string>;
|
|
181
|
-
}): boolean;
|
|
182
|
-
/**
|
|
183
|
-
* Asks the host for the turns before `before` and adds them; resolves how
|
|
184
|
-
* many it answered. Rejects with the host's refusal, or when the answer is
|
|
185
|
-
* not a page this client reads.
|
|
186
|
-
*/
|
|
187
|
-
requestOlder(options: {
|
|
188
|
-
send: DeepAgentHistorySend;
|
|
189
|
-
threadId: string;
|
|
190
|
-
before: string;
|
|
191
|
-
beforeIsPrompt: boolean;
|
|
192
|
-
turns?: number;
|
|
193
|
-
}): Promise<number>;
|
|
194
|
-
/**
|
|
195
|
-
* Fetches a summarized turn's next older steps (`history/page` with its
|
|
196
|
-
* `turn`) into the store, newest first. A turn already loading, or with no
|
|
197
|
-
* steps left, is a no-op. Rejects with the host's refusal.
|
|
198
|
-
*/
|
|
199
|
-
loadSteps(options: {
|
|
200
|
-
send: DeepAgentHistorySend;
|
|
201
|
-
marker: DeepAgentTurnStepsMarker;
|
|
202
|
-
}): Promise<void>;
|
|
203
|
-
}
|
|
204
|
-
export declare function createDeepAgentHistoryStore(): DeepAgentHistoryStore;
|
|
205
|
-
/**
|
|
206
|
-
* The marker the join puts on a summarized turn's first reply message: the
|
|
207
|
-
* turn's steps it has not shown yet, so a renderer reads exact counts ("Used
|
|
208
|
-
* 313 tools") and knows whether opening it has steps to fetch.
|
|
209
|
-
*/
|
|
210
|
-
export interface DeepAgentTurnStepsMarker {
|
|
211
|
-
/** The turn's first message: the id its steps are paged by. */
|
|
212
|
-
turn: string;
|
|
213
|
-
/** Steps not loaded yet. */
|
|
214
|
-
hiddenSteps: number;
|
|
215
|
-
/** Tool calls among them. */
|
|
216
|
-
hiddenTools: number;
|
|
217
|
-
/** Of which `task` delegations. */
|
|
218
|
-
hiddenDelegations: number;
|
|
219
|
-
/** The oldest step loaded, the next steps request's `before`. */
|
|
220
|
-
before: string | undefined;
|
|
221
|
-
}
|
|
222
|
-
/** The marker a join put on a source message, or `undefined`. */
|
|
223
|
-
export declare function readTurnStepsMarker(message: unknown): DeepAgentTurnStepsMarker | undefined;
|
|
224
|
-
/**
|
|
225
|
-
* The transcript a converter renders: the paged turns in front of the live
|
|
226
|
-
* window, when they still meet it.
|
|
227
|
-
*
|
|
228
|
-
* The paged turns end just before the snapshot's anchor. While the anchor is
|
|
229
|
-
* in `live`, they are joined in front of it, minus any message `live` already
|
|
230
|
-
* holds (a reveal or an edit paged an interest page over the same range). When
|
|
231
|
-
* the anchor has left the live window (an edit rewound past it, a branch
|
|
232
|
-
* switch), the pages describe another transcript: `live` is returned alone,
|
|
233
|
-
* and {@link isDeepAgentHistoryDetached} tells the window sync to clear them.
|
|
234
|
-
*
|
|
235
|
-
* Each summarized turn gets its fetched steps between its prompt and its
|
|
236
|
-
* answer, and its first reply message the {@link DeepAgentTurnStepsMarker}.
|
|
237
|
-
* The newest turn of a page asked inside a turn has its rest in `live`, so its
|
|
238
|
-
* marker lands on the first live message after its prompt.
|
|
239
|
-
*/
|
|
240
|
-
export declare function joinDeepAgentHistory({ history, threadId, live, liveIds, }: {
|
|
241
|
-
history: DeepAgentHistorySnapshot | null;
|
|
242
|
-
threadId: string | undefined;
|
|
243
|
-
live: LangChainMessage[];
|
|
244
|
-
/** The live window's chain ids; the anchor must be among them. */
|
|
245
|
-
liveIds: ReadonlySet<string>;
|
|
246
|
-
}): LangChainMessage[];
|
|
247
|
-
/** Whether the paged turns no longer meet the live window: another conversation, or the anchor left it. */
|
|
248
|
-
export declare function isDeepAgentHistoryDetached({ history, threadId, liveIds, }: {
|
|
249
|
-
history: DeepAgentHistorySnapshot;
|
|
250
|
-
threadId: string | undefined;
|
|
251
|
-
liveIds: ReadonlySet<string>;
|
|
252
|
-
}): boolean;
|
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import { DEEP_AGENT_HISTORY_PAGE_COMMAND } from "./generated/runconfig-contract.js";
|
|
2
|
-
import { QUIET_TOOL_NAMES } from "./tool-names.js";
|
|
3
|
-
const DEEP_AGENT_HISTORY_PAGE_TURNS = 10;
|
|
4
|
-
const DEEP_AGENT_TURN_STEPS_PAGE = 100;
|
|
5
|
-
const DEEP_AGENT_TURN_STEPS_KEY = "athena_turn_steps";
|
|
6
|
-
const DEEP_AGENT_HISTORY_START_KEY = "athenaHistoryStart";
|
|
7
|
-
function isDeepAgentHistoryAtStart(state) {
|
|
8
|
-
return isRecord(state) && state[DEEP_AGENT_HISTORY_START_KEY] === true;
|
|
9
|
-
}
|
|
10
|
-
function buildHistoryPageCommand({
|
|
11
|
-
before,
|
|
12
|
-
turns = DEEP_AGENT_HISTORY_PAGE_TURNS
|
|
13
|
-
}) {
|
|
14
|
-
return { type: DEEP_AGENT_HISTORY_PAGE_COMMAND, before, turns };
|
|
15
|
-
}
|
|
16
|
-
function buildTurnStepsCommand({
|
|
17
|
-
turn,
|
|
18
|
-
before,
|
|
19
|
-
steps = DEEP_AGENT_TURN_STEPS_PAGE
|
|
20
|
-
}) {
|
|
21
|
-
return {
|
|
22
|
-
type: DEEP_AGENT_HISTORY_PAGE_COMMAND,
|
|
23
|
-
turn,
|
|
24
|
-
...before !== void 0 && { before },
|
|
25
|
-
steps
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
29
|
-
const isCount = (value) => typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
30
|
-
const isId = (value) => typeof value === "string" && value.length > 0;
|
|
31
|
-
function readMessages(value) {
|
|
32
|
-
if (!Array.isArray(value)) return null;
|
|
33
|
-
for (const message of value) {
|
|
34
|
-
if (!isRecord(message) || !isId(message.id) || typeof message.type !== "string") return null;
|
|
35
|
-
}
|
|
36
|
-
return value;
|
|
37
|
-
}
|
|
38
|
-
function readMore(value) {
|
|
39
|
-
return isRecord(value) && typeof value.before === "boolean" ? { before: value.before } : null;
|
|
40
|
-
}
|
|
41
|
-
function readSteps(value) {
|
|
42
|
-
if (value === null) return null;
|
|
43
|
-
if (!isRecord(value)) return void 0;
|
|
44
|
-
const { count, tools, delegations, first, last } = value;
|
|
45
|
-
if (!isCount(count) || !isCount(tools) || !isCount(delegations)) return void 0;
|
|
46
|
-
if (first !== null && !isId(first) || last !== null && !isId(last)) return void 0;
|
|
47
|
-
return { count, tools, delegations, first, last };
|
|
48
|
-
}
|
|
49
|
-
function readHistoryPageAnswer(payload) {
|
|
50
|
-
if (!isRecord(payload) || !Array.isArray(payload.turns)) return null;
|
|
51
|
-
const more = readMore(payload.more);
|
|
52
|
-
if (more === null) return null;
|
|
53
|
-
const turns = [];
|
|
54
|
-
for (const turn of payload.turns) {
|
|
55
|
-
if (!isRecord(turn) || !isId(turn.id)) return null;
|
|
56
|
-
const messages = readMessages(turn.messages);
|
|
57
|
-
const steps = readSteps(turn.steps);
|
|
58
|
-
if (messages === null || steps === void 0) return null;
|
|
59
|
-
turns.push({ id: turn.id, messages, steps });
|
|
60
|
-
}
|
|
61
|
-
return { turns, more };
|
|
62
|
-
}
|
|
63
|
-
function readTurnStepsAnswer(payload) {
|
|
64
|
-
if (!isRecord(payload) || !isId(payload.turn)) return null;
|
|
65
|
-
const messages = readMessages(payload.messages);
|
|
66
|
-
const more = readMore(payload.more);
|
|
67
|
-
if (messages === null || more === null) return null;
|
|
68
|
-
return { turn: payload.turn, messages, more };
|
|
69
|
-
}
|
|
70
|
-
function createDeepAgentHistoryStore() {
|
|
71
|
-
let snapshot = null;
|
|
72
|
-
const loadingSteps = /* @__PURE__ */ new Set();
|
|
73
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
74
|
-
const publish = (next) => {
|
|
75
|
-
snapshot = next;
|
|
76
|
-
for (const listener of listeners) listener();
|
|
77
|
-
};
|
|
78
|
-
const store = {
|
|
79
|
-
getSnapshot: () => snapshot,
|
|
80
|
-
subscribe(listener) {
|
|
81
|
-
listeners.add(listener);
|
|
82
|
-
return () => {
|
|
83
|
-
listeners.delete(listener);
|
|
84
|
-
};
|
|
85
|
-
},
|
|
86
|
-
addPage({ threadId, before, beforeIsPrompt, answer }) {
|
|
87
|
-
var _a;
|
|
88
|
-
const current = snapshot;
|
|
89
|
-
const continues = current !== null && current.threadId === threadId && ((_a = current.turns[0]) == null ? void 0 : _a.id) === before;
|
|
90
|
-
if (!continues) {
|
|
91
|
-
loadingSteps.clear();
|
|
92
|
-
publish({
|
|
93
|
-
threadId,
|
|
94
|
-
anchor: before,
|
|
95
|
-
anchorInsideTurn: !beforeIsPrompt,
|
|
96
|
-
turns: answer.turns,
|
|
97
|
-
more: answer.more.before,
|
|
98
|
-
steps: /* @__PURE__ */ new Map()
|
|
99
|
-
});
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const held = new Set(current.turns.map((turn) => turn.id));
|
|
103
|
-
publish({
|
|
104
|
-
...current,
|
|
105
|
-
turns: [...answer.turns.filter((turn) => !held.has(turn.id)), ...current.turns],
|
|
106
|
-
more: answer.more.before
|
|
107
|
-
});
|
|
108
|
-
},
|
|
109
|
-
addSteps({ threadId, answer }) {
|
|
110
|
-
const current = snapshot;
|
|
111
|
-
if (current === null || current.threadId !== threadId) return;
|
|
112
|
-
if (!current.turns.some((turn) => turn.id === answer.turn)) return;
|
|
113
|
-
const loaded = current.steps.get(answer.turn);
|
|
114
|
-
const held = new Set(loaded == null ? void 0 : loaded.messages.map((message) => message.id));
|
|
115
|
-
const steps = new Map(current.steps);
|
|
116
|
-
steps.set(answer.turn, {
|
|
117
|
-
messages: [
|
|
118
|
-
...answer.messages.filter((message) => !held.has(message.id)),
|
|
119
|
-
...(loaded == null ? void 0 : loaded.messages) ?? []
|
|
120
|
-
],
|
|
121
|
-
more: answer.more.before
|
|
122
|
-
});
|
|
123
|
-
publish({ ...current, steps });
|
|
124
|
-
},
|
|
125
|
-
isLoadingSteps: (turn) => loadingSteps.has(turn),
|
|
126
|
-
setLoadingSteps(turn, loading) {
|
|
127
|
-
if (loading) loadingSteps.add(turn);
|
|
128
|
-
else loadingSteps.delete(turn);
|
|
129
|
-
},
|
|
130
|
-
clear() {
|
|
131
|
-
loadingSteps.clear();
|
|
132
|
-
if (snapshot !== null) publish(null);
|
|
133
|
-
},
|
|
134
|
-
join({ threadId, live, liveIds }) {
|
|
135
|
-
const history = snapshot;
|
|
136
|
-
if (history === null || history.turns.length === 0 || isDeepAgentHistoryDetached({ history, threadId, liveIds })) {
|
|
137
|
-
return { messages: live, atStart: false };
|
|
138
|
-
}
|
|
139
|
-
return { messages: joinDeepAgentHistory({ history, threadId, live, liveIds }), atStart: !history.more };
|
|
140
|
-
},
|
|
141
|
-
isDetached: ({ threadId, liveIds }) => snapshot !== null && isDeepAgentHistoryDetached({ history: snapshot, threadId, liveIds }),
|
|
142
|
-
async requestOlder({ send, threadId, before, beforeIsPrompt, turns }) {
|
|
143
|
-
const answer = readHistoryPageAnswer(await send(buildHistoryPageCommand({ before, turns })));
|
|
144
|
-
if (answer === null) throw new Error("history/page answered in a shape this client cannot read");
|
|
145
|
-
store.addPage({ threadId, before, beforeIsPrompt, answer });
|
|
146
|
-
return answer.turns.length;
|
|
147
|
-
},
|
|
148
|
-
async loadSteps({ send, marker }) {
|
|
149
|
-
var _a;
|
|
150
|
-
const current = snapshot;
|
|
151
|
-
if (current === null || marker.hiddenSteps === 0 || loadingSteps.has(marker.turn)) return;
|
|
152
|
-
const newestInsideTurn = current.anchorInsideTurn && ((_a = current.turns.at(-1)) == null ? void 0 : _a.id) === marker.turn;
|
|
153
|
-
const before = marker.before ?? (newestInsideTurn ? current.anchor : void 0);
|
|
154
|
-
loadingSteps.add(marker.turn);
|
|
155
|
-
try {
|
|
156
|
-
const answer = readTurnStepsAnswer(await send(buildTurnStepsCommand({ turn: marker.turn, before })));
|
|
157
|
-
if (answer === null) {
|
|
158
|
-
throw new Error("history/page answered steps in a shape this client cannot read");
|
|
159
|
-
}
|
|
160
|
-
store.addSteps({ threadId: current.threadId, answer });
|
|
161
|
-
} finally {
|
|
162
|
-
loadingSteps.delete(marker.turn);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
return store;
|
|
167
|
-
}
|
|
168
|
-
function toolCalls(messages) {
|
|
169
|
-
let tools = 0;
|
|
170
|
-
let delegations = 0;
|
|
171
|
-
for (const message of messages) {
|
|
172
|
-
if (message.type !== "ai") continue;
|
|
173
|
-
for (const call of message.tool_calls ?? []) {
|
|
174
|
-
if (QUIET_TOOL_NAMES.has(call.name)) continue;
|
|
175
|
-
tools += 1;
|
|
176
|
-
if (call.name === "task") delegations += 1;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return { tools, delegations };
|
|
180
|
-
}
|
|
181
|
-
function readTurnStepsMarker(message) {
|
|
182
|
-
if (!isRecord(message) || !isRecord(message.additional_kwargs)) return void 0;
|
|
183
|
-
const marker = message.additional_kwargs[DEEP_AGENT_TURN_STEPS_KEY];
|
|
184
|
-
if (!isRecord(marker) || !isId(marker.turn)) return void 0;
|
|
185
|
-
const { hiddenSteps, hiddenTools, hiddenDelegations, before } = marker;
|
|
186
|
-
if (!isCount(hiddenSteps) || !isCount(hiddenTools) || !isCount(hiddenDelegations)) return void 0;
|
|
187
|
-
return {
|
|
188
|
-
turn: marker.turn,
|
|
189
|
-
hiddenSteps,
|
|
190
|
-
hiddenTools,
|
|
191
|
-
hiddenDelegations,
|
|
192
|
-
before: isId(before) ? before : void 0
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
const markedCopies = /* @__PURE__ */ new WeakMap();
|
|
196
|
-
function withMarker(message, marker) {
|
|
197
|
-
const key = JSON.stringify(marker);
|
|
198
|
-
const cached = markedCopies.get(message);
|
|
199
|
-
if ((cached == null ? void 0 : cached.key) === key) return cached.message;
|
|
200
|
-
const kwargs = message.additional_kwargs;
|
|
201
|
-
const marked = {
|
|
202
|
-
...message,
|
|
203
|
-
additional_kwargs: { ...kwargs ?? {}, [DEEP_AGENT_TURN_STEPS_KEY]: marker }
|
|
204
|
-
};
|
|
205
|
-
markedCopies.set(message, { key, message: marked });
|
|
206
|
-
return marked;
|
|
207
|
-
}
|
|
208
|
-
function joinDeepAgentHistory({
|
|
209
|
-
history,
|
|
210
|
-
threadId,
|
|
211
|
-
live,
|
|
212
|
-
liveIds
|
|
213
|
-
}) {
|
|
214
|
-
var _a, _b;
|
|
215
|
-
if (history === null || history.turns.length === 0 || isDeepAgentHistoryDetached({ history, threadId, liveIds })) {
|
|
216
|
-
return live;
|
|
217
|
-
}
|
|
218
|
-
const joined = [];
|
|
219
|
-
let pendingMarker = null;
|
|
220
|
-
const markNext = (message) => {
|
|
221
|
-
if (pendingMarker === null || message.type !== "ai") return message;
|
|
222
|
-
const marked = withMarker(message, pendingMarker);
|
|
223
|
-
pendingMarker = null;
|
|
224
|
-
return marked;
|
|
225
|
-
};
|
|
226
|
-
for (const turn of history.turns) {
|
|
227
|
-
if (turn.steps === null) {
|
|
228
|
-
for (const message of turn.messages) {
|
|
229
|
-
if (!liveIds.has(message.id ?? "")) joined.push(message);
|
|
230
|
-
}
|
|
231
|
-
continue;
|
|
232
|
-
}
|
|
233
|
-
const loaded = ((_a = history.steps.get(turn.id)) == null ? void 0 : _a.messages) ?? [];
|
|
234
|
-
const [first, ...rest] = turn.messages;
|
|
235
|
-
const prompt = (first == null ? void 0 : first.type) === "human" ? first : void 0;
|
|
236
|
-
const answer = prompt === void 0 ? turn.messages : rest;
|
|
237
|
-
const paged = toolCalls(loaded);
|
|
238
|
-
pendingMarker = {
|
|
239
|
-
turn: turn.id,
|
|
240
|
-
hiddenSteps: Math.max(0, turn.steps.count - loaded.length),
|
|
241
|
-
hiddenTools: Math.max(0, turn.steps.tools - paged.tools),
|
|
242
|
-
hiddenDelegations: Math.max(0, turn.steps.delegations - paged.delegations),
|
|
243
|
-
before: (_b = loaded[0]) == null ? void 0 : _b.id
|
|
244
|
-
};
|
|
245
|
-
for (const message of [...prompt ? [prompt] : [], ...loaded, ...answer]) {
|
|
246
|
-
if (liveIds.has(message.id ?? "")) continue;
|
|
247
|
-
joined.push(markNext(message));
|
|
248
|
-
}
|
|
249
|
-
if (pendingMarker !== null && (turn !== history.turns.at(-1) || !history.anchorInsideTurn)) {
|
|
250
|
-
pendingMarker = null;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
for (const message of live) joined.push(markNext(message));
|
|
254
|
-
return joined;
|
|
255
|
-
}
|
|
256
|
-
function isDeepAgentHistoryDetached({
|
|
257
|
-
history,
|
|
258
|
-
threadId,
|
|
259
|
-
liveIds
|
|
260
|
-
}) {
|
|
261
|
-
if (threadId !== void 0 && history.threadId !== threadId) return true;
|
|
262
|
-
return liveIds.size > 0 && !liveIds.has(history.anchor);
|
|
263
|
-
}
|
|
264
|
-
export {
|
|
265
|
-
DEEP_AGENT_HISTORY_PAGE_TURNS,
|
|
266
|
-
DEEP_AGENT_HISTORY_START_KEY,
|
|
267
|
-
DEEP_AGENT_TURN_STEPS_KEY,
|
|
268
|
-
DEEP_AGENT_TURN_STEPS_PAGE,
|
|
269
|
-
buildHistoryPageCommand,
|
|
270
|
-
buildTurnStepsCommand,
|
|
271
|
-
createDeepAgentHistoryStore,
|
|
272
|
-
isDeepAgentHistoryAtStart,
|
|
273
|
-
isDeepAgentHistoryDetached,
|
|
274
|
-
joinDeepAgentHistory,
|
|
275
|
-
readHistoryPageAnswer,
|
|
276
|
-
readTurnStepsAnswer,
|
|
277
|
-
readTurnStepsMarker
|
|
278
|
-
};
|
|
279
|
-
//# sourceMappingURL=history-pages.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"history-pages.js","sources":["../../../../agent-runtime/src/history-pages.ts"],"sourcesContent":["import type { LangChainMessage } from '@assistant-ui/react-langgraph';\nimport { DEEP_AGENT_HISTORY_PAGE_COMMAND } from './generated/runconfig-contract';\nimport { QUIET_TOOL_NAMES } from './tool-names';\n\n/**\n * Older history by command, a turn at a time — the client half of agora's\n * `history_page.py` (protocol 3, `docs/plans/2026-11-03-history-by-command-plan.md`).\n *\n * A host advertising `DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION` answers\n * `history/page` with whole turns older than a message the client holds, as a\n * command result: nothing is mounted in the attach's view, so no interest\n * document grows with how far back a reader goes, and a re-attach restates\n * nothing it paged. The client keeps the answers in a\n * {@link DeepAgentHistoryStore} and joins them in front of the live window\n * ({@link joinDeepAgentHistory}).\n *\n * A turn longer than the host's whole-turn limit rides as its prompt and its\n * answer, with `steps` counting what it left out; `history/page` with a\n * `turn` pages those steps newest first. The join marks each summarized turn\n * on a source message ({@link DEEP_AGENT_TURN_STEPS_KEY}) so a renderer reads\n * the turn's exact counts, and inserts the steps fetched so far between the\n * prompt and the answer.\n */\n\n/** Turns one `history/page` asks for. */\nexport const DEEP_AGENT_HISTORY_PAGE_TURNS = 10;\n/** Steps of one turn one `history/page` asks for. */\nexport const DEEP_AGENT_TURN_STEPS_PAGE = 100;\n/** `additional_kwargs` key the join marks a summarized turn's first reply message with. */\nexport const DEEP_AGENT_TURN_STEPS_KEY = 'athena_turn_steps';\n/**\n * Key on the composed thread state (`useDeepAgentThread`'s converter) set when\n * the paged turns joined in front of the window reach the transcript's start:\n * the live window's own `hasOlder` still says older messages exist, so an\n * edit's anchor search reads this to know the first message has no parent.\n */\nexport const DEEP_AGENT_HISTORY_START_KEY = 'athenaHistoryStart';\n\n/** Whether a composed thread state says its messages start at the transcript's start. */\nexport function isDeepAgentHistoryAtStart(state: unknown): boolean {\n return isRecord(state) && state[DEEP_AGENT_HISTORY_START_KEY] === true;\n}\n\n/** What a summarized turn's page left out (the host's `steps`). */\nexport interface DeepAgentHistoryTurnSteps {\n /** Messages left out. */\n count: number;\n /** Tool calls among the messages left out (a renderer adds the ones it holds). */\n tools: number;\n /** Of which `task` delegations. */\n delegations: number;\n first: string | null;\n last: string | null;\n}\n\n/** One turn of a `history/page` answer. */\nexport interface DeepAgentHistoryTurn {\n /** The turn's first message (its prompt), the id its steps are paged by. */\n id: string;\n /** What the page shows of it, oldest first: the prompt and the answer, or the whole turn. */\n messages: LangChainMessage[];\n /** What it left out, or `null` when the turn rides whole. */\n steps: DeepAgentHistoryTurnSteps | null;\n}\n\nexport interface DeepAgentHistoryPageAnswer {\n turns: DeepAgentHistoryTurn[];\n more: { before: boolean };\n}\n\nexport interface DeepAgentTurnStepsAnswer {\n turn: string;\n /** Steps, oldest first. */\n messages: LangChainMessage[];\n more: { before: boolean };\n}\n\n/** The `history/page` command asking for turns older than `before`. */\nexport interface HistoryPageCommand {\n readonly type: typeof DEEP_AGENT_HISTORY_PAGE_COMMAND;\n readonly before: string;\n readonly turns: number;\n}\n\n/** The `history/page` command asking for one turn's steps older than `before`. */\nexport interface TurnStepsCommand {\n readonly type: typeof DEEP_AGENT_HISTORY_PAGE_COMMAND;\n readonly turn: string;\n readonly before?: string;\n readonly steps: number;\n}\n\ndeclare module '@assistant-ui/core' {\n namespace Assistant {\n interface Commands {\n /** Older turns, outside the attach's view. */\n historyPage: HistoryPageCommand;\n /** One summarized turn's steps. */\n historyTurnSteps: TurnStepsCommand;\n }\n }\n}\n\nexport function buildHistoryPageCommand({\n before,\n turns = DEEP_AGENT_HISTORY_PAGE_TURNS,\n}: {\n before: string;\n turns?: number;\n}): HistoryPageCommand {\n return { type: DEEP_AGENT_HISTORY_PAGE_COMMAND, before, turns };\n}\n\nexport function buildTurnStepsCommand({\n turn,\n before,\n steps = DEEP_AGENT_TURN_STEPS_PAGE,\n}: {\n turn: string;\n before?: string | undefined;\n steps?: number;\n}): TurnStepsCommand {\n return {\n type: DEEP_AGENT_HISTORY_PAGE_COMMAND,\n turn,\n ...(before !== undefined && { before }),\n steps,\n };\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\nconst isCount = (value: unknown): value is number =>\n typeof value === 'number' && Number.isInteger(value) && value >= 0;\nconst isId = (value: unknown): value is string => typeof value === 'string' && value.length > 0;\n\nfunction readMessages(value: unknown): LangChainMessage[] | null {\n if (!Array.isArray(value)) return null;\n for (const message of value) {\n if (!isRecord(message) || !isId(message.id) || typeof message.type !== 'string') return null;\n }\n return value as LangChainMessage[];\n}\n\nfunction readMore(value: unknown): { before: boolean } | null {\n return isRecord(value) && typeof value.before === 'boolean' ? { before: value.before } : null;\n}\n\nfunction readSteps(value: unknown): DeepAgentHistoryTurnSteps | null | undefined {\n if (value === null) return null;\n if (!isRecord(value)) return undefined;\n const { count, tools, delegations, first, last } = value;\n if (!isCount(count) || !isCount(tools) || !isCount(delegations)) return undefined;\n if ((first !== null && !isId(first)) || (last !== null && !isId(last))) return undefined;\n return { count, tools, delegations, first, last };\n}\n\n/** A `history/page` answer to `{before, turns}`, or `null` when it is malformed. */\nexport function readHistoryPageAnswer(payload: unknown): DeepAgentHistoryPageAnswer | null {\n if (!isRecord(payload) || !Array.isArray(payload.turns)) return null;\n const more = readMore(payload.more);\n if (more === null) return null;\n const turns: DeepAgentHistoryTurn[] = [];\n for (const turn of payload.turns) {\n if (!isRecord(turn) || !isId(turn.id)) return null;\n const messages = readMessages(turn.messages);\n const steps = readSteps(turn.steps);\n if (messages === null || steps === undefined) return null;\n turns.push({ id: turn.id, messages, steps });\n }\n return { turns, more };\n}\n\n/** A `history/page` answer to `{turn, before?, steps}`, or `null` when it is malformed. */\nexport function readTurnStepsAnswer(payload: unknown): DeepAgentTurnStepsAnswer | null {\n if (!isRecord(payload) || !isId(payload.turn)) return null;\n const messages = readMessages(payload.messages);\n const more = readMore(payload.more);\n if (messages === null || more === null) return null;\n return { turn: payload.turn, messages, more };\n}\n\n/** The steps of one summarized turn fetched so far, oldest first. */\nexport interface DeepAgentHistoryTurnStepsLoaded {\n messages: LangChainMessage[];\n /** Older steps of the turn remain. */\n more: boolean;\n}\n\n/** The turns one conversation has paged in, in front of its live window. */\nexport interface DeepAgentHistorySnapshot {\n /** The conversation they belong to. */\n threadId: string;\n /** The message the first page was asked `before`: the live window's first message then. */\n anchor: string;\n /** Whether the anchor is a reply rather than a prompt: the newest turn's rest is in the live window. */\n anchorInsideTurn: boolean;\n /** Turns, oldest first. */\n turns: DeepAgentHistoryTurn[];\n /** Older turns remain beyond the first. */\n more: boolean;\n /** Steps fetched per summarized turn id. */\n steps: ReadonlyMap<string, DeepAgentHistoryTurnStepsLoaded>;\n}\n\n/** How a store asks the host: the thread's `sendCommand` (its answer, the command's payload). */\nexport type DeepAgentHistorySend = (command: HistoryPageCommand | TurnStepsCommand) => unknown;\n\n/**\n * The history paged in for the open conversation: a subscribable store the\n * thread's converter joins in front of its live window and the window sync\n * fills. One per provider, like the tool-output store; it holds one\n * conversation at a time and resets when another one pages.\n *\n * Everything history pages do runs through the store's methods, so a surface\n * that creates no store (it never pages by command) bundles none of it: the\n * shared thread and window sync only call `historyPages?.…`.\n */\nexport interface DeepAgentHistoryStore {\n /** The current snapshot (a new object on every change), or `null` when empty. */\n getSnapshot(): DeepAgentHistorySnapshot | null;\n subscribe(listener: () => void): () => void;\n /**\n * Adds a page asked `before` a message. A page for another conversation, or\n * asked before a message other than the oldest turn held, starts over.\n */\n addPage(page: {\n threadId: string;\n before: string;\n beforeIsPrompt: boolean;\n answer: DeepAgentHistoryPageAnswer;\n }): void;\n /** Adds one summarized turn's older steps. */\n addSteps(steps: { threadId: string; answer: DeepAgentTurnStepsAnswer }): void;\n /** Whether a steps request for the turn is in flight — the loader's dedupe. */\n isLoadingSteps(turn: string): boolean;\n setLoadingSteps(turn: string, loading: boolean): void;\n clear(): void;\n /**\n * The transcript to render: the held turns joined in front of the live\n * window ({@link joinDeepAgentHistory}), and whether they reach the\n * transcript's start (`more.before` false). `live` alone, `atStart` false,\n * while nothing held meets the window.\n */\n join(options: {\n threadId: string | undefined;\n live: LangChainMessage[];\n liveIds: ReadonlySet<string>;\n }): { messages: LangChainMessage[]; atStart: boolean };\n /** Whether the held turns no longer meet the live window ({@link isDeepAgentHistoryDetached}). */\n isDetached(options: { threadId: string | undefined; liveIds: ReadonlySet<string> }): boolean;\n /**\n * Asks the host for the turns before `before` and adds them; resolves how\n * many it answered. Rejects with the host's refusal, or when the answer is\n * not a page this client reads.\n */\n requestOlder(options: {\n send: DeepAgentHistorySend;\n threadId: string;\n before: string;\n beforeIsPrompt: boolean;\n turns?: number;\n }): Promise<number>;\n /**\n * Fetches a summarized turn's next older steps (`history/page` with its\n * `turn`) into the store, newest first. A turn already loading, or with no\n * steps left, is a no-op. Rejects with the host's refusal.\n */\n loadSteps(options: { send: DeepAgentHistorySend; marker: DeepAgentTurnStepsMarker }): Promise<void>;\n}\n\nexport function createDeepAgentHistoryStore(): DeepAgentHistoryStore {\n let snapshot: DeepAgentHistorySnapshot | null = null;\n const loadingSteps = new Set<string>();\n const listeners = new Set<() => void>();\n const publish = (next: DeepAgentHistorySnapshot | null) => {\n snapshot = next;\n for (const listener of listeners) listener();\n };\n const store: DeepAgentHistoryStore = {\n getSnapshot: () => snapshot,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n addPage({ threadId, before, beforeIsPrompt, answer }) {\n const current = snapshot;\n const continues =\n current !== null && current.threadId === threadId && current.turns[0]?.id === before;\n if (!continues) {\n loadingSteps.clear();\n publish({\n threadId,\n anchor: before,\n anchorInsideTurn: !beforeIsPrompt,\n turns: answer.turns,\n more: answer.more.before,\n steps: new Map(),\n });\n return;\n }\n const held = new Set(current.turns.map((turn) => turn.id));\n publish({\n ...current,\n turns: [...answer.turns.filter((turn) => !held.has(turn.id)), ...current.turns],\n more: answer.more.before,\n });\n },\n addSteps({ threadId, answer }) {\n const current = snapshot;\n if (current === null || current.threadId !== threadId) return;\n if (!current.turns.some((turn) => turn.id === answer.turn)) return;\n const loaded = current.steps.get(answer.turn);\n const held = new Set(loaded?.messages.map((message) => message.id));\n const steps = new Map(current.steps);\n steps.set(answer.turn, {\n messages: [\n ...answer.messages.filter((message) => !held.has(message.id)),\n ...(loaded?.messages ?? []),\n ],\n more: answer.more.before,\n });\n publish({ ...current, steps });\n },\n isLoadingSteps: (turn) => loadingSteps.has(turn),\n setLoadingSteps(turn, loading) {\n if (loading) loadingSteps.add(turn);\n else loadingSteps.delete(turn);\n },\n clear() {\n loadingSteps.clear();\n if (snapshot !== null) publish(null);\n },\n join({ threadId, live, liveIds }) {\n const history = snapshot;\n if (history === null || history.turns.length === 0 || isDeepAgentHistoryDetached({ history, threadId, liveIds })) {\n return { messages: live, atStart: false };\n }\n return { messages: joinDeepAgentHistory({ history, threadId, live, liveIds }), atStart: !history.more };\n },\n isDetached: ({ threadId, liveIds }) =>\n snapshot !== null && isDeepAgentHistoryDetached({ history: snapshot, threadId, liveIds }),\n async requestOlder({ send, threadId, before, beforeIsPrompt, turns }) {\n const answer = readHistoryPageAnswer(await send(buildHistoryPageCommand({ before, turns })));\n if (answer === null) throw new Error('history/page answered in a shape this client cannot read');\n store.addPage({ threadId, before, beforeIsPrompt, answer });\n return answer.turns.length;\n },\n async loadSteps({ send, marker }) {\n const current = snapshot;\n if (current === null || marker.hiddenSteps === 0 || loadingSteps.has(marker.turn)) return;\n // The newest turn of a page asked inside a turn: its later steps are in\n // the live window, so the steps it left out end at the page's anchor.\n const newestInsideTurn = current.anchorInsideTurn && current.turns.at(-1)?.id === marker.turn;\n const before = marker.before ?? (newestInsideTurn ? current.anchor : undefined);\n loadingSteps.add(marker.turn);\n try {\n const answer = readTurnStepsAnswer(await send(buildTurnStepsCommand({ turn: marker.turn, before })));\n if (answer === null) {\n throw new Error('history/page answered steps in a shape this client cannot read');\n }\n store.addSteps({ threadId: current.threadId, answer });\n } finally {\n loadingSteps.delete(marker.turn);\n }\n },\n };\n return store;\n}\n\n/**\n * The marker the join puts on a summarized turn's first reply message: the\n * turn's steps it has not shown yet, so a renderer reads exact counts (\"Used\n * 313 tools\") and knows whether opening it has steps to fetch.\n */\nexport interface DeepAgentTurnStepsMarker {\n /** The turn's first message: the id its steps are paged by. */\n turn: string;\n /** Steps not loaded yet. */\n hiddenSteps: number;\n /** Tool calls among them. */\n hiddenTools: number;\n /** Of which `task` delegations. */\n hiddenDelegations: number;\n /** The oldest step loaded, the next steps request's `before`. */\n before: string | undefined;\n}\n\n/**\n * The tool calls among `messages` the converter shows. The host counts every\n * call of a turn; a quiet call (`QUIET_TOOL_NAMES`) never renders, so it stays\n * in the hidden count once loaded and the turn's total holds still as its\n * steps load.\n */\nfunction toolCalls(messages: readonly LangChainMessage[]): { tools: number; delegations: number } {\n let tools = 0;\n let delegations = 0;\n for (const message of messages) {\n if (message.type !== 'ai') continue;\n for (const call of message.tool_calls ?? []) {\n if (QUIET_TOOL_NAMES.has(call.name)) continue;\n tools += 1;\n if (call.name === 'task') delegations += 1;\n }\n }\n return { tools, delegations };\n}\n\n/** The marker a join put on a source message, or `undefined`. */\nexport function readTurnStepsMarker(message: unknown): DeepAgentTurnStepsMarker | undefined {\n if (!isRecord(message) || !isRecord(message.additional_kwargs)) return undefined;\n const marker = message.additional_kwargs[DEEP_AGENT_TURN_STEPS_KEY];\n if (!isRecord(marker) || !isId(marker.turn)) return undefined;\n const { hiddenSteps, hiddenTools, hiddenDelegations, before } = marker;\n if (!isCount(hiddenSteps) || !isCount(hiddenTools) || !isCount(hiddenDelegations)) return undefined;\n return {\n turn: marker.turn,\n hiddenSteps,\n hiddenTools,\n hiddenDelegations,\n before: isId(before) ? before : undefined,\n };\n}\n\n/** The marked copy of a message, reused while the message and its marker are the same. */\nconst markedCopies = new WeakMap<object, { key: string; message: LangChainMessage }>();\n\nfunction withMarker(message: LangChainMessage, marker: DeepAgentTurnStepsMarker): LangChainMessage {\n const key = JSON.stringify(marker);\n const cached = markedCopies.get(message);\n if (cached?.key === key) return cached.message;\n // Every wire message carries `additional_kwargs` in practice; the upstream\n // type leaves it off tool messages.\n const kwargs = (message as { additional_kwargs?: Record<string, unknown> }).additional_kwargs;\n const marked = {\n ...message,\n additional_kwargs: { ...(kwargs ?? {}), [DEEP_AGENT_TURN_STEPS_KEY]: marker },\n } as LangChainMessage;\n markedCopies.set(message, { key, message: marked });\n return marked;\n}\n\n/**\n * The transcript a converter renders: the paged turns in front of the live\n * window, when they still meet it.\n *\n * The paged turns end just before the snapshot's anchor. While the anchor is\n * in `live`, they are joined in front of it, minus any message `live` already\n * holds (a reveal or an edit paged an interest page over the same range). When\n * the anchor has left the live window (an edit rewound past it, a branch\n * switch), the pages describe another transcript: `live` is returned alone,\n * and {@link isDeepAgentHistoryDetached} tells the window sync to clear them.\n *\n * Each summarized turn gets its fetched steps between its prompt and its\n * answer, and its first reply message the {@link DeepAgentTurnStepsMarker}.\n * The newest turn of a page asked inside a turn has its rest in `live`, so its\n * marker lands on the first live message after its prompt.\n */\nexport function joinDeepAgentHistory({\n history,\n threadId,\n live,\n liveIds,\n}: {\n history: DeepAgentHistorySnapshot | null;\n threadId: string | undefined;\n live: LangChainMessage[];\n /** The live window's chain ids; the anchor must be among them. */\n liveIds: ReadonlySet<string>;\n}): LangChainMessage[] {\n if (history === null || history.turns.length === 0 || isDeepAgentHistoryDetached({ history, threadId, liveIds })) {\n return live;\n }\n const joined: LangChainMessage[] = [];\n let pendingMarker: DeepAgentTurnStepsMarker | null = null;\n // The marker rides an assistant message: a tool result whose call is older\n // than what is loaded (a head that starts on one) converts to no row.\n const markNext = (message: LangChainMessage): LangChainMessage => {\n if (pendingMarker === null || message.type !== 'ai') return message;\n const marked = withMarker(message, pendingMarker);\n pendingMarker = null;\n return marked;\n };\n for (const turn of history.turns) {\n if (turn.steps === null) {\n for (const message of turn.messages) {\n if (!liveIds.has(message.id ?? '')) joined.push(message);\n }\n continue;\n }\n const loaded = history.steps.get(turn.id)?.messages ?? [];\n const [first, ...rest] = turn.messages;\n const prompt = first?.type === 'human' ? first : undefined;\n const answer = prompt === undefined ? turn.messages : rest;\n // The host counts only the messages the page left out; of those, the\n // steps paged in since render on their own, so they leave the hidden count.\n const paged = toolCalls(loaded);\n pendingMarker = {\n turn: turn.id,\n hiddenSteps: Math.max(0, turn.steps.count - loaded.length),\n hiddenTools: Math.max(0, turn.steps.tools - paged.tools),\n hiddenDelegations: Math.max(0, turn.steps.delegations - paged.delegations),\n before: loaded[0]?.id,\n };\n for (const message of [...(prompt ? [prompt] : []), ...loaded, ...answer]) {\n if (liveIds.has(message.id ?? '')) continue;\n joined.push(markNext(message));\n }\n // A summarized turn with no reply shown carries its marker no further,\n // except the newest one of a page asked inside a turn: its rest is live.\n if (pendingMarker !== null && (turn !== history.turns.at(-1) || !history.anchorInsideTurn)) {\n pendingMarker = null;\n }\n }\n for (const message of live) joined.push(markNext(message));\n return joined;\n}\n\n/** Whether the paged turns no longer meet the live window: another conversation, or the anchor left it. */\nexport function isDeepAgentHistoryDetached({\n history,\n threadId,\n liveIds,\n}: {\n history: DeepAgentHistorySnapshot;\n threadId: string | undefined;\n liveIds: ReadonlySet<string>;\n}): boolean {\n if (threadId !== undefined && history.threadId !== threadId) return true;\n return liveIds.size > 0 && !liveIds.has(history.anchor);\n}\n"],"names":[],"mappings":"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"}
|