@brainpilot/runtime 0.0.5 → 0.0.6
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 +61 -0
- package/dist/agent-error.d.ts +51 -0
- package/dist/agent-error.d.ts.map +1 -0
- package/dist/agent-error.js +163 -0
- package/dist/agent-error.js.map +1 -0
- package/dist/agent-factory.d.ts.map +1 -1
- package/dist/agent-factory.js +36 -6
- package/dist/agent-factory.js.map +1 -1
- package/dist/events.d.ts +18 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +24 -0
- package/dist/events.js.map +1 -1
- package/dist/extensions/agent-status.d.ts +91 -0
- package/dist/extensions/agent-status.d.ts.map +1 -0
- package/dist/extensions/agent-status.js +103 -0
- package/dist/extensions/agent-status.js.map +1 -0
- package/dist/extensions/trace-reminder.d.ts +94 -0
- package/dist/extensions/trace-reminder.d.ts.map +1 -0
- package/dist/extensions/trace-reminder.js +153 -0
- package/dist/extensions/trace-reminder.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mailbox.d.ts +37 -1
- package/dist/mailbox.d.ts.map +1 -1
- package/dist/mailbox.js +79 -2
- package/dist/mailbox.js.map +1 -1
- package/dist/mas-agent.d.ts +74 -12
- package/dist/mas-agent.d.ts.map +1 -1
- package/dist/mas-agent.js +158 -33
- package/dist/mas-agent.js.map +1 -1
- package/dist/materialize-skills.d.ts +40 -0
- package/dist/materialize-skills.d.ts.map +1 -0
- package/dist/materialize-skills.js +141 -0
- package/dist/materialize-skills.js.map +1 -0
- package/dist/mock-agent.d.ts.map +1 -1
- package/dist/mock-agent.js +13 -1
- package/dist/mock-agent.js.map +1 -1
- package/dist/personas.d.ts +16 -0
- package/dist/personas.d.ts.map +1 -1
- package/dist/personas.js +651 -8
- package/dist/personas.js.map +1 -1
- package/dist/pi-provider.d.ts +5 -0
- package/dist/pi-provider.d.ts.map +1 -1
- package/dist/pi-provider.js +7 -1
- package/dist/pi-provider.js.map +1 -1
- package/dist/provider-config.d.ts +5 -0
- package/dist/provider-config.d.ts.map +1 -1
- package/dist/provider-config.js +2 -0
- package/dist/provider-config.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +82 -8
- package/dist/server.js.map +1 -1
- package/dist/session-manager.d.ts +311 -8
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +896 -39
- package/dist/session-manager.js.map +1 -1
- package/dist/tools/skill-search.d.ts +53 -0
- package/dist/tools/skill-search.d.ts.map +1 -0
- package/dist/tools/skill-search.js +269 -0
- package/dist/tools/skill-search.js.map +1 -0
- package/dist/tools/system-tools.d.ts +22 -1
- package/dist/tools/system-tools.d.ts.map +1 -1
- package/dist/tools/system-tools.js +149 -21
- package/dist/tools/system-tools.js.map +1 -1
- package/dist/trace.d.ts +27 -1
- package/dist/trace.d.ts.map +1 -1
- package/dist/trace.js +60 -3
- package/dist/trace.js.map +1 -1
- package/dist/types.d.ts +51 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AgUiEvent, type AgentStatus, type FileContent, type FileEntry, type Session, type SessionTokenUsage, type TraceGraph } from "@brainpilot/protocol";
|
|
2
2
|
import { MasAgent } from "./mas-agent.js";
|
|
3
3
|
import { McpBridge } from "./mcp-bridge.js";
|
|
4
4
|
import type { AgentSessionFactory, EventListener } from "./types.js";
|
|
@@ -11,6 +11,20 @@ export interface SessionManagerOptions {
|
|
|
11
11
|
persist?: boolean;
|
|
12
12
|
/** Override the external MCP bridge (default: real stdio bridge). Tests inject a fake. */
|
|
13
13
|
mcpBridge?: McpBridge;
|
|
14
|
+
/**
|
|
15
|
+
* Absolute path to the directory of user-editable skills loaded through Pi's
|
|
16
|
+
* native skill pipeline (`additionalSkillPaths`). When omitted, defaults to
|
|
17
|
+
* `<dataRoot>/bp_template/skills`. The built-in skill content is materialized
|
|
18
|
+
* here on first use (see `materializeSkills`).
|
|
19
|
+
*/
|
|
20
|
+
skillsDir?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Absolute path to the directory backing the `skill_search` tool (the second
|
|
23
|
+
* skill-loading path — long-tail domain library NOT exposed via Pi's
|
|
24
|
+
* `<available_skills>`). When omitted, defaults to
|
|
25
|
+
* `<dataRoot>/bp_template/skills-router`. Materialized alongside `skillsDir`.
|
|
26
|
+
*/
|
|
27
|
+
routerSkillsDir?: string;
|
|
14
28
|
/**
|
|
15
29
|
* Memory budget in bytes (issue #20 / R-4). When set, an opt-in soft watchdog
|
|
16
30
|
* refuses new work past ~85% of the budget. Defaults to `BP_MEM_LIMIT_MB`
|
|
@@ -20,18 +34,48 @@ export interface SessionManagerOptions {
|
|
|
20
34
|
memLimitBytes?: number | null;
|
|
21
35
|
/** Override the watchdog's RSS reader (tests inject; default reads real RSS). */
|
|
22
36
|
readRss?: () => number;
|
|
37
|
+
/**
|
|
38
|
+
* Max estimated tokens per tool result before truncation (issue #80).
|
|
39
|
+
* When a tool returns content exceeding this threshold, the result is
|
|
40
|
+
* truncated, the full content is saved to the session workspace, and a
|
|
41
|
+
* warning is surfaced in the chat. Default: 64000 (~224KB text).
|
|
42
|
+
* Set to 0 to disable truncation entirely.
|
|
43
|
+
* Env override: BP_MAX_TOOL_RESULT_TOKENS.
|
|
44
|
+
*/
|
|
45
|
+
maxToolResultTokens?: number;
|
|
23
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Conservative token estimation from character count (issue #80).
|
|
49
|
+
* English text averages ~4 chars/token; CJK text ~1-2 chars/token.
|
|
50
|
+
* 3.5 gives a safety margin — we'd rather truncate slightly early than
|
|
51
|
+
* overflow the provider's context window. Exported for tests.
|
|
52
|
+
*/
|
|
53
|
+
export declare function estimateTokens(text: string): number;
|
|
24
54
|
export declare class SessionManager {
|
|
25
55
|
private readonly sessions;
|
|
26
56
|
private readonly dataRoot;
|
|
27
57
|
private readonly agentFactory;
|
|
28
58
|
private readonly persist;
|
|
29
59
|
private lastActivityAt;
|
|
60
|
+
private readonly deliveryLoops;
|
|
30
61
|
private mcpBridge;
|
|
31
62
|
private mcpTools;
|
|
32
63
|
private mcpLoaded;
|
|
64
|
+
private readonly skillsDir;
|
|
65
|
+
private readonly routerSkillsDir;
|
|
66
|
+
private skillsMaterialized;
|
|
33
67
|
private readonly memWatchdog;
|
|
68
|
+
private readonly maxToolResultTokens;
|
|
34
69
|
constructor(opts?: SessionManagerOptions);
|
|
70
|
+
/**
|
|
71
|
+
* Materialize the bundled @brainpilot/skills content into `this.skillsDir`
|
|
72
|
+
* (skip-if-exists) so Pi's native skill pipeline can load it. Idempotent —
|
|
73
|
+
* runs at most once per manager. Called at server startup (so skills exist and
|
|
74
|
+
* are user-visible before any agent runs, incl. Docker pure-compose where no
|
|
75
|
+
* CLI scaffold ran) AND lazily before the first non-trace agent. Best-effort:
|
|
76
|
+
* skills are a convenience, not a hard dependency, so failures are swallowed.
|
|
77
|
+
*/
|
|
78
|
+
ensureSkillsMaterialized(): Promise<void>;
|
|
35
79
|
/**
|
|
36
80
|
* Load external MCP tools once. No-op in mock mode (BP_MOCK=1) and when no
|
|
37
81
|
* `mcp_servers.json` is present, so the default path stays zero-overhead.
|
|
@@ -39,11 +83,24 @@ export declare class SessionManager {
|
|
|
39
83
|
private ensureMcpTools;
|
|
40
84
|
private bpDir;
|
|
41
85
|
private workspaceDir;
|
|
86
|
+
/**
|
|
87
|
+
* #60: composer uploads in single-user mode are POSTed against the literal
|
|
88
|
+
* sandbox id `"local"` (the web `LOCAL_SANDBOX.id`), because a file can be
|
|
89
|
+
* attached in the draft composer *before* the real session exists. They land
|
|
90
|
+
* in `workspaces/local/` — but the agent's cwd is `workspaces/<sessionId>/`,
|
|
91
|
+
* so without this it can't read the file the user just attached. We treat
|
|
92
|
+
* `workspaces/local/` as a staging area and drain it into the real session
|
|
93
|
+
* workspace right before the agent runs (see drainLocalUploads).
|
|
94
|
+
*/
|
|
95
|
+
private static readonly UPLOAD_STAGING_SID;
|
|
96
|
+
/**
|
|
97
|
+
* #97: max CONSECUTIVE failed delivery runs for one expert before the failure
|
|
98
|
+
* is escalated to the principal instead of self-retried. Matches the legacy
|
|
99
|
+
* circuit-breaker threshold (3). Only `retryable` errors consume retries;
|
|
100
|
+
* a `fatal` error escalates on the first failure regardless of this cap.
|
|
101
|
+
*/
|
|
102
|
+
private static readonly MAX_DELIVERY_RETRIES;
|
|
42
103
|
private historyPath;
|
|
43
|
-
/** Skills shared by every session (user-editable `bp_template/skills/`). */
|
|
44
|
-
private templateSkillsDir;
|
|
45
|
-
/** This session's own skill dir (`.bp/<sid>/skills/`), overrides/augments the template. */
|
|
46
|
-
private sessionSkillsDir;
|
|
47
104
|
/** User-editable persona override for an agent (`bp_template/agents/<name>/prompt.md`). */
|
|
48
105
|
private agentPromptPath;
|
|
49
106
|
/**
|
|
@@ -64,6 +121,35 @@ export declare class SessionManager {
|
|
|
64
121
|
readSessionFileRaw(sid: string, rel: string): Promise<Buffer>;
|
|
65
122
|
/** Delete a workspace file. Returns false if it was already gone. */
|
|
66
123
|
deleteSessionFile(sid: string, rel: string): Promise<boolean>;
|
|
124
|
+
/**
|
|
125
|
+
* #47: write an uploaded file into the session workspace. Content arrives
|
|
126
|
+
* base64-encoded (binary-safe over the JSON byte chain). The same
|
|
127
|
+
* `resolveWorkspacePath` guard prevents path traversal; parent dirs are
|
|
128
|
+
* created so an upload like `docs/foo.pdf` works. The file lands in the
|
|
129
|
+
* agent's cwd, so it can `read` it by its workspace-relative path.
|
|
130
|
+
* `maxBytes` (default 20 MiB) bounds the decoded size.
|
|
131
|
+
*/
|
|
132
|
+
writeSessionFile(sid: string, rel: string, contentBase64: string, maxBytes?: number): Promise<{
|
|
133
|
+
path: string;
|
|
134
|
+
size: number;
|
|
135
|
+
}>;
|
|
136
|
+
/**
|
|
137
|
+
* #60: drain the composer upload staging area (`workspaces/local/`) into a
|
|
138
|
+
* real session's workspace so the agent — whose cwd is `workspaces/<sid>/` —
|
|
139
|
+
* can read files the user attached in the draft composer (when no real
|
|
140
|
+
* session id existed yet, the web uploads against the literal `"local"`
|
|
141
|
+
* sandbox id). Called right before the agent runs.
|
|
142
|
+
*
|
|
143
|
+
* Move semantics: each staged entry is renamed into the session workspace
|
|
144
|
+
* (an existing same-named entry in the session is left untouched and the
|
|
145
|
+
* staged copy is discarded), then the staging area is emptied so files never
|
|
146
|
+
* leak into the next session. No-op when the target IS the staging sid, or
|
|
147
|
+
* when the staging dir is missing/empty. Best-effort: never throws — a copy
|
|
148
|
+
* failure must not block the user's prompt.
|
|
149
|
+
*/
|
|
150
|
+
private drainLocalUploads;
|
|
151
|
+
/** Recursively copy a file or directory tree (drainLocalUploads fallback). */
|
|
152
|
+
private copyEntry;
|
|
67
153
|
/**
|
|
68
154
|
* Resolve an agent's system persona. Prefers the user-editable on-disk
|
|
69
155
|
* `bp_template/agents/<name>/prompt.md` (so personas can be tuned without a
|
|
@@ -76,6 +162,17 @@ export declare class SessionManager {
|
|
|
76
162
|
title?: string;
|
|
77
163
|
providerId?: string;
|
|
78
164
|
modelId?: string;
|
|
165
|
+
},
|
|
166
|
+
/**
|
|
167
|
+
* Internal restore path (see `restoreFromDisk`): when provided, the entry
|
|
168
|
+
* inherits the on-disk meta.json timestamps verbatim instead of stamping
|
|
169
|
+
* fresh ones, and `writeMeta` is skipped so the canonical file is not
|
|
170
|
+
* clobbered with boot-time values. Public callers should not pass this.
|
|
171
|
+
*/
|
|
172
|
+
_restore?: {
|
|
173
|
+
createdAt: string;
|
|
174
|
+
updatedAt: string;
|
|
175
|
+
lastActivityAt: number;
|
|
79
176
|
}): Promise<Session>;
|
|
80
177
|
getSession(id: string): Session | undefined;
|
|
81
178
|
/**
|
|
@@ -92,17 +189,182 @@ export declare class SessionManager {
|
|
|
92
189
|
agentsKilled: number;
|
|
93
190
|
}>;
|
|
94
191
|
/** Send a user message to an agent (default principal). §7 L3 isolated. */
|
|
95
|
-
sendMessage(sessionId: string, content: string, agentName?: string
|
|
192
|
+
sendMessage(sessionId: string, content: string, agentName?: string, opts?: {
|
|
193
|
+
uuid?: string;
|
|
194
|
+
}): Promise<{
|
|
96
195
|
accepted: boolean;
|
|
97
196
|
runId?: string;
|
|
98
197
|
}>;
|
|
99
|
-
/**
|
|
198
|
+
/**
|
|
199
|
+
* Ask the terminal user a question on behalf of `agent`. Emits a
|
|
200
|
+
* `user_input_request` event and returns a promise that resolves when
|
|
201
|
+
* `resolveInput` is called with the matching request_id, or rejects if the
|
|
202
|
+
* session is interrupted/evicted. Blocks the calling tool's turn.
|
|
203
|
+
*/
|
|
204
|
+
private requestUserInput;
|
|
205
|
+
/**
|
|
206
|
+
* Resolve an outstanding ask_user request. Returns false when the session or
|
|
207
|
+
* request_id is unknown/already consumed (stale answer). Pure lookup; never
|
|
208
|
+
* throws — the server handles 404 for unknown sessions before calling.
|
|
209
|
+
*/
|
|
210
|
+
resolveInput(sessionId: string, requestId: string, answer: string): boolean;
|
|
211
|
+
/**
|
|
212
|
+
* Interrupt a session (or a specific agent).
|
|
213
|
+
*
|
|
214
|
+
* Targeted (`agentName` given): abort just that agent. Mailboxes and the
|
|
215
|
+
* principal are left untouched — a narrow "stop this one expert" contract.
|
|
216
|
+
*
|
|
217
|
+
* Whole-session (`agentName` omitted, the Stop button — #90): abort EVERY
|
|
218
|
+
* agent (incl. their running script subprocesses, via Pi `session.abort()`),
|
|
219
|
+
* then clear ALL mailboxes so a queued message can't re-wake a stopped agent,
|
|
220
|
+
* surface a user-facing system_message, and immediately prompt the principal
|
|
221
|
+
* one run with an interrupt notice so PI knows the user interrupted and should
|
|
222
|
+
* await further instructions.
|
|
223
|
+
*/
|
|
100
224
|
interrupt(sessionId: string, agentName?: string): Promise<boolean>;
|
|
225
|
+
/**
|
|
226
|
+
* #90: after a whole-session Stop, prompt the principal one run with an
|
|
227
|
+
* interrupt notice. Mirrors `sendMessage`'s fire-and-track run accounting but
|
|
228
|
+
* emits NO role:"user" text chunk — the notice is system context, not a user
|
|
229
|
+
* bubble. The principal should acknowledge briefly and await the user.
|
|
230
|
+
*/
|
|
231
|
+
private notifyPrincipalInterrupted;
|
|
232
|
+
/** Test/diagnostic accessor: number of queued messages in `agent`'s inbox. */
|
|
233
|
+
mailboxCount(sessionId: string, agent: string): number;
|
|
234
|
+
/**
|
|
235
|
+
* Wrap a SystemTool so its execute() results are guarded against overflowing
|
|
236
|
+
* the model's context window (issue #80). When truncation triggers, the full
|
|
237
|
+
* result is saved to `<workspace>/.truncated/` and a system_message warning
|
|
238
|
+
* is emitted. No-op when maxToolResultTokens is 0.
|
|
239
|
+
*/
|
|
240
|
+
private wrapToolWithTruncation;
|
|
241
|
+
/**
|
|
242
|
+
* Estimate tokens in a tool result, truncate if over budget, save the full
|
|
243
|
+
* content to the session workspace, and emit a warning event.
|
|
244
|
+
*/
|
|
245
|
+
private truncateToolResult;
|
|
101
246
|
/** Ensure an agent exists (create or resurrect). */
|
|
102
247
|
ensureAgent(sessionId: string, name: string): Promise<MasAgent>;
|
|
248
|
+
/**
|
|
249
|
+
* 意图二 fallback — the trace-reminder extension calls this (via the factory's
|
|
250
|
+
* `onUnreplied`) when an expert was reminded once and STILL did not
|
|
251
|
+
* `send_message` its delegator (the "silence" path; a hard *error* run is
|
|
252
|
+
* handled separately). We write a NEUTRAL system note into the REAL delegator's
|
|
253
|
+
* mailbox and wake it so it never dead-waits. The delegator is whoever last
|
|
254
|
+
* delegated to this expert (#97 directed escalation), falling back to the
|
|
255
|
+
* principal. This fires during the expert's run (before the clean-run cleanup
|
|
256
|
+
* in `runDeliveryLoop`), so the delegator record is still present. The note
|
|
257
|
+
* only states the fact — the expert ended without delivering a result — and
|
|
258
|
+
* deliberately gives NO directive ("re-delegate", "proceed without it"): the
|
|
259
|
+
* delegator decides what to do. Best-effort: a failed write must never break
|
|
260
|
+
* the agent loop.
|
|
261
|
+
*/
|
|
262
|
+
private writeFallbackToDelegator;
|
|
263
|
+
/**
|
|
264
|
+
* #97: snapshot the live team status for injection into the principal's turn
|
|
265
|
+
* (via the agent-status extension's Pi `context` hook). Lists every agent —
|
|
266
|
+
* INCLUDING the principal itself, so it sees its own inbox backlog — with its
|
|
267
|
+
* authoritative status and the number of messages still queued unread in its
|
|
268
|
+
* inbox (`mailbox.count`). Excludes the trace agent (an internal recorder) and
|
|
269
|
+
* any stopped agent (destroyed; irrelevant to current coordination). Returns
|
|
270
|
+
* "" when nothing is worth reporting so the extension injects nothing.
|
|
271
|
+
*/
|
|
272
|
+
private renderAgentStatus;
|
|
103
273
|
destroyAgent(sessionId: string, name: string): Promise<void>;
|
|
274
|
+
/**
|
|
275
|
+
* #76: wake `name` to consume its mailbox. Fire-and-forget — `send_message`
|
|
276
|
+
* calls this after writing; the actual run happens in a serial delivery loop.
|
|
277
|
+
* The re-entrancy guard (`deliveryLoops`) means concurrent wakes for the same
|
|
278
|
+
* agent collapse into the one already-running loop (which re-drains after each
|
|
279
|
+
* turn), so an agent's `prompt` is never invoked concurrently.
|
|
280
|
+
*/
|
|
281
|
+
private wakeAgent;
|
|
282
|
+
/**
|
|
283
|
+
* Drain `name`'s inbox and run it, looping so messages that arrive *during* a
|
|
284
|
+
* turn are picked up without a second external wake. Each iteration atomically
|
|
285
|
+
* drains the inbox, ensures the agent, wraps the messages as
|
|
286
|
+
* `<message_envelope>`s (the format the A2A persona documents), and prompts.
|
|
287
|
+
* `MasAgent.prompt` is error-isolated (never throws), so a failed expert turn
|
|
288
|
+
* ends the loop cleanly rather than rejecting. A `session_state` frame is
|
|
289
|
+
* emitted on entry and exit so the derived run-active flag reflects the
|
|
290
|
+
* delegated work even across the await gap between the sender finishing and
|
|
291
|
+
* the target starting.
|
|
292
|
+
*/
|
|
293
|
+
private runDeliveryLoop;
|
|
294
|
+
/**
|
|
295
|
+
* #97: react to a failed delegated expert run. Returns true when a self-retry
|
|
296
|
+
* was queued (the loop should continue and re-drain the agent's own inbox),
|
|
297
|
+
* false when the failure was escalated to the principal (the loop should stop).
|
|
298
|
+
*
|
|
299
|
+
* Policy:
|
|
300
|
+
* - `retryable` (rate limit / 5xx / network) AND under the retry cap →
|
|
301
|
+
* re-wake the SAME expert with a neutral system nudge in its own inbox, and
|
|
302
|
+
* surface a `warning` to the user ("retrying n/N"). Re-running may succeed.
|
|
303
|
+
* - `fatal` (auth / missing key / forbidden), OR the cap is reached →
|
|
304
|
+
* escalate: write a NEUTRAL error note to the principal's mailbox + wake it,
|
|
305
|
+
* surface an `error` to the user, and reset the streak so a future task to
|
|
306
|
+
* this expert starts fresh.
|
|
307
|
+
*/
|
|
308
|
+
private handleDeliveryError;
|
|
309
|
+
/**
|
|
310
|
+
* #97 directed escalation: resolve who an expert's failure/silence should be
|
|
311
|
+
* reported to. Returns the recorded delegator ONLY when it is a still-live,
|
|
312
|
+
* non-trace agent other than the expert itself (a destroyed/stopped delegator
|
|
313
|
+
* would be wrongly resurrected by the wake, and a self/system target is
|
|
314
|
+
* nonsensical). Otherwise falls back to `principal`, the root coordinator,
|
|
315
|
+
* which always exists and owns un-rooted work.
|
|
316
|
+
*/
|
|
317
|
+
private delegatorFor;
|
|
318
|
+
/**
|
|
319
|
+
* #97 error escalation: write a NEUTRAL, error-flavored system note into the
|
|
320
|
+
* REAL delegator's mailbox and wake it, so whoever delegated the work (the
|
|
321
|
+
* principal, or another agent in a chain like auditor→engineer) learns the
|
|
322
|
+
* expert failed rather than dead-waiting. Distinct from
|
|
323
|
+
* `writeFallbackToDelegator` (the "silence" path): this one states an ERROR
|
|
324
|
+
* occurred and carries the error headline as context, but — like the silence
|
|
325
|
+
* note — gives NO directive ("re-delegate" / "proceed"): the delegator decides.
|
|
326
|
+
* Best-effort; never breaks the loop.
|
|
327
|
+
*/
|
|
328
|
+
private writeErrorToDelegator;
|
|
329
|
+
/**
|
|
330
|
+
* Wrap drained mailbox messages in the `<message_envelope>` header the A2A
|
|
331
|
+
* persona (`personas.ts`) tells agents to expect, so the model knows who sent
|
|
332
|
+
* each message and why. User-origin messages declare `<source type="user"/>`;
|
|
333
|
+
* agent-origin ones name the sender.
|
|
334
|
+
*
|
|
335
|
+
* 意图一·触发点2 (Pi-native hooks): when the PRINCIPAL receives a message from
|
|
336
|
+
* another agent (not the user — i.e. an expert reporting back), append a single
|
|
337
|
+
* static line nudging it to record_trace any real decision it makes while
|
|
338
|
+
* processing the reply. Stateless, loop-free (at most one line per delivery).
|
|
339
|
+
*/
|
|
340
|
+
private renderEnvelopes;
|
|
104
341
|
/** §10 polling fallback: list agents with authoritative status. */
|
|
105
342
|
listAgents(sessionId: string): AgentStatus[];
|
|
343
|
+
/**
|
|
344
|
+
* #76: a session is "running" whenever ANY non-trace agent is running, or a
|
|
345
|
+
* mailbox delivery loop is pending for a non-trace target (the loop is
|
|
346
|
+
* registered synchronously inside `send_message`, so this closes the await gap
|
|
347
|
+
* between the sender finishing its turn and the delegated target starting —
|
|
348
|
+
* without it the flag would flicker false in that window). The trace agent is
|
|
349
|
+
* a real spawned agent (record_trace dispatches `trace_event` envelopes into
|
|
350
|
+
* its mailbox and it owns the Graph of Trace as editor, see
|
|
351
|
+
* `system-tools.ts:createRecordTraceTool`), but it is excluded from the
|
|
352
|
+
* AGGREGATE: a trace recording isn't "the user's task is still running". It
|
|
353
|
+
* is still LISTED in `agents[]` with its own status so the Agents panel shows
|
|
354
|
+
* its idle/running transitions live.
|
|
355
|
+
*/
|
|
356
|
+
private deriveRunActive;
|
|
357
|
+
/**
|
|
358
|
+
* #70/#76: emit the authoritative live snapshot as a `CUSTOM:session_state`
|
|
359
|
+
* event. This is the wholesale source the web Agents panel replaces its
|
|
360
|
+
* agents list from; it is pushed on every agent status transition
|
|
361
|
+
* (`onStatusChange`), an initial frame in `sendMessage`, and on delivery-loop
|
|
362
|
+
* entry/exit. `runState.active` is DERIVED (any non-trace agent running / a
|
|
363
|
+
* pending delivery), so a delegated expert keeps the run visibly active. The
|
|
364
|
+
* ring buffer replays the last frame on reconnect, so a re-subscribing client
|
|
365
|
+
* recovers the current snapshot. Shape matches `SessionStateSnapshotSchema`.
|
|
366
|
+
*/
|
|
367
|
+
private emitSessionState;
|
|
106
368
|
getSessionState(sessionId: string): {
|
|
107
369
|
runState: {
|
|
108
370
|
active: boolean;
|
|
@@ -110,9 +372,34 @@ export declare class SessionManager {
|
|
|
110
372
|
};
|
|
111
373
|
agents: AgentStatus[];
|
|
112
374
|
lastActivityTs: string;
|
|
375
|
+
tokenUsage: SessionTokenUsage;
|
|
113
376
|
} | undefined;
|
|
114
377
|
/** The session's Graph of Trace (reasoning DAG), or undefined if no session. */
|
|
115
378
|
getTrace(sessionId: string): TraceGraph | undefined;
|
|
379
|
+
/**
|
|
380
|
+
* Read persisted AG-UI events for a session from `.bp/<sid>/events.jsonl`.
|
|
381
|
+
* Used by the web to rehydrate chat history after a runtime restart (the
|
|
382
|
+
* in-memory bus ring buffer only carries `recent()` for live SSE replay).
|
|
383
|
+
*
|
|
384
|
+
* The file is read line-by-line and unparseable lines are skipped so a
|
|
385
|
+
* single corrupt record doesn't poison the whole history.
|
|
386
|
+
*
|
|
387
|
+
* `limit` caps the returned array; when total > limit we return the **tail**
|
|
388
|
+
* (most recent events) for lightweight callers. Default 1000, positive
|
|
389
|
+
* limits are capped at 5000. `limit <= 0` returns the full log and is used by
|
|
390
|
+
* the web rehydrate path so long sessions are not sliced through the middle
|
|
391
|
+
* of a streamed message.
|
|
392
|
+
*
|
|
393
|
+
* Returns `undefined` if the session id isn't in memory — this method is
|
|
394
|
+
* only useful for known sessions (call `restoreFromDisk` first if needed).
|
|
395
|
+
*/
|
|
396
|
+
readEventHistory(sessionId: string, opts?: {
|
|
397
|
+
limit?: number;
|
|
398
|
+
}): Promise<{
|
|
399
|
+
events: AgUiEvent[];
|
|
400
|
+
total: number;
|
|
401
|
+
truncated: boolean;
|
|
402
|
+
} | undefined>;
|
|
116
403
|
metrics(): {
|
|
117
404
|
activeSessions: number;
|
|
118
405
|
runningAgents: number;
|
|
@@ -145,7 +432,23 @@ export declare class SessionManager {
|
|
|
145
432
|
/** Load a session's stored provider ref from disk (restore path). */
|
|
146
433
|
private readProviderRef;
|
|
147
434
|
private loadTrace;
|
|
148
|
-
|
|
435
|
+
private usagePath;
|
|
436
|
+
/** Persist cumulative token usage (best-effort; never throws). */
|
|
437
|
+
private writeUsage;
|
|
438
|
+
/** Rehydrate cumulative token usage from disk (restore path). */
|
|
439
|
+
private loadUsage;
|
|
440
|
+
/**
|
|
441
|
+
* Restore session list from disk. Reads `<dataRoot>/.bp/<id>/meta.json` for
|
|
442
|
+
* every directory and recreates the session entry with its original
|
|
443
|
+
* timestamps preserved (provider ref, mailbox, trace also rehydrate via the
|
|
444
|
+
* normal `createSession` restore path). §10 策略A: agents start idle and
|
|
445
|
+
* are lazily revived when the user actually sends a message.
|
|
446
|
+
*
|
|
447
|
+
* Idempotent — sessions already in memory are skipped, not reset.
|
|
448
|
+
*
|
|
449
|
+
* Returns the ids that were restored this call (i.e. excluding ones that
|
|
450
|
+
* were already loaded or whose meta.json was missing / malformed).
|
|
451
|
+
*/
|
|
149
452
|
restoreFromDisk(): Promise<string[]>;
|
|
150
453
|
}
|
|
151
454
|
//# sourceMappingURL=session-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"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"}
|