@oh-my-pi/pi-coding-agent 12.7.6 → 12.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -37
- package/README.md +9 -1052
- package/package.json +7 -7
- package/src/cli/args.ts +1 -0
- package/src/cli/update-cli.ts +49 -35
- package/src/cli/web-search-cli.ts +3 -2
- package/src/commands/web-search.ts +1 -0
- package/src/config/model-registry.ts +6 -0
- package/src/config/settings-schema.ts +25 -3
- package/src/config/settings.ts +1 -0
- package/src/extensibility/extensions/wrapper.ts +20 -13
- package/src/extensibility/slash-commands.ts +12 -91
- package/src/lsp/client.ts +24 -27
- package/src/lsp/index.ts +92 -42
- package/src/mcp/config-writer.ts +33 -0
- package/src/mcp/config.ts +6 -1
- package/src/mcp/types.ts +1 -0
- package/src/modes/components/custom-editor.ts +8 -5
- package/src/modes/components/settings-defs.ts +2 -1
- package/src/modes/controllers/command-controller.ts +12 -6
- package/src/modes/controllers/input-controller.ts +21 -186
- package/src/modes/controllers/mcp-command-controller.ts +60 -3
- package/src/modes/interactive-mode.ts +2 -2
- package/src/modes/types.ts +1 -1
- package/src/sdk.ts +23 -1
- package/src/secrets/index.ts +116 -0
- package/src/secrets/obfuscator.ts +269 -0
- package/src/secrets/regex.ts +21 -0
- package/src/session/agent-session.ts +143 -21
- package/src/session/compaction/branch-summarization.ts +2 -2
- package/src/session/compaction/compaction.ts +10 -3
- package/src/session/compaction/utils.ts +25 -1
- package/src/slash-commands/builtin-registry.ts +419 -0
- package/src/web/scrapers/github.ts +50 -12
- package/src/web/search/index.ts +5 -5
- package/src/web/search/provider.ts +13 -2
- package/src/web/search/providers/brave.ts +165 -0
- package/src/web/search/types.ts +1 -1
- package/docs/compaction.md +0 -436
- package/docs/config-usage.md +0 -176
- package/docs/custom-tools.md +0 -585
- package/docs/environment-variables.md +0 -257
- package/docs/extension-loading.md +0 -106
- package/docs/extensions.md +0 -1342
- package/docs/fs-scan-cache-architecture.md +0 -50
- package/docs/hooks.md +0 -906
- package/docs/models.md +0 -234
- package/docs/python-repl.md +0 -110
- package/docs/rpc.md +0 -1173
- package/docs/sdk.md +0 -1039
- package/docs/session-tree-plan.md +0 -84
- package/docs/session.md +0 -368
- package/docs/skills.md +0 -254
- package/docs/theme.md +0 -696
- package/docs/tree.md +0 -206
- package/docs/tui.md +0 -487
package/docs/models.md
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
# `models.yml` provider integration guide
|
|
2
|
-
|
|
3
|
-
`models.yml` lets you register custom model providers (local or hosted), override built-in providers, and tune model metadata.
|
|
4
|
-
|
|
5
|
-
Default location:
|
|
6
|
-
|
|
7
|
-
- `~/.omp/agent/models.yml`
|
|
8
|
-
|
|
9
|
-
Legacy support:
|
|
10
|
-
|
|
11
|
-
- `models.json` is still read and auto-migrated to `models.yml` when possible.
|
|
12
|
-
|
|
13
|
-
## Top-level shape
|
|
14
|
-
|
|
15
|
-
```yaml
|
|
16
|
-
providers:
|
|
17
|
-
<provider-name>:
|
|
18
|
-
# Provider config
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
`<provider-name>` is the provider ID used everywhere else (selection, auth lookup, etc.).
|
|
22
|
-
|
|
23
|
-
## Provider fields
|
|
24
|
-
|
|
25
|
-
```yaml
|
|
26
|
-
providers:
|
|
27
|
-
my-provider:
|
|
28
|
-
baseUrl: https://api.example.com/v1
|
|
29
|
-
apiKey: MY_PROVIDER_API_KEY
|
|
30
|
-
api: openai-responses
|
|
31
|
-
headers:
|
|
32
|
-
X-Custom-Header: value
|
|
33
|
-
authHeader: true
|
|
34
|
-
auth: apiKey
|
|
35
|
-
discovery:
|
|
36
|
-
type: ollama
|
|
37
|
-
modelOverrides:
|
|
38
|
-
<model-id-within-provider>:
|
|
39
|
-
name: Friendly Name
|
|
40
|
-
models:
|
|
41
|
-
- id: model-id
|
|
42
|
-
name: My Model
|
|
43
|
-
api: openai-responses
|
|
44
|
-
reasoning: false
|
|
45
|
-
input: [text]
|
|
46
|
-
cost:
|
|
47
|
-
input: 0
|
|
48
|
-
output: 0
|
|
49
|
-
cacheRead: 0
|
|
50
|
-
cacheWrite: 0
|
|
51
|
-
contextWindow: 128000
|
|
52
|
-
maxTokens: 16384
|
|
53
|
-
headers:
|
|
54
|
-
X-Model-Header: value
|
|
55
|
-
compat:
|
|
56
|
-
supportsStore: true
|
|
57
|
-
supportsDeveloperRole: true
|
|
58
|
-
supportsReasoningEffort: true
|
|
59
|
-
maxTokensField: max_completion_tokens
|
|
60
|
-
openRouterRouting:
|
|
61
|
-
only: [anthropic]
|
|
62
|
-
vercelGatewayRouting:
|
|
63
|
-
order: [openai, anthropic]
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### `api` values
|
|
67
|
-
|
|
68
|
-
Supported API adapters:
|
|
69
|
-
|
|
70
|
-
- `openai-completions`
|
|
71
|
-
- `openai-responses`
|
|
72
|
-
- `openai-codex-responses`
|
|
73
|
-
- `azure-openai-responses`
|
|
74
|
-
- `anthropic-messages`
|
|
75
|
-
- `google-generative-ai`
|
|
76
|
-
- `google-vertex`
|
|
77
|
-
|
|
78
|
-
`auth` values:
|
|
79
|
-
|
|
80
|
-
- `apiKey` (default)
|
|
81
|
-
- `none`
|
|
82
|
-
|
|
83
|
-
`discovery.type` values:
|
|
84
|
-
|
|
85
|
-
- `ollama`
|
|
86
|
-
|
|
87
|
-
If `discovery` is set, provider-level `api` is required.
|
|
88
|
-
|
|
89
|
-
## Required vs optional
|
|
90
|
-
|
|
91
|
-
### Full custom provider (defines `models`)
|
|
92
|
-
|
|
93
|
-
If `models` is non-empty, you must set:
|
|
94
|
-
|
|
95
|
-
- `baseUrl`
|
|
96
|
-
- `apiKey` (unless `auth: none`)
|
|
97
|
-
- `api` at provider level or per model
|
|
98
|
-
|
|
99
|
-
If `auth: none` is set, `apiKey` is optional even when `models` are defined.
|
|
100
|
-
|
|
101
|
-
### Override-only provider (no `models`)
|
|
102
|
-
|
|
103
|
-
If `models` is empty/missing, set at least one of:
|
|
104
|
-
|
|
105
|
-
- `baseUrl`
|
|
106
|
-
- `modelOverrides`
|
|
107
|
-
- `discovery`
|
|
108
|
-
|
|
109
|
-
Use this to modify built-in providers without redefining all models.
|
|
110
|
-
|
|
111
|
-
Default values when omitted in a model definition:
|
|
112
|
-
|
|
113
|
-
- `reasoning: false`
|
|
114
|
-
- `input: [text]`
|
|
115
|
-
- `cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }`
|
|
116
|
-
- `contextWindow: 128000`
|
|
117
|
-
- `maxTokens: 16384`
|
|
118
|
-
|
|
119
|
-
Header merge behavior:
|
|
120
|
-
|
|
121
|
-
- Provider `headers` are applied first
|
|
122
|
-
- Model-level `headers` override provider headers on key conflicts
|
|
123
|
-
## Merge behavior
|
|
124
|
-
|
|
125
|
-
`models.yml` does not replace the built-in registry.
|
|
126
|
-
|
|
127
|
-
1. Built-in models load first.
|
|
128
|
-
2. Provider-level overrides (`baseUrl`, `headers`) are applied.
|
|
129
|
-
3. `modelOverrides` are applied by model ID within each provider.
|
|
130
|
-
4. Custom `models` are merged in.
|
|
131
|
-
5. If a custom model has the same `provider + id` as an existing model, it replaces that model.
|
|
132
|
-
|
|
133
|
-
## API key behavior
|
|
134
|
-
|
|
135
|
-
`apiKey` resolution is:
|
|
136
|
-
|
|
137
|
-
1. Treat value as env var name (preferred)
|
|
138
|
-
2. If env var not found, treat value as literal key
|
|
139
|
-
|
|
140
|
-
Example:
|
|
141
|
-
|
|
142
|
-
```yaml
|
|
143
|
-
apiKey: OPENROUTER_API_KEY
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
If `OPENROUTER_API_KEY` exists, that value is used. Otherwise, the literal string `OPENROUTER_API_KEY` is used as the token.
|
|
147
|
-
|
|
148
|
-
Use `authHeader: true` when your endpoint expects:
|
|
149
|
-
|
|
150
|
-
```http
|
|
151
|
-
Authorization: Bearer <apiKey>
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
Set `auth: none` for keyless providers (local gateways, unauthenticated dev endpoints).
|
|
155
|
-
|
|
156
|
-
## Practical integration patterns
|
|
157
|
-
|
|
158
|
-
### 1) OpenAI-compatible endpoint (vLLM / LM Studio / gateway)
|
|
159
|
-
|
|
160
|
-
```yaml
|
|
161
|
-
providers:
|
|
162
|
-
local-openai:
|
|
163
|
-
baseUrl: http://127.0.0.1:8000/v1
|
|
164
|
-
auth: none
|
|
165
|
-
api: openai-completions
|
|
166
|
-
models:
|
|
167
|
-
- id: Qwen/Qwen2.5-Coder-32B-Instruct
|
|
168
|
-
name: Qwen 2.5 Coder 32B (local)
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### 2) Anthropic-compatible proxy
|
|
172
|
-
|
|
173
|
-
```yaml
|
|
174
|
-
providers:
|
|
175
|
-
anthropic-proxy:
|
|
176
|
-
baseUrl: https://proxy.example.com/anthropic
|
|
177
|
-
apiKey: ANTHROPIC_PROXY_KEY
|
|
178
|
-
api: anthropic-messages
|
|
179
|
-
authHeader: true
|
|
180
|
-
models:
|
|
181
|
-
- id: claude-sonnet-4-20250514
|
|
182
|
-
name: Claude Sonnet 4 (Proxy)
|
|
183
|
-
reasoning: true
|
|
184
|
-
input: [text, image]
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### 3) Override built-in provider without redefining models
|
|
188
|
-
|
|
189
|
-
```yaml
|
|
190
|
-
providers:
|
|
191
|
-
openrouter:
|
|
192
|
-
baseUrl: https://my-corp-proxy.example.com/v1
|
|
193
|
-
headers:
|
|
194
|
-
X-Team: platform
|
|
195
|
-
modelOverrides:
|
|
196
|
-
anthropic/claude-sonnet-4:
|
|
197
|
-
name: Sonnet 4 (Corp Route)
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### 4) Runtime discovery for Ollama
|
|
201
|
-
|
|
202
|
-
```yaml
|
|
203
|
-
providers:
|
|
204
|
-
ollama:
|
|
205
|
-
baseUrl: http://127.0.0.1:11434
|
|
206
|
-
api: openai-completions
|
|
207
|
-
auth: none
|
|
208
|
-
discovery:
|
|
209
|
-
type: ollama
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
The agent will query `GET /api/tags` and register discovered models dynamically.
|
|
213
|
-
|
|
214
|
-
## Validation failures to watch for
|
|
215
|
-
|
|
216
|
-
Common schema/validation errors:
|
|
217
|
-
|
|
218
|
-
- Provider with `models` but missing `baseUrl`
|
|
219
|
-
- Provider with `models` and `auth != none` but missing `apiKey`
|
|
220
|
-
- Model missing `api` when neither provider-level nor model-level `api` is set
|
|
221
|
-
- Non-positive `contextWindow` or `maxTokens`
|
|
222
|
-
- `discovery` configured without provider-level `api`
|
|
223
|
-
|
|
224
|
-
When `models.yml` has errors, the agent falls back to built-in models and reports a load error.
|
|
225
|
-
|
|
226
|
-
## Quick start
|
|
227
|
-
|
|
228
|
-
1. Create `~/.omp/agent/models.yml`
|
|
229
|
-
2. Add one provider with one model
|
|
230
|
-
3. Start the agent and open `/model`
|
|
231
|
-
4. Confirm your provider/model appears
|
|
232
|
-
5. If auth fails, check env vars and `authHeader`
|
|
233
|
-
|
|
234
|
-
For SDK usage, `ModelRegistry` also accepts a custom path so you can load non-default `models.yml` files programmatically.
|
package/docs/python-repl.md
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
# Python REPL (Jupyter Kernel Gateway)
|
|
2
|
-
|
|
3
|
-
## Requirements
|
|
4
|
-
|
|
5
|
-
- Python 3 available on PATH (or via an active virtualenv)
|
|
6
|
-
- `jupyter-kernel-gateway` (`kernel_gateway` module) and `ipykernel` installed in the selected Python environment
|
|
7
|
-
|
|
8
|
-
Install:
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
python -m pip install jupyter_kernel_gateway ipykernel
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## How It Works
|
|
15
|
-
|
|
16
|
-
The Python tool uses a Jupyter Kernel Gateway and talks to it over REST and WebSocket APIs.
|
|
17
|
-
By default it uses a shared local gateway so multiple pi instances reuse the same gateway process.
|
|
18
|
-
|
|
19
|
-
Shared-gateway startup flow:
|
|
20
|
-
|
|
21
|
-
1. Filter the environment and resolve the Python runtime (including venv detection)
|
|
22
|
-
2. Acquire the shared gateway (reuse a healthy gateway or spawn `python -m kernel_gateway` on 127.0.0.1:PORT)
|
|
23
|
-
3. Wait for gateway readiness (`GET /api/kernelspecs`)
|
|
24
|
-
4. Create a kernel (`POST /api/kernels`)
|
|
25
|
-
5. Connect WebSocket for execution messages
|
|
26
|
-
6. Initialize kernel environment, run prelude helpers, and load extension modules
|
|
27
|
-
|
|
28
|
-
## External Gateway Support
|
|
29
|
-
|
|
30
|
-
Instead of spawning a local gateway, you can connect to an already-running Jupyter Kernel Gateway:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
# Connect to external gateway
|
|
34
|
-
export PI_PYTHON_GATEWAY_URL="http://127.0.0.1:8888"
|
|
35
|
-
|
|
36
|
-
# Optional: auth token if gateway requires it (KG_AUTH_TOKEN)
|
|
37
|
-
export PI_PYTHON_GATEWAY_TOKEN="your-token-here"
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
When `PI_PYTHON_GATEWAY_URL` is set:
|
|
41
|
-
|
|
42
|
-
- No local gateway process is spawned
|
|
43
|
-
- Kernels are created on the external gateway
|
|
44
|
-
- The gateway process is not killed on shutdown
|
|
45
|
-
- Availability check uses `/api/kernelspecs` endpoint instead of local module check
|
|
46
|
-
|
|
47
|
-
This is useful for:
|
|
48
|
-
|
|
49
|
-
- Remote kernel execution
|
|
50
|
-
- Shared kernel environments
|
|
51
|
-
- Pre-configured gateway setups
|
|
52
|
-
|
|
53
|
-
## Environment Propagation
|
|
54
|
-
|
|
55
|
-
- The kernel inherits a filtered environment (explicit allowlist + denylist)
|
|
56
|
-
- Allowlisted prefixes include `LC_`, `XDG_`, and `PI_`; known API-key vars are removed
|
|
57
|
-
- `PYTHONPATH` is passed through if present
|
|
58
|
-
- Virtual environments are detected via `VIRTUAL_ENV`, `.venv/`, or `venv/` and preferred when present
|
|
59
|
-
|
|
60
|
-
## Prelude Extensions
|
|
61
|
-
|
|
62
|
-
Optional `.py` modules are loaded after the prelude from:
|
|
63
|
-
|
|
64
|
-
- `~/.omp/agent/modules` and `~/.pi/agent/modules`
|
|
65
|
-
- `<project>/.omp/modules` and `<project>/.pi/modules`
|
|
66
|
-
|
|
67
|
-
Project modules override user modules with the same filename.
|
|
68
|
-
|
|
69
|
-
## Kernel Modes
|
|
70
|
-
|
|
71
|
-
Settings under `python` control exposure and reuse:
|
|
72
|
-
|
|
73
|
-
- `toolMode`: `both` (default), `ipy-only`, `bash-only`
|
|
74
|
-
- `kernelMode`: `session` (default) or `per-call`
|
|
75
|
-
- `sharedGateway`: `true` (default). Setting to `false` throws an error because local (per-process) gateways are not supported; the shared gateway is required.
|
|
76
|
-
|
|
77
|
-
Mode behavior:
|
|
78
|
-
|
|
79
|
-
- `session`: reuse kernels per session id, serialize execution, evict after 5 minutes of idle time (max 4 sessions)
|
|
80
|
-
- `per-call`: create a fresh kernel per tool call and shut it down afterward
|
|
81
|
-
|
|
82
|
-
Environment override:
|
|
83
|
-
|
|
84
|
-
- `PI_PY=0|bash` → `bash-only`
|
|
85
|
-
- `PI_PY=1|py` → `ipy-only`
|
|
86
|
-
- `PI_PY=mix|both` → `both`
|
|
87
|
-
|
|
88
|
-
## Shell Helper
|
|
89
|
-
|
|
90
|
-
The Python prelude exposes `run()` which executes a shell command via `bash -c` (or `sh -c` fallback)
|
|
91
|
-
and returns a `ShellResult` with `stdout`, `stderr`, and `code`.
|
|
92
|
-
|
|
93
|
-
## Output Handling
|
|
94
|
-
|
|
95
|
-
- Streams `stdout`/`stderr` as text
|
|
96
|
-
- `application/x-omp-status` emits structured status events for the TUI
|
|
97
|
-
- `image/png` display data renders inline in TUI
|
|
98
|
-
- `application/json` display data renders as a collapsible tree
|
|
99
|
-
- `text/markdown` is rendered as-is, `text/plain` is used as a fallback
|
|
100
|
-
- `text/html` display data is converted to basic markdown
|
|
101
|
-
|
|
102
|
-
## Troubleshooting
|
|
103
|
-
|
|
104
|
-
- **Kernel unavailable**: Ensure `python` + `jupyter-kernel-gateway` + `ipykernel` are installed; the session will fall back to bash-only.
|
|
105
|
-
- **Python mode override**: Check `python.toolMode` or `PI_PY` if the Python tool is missing.
|
|
106
|
-
- **Shared gateway disabled**: `python.sharedGateway=false` causes the Python tool to error because local (per-process) gateways are not supported.
|
|
107
|
-
- **Skip preflight checks**: Set `PI_PYTHON_SKIP_CHECK=1` to bypass kernel availability checks.
|
|
108
|
-
- **External gateway unreachable**: Check the URL is correct and the gateway is running. If auth is required, set `PI_PYTHON_GATEWAY_TOKEN`.
|
|
109
|
-
- **IPC tracing**: Set `PI_PYTHON_IPC_TRACE=1` to log kernel message flow.
|
|
110
|
-
- **Stdin requests**: Interactive input is not supported; refactor code to avoid `input()` or provide data programmatically.
|