@mjasnikovs/pi-task 0.38.19 → 0.38.20
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 +1 -0
- package/dist/config/config.d.ts +19 -0
- package/dist/config/config.js +10 -2
- package/dist/config/reasoning-args.d.ts +10 -0
- package/dist/config/reasoning-args.js +23 -0
- package/dist/config/reasoning.d.ts +160 -0
- package/dist/config/reasoning.js +530 -0
- package/dist/config/register.d.ts +72 -2
- package/dist/config/register.js +182 -33
- package/dist/shared/model-endpoint.d.ts +34 -0
- package/dist/shared/model-endpoint.js +36 -0
- package/dist/shared/reasoning-capability.d.ts +86 -0
- package/dist/shared/reasoning-capability.js +82 -0
- package/dist/task/child-runner.d.ts +19 -26
- package/dist/task/child-runner.js +48 -6
- package/dist/task/decompose-fidelity.d.ts +21 -8
- package/dist/task/decompose-fidelity.js +98 -17
- package/dist/task/gate-child.d.ts +10 -0
- package/dist/task/gate-child.js +1 -0
- package/dist/task/gate-deps.js +4 -0
- package/dist/task/implementation-thinking.d.ts +54 -0
- package/dist/task/implementation-thinking.js +33 -0
- package/dist/task/orchestrator.d.ts +7 -0
- package/dist/task/orchestrator.js +42 -14
- package/dist/task/phases.js +47 -24
- package/dist/task/prompts.d.ts +0 -23
- package/dist/task/prompts.js +0 -25
- package/dist/task/reasoning-groups.d.ts +36 -0
- package/dist/task/reasoning-groups.js +36 -0
- package/dist/task/spec-validation.d.ts +28 -0
- package/dist/task/spec-validation.js +44 -0
- package/dist/task/title-label.js +2 -2
- package/dist/workers/docs-core.js +4 -0
- package/dist/workers/fetch-core.js +4 -0
- package/dist/workers/focused-extractor.d.ts +12 -1
- package/dist/workers/focused-extractor.js +6 -2
- package/dist/workers/index.js +2 -0
- package/dist/workers/pi-worker-core.d.ts +22 -0
- package/dist/workers/pi-worker-core.js +24 -6
- package/dist/workers/pi-worker-docs.js +4 -0
- package/dist/workers/pi-worker.js +11 -1
- package/dist/workers/reasoning-warning.d.ts +64 -0
- package/dist/workers/reasoning-warning.js +142 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -214,6 +214,7 @@ Run `/task-config` to toggle pi-task's behavior in an editor dialog. Settings pe
|
|
|
214
214
|
| **command timeout** | 15 min | Wall-clock ceiling on a **single** tool execution. Local models routinely run a command that never returns (a hung build, a dev server, a check with no timeout) and the run wedges until you abort by hand — pi's bash tool has an optional timeout with no default, so this is the missing one. One knob, two surfaces: in the main session the overrun call is cancelled (killing the tool's whole process tree) plus a reminder turn; in the verify/fix gate children the child is killed and re-spawned with a hint, halving the ceiling on repeat hangs. Choices: 5/10/15/30 min or **off** — off unguards both surfaces, gates included. |
|
|
215
215
|
| **stuck reply retry** | 10 min | Inactivity ceiling on the **model stream**. A hung or silently-dropped stream throws nothing at all, so neither the connection-error retry (it needs a reported error) nor the **command timeout** (tool calls only) nor the dead-backend stall guard (a reachable endpoint reads as proof of life) can see it — an mx5 run lost ~2.9h to three of them while the model server stayed healthy. Measured as time since the **last stream event of any kind**, so a slow model emitting one token every 30s is never touched, and it pauses while a tool runs. On expiry the main session aborts the turn (through the same channel the command watchdog uses) and posts a resume reminder; a child is killed and routed into the existing connection-error retry. Choices: 5/10/20/30 min or **off**. Keep it generous on local backends — prompt processing on a large context legitimately emits nothing for minutes. |
|
|
216
216
|
| **yolo mode** | off | **Unattended runs.** Wherever pi-task would stop and ask, it takes the option already marked RECOMMENDED, stamps the artifact `(YOLO)` so an audit can tell a machine decided, and shows no prompt at all — clarify/grill answers, the verify-FAIL picker (auto-**Accept**, recorded as a yolo debt), and the final-gate picker (autofix while the budget lasts, then leave the run FAILED). A question with no recommendation is **skipped**, never invented. For throwaway/test projects nobody is watching; a real run should decide these itself. |
|
|
217
|
+
| **reasoning** | default | How much the helper sessions think before answering. Local models differ sharply here: some break without reasoning, some waste minutes with it, and some cannot do it at all. The seven **think:** rows below set one level per group of steps — research workers, spec phases, /task-auto planning, /task-plan, the checking gates, the small extraction children, and the implementation turn itself. **default** uses the table pi-task has measured, **on** and **off** force one answer everywhere, and **custom** is whatever the think: rows say (changing any of them switches to custom). A step on **inherit** passes no flag at all, so it uses whatever thinking level pi itself is set to — which is what every step did before this setting existed, and is what every cell of the measured table currently holds. The think: rows always show what a step *actually* runs at, not what the stored table says. Three tiers of model exist and pi-task tells them apart: full levels (`reasoning_effort` in the chat template, e.g. Qwen3.8), on/off only (e.g. Qwen3.6, Gemma 4), and none at all. pi silently CLAMPS a level a model does not declare — a level you set can be erased, and an `off` can be clamped back up to `medium` — so a startup warning names the model and the steps it will not honour. It never fires while every step is on inherit. |
|
|
217
218
|
| **debug logs** | events | How much of a run is written to `.pi-tasks/*-debug.log`. **`events`** keeps decisions and guard actions — which phase ran, why a worker was retried, what the git-state guard restored, what a write-capable child changed on disk, why a gate returned FAIL — a few lines per task. **`full`** adds every line the child model emitted and every tool result; that's ~85% of the bytes (a real 247 KB `verify-debug.log` is 1315 lines, 521 of them tool dumps) and is what you want while actively debugging. **`off`** writes nothing. Nothing in pi-task ever reads these files back, so the setting cannot change how a run behaves — only whether you can explain it afterwards, and a log not written can't be recovered later. |
|
|
218
219
|
| **watch: …** | all on | One toggle per tool in the live session, deciding whether **command timeout** applies to it. The list is discovered from `pi.getAllTools()` when the menu opens — built-ins first, then each extension's tools with the owning entry-point path in the description — so nothing is typed by hand and an uninstalled tool just stops being listed. Turn one **off** only for a tool that already owns a longer bounded, cancellable contract of its own (the guard exists because pi's `bash` has an optional timeout with *no* default — that reasoning doesn't transfer to a tool that has one). Two things to know before you do: a genuine hang in an unwatched tool is caught by nothing, since **stuck reply retry** is paused for the whole time any tool runs; and an unwatched tool is still killed as collateral if a *watched* sibling in the same turn overruns, because pi runs sibling tool calls concurrently and the abort ends the whole turn. Stored as exemptions, so the default and every tool pi-task has never seen stay guarded. |
|
|
219
220
|
| **ext: …** | all off | One toggle per installed host `pi` extension, loading it into every child session by explicit path. Children otherwise run with extensions off, so a provider registered by an extension (e.g. `pi-lmstudio`) doesn't exist in them and they can't resolve the default model. Children also inherit the extension's tools and hooks, so only enable ones you trust. The list is strictly additive (discovery stays off), and an entry whose file is gone is skipped at spawn time, never fatal. |
|
package/dist/config/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type SearchProvider } from '../workers/search-types.js';
|
|
2
|
+
import { type GroupSetting, type ReasoningGroup, type ReasoningMode } from './reasoning.js';
|
|
2
3
|
export interface PiTaskConfig {
|
|
3
4
|
remote: boolean;
|
|
4
5
|
autoCommit: boolean;
|
|
@@ -134,6 +135,24 @@ export interface PiTaskConfig {
|
|
|
134
135
|
* cannot be recovered after the fact.
|
|
135
136
|
*/
|
|
136
137
|
debugLogs: DebugLogLevel;
|
|
138
|
+
/**
|
|
139
|
+
* Which reasoning profile is in force. See config/reasoning.ts for the four
|
|
140
|
+
* modes and the group vocabulary.
|
|
141
|
+
*
|
|
142
|
+
* DEFAULT `default`, whose table ships all-`inherit` — so installing this
|
|
143
|
+
* version changes no child's argv until the user opts in.
|
|
144
|
+
*/
|
|
145
|
+
reasoningMode: ReasoningMode;
|
|
146
|
+
/**
|
|
147
|
+
* The per-group thinking levels, consulted ONLY when
|
|
148
|
+
* `reasoningMode === 'custom'`.
|
|
149
|
+
*
|
|
150
|
+
* Kept populated in every mode so switching to `custom` and back does not
|
|
151
|
+
* lose the user's table — the same reason `commandTimeoutExemptTools`
|
|
152
|
+
* survives the watchdog being turned off. Its sanitizer always returns a
|
|
153
|
+
* complete record, so no consumer needs a per-key fallback.
|
|
154
|
+
*/
|
|
155
|
+
reasoningLevels: Record<ReasoningGroup, GroupSetting>;
|
|
137
156
|
}
|
|
138
157
|
/** How verbose the `.pi-tasks/*-debug.log` trail is. See {@link PiTaskConfig.debugLogs}. */
|
|
139
158
|
export type DebugLogLevel = 'off' | 'events' | 'full';
|
package/dist/config/config.js
CHANGED
|
@@ -3,6 +3,7 @@ import * as fsp from 'node:fs/promises';
|
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import * as os from 'node:os';
|
|
5
5
|
import { isSearchProvider } from '../workers/search-types.js';
|
|
6
|
+
import { DEFAULT_REASONING_TABLE, sanitizeReasoningLevels, sanitizeReasoningMode } from './reasoning.js';
|
|
6
7
|
import { DEFAULT_STREAM_INACTIVITY_MS } from '../shared/stream-watchdog.js';
|
|
7
8
|
/**
|
|
8
9
|
* The debug-log choices offered by /task-config, in cycle order (quietest →
|
|
@@ -104,7 +105,12 @@ export const DEFAULT_CONFIG = {
|
|
|
104
105
|
yoloMode: false,
|
|
105
106
|
// EVENTS: the model chatter is 85% of the bytes and nobody reads it; the
|
|
106
107
|
// guard/verdict markers are the 15% that explains a failed run.
|
|
107
|
-
debugLogs: DEFAULT_DEBUG_LOGS
|
|
108
|
+
debugLogs: DEFAULT_DEBUG_LOGS,
|
|
109
|
+
// DEFAULT: the measured per-group table, which currently holds `inherit` in
|
|
110
|
+
// every cell. Every child's argv is byte-identical to the version before
|
|
111
|
+
// reasoning profiles existed until a cell is filled in by an A/B.
|
|
112
|
+
reasoningMode: 'default',
|
|
113
|
+
reasoningLevels: { ...DEFAULT_REASONING_TABLE }
|
|
108
114
|
};
|
|
109
115
|
/**
|
|
110
116
|
* A hand-edited config can hold anything; keep only string entries so a stray
|
|
@@ -155,7 +161,9 @@ export const CONFIG_LOADERS = {
|
|
|
155
161
|
requestTimeoutMs: sanitizeRequestTimeoutMs,
|
|
156
162
|
commandTimeoutExemptTools: sanitizeCommandTimeoutExemptTools,
|
|
157
163
|
streamInactivityMs: sanitizeStreamInactivityMs,
|
|
158
|
-
debugLogs: sanitizeDebugLogs
|
|
164
|
+
debugLogs: sanitizeDebugLogs,
|
|
165
|
+
reasoningMode: sanitizeReasoningMode,
|
|
166
|
+
reasoningLevels: sanitizeReasoningLevels
|
|
159
167
|
};
|
|
160
168
|
/**
|
|
161
169
|
* Turn parsed config JSON into a `PiTaskConfig`. Pure — this is the seam the load
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ReasoningGroup } from './reasoning.js';
|
|
2
|
+
/**
|
|
3
|
+
* The `['--thinking', level]` fragment for a group, or `[]` when the group is
|
|
4
|
+
* `inherit` and the child should keep falling back to settings.json.
|
|
5
|
+
*
|
|
6
|
+
* This is the ONLY function the argv builders call. They never read config
|
|
7
|
+
* themselves — an argv builder that resolves its own policy is one that cannot
|
|
8
|
+
* be told to do something else, which is how childBaseArgs became universal.
|
|
9
|
+
*/
|
|
10
|
+
export declare function groupThinkingArgs(group: ReasoningGroup): string[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live-config bridge for reasoning profiles: group in, argv fragment out.
|
|
3
|
+
*
|
|
4
|
+
* Separate from reasoning.ts because that module must stay import-free — see its
|
|
5
|
+
* header. This file is the one hop that reads `getConfig()`, so it imports both
|
|
6
|
+
* and neither imports it back: a tree, not a cycle.
|
|
7
|
+
*
|
|
8
|
+
* Read PER CALL, never cached at module scope, so a /task-config change lands on
|
|
9
|
+
* the next child without a restart — the same contract childBaseArgs states.
|
|
10
|
+
*/
|
|
11
|
+
import { getConfig } from './config.js';
|
|
12
|
+
import { resolveReasoning, thinkingArgs } from './reasoning.js';
|
|
13
|
+
/**
|
|
14
|
+
* The `['--thinking', level]` fragment for a group, or `[]` when the group is
|
|
15
|
+
* `inherit` and the child should keep falling back to settings.json.
|
|
16
|
+
*
|
|
17
|
+
* This is the ONLY function the argv builders call. They never read config
|
|
18
|
+
* themselves — an argv builder that resolves its own policy is one that cannot
|
|
19
|
+
* be told to do something else, which is how childBaseArgs became universal.
|
|
20
|
+
*/
|
|
21
|
+
export function groupThinkingArgs(group) {
|
|
22
|
+
return thinkingArgs(resolveReasoning(group, getConfig()));
|
|
23
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reasoning profiles — which thinking level each group of model children runs at.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS
|
|
5
|
+
* ---------------
|
|
6
|
+
* Every pi-task child inherits `defaultThinkingLevel` from the host's
|
|
7
|
+
* `~/.pi/agent/settings.json`, because `CHILD_BASE_ARGS`
|
|
8
|
+
* (shared/child-process.ts) passes no `--thinking`. That is one level for ~33
|
|
9
|
+
* children whose jobs are nothing alike: a planner that must reason to produce a
|
|
10
|
+
* plan at all, and a label-compressor that emits four words.
|
|
11
|
+
*
|
|
12
|
+
* The control that WAS here — appending Qwen3's `/no_think` soft switch to eight
|
|
13
|
+
* prompts — is measured inert. Captured live against Qwen3.8-27B with server
|
|
14
|
+
* thinking on and `/no_think` still in the prompt: median 17k-char trace anyway,
|
|
15
|
+
* n=25. A harness cannot disable thinking by prompt text; the chat-template
|
|
16
|
+
* kwarg beats it. `--thinking` sets that kwarg, so it is the lever that works.
|
|
17
|
+
*
|
|
18
|
+
* PURE MODULE — no imports with runtime side effects, so `config.ts` can import
|
|
19
|
+
* the table and the sanitizers during its own module evaluation. `getConfig()`
|
|
20
|
+
* lives one hop away in `reasoning-args.ts` for exactly this reason: importing
|
|
21
|
+
* it here would make config.ts ⇄ reasoning.ts a real cycle, and whichever module
|
|
22
|
+
* a caller reached first would decide whether `DEFAULT_REASONING_TABLE` was
|
|
23
|
+
* initialised before `DEFAULT_CONFIG` read it.
|
|
24
|
+
*/
|
|
25
|
+
import type { PiTaskConfig } from './config.js';
|
|
26
|
+
/**
|
|
27
|
+
* The child roles that share one reasoning setting.
|
|
28
|
+
*
|
|
29
|
+
* Grouped by JOB, not by spawn mechanism — two children that both go through
|
|
30
|
+
* `runWorker` (a research worker and a verify gate) want different amounts of
|
|
31
|
+
* thinking, while two that reach the model by different code paths (`refine` via
|
|
32
|
+
* runPhaseChild, `compress-label` via the same) want the same.
|
|
33
|
+
*
|
|
34
|
+
* - `research` the four research workers, plus the ad-hoc `pi-worker` tool
|
|
35
|
+
* - `phase` refine, verify-tooling, grill, compose, critique, compress-label
|
|
36
|
+
* - `planning` /task-auto's clarify / decompose / extract children
|
|
37
|
+
* - `plan` /task-plan's question and answer children
|
|
38
|
+
* - `gate` enforce, verify, lint-fix, final-fix, recommend
|
|
39
|
+
* - `extraction` the --no-tools focused docs/fetch extractors
|
|
40
|
+
* - `implementation` the host-session turn that writes the code (not a child)
|
|
41
|
+
*/
|
|
42
|
+
export type ReasoningGroup = 'research' | 'phase' | 'planning' | 'plan' | 'gate' | 'extraction' | 'implementation';
|
|
43
|
+
export declare const REASONING_GROUPS: readonly ReasoningGroup[];
|
|
44
|
+
/**
|
|
45
|
+
* The four profiles offered by /task-config.
|
|
46
|
+
* - `default` the measured per-group table below
|
|
47
|
+
* - `on` one level everywhere ({@link REASONING_ON_LEVEL})
|
|
48
|
+
* - `off` no thinking anywhere
|
|
49
|
+
* - `custom` the user's own per-group table
|
|
50
|
+
*/
|
|
51
|
+
export type ReasoningMode = 'default' | 'on' | 'off' | 'custom';
|
|
52
|
+
export declare const REASONING_MODES: readonly ReasoningMode[];
|
|
53
|
+
/**
|
|
54
|
+
* What one group is set to.
|
|
55
|
+
*
|
|
56
|
+
* `inherit` is NOT a pi thinking level — it means EMIT NO FLAG, so the child
|
|
57
|
+
* falls back to `settings.json` exactly as it does today. It is what lets this
|
|
58
|
+
* whole feature ship as a zero-behaviour-change commit: with every cell at
|
|
59
|
+
* `inherit`, every child's argv is byte-identical to the version before it.
|
|
60
|
+
*/
|
|
61
|
+
export type GroupSetting = 'inherit' | 'off' | 'minimal' | 'low' | 'medium' | 'high';
|
|
62
|
+
/**
|
|
63
|
+
* The settings offered in /task-config: `inherit` plus pi's OWN cycle
|
|
64
|
+
* (`THINKING_LEVELS` in pi-coding-agent's agent-session).
|
|
65
|
+
*
|
|
66
|
+
* `xhigh` and `max` are DELIBERATELY ABSENT. pi treats an absent
|
|
67
|
+
* `thinkingLevelMap` entry as "supported" for the standard levels but requires a
|
|
68
|
+
* declared entry for the extended two (pi-ai `getSupportedThinkingLevels`), so a
|
|
69
|
+
* model with no map would receive the raw string — and Qwen3.8's chat template
|
|
70
|
+
* answers an unknown effort with HTTP 500, not a clamp. Offering a level that pi's
|
|
71
|
+
* own UI does not is how you ship a `--thinking` that hard-fails on some models.
|
|
72
|
+
* This machine already reaches xhigh through `"high": "xhigh"` in its map.
|
|
73
|
+
*/
|
|
74
|
+
export declare const REASONING_SETTINGS: readonly GroupSetting[];
|
|
75
|
+
/**
|
|
76
|
+
* The level mode `on` uses, and the treatment arm of the A/B that fills in
|
|
77
|
+
* {@link DEFAULT_REASONING_TABLE}. ONE constant so the shipped config and the
|
|
78
|
+
* measurement behind it can never drift apart.
|
|
79
|
+
*/
|
|
80
|
+
export declare const REASONING_ON_LEVEL: GroupSetting;
|
|
81
|
+
/**
|
|
82
|
+
* The per-group table used by mode `default`.
|
|
83
|
+
*
|
|
84
|
+
* A cell is `inherit` until it has been MEASURED, and then it names a level.
|
|
85
|
+
* Every non-`inherit` cell here must be a live A/B result
|
|
86
|
+
* (scripts/live-reasoning-group-ab.ts, n>=20 per arm, arms `off` vs
|
|
87
|
+
* {@link REASONING_ON_LEVEL}) carrying its date, model, counts and RUNG in the
|
|
88
|
+
* comment beside it. A cell filled in from intuition is WORSE than `inherit`:
|
|
89
|
+
* `inherit` is honest about knowing nothing, while a wrong cell is a
|
|
90
|
+
* measurement nobody took, wearing the authority of a default.
|
|
91
|
+
*
|
|
92
|
+
* THE RUNG IS PART OF THE RESULT, so read it before trusting a cell. The
|
|
93
|
+
* harness returns a two-way verdict — `off` or {@link REASONING_ON_LEVEL},
|
|
94
|
+
* never a tie — down a three-rung ladder: rung 1 a significant quality
|
|
95
|
+
* difference, rung 2 quality level and a significant speed difference, rung 3
|
|
96
|
+
* nothing separated the arms and the cheaper level carries it by a stated
|
|
97
|
+
* prior. A rung-3 cell is a DECISION, not a finding: it says "no reason found
|
|
98
|
+
* to pay for thinking", not "thinking was shown not to help". At n=20/arm the
|
|
99
|
+
* run is only powered for large effects, so rung 3 is the common outcome and
|
|
100
|
+
* an absent effect and an undetected one look identical from here.
|
|
101
|
+
*
|
|
102
|
+
* NOTHING IS ALREADY ON THE RECORD, and the belief that something was is worth
|
|
103
|
+
* writing down. This docstring used to say magicknumbers.md had measured the
|
|
104
|
+
* decompose child "with one knob, `enable_thinking` — off answered 1/10, on
|
|
105
|
+
* answered 8/8", and treated that as the split the A/B had to reproduce.
|
|
106
|
+
*
|
|
107
|
+
* VERIFIED 2026-08-27: the string "8/8" does not appear in magicknumbers.md, and
|
|
108
|
+
* never has (`git log -S`; the phrase was introduced by THIS file's own commit,
|
|
109
|
+
* `0b91f71`). What that page records is
|
|
110
|
+
*
|
|
111
|
+
* "Measured, captured decompose request, REASONING OFF, n=10 per cell:
|
|
112
|
+
* 1/10 → 7/10 (stall detector) → 8/9 (all three)."
|
|
113
|
+
*
|
|
114
|
+
* — a ladder over THREE GUARDS at CONSTANT reasoning off, from `fea7bbb`. Both
|
|
115
|
+
* endpoints are the same arm. `enable_thinking` is not its knob and never was,
|
|
116
|
+
* and the "8/8" is a misread of the ladder's last cell, `8/9`.
|
|
117
|
+
*
|
|
118
|
+
* So no reasoning effect on `planning` had ever been measured, and the 10/10 vs
|
|
119
|
+
* 10/10 read on the current tree was not a contradiction of a prior result — it
|
|
120
|
+
* was the only reading there had ever been. The controls that page DOES record
|
|
121
|
+
* (Qwen3.6-27B 10/10, Gemma4-12B 10/10) are likewise reasoning off, so they say
|
|
122
|
+
* nothing about a cell flipping by model either.
|
|
123
|
+
*
|
|
124
|
+
* The `planning` cell below is the FIRST measured reading of that knob, taken
|
|
125
|
+
* 2026-08-27 on a citation-fidelity axis built for it. It is also the first cell
|
|
126
|
+
* that is not `off`.
|
|
127
|
+
*/
|
|
128
|
+
export declare const DEFAULT_REASONING_TABLE: Readonly<Record<ReasoningGroup, GroupSetting>>;
|
|
129
|
+
/**
|
|
130
|
+
* A hand-edited or stale mode must not reach {@link resolveReasoning}'s switch as
|
|
131
|
+
* an unknown string — the `default:` arm would silently absorb it and the user
|
|
132
|
+
* would see "custom" in the file and the default table in behaviour.
|
|
133
|
+
*/
|
|
134
|
+
export declare function sanitizeReasoningMode(value: unknown): ReasoningMode;
|
|
135
|
+
/**
|
|
136
|
+
* Always returns a COMPLETE record, never a partial one.
|
|
137
|
+
*
|
|
138
|
+
* A hand-edited file missing a group, or one carrying a group from a future
|
|
139
|
+
* version, must not reach `resolveReasoning` as a hole: `levels[group]` would be
|
|
140
|
+
* `undefined`, and every call site would need its own fallback. Filling the gaps
|
|
141
|
+
* here means the type is true at the only place that constructs the value.
|
|
142
|
+
*/
|
|
143
|
+
export declare function sanitizeReasoningLevels(value: unknown): Record<ReasoningGroup, GroupSetting>;
|
|
144
|
+
/**
|
|
145
|
+
* What one group is actually set to, given a config. The ONLY place the four
|
|
146
|
+
* modes are interpreted.
|
|
147
|
+
*
|
|
148
|
+
* `cfg` is required rather than defaulted to `getConfig()` so this module stays
|
|
149
|
+
* import-free (see the header). Callers that want the live config use
|
|
150
|
+
* `groupThinkingArgs` from reasoning-args.ts.
|
|
151
|
+
*/
|
|
152
|
+
export declare function resolveReasoning(group: ReasoningGroup, cfg: PiTaskConfig): GroupSetting;
|
|
153
|
+
/**
|
|
154
|
+
* The argv fragment for a setting. `inherit` is the empty fragment — no flag at
|
|
155
|
+
* all — which is what makes an all-`inherit` config byte-identical to the
|
|
156
|
+
* version before this feature existed.
|
|
157
|
+
*/
|
|
158
|
+
export declare function thinkingArgs(setting: GroupSetting): string[];
|
|
159
|
+
/** One honest sentence per group, for the /task-config rows. */
|
|
160
|
+
export declare const REASONING_GROUP_HELP: Readonly<Record<ReasoningGroup, string>>;
|