@brainpilot/runtime 0.0.4 → 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 +45 -10
- 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/mcp-bridge.d.ts +15 -2
- package/dist/mcp-bridge.d.ts.map +1 -1
- package/dist/mcp-bridge.js +53 -10
- package/dist/mcp-bridge.js.map +1 -1
- package/dist/mem-watchdog.d.ts +63 -0
- package/dist/mem-watchdog.d.ts.map +1 -0
- package/dist/mem-watchdog.js +81 -0
- package/dist/mem-watchdog.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 +32 -1
- package/dist/pi-provider.d.ts.map +1 -1
- package/dist/pi-provider.js +70 -0
- package/dist/pi-provider.js.map +1 -1
- package/dist/provider-config.d.ts +23 -0
- package/dist/provider-config.d.ts.map +1 -0
- package/dist/provider-config.js +49 -0
- package/dist/provider-config.js.map +1 -0
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +146 -8
- package/dist/server.js.map +1 -1
- package/dist/session-manager.d.ts +367 -8
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +1082 -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 +61 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-status — a Pi-native extension that injects a fresh team-status block
|
|
3
|
+
* at the top of EVERY turn for the agent it is registered on (#97).
|
|
4
|
+
*
|
|
5
|
+
* Why an extension / the `context` hook (not the system prompt):
|
|
6
|
+
* - The per-role persona is injected via `appendSystemPrompt`, which Pi
|
|
7
|
+
* evaluates ONCE at session creation. A team-status snapshot put there would
|
|
8
|
+
* be frozen at "session start" and go stale immediately.
|
|
9
|
+
* - Pi's `context` hook fires before EACH LLM call (every turn within a run)
|
|
10
|
+
* and lets an extension non-destructively rewrite the `messages` array that
|
|
11
|
+
* is sent to the model. That rewrite is per-turn EPHEMERAL — it is applied to
|
|
12
|
+
* a local copy and is NOT persisted to the session history (events.jsonl).
|
|
13
|
+
* So a status block injected here is recomputed and current on every turn,
|
|
14
|
+
* and never accumulates stale snapshots on disk.
|
|
15
|
+
*
|
|
16
|
+
* Mechanism (Pi SDK, verified against the docs corpus):
|
|
17
|
+
* - Registered per-AgentSession via DefaultResourceLoader.extensionFactories,
|
|
18
|
+
* same as trace-reminder. Closure state is naturally per-agent.
|
|
19
|
+
* - `context` handler receives `{ messages }` (a safe-to-mutate copy) and may
|
|
20
|
+
* return `{ messages }` to replace what the model sees this turn.
|
|
21
|
+
* - Because the host appends a NEW block each turn, we first STRIP any block we
|
|
22
|
+
* injected on a previous turn (identified by the `<agent_status>` opener) so
|
|
23
|
+
* the model only ever sees the latest snapshot, not a pile of old ones.
|
|
24
|
+
*
|
|
25
|
+
* Only the real factory loads this — the mock has no Pi event loop, so the
|
|
26
|
+
* behavioural injection is verified in real mode. The pure block renderer
|
|
27
|
+
* (`renderAgentStatusBlock`) and the strip/inject logic are unit-tested here via
|
|
28
|
+
* a fake `pi`.
|
|
29
|
+
*/
|
|
30
|
+
/** Opening tag — also the marker used to recognise a block we injected before. */
|
|
31
|
+
const TAG_OPEN = "<agent_status>";
|
|
32
|
+
const TAG_CLOSE = "</agent_status>";
|
|
33
|
+
/**
|
|
34
|
+
* Build the team-status block as a natural-language list (#97, option B). The
|
|
35
|
+
* wording is self-explanatory so the model needs no schema knowledge: each line
|
|
36
|
+
* names an agent, its status, and how many messages are still waiting unread in
|
|
37
|
+
* its inbox. Returns "" when there is nothing to report (caller skips injection).
|
|
38
|
+
*
|
|
39
|
+
* `lines` should already be filtered by the caller (trace agent excluded,
|
|
40
|
+
* stopped agents excluded). Order is preserved.
|
|
41
|
+
*/
|
|
42
|
+
export function renderAgentStatusBlock(lines) {
|
|
43
|
+
if (lines.length === 0)
|
|
44
|
+
return "";
|
|
45
|
+
const body = lines
|
|
46
|
+
.map((l) => {
|
|
47
|
+
const n = l.unread;
|
|
48
|
+
const msg = `${n} unread message${n === 1 ? "" : "s"}`;
|
|
49
|
+
return `- ${l.name}: ${l.status}, ${msg}`;
|
|
50
|
+
})
|
|
51
|
+
.join("\n");
|
|
52
|
+
return (`${TAG_OPEN}\n` +
|
|
53
|
+
`Current agents (status, and how many messages are still waiting unread in each inbox):\n` +
|
|
54
|
+
`${body}\n` +
|
|
55
|
+
`${TAG_CLOSE}`);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Collect the status lines for a team snapshot from the live agents (#97).
|
|
59
|
+
* Includes every agent — INCLUDING the principal, so it sees its own backlog —
|
|
60
|
+
* except the trace agent (an internal recorder) and any stopped agent
|
|
61
|
+
* (destroyed; irrelevant to coordination). `unreadOf` returns the number of
|
|
62
|
+
* messages still queued unread in that agent's inbox. Order follows iteration.
|
|
63
|
+
*/
|
|
64
|
+
export function collectAgentStatusLines(agents, unreadOf) {
|
|
65
|
+
const lines = [];
|
|
66
|
+
for (const a of agents) {
|
|
67
|
+
if (a.role === "trace")
|
|
68
|
+
continue;
|
|
69
|
+
if (a.status === "stopped")
|
|
70
|
+
continue;
|
|
71
|
+
lines.push({ name: a.name, status: a.status, unread: unreadOf(a.name) });
|
|
72
|
+
}
|
|
73
|
+
return lines;
|
|
74
|
+
}
|
|
75
|
+
/** True for a `user` message whose text is a status block we injected earlier. */
|
|
76
|
+
function isStatusMessage(m) {
|
|
77
|
+
return (m.role === "user" &&
|
|
78
|
+
m.content.some((c) => c.type === "text" && (c.text ?? "").startsWith(TAG_OPEN)));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Build the extension factory for one agent. The returned function is what Pi
|
|
82
|
+
* calls with the per-session `ExtensionAPI`.
|
|
83
|
+
*/
|
|
84
|
+
export function makeAgentStatusExt(deps) {
|
|
85
|
+
return (pi) => {
|
|
86
|
+
pi.on("context", (e) => {
|
|
87
|
+
const block = deps.renderStatus();
|
|
88
|
+
// Strip any block we injected on a previous turn so only the latest
|
|
89
|
+
// snapshot survives (the context copy is ephemeral — this never touches
|
|
90
|
+
// persisted history).
|
|
91
|
+
const stripped = e.messages.filter((m) => !isStatusMessage(m));
|
|
92
|
+
const removedSome = stripped.length !== e.messages.length;
|
|
93
|
+
if (!block) {
|
|
94
|
+
// Nothing to report this turn. Only return a rewrite if we actually
|
|
95
|
+
// removed a stale block; otherwise leave the messages untouched.
|
|
96
|
+
return removedSome ? { messages: stripped } : undefined;
|
|
97
|
+
}
|
|
98
|
+
stripped.push({ role: "user", content: [{ type: "text", text: block }] });
|
|
99
|
+
return { messages: stripped };
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=agent-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-status.js","sourceRoot":"","sources":["../../src/extensions/agent-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* trace-reminder — the one Pi-native extension (replaces #79 captureMilestone).
|
|
3
|
+
*
|
|
4
|
+
* Philosophy (vs. #79): the host no longer writes trace nodes on the agent's
|
|
5
|
+
* behalf. Instead we REMIND the agent at the right moment and let it decide:
|
|
6
|
+
* - 意图一 (work leaves a trace): if a run ended without record_trace, nudge.
|
|
7
|
+
* Applies to BOTH principal and expert (every non-trace role), not just PI.
|
|
8
|
+
* - 意图二 (expert results flow back): if an expert run produced work but never
|
|
9
|
+
* send_message'd the principal, nudge; if it still won't, the host writes a
|
|
10
|
+
* fallback note into the principal's mailbox so the PI never dead-waits.
|
|
11
|
+
* - 意图三 (PI keeps to delegation): if the principal does substantive work
|
|
12
|
+
* directly without delegating, append a soft reminder to the tool result.
|
|
13
|
+
* - 意图四 (resource awareness): on a tool error, append a soft hint that the
|
|
14
|
+
* knowledge tools / record_trace exist. (Static identity lives in personas.)
|
|
15
|
+
*
|
|
16
|
+
* 意图一 and 意图二 are ORTHOGONAL checks (B): an expert can owe both a trace
|
|
17
|
+
* and a reply. They limit independently (A — separate counters), but when BOTH
|
|
18
|
+
* lapse at the same run end they collapse into ONE merged reminder rather than
|
|
19
|
+
* two separate followUps (fewer round-trips).
|
|
20
|
+
*
|
|
21
|
+
* Mechanism (Pi SDK v0.79, verified against installed d.ts + real provider):
|
|
22
|
+
* - Registered per-AgentSession via DefaultResourceLoader.extensionFactories.
|
|
23
|
+
* Closure state is therefore naturally isolated per agent.
|
|
24
|
+
* - One prompt() == one agent loop (agent_start…agent_end) spanning MANY turns.
|
|
25
|
+
* "Did the work" flags are RUN-scoped (reset on agent_start, accumulated
|
|
26
|
+
* across turns) — resetting them on turn_start was the false-report bug.
|
|
27
|
+
* - `agent_end` / `turn_*` are pure notifications (no return value, cannot
|
|
28
|
+
* block). The ONLY "force continue" lever is `pi.sendUserMessage(text,
|
|
29
|
+
* {deliverAs:"followUp"})` inside `agent_end`: it releases the current stop
|
|
30
|
+
* and starts a NEW agent loop (a fresh agent_start) — which is why the
|
|
31
|
+
* anti-loop counters must NOT reset on agent_start.
|
|
32
|
+
* - `tool_result` MAY return `{content}` to rewrite the result text — used for
|
|
33
|
+
* the soft reminders (意图三/四).
|
|
34
|
+
*/
|
|
35
|
+
import type { AgentRole } from "../types.js";
|
|
36
|
+
/** Minimal structural surface of Pi's ExtensionAPI we depend on. */
|
|
37
|
+
interface PiExtensionApi {
|
|
38
|
+
on(event: "agent_start", handler: () => void): void;
|
|
39
|
+
on(event: "tool_execution_start", handler: (e: {
|
|
40
|
+
toolName: string;
|
|
41
|
+
args?: unknown;
|
|
42
|
+
}) => void): void;
|
|
43
|
+
on(event: "tool_execution_end", handler: (e: {
|
|
44
|
+
toolName: string;
|
|
45
|
+
isError: boolean;
|
|
46
|
+
}) => void): void;
|
|
47
|
+
on(event: "tool_result", handler: (e: {
|
|
48
|
+
toolName: string;
|
|
49
|
+
isError: boolean;
|
|
50
|
+
content: Array<{
|
|
51
|
+
type: string;
|
|
52
|
+
text?: string;
|
|
53
|
+
}>;
|
|
54
|
+
}) => {
|
|
55
|
+
content: Array<{
|
|
56
|
+
type: "text";
|
|
57
|
+
text: string;
|
|
58
|
+
}>;
|
|
59
|
+
} | void): void;
|
|
60
|
+
on(event: "agent_end", handler: (e: AgentEndLike) => void): void;
|
|
61
|
+
sendUserMessage(content: string, options?: {
|
|
62
|
+
deliverAs?: "steer" | "followUp";
|
|
63
|
+
}): void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Structural slice of Pi's `AgentEndEvent` we read: the run's message list, used
|
|
67
|
+
* only to detect whether the run ENDED IN AN ERROR (last assistant message's
|
|
68
|
+
* `stopReason`). A provider failure (401, retry exhausted, mid-stream error) is
|
|
69
|
+
* encoded by Pi as a final AssistantMessage with `stopReason: "error" |
|
|
70
|
+
* "aborted"` — it does NOT throw. When that's the case the host owns recovery
|
|
71
|
+
* (#97 self-retry / escalation), so this extension must NOT also nudge/followUp.
|
|
72
|
+
*/
|
|
73
|
+
interface AgentEndLike {
|
|
74
|
+
messages?: Array<{
|
|
75
|
+
role?: string;
|
|
76
|
+
stopReason?: string;
|
|
77
|
+
}>;
|
|
78
|
+
}
|
|
79
|
+
export interface TraceReminderDeps {
|
|
80
|
+
role: AgentRole;
|
|
81
|
+
name: string;
|
|
82
|
+
/**
|
|
83
|
+
* 意图二 fallback: invoked when an expert was reminded once and STILL did not
|
|
84
|
+
* report back. The host writes a note into the principal's mailbox.
|
|
85
|
+
*/
|
|
86
|
+
onUnreplied: (agentName: string) => void;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Build the extension factory for one agent. The returned function is what Pi
|
|
90
|
+
* calls with the per-session `ExtensionAPI`.
|
|
91
|
+
*/
|
|
92
|
+
export declare function makeTraceReminderExt(deps: TraceReminderDeps): (pi: PiExtensionApi) => void;
|
|
93
|
+
export {};
|
|
94
|
+
//# sourceMappingURL=trace-reminder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-reminder.d.ts","sourceRoot":"","sources":["../../src/extensions/trace-reminder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,oEAAoE;AACpE,UAAU,cAAc;IACtB,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACpD,EAAE,CAAC,KAAK,EAAE,sBAAsB,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACpG,EAAE,CAAC,KAAK,EAAE,oBAAoB,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACpG,EAAE,CACA,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,CAAC,CAAC,EAAE;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACjD,KAAK;QAAE,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,GAAG,IAAI,GAC9D,IAAI,CAAC;IACR,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;CACxF;AAED;;;;;;;GAOG;AACH,UAAU,YAAY;IACpB,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAeD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AA2BD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,CAAC,EAAE,EAAE,cAAc,KAAK,IAAI,CAyH1F"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/** True when the run's last assistant message ended in an error/abort. */
|
|
2
|
+
function endedInError(e) {
|
|
3
|
+
const msgs = e.messages;
|
|
4
|
+
if (!Array.isArray(msgs))
|
|
5
|
+
return false;
|
|
6
|
+
for (let i = msgs.length - 1; i >= 0; i--) {
|
|
7
|
+
const m = msgs[i];
|
|
8
|
+
if (m?.role === "assistant") {
|
|
9
|
+
return m.stopReason === "error" || m.stopReason === "aborted";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Management/coordination tools that are legitimate for a principal to call
|
|
16
|
+
* directly — they don't count as "doing the work itself" (意图三 exemption).
|
|
17
|
+
*/
|
|
18
|
+
const MGMT_TOOLS = new Set([
|
|
19
|
+
"create_agent",
|
|
20
|
+
"destroy_agent",
|
|
21
|
+
"record_trace",
|
|
22
|
+
"send_message",
|
|
23
|
+
"ask_user",
|
|
24
|
+
"get_trace_graph",
|
|
25
|
+
]);
|
|
26
|
+
const TRACE_REMINDER = "你本轮做了实质工作但尚未调用 record_trace。如果这步值得留痕,请调用 record_trace 记录后再结束。";
|
|
27
|
+
const EXPERT_REPLY_REMINDER = "你尚未通过 send_message(to=\"principal\", ...) 把结果回交给 Principal。请回交结果,否则 Principal 收不到你的产出。";
|
|
28
|
+
const MERGED_REMINDER = "你本轮尚未回交结果,也未记录关键决策。结束前请:" +
|
|
29
|
+
"① 用 send_message(to=\"principal\", ...) 回交结果;" +
|
|
30
|
+
"② 用 record_trace 记录关键决策。";
|
|
31
|
+
const DELEGATE_REMINDER = "[提醒:作为 Principal,实质工作应委派给专家,而不是自己埋头执行。]";
|
|
32
|
+
const TOOL_FAILURE_REMINDER = "[提醒:该工具调用失败。可用 record_trace 记录这次失败,或借助知识库/检索工具寻找替代方案。]";
|
|
33
|
+
/**
|
|
34
|
+
* Build the extension factory for one agent. The returned function is what Pi
|
|
35
|
+
* calls with the per-session `ExtensionAPI`.
|
|
36
|
+
*/
|
|
37
|
+
export function makeTraceReminderExt(deps) {
|
|
38
|
+
return (pi) => {
|
|
39
|
+
// Per-RUN flags — reset on agent_start (NOT turn_start). A single prompt()
|
|
40
|
+
// is one agent loop (agent_start…agent_end) spanning MANY turns, and a model
|
|
41
|
+
// naturally calls a tool in one turn then writes its closing sentence in the
|
|
42
|
+
// NEXT (tool-less) turn. Resetting on turn_start wiped the earlier turn's
|
|
43
|
+
// success, so agent_end only ever saw the last turn and falsely reported the
|
|
44
|
+
// work as undone. Keyed to the run, these accumulate across all its turns.
|
|
45
|
+
let traced = false;
|
|
46
|
+
let replied = false;
|
|
47
|
+
let delegated = false;
|
|
48
|
+
let delegateRemindCount = 0;
|
|
49
|
+
// ⚠️ Cross-run-CHAIN counters — MUST NOT reset on agent_start/turn_start nor
|
|
50
|
+
// at the top of agent_end. sendUserMessage(followUp) starts a NEW agent loop
|
|
51
|
+
// (verified: a followUp fires a fresh agent_start) whose end re-enters
|
|
52
|
+
// agent_end; if these were cleared we would re-remind forever. They are reset
|
|
53
|
+
// ONLY at the terminal exits below (dimension satisfied, or already reminded
|
|
54
|
+
// once → fallback/let-go). Decoupled per dimension (A) so a trace reminder
|
|
55
|
+
// and a reply reminder limit independently.
|
|
56
|
+
let traceRemindCount = 0;
|
|
57
|
+
let replyRemindCount = 0;
|
|
58
|
+
pi.on("agent_start", () => {
|
|
59
|
+
traced = false;
|
|
60
|
+
replied = false;
|
|
61
|
+
delegated = false;
|
|
62
|
+
delegateRemindCount = 0;
|
|
63
|
+
});
|
|
64
|
+
// tool_execution_start: nothing required for accounting (we key off
|
|
65
|
+
// tool_execution_end which carries success/failure). Kept as a no-op anchor
|
|
66
|
+
// so the wiring is obvious if richer arg capture is needed later.
|
|
67
|
+
pi.on("tool_execution_end", (e) => {
|
|
68
|
+
if (e.isError)
|
|
69
|
+
return; // only successful calls count toward "did the work"
|
|
70
|
+
const t = e.toolName;
|
|
71
|
+
if (t === "record_trace" || t.startsWith("create_trace"))
|
|
72
|
+
traced = true;
|
|
73
|
+
if (t === "send_message")
|
|
74
|
+
replied = true;
|
|
75
|
+
if (t === "create_agent")
|
|
76
|
+
delegated = true;
|
|
77
|
+
});
|
|
78
|
+
pi.on("tool_result", (e) => {
|
|
79
|
+
// 意图四 (failure hint) takes precedence; 意图三 (over-step) can stack.
|
|
80
|
+
let suffix = "";
|
|
81
|
+
if (e.isError) {
|
|
82
|
+
suffix += `\n${TOOL_FAILURE_REMINDER}`;
|
|
83
|
+
}
|
|
84
|
+
if (deps.role === "principal" &&
|
|
85
|
+
!delegated &&
|
|
86
|
+
!MGMT_TOOLS.has(e.toolName) &&
|
|
87
|
+
delegateRemindCount < 1) {
|
|
88
|
+
delegateRemindCount++;
|
|
89
|
+
suffix += `\n${DELEGATE_REMINDER}`;
|
|
90
|
+
}
|
|
91
|
+
if (!suffix)
|
|
92
|
+
return; // no rewrite — leave the result untouched
|
|
93
|
+
// Rewrite by appending to the existing text content; the tool still ran.
|
|
94
|
+
const text = e.content.map((c) => (c.type === "text" ? c.text ?? "" : "")).join("");
|
|
95
|
+
return { content: [{ type: "text", text: `${text}${suffix}` }] };
|
|
96
|
+
});
|
|
97
|
+
pi.on("agent_end", (e) => {
|
|
98
|
+
if (deps.role === "trace")
|
|
99
|
+
return; // the recorder itself — never nudge.
|
|
100
|
+
// #97: if THIS run ended in an error (provider 401 / retry exhausted /
|
|
101
|
+
// mid-stream failure), bail entirely. A followUp here would just re-hit the
|
|
102
|
+
// broken provider, and onUnreplied would mislabel an error as silence. The
|
|
103
|
+
// host's delivery-loop error path owns recovery (self-retry / escalation).
|
|
104
|
+
if (endedInError(e))
|
|
105
|
+
return;
|
|
106
|
+
// Two ORTHOGONAL checks (B). Both can be true for one expert (it produced
|
|
107
|
+
// work worth tracing AND owes the principal a reply).
|
|
108
|
+
// - 留痕 (trace): every non-trace role is nudged unconditionally when it
|
|
109
|
+
// ends a run without a record_trace.
|
|
110
|
+
// - 回交 (reply): only an expert has a principal to report back to.
|
|
111
|
+
const needTrace = !traced;
|
|
112
|
+
const needReply = deps.role !== "principal" && !replied;
|
|
113
|
+
// A satisfied dimension resets its own counter (so a later real lapse is
|
|
114
|
+
// nudged afresh).
|
|
115
|
+
if (!needTrace)
|
|
116
|
+
traceRemindCount = 0;
|
|
117
|
+
if (!needReply)
|
|
118
|
+
replyRemindCount = 0;
|
|
119
|
+
const canTrace = needTrace && traceRemindCount < 1;
|
|
120
|
+
const canReply = needReply && replyRemindCount < 1;
|
|
121
|
+
// Both lapsed and both still nudge-able → ONE merged reminder, not two.
|
|
122
|
+
if (canTrace && canReply) {
|
|
123
|
+
traceRemindCount++;
|
|
124
|
+
replyRemindCount++;
|
|
125
|
+
pi.sendUserMessage(MERGED_REMINDER, { deliverAs: "followUp" });
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (canReply) {
|
|
129
|
+
replyRemindCount++;
|
|
130
|
+
pi.sendUserMessage(EXPERT_REPLY_REMINDER, { deliverAs: "followUp" });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (canTrace) {
|
|
134
|
+
traceRemindCount++;
|
|
135
|
+
pi.sendUserMessage(TRACE_REMINDER, { deliverAs: "followUp" });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// Nothing left to nudge (each lapsed dimension was already reminded once).
|
|
139
|
+
// Terminal handling per dimension:
|
|
140
|
+
// - reply has a host fallback so the principal never dead-waits;
|
|
141
|
+
// - trace has none (PI/expert self-decides) — just let it go.
|
|
142
|
+
// ⚠️ counters reset only here (the already-reminded terminal exit).
|
|
143
|
+
if (needReply) {
|
|
144
|
+
deps.onUnreplied(deps.name);
|
|
145
|
+
replyRemindCount = 0;
|
|
146
|
+
}
|
|
147
|
+
if (needTrace) {
|
|
148
|
+
traceRemindCount = 0;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=trace-reminder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-reminder.js","sourceRoot":"","sources":["../../src/extensions/trace-reminder.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -23,5 +23,7 @@ export { createServer, startServer } from "./server.js";
|
|
|
23
23
|
export type { StartServerOptions } from "./server.js";
|
|
24
24
|
export { McpBridge, loadMcpServersConfig, defaultMcpConnect } from "./mcp-bridge.js";
|
|
25
25
|
export type { McpServersConfig, McpServerSpec, McpClientLike, McpConnectFn } from "./mcp-bridge.js";
|
|
26
|
+
export { materializeSkills, resolveBundledSkillsDir } from "./materialize-skills.js";
|
|
27
|
+
export type { MaterializeSkillsResult } from "./materialize-skills.js";
|
|
26
28
|
export type { AgentRole, IAgentSession, AgentSessionFactory, PiAgentEvent, PiAssistantMessageEvent, SystemTool, SystemToolResult, EventListener, } from "./types.js";
|
|
27
29
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EACL,QAAQ,EACR,qBAAqB,EACrB,UAAU,GACX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrF,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpG,YAAY,EACV,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EACL,QAAQ,EACR,qBAAqB,EACrB,UAAU,GACX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrF,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpG,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACrF,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,YAAY,EACV,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -17,4 +17,5 @@ export { allSystemTools, systemToolsForRole, systemToolNamesForRole, builtinTool
|
|
|
17
17
|
export { PERSONAS, BUILTIN_PERSONA_NAMES, personaFor, } from "./personas.js";
|
|
18
18
|
export { createServer, startServer } from "./server.js";
|
|
19
19
|
export { McpBridge, loadMcpServersConfig, defaultMcpConnect } from "./mcp-bridge.js";
|
|
20
|
+
export { materializeSkills, resolveBundledSkillsDir } from "./materialize-skills.js";
|
|
20
21
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,qBAAqB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,QAAQ,EACR,qBAAqB,EACrB,UAAU,GACX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,qBAAqB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,QAAQ,EACR,qBAAqB,EACrB,UAAU,GACX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGrF,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/mailbox.d.ts
CHANGED
|
@@ -6,6 +6,23 @@ export interface MailboxMessage {
|
|
|
6
6
|
msgType: MsgType;
|
|
7
7
|
timestamp: number;
|
|
8
8
|
}
|
|
9
|
+
/** Per-agent inbox capacity (#76). A write past this is rejected. */
|
|
10
|
+
export declare const MAX_INBOX = 20;
|
|
11
|
+
/**
|
|
12
|
+
* Default batch limits for one delivery turn (#76). The loop drains at most
|
|
13
|
+
* `BATCH_MAX_MESSAGES`, and stops early once the accumulated content would
|
|
14
|
+
* exceed `BATCH_MAX_CHARS` — except the FIRST message is always taken even if it
|
|
15
|
+
* alone exceeds the budget (so an oversized message is delivered on its own
|
|
16
|
+
* rather than stranded forever).
|
|
17
|
+
*/
|
|
18
|
+
export declare const BATCH_MAX_MESSAGES = 3;
|
|
19
|
+
export declare const BATCH_MAX_CHARS = 24000;
|
|
20
|
+
/** Thrown by `write` when the target inbox is at capacity. */
|
|
21
|
+
export declare class MailboxFullError extends Error {
|
|
22
|
+
readonly agent: string;
|
|
23
|
+
readonly limit: number;
|
|
24
|
+
constructor(agent: string, limit: number);
|
|
25
|
+
}
|
|
9
26
|
export declare class Mailbox {
|
|
10
27
|
readonly sessionId: string;
|
|
11
28
|
private readonly baseDir?;
|
|
@@ -13,12 +30,31 @@ export declare class Mailbox {
|
|
|
13
30
|
private writeChain;
|
|
14
31
|
constructor(sessionId: string, baseDir?: string | undefined);
|
|
15
32
|
private inbox;
|
|
16
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Write a message to `toAgent`'s inbox (in-memory + persisted). Throws
|
|
35
|
+
* `MailboxFullError` when the inbox is already at `MAX_INBOX` (#76 backpressure
|
|
36
|
+
* — keeps a runaway ping-pong from growing the inbox without bound).
|
|
37
|
+
*/
|
|
17
38
|
write(msg: Omit<MailboxMessage, "timestamp"> & {
|
|
18
39
|
timestamp?: number;
|
|
19
40
|
}): Promise<void>;
|
|
20
41
|
/** Atomically drain `agent`'s inbox (returns messages, clears the box). */
|
|
21
42
|
read(agent: string): Promise<MailboxMessage[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Drain a bounded batch from the FRONT of `agent`'s inbox (#76). Takes up to
|
|
45
|
+
* `maxMessages`, stopping early once including the next message would push the
|
|
46
|
+
* accumulated content past `maxChars` — except the first message is always
|
|
47
|
+
* taken (an oversized message ships alone rather than stranding). Remaining
|
|
48
|
+
* messages stay queued in order for the next turn. FIFO preserved.
|
|
49
|
+
*/
|
|
50
|
+
readBatch(agent: string, maxMessages?: number, maxChars?: number): Promise<MailboxMessage[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Drain EVERY inbox (in-memory + persisted) so no queued message can re-wake
|
|
53
|
+
* an agent. Used by whole-session interrupt (#90 Stop): after aborting all
|
|
54
|
+
* agents we clear their mailboxes, otherwise the delivery loop would re-deliver
|
|
55
|
+
* pending messages and revive the agents the user just stopped.
|
|
56
|
+
*/
|
|
57
|
+
clearAll(): Promise<void>;
|
|
22
58
|
/** Non-destructive peek. */
|
|
23
59
|
peek(agent: string): readonly MailboxMessage[];
|
|
24
60
|
count(agent: string): number;
|
package/dist/mailbox.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mailbox.d.ts","sourceRoot":"","sources":["../src/mailbox.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mailbox.d.ts","sourceRoot":"","sources":["../src/mailbox.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,OAAO,GACf,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,aAAa,GACb,QAAQ,CAAC;AAEb,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qEAAqE;AACrE,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,eAAe,QAAS,CAAC;AAEtC,8DAA8D;AAC9D,qBAAa,gBAAiB,SAAQ,KAAK;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM;gBAArC,KAAK,EAAE,MAAM,EAAW,KAAK,EAAE,MAAM;CAI3D;AAED,qBAAa,OAAO;IAKhB,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAL3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,UAAU,CAAoC;gBAG3C,SAAS,EAAE,MAAM,EACT,OAAO,CAAC,EAAE,MAAM,YAAA;IAGnC,OAAO,CAAC,KAAK;IASb;;;;OAIG;IACG,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,GAAG;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3F,2EAA2E;IACrE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAOpD;;;;;;OAMG;IACG,SAAS,CACb,KAAK,EAAE,MAAM,EACb,WAAW,SAAqB,EAChC,QAAQ,SAAkB,GACzB,OAAO,CAAC,cAAc,EAAE,CAAC;IAkB5B;;;;;OAKG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B,4BAA4B;IAC5B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,cAAc,EAAE;IAI9C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI5B,OAAO,CAAC,SAAS;YAKH,OAAO;IAarB,4EAA4E;IACtE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
package/dist/mailbox.js
CHANGED
|
@@ -7,9 +7,36 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Delivery semantics (ported from legacy `mailbox.py`): reading an inbox
|
|
9
9
|
* atomically drains it (avoids re-delivery). Writes append.
|
|
10
|
+
*
|
|
11
|
+
* Backpressure (#76): an inbox is capped at `MAX_INBOX` messages. A write past
|
|
12
|
+
* the cap throws `MailboxFullError` so the sending tool surfaces the failure to
|
|
13
|
+
* its agent (Pi signals tool failure by throwing) instead of letting a runaway
|
|
14
|
+
* agent↔agent ping-pong grow the inbox without bound.
|
|
10
15
|
*/
|
|
11
16
|
import { mkdir, readFile, writeFile, readdir } from "node:fs/promises";
|
|
12
17
|
import { join } from "node:path";
|
|
18
|
+
/** Per-agent inbox capacity (#76). A write past this is rejected. */
|
|
19
|
+
export const MAX_INBOX = 20;
|
|
20
|
+
/**
|
|
21
|
+
* Default batch limits for one delivery turn (#76). The loop drains at most
|
|
22
|
+
* `BATCH_MAX_MESSAGES`, and stops early once the accumulated content would
|
|
23
|
+
* exceed `BATCH_MAX_CHARS` — except the FIRST message is always taken even if it
|
|
24
|
+
* alone exceeds the budget (so an oversized message is delivered on its own
|
|
25
|
+
* rather than stranded forever).
|
|
26
|
+
*/
|
|
27
|
+
export const BATCH_MAX_MESSAGES = 3;
|
|
28
|
+
export const BATCH_MAX_CHARS = 24_000;
|
|
29
|
+
/** Thrown by `write` when the target inbox is at capacity. */
|
|
30
|
+
export class MailboxFullError extends Error {
|
|
31
|
+
agent;
|
|
32
|
+
limit;
|
|
33
|
+
constructor(agent, limit) {
|
|
34
|
+
super(`mailbox for "${agent}" is full (limit ${limit}); message rejected`);
|
|
35
|
+
this.agent = agent;
|
|
36
|
+
this.limit = limit;
|
|
37
|
+
this.name = "MailboxFullError";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
13
40
|
export class Mailbox {
|
|
14
41
|
sessionId;
|
|
15
42
|
baseDir;
|
|
@@ -27,10 +54,17 @@ export class Mailbox {
|
|
|
27
54
|
}
|
|
28
55
|
return box;
|
|
29
56
|
}
|
|
30
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Write a message to `toAgent`'s inbox (in-memory + persisted). Throws
|
|
59
|
+
* `MailboxFullError` when the inbox is already at `MAX_INBOX` (#76 backpressure
|
|
60
|
+
* — keeps a runaway ping-pong from growing the inbox without bound).
|
|
61
|
+
*/
|
|
31
62
|
async write(msg) {
|
|
63
|
+
const box = this.inbox(msg.toAgent);
|
|
64
|
+
if (box.length >= MAX_INBOX)
|
|
65
|
+
throw new MailboxFullError(msg.toAgent, MAX_INBOX);
|
|
32
66
|
const full = { ...msg, timestamp: msg.timestamp ?? Date.now() };
|
|
33
|
-
|
|
67
|
+
box.push(full);
|
|
34
68
|
await this.persist(full.toAgent);
|
|
35
69
|
}
|
|
36
70
|
/** Atomically drain `agent`'s inbox (returns messages, clears the box). */
|
|
@@ -41,6 +75,49 @@ export class Mailbox {
|
|
|
41
75
|
await this.persist(agent);
|
|
42
76
|
return out;
|
|
43
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Drain a bounded batch from the FRONT of `agent`'s inbox (#76). Takes up to
|
|
80
|
+
* `maxMessages`, stopping early once including the next message would push the
|
|
81
|
+
* accumulated content past `maxChars` — except the first message is always
|
|
82
|
+
* taken (an oversized message ships alone rather than stranding). Remaining
|
|
83
|
+
* messages stay queued in order for the next turn. FIFO preserved.
|
|
84
|
+
*/
|
|
85
|
+
async readBatch(agent, maxMessages = BATCH_MAX_MESSAGES, maxChars = BATCH_MAX_CHARS) {
|
|
86
|
+
const box = this.inbox(agent);
|
|
87
|
+
if (box.length === 0)
|
|
88
|
+
return [];
|
|
89
|
+
const take = [];
|
|
90
|
+
let chars = 0;
|
|
91
|
+
for (const m of box) {
|
|
92
|
+
if (take.length >= maxMessages)
|
|
93
|
+
break;
|
|
94
|
+
const next = chars + m.content.length;
|
|
95
|
+
// Always take the first; otherwise respect the char budget.
|
|
96
|
+
if (take.length > 0 && next > maxChars)
|
|
97
|
+
break;
|
|
98
|
+
take.push(m);
|
|
99
|
+
chars = next;
|
|
100
|
+
}
|
|
101
|
+
box.splice(0, take.length);
|
|
102
|
+
await this.persist(agent);
|
|
103
|
+
return take;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Drain EVERY inbox (in-memory + persisted) so no queued message can re-wake
|
|
107
|
+
* an agent. Used by whole-session interrupt (#90 Stop): after aborting all
|
|
108
|
+
* agents we clear their mailboxes, otherwise the delivery loop would re-deliver
|
|
109
|
+
* pending messages and revive the agents the user just stopped.
|
|
110
|
+
*/
|
|
111
|
+
async clearAll() {
|
|
112
|
+
const agents = [...this.inboxes.keys()];
|
|
113
|
+
for (const agent of agents) {
|
|
114
|
+
const box = this.inbox(agent);
|
|
115
|
+
if (box.length === 0)
|
|
116
|
+
continue;
|
|
117
|
+
box.length = 0;
|
|
118
|
+
await this.persist(agent);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
44
121
|
/** Non-destructive peek. */
|
|
45
122
|
peek(agent) {
|
|
46
123
|
return [...this.inbox(agent)];
|
package/dist/mailbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mailbox.js","sourceRoot":"","sources":["../src/mailbox.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"mailbox.js","sourceRoot":"","sources":["../src/mailbox.ts"],"names":[],"mappings":"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"}
|