@andares/pi-toolkits 0.7.1 → 0.7.3
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/README.md +12 -11
- package/README.zh-CN.md +12 -11
- package/package.json +5 -5
- package/src/features/ask/bash-sandbox.test.ts +133 -2
- package/src/features/ask/bash-sandbox.ts +221 -17
- package/src/features/ask/constants.ts +16 -1
- package/src/features/ask/index.ts +39 -19
- package/src/features/ask/prompt.test.ts +45 -0
- package/src/features/ask/prompt.ts +51 -12
- package/src/features/ask/reasons.test.ts +35 -0
- package/src/features/ask/reasons.ts +68 -0
- package/src/features/autostart/index.ts +2 -1
- package/src/features/compact/index.ts +8 -4
- package/src/features/compact/prompt.ts +12 -4
- package/src/features/favorites/constants.ts +5 -4
- package/src/features/favorites/patch-cycle.ts +8 -7
- package/src/features/favorites/patch-selector.ts +4 -4
- package/src/features/stash/stash.ts +1 -1
- package/src/lib/model-config.ts +2 -2
- package/src/lib/model-picker.ts +2 -2
- package/src/lib/tools.ts +5 -3
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
* before running its own compaction
|
|
12
12
|
* - prompts, message assembly, split-turn handling, output budgets, and the
|
|
13
13
|
* summary file-list tail are verbatim pi built-in behavior (copied from
|
|
14
|
-
* 0.87.1,
|
|
15
|
-
* differs
|
|
14
|
+
* 0.87.1, byte-identical across every published version of the supported
|
|
15
|
+
* window, 0.99.0 → 1.2.0) — only the executing model differs. The one
|
|
16
|
+
* exception is `serializeConversation`, which is imported from the host
|
|
17
|
+
* instead of mirrored, so it tracks whatever the running host does
|
|
18
|
+
* (1.2.0 stopped feeding assistant thinking into the request).
|
|
16
19
|
* - lossless fallback: unset config, unavailable model, empty/failed
|
|
17
20
|
* summary, or user abort → return undefined and pi's default compaction
|
|
18
21
|
* (session model) runs untouched. The extension can never make
|
|
@@ -116,7 +119,7 @@ async function completeSummary(
|
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
/**
|
|
119
|
-
* pi's output-budget formula (compaction.js, 0.87.1 → 1.0
|
|
122
|
+
* pi's output-budget formula (compaction.js, 0.87.1 → 1.2.0 unchanged): a
|
|
120
123
|
* fraction of reserveTokens clamped by the model's own output cap.
|
|
121
124
|
*/
|
|
122
125
|
function summarizationBudget(
|
|
@@ -132,7 +135,8 @@ function summarizationBudget(
|
|
|
132
135
|
|
|
133
136
|
/**
|
|
134
137
|
* Run the full compaction summarization with the configured model,
|
|
135
|
-
* replicating pi's compact() (0.87.1,
|
|
138
|
+
* replicating pi's compact() (0.87.1, byte-identical across the supported
|
|
139
|
+
* 0.99.0 → 1.2.0 window):
|
|
136
140
|
* history summary (first-connection or iterative-update prompt, custom
|
|
137
141
|
* focus appended), plus a separate turn-prefix checkpoint when the cut point
|
|
138
142
|
* splits a turn, merged into one summary with the file-list tail. Returns
|
|
@@ -5,9 +5,15 @@
|
|
|
5
5
|
* compaction (dist/core/compaction/compaction.js and utils.js) so that
|
|
6
6
|
* summaries produced by the configured compact model are formatted exactly
|
|
7
7
|
* like pi's own compaction output. Only the executing model differs.
|
|
8
|
-
* Verified byte-identical against
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Verified byte-identical against every published version of the supported
|
|
9
|
+
* window (0.99.0 → 1.2.0): dist/core/compaction/compaction.js and
|
|
10
|
+
* core/usage-totals.js are unchanged files across that span, and the only
|
|
11
|
+
* utils.js change (1.2.0 dropping assistant thinking from
|
|
12
|
+
* serializeConversation) does not touch the strings mirrored here — that
|
|
13
|
+
* serializer is imported from the host, not mirrored. 0.87.0 shipped a
|
|
14
|
+
* different split-turn prefix prompt; the text mirrored here is 0.87.1's
|
|
15
|
+
* fix, and the mirror is the only variant any supported host gets —
|
|
16
|
+
* intentional.
|
|
11
17
|
*
|
|
12
18
|
* Update these strings whenever pi changes its built-in prompts (diff
|
|
13
19
|
* dist/core/compaction/compaction.js between versions).
|
|
@@ -196,7 +202,9 @@ export function formatFileOperations(
|
|
|
196
202
|
|
|
197
203
|
/**
|
|
198
204
|
* Combine two provider usage records field-wise (pi 0.87.1 compaction.js
|
|
199
|
-
* combineUsage
|
|
205
|
+
* combineUsage, moved verbatim to core/usage-totals.js in 0.99.0 and
|
|
206
|
+
* unchanged through 1.2.0): used when
|
|
207
|
+
* a split turn produces two summarization calls.
|
|
200
208
|
*/
|
|
201
209
|
export function combineUsage<T extends UsageLike>(first: T, second: T): T {
|
|
202
210
|
return {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* bindings — only the cycle semantics change (patch-cycle.ts), so no
|
|
9
9
|
* keybinding conflicts arise.
|
|
10
10
|
*
|
|
11
|
-
* Verified against
|
|
11
|
+
* Verified against every published version of the supported window
|
|
12
|
+
* (0.99.0 → 1.2.0) keybinding
|
|
12
13
|
* tables + pi-tui input dispatch on WSL2 + Windows Terminal; re-run
|
|
13
14
|
* `pnpm check:keybindings` after every host upgrade before trusting this.
|
|
14
15
|
*/
|
|
@@ -25,15 +26,15 @@ export const FAVORITES_FILE = "pi-toolkits-favorites.json";
|
|
|
25
26
|
* missed — audit trail below; re-run `pnpm check:keybindings` on upgrades.
|
|
26
27
|
*
|
|
27
28
|
* Why ctrl+f is dead: fullscreen became pi's default `tuiMode` in 1.0
|
|
28
|
-
* (0.
|
|
29
|
+
* (0.87–0.99 defaulted to `regular`, where the binding is inert). On
|
|
29
30
|
* Windows/WSL `tui.altScreen.search` resolves to ctrl+f, and
|
|
30
31
|
* `TuiAltScreen.handleViewportInput()` checks it before
|
|
31
32
|
* `shouldDeferViewportInputToOverlay()`, so the keystroke opens transcript
|
|
32
|
-
* search and the selector never sees it (verified in pi-tui 1.0
|
|
33
|
+
* search and the selector never sees it (verified in pi-tui 1.2.0
|
|
33
34
|
* `dist/tui-alt-screen.js`: the search check is the first key branch and
|
|
34
35
|
* returns `{ consume: true }` unconditionally).
|
|
35
36
|
*
|
|
36
|
-
* Why ctrl+alt+f was discarded: clean at the pi layer across 0.
|
|
37
|
+
* Why ctrl+alt+f was discarded: clean at the pi layer across 0.99–1.2 (only
|
|
37
38
|
* ctrl+alt+] is taken from that family) and byte-distinguishable without
|
|
38
39
|
* kitty — but grabbed at the OS/app layer on the author's machine by a
|
|
39
40
|
* Windows screenshot tool, so it never reached the terminal. Lesson: a key
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
* - with exactly one favorite, already on it → undefined (stock "only one
|
|
15
15
|
* model available" feedback); otherwise jump to it
|
|
16
16
|
* - the apply logic mirrors pi's _cycleScopedModel/_cycleAvailableModel
|
|
17
|
-
* (byte-identical across every published version in
|
|
17
|
+
* (byte-identical across every published version in the supported window
|
|
18
|
+
* 0.99.0 → 1.2.0:
|
|
18
19
|
* state swap, session persistence, default-model persistence only when
|
|
19
20
|
* `options.persist` is set, thinking-level re-clamp, model_select emit
|
|
20
21
|
* with source "cycle")
|
|
@@ -30,9 +31,9 @@ import { getFavoritesStore, modelKey } from "./store.js";
|
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* pi's `Model<any>` — the exact type of `ModelCycleResult.model`
|
|
33
|
-
* (pi-coding-agent 0.
|
|
34
|
+
* (pi-coding-agent 0.99–1.2; the field is unchanged across that span).
|
|
34
35
|
* Derived here instead of importing `Model` from @earendil-works/pi-ai,
|
|
35
|
-
* whose index.d.ts (0.
|
|
36
|
+
* whose index.d.ts (0.99 through 1.2.0 alike) re-exports it via an
|
|
36
37
|
* extensioned `"./types.ts"` specifier that not every TS resolver substitutes
|
|
37
38
|
* to `types.d.ts` (tsc 5.9 bundler does; other tsserver builds don't).
|
|
38
39
|
*/
|
|
@@ -56,7 +57,7 @@ interface CycleSessionInternals {
|
|
|
56
57
|
setDefaultModelAndProvider(provider: string, id: string): void;
|
|
57
58
|
};
|
|
58
59
|
/**
|
|
59
|
-
* pi 0.
|
|
60
|
+
* pi 0.99–1.2: keeps a persisted default usable when cycling inside a
|
|
60
61
|
* non-empty --models scope.
|
|
61
62
|
*/
|
|
62
63
|
_addPersistedDefaultToNonEmptyScope(model: unknown): void;
|
|
@@ -97,7 +98,7 @@ function nextCycleIndex(
|
|
|
97
98
|
: (currentIndex - 1 + len) % len;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
/** Options accepted by pi
|
|
101
|
+
/** Options accepted by pi's cycleModel (persist gates default-model persistence). */
|
|
101
102
|
interface CycleOptions {
|
|
102
103
|
persist?: boolean;
|
|
103
104
|
}
|
|
@@ -139,7 +140,7 @@ export function applyCyclePatch(): boolean {
|
|
|
139
140
|
return original.call(this, direction, options);
|
|
140
141
|
}
|
|
141
142
|
|
|
142
|
-
// Same source and availability filtering as pi
|
|
143
|
+
// Same source and availability filtering as pi's stock cycling (0.99–1.2).
|
|
143
144
|
const scoped = this._scopedModels.length > 0;
|
|
144
145
|
let candidates: CycleCandidate[];
|
|
145
146
|
if (scoped) {
|
|
@@ -184,7 +185,7 @@ export function applyCyclePatch(): boolean {
|
|
|
184
185
|
: this._getThinkingLevelForModelSwitch();
|
|
185
186
|
this.agent.state.model = next.model;
|
|
186
187
|
this.sessionManager.appendModelChange(next.model.provider, next.model.id);
|
|
187
|
-
// pi 0.
|
|
188
|
+
// pi 0.99–1.2: only persist the default model when the caller asked for it.
|
|
188
189
|
if (options.persist) {
|
|
189
190
|
this.settingsManager.setDefaultModelAndProvider(
|
|
190
191
|
next.model.provider,
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* keeps loading and ctrl+p falls back to stock behavior. The prototype
|
|
23
23
|
* shape touched here (handleInput/updateList/filterModels and the instance
|
|
24
24
|
* fields below) is byte-identical across every published version in
|
|
25
|
-
* pi 0.
|
|
25
|
+
* pi 0.99.0 → 1.2.0 (and 0.87.0 → 1.1.0 before the floor moved).
|
|
26
26
|
*/
|
|
27
27
|
import {
|
|
28
28
|
ModelSelectorComponent,
|
|
@@ -61,7 +61,7 @@ interface SelectorPatchTarget {
|
|
|
61
61
|
handleInput(keyData: string): void;
|
|
62
62
|
updateList(): void;
|
|
63
63
|
filterModels(query: string): void;
|
|
64
|
-
/** pi 0.
|
|
64
|
+
/** pi 0.99–1.2: default-model badge source. */
|
|
65
65
|
isDefaultModel(model: ModelRef): boolean;
|
|
66
66
|
listContainer: ListContainerLike;
|
|
67
67
|
searchInput: SearchInputLike;
|
|
@@ -116,7 +116,7 @@ let patched = false;
|
|
|
116
116
|
export function applyModelSelectorPatches(): boolean {
|
|
117
117
|
if (patched) return true;
|
|
118
118
|
// SAFETY: ModelSelectorComponent's members are TS-private (compile-time
|
|
119
|
-
// only); the structural view matches pi 0.
|
|
119
|
+
// only); the structural view matches pi 0.99–1.2's prototype shape
|
|
120
120
|
// (byte-identical across that span) and every touched method is
|
|
121
121
|
// existence-checked below before any patching happens.
|
|
122
122
|
const proto =
|
|
@@ -155,7 +155,7 @@ export function applyModelSelectorPatches(): boolean {
|
|
|
155
155
|
};
|
|
156
156
|
|
|
157
157
|
// ── 2. List rendering: hint row + bold bright yellow favorites ────────
|
|
158
|
-
// Replicates the built-in updateList layout (pi 0.
|
|
158
|
+
// Replicates the built-in updateList layout (pi 0.99–1.2: fixed-width cursor
|
|
159
159
|
// and ✓ current-marker columns, provider badge, `· default` badge, scroll
|
|
160
160
|
// indicator, empty/error states, refresh status, Model Name footer) with
|
|
161
161
|
// one change: favorited model ids render in the favorite style.
|
|
@@ -21,7 +21,7 @@ import type { KeyId } from "@earendil-works/pi-tui";
|
|
|
21
21
|
/**
|
|
22
22
|
* Stash hotkey.
|
|
23
23
|
*
|
|
24
|
-
* Compatibility rationale (verified against pi 0.
|
|
24
|
+
* Compatibility rationale (verified against pi 0.99.0–1.2.0 keybindings, live
|
|
25
25
|
* matchesKey probes and terminal/OS behavior):
|
|
26
26
|
* - pi: no default binding for ctrl+alt+<letter> (only ctrl+alt+] is taken);
|
|
27
27
|
* extension shortcuts dispatch first while the editor is focused
|
package/src/lib/model-config.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* (review, compact-model — favorites keeps its own store-local key logic).
|
|
5
5
|
*
|
|
6
6
|
* Types are derived from pi-coding-agent's own exports (ModelRegistry)
|
|
7
|
-
* rather than imported from @earendil-works/pi-ai: pi-ai's index.d.ts (0.
|
|
8
|
-
* through 1.0
|
|
7
|
+
* rather than imported from @earendil-works/pi-ai: pi-ai's index.d.ts (0.99
|
|
8
|
+
* through 1.2.0 alike) re-exports `Model`/`Api` via extensioned
|
|
9
9
|
* `./types.ts` specifiers, which tsc 5.9 bundler resolution substitutes to
|
|
10
10
|
* `.d.ts` but some tsserver builds do not. Deriving from ModelRegistry keeps
|
|
11
11
|
* every resolver in agreement with the exact type
|
package/src/lib/model-picker.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* The component is driven through a small ModelRuntime facade backed by
|
|
11
11
|
* ctx.modelRegistry (pi's extension-facing wrapper). SAFETY: verified
|
|
12
|
-
* against pi 0.
|
|
12
|
+
* against pi 0.99.0–1.2.0 dist (modes/interactive/components/model-selector.js +
|
|
13
13
|
* model-catalog-refresh.js — byte-identical across that span) — the
|
|
14
14
|
* component only calls getAvailableSnapshot, getModel, getError and refresh
|
|
15
15
|
* on modelRuntime, and ModelRegistry provides exactly those
|
|
@@ -42,7 +42,7 @@ function modelRuntimeFacade(ctx: ExtensionContext): ModelRuntime {
|
|
|
42
42
|
refresh: (options?: { signal?: AbortSignal }) =>
|
|
43
43
|
ctx.modelRegistry.refresh(options),
|
|
44
44
|
};
|
|
45
|
-
// SAFETY: the selector only touches the four members above (pi 0.
|
|
45
|
+
// SAFETY: the selector only touches the four members above (pi 0.99–1.2
|
|
46
46
|
// model-selector.js); everything else on ModelRuntime is never reached
|
|
47
47
|
// from this component.
|
|
48
48
|
return facade as unknown as ModelRuntime;
|
package/src/lib/tools.ts
CHANGED
|
@@ -8,9 +8,11 @@ export function snapshotActiveTools(pi: ExtensionAPI): string[] {
|
|
|
8
8
|
return [...pi.getActiveTools()];
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
/** Restore a previously snapshotted tool set
|
|
12
|
-
export function restoreActiveTools(
|
|
13
|
-
|
|
11
|
+
/** Restore a previously snapshotted tool set (an empty snapshot = no tools). */
|
|
12
|
+
export function restoreActiveTools(
|
|
13
|
+
pi: ExtensionAPI,
|
|
14
|
+
snapshot: readonly string[],
|
|
15
|
+
): void {
|
|
14
16
|
pi.setActiveTools([...snapshot]);
|
|
15
17
|
}
|
|
16
18
|
|