@mjasnikovs/pi-task 0.38.31 → 0.39.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/README.md +2 -1
- package/dist/config/config.d.ts +16 -2
- package/dist/config/config.js +7 -2
- package/dist/config/group-args.d.ts +52 -0
- package/dist/config/group-args.js +110 -0
- package/dist/config/group-models.d.ts +88 -0
- package/dist/config/group-models.js +117 -0
- package/dist/config/groups.d.ts +76 -0
- package/dist/config/groups.js +110 -0
- package/dist/config/option-picker.d.ts +70 -0
- package/dist/config/option-picker.js +113 -0
- package/dist/config/reasoning.d.ts +26 -64
- package/dist/config/reasoning.js +31 -115
- package/dist/config/register.d.ts +144 -24
- package/dist/config/register.js +345 -56
- package/dist/index.js +2 -0
- package/dist/remote/push.js +1 -7
- package/dist/shared/data-home.d.ts +8 -0
- package/dist/shared/data-home.js +14 -0
- package/dist/shared/model-endpoint.d.ts +53 -0
- package/dist/shared/model-endpoint.js +98 -2
- package/dist/shared/reasoning-capability.d.ts +25 -5
- package/dist/shared/reasoning-capability.js +18 -9
- package/dist/task/child-runner.d.ts +19 -16
- package/dist/task/child-runner.js +64 -36
- package/dist/task/context-usage.d.ts +46 -0
- package/dist/task/context-usage.js +41 -0
- package/dist/task/gate-child.d.ts +15 -4
- package/dist/task/gate-child.js +2 -2
- package/dist/task/gate-deps.js +7 -2
- package/dist/task/implementation-hold.d.ts +118 -0
- package/dist/task/implementation-hold.js +165 -0
- package/dist/task/model-hold-stash.d.ts +43 -0
- package/dist/task/model-hold-stash.js +70 -0
- package/dist/task/orchestrator.d.ts +18 -5
- package/dist/task/orchestrator.js +36 -4
- package/dist/task/phases.js +2 -2
- package/dist/task/research-worker.d.ts +2 -2
- package/dist/task/research-worker.js +1 -1
- package/dist/workers/docs-core.js +2 -2
- package/dist/workers/docs-lookup.d.ts +4 -3
- package/dist/workers/docs-lookup.js +1 -1
- package/dist/workers/fetch-core.js +2 -2
- package/dist/workers/focused-extractor.d.ts +4 -3
- package/dist/workers/focused-extractor.js +5 -4
- package/dist/workers/index.js +2 -0
- package/dist/workers/model-warning.d.ts +69 -0
- package/dist/workers/model-warning.js +113 -0
- package/dist/workers/pi-worker-core.d.ts +7 -7
- package/dist/workers/pi-worker-core.js +4 -3
- package/dist/workers/pi-worker-docs.js +2 -2
- package/dist/workers/pi-worker.js +4 -4
- package/dist/workers/reasoning-warning.d.ts +17 -9
- package/dist/workers/reasoning-warning.js +69 -22
- package/package.json +1 -1
- package/dist/config/reasoning-args.d.ts +0 -23
- package/dist/config/reasoning-args.js +0 -28
- package/dist/task/implementation-thinking.d.ts +0 -56
- package/dist/task/implementation-thinking.js +0 -32
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionCommandContext } from '@earendil-works/pi-coding-agent';
|
|
2
2
|
import { SettingsList } from '@earendil-works/pi-tui';
|
|
3
3
|
import type { Component } from '@earendil-works/pi-tui';
|
|
4
|
+
import { type ReasoningModelFacts } from '../shared/reasoning-capability.js';
|
|
5
|
+
import { type PairOptions } from './option-picker.js';
|
|
4
6
|
import { type PiTaskConfig } from './config.js';
|
|
5
7
|
import { type InstalledExtension } from './extension-list.js';
|
|
6
8
|
import { type GuardableTool } from './tool-list.js';
|
|
7
|
-
import { type
|
|
9
|
+
import { type GroupSetting, type ChildGroup } from './reasoning.js';
|
|
8
10
|
type Theme = ExtensionCommandContext['ui']['theme'];
|
|
9
11
|
/**
|
|
10
12
|
* Frames a child component (the settings list) in a rounded border with a title
|
|
@@ -54,7 +56,7 @@ declare class BorderedBox implements Component {
|
|
|
54
56
|
export interface ConfigItem {
|
|
55
57
|
/**
|
|
56
58
|
* The row's id. A `keyof PiTaskConfig` for a fixed setting; a prefixed
|
|
57
|
-
* string (`
|
|
59
|
+
* string (`step:`, `tool:`, `ext:`) for a DISCOVERED one.
|
|
58
60
|
*
|
|
59
61
|
* It is `string`, not `keyof PiTaskConfig`, and that is what lets the three
|
|
60
62
|
* dynamic families BE rows instead of bypassing them — so the round-trip
|
|
@@ -73,6 +75,17 @@ export interface ConfigItem {
|
|
|
73
75
|
description: string;
|
|
74
76
|
/** Offered values. Omitted for a boolean, which is always on/off. */
|
|
75
77
|
values?: string[];
|
|
78
|
+
/**
|
|
79
|
+
* Rows whose choice is a LIST, not a cycle. Present ⇒ Enter opens a picker
|
|
80
|
+
* instead of stepping `values`.
|
|
81
|
+
*
|
|
82
|
+
* A FUNCTION of the draft config, evaluated at Enter-time, because what a row
|
|
83
|
+
* may offer can depend on another row the user changed while the panel was
|
|
84
|
+
* open: a group's thinking options narrow to what its chosen model declares.
|
|
85
|
+
* `values` stays the STATIC complete vocabulary, because that is what the
|
|
86
|
+
* round-trip property in config-items.test.ts quantifies over.
|
|
87
|
+
*/
|
|
88
|
+
picker?: (cfg: PiTaskConfig) => PairOptions;
|
|
76
89
|
/** What the panel shows for the current value. */
|
|
77
90
|
format: (cfg: PiTaskConfig) => string;
|
|
78
91
|
/** Write the chosen label back. A value it does not recognise is ignored. */
|
|
@@ -92,7 +105,7 @@ export interface ConfigItem {
|
|
|
92
105
|
* exemptions from it) end up separated by rows that have nothing to do with
|
|
93
106
|
* them. The headers are inert rows: no `values`, so Enter does nothing on them.
|
|
94
107
|
*/
|
|
95
|
-
export type Section = 'session' | 'checks' | 'research' | 'reasoning' | 'timeouts' | 'unattended' | 'logging' | 'extensions';
|
|
108
|
+
export type Section = 'session' | 'checks' | 'research' | 'profile' | 'reasoning' | 'timeouts' | 'unattended' | 'logging' | 'extensions';
|
|
96
109
|
/** Section order, and the label each header renders. */
|
|
97
110
|
export declare const SECTIONS: ReadonlyArray<{
|
|
98
111
|
key: Section;
|
|
@@ -100,6 +113,18 @@ export declare const SECTIONS: ReadonlyArray<{
|
|
|
100
113
|
}>;
|
|
101
114
|
/** Marks a header row, so onChange can ignore one and tests can find them. */
|
|
102
115
|
export declare const SECTION_ID_PREFIX = "section:";
|
|
116
|
+
/**
|
|
117
|
+
* Is this row scenery rather than a setting?
|
|
118
|
+
*
|
|
119
|
+
* Reads the ID, not `values`. Those two agreed only while every real row cycled
|
|
120
|
+
* a list: a picker row has a `submenu` and may carry `values` purely for the
|
|
121
|
+
* round-trip contract, so "no values" stopped meaning "not a row". Both
|
|
122
|
+
* `sectionHeader` and `sectionGap` already stamp the prefix, so this is exact
|
|
123
|
+
* rather than a heuristic, and all three consumers ask the same question.
|
|
124
|
+
*/
|
|
125
|
+
export declare const isSectionRow: (item: {
|
|
126
|
+
id: string;
|
|
127
|
+
}) => boolean;
|
|
103
128
|
/**
|
|
104
129
|
* Every setting rendered by /task-config, in display order.
|
|
105
130
|
*
|
|
@@ -114,7 +139,7 @@ export declare function toolItems(tools: readonly GuardableTool[]): ConfigItem[]
|
|
|
114
139
|
/** Apply a per-tool watchdog toggle to the exemption list (idempotent both ways). */
|
|
115
140
|
export declare function applyToolToggle(exempt: readonly string[], toolName: string, watched: boolean): string[];
|
|
116
141
|
/**
|
|
117
|
-
* The label for one
|
|
142
|
+
* The label for one step row.
|
|
118
143
|
*
|
|
119
144
|
* A group whose name carries a colon is a CHILD of the group before the colon —
|
|
120
145
|
* `research:files` is one of the four workers `research` fans out to. Rendered
|
|
@@ -123,15 +148,95 @@ export declare function applyToolToggle(exempt: readonly string[], toolName: str
|
|
|
123
148
|
* parent is also a row.
|
|
124
149
|
*
|
|
125
150
|
* So a child is drawn as a tree branch under its parent and loses the repeated
|
|
126
|
-
* `
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
151
|
+
* `research:` prefix, the same text at the head of four consecutive lines. `└─`
|
|
152
|
+
* on the last child, `├─` on the rest, decided from the group's position in
|
|
153
|
+
* {@link CHILD_GROUPS} rather than a hand-kept list — adding a fifth worker
|
|
154
|
+
* moves the corner on its own.
|
|
155
|
+
*
|
|
156
|
+
* A parentless group is its own bare name. It carried a `think: ` prefix while
|
|
157
|
+
* there were two families to tell apart; with one row per step there is nothing
|
|
158
|
+
* to disambiguate, and the prefix was the widest thing in the column.
|
|
130
159
|
*
|
|
131
160
|
* Leading spaces survive: SettingsList pads the label right, never trims it.
|
|
132
161
|
*/
|
|
133
|
-
export declare function
|
|
134
|
-
|
|
162
|
+
export declare function stepRowLabel(group: ChildGroup): string;
|
|
163
|
+
/**
|
|
164
|
+
* What this machine can offer a model row, and what each offer can DO.
|
|
165
|
+
*
|
|
166
|
+
* `facts` is what lets the thinking rows narrow: a group pinned to a
|
|
167
|
+
* `reasoning: false` model may only be offered `off`. It answers `undefined` for
|
|
168
|
+
* a spec it cannot resolve — a vanished model, or `inherit` before a session
|
|
169
|
+
* exists — and every consumer reads that as "offer everything", which is exactly
|
|
170
|
+
* today's behaviour.
|
|
171
|
+
*/
|
|
172
|
+
export interface ModelCatalog {
|
|
173
|
+
/** Offerable `provider/id` specs, without `inherit`. */
|
|
174
|
+
specs: readonly string[];
|
|
175
|
+
/** Human note per spec, e.g. an extension-provided provider's warning. */
|
|
176
|
+
note?: (spec: string) => string | undefined;
|
|
177
|
+
facts: (spec: string) => ReasoningModelFacts | undefined;
|
|
178
|
+
}
|
|
179
|
+
/** No registry reachable. Every row still renders; nothing narrows. */
|
|
180
|
+
export declare const EMPTY_CATALOG: ModelCatalog;
|
|
181
|
+
/**
|
|
182
|
+
* The levels a row may offer, given the model that row's group will run on.
|
|
183
|
+
*
|
|
184
|
+
* The INTERSECTION with `REASONING_SETTINGS`, not `supportedThinkingLevels`
|
|
185
|
+
* directly: that returns the whole ladder including `xhigh` and `max`, which
|
|
186
|
+
* this menu excludes on purpose (see reasoning.ts) because pi's own UI may not
|
|
187
|
+
* offer them. A model declaring `xhigh` must not smuggle it in here.
|
|
188
|
+
*/
|
|
189
|
+
export declare function offeredLevels(facts: ReasoningModelFacts | undefined): GroupSetting[];
|
|
190
|
+
/**
|
|
191
|
+
* `level · provider/id`, the one string a step row shows and accepts.
|
|
192
|
+
*
|
|
193
|
+
* THE LEVEL COMES FIRST, and that is a display decision with teeth.
|
|
194
|
+
* `SettingsList` truncates a value from the RIGHT, so whatever is last is what
|
|
195
|
+
* silently disappears — and a real local model id (`local/Qwen3.8-27B-UD-Q4_K_XL
|
|
196
|
+
* .gguf`) is wide enough to consume the whole column on its own. Level-first
|
|
197
|
+
* means the half that falls off is the one still identifiable from its head, and
|
|
198
|
+
* the levels line up as a column you can read down.
|
|
199
|
+
*/
|
|
200
|
+
export declare function formatStepValue(spec: string, level: GroupSetting): string;
|
|
201
|
+
/**
|
|
202
|
+
* The two halves back out, or `undefined` for anything not of that shape.
|
|
203
|
+
*
|
|
204
|
+
* Split on the FIRST separator, because the level leads and is a closed set,
|
|
205
|
+
* while a `provider/id` could conceivably contain one.
|
|
206
|
+
*/
|
|
207
|
+
export declare function parseStepValue(value: string): {
|
|
208
|
+
spec: string;
|
|
209
|
+
level: GroupSetting;
|
|
210
|
+
} | undefined;
|
|
211
|
+
/**
|
|
212
|
+
* One row per step, carrying BOTH dials.
|
|
213
|
+
*
|
|
214
|
+
* They were two parallel blocks of eleven, and the coupling between them was
|
|
215
|
+
* invisible: choosing a model re-clamps that step's thinking level, but the row
|
|
216
|
+
* that moved was eleven rows away from the row you touched. One row shows the
|
|
217
|
+
* pair, and the two-step picker shows the clamp happening.
|
|
218
|
+
*
|
|
219
|
+
* `values` is the LEGAL cross product — every model against only the levels that
|
|
220
|
+
* model declares. Nothing renders it: the picker offers two short lists, and the
|
|
221
|
+
* round-trip property in config-items.test.ts is its only reader. Building it
|
|
222
|
+
* from `offeredLevels` rather than the full ladder is what makes the property
|
|
223
|
+
* true, because a pair the model cannot honour would be clamped by `apply` and
|
|
224
|
+
* would not round-trip.
|
|
225
|
+
*/
|
|
226
|
+
export declare function stepItems(catalog?: ModelCatalog): ConfigItem[];
|
|
227
|
+
/**
|
|
228
|
+
* Write both halves of a step row, atomically.
|
|
229
|
+
*
|
|
230
|
+
* Atomically matters for the round-trip property, which starts from a FRESH
|
|
231
|
+
* config every iteration: a value that wrote only one half would leave the other
|
|
232
|
+
* at its default and render as something else.
|
|
233
|
+
*
|
|
234
|
+
* The level is re-clamped even though the picker only ever offers legal pairs.
|
|
235
|
+
* The picker is not the only door — `values` is built when the panel opens, and
|
|
236
|
+
* a registry that moved underneath it would otherwise let an unhonourable level
|
|
237
|
+
* through.
|
|
238
|
+
*/
|
|
239
|
+
export declare function applyStepValue(cfg: PiTaskConfig, group: ChildGroup, chosen: string, catalog: ModelCatalog): void;
|
|
135
240
|
/**
|
|
136
241
|
* Apply one group row's new value.
|
|
137
242
|
*
|
|
@@ -142,7 +247,7 @@ export declare function reasoningItems(): ConfigItem[];
|
|
|
142
247
|
* it, nudging `research` while in `off` would silently return every other group
|
|
143
248
|
* to whatever the stored table happened to hold.
|
|
144
249
|
*/
|
|
145
|
-
export declare function applyReasoningLevel(cfg: PiTaskConfig, group:
|
|
250
|
+
export declare function applyReasoningLevel(cfg: PiTaskConfig, group: ChildGroup, chosen: string): void;
|
|
146
251
|
/**
|
|
147
252
|
* Tallest body the settings list can render, so {@link BorderedBox} can pad
|
|
148
253
|
* every frame to it and hold the border still. Mirrors SettingsList's own
|
|
@@ -157,17 +262,32 @@ export type PanelItem = {
|
|
|
157
262
|
description: string;
|
|
158
263
|
currentValue: string;
|
|
159
264
|
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
265
|
+
* The values a cycling row steps through. A section header carries none.
|
|
266
|
+
*
|
|
267
|
+
* It is NOT what marks a header any more — {@link isSectionRow} reads the id
|
|
268
|
+
* for that. A model row legitimately has both a `values` list and a
|
|
269
|
+
* `submenu`, so "no values" and "not a row" stopped being the same fact the
|
|
270
|
+
* moment pickers existed.
|
|
163
271
|
*/
|
|
164
272
|
values?: string[];
|
|
273
|
+
/**
|
|
274
|
+
* Enter-time options for a picker row, already closed over the draft config
|
|
275
|
+
* by {@link renderRows}.
|
|
276
|
+
*
|
|
277
|
+
* Deliberately NOT called `submenu`: pi-tui's `SettingItem.submenu` is a
|
|
278
|
+
* COMPONENT FACTORY, and a PanelItem is handed to `SettingsList` directly by
|
|
279
|
+
* tests and by the headless path. Two different things under one name would
|
|
280
|
+
* make PanelItem stop being assignable to SettingItem, for no gain.
|
|
281
|
+
* {@link createSettingsPanel} is where a theme exists, so it is where these
|
|
282
|
+
* options become a component.
|
|
283
|
+
*/
|
|
284
|
+
pickerOptions?: () => PairOptions;
|
|
165
285
|
/**
|
|
166
286
|
* What the headless one-line rendering calls this row, when `label` reads
|
|
167
287
|
* only in the panel. A tree branch means nothing on a line of `|`-joined
|
|
168
|
-
* rows: `├─ files` there names no parent, where `
|
|
169
|
-
* does. Set by the
|
|
170
|
-
*
|
|
288
|
+
* rows: `├─ files` there names no parent, where `step: research:files`
|
|
289
|
+
* does. Set by the step rows; every other row leaves it off and its `label`
|
|
290
|
+
* is used.
|
|
171
291
|
*/
|
|
172
292
|
headlessLabel?: string;
|
|
173
293
|
};
|
|
@@ -181,10 +301,10 @@ export declare function createSettingsPanel(items: PanelItem[], theme: Theme,
|
|
|
181
301
|
* Called with the row's id, its new value, and the LIST ITSELF.
|
|
182
302
|
*
|
|
183
303
|
* The list is handed back because some rows change what OTHER rows display:
|
|
184
|
-
* flipping `
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
304
|
+
* flipping `profile` to off means every `step:` row now runs at off, and a
|
|
305
|
+
* row's `currentValue` is a snapshot taken when the panel was built. Without
|
|
306
|
+
* a way to write the others back, the menu would show `profile off` beside
|
|
307
|
+
* rows still claiming `inherit`.
|
|
188
308
|
*/
|
|
189
309
|
onChange: (id: string, newValue: string, list: SettingsList) => void, onCancel: () => void): BorderedBox;
|
|
190
310
|
/**
|
|
@@ -198,17 +318,17 @@ onChange: (id: string, newValue: string, list: SettingsList) => void, onCancel:
|
|
|
198
318
|
* Fixed rows come before discovered ones within a section, so a freshly
|
|
199
319
|
* installed extension appends rather than reshuffling the menu.
|
|
200
320
|
*/
|
|
201
|
-
export declare function configRows(installed: InstalledExtension[], tools?: readonly GuardableTool[]): ConfigItem[];
|
|
321
|
+
export declare function configRows(installed: InstalledExtension[], tools?: readonly GuardableTool[], catalog?: ModelCatalog): ConfigItem[];
|
|
202
322
|
/** Render `rows` for the current config, grouped under their section headers. */
|
|
203
323
|
export declare function renderRows(cfg: PiTaskConfig, rows: readonly ConfigItem[]): PanelItem[];
|
|
204
324
|
/** The full settings row list for the current config, in menu order. */
|
|
205
|
-
export declare function panelItems(cfg: PiTaskConfig, installed: InstalledExtension[], tools?: readonly GuardableTool[]): PanelItem[];
|
|
325
|
+
export declare function panelItems(cfg: PiTaskConfig, installed: InstalledExtension[], tools?: readonly GuardableTool[], catalog?: ModelCatalog): PanelItem[];
|
|
206
326
|
/**
|
|
207
327
|
* Re-ask every row what it now displays, and write the answers back.
|
|
208
328
|
*
|
|
209
329
|
* A row's `currentValue` in the live list is a snapshot taken when the panel was
|
|
210
330
|
* built, and rows describe each other: cycling `reasoning` to `off` changes what
|
|
211
|
-
* every `
|
|
331
|
+
* every `step:` row runs at, and setting one step row flips the profile, which
|
|
212
332
|
* changes all the others.
|
|
213
333
|
*
|
|
214
334
|
* This runs after ANY change, over EVERY row. Re-reading a `format` costs
|