@lawaty/lacode 2.1.0-beta.0 → 2.3.0-beta.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 +42 -0
- package/README.md +14 -0
- package/dist/agents.js +2 -0
- package/dist/commands.js +2 -0
- package/dist/index.js +2515 -2110
- package/dist/lacode.js +2 -0
- package/dist/pool.js +194 -18
- package/dist/tui.js +153 -25
- package/dist/tunnel.js +2 -0
- package/docs/CONFIGURATION.md +15 -1
- package/docs/USER-STORIES.md +56 -8
- package/package.json +2 -1
- package/presets/README.md +6 -6
- package/scripts/pool-selection.mjs +281 -0
- package/scripts/refresh-pool.mjs +149 -69
- package/scripts/score-models.mjs +227 -68
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,48 @@ commit as the changelog entry it describes.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [2.3.0-beta.0] — reliable pool refresh, autonomy modes, and empty-response failover
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Modes: YOLO (`/yolo`) approves permission requests that would ask, while an explicit `deny` still wins; YKB (`/ykb`) tells the agent not to ask and answers questions with the `(Recommended)` option (or the first option when none is marked); `/modes` shows both. The `yolo`/`ykb` options only seed the live file, and toggles apply without a restart. (US-37, US-38)
|
|
17
|
+
- Pool: an empty task result is now a failure. The model is benched for `empty response`, the task result explains the bench, and the next spawn routes to another slot. This fixes the “routed only to one slot, and it returns nothing” case. (US-4)
|
|
18
|
+
- Pool: the refresh now runs every 6 hours and also after a startup, so a run killed by a reboot is retried. A `--budget-min` wall-clock budget (default 30) writes what was measured, core providers are scanned first, and unscanned or truncated providers keep their previous rows. (US-39)
|
|
19
|
+
- Pool: one shared failure classifier (`credit`, `rate-limited`, `agreement`, `credential`, `not-served`, `timeout`, `network`, `server`) is persisted as `status`/`kind`. Transient rows with no reset get a 45-minute retry, and per-provider warnings name the dominant failure.
|
|
20
|
+
- Pool: a refresh lock serializes the 6-hour run and transient retry timers; a lock left by a dead PID is reclaimed.
|
|
21
|
+
- Pool: a slot can carry a tokens-per-minute budget (`tpm:`), and the router keeps a learned TPM record; a sub-threshold slot is dropped with a warning instead of being sent a task it cannot finish.
|
|
22
|
+
- Config: `contextAutoUpdate: false` disables the automatic context-map refresh.
|
|
23
|
+
- TUI: `/yolo`, `/ykb`, and `/modes` commands.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Pool: the last slot is now a reserved `opencode` (Zen) slot at weight 2, so a full field of other providers cannot squeeze Zen out.
|
|
28
|
+
- Pool: a transient failure keeps the last measured rankable row in `model-scores.json` instead of erasing it on the next write.
|
|
29
|
+
- Pool: routing never falls back to a cooling or unavailable slot. When no slot is usable, the spawn fails with a message naming every cooling slot and its reason; a reaped model refuses routing until its cooldown lapses.
|
|
30
|
+
- Timer: the service has no start timeout, and the timer has a 5-minute startup catch-up trigger in addition to the 6-hour calendar.
|
|
31
|
+
- Event fan-out: a failing plugin event handler is logged once per minute with its message and stack instead of being silently swallowed.
|
|
32
|
+
- Timer migration: resolves a real `node` binary when the host executable is not named `node`.
|
|
33
|
+
- Notifications: `dispose` clears pending claim-release and popup timers.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- Pool: empty task results were treated as successes, so the same empty model kept winning every small task.
|
|
38
|
+
- Pool: a killed refresh wrote nothing; partial scans now keep the previous pool and the next run is triggered after a reboot.
|
|
39
|
+
- Docs: USER-STORIES covers the refresh and empty-response behavior (US-39), and US-4/US-5 no longer claim the pool never refuses work.
|
|
40
|
+
|
|
41
|
+
## [2.2.0-beta.0] — context-aware pool routing
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- Pool: context-aware routing. `pool.txt` lines carry a `c:<context>` token, and the router prefers the smallest model whose context fits the task prompt, so large-context models are reserved for large tasks.
|
|
46
|
+
- Pool: `npm run score` probes providers with no direct HTTP endpoint (or an unexpanded `${...}` URL) through the local opencode session, and considers catalogue-priced models on providers other than `opencode`/`opencode-go`, whose credits cover them.
|
|
47
|
+
- Pool: a rate-limit reset or a `402 out of credits` answer schedules a transient retry; a transient failure keeps the model's previous score until the retry.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- Pool: the context floor is now 100k. Slots are ordered as `opencode-go` (weight 4), small-context providers (weight 2), large-context providers (weight 1), and at most one `opencode` model last.
|
|
52
|
+
- Pool: small-context models are preferred for ordinary work; large-context models are used when the estimated task size needs them or when small slots are full.
|
|
53
|
+
|
|
12
54
|
## [2.1.0-beta.0] — every provider counts, and the timer installs itself
|
|
13
55
|
|
|
14
56
|
### Added
|
package/README.md
CHANGED
|
@@ -156,10 +156,24 @@ option is optional:
|
|
|
156
156
|
| `feedbackHint` | `true` | Show the one-time feedback note on the first interactive run. `false` — or `LACODE_NO_FEEDBACK_HINT=1` — turns it off. The flag lives in `~/.local/share/opencode/lacode/feedback.json`; nothing is sent anywhere. |
|
|
157
157
|
| `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. |
|
|
158
158
|
| `omniroute` | — | Optional [OmniRoute](docs/OMNIROUTE.md) gateway integration. Absent or `{ enabled: false }` changes nothing. |
|
|
159
|
+
| `yolo` | `false` | Start with YOLO mode on: permission requests that would ask are auto-approved. Explicit `deny` rules still win. Toggle live with `/yolo`. |
|
|
160
|
+
| `ykb` | `false` | Start with YKB (You Know Better) mode on: the agent is told not to ask, and questions that still appear are answered with the recommended option. Toggle live with `/ykb`. |
|
|
159
161
|
| `watchMs` | `1000` | How often the pool files are checked for changes. `0` disables live reload. |
|
|
160
162
|
| `watchDebounceMs` | `250` | Collapse a burst of editor writes into one reload. |
|
|
161
163
|
| `imagePaste` | — | Image attachments: `maxBytes` (4 MiB), `maxImages` (10) and `dir`. |
|
|
162
164
|
|
|
165
|
+
## Modes
|
|
166
|
+
|
|
167
|
+
Two runtime modes can be seeded from plugin options and toggled from the TUI:
|
|
168
|
+
|
|
169
|
+
| Command | Effect |
|
|
170
|
+
| --- | --- |
|
|
171
|
+
| `/yolo` | Toggle YOLO. Every permission request that would `ask` is approved automatically; an explicit `deny` still wins. |
|
|
172
|
+
| `/ykb` | Toggle YKB (You Know Better). The agent is told not to ask questions and to continue with its recommendation. A question that still appears is answered with its `(Recommended)` option, or its first option when none is marked. |
|
|
173
|
+
| `/modes` | Show both switches. |
|
|
174
|
+
|
|
175
|
+
The toggles write `~/.config/lacode/modes.json` (override with `LACODE_MODES_FILE`) and the server picks the change up on the next decision — no restart. Turning a mode on also answers requests that are already pending. The `yolo` / `ykb` plugin options only seed the file on first run; after that, the file wins. A free-text question with no options is left for the user, since there is no option to choose.
|
|
176
|
+
|
|
163
177
|
### Staying up to date
|
|
164
178
|
|
|
165
179
|
opencode's plugin cache is **write-once**: it resolves `@lawaty/lacode` to an
|
package/dist/agents.js
CHANGED
|
@@ -51,6 +51,8 @@ var FALLBACK_SLOTS = [
|
|
|
51
51
|
{ index: 3, model: "opencode/deepseek-v4.1-flash-free", weight: 1 },
|
|
52
52
|
{ index: 4, model: "opencode/glm-5.3-flash-free", weight: 1 }
|
|
53
53
|
];
|
|
54
|
+
var CONTEXT_OVERFLOW_COOLDOWN_MS = 10 * 60 * 1e3;
|
|
55
|
+
var BELOW_MIN_CONTEXT_COOLDOWN_MS = 6 * 60 * 60 * 1e3;
|
|
54
56
|
var STATE_SWEEP_INTERVAL_MS = 60 * 60 * 1e3;
|
|
55
57
|
var CHILD_MEMORY_MS = 30 * 6e4;
|
|
56
58
|
|
package/dist/commands.js
CHANGED
|
@@ -50,6 +50,8 @@ var DEFAULT_PRESET = join2(PRESETS_DIR, "free-tier.json");
|
|
|
50
50
|
var USER_CONFIG_DIR = join2(homedir(), ".config", "lacode");
|
|
51
51
|
var USER_MODELS_PATH = join2(USER_CONFIG_DIR, "pool.json");
|
|
52
52
|
var USER_MODELS_TXT = join2(USER_CONFIG_DIR, "pool.txt");
|
|
53
|
+
var CONTEXT_OVERFLOW_COOLDOWN_MS = 10 * 60 * 1e3;
|
|
54
|
+
var BELOW_MIN_CONTEXT_COOLDOWN_MS = 6 * 60 * 60 * 1e3;
|
|
53
55
|
var STATE_SWEEP_INTERVAL_MS = 60 * 60 * 1e3;
|
|
54
56
|
var CHILD_MEMORY_MS = 30 * 6e4;
|
|
55
57
|
|