playmaker-cli 0.5.0__tar.gz → 0.6.0__tar.gz
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.
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/CHANGELOG.md +57 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/PKG-INFO +59 -16
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/README.md +56 -13
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/pyproject.toml +4 -2
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/skills/playmaker-coach/SKILL.md +31 -20
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/agents/agy.py +7 -4
- playmaker_cli-0.6.0/src/playmaker/agents/opencode.py +461 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/cli.py +39 -8
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/quotas.py +160 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/registry.py +2 -0
- playmaker_cli-0.6.0/tests/test_opencode.py +430 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/tests/test_permissions.py +18 -0
- playmaker_cli-0.6.0/tests/test_quotas_zai.py +165 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/tests/test_registry.py +2 -2
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/.gitignore +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/LICENSE +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/__init__.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/__main__.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/agents/__init__.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/agents/base.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/agents/claude.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/agents/codex.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/agents/gemini.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/config.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/notify.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/state.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/src/playmaker/watcher.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/tests/__init__.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/tests/test_agy.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/tests/test_claude.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/tests/test_codex.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/tests/test_quotas_antigravity.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/tests/test_skill.py +0 -0
- {playmaker_cli-0.5.0 → playmaker_cli-0.6.0}/tests/test_state.py +0 -0
|
@@ -5,6 +5,63 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.6.0] - 2026-07-27
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`opencode` agent handler — one lane, ~75 providers.** The ask was z.ai GLM
|
|
13
|
+
support, but playmaker never talks to a model API: it drives agent CLIs. So
|
|
14
|
+
rather than teach the claude handler an `ANTHROPIC_BASE_URL` override — which
|
|
15
|
+
would have *replaced* the Anthropic lane rather than added one — the handler
|
|
16
|
+
wraps [opencode](https://opencode.ai), whose `--model provider/model` already
|
|
17
|
+
reaches GLM (`zai-coding-plan/glm-5.2`), local LMStudio/MLX models, and
|
|
18
|
+
everything else on models.dev. Oneshot via `opencode run --format json`,
|
|
19
|
+
resume via `-s <id>`; every JSONL event carries `sessionID`, so a detached
|
|
20
|
+
dispatch records the id from the first line rather than at completion.
|
|
21
|
+
|
|
22
|
+
Four behaviours worth knowing. opencode resolves its working directory from
|
|
23
|
+
`process.env.PWD`, which `subprocess.Popen(cwd=…)` does not update — left
|
|
24
|
+
alone it ignores `--cwd` and writes into whatever directory the coach was
|
|
25
|
+
sitting in, so the handler passes `--dir` and corrects `PWD`.
|
|
26
|
+
opencode ≥1.18 keeps transcripts in SQLite
|
|
27
|
+
(`opencode.db`), not one file per session, so playmaker writes a pointer at
|
|
28
|
+
`~/.playmaker/opencode/<id>.session` and reads the `session`/`message`/`part`
|
|
29
|
+
tables live — which keeps `thread --follow` current rather than frozen.
|
|
30
|
+
Cost comes from opencode's own per-session accounting rather than the stream,
|
|
31
|
+
because `run --format json` can exit before its final `step_finish`
|
|
32
|
+
([opencode#26855](https://github.com/anomalyco/opencode/issues/26855)).
|
|
33
|
+
And `[agents.opencode] model` matters more than the usual `--model` default:
|
|
34
|
+
left unset, opencode falls back to whatever its own `opencode.json` says,
|
|
35
|
+
which is typically the model you last picked interactively rather than the
|
|
36
|
+
one you meant to dispatch to.
|
|
37
|
+
|
|
38
|
+
Permissions follow agy, for the same reason: `--auto` is opencode's only
|
|
39
|
+
lever, so a detached run either auto-approves or comes back having done
|
|
40
|
+
nothing. `yolo` defaults to `true`; narrow it with the `permission` block in
|
|
41
|
+
your own opencode.json, which `--auto` still honours for denies.
|
|
42
|
+
- **`zai` quota probe** — GLM Coding Plan windows (5-hour, weekly, and the
|
|
43
|
+
monthly MCP tool pool) from `api.z.ai/api/monitor/usage/quota/limit`, keyed
|
|
44
|
+
off the credential opencode already wrote to its `auth.json`, so playmaker
|
|
45
|
+
still stores no secret of its own. Reported as its own provider rather than
|
|
46
|
+
under `opencode`, because the quota belongs to the plan — an opencode lane
|
|
47
|
+
pointed at a local model spends nothing here. Degrades to *unsupported*, not
|
|
48
|
+
an error row, when no Z.ai credential exists.
|
|
49
|
+
|
|
50
|
+
## [0.5.1] - 2026-07-27
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- **The bundled coach skill taught agy model names agy no longer accepts.**
|
|
55
|
+
`agy models` switched from quoted display strings (`"Claude Opus 4.6
|
|
56
|
+
(Thinking)"`) to bare slugs (`claude-opus-4-6-thinking`), so every agy
|
|
57
|
+
dispatch the skill proposed failed model validation. The skill now says to
|
|
58
|
+
read the live roster from `agy models` instead of spelling names from
|
|
59
|
+
memory. It also recommended `codex -m gpt-5-codex`, which fails on accounts
|
|
60
|
+
whose plan lacks that model; codex dispatches now default to the account's
|
|
61
|
+
own default model. Both fixes landed on main just after v0.5.0 was tagged —
|
|
62
|
+
this release exists because the skill ships inside the wheel, so doc fixes
|
|
63
|
+
are not live until published.
|
|
64
|
+
|
|
8
65
|
## [0.5.0] - 2026-07-27
|
|
9
66
|
|
|
10
67
|
### Changed
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: playmaker-cli
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Playing-coach CLI for orchestrating Claude Code, Codex and
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Playing-coach CLI for orchestrating Claude Code, Codex, Antigravity and opencode sub-agents in parallel.
|
|
5
5
|
Project-URL: Homepage, https://github.com/vladsafedev/playmaker
|
|
6
6
|
Project-URL: Repository, https://github.com/vladsafedev/playmaker
|
|
7
7
|
Project-URL: Issues, https://github.com/vladsafedev/playmaker/issues
|
|
8
8
|
Author-email: Vladislav Shulyugin <vladislav.shulyugin@gmail.com>
|
|
9
9
|
License-Expression: MIT
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Keywords: agents,ai,antigravity,claude,claude-code,cli,codex,gemini,orchestration,subagents
|
|
11
|
+
Keywords: agents,ai,antigravity,claude,claude-code,cli,codex,gemini,glm,opencode,orchestration,subagents
|
|
12
12
|
Classifier: Development Status :: 3 - Alpha
|
|
13
13
|
Classifier: Environment :: Console
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
@@ -28,11 +28,11 @@ Description-Content-Type: text/markdown
|
|
|
28
28
|
# playmaker
|
|
29
29
|
|
|
30
30
|
[](https://github.com/vladsafedev/playmaker/actions/workflows/ci.yml)
|
|
31
|
-
[](https://pypi.org/project/playmaker-cli/)
|
|
32
|
-
[](https://pypi.org/project/playmaker-cli/)
|
|
31
|
+
[](https://pypi.org/project/playmaker-cli/)
|
|
32
|
+
[](https://pypi.org/project/playmaker-cli/)
|
|
33
33
|
[](LICENSE)
|
|
34
34
|
|
|
35
|
-
**Run Claude Code, Codex and
|
|
35
|
+
**Run Claude Code, Codex, Antigravity and opencode as parallel sub-agents from one terminal — and spend separate quotas instead of one.**
|
|
36
36
|
|
|
37
37
|
You stay in your Claude Code session doing the part only you can do. `playmaker`
|
|
38
38
|
fans the rest out to other agent CLIs as detached processes, tracks them,
|
|
@@ -41,9 +41,9 @@ parses their native session files, and pings you when they land.
|
|
|
41
41
|
```console
|
|
42
42
|
$ B=dashboard # one label for the whole fan-out
|
|
43
43
|
|
|
44
|
-
$ playmaker dispatch codex --batch $B
|
|
44
|
+
$ playmaker dispatch codex --batch $B -p "Add PATCH /users/:id …"
|
|
45
45
|
session: 9f2c1a4e-… pid: 48211 (detached)
|
|
46
|
-
$ playmaker dispatch agy --batch $B --model
|
|
46
|
+
$ playmaker dispatch agy --batch $B --model gemini-3.6-flash-high -p "pytest coverage for …"
|
|
47
47
|
session: 4b1f9c02-… pid: 48219 (detached)
|
|
48
48
|
$ playmaker dispatch claude --batch $B --model sonnet -p "Update the API docs for …"
|
|
49
49
|
session: c07d5511-… pid: 48244 (detached)
|
|
@@ -74,10 +74,12 @@ in one serial session:
|
|
|
74
74
|
1. **Wall-clock speed.** A task that decomposes into 3–5 independent
|
|
75
75
|
work-streams (schema, backend, frontend, tests, docs) finishes 2–4× faster
|
|
76
76
|
when each stream runs as its own parallel agent.
|
|
77
|
-
2. **Provider arbitrage.** Codex and
|
|
78
|
-
pools from your Anthropic plan. Every slice you hand them is
|
|
79
|
-
main session never spends — and Antigravity's roster includes
|
|
80
|
-
Sonnet/Opus, so even Claude-quality work can run on Google's pool.
|
|
77
|
+
2. **Provider arbitrage.** Codex, Antigravity and opencode quotas are entirely
|
|
78
|
+
separate pools from your Anthropic plan. Every slice you hand them is
|
|
79
|
+
capacity your main session never spends — and Antigravity's roster includes
|
|
80
|
+
Claude Sonnet/Opus, so even Claude-quality work can run on Google's pool.
|
|
81
|
+
`opencode` widens this the most: one CLI fronting ~75 providers, from a z.ai
|
|
82
|
+
GLM coding plan to models running locally on your own machine.
|
|
81
83
|
3. **Bucket arbitrage inside one plan.** Headless `claude -p` draws on the same
|
|
82
84
|
subscription as your interactive session, but per-model weekly buckets are
|
|
83
85
|
separate — dispatching `--model sonnet` spends Sonnet's usually-idle bucket
|
|
@@ -134,6 +136,16 @@ The other agents differ, because their CLIs do:
|
|
|
134
136
|
either auto-approves or comes back having done nothing. It therefore
|
|
135
137
|
defaults to `yolo = true`; layer `sandbox = true` on top for agy's own
|
|
136
138
|
terminal restrictions.
|
|
139
|
+
- **opencode** is the same story: its only lever is `--auto`, so it also
|
|
140
|
+
defaults to `yolo = true`. The granular control lives in opencode's own
|
|
141
|
+
config rather than in playmaker — and `--auto` still honours it, because it
|
|
142
|
+
auto-approves only what you have not explicitly denied:
|
|
143
|
+
|
|
144
|
+
```jsonc
|
|
145
|
+
// ~/.config/opencode/opencode.json
|
|
146
|
+
{ "permission": { "edit": "allow", "bash": "allow", "webfetch": "deny" } }
|
|
147
|
+
```
|
|
148
|
+
|
|
137
149
|
- **gemini** (legacy) runs with `--yolo`.
|
|
138
150
|
|
|
139
151
|
## Install
|
|
@@ -168,8 +180,9 @@ playmaker agents # which agent CLIs are reachable
|
|
|
168
180
|
| Agent | Install | Notes |
|
|
169
181
|
|---|---|---|
|
|
170
182
|
| **Claude Code** | `npm i -g @anthropic-ai/claude-code` | `--model sonnet` / `opus` / `haiku` |
|
|
171
|
-
| **Codex CLI** | `npm i -g @openai/codex` | `--model
|
|
172
|
-
| **Antigravity (`agy`)** | bundled with [Antigravity](https://antigravity.google) |
|
|
183
|
+
| **Codex CLI** | `npm i -g @openai/codex` | the model roster depends on your plan; omit `--model` to use the account default |
|
|
184
|
+
| **Antigravity (`agy`)** | bundled with [Antigravity](https://antigravity.google) | `--model claude-opus-4-6-thinking` — the roster moves, so read it from `agy models` |
|
|
185
|
+
| **opencode** | `brew install sst/tap/opencode` (or see [opencode.ai](https://opencode.ai)) | `--model provider/model`, e.g. `zai-coding-plan/glm-5.2`; roster from `opencode models`, providers from `opencode auth login` |
|
|
173
186
|
| **Gemini CLI** (legacy) | `npm i -g @google/gemini-cli` | still supported, superseded by `agy` |
|
|
174
187
|
|
|
175
188
|
At least one is required; `playmaker agents` tells you which it can see.
|
|
@@ -233,9 +246,11 @@ flowchart LR
|
|
|
233
246
|
P --> A1["claude -p<br/>--model sonnet"]
|
|
234
247
|
P --> A2["codex exec"]
|
|
235
248
|
P --> A3["agy -p"]
|
|
249
|
+
P --> A4["opencode run<br/>-m zai-coding-plan/glm-5.2"]
|
|
236
250
|
A1 --> S[("state.db<br/>outputs/ + logs/")]
|
|
237
251
|
A2 --> S
|
|
238
252
|
A3 --> S
|
|
253
|
+
A4 --> S
|
|
239
254
|
S -->|"list / thread / summary"| C
|
|
240
255
|
S -.->|"batch drained"| N["one ping"]
|
|
241
256
|
```
|
|
@@ -250,6 +265,7 @@ bookkeeping in between.
|
|
|
250
265
|
├── agents/ optional agent profile markdown (claude.md, codex.md, agy.md…)
|
|
251
266
|
├── outputs/ final output per session — .md, or .json if the agent returned JSON
|
|
252
267
|
├── logs/ subprocess stdout for detached runs
|
|
268
|
+
├── opencode/ pointer per opencode session (its transcript lives in SQLite)
|
|
253
269
|
└── quotas.json latest capacity snapshot
|
|
254
270
|
```
|
|
255
271
|
|
|
@@ -261,6 +277,7 @@ and locates the session file the tool writes locally. Empirically:
|
|
|
261
277
|
| Claude | `~/.claude/projects/<cwd-with-slashes-as-dashes>/<id>.jsonl` |
|
|
262
278
|
| Codex | `~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-<ts>-<thread_id>.jsonl` |
|
|
263
279
|
| Antigravity | `~/.gemini/antigravity-cli/brain/<conversation-id>/.system_generated/logs/transcript_full.jsonl` |
|
|
280
|
+
| opencode | SQLite — `~/.local/share/opencode/opencode.db` (`session` / `message` / `part`); playmaker keeps a pointer at `~/.playmaker/opencode/<id>.session` |
|
|
264
281
|
| Gemini | `~/.gemini/tmp/<cwd-basename>/chats/session-<ts>-<short_id>.{json,jsonl}` |
|
|
265
282
|
|
|
266
283
|
`thread` and `summary` normalize all of them into the same turn list, so every
|
|
@@ -276,6 +293,21 @@ dispatch; and a wrong `--model` is a silent failure on both **codex** (reports
|
|
|
276
293
|
`turn.failed` while exiting 0) and **agy** (runs its default model instead) —
|
|
277
294
|
playmaker turns both into real errors.
|
|
278
295
|
|
|
296
|
+
**opencode** deserves its own note, because one CLI is many providers. Models
|
|
297
|
+
are `provider/model` strings from `opencode models`, and if you don't pass
|
|
298
|
+
`--model` opencode falls back to the default in *its* config — often whatever
|
|
299
|
+
you last picked interactively. Set the lane's default once:
|
|
300
|
+
|
|
301
|
+
```toml
|
|
302
|
+
[agents.opencode]
|
|
303
|
+
model = "zai-coding-plan/glm-5.2"
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
It also has agy's working-directory problem in a different costume: opencode
|
|
307
|
+
reads `process.env.PWD`, which a subprocess `cwd` does not update, so left
|
|
308
|
+
alone it would ignore `--cwd` and write into the directory *you* were standing
|
|
309
|
+
in. playmaker passes `--dir` and fixes up `PWD`, so `--cwd` means what it says.
|
|
310
|
+
|
|
279
311
|
## Notifications
|
|
280
312
|
|
|
281
313
|
Every detached dispatch pings when it finishes. With
|
|
@@ -321,11 +353,16 @@ Antigravity (agy)
|
|
|
321
353
|
Gemini weekly ███████████████████░ 95% left
|
|
322
354
|
Claude/GPT 5h ██████████████████░░ 90% left resets in 2h 05m
|
|
323
355
|
Claude/GPT weekly ██████████████░░░░░░ 70% left resets in 5d 1h
|
|
356
|
+
|
|
357
|
+
Z.ai (GLM, via opencode) Max
|
|
358
|
+
Session ████████████████████ 100% left
|
|
359
|
+
Weekly ███████████████████░ 95% left resets in 1d 11h
|
|
360
|
+
MCP tools ███████████████████░ 99% left resets in 25d 11h
|
|
324
361
|
```
|
|
325
362
|
|
|
326
363
|
The `Weekly` and `Sonnet` rows above are the point: they are **separate
|
|
327
|
-
buckets**. So is every agy row
|
|
328
|
-
spend.
|
|
364
|
+
buckets**. So is every agy row, and so is the whole Z.ai block. Routing a
|
|
365
|
+
subtask is choosing which of them to spend.
|
|
329
366
|
|
|
330
367
|
- **Claude** — OAuth usage API; token from the Claude Code Keychain entry.
|
|
331
368
|
- **Codex** — ChatGPT `wham/usage` API; token from `~/.codex/auth.json`.
|
|
@@ -336,6 +373,12 @@ spend.
|
|
|
336
373
|
`retrieveUserQuota` on the Antigravity backend, which surfaces only coarse
|
|
337
374
|
Gemini buckets and is flagged *daemon offline*. Approach ported from
|
|
338
375
|
[steipete/CodexBar](https://github.com/steipete/CodexBar).
|
|
376
|
+
- **Z.ai** — GLM Coding Plan usage API; key from opencode's
|
|
377
|
+
`~/.local/share/opencode/auth.json` (or `$ZAI_API_KEY`). Reported as its own
|
|
378
|
+
provider because the quota belongs to the plan, not to opencode — an opencode
|
|
379
|
+
lane pointed at a local model spends nothing here. Shows *unsupported* rather
|
|
380
|
+
than an error when no Z.ai credential exists. `MCP tools` is the monthly
|
|
381
|
+
web-search/reader pool, not inference.
|
|
339
382
|
|
|
340
383
|
Reading these at *model* granularity is the point: they are the load-balancing
|
|
341
384
|
input the coach skill uses to route each subtask.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# playmaker
|
|
2
2
|
|
|
3
3
|
[](https://github.com/vladsafedev/playmaker/actions/workflows/ci.yml)
|
|
4
|
-
[](https://pypi.org/project/playmaker-cli/)
|
|
5
|
-
[](https://pypi.org/project/playmaker-cli/)
|
|
4
|
+
[](https://pypi.org/project/playmaker-cli/)
|
|
5
|
+
[](https://pypi.org/project/playmaker-cli/)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
**Run Claude Code, Codex and
|
|
8
|
+
**Run Claude Code, Codex, Antigravity and opencode as parallel sub-agents from one terminal — and spend separate quotas instead of one.**
|
|
9
9
|
|
|
10
10
|
You stay in your Claude Code session doing the part only you can do. `playmaker`
|
|
11
11
|
fans the rest out to other agent CLIs as detached processes, tracks them,
|
|
@@ -14,9 +14,9 @@ parses their native session files, and pings you when they land.
|
|
|
14
14
|
```console
|
|
15
15
|
$ B=dashboard # one label for the whole fan-out
|
|
16
16
|
|
|
17
|
-
$ playmaker dispatch codex --batch $B
|
|
17
|
+
$ playmaker dispatch codex --batch $B -p "Add PATCH /users/:id …"
|
|
18
18
|
session: 9f2c1a4e-… pid: 48211 (detached)
|
|
19
|
-
$ playmaker dispatch agy --batch $B --model
|
|
19
|
+
$ playmaker dispatch agy --batch $B --model gemini-3.6-flash-high -p "pytest coverage for …"
|
|
20
20
|
session: 4b1f9c02-… pid: 48219 (detached)
|
|
21
21
|
$ playmaker dispatch claude --batch $B --model sonnet -p "Update the API docs for …"
|
|
22
22
|
session: c07d5511-… pid: 48244 (detached)
|
|
@@ -47,10 +47,12 @@ in one serial session:
|
|
|
47
47
|
1. **Wall-clock speed.** A task that decomposes into 3–5 independent
|
|
48
48
|
work-streams (schema, backend, frontend, tests, docs) finishes 2–4× faster
|
|
49
49
|
when each stream runs as its own parallel agent.
|
|
50
|
-
2. **Provider arbitrage.** Codex and
|
|
51
|
-
pools from your Anthropic plan. Every slice you hand them is
|
|
52
|
-
main session never spends — and Antigravity's roster includes
|
|
53
|
-
Sonnet/Opus, so even Claude-quality work can run on Google's pool.
|
|
50
|
+
2. **Provider arbitrage.** Codex, Antigravity and opencode quotas are entirely
|
|
51
|
+
separate pools from your Anthropic plan. Every slice you hand them is
|
|
52
|
+
capacity your main session never spends — and Antigravity's roster includes
|
|
53
|
+
Claude Sonnet/Opus, so even Claude-quality work can run on Google's pool.
|
|
54
|
+
`opencode` widens this the most: one CLI fronting ~75 providers, from a z.ai
|
|
55
|
+
GLM coding plan to models running locally on your own machine.
|
|
54
56
|
3. **Bucket arbitrage inside one plan.** Headless `claude -p` draws on the same
|
|
55
57
|
subscription as your interactive session, but per-model weekly buckets are
|
|
56
58
|
separate — dispatching `--model sonnet` spends Sonnet's usually-idle bucket
|
|
@@ -107,6 +109,16 @@ The other agents differ, because their CLIs do:
|
|
|
107
109
|
either auto-approves or comes back having done nothing. It therefore
|
|
108
110
|
defaults to `yolo = true`; layer `sandbox = true` on top for agy's own
|
|
109
111
|
terminal restrictions.
|
|
112
|
+
- **opencode** is the same story: its only lever is `--auto`, so it also
|
|
113
|
+
defaults to `yolo = true`. The granular control lives in opencode's own
|
|
114
|
+
config rather than in playmaker — and `--auto` still honours it, because it
|
|
115
|
+
auto-approves only what you have not explicitly denied:
|
|
116
|
+
|
|
117
|
+
```jsonc
|
|
118
|
+
// ~/.config/opencode/opencode.json
|
|
119
|
+
{ "permission": { "edit": "allow", "bash": "allow", "webfetch": "deny" } }
|
|
120
|
+
```
|
|
121
|
+
|
|
110
122
|
- **gemini** (legacy) runs with `--yolo`.
|
|
111
123
|
|
|
112
124
|
## Install
|
|
@@ -141,8 +153,9 @@ playmaker agents # which agent CLIs are reachable
|
|
|
141
153
|
| Agent | Install | Notes |
|
|
142
154
|
|---|---|---|
|
|
143
155
|
| **Claude Code** | `npm i -g @anthropic-ai/claude-code` | `--model sonnet` / `opus` / `haiku` |
|
|
144
|
-
| **Codex CLI** | `npm i -g @openai/codex` | `--model
|
|
145
|
-
| **Antigravity (`agy`)** | bundled with [Antigravity](https://antigravity.google) |
|
|
156
|
+
| **Codex CLI** | `npm i -g @openai/codex` | the model roster depends on your plan; omit `--model` to use the account default |
|
|
157
|
+
| **Antigravity (`agy`)** | bundled with [Antigravity](https://antigravity.google) | `--model claude-opus-4-6-thinking` — the roster moves, so read it from `agy models` |
|
|
158
|
+
| **opencode** | `brew install sst/tap/opencode` (or see [opencode.ai](https://opencode.ai)) | `--model provider/model`, e.g. `zai-coding-plan/glm-5.2`; roster from `opencode models`, providers from `opencode auth login` |
|
|
146
159
|
| **Gemini CLI** (legacy) | `npm i -g @google/gemini-cli` | still supported, superseded by `agy` |
|
|
147
160
|
|
|
148
161
|
At least one is required; `playmaker agents` tells you which it can see.
|
|
@@ -206,9 +219,11 @@ flowchart LR
|
|
|
206
219
|
P --> A1["claude -p<br/>--model sonnet"]
|
|
207
220
|
P --> A2["codex exec"]
|
|
208
221
|
P --> A3["agy -p"]
|
|
222
|
+
P --> A4["opencode run<br/>-m zai-coding-plan/glm-5.2"]
|
|
209
223
|
A1 --> S[("state.db<br/>outputs/ + logs/")]
|
|
210
224
|
A2 --> S
|
|
211
225
|
A3 --> S
|
|
226
|
+
A4 --> S
|
|
212
227
|
S -->|"list / thread / summary"| C
|
|
213
228
|
S -.->|"batch drained"| N["one ping"]
|
|
214
229
|
```
|
|
@@ -223,6 +238,7 @@ bookkeeping in between.
|
|
|
223
238
|
├── agents/ optional agent profile markdown (claude.md, codex.md, agy.md…)
|
|
224
239
|
├── outputs/ final output per session — .md, or .json if the agent returned JSON
|
|
225
240
|
├── logs/ subprocess stdout for detached runs
|
|
241
|
+
├── opencode/ pointer per opencode session (its transcript lives in SQLite)
|
|
226
242
|
└── quotas.json latest capacity snapshot
|
|
227
243
|
```
|
|
228
244
|
|
|
@@ -234,6 +250,7 @@ and locates the session file the tool writes locally. Empirically:
|
|
|
234
250
|
| Claude | `~/.claude/projects/<cwd-with-slashes-as-dashes>/<id>.jsonl` |
|
|
235
251
|
| Codex | `~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-<ts>-<thread_id>.jsonl` |
|
|
236
252
|
| Antigravity | `~/.gemini/antigravity-cli/brain/<conversation-id>/.system_generated/logs/transcript_full.jsonl` |
|
|
253
|
+
| opencode | SQLite — `~/.local/share/opencode/opencode.db` (`session` / `message` / `part`); playmaker keeps a pointer at `~/.playmaker/opencode/<id>.session` |
|
|
237
254
|
| Gemini | `~/.gemini/tmp/<cwd-basename>/chats/session-<ts>-<short_id>.{json,jsonl}` |
|
|
238
255
|
|
|
239
256
|
`thread` and `summary` normalize all of them into the same turn list, so every
|
|
@@ -249,6 +266,21 @@ dispatch; and a wrong `--model` is a silent failure on both **codex** (reports
|
|
|
249
266
|
`turn.failed` while exiting 0) and **agy** (runs its default model instead) —
|
|
250
267
|
playmaker turns both into real errors.
|
|
251
268
|
|
|
269
|
+
**opencode** deserves its own note, because one CLI is many providers. Models
|
|
270
|
+
are `provider/model` strings from `opencode models`, and if you don't pass
|
|
271
|
+
`--model` opencode falls back to the default in *its* config — often whatever
|
|
272
|
+
you last picked interactively. Set the lane's default once:
|
|
273
|
+
|
|
274
|
+
```toml
|
|
275
|
+
[agents.opencode]
|
|
276
|
+
model = "zai-coding-plan/glm-5.2"
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
It also has agy's working-directory problem in a different costume: opencode
|
|
280
|
+
reads `process.env.PWD`, which a subprocess `cwd` does not update, so left
|
|
281
|
+
alone it would ignore `--cwd` and write into the directory *you* were standing
|
|
282
|
+
in. playmaker passes `--dir` and fixes up `PWD`, so `--cwd` means what it says.
|
|
283
|
+
|
|
252
284
|
## Notifications
|
|
253
285
|
|
|
254
286
|
Every detached dispatch pings when it finishes. With
|
|
@@ -294,11 +326,16 @@ Antigravity (agy)
|
|
|
294
326
|
Gemini weekly ███████████████████░ 95% left
|
|
295
327
|
Claude/GPT 5h ██████████████████░░ 90% left resets in 2h 05m
|
|
296
328
|
Claude/GPT weekly ██████████████░░░░░░ 70% left resets in 5d 1h
|
|
329
|
+
|
|
330
|
+
Z.ai (GLM, via opencode) Max
|
|
331
|
+
Session ████████████████████ 100% left
|
|
332
|
+
Weekly ███████████████████░ 95% left resets in 1d 11h
|
|
333
|
+
MCP tools ███████████████████░ 99% left resets in 25d 11h
|
|
297
334
|
```
|
|
298
335
|
|
|
299
336
|
The `Weekly` and `Sonnet` rows above are the point: they are **separate
|
|
300
|
-
buckets**. So is every agy row
|
|
301
|
-
spend.
|
|
337
|
+
buckets**. So is every agy row, and so is the whole Z.ai block. Routing a
|
|
338
|
+
subtask is choosing which of them to spend.
|
|
302
339
|
|
|
303
340
|
- **Claude** — OAuth usage API; token from the Claude Code Keychain entry.
|
|
304
341
|
- **Codex** — ChatGPT `wham/usage` API; token from `~/.codex/auth.json`.
|
|
@@ -309,6 +346,12 @@ spend.
|
|
|
309
346
|
`retrieveUserQuota` on the Antigravity backend, which surfaces only coarse
|
|
310
347
|
Gemini buckets and is flagged *daemon offline*. Approach ported from
|
|
311
348
|
[steipete/CodexBar](https://github.com/steipete/CodexBar).
|
|
349
|
+
- **Z.ai** — GLM Coding Plan usage API; key from opencode's
|
|
350
|
+
`~/.local/share/opencode/auth.json` (or `$ZAI_API_KEY`). Reported as its own
|
|
351
|
+
provider because the quota belongs to the plan, not to opencode — an opencode
|
|
352
|
+
lane pointed at a local model spends nothing here. Shows *unsupported* rather
|
|
353
|
+
than an error when no Z.ai credential exists. `MCP tools` is the monthly
|
|
354
|
+
web-search/reader pool, not inference.
|
|
312
355
|
|
|
313
356
|
Reading these at *model* granularity is the point: they are the load-balancing
|
|
314
357
|
input the coach skill uses to route each subtask.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "playmaker-cli"
|
|
3
|
-
version = "0.
|
|
4
|
-
description = "Playing-coach CLI for orchestrating Claude Code, Codex and
|
|
3
|
+
version = "0.6.0"
|
|
4
|
+
description = "Playing-coach CLI for orchestrating Claude Code, Codex, Antigravity and opencode sub-agents in parallel."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
7
7
|
license = "MIT"
|
|
@@ -19,6 +19,8 @@ keywords = [
|
|
|
19
19
|
"codex",
|
|
20
20
|
"antigravity",
|
|
21
21
|
"gemini",
|
|
22
|
+
"opencode",
|
|
23
|
+
"glm",
|
|
22
24
|
"subagents",
|
|
23
25
|
]
|
|
24
26
|
classifiers = [
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: playmaker-coach
|
|
3
|
-
description: Playing-coach orchestration of Claude/Codex/Antigravity (agy) sub-agents via the `playmaker` CLI and in-session Task sub-agents. Triggered when the user gives a complex multi-component task where decomposition gives >2x parallel speedup (e.g. "build admin dashboard with schema, backend, FE, tests, docs"). NOT triggered for single-file refactor, single bug fix, single component, or simple Q&A — those stay in this thread without delegation.
|
|
3
|
+
description: Playing-coach orchestration of Claude/Codex/Antigravity (agy)/opencode sub-agents via the `playmaker` CLI and in-session Task sub-agents. Triggered when the user gives a complex multi-component task where decomposition gives >2x parallel speedup (e.g. "build admin dashboard with schema, backend, FE, tests, docs"). NOT triggered for single-file refactor, single bug fix, single component, or simple Q&A — those stay in this thread without delegation.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# playmaker-coach — playing-coach orchestration
|
|
7
7
|
|
|
8
|
-
Use the `playmaker` CLI as a facade to dispatch sub-tasks to Codex / Antigravity (`agy`) / a sibling Claude, monitor them, read their threads, review their diffs, and feed back. The coach (this thread) does its own portion of the work in parallel.
|
|
8
|
+
Use the `playmaker` CLI as a facade to dispatch sub-tasks to Codex / Antigravity (`agy`) / opencode / a sibling Claude, monitor them, read their threads, review their diffs, and feed back. The coach (this thread) does its own portion of the work in parallel.
|
|
9
9
|
|
|
10
|
-
> **`agy` (Antigravity CLI)** does not only serve Google models:
|
|
10
|
+
> **`agy` (Antigravity CLI)** does not only serve Google models: alongside the Gemini Flash and Pro tiers, `agy models` carries **Claude Sonnet and Opus** and a **GPT-OSS** mid-tier. Opus via agy runs on *Google's* quota pool — top-tier Claude work that does not touch the Anthropic subscription's scarce Opus weekly bucket: `--model claude-opus-4-6-thinking`.
|
|
11
|
+
>
|
|
12
|
+
> **Never write an agy model name from memory — run `agy models` and copy a line.** Both the roster *and its spelling* move with Antigravity releases: names used to be quoted display strings like `"Claude Opus 4.6 (Thinking)"` and are now bare slugs. playmaker validates `--model` against the live roster and fails the dispatch on a stale name, so a wrong guess costs you a round-trip.
|
|
11
13
|
|
|
12
14
|
**The point of the coach pattern:** all available models do useful work in parallel under your direction. The coach's job is *orchestration*, not *production*. A coach that does its own implementation, runs its own codebase recon, and reviews everything line by line burns the same budget delegation was meant to save. Treat your own context window as the most expensive resource on the table — every byte you read or generate yourself is a byte that could have come from a cheaper model. Push out as much as you can: implementation, recon, summarization, even drafting the per-subtask prompts when the task is large enough.
|
|
13
15
|
|
|
@@ -21,7 +23,7 @@ All Claude work — coach, internal sub-agents, external `claude -p` — draws f
|
|
|
21
23
|
|
|
22
24
|
3. **External dispatch — `playmaker dispatch <agent>`.** Separate OS processes, tracked in playmaker (`list`/`watch`/`thread`/`continue`):
|
|
23
25
|
- **`claude -p` (sibling Claude):** same subscription. Its key lever is the model bucket — **Sonnet is a separate weekly bucket from Opus**, usually idle while Opus depletes, so default **`--model sonnet`** to spare the scarce Opus bucket (**`--model haiku`** for trivial mechanical work). It **can write files** — playmaker runs it in `acceptEdits`, so it edits and runs commands freely inside `--cwd` and is refused outside it (see §10). Use it over an internal sub-agent when you want a **tracked, detached work-stream** you can monitor/continue independently of the coach's turn.
|
|
24
|
-
- **`codex` / `agy`:** each on its own subscription/quota — the right home for **write-heavy** parallel implementation that can leave the Anthropic subscription. `agy` is special: besides Gemini tiers it carries **Claude Sonnet/Opus 4.6 (Thinking)** on Google's pool, so even "must be Claude-quality" work can leave the Anthropic quota.
|
|
26
|
+
- **`codex` / `agy` / `opencode`:** each on its own subscription/quota — the right home for **write-heavy** parallel implementation that can leave the Anthropic subscription. `agy` is special: besides Gemini tiers it carries **Claude Sonnet/Opus 4.6 (Thinking)** on Google's pool, so even "must be Claude-quality" work can leave the Anthropic quota. `opencode` is the widest lane: one CLI over ~75 providers, addressed as `provider/model` — a GLM coding plan (`zai-coding-plan/glm-5.2`), or a model running locally on this machine, which spends **no** subscription quota at all.
|
|
25
27
|
|
|
26
28
|
**Routing cheat-sheet for Claude-side work:**
|
|
27
29
|
|
|
@@ -30,8 +32,10 @@ All Claude work — coach, internal sub-agents, external `claude -p` — draws f
|
|
|
30
32
|
| writes files and the coach integrates the result directly | **internal sub-agent** (Task tool) | in-session, write-capable, returns into context |
|
|
31
33
|
| is an independent stream you'll monitor / continue separately | **external `dispatch claude --model sonnet`** | tracked & detached; Sonnet's own weekly bucket spares Opus |
|
|
32
34
|
| is heavy reasoning only the coach can do | **coach** | top-tier Opus, serial |
|
|
33
|
-
| is write-heavy and can leave Claude | **codex / agy** | their own quotas |
|
|
34
|
-
| needs top-tier Claude but the Anthropic Opus weekly is precious | **`dispatch agy --model
|
|
35
|
+
| is write-heavy and can leave Claude | **codex / agy / opencode** | their own quotas |
|
|
36
|
+
| needs top-tier Claude but the Anthropic Opus weekly is precious | **`dispatch agy --model claude-opus-4-6-thinking`** | Opus quality on Google's pool |
|
|
37
|
+
| is bulk work and every subscription is running low | **`dispatch opencode --model zai-coding-plan/glm-5.2`** | a separate GLM plan, untouched by the others |
|
|
38
|
+
| is mechanical and privacy-sensitive, or all quotas are spent | **`dispatch opencode --model <local provider>/<model>`** | runs on this machine; costs no quota, just wall-clock |
|
|
35
39
|
|
|
36
40
|
**Sonnet is your cheap parallel Claude worker** — a separate weekly bucket that usually sits idle while Opus depletes. Reach for it (via `dispatch claude --model sonnet`, or by pointing an internal sub-agent at Sonnet) instead of burning Opus on mid-tier work.
|
|
37
41
|
|
|
@@ -59,6 +63,7 @@ playmaker quotas --refresh # current capacity, broken out per model
|
|
|
59
63
|
- Claude: two non-coach ways to run it — an **internal sub-agent** (Task tool; in-session, write-capable, result returns to the coach) and an **external `claude -p` dispatch** (tracked, detached stream). Both draw on the subscription; the difference is where results land, not cost. See "Execution lanes". Default external Claude to `--model sonnet` — its weekly bucket is separate from Opus and usually idle, so it spares the scarce coach (Opus) bucket.
|
|
60
64
|
- Antigravity (`agy`): one Google pool split across model families — Gemini Flash tiers for cheap bulk work, Gemini 3.1 Pro for hard Gemini work, **Claude Sonnet/Opus 4.6 (Thinking)** as Anthropic-quality capacity that spends *Google's* quota, GPT-OSS 120B as a spare mid-tier. `playmaker quotas` shows the **full categorized breakdown** — `Gemini 5h` / `Gemini weekly` and `Claude/GPT 5h` / `Claude/GPT weekly`. Two things share a bucket: all Gemini models draw the Gemini bucket, and Claude *and* GPT-OSS share the Claude/GPT bucket. So dispatching Opus 4.6 via agy spends the same `Claude/GPT` bucket as Sonnet or GPT-OSS — watch the `Claude/GPT 5h` window when fanning out several agy-Claude jobs. (This needs agy's local daemon up — normally true when any agy process is running; if `playmaker quotas` tags agy "daemon offline" it fell back to a coarse Gemini-only view.)
|
|
61
65
|
- Codex: top-tier vs lighter modes (where applicable).
|
|
66
|
+
- Z.ai (GLM): shown as its own provider because the plan is what has the quota, not the CLI — `Session` (5h) and `Weekly` windows plus a monthly `MCP tools` pool that only web-search/reader calls touch. It appears whenever `opencode auth login` has a Z.AI credential, and reads *unsupported* when it doesn't. An `opencode` dispatch pointed at a **local** model spends none of it, so local lanes never show up in this table at all.
|
|
62
67
|
|
|
63
68
|
If `quotas.json` is more than 1h old (or shows errors), say so before relying on the numbers.
|
|
64
69
|
|
|
@@ -69,7 +74,7 @@ Codebase exploration ("find where the User entity lives, list its existing field
|
|
|
69
74
|
Pattern: dispatch a recon subtask with an explicit deliverable.
|
|
70
75
|
|
|
71
76
|
```bash
|
|
72
|
-
playmaker dispatch agy --model
|
|
77
|
+
playmaker dispatch agy --model gemini-3.6-flash-low --cwd $(pwd) --sync \
|
|
73
78
|
--prompt "Recon only — do not edit any files. In apps/backend/, locate: (a) the User entity/schema and the migration tooling used (Prisma vs TypeORM vs other), (b) the auth middleware that resolves the current user, (c) where DTOs are defined for user PATCH endpoints if any. Report under 200 words as a numbered list with file paths and line ranges."
|
|
74
79
|
```
|
|
75
80
|
|
|
@@ -89,9 +94,9 @@ Break the task into 2-5 subtasks (don't go finer-grained than that on first run
|
|
|
89
94
|
|
|
90
95
|
1. Sort *models* (not agents) by remaining capacity — freshest at the top. A provider with one fresh model and one depleted model is two separate buckets.
|
|
91
96
|
2. **Tier-match each subtask to the cheapest model that can finish it cleanly:**
|
|
92
|
-
- **Architectural / spec judgment / cross-module integration:** top tier (Opus, agy
|
|
93
|
-
- **Pattern-following implementation, well-scoped CRUD, mechanical refactor, test scaffolding, writing inside an existing convention:** mid tier (Claude Sonnet, agy
|
|
94
|
-
- **Recon, summarization, mechanical loops over many files, name normalization:** cheap tier (agy
|
|
97
|
+
- **Architectural / spec judgment / cross-module integration:** top tier (Opus, agy `claude-opus-4-6-thinking` / `gemini-3.1-pro-high`, Codex top-tier). The coach lives here; agy-Opus is the overflow lane when the Anthropic Opus weekly is precious.
|
|
98
|
+
- **Pattern-following implementation, well-scoped CRUD, mechanical refactor, test scaffolding, writing inside an existing convention:** mid tier (Claude Sonnet, agy `claude-sonnet-4-6` / `gemini-3.5-flash-high` / `gemini-3.1-pro-low`, mid-tier Codex). This is where the bulk of delegated implementation goes.
|
|
99
|
+
- **Recon, summarization, mechanical loops over many files, name normalization:** cheap tier (agy's lowest Flash tiers, **Claude Haiku**, Sonnet for recon-with-judgment).
|
|
95
100
|
|
|
96
101
|
For Claude specifically, tier is orthogonal to **lane** (see "Execution lanes"): pick the model tier here, then decide *internal sub-agent* (coach integrates the result) vs *external `-p`* (tracked detached stream).
|
|
97
102
|
3. Pass the model explicitly: `playmaker dispatch <agent> --model <name> ...`. Without `--model`, the agent CLI uses its default — which is usually fine but means the coach gives up control over tier-matching. **For sibling Claude, default to `--model sonnet`** (Haiku for trivial mechanical work); never omit it and let the CLI pick Opus — that burns the scarce shared Opus weekly bucket.
|
|
@@ -112,7 +117,7 @@ To make a subtask finishable, every dispatch must carry:
|
|
|
112
117
|
2. **Acceptance criteria as a check the agent runs itself.** A green command — `npx prisma validate`, `pnpm test users.spec.ts`, `tsc --noEmit`, an `eslint` pass on a specific file. The agent is told to keep iterating until that command exits 0 and to surface its output in the final answer. This replaces coach-side review for ~80% of the work.
|
|
113
118
|
3. **Done definition in one sentence**, written so the coach can confirm it in seconds without reading the diff line by line. "Column added, migration generated, prisma validate green." If the coach can't write such a sentence, the subtask isn't sized right yet — split or specify further before dispatching.
|
|
114
119
|
4. **Context the agent needs but doesn't have.** Spec section excerpts, naming conventions, the one related file it should mirror. Paste these into the prompt; don't make the agent find them by reading half the repo. If your team keeps durable notes (a docs folder, a wiki, a notes vault), pass the *exact* paths worth reading rather than asking the agent to go looking.
|
|
115
|
-
5. **Match to capability.** Codex / agy-Gemini do well on pattern-following, well-scoped CRUD, test scaffolding, mechanical refactors, and writing within an existing convention. They do poorly on architectural decisions across files they haven't been pointed at, novel API design, and judging whether a spec rule applies. Keep those for the coach — or for agy's
|
|
120
|
+
5. **Match to capability.** Codex / agy-Gemini do well on pattern-following, well-scoped CRUD, test scaffolding, mechanical refactors, and writing within an existing convention. They do poorly on architectural decisions across files they haven't been pointed at, novel API design, and judging whether a spec rule applies. Keep those for the coach — or for agy's `claude-opus-4-6-thinking` when the subtask genuinely needs top-tier judgment but should not burn the Anthropic Opus weekly. If a profile in `.playmaker/agents/<name>.md` exists, trust its guidance over these defaults.
|
|
116
121
|
|
|
117
122
|
A useful smell test before dispatching: *"If this came back done, would I review by running one command and reading one paragraph — or would I need to read the whole diff and think hard about whether it's right?"* If the latter, re-scope before sending.
|
|
118
123
|
|
|
@@ -121,7 +126,7 @@ Output the plan as a short proposal:
|
|
|
121
126
|
Plan:
|
|
122
127
|
- Coach (me): schema design + integration glue
|
|
123
128
|
- Codex: FastAPI handlers in apps/api/
|
|
124
|
-
- agy (
|
|
129
|
+
- agy (gemini-3.6-flash-high): pytest tests + README
|
|
125
130
|
|
|
126
131
|
Quotas: Claude session 93% / weekly 80%, Codex 100%,
|
|
127
132
|
agy Gemini 5h 100% / weekly 96%, Claude/GPT 5h 88% / weekly 71%.
|
|
@@ -151,7 +156,13 @@ playmaker dispatch <agent> --model <name> --prompt "<scoped prompt>" --cwd $(pwd
|
|
|
151
156
|
|
|
152
157
|
Always pass `--cwd $(pwd)` — `playmaker`'s default is the *coach process's* current dir, which is not always what you want.
|
|
153
158
|
|
|
154
|
-
Always pass `--model` when you've made a tier-matching decision in step 3. Without it, the agent CLI uses its own default (which may be its top-tier model, defeating the load-distribution effort). Model name is what the agent's native CLI accepts: `claude --model sonnet`, `
|
|
159
|
+
Always pass `--model` when you've made a tier-matching decision in step 3. Without it, the agent CLI uses its own default (which may be its top-tier model, defeating the load-distribution effort). Model name is what the agent's native CLI accepts: `claude --model sonnet`, `agy --model gemini-3.6-flash-high` — for agy, copy the line from `agy models` rather than typing it.
|
|
160
|
+
|
|
161
|
+
Two exceptions to "always pass `--model`":
|
|
162
|
+
- **codex** — its model roster depends on the account plan, and an unavailable name fails the whole dispatch (`codex turn failed: … not supported when using Codex with a ChatGPT account`). Omitting `--model` uses whatever that account actually has, which is usually what you want.
|
|
163
|
+
- **agy** — its own default is a top-tier model, so omitting `--model` on a dispatch meant to be cheap silently spends the expensive bucket. Always pass it here.
|
|
164
|
+
|
|
165
|
+
**opencode is `provider/model`, and the default is a trap.** Names look like `zai-coding-plan/glm-5.2` or `lmstudio/qwen/qwen3-coder-30b` — **run `opencode models` and copy a line** rather than writing one from memory; playmaker validates against that roster and fails the dispatch on a name it doesn't contain. Omitting `--model` does *not* fall back to something sensible: it uses whatever is set in the user's own `~/.config/opencode/opencode.json`, which is typically the last model they picked interactively — often a small local one. So for opencode, always pass `--model` unless `[agents.opencode] model` is already set in `~/.playmaker/config.toml`.
|
|
155
166
|
|
|
156
167
|
**agy prompt discipline:** the agy agent's shell lives in a private scratch directory, not the workspace. playmaker automatically prepends a workspace preamble to every agy dispatch, but reinforce it: word file instructions with paths relative to the workspace root or absolute paths, never "in the current directory".
|
|
157
168
|
|
|
@@ -163,8 +174,8 @@ Always pass `--model` when you've made a tier-matching decision in step 3. Witho
|
|
|
163
174
|
|
|
164
175
|
```bash
|
|
165
176
|
B=admin-dashboard # any short label shared across this fan-out
|
|
166
|
-
playmaker dispatch codex --batch "$B" --
|
|
167
|
-
playmaker dispatch agy --batch "$B" --model
|
|
177
|
+
playmaker dispatch codex --batch "$B" --prompt "..." --cwd $(pwd)
|
|
178
|
+
playmaker dispatch agy --batch "$B" --model gemini-3.6-flash-high --prompt "..." --cwd $(pwd)
|
|
168
179
|
```
|
|
169
180
|
|
|
170
181
|
`playmaker continue <id> --model <name>` overrides the model for one follow-up turn while keeping the live session; without `--model` it inherits the parent session's model.
|
|
@@ -173,7 +184,7 @@ For sequential delegation (e.g. "I'll do schema first, then Codex builds on top"
|
|
|
173
184
|
|
|
174
185
|
```bash
|
|
175
186
|
git commit -am "checkpoint: schema before backend dispatch"
|
|
176
|
-
playmaker dispatch codex --
|
|
187
|
+
playmaker dispatch codex --prompt "..." --cwd $(pwd) --sync # blocks, prints output
|
|
177
188
|
```
|
|
178
189
|
|
|
179
190
|
### 6. Coach's own work
|
|
@@ -224,7 +235,7 @@ If `playmaker dispatch` returns an error (binary missing, auth bad, agent unavai
|
|
|
224
235
|
Both Claude lanes are on the subscription, so pick by **where the work lives**, not cost:
|
|
225
236
|
- **Coach folds the result in directly → internal sub-agent (Task tool).** In-session, write-capable, returns into context. Default choice for "more Claude."
|
|
226
237
|
- **Independent stream you'll monitor / continue separately → `playmaker dispatch claude --model sonnet`.** Tracked, detached; Sonnet's separate weekly bucket spares Opus.
|
|
227
|
-
- **Work that can leave the Claude family → Codex / agy** (their own quotas).
|
|
238
|
+
- **Work that can leave the Claude family → Codex / agy / opencode** (their own quotas, or none at all for a local model).
|
|
228
239
|
|
|
229
240
|
If a dispatch comes back with zero file changes, check `playmaker summary <id>`. Two common causes for Claude: the subtask tried to write outside `--cwd` and was refused (re-dispatch with the right `--cwd`), or the run needed a permission the configured mode doesn't grant — a "I need your permission" answer, not a crash. For **agy** specifically, a "done" with no file changes usually means the files landed in agy's private scratch dir (`~/.gemini/antigravity-cli/scratch/`) — the prompt referred to "the current directory" instead of workspace paths; re-dispatch with explicit paths.
|
|
230
241
|
|
|
@@ -238,7 +249,7 @@ If a dispatch comes back with zero file changes, check `playmaker summary <id>`.
|
|
|
238
249
|
## Quota awareness
|
|
239
250
|
|
|
240
251
|
- **Read Claude quota at model granularity:** Sonnet weekly and Opus weekly are **independent buckets**. Coach and internal sub-agents on Opus spend the scarce one; Sonnet usually sits idle. Push mid-tier work to Sonnet (an internal sub-agent set to Sonnet, or `dispatch claude --model sonnet`) to spare Opus.
|
|
241
|
-
- Read quotas at *model* granularity, not *agent* granularity. For agy, the probe reports four windows — `Gemini 5h/weekly` and `Claude/GPT 5h/weekly`; for Codex, top-tier vs lighter modes.
|
|
252
|
+
- Read quotas at *model* granularity, not *agent* granularity. For agy, the probe reports four windows — `Gemini 5h/weekly` and `Claude/GPT 5h/weekly`; for Codex, top-tier vs lighter modes; for opencode, the quota is reported under the **provider** it is pointed at (`Z.ai`), and a local model reports nothing because it spends nothing.
|
|
242
253
|
- Skip a *model* if its `*_left` is below ~10%; reroute the subtask to the same agent with a different model, or to a different agent entirely.
|
|
243
254
|
- If a top-tier `weekly_*_left` is degrading toward the deadline, push as much work as possible to mid- and cheap-tier models on the same provider (which are often nowhere near depleted), instead of switching providers blindly.
|
|
244
255
|
- agy's **5-hour** window is the one that bites during a fan-out: it "smooths aggregate demand", so a burst of agy dispatches drains `Gemini 5h` or `Claude/GPT 5h` well before the weekly. If a 5h window is low, spread the burst or move some slices to Codex/coach.
|
|
@@ -263,9 +274,9 @@ playmaker watch # Rich live TUI of sessions
|
|
|
263
274
|
|
|
264
275
|
Every command takes `--json` for machine-readable output.
|
|
265
276
|
|
|
266
|
-
`--model NAME` is forwarded to the agent's native CLI: `claude --model sonnet`, `
|
|
277
|
+
`--model NAME` is forwarded to the agent's native CLI: `claude --model sonnet`, `agy --model claude-opus-4-6-thinking`, `codex -m <whatever that account has>`, `opencode -m zai-coding-plan/glm-5.2`. Without it the agent CLI uses its own default. Model is stored on the session row, so detached re-runs and `continue` inherit it; `continue --model X` overrides for that one turn.
|
|
267
278
|
|
|
268
|
-
agy
|
|
279
|
+
**The agy roster is not documented here on purpose** — it changes with Antigravity releases, and so does the spelling convention. Run `agy models` and copy a line. At the time of writing it returns bare slugs in the shape `gemini-3.6-flash-{low,medium,high}`, `gemini-3.1-pro-{low,high}`, `claude-sonnet-4-6`, `claude-opus-4-6-thinking`, `gpt-oss-120b-medium` — but treat that as an example of the *shape*, not a list to copy from.
|
|
269
280
|
|
|
270
281
|
## Anti-patterns
|
|
271
282
|
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"""Antigravity CLI (`agy`) handler.
|
|
2
2
|
|
|
3
3
|
Empirically (agy 1.1.1):
|
|
4
|
-
- oneshot: `agy -p "<prompt>" [--model
|
|
4
|
+
- oneshot: `agy -p "<prompt>" [--model <name>] [--dangerously-skip-permissions]
|
|
5
5
|
[--print-timeout 60m] [--log-file <path>]`; stdout is the final response as
|
|
6
6
|
plain text (no JSON envelope).
|
|
7
7
|
- resume: `agy --conversation <uuid> -p "..."` — keeps the same conversation id.
|
|
8
|
-
-
|
|
9
|
-
"
|
|
8
|
+
- `--model` takes a name from `agy models` verbatim, e.g.
|
|
9
|
+
"claude-opus-4-6-thinking", "gemini-3.6-flash-high". Both the roster and its
|
|
10
|
+
*spelling* move with Antigravity releases — earlier builds took display names
|
|
11
|
+
like "Claude Opus 4.6 (Thinking)" — which is why _validate_model() reads the
|
|
12
|
+
live list instead of trusting a hardcoded one.
|
|
10
13
|
- the conversation id is NOT printed to stdout; it is recovered from the CLI
|
|
11
14
|
debug log (`--log-file`) via the `Created conversation <uuid>` line, which
|
|
12
15
|
appears a few seconds in — that is our early on_session_started signal.
|
|
@@ -53,7 +56,7 @@ class AgyHandler:
|
|
|
53
56
|
@staticmethod
|
|
54
57
|
@functools.lru_cache(maxsize=1)
|
|
55
58
|
def available_models() -> tuple[str, ...]:
|
|
56
|
-
"""Exact model
|
|
59
|
+
"""Exact model names agy accepts, from `agy models`.
|
|
57
60
|
|
|
58
61
|
agy resolves an unknown `--model` to its default *silently* (no error,
|
|
59
62
|
wrong model runs), so we validate against this list before dispatch.
|