@averyyy/pi-coding-agent 0.84.3-piclient.1 → 0.84.4-piclient.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 +123 -0
- package/README.md +5 -4
- package/dist/bundle/chunks/{chunk-GPPBJGBU.js → chunk-2KVJKXS2.js} +1 -1
- package/dist/bundle/chunks/{chunk-QI42RBZ4.js → chunk-AP7VCR6I.js} +73 -72
- package/dist/bundle/chunks/{google-generative-ai-XDKMGBCJ.js → google-generative-ai-YMUPJBKR.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-D5FGEO3Y.js → google-vertex-MPWMV4OF.js} +1 -1
- package/dist/bundle/chunks/https-proxy-agent-2VXB7436.js +13 -0
- package/dist/bundle/chunks/{mistral-conversations-YK73UAOZ.js → mistral-conversations-Q3AWZJAZ.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-JD4WAC3R.js → openai-completions-ERMU2SS7.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +2 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/agent-session.d.ts +12 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +102 -19
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +8 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +9 -4
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +42 -22
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +45 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +18 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +4 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +8 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +17 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +10 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +48 -24
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +7 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +3 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +12 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +6 -4
- package/dist/utils/shell.js.map +1 -1
- package/docs/compaction.md +2 -0
- package/docs/custom-provider.md +7 -7
- package/docs/environment-variables.md +3 -0
- package/docs/extensions.md +18 -0
- package/docs/keybindings.md +1 -1
- package/docs/quickstart.md +1 -1
- package/docs/rpc.md +23 -0
- package/docs/settings.md +12 -4
- package/docs/terminal-setup.md +12 -0
- package/docs/usage.md +4 -3
- 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/package.json +6 -6
- package/dist/bundle/chunks/dist-RDWOYWHR.js +0 -13
|
@@ -170,6 +170,8 @@ export class AgentSession {
|
|
|
170
170
|
_followUpMessages = [];
|
|
171
171
|
/** Messages queued to be included with the next user prompt as context ("asides"). */
|
|
172
172
|
_pendingNextTurnMessages = [];
|
|
173
|
+
/** Context-only custom messages queued during a run, flushed once the current turn's tool results are in. */
|
|
174
|
+
_pendingCustomMessages = [];
|
|
173
175
|
// Compaction state
|
|
174
176
|
_compactionAbortController = undefined;
|
|
175
177
|
_autoCompactionAbortController = undefined;
|
|
@@ -472,6 +474,11 @@ export class AgentSession {
|
|
|
472
474
|
followUp: [...this._followUpMessages],
|
|
473
475
|
});
|
|
474
476
|
}
|
|
477
|
+
async _emitSessionCompactFailed(event) {
|
|
478
|
+
if (this._extensionRunner.hasHandlers("session_compact_failed")) {
|
|
479
|
+
await this._extensionRunner.emit({ type: "session_compact_failed", ...event });
|
|
480
|
+
}
|
|
481
|
+
}
|
|
475
482
|
_getIdleWaitPromise() {
|
|
476
483
|
if (!this._idleWaitPromise) {
|
|
477
484
|
this._idleWaitPromise = new Promise((resolve) => {
|
|
@@ -562,6 +569,14 @@ export class AgentSession {
|
|
|
562
569
|
}
|
|
563
570
|
}
|
|
564
571
|
}
|
|
572
|
+
// A turn ends after its assistant message and every tool result has been appended,
|
|
573
|
+
// so this is the first point in the run where a context-only custom message can be
|
|
574
|
+
// inserted without landing between a tool call and its result. Flushing after the
|
|
575
|
+
// extension and listener dispatch above also picks up messages that turn_end
|
|
576
|
+
// handlers queued.
|
|
577
|
+
if (event.type === "turn_end") {
|
|
578
|
+
this._flushPendingCustomMessages();
|
|
579
|
+
}
|
|
565
580
|
};
|
|
566
581
|
_willRetryAfterAgentEnd(event) {
|
|
567
582
|
const settings = this.settingsManager.getRetrySettings();
|
|
@@ -990,6 +1005,7 @@ export class AgentSession {
|
|
|
990
1005
|
finally {
|
|
991
1006
|
this._systemPromptOverride = undefined;
|
|
992
1007
|
this._flushPendingBashMessages();
|
|
1008
|
+
this._flushPendingCustomMessages();
|
|
993
1009
|
await this._emitAgentSettled();
|
|
994
1010
|
}
|
|
995
1011
|
}
|
|
@@ -1148,8 +1164,9 @@ export class AgentSession {
|
|
|
1148
1164
|
preflightResult?.(true);
|
|
1149
1165
|
return;
|
|
1150
1166
|
}
|
|
1151
|
-
// Flush any pending bash messages before the new prompt
|
|
1167
|
+
// Flush any pending bash and custom messages before the new prompt
|
|
1152
1168
|
this._flushPendingBashMessages();
|
|
1169
|
+
this._flushPendingCustomMessages();
|
|
1153
1170
|
// Validate model
|
|
1154
1171
|
if (!this.model) {
|
|
1155
1172
|
throw new Error(formatNoModelSelectedMessage());
|
|
@@ -1366,8 +1383,9 @@ export class AgentSession {
|
|
|
1366
1383
|
/**
|
|
1367
1384
|
* Send a custom message to the session. Creates a CustomMessageEntry.
|
|
1368
1385
|
*
|
|
1369
|
-
* Handles
|
|
1386
|
+
* Handles four cases:
|
|
1370
1387
|
* - Streaming: queues message, processed when loop pulls from queue
|
|
1388
|
+
* - Streaming + triggerTurn false: appended to state/session once the current turn ends
|
|
1371
1389
|
* - Not streaming + triggerTurn: appends to state/session, starts new turn
|
|
1372
1390
|
* - Not streaming + no trigger: appends to state/session, no turn
|
|
1373
1391
|
*
|
|
@@ -1399,11 +1417,34 @@ export class AgentSession {
|
|
|
1399
1417
|
else if (options?.triggerTurn) {
|
|
1400
1418
|
await this._runAgentPrompt(appMessage);
|
|
1401
1419
|
}
|
|
1420
|
+
else if (this.isStreaming) {
|
|
1421
|
+
// Appending now would put the message between an assistant tool call and its
|
|
1422
|
+
// result, which providers that validate message order reject on replay. Defer
|
|
1423
|
+
// to the end of the turn. Nothing is emitted yet: message events must not
|
|
1424
|
+
// describe messages the session tree does not contain.
|
|
1425
|
+
this._pendingCustomMessages.push(appMessage);
|
|
1426
|
+
}
|
|
1402
1427
|
else {
|
|
1403
|
-
this.
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1428
|
+
this._appendCustomMessage(appMessage);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
_appendCustomMessage(appMessage) {
|
|
1432
|
+
this.agent.state.messages.push(appMessage);
|
|
1433
|
+
this.sessionManager.appendCustomMessageEntry(appMessage.customType, appMessage.content, appMessage.display, appMessage.details);
|
|
1434
|
+
this._emit({ type: "message_start", message: appMessage });
|
|
1435
|
+
this._emit({ type: "message_end", message: appMessage });
|
|
1436
|
+
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Append custom messages queued while the agent was running.
|
|
1439
|
+
* Called once the current turn's tool results are in agent state and session history.
|
|
1440
|
+
*/
|
|
1441
|
+
_flushPendingCustomMessages() {
|
|
1442
|
+
if (this._pendingCustomMessages.length === 0)
|
|
1443
|
+
return;
|
|
1444
|
+
const pending = this._pendingCustomMessages;
|
|
1445
|
+
this._pendingCustomMessages = [];
|
|
1446
|
+
for (const appMessage of pending) {
|
|
1447
|
+
this._appendCustomMessage(appMessage);
|
|
1407
1448
|
}
|
|
1408
1449
|
}
|
|
1409
1450
|
/**
|
|
@@ -1518,6 +1559,7 @@ export class AgentSession {
|
|
|
1518
1559
|
this.sessionManager.appendModelChange(model.provider, model.id);
|
|
1519
1560
|
if (options.persist) {
|
|
1520
1561
|
this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
|
|
1562
|
+
this._addPersistedDefaultToNonEmptyScope(model);
|
|
1521
1563
|
}
|
|
1522
1564
|
// Apply thinking level for the new model.
|
|
1523
1565
|
// Per-model thinking level overrides take priority over the global default.
|
|
@@ -1525,6 +1567,20 @@ export class AgentSession {
|
|
|
1525
1567
|
this.setThinkingLevel(thinkingLevel);
|
|
1526
1568
|
await this._emitModelSelect(model, previousModel, "set");
|
|
1527
1569
|
}
|
|
1570
|
+
_addPersistedDefaultToNonEmptyScope(model) {
|
|
1571
|
+
if (this._scopedModels.length === 0)
|
|
1572
|
+
return;
|
|
1573
|
+
if (this._scopedModels.some((scoped) => modelsAreEqual(scoped.model, model)))
|
|
1574
|
+
return;
|
|
1575
|
+
this._scopedModels = [...this._scopedModels, { model }];
|
|
1576
|
+
const enabledModels = this.settingsManager.getEnabledModels();
|
|
1577
|
+
if (!enabledModels?.length)
|
|
1578
|
+
return;
|
|
1579
|
+
const modelReference = `${model.provider}/${model.id}`;
|
|
1580
|
+
if (enabledModels.some((pattern) => pattern.toLowerCase() === modelReference.toLowerCase()))
|
|
1581
|
+
return;
|
|
1582
|
+
this.settingsManager.setEnabledModels([...enabledModels, modelReference]);
|
|
1583
|
+
}
|
|
1528
1584
|
/**
|
|
1529
1585
|
* Cycle to next/previous model.
|
|
1530
1586
|
* Uses scoped models (from --models flag) if available, otherwise all available models.
|
|
@@ -1555,6 +1611,7 @@ export class AgentSession {
|
|
|
1555
1611
|
this.sessionManager.appendModelChange(next.model.provider, next.model.id);
|
|
1556
1612
|
if (options.persist) {
|
|
1557
1613
|
this.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);
|
|
1614
|
+
this._addPersistedDefaultToNonEmptyScope(next.model);
|
|
1558
1615
|
}
|
|
1559
1616
|
// Apply thinking level for the new model.
|
|
1560
1617
|
// - Explicit scoped model thinking level overrides defaults
|
|
@@ -1581,6 +1638,7 @@ export class AgentSession {
|
|
|
1581
1638
|
this.sessionManager.appendModelChange(nextModel.provider, nextModel.id);
|
|
1582
1639
|
if (options.persist) {
|
|
1583
1640
|
this.settingsManager.setDefaultModelAndProvider(nextModel.provider, nextModel.id);
|
|
1641
|
+
this._addPersistedDefaultToNonEmptyScope(nextModel);
|
|
1584
1642
|
}
|
|
1585
1643
|
// Apply thinking level for the new model.
|
|
1586
1644
|
// Model persistence does not implicitly rewrite the global thinking default.
|
|
@@ -1920,20 +1978,24 @@ export class AgentSession {
|
|
|
1920
1978
|
// independent of the configured context size or any context-clamped provider request limit.
|
|
1921
1979
|
// A successful response over the configured window should compact but must not retry: the
|
|
1922
1980
|
// assistant answer already completed and agent.continue() cannot continue from an assistant.
|
|
1981
|
+
const contextOverflow = sameModel && isContextOverflow(assistantMessage, contextWindow);
|
|
1923
1982
|
const recoverableLength = sameModel && isRecoverableLength(assistantMessage, this.model?.maxTokens ?? 0);
|
|
1924
|
-
if (
|
|
1983
|
+
if (contextOverflow || recoverableLength) {
|
|
1925
1984
|
const willRetry = assistantMessage.stopReason !== "stop";
|
|
1926
1985
|
if (!willRetry) {
|
|
1927
1986
|
return await this._runAutoCompaction("overflow", false);
|
|
1928
1987
|
}
|
|
1929
1988
|
if (this._overflowRecoveryAttempted) {
|
|
1989
|
+
const errorMessage = contextOverflow
|
|
1990
|
+
? "Context overflow recovery failed after one compact-and-retry attempt. Try reducing context or switching to a larger-context model."
|
|
1991
|
+
: "Truncated response recovery failed after one compact-and-retry attempt.";
|
|
1930
1992
|
this._emit({
|
|
1931
1993
|
type: "compaction_end",
|
|
1932
1994
|
reason: "overflow",
|
|
1933
1995
|
result: undefined,
|
|
1934
1996
|
aborted: false,
|
|
1935
1997
|
willRetry: false,
|
|
1936
|
-
errorMessage
|
|
1998
|
+
errorMessage,
|
|
1937
1999
|
});
|
|
1938
2000
|
return false;
|
|
1939
2001
|
}
|
|
@@ -1963,16 +2025,16 @@ export class AgentSession {
|
|
|
1963
2025
|
if (assistantMessage.stopReason === "error" || directContextTokens === 0) {
|
|
1964
2026
|
const messages = this.agent.state.messages;
|
|
1965
2027
|
const estimate = estimateContextTokens(messages);
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
//
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
2028
|
+
// When a valid usage entry exists, verify it is post-compaction. Kept
|
|
2029
|
+
// pre-compaction messages have stale usage reflecting the old (larger)
|
|
2030
|
+
// context and would falsely trigger compaction right after one finished.
|
|
2031
|
+
if (estimate.lastUsageIndex !== null) {
|
|
2032
|
+
const usageMsg = messages[estimate.lastUsageIndex];
|
|
2033
|
+
if (compactionTimestamp > 0 &&
|
|
2034
|
+
usageMsg.role === "assistant" &&
|
|
2035
|
+
usageMsg.timestamp <= compactionTimestamp) {
|
|
2036
|
+
return false;
|
|
2037
|
+
}
|
|
1976
2038
|
}
|
|
1977
2039
|
contextTokens = estimate.tokens;
|
|
1978
2040
|
}
|
|
@@ -1990,6 +2052,7 @@ export class AgentSession {
|
|
|
1990
2052
|
async _runAutoCompaction(reason, willRetry, preparationOverride, preparationOptions) {
|
|
1991
2053
|
const settings = this.settingsManager.getCompactionSettings();
|
|
1992
2054
|
let started = false;
|
|
2055
|
+
let fromExtension = false;
|
|
1993
2056
|
try {
|
|
1994
2057
|
if (!this.model) {
|
|
1995
2058
|
return false;
|
|
@@ -2029,7 +2092,6 @@ export class AgentSession {
|
|
|
2029
2092
|
this._autoCompactionAbortController = new AbortController();
|
|
2030
2093
|
started = true;
|
|
2031
2094
|
let extensionCompaction;
|
|
2032
|
-
let fromExtension = false;
|
|
2033
2095
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
2034
2096
|
const extensionResult = (await this._extensionRunner.emit({
|
|
2035
2097
|
type: "session_before_compact",
|
|
@@ -2048,6 +2110,12 @@ export class AgentSession {
|
|
|
2048
2110
|
aborted: true,
|
|
2049
2111
|
willRetry: false,
|
|
2050
2112
|
});
|
|
2113
|
+
await this._emitSessionCompactFailed({
|
|
2114
|
+
reason,
|
|
2115
|
+
aborted: true,
|
|
2116
|
+
willRetry: false,
|
|
2117
|
+
fromExtension: false,
|
|
2118
|
+
});
|
|
2051
2119
|
return false;
|
|
2052
2120
|
}
|
|
2053
2121
|
if (extensionResult?.compaction) {
|
|
@@ -2085,6 +2153,12 @@ export class AgentSession {
|
|
|
2085
2153
|
aborted: true,
|
|
2086
2154
|
willRetry: false,
|
|
2087
2155
|
});
|
|
2156
|
+
await this._emitSessionCompactFailed({
|
|
2157
|
+
reason,
|
|
2158
|
+
aborted: true,
|
|
2159
|
+
willRetry: false,
|
|
2160
|
+
fromExtension,
|
|
2161
|
+
});
|
|
2088
2162
|
return false;
|
|
2089
2163
|
}
|
|
2090
2164
|
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
|
|
@@ -2141,6 +2215,15 @@ export class AgentSession {
|
|
|
2141
2215
|
? `Context overflow recovery failed: ${errorMessage}`
|
|
2142
2216
|
: `Auto-compaction failed: ${errorMessage}`,
|
|
2143
2217
|
});
|
|
2218
|
+
await this._emitSessionCompactFailed({
|
|
2219
|
+
reason,
|
|
2220
|
+
errorMessage: reason === "overflow"
|
|
2221
|
+
? `Context overflow recovery failed: ${errorMessage}`
|
|
2222
|
+
: `Auto-compaction failed: ${errorMessage}`,
|
|
2223
|
+
aborted: false,
|
|
2224
|
+
willRetry: false,
|
|
2225
|
+
fromExtension,
|
|
2226
|
+
});
|
|
2144
2227
|
}
|
|
2145
2228
|
return false;
|
|
2146
2229
|
}
|