@caupulican/pi-adaptative 0.81.0 → 0.81.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/CHANGELOG.md +8 -0
- package/dist/core/agent-session.d.ts +4 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +48 -7
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +4 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +6 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/settings-manager.d.ts +16 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +22 -0
- package/dist/core/settings-manager.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
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { readFileSync } from "node:fs";
|
|
16
16
|
import { basename, dirname, join } from "node:path";
|
|
17
|
-
import { classifyFailure, compactToolResultDetailsForRetention, createCustomMessage, DEFAULT_RETRY_POLICY,
|
|
17
|
+
import { classifyFailure, compactToolResultDetailsForRetention, computeRetryDelayMs, createCustomMessage, DEFAULT_RETRY_POLICY, RetryController, sleepAbortable, withStreamIdleWatchdog, } from "@caupulican/pi-agent-core";
|
|
18
18
|
import { calculateContextTokens, compact, estimateContextTokens, getLatestCompactionEntry, prepareCompaction, shouldCompact, } from "@caupulican/pi-agent-core/node";
|
|
19
19
|
import { cleanupSessionResources, isContextOverflow, streamSimple } from "@caupulican/pi-ai";
|
|
20
20
|
import { getAgentDir } from "../config.js";
|
|
@@ -64,12 +64,13 @@ import { ToolGateController } from "./tool-gate-controller.js";
|
|
|
64
64
|
* key stable regardless of how many times this module is evaluated.
|
|
65
65
|
*/
|
|
66
66
|
const RAW_STREAM_MARKER = Symbol.for("pi.rawStreamSimple");
|
|
67
|
-
/** Test-only override of the stream-idle bounds. Read
|
|
67
|
+
/** Test-only override of the stream-idle bounds. Read per-request by the wiring's resolver. */
|
|
68
68
|
let streamIdleOptionsOverride;
|
|
69
69
|
/**
|
|
70
70
|
* Test hook: override the stream-idle bounds so a stall can be provoked in-suite without a
|
|
71
|
-
*
|
|
72
|
-
*
|
|
71
|
+
* multi-minute wait. Pass `undefined` to restore the user-locked defaults (connect 120s /
|
|
72
|
+
* active 180s / quiet 600s, or the user's retry.stall settings). Applies per request — it
|
|
73
|
+
* may be set or changed at any time before the request that should observe it.
|
|
73
74
|
*/
|
|
74
75
|
export function setStreamIdleOptionsForTests(opts) {
|
|
75
76
|
streamIdleOptionsOverride = opts;
|
|
@@ -248,7 +249,13 @@ export class AgentSession {
|
|
|
248
249
|
// Wrapping also breaks the `streamFn === streamSimple` identity the auth-injection checks
|
|
249
250
|
// use, so the wrapper carries a rawness marker that _isRawStreamSimple reads.
|
|
250
251
|
const baseStreamFn = this.agent.streamFn;
|
|
251
|
-
this.
|
|
252
|
+
// `this.settingsManager` is assigned below; the resolver closes over the config reference
|
|
253
|
+
// because the wrapper must be installed before that assignment runs.
|
|
254
|
+
const stallSettingsSource = config.settingsManager;
|
|
255
|
+
this.agent.streamFn = tagRawness(withStreamIdleWatchdog(baseStreamFn, () => ({
|
|
256
|
+
...stallSettingsSource.getStreamStallSettings(),
|
|
257
|
+
...streamIdleOptionsOverride,
|
|
258
|
+
})), baseStreamFn === streamSimple);
|
|
252
259
|
this.sessionManager = config.sessionManager;
|
|
253
260
|
this.settingsManager = config.settingsManager;
|
|
254
261
|
// Auto-retry rides the reliability kernel: the controller owns the attempt counter and the
|
|
@@ -2178,7 +2185,8 @@ export class AgentSession {
|
|
|
2178
2185
|
}
|
|
2179
2186
|
else {
|
|
2180
2187
|
// Generate compaction result
|
|
2181
|
-
const
|
|
2188
|
+
const compactionSignal = this._compactionAbortController.signal;
|
|
2189
|
+
const result = await this._compactWithRetry(() => compact(preparation, compactionModel, apiKey, headers, customInstructions, compactionSignal, this.thinkingLevel, this.agent.streamFn, this._buildCompactionPreDigest()), compactionSignal);
|
|
2182
2190
|
summary = result.summary;
|
|
2183
2191
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
2184
2192
|
tokensBefore = result.tokensBefore;
|
|
@@ -2460,7 +2468,8 @@ export class AgentSession {
|
|
|
2460
2468
|
}
|
|
2461
2469
|
else {
|
|
2462
2470
|
// Generate compaction result
|
|
2463
|
-
const
|
|
2471
|
+
const autoCompactionSignal = this._autoCompactionAbortController.signal;
|
|
2472
|
+
const compactResult = await this._compactWithRetry(() => compact(preparation, compactionModel, apiKey, headers, undefined, autoCompactionSignal, this.thinkingLevel, this.agent.streamFn, this._buildCompactionPreDigest()), autoCompactionSignal);
|
|
2464
2473
|
summary = compactResult.summary;
|
|
2465
2474
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
2466
2475
|
tokensBefore = compactResult.tokensBefore;
|
|
@@ -2526,6 +2535,38 @@ export class AgentSession {
|
|
|
2526
2535
|
this._autoCompactionAbortController = undefined;
|
|
2527
2536
|
}
|
|
2528
2537
|
}
|
|
2538
|
+
/**
|
|
2539
|
+
* Run one compaction attempt, retrying retryable provider failures (stream stalls,
|
|
2540
|
+
* 429/5xx, network drops) with the session's retry policy. The reliability kernel
|
|
2541
|
+
* classifies a stall as retryable by design (see withStreamIdleWatchdog); without this
|
|
2542
|
+
* loop a single transient killed the whole compaction while ordinary turns survived the
|
|
2543
|
+
* same failure via auto-retry. Caller aborts are never retried; sleepAbortable rejects
|
|
2544
|
+
* with the abort reason if the signal fires mid-backoff.
|
|
2545
|
+
*/
|
|
2546
|
+
async _compactWithRetry(run, signal) {
|
|
2547
|
+
const retrySettings = this.settingsManager.getRetrySettings();
|
|
2548
|
+
const maxAttempts = retrySettings.enabled ? Math.max(1, retrySettings.maxRetries + 1) : 1;
|
|
2549
|
+
const policy = {
|
|
2550
|
+
maxAttempts,
|
|
2551
|
+
baseDelayMs: retrySettings.baseDelayMs,
|
|
2552
|
+
maxDelayMs: DEFAULT_RETRY_POLICY.maxDelayMs,
|
|
2553
|
+
jitterRatio: 0,
|
|
2554
|
+
};
|
|
2555
|
+
for (let attempt = 1;; attempt++) {
|
|
2556
|
+
try {
|
|
2557
|
+
return await run();
|
|
2558
|
+
}
|
|
2559
|
+
catch (error) {
|
|
2560
|
+
if (signal.aborted || attempt >= maxAttempts)
|
|
2561
|
+
throw error;
|
|
2562
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2563
|
+
const classified = classifyFailure({ message });
|
|
2564
|
+
if (!classified.retryable)
|
|
2565
|
+
throw error;
|
|
2566
|
+
await sleepAbortable(computeRetryDelayMs(policy, attempt, { retryAfterMs: classified.retryAfterMs }), signal);
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2529
2570
|
/**
|
|
2530
2571
|
* Toggle auto-compaction setting.
|
|
2531
2572
|
*/
|