akm-cli 0.10.261017-beta → 0.10.261019
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 +51 -0
- package/dist/assets/opencode/akm-plugin.js +103 -1
- package/dist/core/config/convert-engine-references.js +23 -7
- package/dist/core/config/convert-engines.js +94 -28
- package/dist/core/config/convert-models-overlay.js +14 -2
- package/dist/integrations/agent/spawn.js +7 -2
- package/dist/integrations/harnesses/opencode/agent-builder.js +10 -1
- package/dist/integrations/harnesses/opencode/runtime/binary.js +6 -3
- package/dist/integrations/harnesses/opencode/runtime/index.js +18 -9
- package/dist/integrations/harnesses/opencode/session-log-v2.js +11 -1
- package/dist/scripts/akm-migrate-node.js +91 -33
- package/dist/scripts/akm-migrate.js +91 -33
- package/docs/architecture/architecture.md +9 -3
- package/docs/architecture/testing/testing-workflow.md +1 -1
- package/docs/migration/README.md +1 -1
- package/docs/migration/release-notes/{0.10.0.md → 0.10.261019.md} +35 -4
- package/docs/migration/release-notes/README.md +1 -1
- package/docs/migration/v0.9-to-v0.10.md +58 -7
- package/docs/reference/configuration.md +45 -13
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# akm v0.10
|
|
1
|
+
# akm v0.10 migration notes (0.10.261019, the first stable 0.10 release)
|
|
2
2
|
|
|
3
3
|
0.10 is a clean-up and tuning release. It covers the daily alphas
|
|
4
4
|
0.10.26101001 through 0.10.26101202 and the monthly releases that follow
|
|
@@ -31,6 +31,19 @@ the old `stashDir` / `sources[]` / `installed[]` layout fails to load and names
|
|
|
31
31
|
`akm migrate apply` under akm 0.9.x. If you are on 0.9.14 or earlier, install
|
|
32
32
|
0.9.31, run `akm migrate apply`, then upgrade.
|
|
33
33
|
|
|
34
|
+
## If you ran a 0.10 beta
|
|
35
|
+
|
|
36
|
+
The betas 0.10.261014 to 0.10.261017 dropped every `opencode-sdk` engine when
|
|
37
|
+
`akm migrate apply` converted `config.json`, so agent work moved from your own
|
|
38
|
+
OpenCode (and its model) to akm's own runtime over your default connection; the
|
|
39
|
+
note it printed did not say so. This release keeps those engines as `opencode`
|
|
40
|
+
harnesses. A
|
|
41
|
+
config a beta already migrated is not converted again: akm keeps the file as it
|
|
42
|
+
was before the rewrite in `<cache dir>/config-backups/` (the five newest), and
|
|
43
|
+
[step 5 of the migration guide](../v0.9-to-v0.10.md#5-fix-what-the-migration-cannot)
|
|
44
|
+
shows how to read the harnesses out of that copy and set them, or write them by
|
|
45
|
+
hand when no copy is left.
|
|
46
|
+
|
|
34
47
|
## Version numbers
|
|
35
48
|
|
|
36
49
|
A 0.10 release is numbered `0.10.YYMMNN`: the UTC year and month, then the
|
|
@@ -74,7 +87,10 @@ not offer it.
|
|
|
74
87
|
config keys, paths and dotted references such as `process.env.CI` in a fenced
|
|
75
88
|
block now reach the `content` search text; quoted strings, assignment values,
|
|
76
89
|
URLs and long token-like strings still do not. Search results, fragments and
|
|
77
|
-
`akm show` are unchanged.
|
|
90
|
+
`akm show` are unchanged. It lifts code lookups and keyword library search
|
|
91
|
+
in akm-eval and costs about 2 NDCG points on the SkillRet skill-selection
|
|
92
|
+
benchmark, where long, code-heavy skills now outrank short, code-free ones;
|
|
93
|
+
tuning is tracked in #1284. On the first run after upgrading, `akm index` (and
|
|
78
94
|
the index `akm upgrade` runs, which `akm upgrade` waits for) re-reads every
|
|
79
95
|
bundle directory and re-embeds only the entries whose embedded text changed.
|
|
80
96
|
Text past `embedding.maxInputTokens` (default 512, about 2,048 characters) is
|
|
@@ -114,7 +130,13 @@ Other breaking changes:
|
|
|
114
130
|
is the default, and `defaults.improveStrategy` is `improve.strategy`. A config
|
|
115
131
|
in the old form still loads, read as the new form in memory with one warning
|
|
116
132
|
that names `akm migrate apply`. `akm migrate apply` converts it under a
|
|
117
|
-
backup:
|
|
133
|
+
backup: every agent engine becomes a harness with its model (an `opencode-sdk`
|
|
134
|
+
engine with no `llmEngine` ran your own OpenCode, so it becomes an `opencode`
|
|
135
|
+
harness; one over an `llmEngine` is akm's own runtime over that connection;
|
|
136
|
+
with no `defaults.llmEngine` and no connection, akm's model work now runs on
|
|
137
|
+
the default harness where 0.9 ran none, and `modelWork: false` on it turns that
|
|
138
|
+
off),
|
|
139
|
+
the default engine is renamed `default`, keys (`apiKeyFile`, a literal
|
|
118
140
|
or `${secrets/...}` `apiKey`) move to `credentials.json`, `models.json` is
|
|
119
141
|
folded into the connections' `models` and moved to the config backups,
|
|
120
142
|
`engine:` in assets, workflows and task sources becomes `connection:` or
|
|
@@ -216,13 +238,22 @@ Other breaking changes:
|
|
|
216
238
|
Harnesses run as thin shells: akm hands a program the prompt and takes its
|
|
217
239
|
standard output as the reply.
|
|
218
240
|
- **OpenCode 2, run by akm.** Agent work on a connection with no harness runs on
|
|
219
|
-
akm's own runtime, a pinned OpenCode 2 binary (2.
|
|
241
|
+
akm's own runtime, a pinned OpenCode 2 binary (2.2.0) that akm fetches from the
|
|
220
242
|
npm registry on first use and runs as a process, with no entry in config. The
|
|
221
243
|
fetch is the one platform package for your machine (about 114 MB, into its
|
|
222
244
|
cache), checked against the registry's sha512 integrity before anything is
|
|
223
245
|
extracted. One fetch runs per cache directory at a time: processes that start
|
|
224
246
|
together wait for it and download nothing more (#1266). The setup wizard
|
|
225
247
|
offers to fetch it right away; `--yes` and `--from` leave it to the first run.
|
|
248
|
+
A run whose model makes the same tool call and gets the same result three
|
|
249
|
+
turns in a row is told so in a message to the model, and failed with a
|
|
250
|
+
message if it makes the call again, not left to its deadline. That one
|
|
251
|
+
request raises a connection's `temperature` below 0.7 to 0.7: at temperature
|
|
252
|
+
0 the message alone changed nothing in the runs measured. A run that
|
|
253
|
+
keeps making different calls is bounded by its timeout: the connection's
|
|
254
|
+
`timeoutMs`, one the run is given, or a scheduled task's `timeout:` (six hours
|
|
255
|
+
when unset); with none, as for `akm agent` by default, it runs until it
|
|
256
|
+
finishes.
|
|
226
257
|
With no network for that step, enable the `opencode` harness with an installed
|
|
227
258
|
OpenCode 2 instead. A harness with `platform: "opencode"` is your
|
|
228
259
|
OpenCode, whichever major is installed, run through its CLI with your config,
|
|
@@ -7,7 +7,7 @@ live one level up in `docs/migration/`.
|
|
|
7
7
|
|
|
8
8
|
## Available notes
|
|
9
9
|
|
|
10
|
-
- [0.10.
|
|
10
|
+
- [0.10.261019](0.10.261019.md) — The 0.10 series: 0.9.15 version floor, merged CLI spellings, `default`/`consolidate` strategies only, OpenCode 2, feedback-scaled ranking, and `0.10.YYMMNN` versions.
|
|
11
11
|
- [0.9.19](0.9.19.md) — Bundle-scoped improve planning, proposal reopen, and consolidate/distill guardrails.
|
|
12
12
|
- [0.9.17](0.9.17.md) — Retire proposals, declared links replacing the LLM entity graph, and scoped improve planning.
|
|
13
13
|
- [0.9.16](0.9.16.md) — Source-bound scheduler grants, local execution authority, and split unsafe overrides.
|
|
@@ -12,7 +12,7 @@ every change that can break a script, a task or a config.
|
|
|
12
12
|
Checked against build 0.10.261013 with the connections and harnesses rework
|
|
13
13
|
(#1244). The
|
|
14
14
|
user-facing summary of the whole series is the
|
|
15
|
-
[0.10
|
|
15
|
+
[0.10 release note](release-notes/0.10.261019.md); the per-build detail is in the
|
|
16
16
|
[CHANGELOG](https://github.com/itlackey/akm/blob/main/CHANGELOG.md).
|
|
17
17
|
|
|
18
18
|
## What the upgrade preserves
|
|
@@ -160,6 +160,33 @@ ignores it.
|
|
|
160
160
|
in; if not, the connection has no key and a note names the variables. Set the
|
|
161
161
|
one you used and run `akm setup --api-key-env NAME`, or store the key with `akm
|
|
162
162
|
setup`.
|
|
163
|
+
- **Agent work no longer runs on your OpenCode (0.10 betas 0.10.261014 to
|
|
164
|
+
0.10.261017 only).** Those builds dropped every `opencode-sdk` engine when they
|
|
165
|
+
migrated `config.json`, so `akm info` lists no harness, agent work runs on akm's
|
|
166
|
+
own runtime over your default connection, and a `harness:` or `--harness` that
|
|
167
|
+
names one of your old engines fails with exit 78. akm keeps the file as it was
|
|
168
|
+
before it rewrote it in `<cache dir>/config-backups/` (`~/.cache/akm/config-backups/`
|
|
169
|
+
by default), the five newest `config-<timestamp>.json`; the one that still holds
|
|
170
|
+
`"engines"` is the one to use (`grep -l '"engines"' ~/.cache/akm/config-backups/config-*.json`).
|
|
171
|
+
Read what this release converts it to, in a scratch config directory so
|
|
172
|
+
nothing is written, with the `models.json.<timestamp>` of the same run beside
|
|
173
|
+
it if there is one, then set each harness on your config (leave out the `ok`,
|
|
174
|
+
`shape` and `schemaVersion` keys the output adds):
|
|
175
|
+
|
|
176
|
+
```sh
|
|
177
|
+
scratch=$(mktemp -d)
|
|
178
|
+
cp ~/.cache/akm/config-backups/config-<timestamp>.json "$scratch/config.json"
|
|
179
|
+
cp ~/.cache/akm/config-backups/models.json.<timestamp> "$scratch/models.json"
|
|
180
|
+
AKM_CONFIG_DIR="$scratch" akm config get harnesses
|
|
181
|
+
akm config set harnesses.<name> '<that entry>'
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
If no pre-migration copy is left (five later config writes prune it), write the
|
|
185
|
+
entries yourself, one per `opencode-sdk` engine you had, the one `defaults.engine`
|
|
186
|
+
named called `default`: `akm config set harnesses.default
|
|
187
|
+
'{"platform":"opencode","models":{"fast":"<provider/model>","balanced":"<provider/model>","reasoning":"<provider/model>"}}'`.
|
|
188
|
+
Add `"agent": "<name>"` if the engine named one. Run `akm info` after: its
|
|
189
|
+
`agents` row names the harness and the model.
|
|
163
190
|
- **Scripts that pass `--engine` or `--require-engines`.** They keep running,
|
|
164
191
|
with one warning each. Change `--engine NAME` to `--connection <name>` or
|
|
165
192
|
`--harness <name>`: how an old engine name resolves, and when it stops, is
|
|
@@ -438,6 +465,23 @@ writes `connections` and `harnesses`, renames the default LLM engine to
|
|
|
438
465
|
runs to `improve.processes` and `improve.qualityGate`, and keeps a connection or
|
|
439
466
|
harness the loader cannot use in the file, with a note on what to fix. It also:
|
|
440
467
|
|
|
468
|
+
- keeps every agent engine as a harness, with its `model`, `bin`, `args`,
|
|
469
|
+
`workspace`, `agent` and `timeoutMs`. An `opencode-sdk` engine with no
|
|
470
|
+
`llmEngine` ran your own OpenCode, with its own providers, models and logins,
|
|
471
|
+
so it becomes an `opencode` harness (without `args`, which 0.9 did not pass to
|
|
472
|
+
it); the harness `defaults.engine` named, when
|
|
473
|
+
there are several, is renamed `default`, and `engine:` keys and `--engine`
|
|
474
|
+
follow. Agent work keeps running on the program and model it ran on. An
|
|
475
|
+
`opencode-sdk` engine over an `llmEngine` ran OpenCode over that connection,
|
|
476
|
+
which is what akm's own runtime is, so it has no entry of its own;
|
|
477
|
+
- notes, when there is no `defaults.llmEngine` and no connection, that akm's own
|
|
478
|
+
model work (improve, index passes, extraction, judges) now runs on the default
|
|
479
|
+
harness where 0.9 ran none: 0.9 ran it only where `defaults.llmEngine` or a
|
|
480
|
+
setting named an engine, and a workflow gate's judge ran on `defaults.engine`.
|
|
481
|
+
To keep the 0.9 behaviour, set `modelWork: false` on that harness; a call that
|
|
482
|
+
names the harness still runs there, and a gate's judge then needs a
|
|
483
|
+
connection;
|
|
484
|
+
|
|
441
485
|
- moves every key akm no longer reads from config (an engine's `apiKeyFile`, a
|
|
442
486
|
literal or `${secrets/...}` `apiKey`, and the same on a connection,
|
|
443
487
|
`embedding` or `search.curateRerank`) into `credentials.json`, for the
|
|
@@ -457,8 +501,10 @@ harness the loader cannot use in the file, with a note on what to fix. It also:
|
|
|
457
501
|
the older entry, and a different key or endpoint leaves both, with a note;
|
|
458
502
|
- folds `models.json` into the `models` of the connections and harnesses it
|
|
459
503
|
names (a connection's own column first, then the `*` column and the flat
|
|
460
|
-
shorthand, then the engine's own model; a
|
|
461
|
-
|
|
504
|
+
shorthand, then the engine's own model; a harness engine's own model stands
|
|
505
|
+
over every column, as it is what ran when a request named none; a model the
|
|
506
|
+
config already names stands; the entries it cannot place are listed in the
|
|
507
|
+
notes) and moves the
|
|
462
508
|
file to `<cache dir>/config-backups/`;
|
|
463
509
|
- rewrites `engine:` on commands, agents, workflows and task sources to
|
|
464
510
|
`connection:` or `harness:` by what the name is now (a name that is neither is
|
|
@@ -480,9 +526,14 @@ strategy's `engine`, `model`, `llm` and `timeoutMs`, an index pass's `engine`
|
|
|
480
526
|
that names a harness (an index pass can only name a connection; with none named
|
|
481
527
|
it runs where all model work does, on the default connection, else the default
|
|
482
528
|
harness, restricted where the harness can be), `models.json`
|
|
483
|
-
entries that name nothing configured, and
|
|
484
|
-
|
|
485
|
-
|
|
529
|
+
entries that name nothing configured, and the model, timeout and workspace of an
|
|
530
|
+
`opencode-sdk` engine that ran over an `llmEngine` (akm's own runtime has no
|
|
531
|
+
entry in config; that connection becomes `default`). `workflow.judgeEngine`
|
|
532
|
+
is dropped because a gate's judge runs on the default connection, else the
|
|
533
|
+
default harness; its note says whether that moves the judge, and with no
|
|
534
|
+
`workflow.judgeEngine` a note says when the judge `defaults.engine` ran it on
|
|
535
|
+
is no longer where it runs. A workflow run
|
|
536
|
+
frozen by an earlier
|
|
486
537
|
release (plan version 7 or lower) whose plan holds a command target cannot be
|
|
487
538
|
resumed: `akm workflow run` abandons it with a message naming `akm workflow run
|
|
488
539
|
<ref>` to start afresh. Let such runs finish before you upgrade.
|
|
@@ -750,7 +801,7 @@ below every daily alpha. Install the first monthly release explicitly once, for
|
|
|
750
801
|
example `npm install -g akm-cli@0.10.261001-beta`; `akm upgrade` works normally
|
|
751
802
|
from there.
|
|
752
803
|
|
|
753
|
-
`akm help migrate 0.10.
|
|
804
|
+
`akm help migrate 0.10.261019` (or `akm help migrate latest`) prints the [0.10 release note](release-notes/0.10.261019.md).
|
|
754
805
|
The loader looks a note up by its exact file name, so `akm help migrate latest`
|
|
755
806
|
and a release number such as `0.10.261001` print the CHANGELOG section
|
|
756
807
|
only.
|
|
@@ -106,7 +106,7 @@ akm reads these keys of a connection:
|
|
|
106
106
|
| `apiKeyFile` | Retired. `akm migrate apply` leaves an engine's key file here, as written, when it cannot read the file yet; akm ignores it (never reads it or sends it) and a later `akm migrate apply` moves the key it names into `credentials.json`. |
|
|
107
107
|
| `models` | Alias to model. See [Aliases](#aliases). |
|
|
108
108
|
| `contextLength` | The model's context window in tokens. `akm improve` sizes its prompts from it (consolidate's chunks, reflect's asset content); unset, it assumes 4096. |
|
|
109
|
-
| `timeoutMs` | How long one call may take, in milliseconds; `null` runs unbounded. Unset, a model call stops after 600 000 (ten minutes) and agent work runs until it finishes. The ceiling is 2 147 483 647. |
|
|
109
|
+
| `timeoutMs` | How long one call may take, in milliseconds; `null` runs unbounded. Unset, a model call stops after 600 000 (ten minutes) and agent work runs until it finishes; akm's own runtime also tells a model that keeps repeating one tool call and result, and ends the run if it goes on, but does not stop one that keeps making different calls ([Without a harness](#without-a-harness)). The ceiling is 2 147 483 647. |
|
|
110
110
|
| `concurrency` | How many requests a workflow `map` step may have in flight on this connection, clamped to 1–64. Unset, 1 on a loopback endpoint (a local model server runs one inference at a time) and 4 on a remote one. akm never sends it. |
|
|
111
111
|
|
|
112
112
|
Every other key, on the connection or in a model entry, is a request field in
|
|
@@ -225,13 +225,13 @@ bindings.
|
|
|
225
225
|
|
|
226
226
|
What asks for a harness decides how akm runs it.
|
|
227
227
|
|
|
228
|
-
**Agent work** (`akm agent`, `akm command run`, `akm proposal new`, agent tasks and workflow agent steps) runs your program the way you would run it yourself. It gets your environment as it is, with nothing filtered out, and your configuration, plugins, settings and logins as they are. akm sets only its own variables for the run: the directories this akm resolved (`AKM_CONFIG_DIR`, `AKM_DATA_DIR`, `AKM_CACHE_DIR`, `AKM_STATE_DIR`, and `AKM_BUNDLE_DIR` when you set one), so a program that runs `akm` uses the same installation, and, when a task runs it, `AKM_EVENT_SOURCE` (unless already set), so the akm commands the program runs count as machine use, not yours. A workflow unit's or task's own `env:` bindings are set over them. On the command line, after your `args` as you wrote them, akm adds the model or agent the asset or flag names, the agent asset's persona where the program takes one there, and what the program needs to run without a person at the terminal: its print or exec mode and its approve-all switch where it asks before acting. Codex runs with the sandbox your Codex configuration sets, or the one your `args` name; model work runs it with `--sandbox read-only` (below). The prompt goes on standard input where the program reads it there and on the command line where it does not; standard output is the reply. `akm agent` with no `--prompt` starts the program interactively instead. What akm scrubs from the output it captures is in [Architecture: Connections and Harnesses](../architecture/architecture.md#connections-and-harnesses) and, for a workflow, [Workflow Schema](workflow-schema.md#the-childs-environment).
|
|
228
|
+
**Agent work** (`akm agent`, `akm command run`, `akm proposal new`, agent tasks and workflow agent steps) runs your program the way you would run it yourself. It gets your environment as it is, with nothing filtered out, and your configuration, plugins, settings and logins as they are. akm sets only its own variables for the run: the directories this akm resolved (`AKM_CONFIG_DIR`, `AKM_DATA_DIR`, `AKM_CACHE_DIR`, `AKM_STATE_DIR`, and `AKM_BUNDLE_DIR` when you set one), so a program that runs `akm` uses the same installation, and, when a task runs it, `AKM_EVENT_SOURCE` (unless already set), so the akm commands the program runs count as machine use, not yours. A workflow unit's or task's own `env:` bindings are set over them. A run given a directory (`--cwd`, a harness's `workspace`) starts there, and `PWD` names it too, as your shell sets it when you `cd` there; OpenCode takes its directory from `PWD`. On the command line, after your `args` as you wrote them, akm adds the model or agent the asset or flag names, the agent asset's persona where the program takes one there, and what the program needs to run without a person at the terminal: its print or exec mode and its approve-all switch where it asks before acting. Codex runs with the sandbox your Codex configuration sets, or the one your `args` name; model work runs it with `--sandbox read-only` (below). The prompt goes on standard input where the program reads it there and on the command line where it does not; standard output is the reply. `akm agent` with no `--prompt` starts the program interactively instead. What akm scrubs from the output it captures is in [Architecture: Connections and Harnesses](../architecture/architecture.md#connections-and-harnesses) and, for a workflow, [Workflow Schema](workflow-schema.md#the-childs-environment).
|
|
229
229
|
|
|
230
230
|
**Model work** (see [Where each process runs](#where-each-process-runs)) is akm's own process, so akm sets the call up as it needs it. The program has the same environment. akm runs it in a scratch directory that it creates for the call and removes after it, stamps the akm commands it runs `improve`, and runs no native agent of yours. Where the program can be restricted, akm also limits its tools. The "Restricted model work" column of the table says on which platforms (OpenCode: on version 2):
|
|
231
231
|
|
|
232
232
|
- Claude Code runs with `--restricted`, so none of your settings files can widen the tools; with `Read` and `Bash` only for `akm search`, `akm show` and `akm curate`; with no MCP servers; and with no transcript saved.
|
|
233
233
|
- Codex runs with `--sandbox read-only`.
|
|
234
|
-
- OpenCode 2 runs as the `akm-model-work` agent, which akm passes inline with the run, merged into your `OPENCODE_CONFIG_CONTENT` and keeping the rest of it; akm reads that variable as OpenCode does, as JSONC (comments and trailing commas), with its `{env:NAME}` references replaced as OpenCode replaces them when the content reads only that way (a reference written outside a string, such as a number), and leaves it out, with one warning, when it is not valid JSONC holding an object. akm writes it in OpenCode 2's native `agents` map, which OpenCode reads over the legacy `agent` map, so an entry of that name in your config, in either map, inline or in a file, does not change it (a same-named entry in your inline `agent` map is left out). Its tools are limited to reading and searching: every tool is denied except `read`, `glob` and `grep`, and `akm_search`, `akm_show` and `akm_curate` when you have the akm OpenCode plugin installed. A tool that a plugin of yours adds is denied too. The limit is on tools: your plugins' own setup and hooks still run in the session. The run is `--standalone`, one process that ends with it, with no background service left behind, and `--title akm`, which names the session and spares the second model request that would generate a title.
|
|
234
|
+
- OpenCode 2 runs as the `akm-model-work` agent, which akm passes inline with the run, merged into your `OPENCODE_CONFIG_CONTENT` and keeping the rest of it; akm reads that variable as OpenCode does, as JSONC (comments and trailing commas), with its `{env:NAME}` references replaced as OpenCode replaces them when the content reads only that way (a reference written outside a string, such as a number), and leaves it out, with one warning, when it is not valid JSONC holding an object. akm writes it in OpenCode 2's native `agents` map, which OpenCode reads over the legacy `agent` map, so an entry of that name in your config, in either map, inline or in a file, does not change it (a same-named entry in your inline `agent` map is left out). Its tools are limited to reading and searching: every tool is denied except `read`, `glob` and `grep`, and `akm_search`, `akm_show` and `akm_curate` when you have the akm OpenCode plugin installed. A tool that a plugin of yours adds is denied too. OpenCode's built-in browser plugin is left out of the run (`-opencode.browser` after your `plugins`): model work denies the browser anyway, and from OpenCode 2.2.0 the plugin's own rules would keep the `skill` tool listed. The limit is on tools: your plugins' own setup and hooks still run in the session. The run is `--standalone`, one process that ends with it, with no background service left behind, and `--title akm`, which names the session and spares the second model request that would generate a title.
|
|
235
235
|
- On Claude Code, Codex and OpenCode, `args` do not apply to model work, except a `--model` they name.
|
|
236
236
|
- OpenCode 1 and every other platform cannot be restricted: the run is unrestricted, in the scratch directory, and akm reports that. The other platforms get the agent-work command line, `args` included.
|
|
237
237
|
- OpenCode model work sets `OPENCODE_DISABLE_FREE_MODELS=1`, which OpenCode 2.1.2 and later honor: a call with no usable provider fails instead of sending the prompt to OpenCode's hosted free model, and so does a call whose model (named, or your OpenCode's default) is one of its free ones. Agent work does not set it: your OpenCode's models are as you would get running it by hand.
|
|
@@ -240,7 +240,7 @@ Where model work is restricted, its tools cannot change the library, so what it
|
|
|
240
240
|
|
|
241
241
|
**History.** A harness run leaves a session in the program's own history, and `akm proposal extract` and improve read that history like any other. The exceptions are the model-work sessions akm marked: Claude Code keeps no transcript of them, and OpenCode 2 records them under the `akm-model-work` agent, which the reader skips. Codex and OpenCode 1 cannot be marked, so their model-work sessions are read like any other. akm's own runtime (below) keeps its sessions in `<akm data dir>/opencode-runtime/data/opencode/opencode.db`, read the same way.
|
|
242
242
|
|
|
243
|
-
**Stopping.** When akm stops a run (a timeout, an abort or a signal to akm) it sends the program's process group SIGINT, as Ctrl-C would. If anything in the group still runs after 5 seconds, or as soon as the program itself has exited and left members behind, it sends SIGTERM, and 5 seconds after that SIGKILL if anything still runs. Workflow `exec` units and task commands are stopped the same way. Windows has no process groups, and a signal sent to a process there ends it at once. A program that records how a run ended acts on the SIGINT: OpenCode 2 marks its session interrupted and releases it, and only a run that had to be terminated or killed stays suspended in your OpenCode history, where your own OpenCode's background service may resume it when it next starts (up to ten attempts, OpenCode's own policy). Through OpenCode 2's background service (measured on 2.1.4) the interrupt ends the `opencode` command and the service's turn alike: the service abandons the turn's model request and marks the session interrupted, and keeps running itself.
|
|
243
|
+
**Stopping.** When akm stops a run (a timeout, an abort or a signal to akm) it sends the program's process group SIGINT, as Ctrl-C would. If anything in the group still runs after 5 seconds, or as soon as the program itself has exited and left members behind, it sends SIGTERM, and 5 seconds after that SIGKILL if anything still runs. Workflow `exec` units and task commands are stopped the same way. Windows has no process groups, and a signal sent to a process there ends it at once. A program that records how a run ended acts on the SIGINT: OpenCode 2 marks its session interrupted and releases it, and only a run that had to be terminated or killed stays suspended in your OpenCode history, where your own OpenCode's background service may resume it when it next starts (up to ten attempts, OpenCode's own policy). Through OpenCode 2's background service (measured on 2.1.4 and 2.2.0) the interrupt ends the `opencode` command and the service's turn alike: the service abandons the turn's model request and marks the session interrupted, and keeps running itself.
|
|
244
244
|
|
|
245
245
|
**OpenCode.** The `opencode` platform runs your installed OpenCode, either major version, as `opencode run`; the reply is its standard output. Agent work is that command with the prompt on stdin, your `args` as written, `--model` when akm names a model and `--agent` when the asset names an agent. Your OpenCode owns its configuration, logins, token refresh and sessions: akm reads, copies and embeds nothing of yours.
|
|
246
246
|
- OpenCode 2 runs agent work through its own background service, which stays up after the command. Add `--standalone` to the harness's `args` for a run that is one process.
|
|
@@ -254,13 +254,13 @@ alike.
|
|
|
254
254
|
### Without a harness
|
|
255
255
|
|
|
256
256
|
Agent work runs on akm's own runtime when no harness is configured: a pinned
|
|
257
|
-
OpenCode 2 binary (2.
|
|
257
|
+
OpenCode 2 binary (2.2.0) that akm runs as a process for each run, driven by the
|
|
258
258
|
default connection. The npm package and the standalone binary do the same.
|
|
259
259
|
|
|
260
260
|
- **The first run fetches OpenCode.** akm downloads the binary for your platform
|
|
261
261
|
from the npm registry, one package of about 114 MB (240 MB on disk), checks it
|
|
262
262
|
against the registry's integrity hash, and keeps it in
|
|
263
|
-
`<akm cache dir>/opencode/2.
|
|
263
|
+
`<akm cache dir>/opencode/2.2.0/`; later runs, and later versions of akm that
|
|
264
264
|
pin the same OpenCode, fetch nothing. Nothing else is downloaded: the binary
|
|
265
265
|
carries the package it reaches the endpoint with. If the fetch fails the run
|
|
266
266
|
fails as not started, naming the package, its URL and the cache path. With no
|
|
@@ -304,7 +304,37 @@ default connection. The npm package and the standalone binary do the same.
|
|
|
304
304
|
- A run reports its session id and the tokens its turn used, read from that
|
|
305
305
|
session once the process has ended; a workflow's `budget.max_tokens` counts
|
|
306
306
|
them. A failed run is a non-zero exit with OpenCode's own message
|
|
307
|
-
(`non_zero_exit`), as for a harness
|
|
307
|
+
(`non_zero_exit`), as for a harness; when the session recorded why its turn
|
|
308
|
+
failed, the run's error carries that too, so a workflow's unit shows it.
|
|
309
|
+
- A model that repeats itself is told, then stopped. When it has made the same
|
|
310
|
+
tool call, with the same input, and been given the same result three turns in
|
|
311
|
+
a row, akm adds a message from the user to its next request: it names the
|
|
312
|
+
tool, says the result will not change, asks the model to use the result it
|
|
313
|
+
has or take a different approach, and says that calling it again stops the
|
|
314
|
+
run. **That one request overrides a lower temperature the connection sets**:
|
|
315
|
+
a `temperature` below 0.7 (0, say) is sent as 0.7, because a model sampled
|
|
316
|
+
greedily (temperature 0) gave the same call again to every wording in every
|
|
317
|
+
try, so at 0 the message alone does nothing, and at 0.7 it left the repeat in
|
|
318
|
+
about half of them. A connection that sets no `temperature` sends none on that
|
|
319
|
+
request either (the endpoint's default applies, and OpenAI's reasoning models
|
|
320
|
+
refuse any other), and one of 0.7 or more is kept. Every other request keeps
|
|
321
|
+
the connection's settings. If the model makes the same call again, or, after
|
|
322
|
+
other calls, makes it three turns in a row again, the run fails
|
|
323
|
+
(`non_zero_exit`) with a message that names the tool. One that changes course
|
|
324
|
+
is not stopped. Each session of a run (a subagent's too) is told for itself.
|
|
325
|
+
OpenCode has no check of its own for this, and with `timeoutMs` unset such a
|
|
326
|
+
run would never end. A call whose result changes is not a repeat, but a poll
|
|
327
|
+
that gets the same answer three times in a row is. An output too long to send
|
|
328
|
+
whole is compared by its text, not by the file OpenCode saves it to. The
|
|
329
|
+
message is added to the request on its way to the model, so OpenCode's stored
|
|
330
|
+
session does not show it; the stop is recorded as any failure is. Only akm's
|
|
331
|
+
own runtime does this; a harness is your program, with whatever limits it has.
|
|
332
|
+
- A run that keeps making different calls is not stopped by that. Its timeout
|
|
333
|
+
bounds it: the connection's `timeoutMs`, one the run is given (`akm agent
|
|
334
|
+
--timeout-ms`, `akm workflow run --timeout`, a workflow unit's `timeout`) or,
|
|
335
|
+
in a scheduled task, the task's `timeout:` (six hours when unset). With none,
|
|
336
|
+
as for `akm agent` and `akm workflow run` by default, it runs until it
|
|
337
|
+
finishes.
|
|
308
338
|
- Runs that start together, in one akm process or several, wait while the first
|
|
309
339
|
run of this OpenCode version prepares its database alone.
|
|
310
340
|
|
|
@@ -736,7 +766,7 @@ index and a warning from `akm health`.
|
|
|
736
766
|
- `models/Xenova/bge-small-en-v1.5/` holding `tokenizer.json`,
|
|
737
767
|
`tokenizer_config.json`, `config.json` and `onnx/model.onnx`, or set `HF_HOME`
|
|
738
768
|
to a directory that holds them and `HF_HUB_OFFLINE=1`.
|
|
739
|
-
- `opencode/2.
|
|
769
|
+
- `opencode/2.2.0/opencode` (`opencode.exe` on Windows) for akm's own agent
|
|
740
770
|
runtime.
|
|
741
771
|
The default is `"off"` so a bare or headless install (`akm bundle create`, `--yes`,
|
|
742
772
|
`--config`) never silently downloads the local embedding model on first
|
|
@@ -1139,18 +1169,20 @@ asset keys move as the table says.
|
|
|
1139
1169
|
| In the file | What `akm migrate apply` does |
|
|
1140
1170
|
| --- | --- |
|
|
1141
1171
|
| `engines.<name>` with `kind: "llm"` | `connections.<name>`. `endpoint`, `contextLength`, `timeoutMs`, `concurrency` and an `apiKey` that is a `$VAR` are kept. `model` becomes `models`, with `fast`, `balanced` and `reasoning` all naming it. `temperature`, `maxTokens`, `enableThinking`, `reasoningEffort` and `extraParams` become request fields (`temperature`, `max_tokens`, `enable_thinking` with `chat_template_kwargs.enable_thinking`, `reasoning_effort`, and the extras as written). `kind`, `provider` and `supportsJsonSchema` are dropped, with a note. |
|
|
1142
|
-
| `engines.<name>` with `kind: "agent"` and `platform: "opencode-sdk"` |
|
|
1172
|
+
| `engines.<name>` with `kind: "agent"` and `platform: "opencode-sdk"`, no `llmEngine` | `harnesses.<name>` with `platform: "opencode"`. The engine ran your own OpenCode, with its providers, models and logins, and the `opencode` harness runs it now. `bin`, `workspace`, `agent` and `timeoutMs` are kept, and `model` (an OpenCode `provider/model`) becomes `models`, naming it for all three aliases. `args` is dropped, with a note: 0.9 did not pass it to OpenCode. |
|
|
1173
|
+
| `engines.<name>` with `kind: "agent"` and `platform: "opencode-sdk"`, with an `llmEngine` | Removed: OpenCode ran over that connection, which is what akm's own runtime is, so it has no entry. When `defaults.llmEngine` or `defaults.engine` names the engine, and `defaults.llmEngine` names no connection, the `llmEngine` connection becomes `default`. The engine's `model`, `timeoutMs`, `workspace`, `bin` and `agent` are dropped, with a note naming those it set. |
|
|
1143
1174
|
| `engines.<name>` with `kind: "agent"`, any other platform | `harnesses.<name>`, keeping `platform`, `bin`, `args`, `workspace`, `agent` and `timeoutMs`. `model` becomes `models`, naming it for all three aliases. |
|
|
1144
|
-
| `defaults.llmEngine`, else `defaults.engine` when it names an LLM engine | That connection is renamed `default`, and every reference to the old name follows. An entry already called `default` moves aside to `legacy-default`, or the first `legacy-default-<n>` nothing else has: the renaming is one name to one name, so no two entries share a name and none is lost. |
|
|
1145
|
-
| `defaults.engine` naming an agent engine, when there are several | That harness is renamed `default`. |
|
|
1175
|
+
| `defaults.llmEngine`, else `defaults.engine` when it names an LLM engine | That connection is renamed `default`, and every reference to the old name follows. An entry already called `default` moves aside to `legacy-default`, or the first `legacy-default-<n>` nothing else has: the renaming is one name to one name, so no two entries share a name and none is lost. A `defaults.llmEngine` that named an agent engine ran akm's model work there; model work runs on the default connection, else the default harness, so a note says when that is another place and names `improve.harness`. With no `defaults.llmEngine` and no connection, 0.9 ran no model work unless a setting named an engine and the default harness takes it now; a note says so and how to turn it off (`modelWork: false`). |
|
|
1176
|
+
| `defaults.engine` naming an agent engine, when there are several | That harness is renamed `default`. With no `defaults.engine`, an engine called `opencode-sdk` is the default agent engine, as the 0.9 fallback made it. |
|
|
1177
|
+
| No `defaults.engine` | 0.9 ran agent work on your own OpenCode, when it was installed. A note says where agent work runs now: on the harness if one is configured, else on akm's own runtime, and then how to enable the harness (`akm setup --harness opencode`). |
|
|
1146
1178
|
| `defaults.improveStrategy` | `improve.strategy`. |
|
|
1147
|
-
| `models.json` | Folded into the `models` of the connections and harnesses it names; what it cannot place is listed in the notes. The file moves to `config-backups/` in the cache directory. |
|
|
1179
|
+
| `models.json` | Folded into the `models` of the connections and harnesses it names; what it cannot place is listed in the notes. The `opencode-sdk` column names the harnesses that were `opencode-sdk` engines, and the `opencode` column those that were `platform: "opencode"`. A harness whose engine had a `model` of its own keeps it for every alias, over any column: it is what ran when a request named none. The file moves to `config-backups/` in the cache directory. |
|
|
1148
1180
|
| `apiKeyFile`, a literal `apiKey`, a `${secrets/...}` `apiKey` | The key moves to `credentials.json` for the connection and its endpoint; a note names where it was, never its value. A key that cannot be read stays on the connection as it was (`apiKey`, or `apiKeyFile` for a key file), with a note that it is still to do; a later run moves it once it can be read. |
|
|
1149
1181
|
| `AKM_ENGINE_<NAME>_API_KEY` or `AKM_LLM_API_KEY` set in the environment | `apiKey: "$AKM_ENGINE_<NAME>_API_KEY"` (or `$AKM_LLM_API_KEY`) on that connection. Set in no variable, an engine that names no key gets none, and a note names the variables 0.9 read. |
|
|
1150
1182
|
| `improve.strategies.<name>.engine`, `model`, `llm`, `timeoutMs` | Dropped, with a note: a strategy says which processes run, not where. |
|
|
1151
1183
|
| `engine`, `model`, `llm`, `timeoutMs` on a strategy's process, its `qualityGate` or its `triage.judgment` | Moved to `improve.processes.<process>` or `improve.qualityGate`, with `engine` becoming `connection` or `harness` by what it named. When that place already says, the first one is kept, with a note. |
|
|
1152
1184
|
| `index.defaults.*`, `index.<pass>.engine` | `index.*`, and `connection`. An index pass cannot name a harness, so an engine that named one is dropped, with a note; a pass that names nothing runs where model work does: on the default connection, else the default harness. |
|
|
1153
|
-
| `workflow.judgeEngine` | Dropped, with a note. |
|
|
1185
|
+
| `workflow.judgeEngine` | Dropped, with a note: a gate's judge runs on the default connection, else the default harness. The note says whether the engine it named is that default, or the judge has moved. With none set, 0.9 ran the judge on `defaults.engine`; a note says when that is not where it runs now. |
|
|
1154
1186
|
| `engine:` in an asset's frontmatter, a workflow step or a task source | `connection:` or `harness:`, by what the configured target is; a name it cannot place becomes `harness:`, with a note. A bundle akm may not change, and an asset that is a symbolic link, are skipped. |
|
|
1155
1187
|
|
|
1156
1188
|
An `engine:` key on an asset that has not been migrated is read the same way,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akm-cli",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.261019",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cursor.",
|
|
6
6
|
"keywords": [
|