@giladbarnea/pi-user-agents 0.0.15 → 0.0.16
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/INTERNALS.md +1 -1
- package/attach.ts +6 -3
- package/package.json +1 -1
package/INTERNALS.md
CHANGED
|
@@ -73,7 +73,7 @@ The file itself appears on the child's first assistant message (`_persist` defer
|
|
|
73
73
|
|
|
74
74
|
The session file does not persist the dispatch options, so every dispatch writes a `pi-user-agents-dispatch` custom entry into the child — the forwarded pi tokens, the plain task, and the isolate flag. At attach the record replays through the same projections dispatch used (`buildChildResourceLoaderOptions`, `resolveToolOptions`), so `--tools`, `--no-extensions`, `--system-prompt` and friends survive the round trip instead of silently widening back to pi defaults. The model and thinking level deliberately come from the file, not the record: reattachment is pi's own resume path — `SessionManager.open` plus `createAgentSessionFromServices` on a non-empty manager takes `createAgentSession`'s has-existing-session branch — and the file reflects any later changes. A record-less child (dispatched before the record existed, or `/fork`-made) still attaches, with pi's default tools and resources.
|
|
75
75
|
|
|
76
|
-
The dispatch preamble — built at the dispatch call site, sent verbatim by `runChildTurns`, or its pane counterpart for `-h` children — doubles as the boundary marker: `splitAtDispatchBoundary` finds the first user message carrying either and recovers the child's own conversation for the overlay and the inherited base whose fingerprint re-arms the rebase fast-forward. The fingerprint compares content, not file bookkeeping: rebuilding custom, compaction, and branch summaries from a session file re-stamps their timestamps (and a branch summary's `fromId`), so `conversationFingerprint` drops those fields or a round-tripped base would never equal main's live context. Without a recognizable boundary (a fork child, or a child whose compaction summarized it away) the whole context attaches and the base is a sentinel that never matches, so `r` stays withheld.
|
|
76
|
+
The dispatch preamble — built at the dispatch call site, sent verbatim by `runChildTurns`, or its pane counterpart for `-h` children — doubles as the boundary marker: `splitAtDispatchBoundary` finds the first user message carrying either and recovers the child's own conversation for the overlay and the inherited base whose fingerprint re-arms the rebase fast-forward. The system messages directly before that prompt belong to the child's conversation: Pi persists the child's prompt and tool changes there on its first request, and counting them as base made every reattached child look drifted. The fingerprint compares content, not file bookkeeping: rebuilding custom, compaction, and branch summaries from a session file re-stamps their timestamps (and a branch summary's `fromId`), so `conversationFingerprint` drops those fields or a round-tripped base would never equal main's live context. Without a recognizable boundary (a fork child, or a child whose compaction summarized it away) the whole context attaches and the base is a sentinel that never matches, so `r` stays withheld.
|
|
77
77
|
|
|
78
78
|
The attached agent parks idle first (`runAttachedTurns` waits for an instruction before running the shared turn loop), and its latest persisted response seeds `pendingSquashMessage`, so steering, `s`, and `r` work immediately without a new turn. A successful attach leaves an `Attached session …` breadcrumb — the detach line's counterpart — and both success states end with a "View agent?" confirmation that opens the overlay.
|
|
79
79
|
|
package/attach.ts
CHANGED
|
@@ -53,7 +53,8 @@ export type DispatchBoundary = {
|
|
|
53
53
|
/**
|
|
54
54
|
* Split a child's resolved context at its dispatch boundary — the first user message carrying
|
|
55
55
|
* a dispatch preamble. Undefined when no message carries one (a /fork child, or a child whose
|
|
56
|
-
* own compaction summarized the boundary away).
|
|
56
|
+
* own compaction summarized the boundary away). The system messages right before that prompt are
|
|
57
|
+
* the child's own: Pi persists its prompt and tool changes there on the child's first request.
|
|
57
58
|
*/
|
|
58
59
|
export function splitAtDispatchBoundary(
|
|
59
60
|
messages: readonly AgentMessage[],
|
|
@@ -63,9 +64,11 @@ export function splitAtDispatchBoundary(
|
|
|
63
64
|
const text = userMessageText(message);
|
|
64
65
|
const preamble = DISPATCH_PREAMBLES.find((candidate) => text.startsWith(candidate));
|
|
65
66
|
if (preamble === undefined) continue;
|
|
67
|
+
let conversationStart = index;
|
|
68
|
+
while (messages[conversationStart - 1]?.role === "system") conversationStart -= 1;
|
|
66
69
|
return {
|
|
67
|
-
base: messages.slice(0,
|
|
68
|
-
conversation: messages.slice(
|
|
70
|
+
base: messages.slice(0, conversationStart),
|
|
71
|
+
conversation: messages.slice(conversationStart),
|
|
69
72
|
task: text.slice(preamble.length),
|
|
70
73
|
};
|
|
71
74
|
}
|