agent-sh 0.12.3 → 0.12.5
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/agent/agent-loop.js +32 -2
- package/dist/context-manager.js +7 -2
- package/dist/event-bus.d.ts +24 -0
- package/package.json +1 -1
package/dist/agent/agent-loop.js
CHANGED
|
@@ -297,6 +297,18 @@ export class AgentLoop {
|
|
|
297
297
|
recallArchiveSize: this.conversation.getRecallArchiveSize(),
|
|
298
298
|
budgetTokens: this.currentMode.contextWindow ?? DEFAULT_CONTEXT_WINDOW,
|
|
299
299
|
}));
|
|
300
|
+
this.bus.onPipe("context:snapshot", (payload) => {
|
|
301
|
+
payload.messages = this.conversation.getMessages();
|
|
302
|
+
payload.contextWindow = this.currentMode.contextWindow ?? DEFAULT_CONTEXT_WINDOW;
|
|
303
|
+
payload.activeTokens = this.conversation.estimateTokens();
|
|
304
|
+
return payload;
|
|
305
|
+
});
|
|
306
|
+
this.bus.onPipeAsync("context:compact", async (payload) => {
|
|
307
|
+
const stats = await this.compactWithHooks(0, undefined, false, payload.strategy);
|
|
308
|
+
if (stats)
|
|
309
|
+
payload.stats = { before: stats.before, after: stats.after, evictedCount: stats.evictedCount };
|
|
310
|
+
return payload;
|
|
311
|
+
});
|
|
300
312
|
// Prior-session preamble (non-blocking). Both the read and the
|
|
301
313
|
// layout go through advisable handlers.
|
|
302
314
|
Promise.resolve(this.handlers.call("history:read-recent"))
|
|
@@ -469,11 +481,12 @@ export class AgentLoop {
|
|
|
469
481
|
* compaction, emit `conversation:after-compact` so listeners
|
|
470
482
|
* (metrics, UI, agent-awareness notes) can react.
|
|
471
483
|
*/
|
|
472
|
-
compactWithHooks(target, keepRecent, force) {
|
|
484
|
+
compactWithHooks(target, keepRecent, force, strategy) {
|
|
473
485
|
const stats = this.handlers.call("conversation:compact", {
|
|
474
486
|
target,
|
|
475
487
|
keepRecent,
|
|
476
488
|
force: !!force,
|
|
489
|
+
strategy,
|
|
477
490
|
});
|
|
478
491
|
if (stats) {
|
|
479
492
|
this.bus.emit("conversation:after-compact", {
|
|
@@ -819,7 +832,24 @@ export class AgentLoop {
|
|
|
819
832
|
// Compaction strategy — default delegates to the two-tier pin
|
|
820
833
|
// strategy in ConversationState; advisors replace wholesale.
|
|
821
834
|
h.define("conversation:compact", (opts) => {
|
|
822
|
-
|
|
835
|
+
const strategy = opts.strategy;
|
|
836
|
+
// Synthesize a CompactResult for manual edits so conversation:after-compact
|
|
837
|
+
// listeners (metrics, file-read cache, system-prompt cache) still run.
|
|
838
|
+
if (strategy?.kind === "rewind" || strategy?.kind === "replace") {
|
|
839
|
+
const before = this.conversation.estimatePromptTokens();
|
|
840
|
+
const beforeLen = this.conversation.getMessages().length;
|
|
841
|
+
const next = strategy.kind === "rewind"
|
|
842
|
+
? this.conversation.getMessages().slice(0, strategy.toIndex)
|
|
843
|
+
: strategy.messages;
|
|
844
|
+
this.conversation.replaceMessages(next);
|
|
845
|
+
const after = this.conversation.estimatePromptTokens();
|
|
846
|
+
const afterLen = this.conversation.getMessages().length;
|
|
847
|
+
return { before, after, evictedCount: Math.max(0, beforeLen - afterLen) };
|
|
848
|
+
}
|
|
849
|
+
const tgt = strategy?.kind === "two-tier-pin" ? strategy.target : opts.target;
|
|
850
|
+
const keep = strategy?.kind === "two-tier-pin" ? strategy.keepRecent : opts.keepRecent;
|
|
851
|
+
const force = strategy?.kind === "two-tier-pin" ? strategy.force : opts.force;
|
|
852
|
+
return this.conversation.compact(tgt, keep, force);
|
|
823
853
|
});
|
|
824
854
|
// Inject a system note mid-loop — used by extensions (subagents,
|
|
825
855
|
// peer messages) to deliver async results into the next iteration.
|
package/dist/context-manager.js
CHANGED
|
@@ -124,7 +124,10 @@ export class ContextManager {
|
|
|
124
124
|
return null;
|
|
125
125
|
const lastSeq = this.exchanges[this.exchanges.length - 1].id;
|
|
126
126
|
// Outputs already carry head+tail+spillPath stubs from capture time.
|
|
127
|
-
const
|
|
127
|
+
const parts = fresh.map((ex) => this.formatExchangeTruncated(ex)).filter((s) => s.length > 0);
|
|
128
|
+
if (parts.length === 0)
|
|
129
|
+
return null;
|
|
130
|
+
const body = parts.join("\n");
|
|
128
131
|
return {
|
|
129
132
|
text: `<shell-events>\n${body}</shell-events>`,
|
|
130
133
|
lastSeq,
|
|
@@ -171,7 +174,9 @@ export class ContextManager {
|
|
|
171
174
|
return s;
|
|
172
175
|
}
|
|
173
176
|
case "agent_query":
|
|
174
|
-
|
|
177
|
+
// Suppress: query already appears as the turn's user message.
|
|
178
|
+
// Kept in `exchanges` so search() can find it by id.
|
|
179
|
+
return "";
|
|
175
180
|
}
|
|
176
181
|
}
|
|
177
182
|
formatExchangeFull(ex) {
|
package/dist/event-bus.d.ts
CHANGED
|
@@ -233,6 +233,30 @@ export interface ShellEvents {
|
|
|
233
233
|
totalTokens: number;
|
|
234
234
|
budgetTokens: number;
|
|
235
235
|
};
|
|
236
|
+
"context:snapshot": {
|
|
237
|
+
messages: unknown[];
|
|
238
|
+
contextWindow: number;
|
|
239
|
+
activeTokens: number;
|
|
240
|
+
};
|
|
241
|
+
"context:compact": {
|
|
242
|
+
strategy?: {
|
|
243
|
+
kind: "two-tier-pin";
|
|
244
|
+
target: number;
|
|
245
|
+
keepRecent?: number;
|
|
246
|
+
force?: boolean;
|
|
247
|
+
} | {
|
|
248
|
+
kind: "rewind";
|
|
249
|
+
toIndex: number;
|
|
250
|
+
} | {
|
|
251
|
+
kind: "replace";
|
|
252
|
+
messages: unknown[];
|
|
253
|
+
};
|
|
254
|
+
stats?: {
|
|
255
|
+
before: number;
|
|
256
|
+
after: number;
|
|
257
|
+
evictedCount: number;
|
|
258
|
+
};
|
|
259
|
+
};
|
|
236
260
|
"agent:register-backend": {
|
|
237
261
|
name: string;
|
|
238
262
|
kill: () => void;
|