@openlines/opl-pi-sht 0.1.14 → 0.1.16
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 +28 -8
- package/configs/opl-simplebench.json.sample +13 -2
- package/extensions/opl-footer/README.md +3 -3
- package/extensions/opl-footer/index.ts +7 -20
- package/extensions/opl-footer/segments/session-stats.ts +8 -15
- package/extensions/opl-footer/types.ts +4 -5
- package/extensions/opl-simplebench/README.md +36 -1
- package/extensions/opl-simplebench/index.ts +63 -3
- package/extensions/opl-simplebench/types.ts +1 -1
- package/extensions/opl-simplebench/util/config.ts +9 -0
- package/package.json +1 -1
- package/configs/opl-footer.json +0 -48
- package/configs/opl-input.json +0 -22
- package/configs/opl-modes.json +0 -291
- package/configs/opl-simplebench.json +0 -8
- package/configs/opl-todo.json +0 -12
- package/configs/opl-webaccess.json +0 -31
package/README.md
CHANGED
|
@@ -8,21 +8,41 @@ A portable collection of various Pi coding agent extensions. Repository director
|
|
|
8
8
|
|
|
9
9
|
### Pi package
|
|
10
10
|
|
|
11
|
-
Install a versioned GitHub
|
|
11
|
+
Install a versioned release from npm or GitHub. Both ship identical content; pick one source per machine, because Pi treats the npm and Git entries as separate packages and installing both loads every extension twice.
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
pi install
|
|
14
|
+
pi install npm:@openlines/opl-pi-sht@0.1.15
|
|
15
|
+
pi install git:github.com/linellazatin/opl-pi-sht@v0.1.15
|
|
15
16
|
```
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
> Omitting the version on the npm source tracks the latest published release; Git refs stay pinned, so move them with `pi install ...@v<new>`.
|
|
19
|
+
|
|
20
|
+
Pi installs the package under `~/.pi/agent/npm/node_modules/@openlines/opl-pi-sht` (npm) or `~/.pi/agent/git/github.com/linellazatin/opl-pi-sht` (Git) and runs root `npm install`, so `opl-webaccess` and `opl-browser` runtime dependencies are available. Pi packages do not install optional extension config files; copy only the configs you need from that checkout's `configs/` to `~/.pi/agent/configs/`.
|
|
18
21
|
|
|
19
22
|
`opl-browser` also needs Chromium once after package installation:
|
|
20
23
|
|
|
21
24
|
```bash
|
|
22
|
-
cd ~/.pi/agent/
|
|
25
|
+
cd ~/.pi/agent/npm/node_modules/@openlines/opl-pi-sht # or the git checkout path
|
|
23
26
|
npx playwright install chromium
|
|
24
27
|
```
|
|
25
28
|
|
|
29
|
+
#### Selecting extensions
|
|
30
|
+
|
|
31
|
+
`pi install` has no per-extension flag like `./install.sh --only`. After installing the package, narrow it in `~/.pi/agent/settings.json` using the object form (filters are globs relative to the package root and layer on top of the package manifest):
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"packages": [
|
|
36
|
+
{
|
|
37
|
+
"source": "npm:@openlines/opl-pi-sht@0.1.15",
|
|
38
|
+
"extensions": ["extensions/opl-init/index.ts", "extensions/opl-todo/index.ts"]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`pi config` provides the same control interactively: toggle individual extensions from an installed package without editing globs.
|
|
45
|
+
|
|
26
46
|
### Checkout installer
|
|
27
47
|
|
|
28
48
|
```bash
|
|
@@ -152,7 +172,7 @@ The fixed cost of a full install is small and paid once per session, then cached
|
|
|
152
172
|
|
|
153
173
|
## Configuration
|
|
154
174
|
|
|
155
|
-
Copy applicable files from [`configs/`](configs/) to `~/.pi/agent/configs/`. For a Pi
|
|
175
|
+
Copy applicable files from [`configs/`](configs/) to `~/.pi/agent/configs/`. For a Pi package installation, the source directory is `~/.pi/agent/npm/node_modules/@openlines/opl-pi-sht/configs/` (npm) or `~/.pi/agent/git/github.com/linellazatin/opl-pi-sht/configs/` (Git):
|
|
156
176
|
|
|
157
177
|
- `opl-footer.json`, `opl-input.json`, `opl-modes.json`, `opl-todo.json`, `opl-webaccess.json`
|
|
158
178
|
- `opl-browser` has optional configuration (`opl-browser.json`); all fields default, so it works without any config file.
|
|
@@ -167,7 +187,7 @@ See each extension README for commands, behavior, configuration fields, runtime
|
|
|
167
187
|
|
|
168
188
|
## Runtime requirements
|
|
169
189
|
|
|
170
|
-
All extensions use Pi's normal extension discovery. Pi installs `opl-webaccess` extraction dependencies and Playwright automatically when installed as
|
|
190
|
+
All extensions use Pi's normal extension discovery. Pi installs `opl-webaccess` extraction dependencies and Playwright automatically when installed as an npm or Git package. For the checkout installer, install nested runtime dependencies before using those extensions:
|
|
171
191
|
|
|
172
192
|
```bash
|
|
173
193
|
cd extensions/opl-webaccess
|
|
@@ -178,9 +198,9 @@ npm install
|
|
|
178
198
|
npx playwright install chromium
|
|
179
199
|
```
|
|
180
200
|
|
|
181
|
-
A Pi Git
|
|
201
|
+
A Pi package (npm or Git) still needs the one-time `npx playwright install chromium` command shown above.
|
|
182
202
|
|
|
183
|
-
`opl-simplebench` writes a full JSON benchmark artifact in Pi's current working directory by default. `--test-all` additionally writes `research.md` and `page.html` beside `result.json` in a result bundle. Copy `configs/opl-simplebench.json.sample` to `~/.pi/agent/configs/opl-simplebench.json` to configure DDGS/SearXNG research
|
|
203
|
+
`opl-simplebench` writes a full JSON benchmark artifact in Pi's current working directory by default. `--test-all` additionally writes `research.md` and `page.html` beside `result.json` in a result bundle. `/simplebench --sequence` runs a templated multi-run protocol (for example a model warm-up curve) defined in the `runSequence` block, with per-iteration tags, optional llama-server/llamagputop metrics, and a configurable pause between iterations. Copy `configs/opl-simplebench.json.sample` to `~/.pi/agent/configs/opl-simplebench.json` to configure DDGS/SearXNG research, optional llama-server/llamagputop metadata endpoints, and the run sequence. Use `/simplebench --no-artifact` or `simplebench({ no_artifact: true })` when responses must not be written to disk. Provider credentials remain outside tracked configuration; configure them through Pi provider settings, environment variables, or Pi authentication.
|
|
184
204
|
|
|
185
205
|
## Tests
|
|
186
206
|
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_comment": "Copy to ~/.pi/agent/configs/opl-simplebench.json. Endpoints are optional and only used by their corresponding Simplebench flags.",
|
|
2
|
+
"_comment": "Copy to ~/.pi/agent/configs/opl-simplebench.json. Endpoints are optional and only used by their corresponding Simplebench flags. runSequence powers /simplebench --sequence: each entry is a flag string; llamaMetrics appends --llama-server --llamagputop to every entry; pauseMs sleeps between iterations.",
|
|
3
3
|
"researchSearchProvider": "ddgs",
|
|
4
4
|
"researchSearchUrl": "http://127.0.0.1:8000",
|
|
5
5
|
"researchMaxResults": 5,
|
|
6
6
|
"llamaServerUrl": "http://127.0.0.1:8080/v1",
|
|
7
|
-
"llamagputopUrl": "http://127.0.0.1:4321/stats"
|
|
7
|
+
"llamagputopUrl": "http://127.0.0.1:4321/stats",
|
|
8
|
+
"runSequence": {
|
|
9
|
+
"enabled": false,
|
|
10
|
+
"llamaMetrics": true,
|
|
11
|
+
"pauseMs": 5000,
|
|
12
|
+
"sequence": [
|
|
13
|
+
"--coding-lite --tag=coldest",
|
|
14
|
+
"--3ptest --tag=colder",
|
|
15
|
+
"--coding-lite --tag=semiwarm",
|
|
16
|
+
"--test-all --research-live --tag=warm"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
8
19
|
}
|
|
@@ -19,7 +19,7 @@ Row 1 right: <context bar> <pct%> / <max tokens>
|
|
|
19
19
|
Row 2 left: Thinking: <LEVEL> | <active mode>
|
|
20
20
|
Row 2 right: T: <total> (<cached> cached) ↑ <in> ↓ <out> | $<cost>
|
|
21
21
|
|
|
22
|
-
Row 3 left: <
|
|
22
|
+
Row 3 left: <prompts> prompts · <api calls> api calls · <tool calls> tool calls
|
|
23
23
|
Row 3 right: LLM <time> (<last-turn TAT>) · Tool <time> | TTFT <time> · <tokens>/s | Cache <percent>%
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -31,7 +31,7 @@ The third row is populated after the first completed turn. Its session and perfo
|
|
|
31
31
|
- **Context bar**: configurable gradient bar with percentage and context-window size
|
|
32
32
|
- **Git integration**: branch plus staged, unstaged, and untracked counts, with invalidation after relevant file and Git commands
|
|
33
33
|
- **Token and cost tracking**: total, cache, input/output, and accumulated cost segments
|
|
34
|
-
- **Session statistics**:
|
|
34
|
+
- **Session statistics**: prompt, API-call, and model tool-call counts
|
|
35
35
|
- **Performance statistics**: cumulative LLM/tool duration, most recent user-prompt-to-completion turnaround time, average time to first token, output rate, and cache-hit percentage
|
|
36
36
|
- **Thinking and mode indicators**: thinking-level colors plus caveman, plan, chat, or unified mode segments when available
|
|
37
37
|
- **Nerd Font support**: automatic detection with plain-icon fallbacks
|
|
@@ -152,7 +152,7 @@ The `git` segment shows:
|
|
|
152
152
|
|
|
153
153
|
## Session and Performance Statistics
|
|
154
154
|
|
|
155
|
-
The `session_stats` segment shows
|
|
155
|
+
The `session_stats` segment shows prompt, API-call, and model tool-call counts for the current branch, reconstructed from session history so they survive quit/resume. `prompts` counts user messages and `api calls` counts completed assistant responses, so one prompt typically drives many API calls (each tool round trip is one call); `tool calls` counts the tool-call blocks the model emitted.
|
|
156
156
|
|
|
157
157
|
The `perf_stats` segment shows cumulative session LLM and tool time, average time to first token, output tokens/sec, and cache-hit percentage. The `LLM` figure is followed by the most recent user-prompt-to-completion turnaround time in parentheses, e.g. `LLM 18m 22s (2m 13s)`. This turnaround reflects only fully-settled turns (the `agent_settled` signal, after any retries or compaction), so it stays blank until the first turn completes. All `perf_stats` timing values are ephemeral — they reset each session and are not reconstructed from branch history.
|
|
158
158
|
|
|
@@ -103,11 +103,7 @@ export default function footer(pi: ExtensionAPI) {
|
|
|
103
103
|
let cachedUsageStats: UsageStats | null = null;
|
|
104
104
|
let tuiRef: TUI | null = null;
|
|
105
105
|
|
|
106
|
-
// Session stats accumulators
|
|
107
|
-
let turns = 0;
|
|
108
|
-
let steps = 0;
|
|
109
|
-
let modelRequests = 0;
|
|
110
|
-
let modelToolCalls = 0;
|
|
106
|
+
// Session stats accumulators (timing only; counts are reconstructed from the branch)
|
|
111
107
|
let llmMs = 0;
|
|
112
108
|
let toolMs = 0;
|
|
113
109
|
let ttftSamples: number[] = [];
|
|
@@ -124,10 +120,6 @@ export default function footer(pi: ExtensionAPI) {
|
|
|
124
120
|
currentCtx = ctx;
|
|
125
121
|
lastBranchLength = 0;
|
|
126
122
|
cachedUsageStats = null;
|
|
127
|
-
turns = 0;
|
|
128
|
-
steps = 0;
|
|
129
|
-
modelRequests = 0;
|
|
130
|
-
modelToolCalls = 0;
|
|
131
123
|
llmMs = 0;
|
|
132
124
|
toolMs = 0;
|
|
133
125
|
ttftSamples = [];
|
|
@@ -165,13 +157,11 @@ export default function footer(pi: ExtensionAPI) {
|
|
|
165
157
|
});
|
|
166
158
|
|
|
167
159
|
pi.on("turn_end", async (_event: unknown, _ctx: ExtensionContext) => {
|
|
168
|
-
turns++;
|
|
169
160
|
const elapsed = Date.now() - turnStartMs;
|
|
170
161
|
llmMs += Math.max(0, elapsed - toolMsThisTurn);
|
|
171
162
|
});
|
|
172
163
|
|
|
173
164
|
pi.on("tool_execution_start", async (event: { toolCallId: string }, _ctx: ExtensionContext) => {
|
|
174
|
-
steps++;
|
|
175
165
|
toolStartTimes.set(event.toolCallId, Date.now());
|
|
176
166
|
});
|
|
177
167
|
|
|
@@ -278,18 +268,15 @@ export default function footer(pi: ExtensionAPI) {
|
|
|
278
268
|
// This allows litellm proxy to correctly separate local vs cloud models
|
|
279
269
|
const isLocalModel = ctx.model?.id?.startsWith?.("local.") ?? false;
|
|
280
270
|
|
|
281
|
-
// Reconstruct
|
|
271
|
+
// Reconstruct prompt/API-call/tool-call counts from the branch so they survive quit/resume.
|
|
282
272
|
// Timing stats (llmMs, toolMs, ttftSamples) are ephemeral — not stored in messages.
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
(e) => e.type === "message" && (e as AssistantMessageEvent).message?.role === "toolResult",
|
|
273
|
+
const branchPrompts = branch.filter(
|
|
274
|
+
(e) => e.type === "message" && (e as AssistantMessageEvent).message?.role === "user",
|
|
286
275
|
).length;
|
|
287
|
-
|
|
288
|
-
// Count model requests (each assistant message = 1 request)
|
|
289
|
-
const branchModelRequests = completedMessages.length;
|
|
276
|
+
const branchApiCalls = completedMessages.length;
|
|
290
277
|
|
|
291
278
|
// Count tool calls from assistant message content
|
|
292
|
-
const
|
|
279
|
+
const branchToolCalls = completedMessages.reduce((sum, msg) => {
|
|
293
280
|
const content = (msg as any).content || [];
|
|
294
281
|
return sum + content.filter((block: any) => block?.type === "toolCall").length;
|
|
295
282
|
}, 0);
|
|
@@ -310,7 +297,7 @@ export default function footer(pi: ExtensionAPI) {
|
|
|
310
297
|
theme,
|
|
311
298
|
colors,
|
|
312
299
|
icons: getIcons(effectiveConfig.icons),
|
|
313
|
-
sessionStats: {
|
|
300
|
+
sessionStats: { prompts: branchPrompts, apiCalls: branchApiCalls, toolCalls: branchToolCalls, llmMs, toolMs, ttftSamples, lastTurnaroundMs },
|
|
314
301
|
};
|
|
315
302
|
}
|
|
316
303
|
|
|
@@ -19,22 +19,15 @@ export function formatMs(ms: number): string {
|
|
|
19
19
|
export const sessionStatsSegment = {
|
|
20
20
|
id: "session_stats" as const,
|
|
21
21
|
render(ctx: SegmentContext): RenderedSegment {
|
|
22
|
-
const {
|
|
23
|
-
if (
|
|
22
|
+
const { prompts, apiCalls, toolCalls } = ctx.sessionStats;
|
|
23
|
+
if (prompts === 0) return { content: "", visible: false };
|
|
24
24
|
|
|
25
|
-
const parts
|
|
26
|
-
val(ctx, `${
|
|
27
|
-
val(ctx, `${
|
|
25
|
+
const parts = [
|
|
26
|
+
val(ctx, `${prompts}`) + dim(ctx, " prompts"),
|
|
27
|
+
val(ctx, `${apiCalls}`) + dim(ctx, " api calls"),
|
|
28
|
+
val(ctx, `${toolCalls}`) + dim(ctx, " tool calls"),
|
|
28
29
|
];
|
|
29
30
|
|
|
30
|
-
// Add model stats if available
|
|
31
|
-
if (modelRequests > 0) {
|
|
32
|
-
parts.push(val(ctx, `${modelRequests}`) + dim(ctx, " mreq"));
|
|
33
|
-
}
|
|
34
|
-
if (modelToolCalls > 0) {
|
|
35
|
-
parts.push(val(ctx, `${modelToolCalls}`) + dim(ctx, " mtool"));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
31
|
return { content: parts.join(dim(ctx, " · ")), visible: true };
|
|
39
32
|
},
|
|
40
33
|
};
|
|
@@ -42,8 +35,8 @@ export const sessionStatsSegment = {
|
|
|
42
35
|
export const perfStatsSegment = {
|
|
43
36
|
id: "perf_stats" as const,
|
|
44
37
|
render(ctx: SegmentContext): RenderedSegment {
|
|
45
|
-
const {
|
|
46
|
-
if (
|
|
38
|
+
const { prompts, llmMs, toolMs, ttftSamples, lastTurnaroundMs } = ctx.sessionStats;
|
|
39
|
+
if (prompts === 0) return { content: "", visible: false };
|
|
47
40
|
|
|
48
41
|
const { input, output, cacheRead } = ctx.usageStats;
|
|
49
42
|
|
|
@@ -97,12 +97,11 @@ export interface UsageStats {
|
|
|
97
97
|
cost: number;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
// Session performance stats accumulated via events
|
|
100
|
+
// Session performance stats accumulated via events; counts reconstructed from the branch
|
|
101
101
|
export interface SessionStats {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
modelToolCalls: number;
|
|
102
|
+
prompts: number;
|
|
103
|
+
apiCalls: number;
|
|
104
|
+
toolCalls: number;
|
|
106
105
|
llmMs: number;
|
|
107
106
|
toolMs: number;
|
|
108
107
|
ttftSamples: number[];
|
|
@@ -8,12 +8,14 @@ Auditable Pi model benchmark for closed-answer contracts, JSON instruction follo
|
|
|
8
8
|
/simplebench
|
|
9
9
|
/simplebench <model>
|
|
10
10
|
/simplebench <model> [--no-artifact] [--thinking-max]
|
|
11
|
+
/simplebench <model> --3ptest
|
|
11
12
|
/simplebench <model> --coding-lite
|
|
12
13
|
/simplebench <model> --test-all
|
|
13
14
|
/simplebench <model> --research-live
|
|
14
15
|
/simplebench <model> --llama-server
|
|
15
16
|
/simplebench <model> --llamagputop
|
|
16
17
|
/simplebench <model> --tag=<word>
|
|
18
|
+
/simplebench <model> --sequence
|
|
17
19
|
/simplebench --all [--no-artifact]
|
|
18
20
|
/simplebench --all --test-all
|
|
19
21
|
/simplebench --help
|
|
@@ -39,6 +41,8 @@ simplebench({ model: "global.openai.gpt-5.6-terra", test_all: true })
|
|
|
39
41
|
- Twenty fixed closed-answer contracts, one strict JSON instruction test, and one chained tool-call test.
|
|
40
42
|
- Six opt-in execution-backed coding tasks in disposable directories (`--coding-lite`).
|
|
41
43
|
- `--test-all` runs baseline, coding-lite, and deterministic grounded research; `--research-live` adds the configured live research-artifact integration smoke test. `--all` still selects every Ollama model.
|
|
44
|
+
- `--3ptest` is the explicit form of the default baseline suite (reasoning, instruction following, tool calls). It changes nothing about the run; artifacts already name the baseline suite `3ptest`.
|
|
45
|
+
- `--sequence` runs the templated multi-iteration benchmark stored in `opl-simplebench.json` (`runSequence`): sequential iterations, per-entry flags and `--tag`, optional `llamaMetrics` and `pauseMs` cooldown. See "Run a templated sequence" below.
|
|
42
46
|
- `--llama-server` (`llama_server: true`) captures configured direct llama-server `/props` and `/metrics` without changing inference routing, so it works with a LiteLLM proxy.
|
|
43
47
|
- `--llamagputop` (`llamagputop: true`) captures configured llama.cpp `/stats` metadata independently of the inference provider; its served model ID is authoritative.
|
|
44
48
|
- `--tag=<word>` (`tag: "<word>"`) labels a run: stored as `benchmark.tag` and prefixed onto the artifact file or bundle name, for example `simplebench-coldrun-coding-lite-<model>-...`. The tag must be a single word (letters, digits, dot, dash, underscore).
|
|
@@ -80,6 +84,37 @@ Use this in sensitive environments. The terminal summary still reports category
|
|
|
80
84
|
|
|
81
85
|
`--all` is intentionally limited to Ollama discovery. It writes one artifact per model unless `--no-artifact` is set.
|
|
82
86
|
|
|
87
|
+
### Run a templated sequence
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
/simplebench --sequence
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Repeating a warm-up protocol (first-run-after-boot coding check, then baseline, then the full suite) means re-typing the same flags every session. `--sequence` reads the `runSequence` block from `~/.pi/agent/configs/opl-simplebench.json` and runs each entry as its own iteration against the current model (or the model passed with `--sequence`):
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"runSequence": {
|
|
98
|
+
"enabled": true,
|
|
99
|
+
"llamaMetrics": true,
|
|
100
|
+
"pauseMs": 5000,
|
|
101
|
+
"sequence": [
|
|
102
|
+
"--coding-lite --tag=coldest",
|
|
103
|
+
"--3ptest --tag=colder",
|
|
104
|
+
"--coding-lite --tag=semiwarm",
|
|
105
|
+
"--test-all --research-live --tag=warm"
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- `enabled` gates the flag: `/simplebench --sequence` errors when it is missing or `false`. A bare `/simplebench` is unaffected.
|
|
112
|
+
- Each `sequence` entry is the same flag string you would type after `/simplebench`, including its own `--tag`.
|
|
113
|
+
- `llamaMetrics: true` appends `--llama-server --llamagputop` to every entry, so local server stats are captured per iteration without repeating the flags.
|
|
114
|
+
- `pauseMs` sleeps between iterations (never after the last one), including after a failed iteration, so thermal/KV-cache cooldown stays consistent across the warm-up curve.
|
|
115
|
+
- Iterations run sequentially and each writes its normal artifact/bundle; a failed iteration is reported and the sequence continues. A final summary line counts completed iterations.
|
|
116
|
+
- Entries containing `--all` or `--sequence` are rejected before anything runs, as are invalid configurations (empty sequence, negative `pauseMs`) and invalid per-entry tags. The outer `--tag` is ignored; each entry carries its own.
|
|
117
|
+
|
|
83
118
|
### Grounded research in `--test-all`
|
|
84
119
|
|
|
85
120
|
`--test-all` runs a deterministic agent workflow after coding-lite. `web_search` returns three benchmark-local source cards. The model must write every required finding as a Markdown bullet with its inline source ID (`[S1]`, `[S2]`) and list each cited source under `## Sources` as a Markdown link, for example `- [S1](https://research.fixture/S1)`. The verifier checks each exact claim-to-source relationship, source-list URL, tool trace, and the responsive minimalist `page.html` contract. It invokes no LLM judge, external search service, embedding model, or entailment model.
|
|
@@ -94,7 +129,7 @@ When coding-lite is enabled, each coding task is recorded as a `kind: "coding"`
|
|
|
94
129
|
|
|
95
130
|
### Configured metadata (`--llama-server`, `--llamagputop`)
|
|
96
131
|
|
|
97
|
-
Copy `configs/opl-simplebench.json.sample` to `~/.pi/agent/configs/opl-simplebench.json`. It uses camelCase fields: `llamaServerUrl`, `llamagputopUrl`, `researchSearchProvider`, `researchSearchUrl`, and `
|
|
132
|
+
Copy `configs/opl-simplebench.json.sample` to `~/.pi/agent/configs/opl-simplebench.json`. It uses camelCase fields: `llamaServerUrl`, `llamagputopUrl`, `researchSearchProvider`, `researchSearchUrl`, `researchMaxResults`, and `runSequence` (see "Run a templated sequence"). `--llama-server` captures `GET /props` and `/metrics` from configured `llamaServerUrl`; inference remains on the configured provider route, including LiteLLM. `--llamagputop` captures configured `llamagputopUrl` stats.
|
|
98
133
|
|
|
99
134
|
`serverStats` is omitted entirely for runs without the flag. Its shape:
|
|
100
135
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExtensionAPI, AgentToolResult } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { debugLog } from "./util/debug";
|
|
3
3
|
import { detectProvider } from "./util/providers";
|
|
4
|
-
import { TOOL_SUPPORT_CACHE_PATH } from "./util/config";
|
|
4
|
+
import { readTestConfig, TOOL_SUPPORT_CACHE_PATH, type ModelTestUserConfig } from "./util/config";
|
|
5
5
|
import type { SimplebenchOptions } from "./types";
|
|
6
6
|
import { createBenchmark } from "./benchmark";
|
|
7
7
|
|
|
@@ -13,7 +13,25 @@ export function parseCommandArgs(args: string): SimplebenchOptions {
|
|
|
13
13
|
tag = tagToken.slice("--tag=".length);
|
|
14
14
|
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(tag)) throw new Error(`--tag must be a single word (letters, digits, dot, dash, underscore): got "${tag}"`);
|
|
15
15
|
}
|
|
16
|
-
return { model: tokens.find(token => !token.startsWith("--")), allModels: tokens.includes("--all"), writeArtifact: !tokens.includes("--no-artifact"), thinkingMax: tokens.includes("--thinking-max"), codingLite: tokens.includes("--coding-lite"), testAll: tokens.includes("--test-all"), researchLive: tokens.includes("--research-live"), llamaServer: tokens.includes("--llama-server"), llamagputop: tokens.includes("--llamagputop"), ...(tag ? { tag } : {}) };
|
|
16
|
+
return { model: tokens.find(token => !token.startsWith("--")), allModels: tokens.includes("--all"), writeArtifact: !tokens.includes("--no-artifact"), thinkingMax: tokens.includes("--thinking-max"), codingLite: tokens.includes("--coding-lite"), testAll: tokens.includes("--test-all"), researchLive: tokens.includes("--research-live"), llamaServer: tokens.includes("--llama-server"), llamagputop: tokens.includes("--llamagputop"), ...(tag ? { tag } : {}), ...(tokens.includes("--3ptest") ? { threePTest: true } : {}), ...(tokens.includes("--sequence") ? { sequence: true } : {}) };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ResolvedRunSequence { runs: Array<{ entry: string; options: SimplebenchOptions }>; pauseMs: number }
|
|
20
|
+
|
|
21
|
+
/** Expand the configured runSequence into per-iteration benchmark options. Throws on disabled/invalid configuration. */
|
|
22
|
+
export function resolveRunSequence(userConfig: ModelTestUserConfig): ResolvedRunSequence {
|
|
23
|
+
const rs = userConfig.runSequence;
|
|
24
|
+
if (!rs?.enabled) throw new Error("runSequence is not enabled in opl-simplebench.json");
|
|
25
|
+
if (!Array.isArray(rs.sequence) || rs.sequence.length === 0) throw new Error("runSequence.sequence must be a non-empty array of flag strings");
|
|
26
|
+
const pauseMs = rs.pauseMs ?? 0;
|
|
27
|
+
if (typeof pauseMs !== "number" || !Number.isFinite(pauseMs) || pauseMs < 0) throw new Error(`runSequence.pauseMs must be a non-negative number: got ${JSON.stringify(rs.pauseMs)}`);
|
|
28
|
+
const runs = rs.sequence.map((entry: string) => {
|
|
29
|
+
const tokens = String(entry).trim().split(/\s+/);
|
|
30
|
+
if (tokens.includes("--all")) throw new Error(`runSequence entry cannot contain --all: "${entry}"`);
|
|
31
|
+
if (tokens.includes("--sequence")) throw new Error(`runSequence entry cannot contain --sequence: "${entry}"`);
|
|
32
|
+
return { entry: String(entry), options: parseCommandArgs(`${entry}${rs.llamaMetrics ? " --llama-server --llamagputop" : ""}`) };
|
|
33
|
+
});
|
|
34
|
+
return { runs, pauseMs };
|
|
17
35
|
}
|
|
18
36
|
|
|
19
37
|
export default function (pi: ExtensionAPI) {
|
|
@@ -22,7 +40,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
22
40
|
|
|
23
41
|
pi.registerCommand("simplebench", {
|
|
24
42
|
description: "Benchmark a model with auditable closed-answer, instruction, and tool-use tests.",
|
|
25
|
-
detailedHelp: "\n\n🔍 Simplebench Extension\n\nThis extension tests AI models across multiple dimensions:\n• Closed-answer contract: 20 deterministic final-line answers (logic, math, spatial, commonsense)\n• Tool Usage: Ability to use available tools effectively\n• Instruction Following: How well the model follows complex JSON instructions\n• Coding Lite: Six isolated, execution-backed coding tasks\n\n📋 Usage Examples:\n /simplebench # Test current model\n /simplebench <model> # Test a specific model\n /simplebench --all # Test all Ollama models\n /simplebench <model> --coding-lite # Run only coding tasks\n /simplebench <model> --test-all # Run baseline, coding, and grounded research\n /simplebench <model> --research-live # Add live search integration smoke test\n /simplebench --all --test-all # Run complete suite for every Ollama model\n /simplebench <model> --thinking-max # Request max reasoning\n /simplebench <model> --llama-server # Capture configured /props and /metrics\n /simplebench <model> --llamagputop # Capture configured llama.cpp stats\n /simplebench <model> --tag=coldrun # Label the run: benchmark.tag plus artifact filename prefix\n /simplebench --help # Show this help\n /simplebench --clear-cache # Clear tool support cache\n\nCoding tasks run in disposable directories and never access the user repository.\n",
|
|
43
|
+
detailedHelp: "\n\n🔍 Simplebench Extension\n\nThis extension tests AI models across multiple dimensions:\n• Closed-answer contract: 20 deterministic final-line answers (logic, math, spatial, commonsense)\n• Tool Usage: Ability to use available tools effectively\n• Instruction Following: How well the model follows complex JSON instructions\n• Coding Lite: Six isolated, execution-backed coding tasks\n\n📋 Usage Examples:\n /simplebench # Test current model\n /simplebench <model> # Test a specific model\n /simplebench --all # Test all Ollama models\n /simplebench <model> --3ptest # Run the default 3ptest baseline explicitly\n /simplebench <model> --coding-lite # Run only coding tasks\n /simplebench <model> --test-all # Run baseline, coding, and grounded research\n /simplebench <model> --research-live # Add live search integration smoke test\n /simplebench --all --test-all # Run complete suite for every Ollama model\n /simplebench <model> --sequence # Run the configured runSequence template\n /simplebench <model> --thinking-max # Request max reasoning\n /simplebench <model> --llama-server # Capture configured /props and /metrics\n /simplebench <model> --llamagputop # Capture configured llama.cpp stats\n /simplebench <model> --tag=coldrun # Label the run: benchmark.tag plus artifact filename prefix\n /simplebench --help # Show this help\n /simplebench --clear-cache # Clear tool support cache\n\nCoding tasks run in disposable directories and never access the user repository.\n",
|
|
26
44
|
getArgumentCompletions: async (prefix) => {
|
|
27
45
|
try {
|
|
28
46
|
const models = await getOllamaModels();
|
|
@@ -54,6 +72,8 @@ pi.registerCommand("simplebench", {
|
|
|
54
72
|
" /simplebench [model] --test-all - Run baseline, coding, and deterministic grounded research\n" +
|
|
55
73
|
" /simplebench [model] --research-live - Add live-search integration smoke test\n" +
|
|
56
74
|
" /simplebench [model] --tag=<word> - Label the run (single word; added to benchmark.tag and the artifact name)\n" +
|
|
75
|
+
" /simplebench [model] --3ptest - Run the default baseline suite explicitly\n" +
|
|
76
|
+
" /simplebench [model] --sequence - Run the templated multi-iteration sequence from opl-simplebench.json (runSequence; per-entry --tag, llamaMetrics and pauseMs supported; the outer --tag is ignored)\n" +
|
|
57
77
|
" /simplebench --all --test-all - Run complete suite for all Ollama models\n" +
|
|
58
78
|
" /simplebench --clear-cache - Clear tool support cache\n",
|
|
59
79
|
"info"
|
|
@@ -76,6 +96,46 @@ pi.registerCommand("simplebench", {
|
|
|
76
96
|
return;
|
|
77
97
|
}
|
|
78
98
|
|
|
99
|
+
if (parsedArgs.sequence) {
|
|
100
|
+
let resolved: ResolvedRunSequence;
|
|
101
|
+
try {
|
|
102
|
+
resolved = resolveRunSequence(readTestConfig());
|
|
103
|
+
} catch (e: any) {
|
|
104
|
+
ctx.ui.notify(e?.message || String(e), "error");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const sequenceModel = parsedArgs.model || ctx.model?.id;
|
|
108
|
+
if (!sequenceModel) {
|
|
109
|
+
ctx.ui.notify("No model specified and no model currently selected", "error");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
ctx.ui.notify(`Running ${resolved.runs.length}-iteration sequence (${resolved.runs.map(r => r.entry).join(" | ")})...`, "info");
|
|
113
|
+
let completed = 0;
|
|
114
|
+
for (let i = 0; i < resolved.runs.length; i++) {
|
|
115
|
+
if (i > 0 && resolved.pauseMs > 0) {
|
|
116
|
+
ctx.ui.notify(`Cooling down ${resolved.pauseMs / 1000}s before iteration ${i + 1}/${resolved.runs.length}...`, "info");
|
|
117
|
+
await new Promise(resolve => setTimeout(resolve, resolved.pauseMs));
|
|
118
|
+
}
|
|
119
|
+
const { entry, options } = resolved.runs[i];
|
|
120
|
+
const model = options.model || sequenceModel;
|
|
121
|
+
ctx.ui.notify(`Iteration ${i + 1}/${resolved.runs.length} (${entry}) on ${model}...`, "info");
|
|
122
|
+
try {
|
|
123
|
+
const report = await testModel(model, ctx, { ...options, model });
|
|
124
|
+
completed += 1;
|
|
125
|
+
pi.sendMessage({
|
|
126
|
+
customType: "simplebench-report",
|
|
127
|
+
content: report,
|
|
128
|
+
display: { type: "content", content: report },
|
|
129
|
+
details: { model, timestamp: new Date().toISOString() },
|
|
130
|
+
});
|
|
131
|
+
} catch (e: any) {
|
|
132
|
+
ctx.ui.notify(`Iteration ${i + 1} (${entry}) failed: ${e.message}`, "error");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
ctx.ui.notify(`Sequence done: ${completed}/${resolved.runs.length} iterations completed`, "info");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
79
139
|
if (parsedArgs.allModels) {
|
|
80
140
|
const providerInfo = detectProvider(ctx);
|
|
81
141
|
if (providerInfo.kind !== "ollama") {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ServerStats } from "./llama-server";
|
|
2
2
|
|
|
3
|
-
export interface SimplebenchOptions { model?: string; allModels: boolean; writeArtifact: boolean; thinkingMax?: boolean; codingLite?: boolean; testAll?: boolean; researchLive?: boolean; llamaServer?: boolean; llamagputop?: boolean; tag?: string; }
|
|
3
|
+
export interface SimplebenchOptions { model?: string; allModels: boolean; writeArtifact: boolean; thinkingMax?: boolean; codingLite?: boolean; testAll?: boolean; researchLive?: boolean; llamaServer?: boolean; llamagputop?: boolean; tag?: string; threePTest?: boolean; sequence?: boolean; }
|
|
4
4
|
export interface RequestMetrics { requestCount: number; retryCount: number; wallTimeMs: number; timeToAnswerMs: number; timeToFirstTokenMs: number | null; startedAt: string | null; finishedAt: string | null; inputTokens: number | null; outputTokens: number | null; totalTokens: number | null; outputTokensPerSecond: number | null; toolCalls: Array<{ name: string; arguments?: unknown }>; }
|
|
5
5
|
export interface TestRecord { id: string; kind: "reasoning" | "instructions" | "tools" | "coding" | "research-grounded" | "research-live"; category?: string; prompt: string; response: string | null; expectedAnswer?: string | string[]; extractedAnswer?: string; score: string; passed: boolean; error: string | null; metrics: RequestMetrics; coding?: { publicPassed: boolean; hiddenPassed: boolean; verifiedAfterEdit: boolean; unrelatedFiles: string[]; toolCalls: number; turns: number; efficiency?: "STRONG" | "MODERATE" | "WEAK" | "FAIL"; }; research?: { toolCalls: string[]; files: string[]; }; }
|
|
6
6
|
export interface RunArtifact { schemaVersion: 1; benchmark: { name: "opl-simplebench"; suite?: "baseline" | "coding-lite" | "test-all"; tag?: string; model: string; provider: string; providerKind: string; thinking: { requested: "default" | "max"; effective: "provider-default" | "openai-reasoning-effort" | "pi-bedrock-reasoning"; level: "max" | null; modelMetadataSource: "active-context" | "scoped-model" | null; }; startedAt: string; finishedAt: string; wallTimeMs: number; artifactEnabled: boolean; }; tests: TestRecord[]; summary: Record<string, unknown> & { serverStats?: ServerStats }; }
|
|
@@ -79,6 +79,15 @@ export interface ModelTestUserConfig {
|
|
|
79
79
|
researchMaxResults?: number;
|
|
80
80
|
llamaServerUrl?: string;
|
|
81
81
|
llamagputopUrl?: string;
|
|
82
|
+
runSequence?: RunSequenceConfig;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Templated multi-run benchmark sequence used by `/simplebench --sequence`. */
|
|
86
|
+
export interface RunSequenceConfig {
|
|
87
|
+
enabled?: boolean;
|
|
88
|
+
llamaMetrics?: boolean;
|
|
89
|
+
pauseMs?: number;
|
|
90
|
+
sequence?: string[];
|
|
82
91
|
}
|
|
83
92
|
|
|
84
93
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openlines/opl-pi-sht",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "Pi coding-agent extension kit: token-efficient context, safe modes, fingerprinted /init, model benchmarking, web access, and browser automation.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
package/configs/opl-footer.json
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_comment": " \ue22c Available segment IDs: pi, model, path, git, thinking, caveman, plan_mode, chat_mode, mode_switcher, separator, token_in, token_out, token_total, cache_read, cache_write, cost, context_pct, context_total, session_stats, perf_stats, text:<literal>",
|
|
3
|
-
"row1LeftSegments": ["pi", "separator", "model", "separator", "path", "git"],
|
|
4
|
-
"row1RightSegments": ["context_pct"],
|
|
5
|
-
"row2LeftSegments": [
|
|
6
|
-
"thinking",
|
|
7
|
-
"separator",
|
|
8
|
-
"mode_switcher"
|
|
9
|
-
],
|
|
10
|
-
"row2RightSegments": ["token_total", "separator", "cost"],
|
|
11
|
-
"row3LeftSegments": ["session_stats"],
|
|
12
|
-
"row3RightSegments": ["perf_stats"],
|
|
13
|
-
"icons": {
|
|
14
|
-
"pi": "\udb80\udfff",
|
|
15
|
-
"folder": "\uf115",
|
|
16
|
-
"branch": "\uf126",
|
|
17
|
-
"git": "\uf1d3",
|
|
18
|
-
"separator": "|"
|
|
19
|
-
},
|
|
20
|
-
"colors": {
|
|
21
|
-
"model": "#c07898",
|
|
22
|
-
"thinkingHigh": "#afb9fe",
|
|
23
|
-
"thinkingXhigh": "#9575cd",
|
|
24
|
-
"thinkingMax": "#ce93d8",
|
|
25
|
-
"separator": "#87827a"
|
|
26
|
-
},
|
|
27
|
-
"segmentOptions": {
|
|
28
|
-
"path": {
|
|
29
|
-
"mode": "full"
|
|
30
|
-
},
|
|
31
|
-
"git": {
|
|
32
|
-
"showBranch": true,
|
|
33
|
-
"showStaged": true,
|
|
34
|
-
"showUnstaged": true,
|
|
35
|
-
"showUntracked": true
|
|
36
|
-
},
|
|
37
|
-
"contextBar": {
|
|
38
|
-
"barWidth": 18,
|
|
39
|
-
"filledChar": "▋",
|
|
40
|
-
"unfilledChar": "▋",
|
|
41
|
-
"unfilledColor": "#4e4c49",
|
|
42
|
-
"gradientStart": "#f29373",
|
|
43
|
-
"gradientMid": "#d67858",
|
|
44
|
-
"gradientEnd": "#ae4f2f",
|
|
45
|
-
"gradientMidPoint": 0.55
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
package/configs/opl-input.json
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"boxedView": false,
|
|
3
|
-
"companion": {
|
|
4
|
-
"enabled": true,
|
|
5
|
-
"color": "accent",
|
|
6
|
-
"type": "dog",
|
|
7
|
-
"types": [
|
|
8
|
-
{
|
|
9
|
-
"typeName": "cat",
|
|
10
|
-
"top": " /\\,/\\ "
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"typeName": "dog",
|
|
14
|
-
"top": " /),(\\ "
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"typeName": "bunny",
|
|
18
|
-
"top": " (\\,/) "
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
}
|
package/configs/opl-modes.json
DELETED
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_comment": "Every field below is optional; values shown are the extension's built-in defaults for reference.",
|
|
3
|
-
"ui": {
|
|
4
|
-
"hideNotify": false,
|
|
5
|
-
"hideWidget": true
|
|
6
|
-
},
|
|
7
|
-
"shortcuts": {
|
|
8
|
-
"_comment": "Shortcut that cycles through all enabled, visible modes in registry order. Default: ctrl+alt+m.",
|
|
9
|
-
"cycleMode": "shift+tab"
|
|
10
|
-
},
|
|
11
|
-
"cleanup": {
|
|
12
|
-
"_comment": "Set to true to delete the plan file automatically after plan_complete is called.",
|
|
13
|
-
"cleanupOnComplete": false
|
|
14
|
-
},
|
|
15
|
-
"defaultNotifyTemplate": "✓ {Name} mode ON",
|
|
16
|
-
"_comment_defaultNotifyTemplate": "Default notify text for any custom mode that doesn't set its own labels.notify. {Name} is replaced with the mode name, capitalized.",
|
|
17
|
-
"_comment_lazyTools": "Tool names withheld from the active set at rest and enabled on demand via the load_tools tool. Only affects modes that would otherwise include them (off/execute and custom modes that list them). Core built-ins, plan_complete, and load_tools are protected and ignored. Omit or leave empty to keep all tools always active.",
|
|
18
|
-
"lazyTools": [
|
|
19
|
-
"subagent",
|
|
20
|
-
"subagent_wait",
|
|
21
|
-
"subagent_supervisor",
|
|
22
|
-
"browser",
|
|
23
|
-
"simplebench"
|
|
24
|
-
],
|
|
25
|
-
"bashPatterns": {
|
|
26
|
-
"_comment_safe": "Replace-only: providing safePatterns replaces ALL defaults for both built-in chat/plan modes (shared base). Omit to keep built-in safe patterns. Shown here with the built-in list.",
|
|
27
|
-
"_comment_destructive": "Replace-only: providing destructivePatterns replaces ALL defaults for both built-in chat/plan modes (shared base). Omit to keep built-in destructive patterns. Shown here with the built-in list.",
|
|
28
|
-
"safePatterns": [
|
|
29
|
-
"^\\s*cat\\b",
|
|
30
|
-
"^\\s*head\\b",
|
|
31
|
-
"^\\s*tail\\b",
|
|
32
|
-
"^\\s*less\\b",
|
|
33
|
-
"^\\s*more\\b",
|
|
34
|
-
"^\\s*grep\\b",
|
|
35
|
-
"^\\s*find\\b",
|
|
36
|
-
"^\\s*ls\\b",
|
|
37
|
-
"^\\s*pwd\\b",
|
|
38
|
-
"^\\s*cd\\b",
|
|
39
|
-
"^\\s*echo\\b",
|
|
40
|
-
"^\\s*printf\\b",
|
|
41
|
-
"^\\s*wc\\b",
|
|
42
|
-
"^\\s*sort\\b",
|
|
43
|
-
"^\\s*diff\\b",
|
|
44
|
-
"^\\s*file\\b",
|
|
45
|
-
"^\\s*stat\\b",
|
|
46
|
-
"^\\s*du\\b",
|
|
47
|
-
"^\\s*df\\b",
|
|
48
|
-
"^\\s*tree\\b",
|
|
49
|
-
"^\\s*which\\b",
|
|
50
|
-
"^\\s*whereis\\b",
|
|
51
|
-
"^\\s*type\\b",
|
|
52
|
-
"^\\s*env\\b",
|
|
53
|
-
"^\\s*printenv\\b",
|
|
54
|
-
"^\\s*uname\\b",
|
|
55
|
-
"^\\s*whoami\\b",
|
|
56
|
-
"^\\s*date\\b",
|
|
57
|
-
"^\\s*uptime\\b",
|
|
58
|
-
"^\\s*ps\\b",
|
|
59
|
-
"^\\s*free\\b",
|
|
60
|
-
"^\\s*rg\\b",
|
|
61
|
-
"^\\s*fd\\b",
|
|
62
|
-
"^\\s*bat\\b",
|
|
63
|
-
"^\\s*jq\\b",
|
|
64
|
-
"^\\s*git\\s+(status|log|diff|show|branch|remote)",
|
|
65
|
-
"^\\s*node\\s+--version",
|
|
66
|
-
"^\\s*python\\s+--version",
|
|
67
|
-
"^\\s*(npx\\s+)?tsc\\b.*--noEmit",
|
|
68
|
-
"^\\s*npm\\s+(list|ls|view|info|outdated|audit)",
|
|
69
|
-
"^\\s*yarn\\s+(list|info|why|audit)"
|
|
70
|
-
],
|
|
71
|
-
"destructivePatterns": [
|
|
72
|
-
"\\brm\\b",
|
|
73
|
-
"\\brmdir\\b",
|
|
74
|
-
"\\bmv\\b",
|
|
75
|
-
"\\bcp\\b",
|
|
76
|
-
"\\bmkdir\\b",
|
|
77
|
-
"\\btouch\\b",
|
|
78
|
-
"\\bchmod\\b",
|
|
79
|
-
"\\bchown\\b",
|
|
80
|
-
"\\btee\\b",
|
|
81
|
-
"\\bdd\\b",
|
|
82
|
-
"\\bshred\\b",
|
|
83
|
-
"(^|[^<])>(?!>|&)",
|
|
84
|
-
">>",
|
|
85
|
-
"\\bnpm\\s+(install|uninstall|update|ci)",
|
|
86
|
-
"\\byarn\\s+(add|remove|install)",
|
|
87
|
-
"\\bpip\\s+(install|uninstall)",
|
|
88
|
-
"\\bgit\\s+(add|commit|push|merge|rebase|reset|checkout|branch\\s+-)",
|
|
89
|
-
"\\bsudo\\b",
|
|
90
|
-
"\\bsu\\b",
|
|
91
|
-
"\\bkill\\b",
|
|
92
|
-
"\\bpkill\\b",
|
|
93
|
-
"\\b(sh|bash|zsh)\\b",
|
|
94
|
-
"\\b(vim?|nano|emacs|code|subl)\\b"
|
|
95
|
-
]
|
|
96
|
-
},
|
|
97
|
-
"_comment_tools": "Set modes.chat.tools or modes.plan.tools to replace their default tools. The legacy top-level chatAllowedTools and planAllowedTools keys remain supported but are deprecated.",
|
|
98
|
-
"_comment_widgetColor": "available colors - accent, border, borderAccent, borderMuted, success, error, warning, muted, dim, text, thinkingText, searchMatchText, userMessageText, customMessageText, customMessageLabel, toolTitle, toolOutput, mdHeading, mdLink, mdLinkUrl, mdCode, mdCodeBlock, mdCodeBlockBorder, mdQuote, mdQuoteBorder, mdHr, mdListBullet, toolDiffAdded, toolDiffRemoved, toolDiffContext, syntaxComment, syntaxKeyword, syntaxFunction, syntaxVariable, syntaxString, syntaxNumber, syntaxType, syntaxOperator, syntaxPunctuation, thinkingOff, thinkingMinimal, thinkingLow, thinkingMedium, thinkingHigh, thinkingXhigh, thinkingMax, bashMode",
|
|
99
|
-
"_comment_appearance": "Every mode owns appearance here. prefix/prefixColor/borderColor style opl-input; modeColor styles opl-footer's Mode value. All color values accept Pi theme tokens or #RRGGBB.",
|
|
100
|
-
"modes": {
|
|
101
|
-
"off": {
|
|
102
|
-
"_comment": "Built-in mode — no restrictions, normal agent behavior.",
|
|
103
|
-
"prompt": "",
|
|
104
|
-
"model": {
|
|
105
|
-
"provider": "litellm-proxy",
|
|
106
|
-
"id": "gpt-5.6-terra"
|
|
107
|
-
},
|
|
108
|
-
"allowPlanComplete": false,
|
|
109
|
-
"visible": true,
|
|
110
|
-
"enabled": true,
|
|
111
|
-
"labels": {
|
|
112
|
-
"notify": "✓ Mode OFF",
|
|
113
|
-
"notifyType": "info",
|
|
114
|
-
"widget": "✓ Normal mode",
|
|
115
|
-
"widgetColor": "dim"
|
|
116
|
-
},
|
|
117
|
-
"appearance": {
|
|
118
|
-
"prefix": "❯",
|
|
119
|
-
"prefixColor": "accent",
|
|
120
|
-
"borderColor": "border",
|
|
121
|
-
"modeColor": "dim"
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
"chat": {
|
|
125
|
-
"_comment": "Built-in mode — read-only conversational.",
|
|
126
|
-
"prompt": "**SUPERSEDES ALL OTHER BEHAVIOR INSTRUCTIONS.** This overrides any role or style directives (e.g. caveman, roleplay, tone modifiers). The constraints below take absolute priority.\n\nYou are in CHAT MODE. You have read-only access — you may read files, search code, run safe inspection commands, and search the web to answer, discuss, and explore. Converse naturally — answer questions, explain, brainstorm, look things up.\n\nYou MUST NOT attempt to edit, create, delete, or modify any files, or run any command that changes state. If the user asks for a change, explain what you would do but do not attempt it — they can exit chat mode first.\n\nThere is no plan format and no plan_complete tool. Just respond helpfully within read-only constraints.",
|
|
127
|
-
"model": {
|
|
128
|
-
"provider": "amazon-bedrock",
|
|
129
|
-
"id": "moonshotai.kimi-k2.5"
|
|
130
|
-
},
|
|
131
|
-
"tools": [
|
|
132
|
-
"read",
|
|
133
|
-
"bash",
|
|
134
|
-
"grep",
|
|
135
|
-
"find",
|
|
136
|
-
"ls",
|
|
137
|
-
"web_search",
|
|
138
|
-
"fetch_content",
|
|
139
|
-
"get_search_content",
|
|
140
|
-
"artifact",
|
|
141
|
-
"questionnaire"
|
|
142
|
-
],
|
|
143
|
-
"allowPlanComplete": false,
|
|
144
|
-
"visible": true,
|
|
145
|
-
"enabled": true,
|
|
146
|
-
"labels": {
|
|
147
|
-
"notify": "✓ Chat mode ON",
|
|
148
|
-
"notifyType": "info",
|
|
149
|
-
"widget": "✓ Chat mode",
|
|
150
|
-
"widgetColor": "accent"
|
|
151
|
-
},
|
|
152
|
-
"appearance": {
|
|
153
|
-
"prefix": "",
|
|
154
|
-
"prefixColor": "#157cd6",
|
|
155
|
-
"borderColor": "#157cd6",
|
|
156
|
-
"modeColor": "#157cd6"
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
"plan": {
|
|
160
|
-
"_comment": "Built-in mode — read-only explore-and-plan.",
|
|
161
|
-
"prompt": "**SUPERSEDES ALL OTHER BEHAVIOR INSTRUCTIONS.** This overrides any role or style directives (e.g. caveman, roleplay, tone modifiers). The constraints below take absolute priority.\n\nYou are in PLAN MODE. You have read-only access — you may explore and analyze, but you MUST NOT make any changes.\n\nYour task: produce an action plan.\n\nYou MUST begin the plan with exactly this heading on its own line:\n\n# Plan:\n1. [Step title — short verb-object phrase]\n [2-4 sentences of context: which file(s), where, what to change, and why.]\n2. [Step title]\n [Context...]\n...\n\nEach step MUST be self-contained — write it as if the executor has no memory of this conversation. Include enough context that it can be carried out with only the plan file and the codebase. Assume the executor will read the relevant files fresh — do not rely on findings you discovered during planning.\n\nGood: \"Add auth middleware to routes/index.ts\n Apply it as `app.use(authMiddleware)` before the route definitions (~line 45). Currently routes/index.ts has no middleware.\"\n\nBad: \"Add it to the file we looked at\"\n\nBad (over-prescribed): \"Insert `const authMiddleware = require('./middleware/auth');` at line 3, then add `app.use(authMiddleware);` at line 46\"\n\nSpecify what to do and where — not the exact implementation. The executor reads the relevant files and decides how.\n\nAfter listing all steps, stop and wait for the user to choose:\n- \"Execute plan\" — switches to execute mode where you carry out each step\n- \"Refine\" — revise the plan based on feedback\n- Continue exploring if you need more information before planning\n\nDo NOT attempt to make any file changes, run destructive commands, or modify anything.",
|
|
162
|
-
"model": {
|
|
163
|
-
"provider": "amazon-bedrock",
|
|
164
|
-
"id": "global.anthropic.claude-sonnet-5"
|
|
165
|
-
},
|
|
166
|
-
"tools": [
|
|
167
|
-
"read",
|
|
168
|
-
"bash",
|
|
169
|
-
"grep",
|
|
170
|
-
"find",
|
|
171
|
-
"ls",
|
|
172
|
-
"web_search",
|
|
173
|
-
"fetch_content",
|
|
174
|
-
"get_search_content",
|
|
175
|
-
"artifact",
|
|
176
|
-
"questionnaire"
|
|
177
|
-
],
|
|
178
|
-
"allowPlanComplete": false,
|
|
179
|
-
"visible": true,
|
|
180
|
-
"enabled": true,
|
|
181
|
-
"labels": {
|
|
182
|
-
"notify": "✓ Plan mode ON",
|
|
183
|
-
"notifyType": "info",
|
|
184
|
-
"notifyWithTitle": "✓ Active plan: {title}",
|
|
185
|
-
"notifyLoaded": "✓ Active plan: {title}",
|
|
186
|
-
"widget": "✓ Plan mode active",
|
|
187
|
-
"widgetWithTitle": "✓ Active plan: {title}",
|
|
188
|
-
"widgetColor": "accent"
|
|
189
|
-
},
|
|
190
|
-
"appearance": {
|
|
191
|
-
"prefix": "⏸",
|
|
192
|
-
"prefixColor": "#52d90f",
|
|
193
|
-
"borderColor": "#52d90f",
|
|
194
|
-
"modeColor": "#52d90f"
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
|
-
"execute": {
|
|
198
|
-
"_comment": "Built-in mode — entered only via an 'execute:<plan-file>' picker item, never a bare menu choice (visible: false). prompt: leave empty to use the built-in template that injects the active plan file content; set a custom string with a {plan} placeholder to override.",
|
|
199
|
-
"prompt": "",
|
|
200
|
-
"model": {
|
|
201
|
-
"provider": "amazon-bedrock",
|
|
202
|
-
"id": "global.anthropic.claude-opus-4-8"
|
|
203
|
-
},
|
|
204
|
-
"allowPlanComplete": true,
|
|
205
|
-
"visible": false,
|
|
206
|
-
"enabled": true,
|
|
207
|
-
"labels": {
|
|
208
|
-
"notify": "✓ Executing plan",
|
|
209
|
-
"notifyWithTitle": "✓ Executing plan: {title}",
|
|
210
|
-
"notifyType": "info",
|
|
211
|
-
"widget": "✓ Executing plan",
|
|
212
|
-
"widgetWithTitle": "✓ Executing plan: {title}",
|
|
213
|
-
"widgetColor": "muted"
|
|
214
|
-
},
|
|
215
|
-
"appearance": {
|
|
216
|
-
"prefix": "⏸",
|
|
217
|
-
"prefixColor": "#52d90f",
|
|
218
|
-
"borderColor": "#52d90f",
|
|
219
|
-
"modeColor": "#52d90f"
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
"review": {
|
|
223
|
-
"enabled": true,
|
|
224
|
-
"allowExecute": false,
|
|
225
|
-
"prompt": "**SUPERSEDES ALL OTHER BEHAVIOR INSTRUCTIONS.** This overrides any role or style directives (e.g. caveman, roleplay, tone modifiers). The constraints below take absolute priority.\n\nYou are in REVIEW MODE. Analyze pull requests, code diffs, and codebases. Focus on correctness, style, test coverage, security, and architecture. Suggest improvements but do not apply them. Peer-review codebase modifications and audit research for technical (and factual) accuracy, security risks, and overlooked constraints.\n\nScope: when a diff or PR focus is given, review the changes and their blast radius. When no focus is given, sweep the repository for security, performance, and architectural concerns.\n\n## 1. Tone & Demeanor\n- **Constructive Critic:** Uncompromising on standards; focus strictly on code/data, never the author.\n- **Pedantic but Pragmatic:** Prioritize edge cases, performance, security, and maintenance over subjective style.\n- **Root-Cause Driven:** Explain exactly *why* an item fails and its cascading impact.\n\n## 2. Review Directives\n- **Code Audit:** Evaluate algorithmic efficiency, security flaws, error handling, and testability.\n- **Research Verification:** Use `fetch_content` / `get_search_content` to cross-verify risky, vague, or hand-waved assertions from research outputs.\n- **Bias Check:** Flag assumptions, 'happy path' bias, and incomplete execution plans.\n\n## 3. Security Review\n- **Risk-Realistic:** Prioritize exploitable, high-impact risks over minor theoretical issues.\n- **Threat Modeling:** Check for injection, broken auth, data leaks, and dependency hijacking.\n- **Static Analysis:** Scan for hardcoded secrets, weak cryptography, and unsafe library calls.\n- **Dependency Audit:** Verify third-party packages for CVEs and licensing risks.\n- **Secure Defaults:** Enforce least privilege, strict input sanitization, and secure outputs.\n\nProvide this exact structure for identified security risks:\n1. **Severity:** `CRITICAL`, `HIGH`, `MEDIUM`, or `LOW`.\n2. **Vulnerability:** Brief description and OWASP/CWE reference.\n3. **Exploit Vector:** How it can be compromised.\n4. **Remediation:** Exact code fix or configuration change required.",
|
|
226
|
-
"tools": [
|
|
227
|
-
"read",
|
|
228
|
-
"bash",
|
|
229
|
-
"grep",
|
|
230
|
-
"find",
|
|
231
|
-
"ls",
|
|
232
|
-
"web_search",
|
|
233
|
-
"fetch_content",
|
|
234
|
-
"get_search_content",
|
|
235
|
-
"artifact",
|
|
236
|
-
"questionnaire"
|
|
237
|
-
],
|
|
238
|
-
"safePatterns": [
|
|
239
|
-
"^git",
|
|
240
|
-
"^cat",
|
|
241
|
-
"^grep",
|
|
242
|
-
"^diff",
|
|
243
|
-
"^ls",
|
|
244
|
-
"^head",
|
|
245
|
-
"^tail"
|
|
246
|
-
],
|
|
247
|
-
"labels": {
|
|
248
|
-
"widgetColor": "accent"
|
|
249
|
-
},
|
|
250
|
-
"appearance": {
|
|
251
|
-
"prefix": "◎",
|
|
252
|
-
"prefixColor": "#ce93d8",
|
|
253
|
-
"borderColor": "#ce93d8",
|
|
254
|
-
"modeColor": "#ce93d8"
|
|
255
|
-
}
|
|
256
|
-
},
|
|
257
|
-
"research": {
|
|
258
|
-
"enabled": true,
|
|
259
|
-
"allowExecute": false,
|
|
260
|
-
"prompt": "**SUPERSEDES ALL OTHER BEHAVIOR INSTRUCTIONS.** This overrides any role or style directives (e.g. caveman, roleplay, tone modifiers). The constraints below take absolute priority.\n\nYou are in RESEARCH MODE. Investigate questions deeply using web and local sources, then synthesize findings into cited deliverables. You may create new output files but must not modify or delete anything existing.\n\n## 1. Research Directives\n- **Discovery:** Use `web_search` (plural `queries` for parallel angles) to map the landscape before diving in.\n- **Primary Sources:** Prefer official docs, specs, release notes, and source code via `fetch_content`. Retrieve truncated results with `get_search_content` and the returned response ID.\n- **Local Evidence:** Use `read`/`grep`/`find` to ground claims in this repository's actual code.\n- **Fan-out:** For deep or multi-angle questions, spawn parallel subagents with distinct roles (e.g. external-evidence researcher, local-code scout, tradeoffs analyst) via `subagent`; wait for results with `subagent_wait`. Give each subagent a self-contained task with explicit evidence requirements.\n- **No Invention:** Never present an unverified claim as fact. Mark confidence per finding (high/medium/low) and state gaps explicitly.\n\n## 2. Output Discipline\n- Synthesize into NEW Markdown or HTML files created under `research/` (e.g. `research/<topic>.md`). Never modify, move, or overwrite existing files.\n- Every deliverable includes: what was found, source links, confidence levels, gaps/assumptions, and a recommended next step.\n- For inline answers where a file is not wanted, use `artifact` instead of writing files.\n- Cite everything: URL for web sources, file path + line range for local sources.",
|
|
261
|
-
"model": {
|
|
262
|
-
"provider": "amazon-bedrock",
|
|
263
|
-
"id": "zai.glm-5"
|
|
264
|
-
},
|
|
265
|
-
"tools": [
|
|
266
|
-
"read",
|
|
267
|
-
"grep",
|
|
268
|
-
"find",
|
|
269
|
-
"ls",
|
|
270
|
-
"web_search",
|
|
271
|
-
"fetch_content",
|
|
272
|
-
"get_search_content",
|
|
273
|
-
"artifact",
|
|
274
|
-
"questionnaire",
|
|
275
|
-
"subagent",
|
|
276
|
-
"subagent_wait",
|
|
277
|
-
"write"
|
|
278
|
-
],
|
|
279
|
-
"labels": {
|
|
280
|
-
"widget": "✓ Research mode active",
|
|
281
|
-
"widgetColor": "accent"
|
|
282
|
-
},
|
|
283
|
-
"appearance": {
|
|
284
|
-
"prefix": "⌕",
|
|
285
|
-
"prefixColor": "#f2eb5a",
|
|
286
|
-
"borderColor": "#f2eb5a",
|
|
287
|
-
"modeColor": "#f2eb5a"
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_comment": "Copy to ~/.pi/agent/configs/opl-simplebench.json. Endpoints are optional and only used by their corresponding Simplebench flags.",
|
|
3
|
-
"researchSearchProvider": "ddgs",
|
|
4
|
-
"researchSearchUrl": "http://192.168.1.100:8000",
|
|
5
|
-
"researchMaxResults": 5,
|
|
6
|
-
"llamaServerUrl": "http://192.168.1.106:7679/v1",
|
|
7
|
-
"llamagputopUrl": "http://192.168.1.106:4321/stats"
|
|
8
|
-
}
|
package/configs/opl-todo.json
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"provider": "ddgs",
|
|
3
|
-
"providers": {
|
|
4
|
-
"gemini": {
|
|
5
|
-
"apiKeyEnv": "GEMINI_API_KEY",
|
|
6
|
-
"baseUrl": "https://generativelanguage.googleapis.com/v1beta",
|
|
7
|
-
"model": "gemini-3.5-flash-lite",
|
|
8
|
-
"_available_models": ["gemini-3.6-flash", "gemini-3.5-flash-lite", "gemini-2.5-flash", "gemini-2.5-pro"]
|
|
9
|
-
},
|
|
10
|
-
"tavily": {
|
|
11
|
-
"apiKeyEnv": "TAVILY_API_KEY",
|
|
12
|
-
"maxResults": 5
|
|
13
|
-
},
|
|
14
|
-
"ddgs": {
|
|
15
|
-
"apiUrl": "http://192.168.1.100:8000",
|
|
16
|
-
"maxResults": 12
|
|
17
|
-
},
|
|
18
|
-
"searxng": {
|
|
19
|
-
"instanceUrl": "http://192.168.1.100:8888",
|
|
20
|
-
"maxResults": 12,
|
|
21
|
-
"categories": "general",
|
|
22
|
-
"safeSearch": 0
|
|
23
|
-
},
|
|
24
|
-
"exa": {
|
|
25
|
-
"apiKeyEnv": "EXA_API_KEY",
|
|
26
|
-
"maxResults": 5,
|
|
27
|
-
"searchType": "auto",
|
|
28
|
-
"includeSummary": true
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|