@earendil-works/pi-coding-agent 0.79.7 → 0.79.8
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 +22 -0
- package/README.md +6 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +37 -36
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +1 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +3 -0
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +0 -7
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/rpc.md +4 -0
- 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/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/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 +60 -39
- package/package.json +6 -6
|
@@ -21,7 +21,7 @@ import { resolvePath } from "../utils/paths.js";
|
|
|
21
21
|
import { sleep } from "../utils/sleep.js";
|
|
22
22
|
import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
|
|
23
23
|
import { executeBashWithOperations } from "./bash-executor.js";
|
|
24
|
-
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
24
|
+
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
25
25
|
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
26
26
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
27
27
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
@@ -49,6 +49,13 @@ export function parseSkillBlock(text) {
|
|
|
49
49
|
userMessage: match[4]?.trim() || undefined,
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
+
function estimateMessagesTokens(messages) {
|
|
53
|
+
let tokens = 0;
|
|
54
|
+
for (const message of messages) {
|
|
55
|
+
tokens += estimateTokens(message);
|
|
56
|
+
}
|
|
57
|
+
return tokens;
|
|
58
|
+
}
|
|
52
59
|
// ============================================================================
|
|
53
60
|
// Constants
|
|
54
61
|
// ============================================================================
|
|
@@ -1329,6 +1336,7 @@ export class AgentSession {
|
|
|
1329
1336
|
const newEntries = this.sessionManager.getEntries();
|
|
1330
1337
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1331
1338
|
this.agent.state.messages = sessionContext.messages;
|
|
1339
|
+
const estimatedTokensAfter = estimateMessagesTokens(sessionContext.messages);
|
|
1332
1340
|
// Get the saved compaction entry for the extension event
|
|
1333
1341
|
const savedCompactionEntry = newEntries.find((e) => e.type === "compaction" && e.summary === summary);
|
|
1334
1342
|
if (this._extensionRunner && savedCompactionEntry) {
|
|
@@ -1342,6 +1350,7 @@ export class AgentSession {
|
|
|
1342
1350
|
summary,
|
|
1343
1351
|
firstKeptEntryId,
|
|
1344
1352
|
tokensBefore,
|
|
1353
|
+
estimatedTokensAfter,
|
|
1345
1354
|
details,
|
|
1346
1355
|
};
|
|
1347
1356
|
this._emit({
|
|
@@ -1416,8 +1425,15 @@ export class AgentSession {
|
|
|
1416
1425
|
if (assistantIsFromBeforeCompaction) {
|
|
1417
1426
|
return false;
|
|
1418
1427
|
}
|
|
1419
|
-
// Case 1: Overflow - LLM returned context overflow error
|
|
1428
|
+
// Case 1: Overflow - LLM returned context overflow error, or reported usage exceeded
|
|
1429
|
+
// the configured window. A successful response over the configured window should compact
|
|
1430
|
+
// but must not retry: the assistant answer already completed and agent.continue() cannot
|
|
1431
|
+
// continue from an assistant message.
|
|
1420
1432
|
if (sameModel && isContextOverflow(assistantMessage, contextWindow)) {
|
|
1433
|
+
const willRetry = assistantMessage.stopReason !== "stop";
|
|
1434
|
+
if (!willRetry) {
|
|
1435
|
+
return await this._runAutoCompaction("overflow", false);
|
|
1436
|
+
}
|
|
1421
1437
|
if (this._overflowRecoveryAttempted) {
|
|
1422
1438
|
this._emit({
|
|
1423
1439
|
type: "compaction_end",
|
|
@@ -1436,7 +1452,7 @@ export class AgentSession {
|
|
|
1436
1452
|
if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
|
|
1437
1453
|
this.agent.state.messages = messages.slice(0, -1);
|
|
1438
1454
|
}
|
|
1439
|
-
return await this._runAutoCompaction("overflow",
|
|
1455
|
+
return await this._runAutoCompaction("overflow", willRetry);
|
|
1440
1456
|
}
|
|
1441
1457
|
// Case 2: Threshold - context is getting large
|
|
1442
1458
|
// For error messages (no usage data), estimate from last successful response.
|
|
@@ -1471,17 +1487,9 @@ export class AgentSession {
|
|
|
1471
1487
|
*/
|
|
1472
1488
|
async _runAutoCompaction(reason, willRetry) {
|
|
1473
1489
|
const settings = this.settingsManager.getCompactionSettings();
|
|
1474
|
-
|
|
1475
|
-
this._autoCompactionAbortController = new AbortController();
|
|
1490
|
+
let started = false;
|
|
1476
1491
|
try {
|
|
1477
1492
|
if (!this.model) {
|
|
1478
|
-
this._emit({
|
|
1479
|
-
type: "compaction_end",
|
|
1480
|
-
reason,
|
|
1481
|
-
result: undefined,
|
|
1482
|
-
aborted: false,
|
|
1483
|
-
willRetry: false,
|
|
1484
|
-
});
|
|
1485
1493
|
return false;
|
|
1486
1494
|
}
|
|
1487
1495
|
let apiKey;
|
|
@@ -1490,13 +1498,6 @@ export class AgentSession {
|
|
|
1490
1498
|
if (this.agent.streamFn === streamSimple) {
|
|
1491
1499
|
const authResult = await this._modelRegistry.getApiKeyAndHeaders(this.model);
|
|
1492
1500
|
if (!authResult.ok || !authResult.apiKey) {
|
|
1493
|
-
this._emit({
|
|
1494
|
-
type: "compaction_end",
|
|
1495
|
-
reason,
|
|
1496
|
-
result: undefined,
|
|
1497
|
-
aborted: false,
|
|
1498
|
-
willRetry: false,
|
|
1499
|
-
});
|
|
1500
1501
|
return false;
|
|
1501
1502
|
}
|
|
1502
1503
|
apiKey = authResult.apiKey;
|
|
@@ -1509,15 +1510,11 @@ export class AgentSession {
|
|
|
1509
1510
|
const pathEntries = this.sessionManager.getBranch();
|
|
1510
1511
|
const preparation = prepareCompaction(pathEntries, settings);
|
|
1511
1512
|
if (!preparation) {
|
|
1512
|
-
this._emit({
|
|
1513
|
-
type: "compaction_end",
|
|
1514
|
-
reason,
|
|
1515
|
-
result: undefined,
|
|
1516
|
-
aborted: false,
|
|
1517
|
-
willRetry: false,
|
|
1518
|
-
});
|
|
1519
1513
|
return false;
|
|
1520
1514
|
}
|
|
1515
|
+
this._emit({ type: "compaction_start", reason });
|
|
1516
|
+
this._autoCompactionAbortController = new AbortController();
|
|
1517
|
+
started = true;
|
|
1521
1518
|
let extensionCompaction;
|
|
1522
1519
|
let fromExtension = false;
|
|
1523
1520
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
@@ -1576,6 +1573,7 @@ export class AgentSession {
|
|
|
1576
1573
|
const newEntries = this.sessionManager.getEntries();
|
|
1577
1574
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1578
1575
|
this.agent.state.messages = sessionContext.messages;
|
|
1576
|
+
const estimatedTokensAfter = estimateMessagesTokens(sessionContext.messages);
|
|
1579
1577
|
// Get the saved compaction entry for the extension event
|
|
1580
1578
|
const savedCompactionEntry = newEntries.find((e) => e.type === "compaction" && e.summary === summary);
|
|
1581
1579
|
if (this._extensionRunner && savedCompactionEntry) {
|
|
@@ -1589,6 +1587,7 @@ export class AgentSession {
|
|
|
1589
1587
|
summary,
|
|
1590
1588
|
firstKeptEntryId,
|
|
1591
1589
|
tokensBefore,
|
|
1590
|
+
estimatedTokensAfter,
|
|
1592
1591
|
details,
|
|
1593
1592
|
};
|
|
1594
1593
|
this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry });
|
|
@@ -1606,16 +1605,18 @@ export class AgentSession {
|
|
|
1606
1605
|
}
|
|
1607
1606
|
catch (error) {
|
|
1608
1607
|
const errorMessage = error instanceof Error ? error.message : "compaction failed";
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1608
|
+
if (started) {
|
|
1609
|
+
this._emit({
|
|
1610
|
+
type: "compaction_end",
|
|
1611
|
+
reason,
|
|
1612
|
+
result: undefined,
|
|
1613
|
+
aborted: false,
|
|
1614
|
+
willRetry: false,
|
|
1615
|
+
errorMessage: reason === "overflow"
|
|
1616
|
+
? `Context overflow recovery failed: ${errorMessage}`
|
|
1617
|
+
: `Auto-compaction failed: ${errorMessage}`,
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1619
1620
|
return false;
|
|
1620
1621
|
}
|
|
1621
1622
|
finally {
|