@akanjs/cli 3.0.0-alpha.40 → 3.0.0-alpha.41

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/.build-stamp CHANGED
@@ -1 +1 @@
1
- 873ee7e4176e7c5645844f46050d48c225f02463271a6932419b73784565ed10
1
+ ebe6f07427135e1b11548007c742cfa1e62256965f0de2c84b3f816d97ef8688
@@ -918,13 +918,13 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
918
918
  in place, so a prompt's own preamble is not sent twice.
919
919
  - **↑ and ↓ in the composer walk what was sent.** A single-line input has nothing of its own on the vertical
920
920
  arrows, and the half-written draft they were walked away from comes back at the bottom of the walk.
921
- - The framework publishes five built-ins on every store surface: `navigate` (internal paths only, the same
921
+ - The framework publishes six built-ins on every store surface: `navigate` (internal paths only, the same
922
922
  router `Link` rides), `goBack` (this session's history — global, because history is not a control a page owns and
923
923
  a page that draws no back link is not one you may not leave), `readScreen` (the rendered DOM as compact text —
924
924
  headings, links, control values, and `(disabled)` on a control or button that has it; the chat's own UI is
925
- skipped via `data-agent-ui`, and a password value is never read), `readState(key)` (one masked store key), and
926
- `highlight(target)`. Declaring a hook tool under one of those names shadows the built-in, so reuse them only to
927
- mean that.
925
+ skipped via `data-agent-ui`, and a password value is never read), `readState(key)` (one masked store key),
926
+ `waitFor(key)` (park until that key moves), and `highlight(target)`. Declaring a hook tool under one of those
927
+ names shadows the built-in, so reuse them only to mean that.
928
928
  - **A tool that changes the screen waits for the screen before it answers.** `router.push` returns while the RSC
929
929
  payload is still in flight and a store action that fires `void fetch.*` commits a tick later, so `navigate`
930
930
  awaits `ScreenSettle.wait()` — DOM quiescence, bounded, because the client router hands its promise to nobody —
@@ -932,6 +932,25 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
932
932
  describes the moment before the change landed and the `readScreen` that follows reads the page the user left.
933
933
  New tools and state from a fresh route are still only listed from the next turn: the catalogue is snapshotted
934
934
  when the turn starts.
935
+ - **A tool that waits for its own work costs no model turns; one that returns early costs one round trip per
936
+ look.** The session awaits `run`, so a `.exec` that awaits the store action finishing the job simply makes the
937
+ turn take that long — and the change report that follows carries whatever landed, so the model needs no second
938
+ call to read the result. A fire-and-forget tool leaves the agent to poll instead, which burns the whole
939
+ `maxTurns` budget in seconds on a job measured in minutes. Say so in the `desc` ("takes about two minutes; do
940
+ not poll while it runs") and, for a route full of slow work, in an `Agent.Guide`.
941
+ - **`waitFor(key, equals?, timeoutSeconds?)` is for the job the *tool* cannot await** — started in an earlier turn,
942
+ or by a person clicking the button. It parks on a published state key, the ones `readState` lists, and resumes
943
+ the moment the key moves; `equals` waits for one value, omitted it waits for any change. Deliberately not a bare
944
+ sleep: a sleep only makes the polling slower, and a screen able to report progress reports it into the store, so
945
+ a screen that reports none publishes a key with `st.expose` — worth doing anyway, since the key becomes readable
946
+ too. Running out is not a failure, it answers with what the key holds now (default 120s, clamped to 600), and a
947
+ key this screen does not read is refused by name with the ones it does.
948
+ - **Stop reaches a tool that is still running.** The session races every call against its abort signal, so a
949
+ two-minute tool does not hold the loop for two minutes after the user presses Stop. The signal itself arrives
950
+ through `AgentAbort.current` — the same module slot `AgentProgress` is — and honouring it is optional, since the
951
+ race lands whatever the tool does; what it buys is the tool's own cleanup, a timer or a poll loop that would
952
+ otherwise run out with nobody left to answer. A tool that ignores it is left running rather than cancelled: the
953
+ work is usually a job a server is already doing.
935
954
  - **`readScreen` takes a `section`, and `highlight` a `target`.** Both resolve a name the agent has already seen —
936
955
  a `data-akan-action` / `data-akan-state` annotation, an `Agent.Zone` or `useScreenScope` container
937
956
  (`data-agent-scope`, which `Load.Units` / `Load.View` / `Data.ListContainer` put on the container they render),
@@ -950,7 +969,8 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
950
969
  - **A slow tool reports its own progress with `AgentProgress.report(message, { done, total })`** from wherever the
951
970
  work is — a store action, an upload loop, an adapter — reached through a module slot rather than a parameter, and
952
971
  a no-op when nobody is rendering it. The chat shows it on that call's row until the row resolves. It is the
953
- browser twin of `McpProgress.report`.
972
+ browser twin of `McpProgress.report`. Import it and `AgentAbort` from `akanjs/store`: an app may not reach
973
+ `use-agentic` directly (`no-import-external-library`), and those two are the channels a long tool body needs.
954
974
  - **The turn cap is a question, not a dead end.** At `maxTurns` the session asks whether to keep going through the
955
975
  same card `askUser` uses, and the answer rides as the user's own turn — so a steer typed instead of the
956
976
  keep-going choice reaches the model as guidance. A host that renders no `pendingQuestion` passes no
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/cli",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -34,7 +34,7 @@
34
34
  "@langchain/openai": "^1.4.6",
35
35
  "@tailwindcss/node": "^4.3.0",
36
36
  "@trapezedev/project": "^7.1.4",
37
- "akanjs": "3.0.0-alpha.40",
37
+ "akanjs": "3.0.0-alpha.41",
38
38
  "chalk": "^5.6.2",
39
39
  "commander": "^14.0.3",
40
40
  "dayjs": "^1.11.20",