pi-maestro-teammate 2.7.0 → 2.7.1
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-maestro-teammate",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.1",
|
|
4
4
|
"description": "Pi extension — teammate agent dispatch with DAG task graphs, RPC messaging, and compact TUI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -222,11 +222,11 @@
|
|
|
222
222
|
"pi-maestro-settings-core"
|
|
223
223
|
],
|
|
224
224
|
"devDependencies": {
|
|
225
|
-
"@earendil-works/pi-agent-core": "0.
|
|
225
|
+
"@earendil-works/pi-agent-core": "0.87.0",
|
|
226
226
|
"@types/cross-spawn": "6.0.6",
|
|
227
|
-
"@earendil-works/pi-ai": "0.
|
|
228
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
229
|
-
"@earendil-works/pi-tui": "0.
|
|
227
|
+
"@earendil-works/pi-ai": "0.87.0",
|
|
228
|
+
"@earendil-works/pi-coding-agent": "0.87.0",
|
|
229
|
+
"@earendil-works/pi-tui": "0.87.0",
|
|
230
230
|
"@types/ssh2": "1.15.5",
|
|
231
231
|
"typebox": "1.3.7"
|
|
232
232
|
},
|
|
@@ -595,9 +595,40 @@ function projectChain(sessionId: string, chain: readonly RawEntry[], include: Re
|
|
|
595
595
|
} {
|
|
596
596
|
const entries: SessionHistoryEntry[] = [];
|
|
597
597
|
const turnSeeds: TurnSeed[] = [];
|
|
598
|
+
// Apply branch-local context edits so the history shows what the model
|
|
599
|
+
// actually received: a null replacement omits the target, otherwise the
|
|
600
|
+
// replacement content stands in for the entry's own content. Mirror the
|
|
601
|
+
// host's scope: only edits surviving the latest compaction boundary (the
|
|
602
|
+
// kept range plus everything after it) can affect the projection.
|
|
603
|
+
let editScopeStart = 0;
|
|
604
|
+
for (let index = chain.length - 1; index >= 0; index--) {
|
|
605
|
+
if (chain[index]?.type !== "compaction") continue;
|
|
606
|
+
const firstKept = chain[index]?.firstKeptEntryId;
|
|
607
|
+
const keptIndex = typeof firstKept === "string" ? chain.findIndex((entry) => entry.id === firstKept) : -1;
|
|
608
|
+
editScopeStart = keptIndex >= 0 && keptIndex < index ? keptIndex : index;
|
|
609
|
+
break;
|
|
610
|
+
}
|
|
611
|
+
const contextEdits = new Map<string, unknown>();
|
|
612
|
+
for (const entry of chain.slice(editScopeStart)) {
|
|
613
|
+
if (entry.type === "context_edit" && typeof entry.targetId === "string" && entry.replacement !== undefined) {
|
|
614
|
+
contextEdits.set(entry.targetId, entry.replacement);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
const projectedContent = (entryIndex: number, entry: RawEntry, content: unknown): { omit: boolean; content: unknown } => {
|
|
618
|
+
// Edits to entries outside the surviving scope are inert for the host —
|
|
619
|
+
// its projection no longer contains the target — so history shows the
|
|
620
|
+
// original bytes the model last saw.
|
|
621
|
+
if (entryIndex < editScopeStart) return { omit: false, content };
|
|
622
|
+
const edit = contextEdits.get(entry.id);
|
|
623
|
+
if (edit === null) return { omit: true, content };
|
|
624
|
+
if (edit && typeof edit === "object" && !Array.isArray(edit) && "content" in edit) {
|
|
625
|
+
return { omit: false, content: (edit as Record<string, unknown>).content };
|
|
626
|
+
}
|
|
627
|
+
return { omit: false, content };
|
|
628
|
+
};
|
|
598
629
|
let turn = 0;
|
|
599
630
|
let firstUser: string | undefined;
|
|
600
|
-
for (const entry of chain) {
|
|
631
|
+
for (const [entryIndex, entry] of chain.entries()) {
|
|
601
632
|
const timestamp = typeof entry.timestamp === "string" ? Date.parse(entry.timestamp) || 0 : 0;
|
|
602
633
|
if (entry.type === "message") {
|
|
603
634
|
const message = entry.message;
|
|
@@ -605,9 +636,11 @@ function projectChain(sessionId: string, chain: readonly RawEntry[], include: Re
|
|
|
605
636
|
const value = message as Record<string, unknown>;
|
|
606
637
|
const role = value.role;
|
|
607
638
|
const messageTimestamp = typeof value.timestamp === "number" ? value.timestamp : timestamp;
|
|
639
|
+
const projected = projectedContent(entryIndex, entry, value.content);
|
|
640
|
+
if (projected.omit) continue;
|
|
608
641
|
if (role === "user") {
|
|
609
642
|
turn += 1;
|
|
610
|
-
const text = contentText(
|
|
643
|
+
const text = contentText(projected.content);
|
|
611
644
|
turnSeeds.push({
|
|
612
645
|
turn,
|
|
613
646
|
startedAt: messageTimestamp,
|
|
@@ -616,7 +649,14 @@ function projectChain(sessionId: string, chain: readonly RawEntry[], include: Re
|
|
|
616
649
|
if (include.has("user")) firstUser ??= text;
|
|
617
650
|
pushEntry(entries, include, { sessionId, entryId: entry.id, turn, kind: "user", text, timestamp: messageTimestamp });
|
|
618
651
|
} else if (role === "assistant") {
|
|
619
|
-
|
|
652
|
+
// The host wraps a string replacement into a single text block for
|
|
653
|
+
// assistant/toolResult roles; mirror that so an edited assistant
|
|
654
|
+
// message still renders instead of vanishing.
|
|
655
|
+
const blocks = Array.isArray(projected.content)
|
|
656
|
+
? projected.content
|
|
657
|
+
: typeof projected.content === "string"
|
|
658
|
+
? [{ type: "text", text: projected.content }]
|
|
659
|
+
: [];
|
|
620
660
|
for (const block of blocks) {
|
|
621
661
|
if (!block || typeof block !== "object" || Array.isArray(block)) continue;
|
|
622
662
|
const candidate = block as Record<string, unknown>;
|
|
@@ -625,13 +665,15 @@ function projectChain(sessionId: string, chain: readonly RawEntry[], include: Re
|
|
|
625
665
|
}
|
|
626
666
|
}
|
|
627
667
|
} else if (role === "toolResult") {
|
|
628
|
-
pushEntry(entries, include, { sessionId, entryId: entry.id, turn, kind: "tool_result", text: contentText(
|
|
668
|
+
pushEntry(entries, include, { sessionId, entryId: entry.id, turn, kind: "tool_result", text: contentText(projected.content), timestamp: messageTimestamp });
|
|
629
669
|
} else if (role === "custom" && value.display === true) {
|
|
630
|
-
pushEntry(entries, include, { sessionId, entryId: entry.id, turn, kind: "visible_custom", text: contentText(
|
|
670
|
+
pushEntry(entries, include, { sessionId, entryId: entry.id, turn, kind: "visible_custom", text: contentText(projected.content), timestamp: messageTimestamp });
|
|
631
671
|
}
|
|
632
672
|
// bashExecution and all other message roles are deliberately excluded.
|
|
633
673
|
} else if (entry.type === "custom_message" && entry.display === true) {
|
|
634
|
-
|
|
674
|
+
const projected = projectedContent(entryIndex, entry, entry.content);
|
|
675
|
+
if (projected.omit) continue;
|
|
676
|
+
pushEntry(entries, include, { sessionId, entryId: entry.id, turn, kind: "visible_custom", text: contentText(projected.content), timestamp });
|
|
635
677
|
} else if (entry.type === "compaction") {
|
|
636
678
|
pushEntry(entries, include, { sessionId, entryId: entry.id, turn, kind: "compaction", text: typeof entry.summary === "string" ? entry.summary : "", timestamp });
|
|
637
679
|
}
|