@tduyng/pi-opencode-z 0.0.3 → 0.0.4

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.
Files changed (2) hide show
  1. package/README.md +37 -34
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,34 +1,26 @@
1
- # pi-opencode-z
1
+ # @tduyng/pi-opencode-z
2
2
 
3
- opencode's Zen models in pi, free ones included. No API key, no proxy, no key of your own: the bridge drives the opencode server already running on your machine.
4
-
5
- ## What it costs
6
-
7
- No tools, no prompt block, no schema. It is a model provider, so the context and the cold start are pi's own.
8
-
9
- The 7k input floor is opencode's, not this extension's. A plain `opencode run` on a free model spends 9,176 input tokens on a one-line prompt, while this bridge spends 6,941 with 2,048 of those served from cache. That floor is opencode's system prompt and built-in tool schemas, and every approach pays it, because stripping those tools is exactly what trips the 403.
10
-
11
- What the bridge does save is per turn. opencode holds the conversation, so each turn sends only the new message instead of re-serializing the transcript, and the tool schemas sit in the cached prefix rather than being pasted back as prose on every request.
12
-
13
- ## Why it works this way
3
+ opencode's Zen models in pi, free ones included, with no API key and no proxy. The bridge drives the opencode server already running on the machine.
14
4
 
15
5
  Since September 2026 the free tier answers any direct API call with `403 FreeTierError: "OpenCode's free tier can only be used from within OpenCode"`. No key and no proxy gets around it, because the check is on where the request originates.
16
6
 
17
7
  So the extension does not call the Zen API. It drives the opencode background server and lets opencode make the upstream call, which is the one thing the free tier accepts.
18
8
 
19
- ## How it works
20
-
21
- The bridge reads the server url and password from `~/.local/state/opencode/service.json` and talks to it over HTTP basic auth as user `opencode`. If the server is not running, `opencode service start` brings it back.
9
+ ## The conversation lives in opencode
22
10
 
23
- Each pi session gets one opencode session, rooted in a throwaway temp directory holding its `opencode.jsonc`. Nothing is written to your repo or to `~/.config/opencode`.
11
+ The bridge sends only the new message each turn instead of re-serialising the transcript, and the tool schemas sit in opencode's cached prefix rather than being pasted back as prose on every request.
24
12
 
25
- Pi's tools reach the model through a local MCP server, exposed as `pi_read`, `pi_bash`, `pi_edit`, and so on. When the model calls one, the bridge holds that MCP request open, hands the call to pi, and pi runs the real tool against your real project. The answer goes back over the same held request and opencode carries on in the same session. The model never touches your files directly, and pi does, under pi's own permissions.
13
+ The bridge exposes pi's tools over MCP as `pi_read`, `pi_bash`, `pi_edit` and so on. When the model calls one, the bridge holds that MCP request open, hands the call to pi, and pi runs the real tool against the real project. The answer goes back over the same held request and opencode carries on in the same session. The model never touches files directly.
26
14
 
27
- Pi hands providers a transcript rather than a prompt and a tool list, so the bridge replays the transcript's system messages to recover the current instructions and tool set before each turn.
15
+ Nothing is written to the repository. Each pi session gets one opencode session rooted in a throwaway temp directory holding its `opencode.jsonc`, and `~/.config/opencode` is untouched.
28
16
 
29
17
  A mode switch that adds or removes tools keeps the session too: the bridge pushes `notifications/tools/list_changed` over MCP, opencode re-lists, and the cached prefix survives.
30
18
 
31
- A full tool-calling turn, measured end to end with a real file read, takes about 10 seconds.
19
+ ## The token floor
20
+
21
+ A plain `opencode run` on a free model spends 9,176 input tokens on a one-line prompt. This bridge spends 6,941, with 2,048 of those served from cache. That floor is opencode's own system prompt and built-in tool schemas, and every approach pays it, because stripping those tools is exactly what trips the 403.
22
+
23
+ What the bridge saves is per turn. A full tool-calling turn with a real file read takes about 10 seconds end to end.
32
24
 
33
25
  ## Use
34
26
 
@@ -46,7 +38,19 @@ pi --provider opencode-z --model mimo-v2.6-flash-free
46
38
  | `/opencode-z config` | Resolved settings and where they come from |
47
39
  | `/opencode-z help` | Usage |
48
40
 
49
- ## Configure
41
+ ## Install
42
+
43
+ - The `opencode` CLI on `PATH`, or `OPENCODE_Z_BIN` pointing at it.
44
+ - The opencode background server. If it is not running, the bridge runs `opencode service start`.
45
+ - No API key and no account.
46
+
47
+ ```bash
48
+ pi install npm:@tduyng/pi-opencode-z
49
+ ```
50
+
51
+ Local checkout: `pi install /path/to/dotfiles/pi/agent/extensions/pi-opencode-z`
52
+
53
+ The bridge reads the server url and password from `~/.local/state/opencode/service.json` and talks to it over HTTP basic auth as user `opencode`.
50
54
 
51
55
  Settings live in `~/.pi/agent/opencode-z.json`, and a project's `.pi/opencode-z.json` overrides it field by field. Environment variables override both, so a one-off run never needs a file.
52
56
 
@@ -67,26 +71,25 @@ A pinned list with a custom binary:
67
71
  }
68
72
  ```
69
73
 
70
- `models` narrows what gets registered: `free` keeps zero-cost models, and a comma-separated string or an array pins the list. Unset or empty, every Zen model your account can reach is registered. Only Zen models appear, never other providers. `OPENCODE_Z_BIN` and `OPENCODE_Z_MODELS` do the same per process and win over the file.
71
-
72
- ## Notes
74
+ `models` narrows what gets registered: `free` keeps zero-cost models, and a comma-separated string or an array pins the list. Unset or empty, every Zen model the account can reach is registered. Only Zen models appear, never other providers. `OPENCODE_Z_BIN` and `OPENCODE_Z_MODELS` do the same per process and win over the file.
73
75
 
74
- The bridge never denies opencode's built-in tools. A `deny` rule anywhere in the agent's permissions trips the free-tier 403 even for tools that were allowed, so every action stays on `ask` and the bridge rejects the unwanted ones at runtime. A weaker model sometimes reaches for its built-in `read` first, gets refused, and retries with `pi_read`, which costs one round trip.
76
+ It adds no tool, no prompt block and no schema, so the context is pi's own and cold start is unchanged.
75
77
 
76
- opencode adds and retires Zen models often, so the catalogue is read live at startup and `/opencode-z refresh` re-reads it.
78
+ ## Notes
77
79
 
78
- The first prompt lists the exact MCP names available in that turn. Some model hosts display these tools under a `functions.` namespace, and the bridge states that the label does not rename a tool, which keeps a model from mistaking a disabled `read` for `pi_read`.
80
+ The bridge never denies opencode's built-in tools. A `deny` rule anywhere in the agent's permissions trips the free-tier 403 even for allowed tools, so every action stays on `ask` and the bridge rejects the unwanted ones at runtime. A weaker model sometimes reaches for its built-in `read` first, gets refused, and retries with `pi_read`, which costs one round trip.
79
81
 
80
- A step that produces reasoning but no text and no tool call is re-prompted through the same bounded recovery path, and so is a step whose only text is a `pi_` call written out as chat template markup.
82
+ opencode adds and retires Zen models often, so the bridge reads the catalogue live at startup and `/opencode-z refresh` re-reads it.
81
83
 
82
- opencode stops a whole step when the model calls two of its built-in tools at once: refusing one declines the rest. The bridge counts its own refusals and, when that stop was its doing, re-prompts the same session with a nudge back to the `pi_` tools, at most twice per turn, instead of failing the turn.
84
+ The first prompt lists the exact MCP names available in that turn. Some model hosts display these tools under a `functions.` namespace, and the bridge states that the label does not rename a tool, so a model does not mistake a disabled `read` for `pi_read`.
83
85
 
84
- When a turn fails, the bridge interrupts opencode and answers waiting tool calls with an error. It keeps the opencode session when pi's transcript still ends at the last completed user message, so a retry reuses the prompt cache, and drops it to rebuild from the transcript when a partial assistant or tool result is present. A timeout usually means the model was still working, since large contexts on high thinking levels are slow, or that opencode got stuck waiting.
86
+ opencode stops a whole step when the model calls two built-in tools at once, since refusing one declines the rest. The bridge counts its own refusals and, when that stop was its doing, re-prompts the same session with a nudge back to the `pi_` tools, at most twice per turn.
85
87
 
86
- ## Install
88
+ When a turn fails, the bridge interrupts opencode and answers waiting tool calls with an error. It keeps the opencode session when pi's transcript still ends at the last completed user message, so a retry reuses the prompt cache, and drops it when a partial assistant or tool result is present.
87
89
 
88
- ```bash
89
- pi install npm:@tduyng/pi-opencode-z
90
- ```
90
+ ## Limits
91
91
 
92
- Local checkout: `pi install /path/to/dotfiles/pi/agent/extensions/pi-opencode-z`
92
+ - A turn times out at 300 seconds, and an MCP exec at 300 seconds. Large contexts on high thinking levels are slow, so a timeout usually means the model was still working.
93
+ - The API request times out at 15 seconds, and the MCP body is capped at 8 MB.
94
+ - A step that produces reasoning but no text and no tool call is re-prompted through a bounded recovery path, twice per turn at most.
95
+ - Free-tier model availability is opencode's to change. The list is read live for that reason.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tduyng/pi-opencode-z",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "opencode's Zen models in Pi, free ones included, by driving the local opencode server. No API key of your own.",
5
5
  "keywords": [
6
6
  "pi",