@dyyz1993/pi-coding-agent 0.74.27 → 0.74.29
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/dist/core/agent-session.d.ts +4 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +58 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/channel-registry.d.ts +2 -0
- package/dist/core/extensions/channel-registry.d.ts.map +1 -1
- package/dist/core/extensions/channel-registry.js.map +1 -1
- package/dist/core/extensions/types.d.ts +17 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/session-manager.d.ts +5 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +44 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/extensions/bash-ext/index.ts +86 -62
- package/dist/extensions/file-snapshot/index.ts +4 -1
- package/dist/extensions/hooks-engine/index.ts +104 -16
- package/dist/extensions/lsp/lsp/index.ts +21 -3
- package/dist/extensions/lsp/lsp/utils/project-scanner.ts +102 -0
- package/dist/extensions/rules-engine/index.js +64 -22
- package/dist/extensions/rules-engine/index.ts +86 -16
- package/dist/extensions/rules-engine/types.d.ts +12 -2
- package/dist/extensions/rules-engine/types.d.ts.map +1 -1
- package/dist/extensions/rules-engine/types.js.map +1 -1
- package/dist/extensions/rules-engine/types.ts +13 -2
- package/dist/extensions/session-supervisor/config.ts +3 -1
- package/dist/extensions/session-supervisor/index.ts +90 -63
- package/dist/extensions/session-supervisor/types.d.ts +321 -0
- package/dist/extensions/session-supervisor/types.d.ts.map +1 -0
- package/dist/extensions/session-supervisor/types.js +92 -0
- package/dist/extensions/session-supervisor/types.js.map +1 -0
- package/dist/extensions/session-supervisor/types.ts +8 -8
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/package.json +1 -1
|
@@ -319,6 +319,35 @@ export class AgentSession {
|
|
|
319
319
|
followUp: [...this._followUpMessages],
|
|
320
320
|
});
|
|
321
321
|
}
|
|
322
|
+
/** Emit entries_invalidated event to extensions when entries are removed from LLM context.
|
|
323
|
+
* This is a notification-only event; it does not block or collect results. */
|
|
324
|
+
_emitEntriesInvalidated(invalidatedEntryIds, reason, operationEntryId) {
|
|
325
|
+
if (!this._extensionRunner || invalidatedEntryIds.length === 0)
|
|
326
|
+
return;
|
|
327
|
+
// Extract toolCallIds from invalidated tool result entries
|
|
328
|
+
const invalidatedToolCallIds = [];
|
|
329
|
+
for (const id of invalidatedEntryIds) {
|
|
330
|
+
const entry = this.sessionManager.getEntry(id);
|
|
331
|
+
if (entry && entry.type === "message" && entry.message.role === "toolResult") {
|
|
332
|
+
const toolCallId = entry.message.toolCallId;
|
|
333
|
+
if (toolCallId) {
|
|
334
|
+
invalidatedToolCallIds.push(toolCallId);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Fire-and-forget: don't await to avoid blocking SessionManager's synchronous _appendEntry
|
|
339
|
+
this._extensionRunner
|
|
340
|
+
.emit({
|
|
341
|
+
type: "entries_invalidated",
|
|
342
|
+
invalidatedEntryIds,
|
|
343
|
+
reason,
|
|
344
|
+
operationEntryId,
|
|
345
|
+
invalidatedToolCallIds,
|
|
346
|
+
})
|
|
347
|
+
.catch(() => {
|
|
348
|
+
// Silently swallow errors — this is a notification, not a critical path
|
|
349
|
+
});
|
|
350
|
+
}
|
|
322
351
|
// Track last assistant message for auto-compaction check
|
|
323
352
|
_lastAssistantMessage = undefined;
|
|
324
353
|
/** Internal handler for agent events - shared by subscribe and reconnect */
|
|
@@ -2091,6 +2120,22 @@ export class AgentSession {
|
|
|
2091
2120
|
}
|
|
2092
2121
|
}
|
|
2093
2122
|
this._extensionRunner = new ExtensionRunner(extensionsResult.extensions, extensionsResult.runtime, this._cwd, this.sessionManager, this._modelRegistry);
|
|
2123
|
+
// Register SessionManager callback to detect entry lifecycle changes
|
|
2124
|
+
// and emit entries_invalidated events to extensions.
|
|
2125
|
+
this.sessionManager.setOnEntryAppended((entry) => {
|
|
2126
|
+
if (entry.type === "deletion") {
|
|
2127
|
+
const e = entry;
|
|
2128
|
+
this._emitEntriesInvalidated(e.targetIds, "deletion", e.id);
|
|
2129
|
+
}
|
|
2130
|
+
else if (entry.type === "fold") {
|
|
2131
|
+
const e = entry;
|
|
2132
|
+
this._emitEntriesInvalidated([e.targetId], "fold", e.id);
|
|
2133
|
+
}
|
|
2134
|
+
else if (entry.type === "segment_summary") {
|
|
2135
|
+
const e = entry;
|
|
2136
|
+
this._emitEntriesInvalidated(e.targetIds, "segment_summary", e.id);
|
|
2137
|
+
}
|
|
2138
|
+
});
|
|
2094
2139
|
const projectRoot = resolveProjectIdentity(this._cwd);
|
|
2095
2140
|
this._extensionRunner.setContextDirFns({
|
|
2096
2141
|
getProjectRoot: () => projectRoot,
|
|
@@ -2483,6 +2528,19 @@ export class AgentSession {
|
|
|
2483
2528
|
// Non-user message: leaf = selected node
|
|
2484
2529
|
newLeafId = targetId;
|
|
2485
2530
|
}
|
|
2531
|
+
// Safety guard: reject navigation that would eliminate ALL user messages.
|
|
2532
|
+
// The new leaf path is root → ... → newLeafId (or null for root reset).
|
|
2533
|
+
// If a summary is provided, it will be a child of newLeafId, so the effective
|
|
2534
|
+
// leaf path includes newLeafId's ancestors. Check both cases.
|
|
2535
|
+
const effectiveLeafId = summaryText ? newLeafId : newLeafId;
|
|
2536
|
+
const userMsgCount = this.sessionManager.countUserMessagesOnPath(effectiveLeafId);
|
|
2537
|
+
if (userMsgCount === 0) {
|
|
2538
|
+
return {
|
|
2539
|
+
cancelled: true,
|
|
2540
|
+
editorText: undefined,
|
|
2541
|
+
reason: `Navigation to "${targetId}" would remove all user messages from the active path. This likely means the target is before the first user message. Use file-level rollback (snapshot.rollback) instead.`,
|
|
2542
|
+
};
|
|
2543
|
+
}
|
|
2486
2544
|
// Switch leaf (with or without summary)
|
|
2487
2545
|
// Summary is attached at the navigation target position (newLeafId), not the old branch
|
|
2488
2546
|
let summaryEntry;
|