@earendil-works/pi-coding-agent 0.86.0 → 0.87.0
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 +62 -0
- package/README.md +37 -0
- package/dist/bundle/chunks/{chunk-7YM6BE7Y.js → chunk-4DKZACXI.js} +53 -46
- package/dist/bundle/chunks/chunk-GV2E3GBU.js +2 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/meta.js +2 -0
- package/dist/bundle/chunks/{openai-completions-KQPOPEVM.js → openai-completions-XHML6MTL.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-XW5APVUE.js → virtual-modules-BNWPZYDH.js} +1 -1
- package/dist/bundle/cli-runtime.js +3 -0
- package/dist/bundle/cli.js +4 -2
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +1 -1
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +27 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +389 -119
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/cache-warmer.d.ts +1 -0
- package/dist/core/cache-warmer.d.ts.map +1 -1
- package/dist/core/cache-warmer.js +15 -1
- package/dist/core/cache-warmer.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +3 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +146 -48
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/crash-log.d.ts +5 -0
- package/dist/core/crash-log.d.ts.map +1 -1
- package/dist/core/crash-log.js +68 -0
- package/dist/core/crash-log.js.map +1 -1
- package/dist/core/export-html/template.js +6 -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 +16 -3
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +110 -5
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +77 -6
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/model-config.d.ts +52 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +16 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -0
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +6 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +61 -35
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-composer.d.ts +1 -0
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +19 -0
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +6 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +36 -9
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +97 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/tools/read.d.ts +4 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +5 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +4 -3
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/bug-report.d.ts +2 -0
- package/dist/modes/interactive/bug-report.d.ts.map +1 -1
- package/dist/modes/interactive/bug-report.js +6 -5
- package/dist/modes/interactive/bug-report.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +4 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +7 -2
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +7 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +5 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +74 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +1 -12
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +74 -20
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js +1 -1
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/tool-result-images.d.ts +3 -1
- package/dist/utils/tool-result-images.d.ts.map +1 -1
- package/dist/utils/tool-result-images.js +4 -1
- package/dist/utils/tool-result-images.js.map +1 -1
- package/dist/utils/wsl.d.ts +3 -0
- package/dist/utils/wsl.d.ts.map +1 -0
- package/dist/utils/wsl.js +15 -0
- package/dist/utils/wsl.js.map +1 -0
- package/docs/compaction.md +23 -4
- package/docs/extensions.md +70 -6
- package/docs/models.md +29 -1
- package/docs/providers.md +8 -0
- package/docs/sdk.md +13 -2
- package/docs/session-format.md +15 -2
- 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/examples/plugins/pi-example-plugin/src/session.ts +3 -2
- package/npm-shrinkwrap.json +20 -20
- package/package.json +8 -8
- package/dist/bundle/chunks/chunk-7IOYH2SY.js +0 -2
|
@@ -6,6 +6,7 @@ import * as crypto from "node:crypto";
|
|
|
6
6
|
import * as fs from "node:fs";
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as path from "node:path";
|
|
9
|
+
import { isRetryableAssistantError, } from "@earendil-works/pi-ai/compat";
|
|
9
10
|
import * as TuiLayouts from "@earendil-works/pi-tui";
|
|
10
11
|
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Markdown, matchesKey, Spacer, setCapabilityOverrides, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
|
|
11
12
|
import chalk from "chalk";
|
|
@@ -15,12 +16,12 @@ import { parseSkillBlock } from "../../core/agent-session.js";
|
|
|
15
16
|
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
16
17
|
import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
|
|
17
18
|
import { formatCacheWarmingStatus, formatCacheWarmingUsage } from "../../core/cache-warmer.js";
|
|
18
|
-
import { recordCrash, takeUnnotifiedCrash } from "../../core/crash-log.js";
|
|
19
|
+
import { findExtensionStackMatches, recordCrash, takeUnnotifiedCrash } from "../../core/crash-log.js";
|
|
19
20
|
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "../../core/defaults.js";
|
|
20
21
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
21
22
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
22
23
|
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
23
|
-
import { createCompactionSummaryMessage } from "../../core/messages.js";
|
|
24
|
+
import { createCompactionSummaryMessage, createCustomMessage } from "../../core/messages.js";
|
|
24
25
|
import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScopeFromModels, } from "../../core/model-resolver.js";
|
|
25
26
|
import { CredentialSynchronizationError } from "../../core/model-runtime.js";
|
|
26
27
|
import { DefaultPackageManager } from "../../core/package-manager.js";
|
|
@@ -120,6 +121,22 @@ function isDeadTerminalError(error) {
|
|
|
120
121
|
const code = error.code;
|
|
121
122
|
return code !== undefined && DEAD_TERMINAL_ERROR_CODES.has(code);
|
|
122
123
|
}
|
|
124
|
+
export function formatCrashExtensionHint(extensionMatches) {
|
|
125
|
+
const matches = Array.isArray(extensionMatches)
|
|
126
|
+
? extensionMatches.filter((match) => typeof match === "string" && match.length > 0)
|
|
127
|
+
: [];
|
|
128
|
+
if (matches.length === 0)
|
|
129
|
+
return undefined;
|
|
130
|
+
const quoted = matches.map((match) => `\`${match}\``);
|
|
131
|
+
const labels = quoted.length === 1
|
|
132
|
+
? quoted[0]
|
|
133
|
+
: quoted.length === 2
|
|
134
|
+
? quoted.join(" and ")
|
|
135
|
+
: `${quoted.slice(0, -1).join(", ")}, and ${quoted[quoted.length - 1]}`;
|
|
136
|
+
const noun = matches.length === 1 ? "extension" : "extensions";
|
|
137
|
+
const pronoun = matches.length === 1 ? "it" : "them";
|
|
138
|
+
return `A stack frame came from loaded ${noun} ${labels}, which may be involved. Try disabling ${pronoun} with \`${APP_NAME} config\`, or run \`${APP_NAME} -ne\` to confirm.`;
|
|
139
|
+
}
|
|
123
140
|
const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in /settings.";
|
|
124
141
|
function isAnthropicSubscriptionAuthKey(apiKey) {
|
|
125
142
|
return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
|
|
@@ -242,6 +259,7 @@ export class InteractiveMode {
|
|
|
242
259
|
managedToolStatusStarted = false;
|
|
243
260
|
// Streaming message tracking
|
|
244
261
|
streamingComponent = undefined;
|
|
262
|
+
entriesRenderedByBoundaryCompaction = new Set();
|
|
245
263
|
streamingMessage = undefined;
|
|
246
264
|
// Tool execution tracking: toolCallId -> component
|
|
247
265
|
pendingTools = new Map();
|
|
@@ -1539,6 +1557,10 @@ export class InteractiveMode {
|
|
|
1539
1557
|
async handleFatalRuntimeError(prefix, error) {
|
|
1540
1558
|
const message = error instanceof Error ? error.message : String(error);
|
|
1541
1559
|
this.showError(`${prefix}: ${message}`);
|
|
1560
|
+
const extensionHint = this.getCrashExtensionHint(error);
|
|
1561
|
+
if (extensionHint) {
|
|
1562
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", extensionHint), this.outputPad, 0));
|
|
1563
|
+
}
|
|
1542
1564
|
if (this.recordCrash("fatal_error", error)) {
|
|
1543
1565
|
this.chatContainer.addChild(new Text(theme.fg("muted", this.crashReportInstructions()), this.outputPad, 0));
|
|
1544
1566
|
}
|
|
@@ -1546,6 +1568,14 @@ export class InteractiveMode {
|
|
|
1546
1568
|
this.stop("transcript");
|
|
1547
1569
|
process.exit(1);
|
|
1548
1570
|
}
|
|
1571
|
+
getCrashExtensionHint(error) {
|
|
1572
|
+
try {
|
|
1573
|
+
return formatCrashExtensionHint(findExtensionStackMatches(error instanceof Error ? error.stack : undefined, this.session.resourceLoader.getExtensions().extensions));
|
|
1574
|
+
}
|
|
1575
|
+
catch {
|
|
1576
|
+
return undefined;
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1549
1579
|
/** Persist a crash so the next start can point the user at `/bug`. Returns false when nothing was written. */
|
|
1550
1580
|
recordCrash(kind, error) {
|
|
1551
1581
|
try {
|
|
@@ -1571,6 +1601,13 @@ export class InteractiveMode {
|
|
|
1571
1601
|
this.chatContainer.addChild(new Text(theme.fg("muted", `If this looks like a ${APP_NAME} bug, /bug sends a report to the developers.`), this.outputPad, 0));
|
|
1572
1602
|
this.ui.requestRender();
|
|
1573
1603
|
}
|
|
1604
|
+
maybeSuggestBugReport(message) {
|
|
1605
|
+
if (message.stopReason !== "error" || isRetryableAssistantError(message))
|
|
1606
|
+
return;
|
|
1607
|
+
if (/\b(?:abort(?:ed)?|cancel(?:l?ed)?)\b/i.test(message.errorMessage ?? ""))
|
|
1608
|
+
return;
|
|
1609
|
+
this.suggestBugReport();
|
|
1610
|
+
}
|
|
1574
1611
|
renderCurrentSessionState() {
|
|
1575
1612
|
this.loadedResourcesContainer.clear();
|
|
1576
1613
|
this.chatContainer.clear();
|
|
@@ -2636,6 +2673,8 @@ export class InteractiveMode {
|
|
|
2636
2673
|
this.ui.requestRender();
|
|
2637
2674
|
break;
|
|
2638
2675
|
case "entry_appended":
|
|
2676
|
+
if (this.entriesRenderedByBoundaryCompaction.delete(event.entry.id))
|
|
2677
|
+
break;
|
|
2639
2678
|
if (event.entry.type === "custom") {
|
|
2640
2679
|
this.addCustomEntryToChat(event.entry);
|
|
2641
2680
|
this.ui.requestRender();
|
|
@@ -2644,6 +2683,34 @@ export class InteractiveMode {
|
|
|
2644
2683
|
this.addCacheWarmingUsage(event.entry);
|
|
2645
2684
|
this.ui.requestRender();
|
|
2646
2685
|
}
|
|
2686
|
+
else if (event.entry.type === "custom_message" && event.entry.display) {
|
|
2687
|
+
this.addMessageToChat(createCustomMessage(event.entry.customType, event.entry.content, event.entry.display, event.entry.details, event.entry.timestamp));
|
|
2688
|
+
this.ui.requestRender();
|
|
2689
|
+
}
|
|
2690
|
+
else if (event.entry.type === "compaction") {
|
|
2691
|
+
const entries = this.sessionManager.buildContextEntries();
|
|
2692
|
+
if (entries[0]?.id !== event.entry.id)
|
|
2693
|
+
break;
|
|
2694
|
+
this.chatContainer.clear();
|
|
2695
|
+
const branch = this.sessionManager.getBranch();
|
|
2696
|
+
const compactionIndex = branch.findIndex((entry) => entry.id === event.entry.id);
|
|
2697
|
+
const entriesAfterCompaction = new Set(branch.slice(compactionIndex + 1).map((entry) => entry.id));
|
|
2698
|
+
const retainedEntries = entries.slice(1);
|
|
2699
|
+
this.renderSessionEntries(retainedEntries.filter((entry) => !entriesAfterCompaction.has(entry.id)));
|
|
2700
|
+
this.addMessageToChat(createCompactionSummaryMessage(event.entry.summary, event.entry.tokensBefore, event.entry.timestamp));
|
|
2701
|
+
if (event.entry.usage) {
|
|
2702
|
+
this.addCompactionCostNotice({
|
|
2703
|
+
type: "compaction_cost",
|
|
2704
|
+
kind: "compaction",
|
|
2705
|
+
usage: event.entry.usage,
|
|
2706
|
+
});
|
|
2707
|
+
}
|
|
2708
|
+
this.renderSessionEntries(retainedEntries.filter((entry) => entriesAfterCompaction.has(entry.id)));
|
|
2709
|
+
for (const entryId of entriesAfterCompaction)
|
|
2710
|
+
this.entriesRenderedByBoundaryCompaction.add(entryId);
|
|
2711
|
+
this.footer.invalidate();
|
|
2712
|
+
this.ui.requestRender();
|
|
2713
|
+
}
|
|
2647
2714
|
break;
|
|
2648
2715
|
case "session_info_changed":
|
|
2649
2716
|
this.updateTerminalTitle();
|
|
@@ -2724,8 +2791,7 @@ export class InteractiveMode {
|
|
|
2724
2791
|
});
|
|
2725
2792
|
}
|
|
2726
2793
|
this.pendingTools.clear();
|
|
2727
|
-
|
|
2728
|
-
this.suggestBugReport();
|
|
2794
|
+
this.maybeSuggestBugReport(this.streamingMessage);
|
|
2729
2795
|
}
|
|
2730
2796
|
else {
|
|
2731
2797
|
// Args are now complete - trigger diff computation for edit tools
|
|
@@ -2873,7 +2939,6 @@ export class InteractiveMode {
|
|
|
2873
2939
|
// Show error only on final failure (success shows normal response)
|
|
2874
2940
|
if (!event.success) {
|
|
2875
2941
|
this.showError(`Retry failed after ${event.attempt} attempts: ${event.finalError || "Unknown error"}`);
|
|
2876
|
-
this.suggestBugReport();
|
|
2877
2942
|
}
|
|
2878
2943
|
this.ui.requestRender();
|
|
2879
2944
|
break;
|
|
@@ -3368,6 +3433,9 @@ export class InteractiveMode {
|
|
|
3368
3433
|
catch { }
|
|
3369
3434
|
console.error(`${APP_NAME} exiting due to uncaughtException:`);
|
|
3370
3435
|
console.error(error);
|
|
3436
|
+
const extensionHint = this.getCrashExtensionHint(error);
|
|
3437
|
+
if (extensionHint)
|
|
3438
|
+
console.error(`\n${extensionHint}`);
|
|
3371
3439
|
if (this.recordCrash("uncaught_exception", error)) {
|
|
3372
3440
|
console.error(`\n${this.crashReportInstructions()}`);
|
|
3373
3441
|
}
|
|
@@ -5258,6 +5326,7 @@ export class InteractiveMode {
|
|
|
5258
5326
|
ui: this.ui,
|
|
5259
5327
|
editorContainer: this.editorContainer,
|
|
5260
5328
|
editor: this.editor,
|
|
5329
|
+
keybindings: this.keybindings,
|
|
5261
5330
|
showStatus: (message) => this.showStatus(message),
|
|
5262
5331
|
showError: (message) => this.showError(message),
|
|
5263
5332
|
}, hint);
|