@caupulican/pi-adaptative 0.80.71 → 0.80.73
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/CHANGELOG.md +23 -0
- package/dist/core/agent-session.d.ts +12 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +44 -6
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/memory/providers/file-store.d.ts.map +1 -1
- package/dist/core/memory/providers/file-store.js +11 -2
- package/dist/core/memory/providers/file-store.js.map +1 -1
- package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
- package/dist/core/memory/providers/transcript-recall.js +14 -3
- package/dist/core/memory/providers/transcript-recall.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +21 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -38,6 +38,7 @@ import { MemoryManager } from "./memory/memory-manager.js";
|
|
|
38
38
|
import { FileStoreProvider } from "./memory/providers/file-store.js";
|
|
39
39
|
import { TranscriptRecallProvider } from "./memory/providers/transcript-recall.js";
|
|
40
40
|
import { compactToolResultDetailsForRetention } from "./message-retention.js";
|
|
41
|
+
import { createCustomMessage } from "./messages.js";
|
|
41
42
|
import { resolveProfileModelSettings } from "./model-resolver.js";
|
|
42
43
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
43
44
|
import { stripResourceProfileBlocks } from "./resource-profile-blocks.js";
|
|
@@ -127,6 +128,12 @@ export class AgentSession {
|
|
|
127
128
|
_effectivenessTracker = new EffectivenessTracker();
|
|
128
129
|
/** R8: registry for deployment-supplied gateway channels + schedulers (lifecycle driven by the host runner). */
|
|
129
130
|
_gatewayRegistry = new GatewayRegistry();
|
|
131
|
+
/** Cache for getSpawnedUsage(), keyed by session entry count (Bug #22 — avoid O(N) per render frame). */
|
|
132
|
+
_spawnedUsageCache;
|
|
133
|
+
/** Set on dispose so in-flight background reflection bails instead of writing to a dead session (Bug #21). */
|
|
134
|
+
_disposed = false;
|
|
135
|
+
/** Aborts in-flight background reflection completions on dispose (Bug #21). */
|
|
136
|
+
_reflectionAbort = new AbortController();
|
|
130
137
|
_isChildSession;
|
|
131
138
|
/** Memory providers registered by extensions via pi.registerMemoryProvider, applied on (re)init. */
|
|
132
139
|
_pendingMemoryProviders = [];
|
|
@@ -676,6 +683,15 @@ export class AgentSession {
|
|
|
676
683
|
this.agent.abort();
|
|
677
684
|
// R8: stop any deployment-registered gateway channels / schedulers.
|
|
678
685
|
void this._gatewayRegistry.stop().catch(() => { });
|
|
686
|
+
// Bug #21: abort any in-flight background reflection so it cannot keep spending tokens or
|
|
687
|
+
// write memory/skills against this now-disposed session.
|
|
688
|
+
this._disposed = true;
|
|
689
|
+
this._reflectionAbort.abort();
|
|
690
|
+
// Bug #20: clear the hooks this session installed on the shared agent so their closures stop
|
|
691
|
+
// pinning this (deactivated) session — and all its history/maps — in memory if the agent
|
|
692
|
+
// instance outlives the session.
|
|
693
|
+
this.agent.afterToolCall = undefined;
|
|
694
|
+
this.agent.transformContext = undefined;
|
|
679
695
|
}
|
|
680
696
|
catch {
|
|
681
697
|
// Dispose must succeed even if an abort hook throws.
|
|
@@ -1111,7 +1127,11 @@ export class AgentSession {
|
|
|
1111
1127
|
if (recall) {
|
|
1112
1128
|
injectedRecall = recall;
|
|
1113
1129
|
recallQuery = expandedText;
|
|
1114
|
-
|
|
1130
|
+
// Inject as a GC-managed custom context message (role "custom", customType
|
|
1131
|
+
// "memory_context"), NOT a persisted user message: the semantic-memory context-GC packs
|
|
1132
|
+
// stale recall pages so they don't accumulate forever (Bug #7), and the transcript index
|
|
1133
|
+
// only re-reads user/assistant text so recalled snippets can't recirculate (Bug #10).
|
|
1134
|
+
messages.push(createCustomMessage("memory_context", recall, false, undefined, new Date().toISOString()));
|
|
1115
1135
|
}
|
|
1116
1136
|
}
|
|
1117
1137
|
catch {
|
|
@@ -3296,8 +3316,15 @@ export class AgentSession {
|
|
|
3296
3316
|
};
|
|
3297
3317
|
return this.sessionManager.appendCustomEntry(SPAWNED_USAGE_CUSTOM_TYPE, report);
|
|
3298
3318
|
}
|
|
3299
|
-
/**
|
|
3319
|
+
/**
|
|
3320
|
+
* Aggregate all recorded spawned-usage reports (see {@link addSpawnedUsage}). Cached by the session
|
|
3321
|
+
* entry count so the interactive footer (which calls this every render frame) is O(1) between turns
|
|
3322
|
+
* instead of an O(N) scan on every keystroke (Bug #22). Recomputes only when entries change.
|
|
3323
|
+
*/
|
|
3300
3324
|
getSpawnedUsage() {
|
|
3325
|
+
const entryCount = this.sessionManager.getEntryCount?.() ?? this.sessionManager.getEntries().length;
|
|
3326
|
+
if (this._spawnedUsageCache?.entryCount === entryCount)
|
|
3327
|
+
return this._spawnedUsageCache.totals;
|
|
3301
3328
|
let cost = 0;
|
|
3302
3329
|
let reports = 0;
|
|
3303
3330
|
for (const entry of this.sessionManager.getEntries()) {
|
|
@@ -3309,7 +3336,9 @@ export class AgentSession {
|
|
|
3309
3336
|
cost += data.usage.cost.total;
|
|
3310
3337
|
reports += 1;
|
|
3311
3338
|
}
|
|
3312
|
-
|
|
3339
|
+
const totals = { cost, reports };
|
|
3340
|
+
this._spawnedUsageCache = { entryCount, totals };
|
|
3341
|
+
return totals;
|
|
3313
3342
|
}
|
|
3314
3343
|
/**
|
|
3315
3344
|
* Run a one-shot LLM completion fully ISOLATED from the main session — the load-bearing
|
|
@@ -3383,18 +3412,23 @@ export class AgentSession {
|
|
|
3383
3412
|
* is best-effort: a model/parse error yields no writes, never throws into the caller.
|
|
3384
3413
|
*/
|
|
3385
3414
|
async runReflectionPass(input) {
|
|
3386
|
-
if (this._isChildSession)
|
|
3415
|
+
if (this._isChildSession || this._disposed)
|
|
3387
3416
|
return null;
|
|
3388
3417
|
const plan = decideDemand(input.signals);
|
|
3389
3418
|
if (plan.act === "skip")
|
|
3390
3419
|
return null;
|
|
3420
|
+
// Bug #21: tie this background pass to the session lifetime. Disposing the session aborts the
|
|
3421
|
+
// in-flight completion (input.signal can add a more specific abort).
|
|
3422
|
+
const signal = input.signal
|
|
3423
|
+
? AbortSignal.any([input.signal, this._reflectionAbort.signal])
|
|
3424
|
+
: this._reflectionAbort.signal;
|
|
3391
3425
|
const complete = (systemPrompt, userPrompt) => this.runIsolatedCompletion({
|
|
3392
3426
|
systemPrompt,
|
|
3393
3427
|
messages: [{ role: "user", content: [{ type: "text", text: userPrompt }], timestamp: Date.now() }],
|
|
3394
3428
|
model: input.model,
|
|
3395
3429
|
thinkingLevel: input.thinkingLevel ?? "low",
|
|
3396
3430
|
maxTokens: plan.tokenBudget,
|
|
3397
|
-
signal
|
|
3431
|
+
signal,
|
|
3398
3432
|
});
|
|
3399
3433
|
const result = await new ReflectionEngine().reflect({
|
|
3400
3434
|
recentTurnText: input.recentTurnText,
|
|
@@ -3404,8 +3438,12 @@ export class AgentSession {
|
|
|
3404
3438
|
plan,
|
|
3405
3439
|
complete,
|
|
3406
3440
|
});
|
|
3441
|
+
// Bug #21: if the session was disposed while the completion was in flight, do NOT write memory
|
|
3442
|
+
// or skills against the dead session.
|
|
3443
|
+
if (this._disposed)
|
|
3444
|
+
return result;
|
|
3407
3445
|
for (const write of result.writes) {
|
|
3408
|
-
await this._applyReflectionWrite(write,
|
|
3446
|
+
await this._applyReflectionWrite(write, signal);
|
|
3409
3447
|
}
|
|
3410
3448
|
// Account the reflection's spend so it surfaces in the footer roll-up (net-token visibility).
|
|
3411
3449
|
// Idempotent on reportId so a retried/duplicated pass cannot double-count.
|