@caupulican/pi-adaptative 0.81.0 → 0.81.2
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 +11 -0
- package/dist/core/agent-session.d.ts +5 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +58 -12
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction-support.d.ts +9 -5
- package/dist/core/compaction-support.d.ts.map +1 -1
- package/dist/core/compaction-support.js +38 -27
- package/dist/core/compaction-support.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
|
|
@@ -587,8 +594,8 @@ export class AgentSession {
|
|
|
587
594
|
}
|
|
588
595
|
throw new Error(formatNoApiKeyFoundMessage(model.provider));
|
|
589
596
|
}
|
|
590
|
-
// Summarizer model selection, request auth (with session-model fallback), and
|
|
591
|
-
// settings live in CompactionSupport (see compaction-support.ts).
|
|
597
|
+
// Summarizer model/thinking selection, request auth (with session-model fallback), and
|
|
598
|
+
// window-adapted settings live in CompactionSupport (see compaction-support.ts).
|
|
592
599
|
_getCompactionRequestAuth(model) {
|
|
593
600
|
return this._compactionSupport.getRequestAuth(model);
|
|
594
601
|
}
|
|
@@ -598,6 +605,9 @@ export class AgentSession {
|
|
|
598
605
|
_resolveCompactionModel(sessionModel) {
|
|
599
606
|
return this._compactionSupport.resolveModel(sessionModel);
|
|
600
607
|
}
|
|
608
|
+
_resolveCompactionThinkingLevel(compactionModel, sessionModel) {
|
|
609
|
+
return this._compactionSupport.resolveThinkingLevel(this.thinkingLevel, compactionModel, sessionModel);
|
|
610
|
+
}
|
|
601
611
|
/**
|
|
602
612
|
* Install tool hooks once on the Agent instance.
|
|
603
613
|
*
|
|
@@ -2135,6 +2145,7 @@ export class AgentSession {
|
|
|
2135
2145
|
throw new Error(formatNoModelSelectedMessage());
|
|
2136
2146
|
}
|
|
2137
2147
|
const compactionModel = this._resolveCompactionModel(this.model);
|
|
2148
|
+
const compactionThinkingLevel = this._resolveCompactionThinkingLevel(compactionModel, this.model);
|
|
2138
2149
|
const { apiKey, headers } = await this._getCompactionRequestAuth(compactionModel);
|
|
2139
2150
|
const pathEntries = this.sessionManager.getBranch();
|
|
2140
2151
|
const settings = this._getAdaptedCompactionSettings();
|
|
@@ -2178,7 +2189,8 @@ export class AgentSession {
|
|
|
2178
2189
|
}
|
|
2179
2190
|
else {
|
|
2180
2191
|
// Generate compaction result
|
|
2181
|
-
const
|
|
2192
|
+
const compactionSignal = this._compactionAbortController.signal;
|
|
2193
|
+
const result = await this._compactWithRetry(() => compact(preparation, compactionModel, apiKey, headers, customInstructions, compactionSignal, compactionThinkingLevel, this.agent.streamFn, this._buildCompactionPreDigest()), compactionSignal);
|
|
2182
2194
|
summary = result.summary;
|
|
2183
2195
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
2184
2196
|
tokensBefore = result.tokensBefore;
|
|
@@ -2390,9 +2402,9 @@ export class AgentSession {
|
|
|
2390
2402
|
});
|
|
2391
2403
|
return false;
|
|
2392
2404
|
}
|
|
2393
|
-
// Summarize with the
|
|
2394
|
-
//
|
|
2395
|
-
//
|
|
2405
|
+
// Summarize with the configured/default compaction model. If its auth turns out unusable at
|
|
2406
|
+
// request time (e.g. expired token), fall back to the session model — the one manual /compact
|
|
2407
|
+
// demonstrably works with — before giving up.
|
|
2396
2408
|
const resolvedCompaction = await this._resolveCompactionModelAndAuth(this._resolveCompactionModel(this.model), this.model);
|
|
2397
2409
|
if (resolvedCompaction.failure) {
|
|
2398
2410
|
this._emit({
|
|
@@ -2406,6 +2418,7 @@ export class AgentSession {
|
|
|
2406
2418
|
return false;
|
|
2407
2419
|
}
|
|
2408
2420
|
const compactionModel = resolvedCompaction.model;
|
|
2421
|
+
const compactionThinkingLevel = this._resolveCompactionThinkingLevel(compactionModel, this.model);
|
|
2409
2422
|
const apiKey = resolvedCompaction.apiKey;
|
|
2410
2423
|
const headers = resolvedCompaction.headers;
|
|
2411
2424
|
const pathEntries = this.sessionManager.getBranch();
|
|
@@ -2460,7 +2473,8 @@ export class AgentSession {
|
|
|
2460
2473
|
}
|
|
2461
2474
|
else {
|
|
2462
2475
|
// Generate compaction result
|
|
2463
|
-
const
|
|
2476
|
+
const autoCompactionSignal = this._autoCompactionAbortController.signal;
|
|
2477
|
+
const compactResult = await this._compactWithRetry(() => compact(preparation, compactionModel, apiKey, headers, undefined, autoCompactionSignal, compactionThinkingLevel, this.agent.streamFn, this._buildCompactionPreDigest()), autoCompactionSignal);
|
|
2464
2478
|
summary = compactResult.summary;
|
|
2465
2479
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
2466
2480
|
tokensBefore = compactResult.tokensBefore;
|
|
@@ -2526,6 +2540,38 @@ export class AgentSession {
|
|
|
2526
2540
|
this._autoCompactionAbortController = undefined;
|
|
2527
2541
|
}
|
|
2528
2542
|
}
|
|
2543
|
+
/**
|
|
2544
|
+
* Run one compaction attempt, retrying retryable provider failures (stream stalls,
|
|
2545
|
+
* 429/5xx, network drops) with the session's retry policy. The reliability kernel
|
|
2546
|
+
* classifies a stall as retryable by design (see withStreamIdleWatchdog); without this
|
|
2547
|
+
* loop a single transient killed the whole compaction while ordinary turns survived the
|
|
2548
|
+
* same failure via auto-retry. Caller aborts are never retried; sleepAbortable rejects
|
|
2549
|
+
* with the abort reason if the signal fires mid-backoff.
|
|
2550
|
+
*/
|
|
2551
|
+
async _compactWithRetry(run, signal) {
|
|
2552
|
+
const retrySettings = this.settingsManager.getRetrySettings();
|
|
2553
|
+
const maxAttempts = retrySettings.enabled ? Math.max(1, retrySettings.maxRetries + 1) : 1;
|
|
2554
|
+
const policy = {
|
|
2555
|
+
maxAttempts,
|
|
2556
|
+
baseDelayMs: retrySettings.baseDelayMs,
|
|
2557
|
+
maxDelayMs: DEFAULT_RETRY_POLICY.maxDelayMs,
|
|
2558
|
+
jitterRatio: 0,
|
|
2559
|
+
};
|
|
2560
|
+
for (let attempt = 1;; attempt++) {
|
|
2561
|
+
try {
|
|
2562
|
+
return await run();
|
|
2563
|
+
}
|
|
2564
|
+
catch (error) {
|
|
2565
|
+
if (signal.aborted || attempt >= maxAttempts)
|
|
2566
|
+
throw error;
|
|
2567
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2568
|
+
const classified = classifyFailure({ message });
|
|
2569
|
+
if (!classified.retryable)
|
|
2570
|
+
throw error;
|
|
2571
|
+
await sleepAbortable(computeRetryDelayMs(policy, attempt, { retryAfterMs: classified.retryAfterMs }), signal);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2529
2575
|
/**
|
|
2530
2576
|
* Toggle auto-compaction setting.
|
|
2531
2577
|
*/
|