@lawaty/lacode 0.11.0 → 1.0.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 +61 -1
- package/README.md +63 -29
- package/dist/agents.js +24 -16
- package/dist/commands.js +11 -3
- package/dist/index.js +567 -106
- package/dist/lacode.js +4 -4
- package/dist/pool.js +14 -38
- package/dist/tunnel.js +1 -1
- package/docs/CONFIGURATION.md +2 -2
- package/docs/USER-STORIES.md +15 -16
- package/package.json +3 -3
- package/presets/README.md +22 -24
- package/presets/free-tier.json +24 -40
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,64 @@ All notable changes to LaCode are recorded here. The format follows
|
|
|
6
6
|
|
|
7
7
|
Versions come from git release commits; the npm version is bumped in the same
|
|
8
8
|
commit as the changelog entry it describes.
|
|
9
|
+
|
|
10
|
+
## [1.0.0] — images, ordered slot fill, and a limit that fails over
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Image attachments from the clipboard or from files.** `/image-in-cb` reads
|
|
15
|
+
the system clipboard through `wl-paste`/`xclip` on Linux, `pngpaste` on macOS,
|
|
16
|
+
or PowerShell on Windows, and `/image` attaches one or more image files. Paths
|
|
17
|
+
honour quotes, `~` and globs; identical bytes are deduped within a message;
|
|
18
|
+
each file is capped at 4 MiB, at 10 images, and at 20 MiB total. Images are
|
|
19
|
+
archived content-addressed under `~/.local/share/opencode/lacode/images` and
|
|
20
|
+
delivered to the model as `FilePart`s. Configure with `imagePaste`
|
|
21
|
+
(`enabled`, `maxBytes`, `maxImages`, `dir`) or `LACODE_IMAGE_DIR`.
|
|
22
|
+
- **A system-prompt guard against slot-variant names.** Every system string is
|
|
23
|
+
scrubbed by `scrubSlotNames()` before the model sees it, so a stale prompt
|
|
24
|
+
cannot teach the model `explore-1` and friends. The transform logs once when
|
|
25
|
+
it has to strip a literal.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **Slot routing fills slots in declaration order in up to two passes.** A
|
|
30
|
+
slot's `weight` is its active-session budget for one pass. Pass 1 fills each
|
|
31
|
+
usable slot to its weight in declaration order; once every usable slot has
|
|
32
|
+
reached its weight, pass 2 fills each to twice its weight. Live claims decide
|
|
33
|
+
the next slot, a released claim immediately reopens its slot, and overflow
|
|
34
|
+
goes to the least-loaded usable slot. There is no stored position.
|
|
35
|
+
- **A hand-named slot variant is coerced to its base, not refused.** The task
|
|
36
|
+
hook rewrites `explore-1` to `explore` before routing, so a caller cannot pin
|
|
37
|
+
a provider or skip ordered fill. Injected agent prompts no longer name
|
|
38
|
+
variants, and `expert` is explicitly opt-in.
|
|
39
|
+
- **Rate-limit failover uses the authenticated plugin client.** Aborting a
|
|
40
|
+
limited child goes through `client.session.abort`, not a bare `fetch`, so an
|
|
41
|
+
`opencode serve` protected by `OPENCODE_SERVER_USERNAME/PASSWORD` no longer
|
|
42
|
+
answers 401 and leaves the child running. A failed abort holds the claim for
|
|
43
|
+
the reaper to retry instead of releasing the slot while the session lives.
|
|
44
|
+
- **A limit on a pooled child with no local claim is identified and handled.**
|
|
45
|
+
The failover path reads the session's `parentID` and user message to recognise
|
|
46
|
+
a pooled variant (`implement-1`, `explore-2`, `context-N`), cools that slot,
|
|
47
|
+
and aborts the child. Root, non-pooled, and unidentifiable sessions are left
|
|
48
|
+
alone.
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- **A limited or hung session no longer survives its slot.** The rate-limit path
|
|
53
|
+
aborts it immediately, including the transient-outage path in
|
|
54
|
+
`message.updated`, and a failed abort no longer frees the slot.
|
|
55
|
+
- **`pool_status` says a cooling slot is unavailable.** A cooling slot is marked
|
|
56
|
+
`UNAVAILABLE (COOLING …)`, and the summary reads `unavailable/cooling: …`.
|
|
57
|
+
- **A `done` popup is raised once per idle period, and an `error` suppresses the
|
|
58
|
+
`done` that follows it in the same turn.** The per-session completion marker
|
|
59
|
+
is cleared when the session goes busy again or is deleted.
|
|
60
|
+
|
|
61
|
+
### Documented
|
|
62
|
+
|
|
63
|
+
- README documents `/image`, `/image-in-cb`, `imagePaste`, the `latest` dist-tag
|
|
64
|
+
for 1.0.0, and the ordered two-pass fill. `OPERATIONS.md`, `presets/README.md`
|
|
65
|
+
and the preset comments describe the same routing rule.
|
|
66
|
+
|
|
9
67
|
## [0.11.0] — the old sessions and the old event rows are swept away on their own, and a pool edit takes effect without a restart
|
|
10
68
|
|
|
11
69
|
### Added
|
|
@@ -703,7 +761,9 @@ experimental; `latest` remains 0.4.2.
|
|
|
703
761
|
|
|
704
762
|
- First published release: pooled subagents over a shared set of models.
|
|
705
763
|
|
|
706
|
-
[Unreleased]: https://github.com/lawaty/lacode/compare/
|
|
764
|
+
[Unreleased]: https://github.com/lawaty/lacode/compare/v1.0.0...HEAD
|
|
765
|
+
[1.0.0]: https://github.com/lawaty/lacode/compare/v0.11.0...v1.0.0
|
|
766
|
+
[0.11.0]: https://github.com/lawaty/lacode/compare/v0.10.0...v0.11.0
|
|
707
767
|
[0.10.0]: https://github.com/lawaty/lacode/compare/v0.9.0...v0.10.0
|
|
708
768
|
[0.9.0]: https://github.com/lawaty/lacode/compare/v0.8.0...v0.9.0
|
|
709
769
|
[0.8.0]: https://github.com/lawaty/lacode/compare/v0.7.1...v0.8.0
|
package/README.md
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
> Ultimate opencode setup for Go users
|
|
4
4
|
|
|
5
|
-
>
|
|
6
|
-
>
|
|
7
|
-
> `@lawaty/lacode@beta`, or pin an exact version. Interfaces here can change
|
|
8
|
-
> between releases without a major bump.
|
|
5
|
+
> LaCode 1.0.0 ships on the npm **`latest`** dist-tag. Prereleases use
|
|
6
|
+
> `beta`: install `@lawaty/lacode@beta`, or pin an exact version.
|
|
9
7
|
|
|
10
8
|
LaCode is an opencode plugin. It routes delegated work onto a weighted pool of
|
|
11
9
|
cheap models instead of the expensive one, reaps subagents that hang without
|
|
@@ -29,8 +27,13 @@ is also on disk at `node_modules/@lawaty/lacode/CHANGELOG.md`.
|
|
|
29
27
|
| Per-model cooldowns and failover | A provider rate-limits mid-session and the whole thing hard-fails, while other providers sit idle. |
|
|
30
28
|
| Hang reaper | A wedged subagent holds its slot forever, so the session stalls with no error and no timeout. |
|
|
31
29
|
| Desktop notifications | With several sessions open you cannot see which one finished, or which is blocked on a question. |
|
|
30
|
+
| Permission answers on the popup | An approval blocks a background session, and finding that session just to click Allow is the interruption. |
|
|
31
|
+
| Distinct notification sounds | A popup says something happened, but not at a glance whether it is a finish, a question or a block. |
|
|
32
32
|
| SSH notification tunnel | Work on a remote host raises its notification on that host, which has no desktop. |
|
|
33
|
-
| Repository context map | Every task starts by exploring your codebase cold,
|
|
33
|
+
| Repository context map | Every task starts by exploring your codebase cold, re-deriving the same layout, entry points and boundaries. |
|
|
34
|
+
| Active backlog | What is half-done, and what can be dropped, lives in chat history the next session cannot see. |
|
|
35
|
+
| Standing instructions | The same direction gets repeated every session, or buried in config that is not per-clone. |
|
|
36
|
+
| Image attachments anywhere | A TUI with no image support locks vision models out entirely. |
|
|
34
37
|
|
|
35
38
|
## Getting started
|
|
36
39
|
|
|
@@ -132,6 +135,9 @@ option is optional:
|
|
|
132
135
|
| `selfUpdate` | `true` | Check for a newer release at most once per ~6h and install it in the background; it applies on the next opencode start. `false` — or `LACODE_NO_SELFUPDATE=1` — turns the check off. |
|
|
133
136
|
| `sound` | `true` | Play a short tone with each notification, one per outcome, so you can tell a finished session from a question or a permission prompt without reading the popup. It is opt-out: `false` — or `LACODE_SOUND=0` (`false`, `off`, `no` work too, and beat the option) — turns the sound off, and anything else, a typo included, leaves it on. |
|
|
134
137
|
| `omniroute` | — | Optional [OmniRoute](docs/OMNIROUTE.md) gateway integration. Absent or `{ enabled: false }` changes nothing. |
|
|
138
|
+
| `watchMs` | `1000` | How often the pool files are checked for changes. `0` disables live reload. |
|
|
139
|
+
| `watchDebounceMs` | `250` | Collapse a burst of editor writes into one reload. |
|
|
140
|
+
| `imagePaste` | — | Image attachments: `maxBytes` (4 MiB), `maxImages` (10) and `dir`. |
|
|
135
141
|
|
|
136
142
|
### Staying up to date
|
|
137
143
|
|
|
@@ -146,6 +152,12 @@ The running session keeps its loaded code; the new version takes effect on the
|
|
|
146
152
|
next start, and the log says so. Run `lacode update` to do it on demand, or
|
|
147
153
|
`lacode update --check` to just report.
|
|
148
154
|
|
|
155
|
+
1.0.0 is published to the `latest` dist-tag; prereleases use `beta`. This check
|
|
156
|
+
follows `latest`. A beta install is therefore reported as current even when a
|
|
157
|
+
newer beta exists,
|
|
158
|
+
and `lacode update` will not move it: pin the version you want in the `plugin`
|
|
159
|
+
entry, because a new specifier is what forces a fresh resolve.
|
|
160
|
+
|
|
149
161
|
### Which LaCode is running
|
|
150
162
|
|
|
151
163
|
`lacode version` answers it — and the answer is often not the version number you
|
|
@@ -156,7 +168,7 @@ lacode version
|
|
|
156
168
|
```
|
|
157
169
|
|
|
158
170
|
```
|
|
159
|
-
version 0.
|
|
171
|
+
version 1.0.0
|
|
160
172
|
root /home/you/lacode
|
|
161
173
|
source checkout
|
|
162
174
|
commit <hash> (dirty)
|
|
@@ -182,16 +194,16 @@ When it reports `stale`, rebuild with `npm run build`. No network is touched;
|
|
|
182
194
|
|
|
183
195
|
## What you get
|
|
184
196
|
|
|
185
|
-
Three
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
197
|
+
Three pooled agents: `explore`, `implement` and `context`. You spawn the base
|
|
198
|
+
name and the pool picks a cheap model slot for it. Behind each base sits up to
|
|
199
|
+
four hidden variants — one per slot — and a spawn of the bare name is the only
|
|
200
|
+
thing that works: a hand-named variant such as `explore-1` is coerced to its
|
|
201
|
+
base and routed by the pool, so naming one cannot pin a provider or skip
|
|
202
|
+
ordered slot filling.
|
|
191
203
|
|
|
192
|
-
A model that rate-limits or runs out of quota is benched
|
|
193
|
-
|
|
194
|
-
|
|
204
|
+
A model that rate-limits or runs out of quota is benched until its window ends,
|
|
205
|
+
so one sick provider does not take the pool with it.
|
|
206
|
+
Those windows are computed backoff rather than a promise from the provider,
|
|
195
207
|
and a quota-shaped one can run for hours — long enough for a provider that has
|
|
196
208
|
since recovered, or whose quota you reset in its own console, to stay excluded
|
|
197
209
|
while every delegated spawn queues behind the survivors. So LaCode asks instead
|
|
@@ -200,30 +212,42 @@ the moment a pool file changes (where it validates every slot, cooling or not),
|
|
|
200
212
|
it probes each benched model with one real request on that exact model. A model
|
|
201
213
|
that answers is re-admitted immediately — nothing restarts, nothing reloads — and
|
|
202
214
|
a model that is still limited keeps exactly the window it had, because a check
|
|
203
|
-
must never be the thing that extends the wait. A model the provider
|
|
204
|
-
|
|
205
|
-
reported as a toast and a log line; a pass that finds nothing changed says
|
|
215
|
+
must never be the thing that extends the wait. A model the provider does not
|
|
216
|
+
serve at all is benched for the quota cap and named in the report.
|
|
217
|
+
A change is reported as a toast and a log line; a pass that finds nothing changed says
|
|
206
218
|
nothing at all.
|
|
207
219
|
|
|
208
|
-
|
|
209
|
-
`/lacode-doctor`, `/agent-instructions`, `/pool
|
|
210
|
-
when your config does not already
|
|
220
|
+
Nine commands: `/context-init`, `/context-update`, `/context-review`,
|
|
221
|
+
`/lacode-doctor`, `/agent-instructions`, `/pool`, `/pool-recheck`, `/image-in-cb`
|
|
222
|
+
and `/image`. Everything is added **only when your config does not already
|
|
211
223
|
define it** — an agent or command you wrote yourself is left byte-identical,
|
|
212
224
|
never patched or partially merged. `{"enabled": false}` turns the whole thing off
|
|
213
225
|
without leaving a trace. The exact injection list, and the five keys that are
|
|
214
226
|
deliberately *not* injected, are in
|
|
215
227
|
[docs/CONFIGURATION.md](docs/CONFIGURATION.md#what-gets-injected).
|
|
216
228
|
|
|
229
|
+
Two more surfaces that need no configuration:
|
|
230
|
+
|
|
231
|
+
- **`pool_status`** — the live view `/lacode-doctor` uses: per-slot load against
|
|
232
|
+
its ceiling, which slot the next spawn takes, cooldowns, hung claims and
|
|
233
|
+
whether the watcher is on. Ask for it when you want to know what the pool is
|
|
234
|
+
doing; it never changes slot selection.
|
|
235
|
+
- **Notifications that wait** — a notification is never auto-dismissed; it stays
|
|
236
|
+
until you close it. On Linux a permission request carries **Allow once**,
|
|
237
|
+
**Always allow** and **Deny** buttons, and LaCode waits up to ten minutes for
|
|
238
|
+
the click.
|
|
239
|
+
|
|
217
240
|
## Context map
|
|
218
241
|
|
|
219
242
|
Agents are stateless between tasks, and exploring your repository is the most
|
|
220
243
|
expensive part of any task — so every agent pays for it again, re-deriving the
|
|
221
244
|
same layout, entry points and boundaries from scratch. LaCode keeps a short,
|
|
222
|
-
maintained map of the repository in `.opencode/context/`
|
|
223
|
-
`architecture`, `contexts`, `conventions`, `workflows`, `decisions
|
|
224
|
-
`active.md
|
|
225
|
-
a standing rule that every agent reads the
|
|
226
|
-
starts from the canonical entry points it
|
|
245
|
+
maintained map of the repository in `.opencode/context/` — five navigation files
|
|
246
|
+
(`architecture`, `contexts`, `conventions`, `workflows`, `decisions`) plus
|
|
247
|
+
`active.md`, the active backlog, where a finished task stays a week and an open
|
|
248
|
+
one stays until done — and injects a standing rule that every agent reads the
|
|
249
|
+
relevant file before exploring and starts from the canonical entry points it
|
|
250
|
+
lists. The map holds conclusions, not
|
|
227
251
|
inventories: it answers "what should I look at first?" and nothing else, which
|
|
228
252
|
is what makes reading it cheaper than the exploration it replaces.
|
|
229
253
|
|
|
@@ -244,6 +268,8 @@ are reading:
|
|
|
244
268
|
/agent-instructions # apply a client instruction to the project's AGENTS.md — client-only, see below
|
|
245
269
|
/pool # rewrite the pool slot table in ~/.config/lacode/pool.txt; picked up automatically
|
|
246
270
|
/pool-recheck # probe the pool now; accepts an optional provider/model list
|
|
271
|
+
/image-in-cb # attach the clipboard image to this message; macOS needs pngpaste, Linux needs wl-paste or xclip
|
|
272
|
+
/image # attach one or more image files to this message; paths honour quotes, ~ and globs
|
|
247
273
|
```
|
|
248
274
|
|
|
249
275
|
The map is local and untracked — it describes your checkout on your machine, so
|
|
@@ -252,11 +278,16 @@ nothing and carry on without it. What this buys is tokens not spent
|
|
|
252
278
|
re-discovering structure; as with everything else here, no savings percentage is
|
|
253
279
|
published, because none has been independently measured. The mechanism, the
|
|
254
280
|
permission rule that makes one writer possible, and what the log lines mean are
|
|
255
|
-
in [docs/CONTEXT.md](docs/CONTEXT.md).
|
|
281
|
+
in [docs/CONTEXT.md](docs/CONTEXT.md). Automatic map runs also clean up after
|
|
282
|
+
themselves: each run's session is deleted once its transcript is written, and
|
|
283
|
+
the last 20 transcripts are kept under
|
|
284
|
+
`~/.local/share/opencode/lacode/cartographer` (`LACODE_TRANSCRIPT_DIR` overrides
|
|
285
|
+
the directory).
|
|
256
286
|
|
|
257
287
|
## Standing instructions
|
|
258
288
|
|
|
259
|
-
The project's root `AGENTS.md`
|
|
289
|
+
The project's root `AGENTS.md` — created on first use by `/agent-instructions` —
|
|
290
|
+
is your own statement of intent: it records
|
|
260
291
|
what you want worked on and how you want it approached. It says nothing about
|
|
261
292
|
where code lives, so it can never contradict the code, and within that domain
|
|
262
293
|
it outranks the generated context files and any agent's inference about what
|
|
@@ -345,7 +376,8 @@ which explains the harness and deliberately contains no results.
|
|
|
345
376
|
## Remote hosts
|
|
346
377
|
|
|
347
378
|
Notifications raised on a remote host need a way back to your desktop. The
|
|
348
|
-
|
|
379
|
+
default hop is a direct `ssh` to your desktop over one warm `ControlMaster`
|
|
380
|
+
connection; a reverse forward is the fallback used when `OC_LOCAL_HOST` is unset:
|
|
349
381
|
|
|
350
382
|
```bash
|
|
351
383
|
lacode notify "build finished" "4 files changed" # local desktop, or forwarded if remote
|
|
@@ -356,6 +388,8 @@ lacode doctor # what the environment reso
|
|
|
356
388
|
must never be able to fail the process that tried to notify you. The one
|
|
357
389
|
exception is an actionable notification — one carrying a permission request id
|
|
358
390
|
— which waits for the click, because the answer is the whole point of it.
|
|
391
|
+
That click path is Linux-only: the popup carries **Allow once**, **Always allow**
|
|
392
|
+
and **Deny**, and macOS gets a plain notice without buttons.
|
|
359
393
|
`lacode forward HOST -- COMMAND` runs a command on another host over ssh and
|
|
360
394
|
exits with its status.
|
|
361
395
|
|
package/dist/agents.js
CHANGED
|
@@ -78,9 +78,12 @@ Every question of the form "what does this file do", "where is X handled", or
|
|
|
78
78
|
that proves it. Never one whole refactor handed over in a single piece \u2014
|
|
79
79
|
see \`# Task size\` below.
|
|
80
80
|
|
|
81
|
-
Spawn the
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
Spawn the pooled base \u2014 \`explore\`, \`implement\` or \`context\`. The plugin decides
|
|
82
|
+
which model runs the work; do not try to choose one yourself.
|
|
83
|
+
|
|
84
|
+
\`expert\` is not part of the pool and is expensive: spawn it only when the user
|
|
85
|
+
explicitly asks for it. Never escalate to it on your own, and never as a
|
|
86
|
+
fallback when a pooled spawn fails.
|
|
84
87
|
|
|
85
88
|
# When the pool is unavailable
|
|
86
89
|
|
|
@@ -89,12 +92,12 @@ pool cannot serve a spawn \u2014 every slot cooling or exhausted, spawns repeate
|
|
|
89
92
|
failing, or a runtime message saying no slot is available \u2014 that is not a reason
|
|
90
93
|
to do the work yourself, and not a reason to stop and ask.
|
|
91
94
|
|
|
92
|
-
**Retry.** A
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
picked the wrong number.
|
|
95
|
+
**Retry.** A cooling model is transient and costs you nothing but a turn. Spawn
|
|
96
|
+
the same base again. If a spawn fails, do not switch to a different name \u2014 a
|
|
97
|
+
failure means the pool has a routing problem, not that you picked the wrong one.
|
|
96
98
|
|
|
97
|
-
Retry is always available
|
|
99
|
+
Retry is always available
|
|
100
|
+
and never wrong, which is why it is the default. But
|
|
98
101
|
"never wrong" is not "sufficient": looping silently against a pool with every
|
|
99
102
|
model cooling goes nowhere and burns the slot doing it. So separate the two
|
|
100
103
|
failures. **Transient** \u2014 a cooldown, a rate limit, one slot at its ceiling \u2014
|
|
@@ -102,7 +105,8 @@ means retry. **Persistent or structural** \u2014 every slot cooling, the same sp
|
|
|
102
105
|
failing repeatedly with the same error, a malformed model id \u2014 means stop
|
|
103
106
|
retrying and *report* it: say what failed (slot, model, error) and continue
|
|
104
107
|
with whatever else the task needs, or ask the user. Surface the failure; do not
|
|
105
|
-
spin on it and do not let it end the whole task.
|
|
108
|
+
spin on it and do not let it end the whole task. Do not escalate to \`expert\` as
|
|
109
|
+
a workaround; it is opt-in by the user.
|
|
106
110
|
|
|
107
111
|
**Never fall back to reading, grepping, exploring or implementing on your own.**
|
|
108
112
|
Do not "just quickly" inspect a file because a spawn failed. A failed spawn is
|
|
@@ -219,8 +223,11 @@ When you need to understand the codebase:
|
|
|
219
223
|
2. Invoke @explore with specific, focused instructions (e.g. "read src/auth.ts", "grep for 'migration' in *.py files", "list the src/ directory")
|
|
220
224
|
3. @explore will return its findings \u2014 you process them and plan accordingly
|
|
221
225
|
|
|
222
|
-
Spawn the
|
|
223
|
-
|
|
226
|
+
Spawn the pooled base (\`explore\`, \`implement\`, \`context\`); the plugin decides
|
|
227
|
+
which model runs the work. Do not try to choose one yourself.
|
|
228
|
+
|
|
229
|
+
\`expert\` is not part of the pool and is expensive: spawn it only when the user
|
|
230
|
+
explicitly asks for it.
|
|
224
231
|
|
|
225
232
|
If the pool cannot serve a spawn \u2014 every slot cooling or exhausted, or repeated
|
|
226
233
|
failures \u2014 do NOT fall back to reading or planning from your own inspection.
|
|
@@ -548,7 +555,7 @@ Trigger: \`.opencode/context/\` exists and work has just been done here.
|
|
|
548
555
|
- an architectural decision
|
|
549
556
|
- a new dependency between subsystems
|
|
550
557
|
- a renamed or relocated subsystem
|
|
551
|
-
|
|
558
|
+
- an invariant not yet recorded in the map
|
|
552
559
|
|
|
553
560
|
Do not update documentation merely because source files changed. Do not
|
|
554
561
|
rewrite files wholesale. Do not make timestamp-only edits. Do not add a fact
|
|
@@ -854,7 +861,7 @@ function buildAgentSet() {
|
|
|
854
861
|
for (let slot = 1; slot <= MAX_SLOTS; slot++) {
|
|
855
862
|
const variant = {
|
|
856
863
|
...def,
|
|
857
|
-
description: `Hidden pool
|
|
864
|
+
description: `Hidden pool slot ${slot} for ${base}. Its model is NOT set here -- LaCode injects it from the resolved pool preset at config time, so the preset is the only place a pool model is written down. Spawn '${base}' and let the pool route.`,
|
|
858
865
|
hidden: true,
|
|
859
866
|
// `mode: "primary"` is what keeps a variant OUT of the model's system
|
|
860
867
|
// prompt. `hidden` cannot do it.
|
|
@@ -866,9 +873,10 @@ function buildAgentSet() {
|
|
|
866
873
|
// and by default-agent resolution. A variant left as `mode: "subagent"`
|
|
867
874
|
// is therefore listed to the model under its own name -- "explore-1:
|
|
868
875
|
// Hidden pool variant explore-1" -- and the model copies that name
|
|
869
|
-
// straight into its next spawn. The
|
|
870
|
-
// naming
|
|
871
|
-
//
|
|
876
|
+
// straight into its next spawn. The task hook coerces a hand-named
|
|
877
|
+
// variant back to its base, because naming one is how a caller would
|
|
878
|
+
// pick the provider and skip ordered slot fill and the slot ceiling. The coercion is right; the
|
|
879
|
+
// leak that provokes it is not.
|
|
872
880
|
//
|
|
873
881
|
// `mode` is the only field that filter respects, and setting it here is
|
|
874
882
|
// safe: the task tool never reads an agent's mode -- it resolves the
|
package/dist/commands.js
CHANGED
|
@@ -93,7 +93,7 @@ context file only if this work introduced or revealed information that will
|
|
|
93
93
|
materially help future agents \u2014 a new boundary or module, a new or moved
|
|
94
94
|
canonical entry point, a changed workflow, a new convention, an architectural
|
|
95
95
|
decision, a new dependency between subsystems, a renamed or moved subsystem,
|
|
96
|
-
or
|
|
96
|
+
or an invariant not yet recorded.
|
|
97
97
|
|
|
98
98
|
Do not edit documentation just because source files changed. No
|
|
99
99
|
timestamp-only edits. If nothing material changed, make no edits and report
|
|
@@ -180,11 +180,11 @@ The pool is ONE global slot table shared by every pooled base (explore, implemen
|
|
|
180
180
|
2. Resolve the instruction above into a target slot table. These are the rules the loader enforces \u2014 never write a file that breaks one:
|
|
181
181
|
- one slot per line: \`<provider>/<model-id> [weight]\`
|
|
182
182
|
- at most ${MAX_SLOTS} slots, and a model may appear only once
|
|
183
|
-
- weight is optional (default 1) and must be a number in (0, ${MAX_WEIGHT}]. It is the slot's
|
|
183
|
+
- weight is optional (default 1) and must be a number in (0, ${MAX_WEIGHT}]. It is the slot's active-session budget for one pass \u2014 how many turns it takes per cycle \u2014 and its concurrency ceiling is twice that. NOT a priority; pick order follows line order.
|
|
184
184
|
- \`#\` starts a comment (whole-line or trailing); blank lines are ignored.
|
|
185
185
|
If the instruction names a model ambiguously, or would need more than ${MAX_SLOTS} slots, stop and ask rather than guessing.
|
|
186
186
|
|
|
187
|
-
3. Write the WHOLE file, not a patch. This file is an override, not an edit target: any slot you drop disappears, and slot numbers are line positions, so a partial write silently renumbers
|
|
187
|
+
3. Write the WHOLE file, not a patch. This file is an override, not an edit target: any slot you drop disappears, and slot numbers are line positions, so a partial write silently renumbers slots. Keep the existing comment header. If the write fails on a missing directory, create \`~/.config/lacode\` first and retry.
|
|
188
188
|
|
|
189
189
|
4. Report the before \u2192 after slot table and the resolved path. The running process watches the pool files: it reloads the table, re-binds the variant agents and validates every slot, so no restart is needed. If a slot names a model the provider does not serve, it will be benched and named in the log and toast \u2014 report that instead of claiming the swap succeeded.
|
|
190
190
|
|
|
@@ -207,6 +207,14 @@ $ARGUMENTS
|
|
|
207
207
|
- Otherwise call \`pool_recheck\` with no arguments; it probes every model that is currently cooling.
|
|
208
208
|
|
|
209
209
|
Report the tool's output as it came back, then add one short line naming what changed: re-admitted, still limited, or benched because the provider does not serve the model. If a model was benched as \`model-missing\`, say so and name the replacement in \`~/.config/lacode/pool.txt\` \u2014 but change nothing yourself.`
|
|
210
|
+
},
|
|
211
|
+
"image-in-cb": {
|
|
212
|
+
description: "Attach the clipboard image to this message \u2014 macOS needs pngpaste, Linux needs wl-paste or xclip.",
|
|
213
|
+
template: "$ARGUMENTS"
|
|
214
|
+
},
|
|
215
|
+
"image": {
|
|
216
|
+
description: "Attach one or more image files to this message",
|
|
217
|
+
template: "$ARGUMENTS"
|
|
210
218
|
}
|
|
211
219
|
};
|
|
212
220
|
function applyCommands(cfg, commands = COMMANDS) {
|