@akanjs/cli 3.0.0-alpha.41 → 3.0.0-alpha.42
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
|
-
|
|
1
|
+
eaeb44245969a1707e38a765624a1541652e2558214acaf1d91d2be618ba8bbe
|
|
@@ -689,6 +689,13 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
689
689
|
providers the way middleware is applied: `option.applyAdaptor(LlmAdaptorRole, ClaudeLlm)`, where the
|
|
690
690
|
implementation is an `adapt()` class in a `srvkit/` implementing `LlmAdaptor.chat(request, onDelta?)` — ignore
|
|
691
691
|
`onDelta` and the chat still answers whole.
|
|
692
|
+
- **An adaptor answers `null` for "not configured" and *throws* for a refusal it can explain.** The two are
|
|
693
|
+
different things to be told: collapsing both into `null`, the way the adapter convention otherwise reads, left a
|
|
694
|
+
user reading `llmUnavailable` — "no model is configured" — about a conversation that had merely outgrown the
|
|
695
|
+
context window. A thrown `Err` reaches the chat as its own text, so the reason the provider gave is what the
|
|
696
|
+
user sees. It travels as the dictionary key plus the values that key interpolates, on both the JSON and the SSE
|
|
697
|
+
path, and **`fetchRunner` resolves it against the dictionary one step before the transcript** — the endpoint has
|
|
698
|
+
no language to resolve it in and the browser does, which is why the key was reaching the screen raw.
|
|
692
699
|
- **A file the user attaches rides the message, and nothing is stored.** The composer takes a paperclip, a drop and
|
|
693
700
|
a paste; an image rides as bytes and a text file as text, which is all a browser reads with no dependency.
|
|
694
701
|
Everything else is the app's own reader — `<Agent.Chat attach={…} />`, one `File` in, a `MessageAttachment` or
|
|
@@ -897,9 +904,9 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
897
904
|
- **`prompt()` endpoints double as the chat's slash commands.** There is no listing endpoint — the client reads
|
|
898
905
|
its own serialized signals — so a prompt's dictionary `.desc()` is what the menu shows, and its guards are
|
|
899
906
|
enforced by the prompt's own GET at call time.
|
|
900
|
-
- **The chat answers
|
|
901
|
-
`/new` (`/clear`), `/retry`, `/copy`, `/help` and `/tools`. An app writes none of them and cannot add
|
|
902
|
-
extension point for a product's own command is a `prompt()` endpoint, which is guarded and server-side.
|
|
907
|
+
- **The chat answers six slash commands of its own**, listed in the same `/` menu ahead of the prompts:
|
|
908
|
+
`/new` (`/clear`), `/retry`, `/compact`, `/copy`, `/help` and `/tools`. An app writes none of them and cannot add
|
|
909
|
+
one — the extension point for a product's own command is a `prompt()` endpoint, which is guarded and server-side.
|
|
903
910
|
**A built-in wins a name collision with a prompt of the same name**, the mirror image of the tool rule: a
|
|
904
911
|
component's `st.tool` shadows a built-in it means to replace, but no library's prompt may take `/new` away from
|
|
905
912
|
the user who typed it — so a shadowed prompt is dropped from the menu rather than listed twice. `/new` and
|
|
@@ -916,6 +923,22 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
916
923
|
only in that browser, so an export is the one path a wrong answer has to whoever could fix it — which is why it
|
|
917
924
|
carries the route and the timestamp. `/retry` replays only the trailing user message, leaving anything before it
|
|
918
925
|
in place, so a prompt's own preamble is not sent twice.
|
|
926
|
+
- **A long conversation summarizes itself, because nothing else is keeping it inside the model's window.** The
|
|
927
|
+
loop runs in the browser and the relay holds no session, so an uncompacted chat grows until the provider
|
|
928
|
+
refuses the whole request — a refusal, never a shorter answer, which is why compaction runs *before* the turn
|
|
929
|
+
that would have overflowed rather than as a recovery after it. Past `compact.at` estimated tokens (four
|
|
930
|
+
characters to a token, over the JSON the turn posts; 24k by default, well under the smallest window a provider
|
|
931
|
+
is likely to have, since the tools and the screen context ride on top of it and neither compacts) the history above the last `keep` messages
|
|
932
|
+
becomes one message standing in for it, flagged `summary` on the wire — `<Agent.Chat compact={{ at, keep }} />`
|
|
933
|
+
tunes it per provider and `{ at: 0 }` turns it off, and `/compact` does the same on demand keeping nothing.
|
|
934
|
+
**The cut only ever lands on a user message**: everything above one is settled, so the kept half can never open
|
|
935
|
+
with a `tool` result whose call was summarized away, a shape every provider dialect rejects. The summarizing
|
|
936
|
+
turn carries no tools and no screen context — it summarizes the conversation, it does not act on it — and it is
|
|
937
|
+
fed a *bounded* digest rather than the transcript itself, since the transcript being summarized is the one that
|
|
938
|
+
no longer fits. A summary that cannot be produced leaves the transcript alone and the turn goes out as it would
|
|
939
|
+
have; one that fails to shrink anything is not retried until another threshold's worth has been added. On the
|
|
940
|
+
wire a summary wears the user's role because the wire has no other, so a provider mapping frames it as a system
|
|
941
|
+
message and `/retry` steps over it — replaying it would send the notes back as a question.
|
|
919
942
|
- **↑ and ↓ in the composer walk what was sent.** A single-line input has nothing of its own on the vertical
|
|
920
943
|
arrows, and the half-written draft they were walked away from comes back at the bottom of the walk.
|
|
921
944
|
- The framework publishes six built-ins on every store surface: `navigate` (internal paths only, the same
|
|
@@ -939,12 +962,13 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
939
962
|
`maxTurns` budget in seconds on a job measured in minutes. Say so in the `desc` ("takes about two minutes; do
|
|
940
963
|
not poll while it runs") and, for a route full of slow work, in an `Agent.Guide`.
|
|
941
964
|
- **`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
|
|
943
|
-
the moment the key moves; `equals` waits for one value, omitted it waits for
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
965
|
+
or by a person clicking the button. It parks on a **store state key a mounted component subscribes**, exactly the
|
|
966
|
+
set `readState` reads, and resumes the moment the key moves; `equals` waits for one value, omitted it waits for
|
|
967
|
+
any change. **Not a resource**: `st.expose` and `st.useState` register on the surface, whose values already ride
|
|
968
|
+
inline in the screen context block, and `waitFor` refuses one of those names like any other. Deliberately not a
|
|
969
|
+
bare sleep either — a sleep only makes the polling slower, and a value worth waiting minutes for is server-derived
|
|
970
|
+
state, which lives in the store already. Running out is not a failure, it answers with what the key holds now
|
|
971
|
+
(default 120s, clamped to 600), and a key this screen does not read is refused by name with the ones it does.
|
|
948
972
|
- **Stop reaches a tool that is still running.** The session races every call against its abort signal, so a
|
|
949
973
|
two-minute tool does not hold the loop for two minutes after the user presses Stop. The signal itself arrives
|
|
950
974
|
through `AgentAbort.current` — the same module slot `AgentProgress` is — and honouring it is optional, since the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/cli",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.42",
|
|
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.
|
|
37
|
+
"akanjs": "3.0.0-alpha.42",
|
|
38
38
|
"chalk": "^5.6.2",
|
|
39
39
|
"commander": "^14.0.3",
|
|
40
40
|
"dayjs": "^1.11.20",
|