@akanjs/cli 3.0.0-beta.0 → 3.0.0-beta.1
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
|
+
d72ecb79076daa348d8166c58417584a4ceda3a467c9d1a7ca95d7d85863822a
|
|
@@ -72,9 +72,22 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
72
72
|
fills whichever adaptor holds `LlmAdaptorRole`, reaching it as the `llmOption` use. The settings are the role's
|
|
73
73
|
rather than one provider's, so they survive a swap. **DeepSeek is the built-in default** (`deepseek-v4-flash` at
|
|
74
74
|
`https://api.deepseek.com`); with no `apiKey` the app still boots and the chat answers `llmUnavailable`. Swap
|
|
75
|
-
providers the way middleware is applied: `option.applyAdaptor(LlmAdaptorRole,
|
|
76
|
-
|
|
77
|
-
`onDelta`
|
|
75
|
+
providers the way middleware is applied: `option.applyAdaptor(LlmAdaptorRole, AnthropicLlm)`. An app may still
|
|
76
|
+
write its own — an `adapt()` class in a `srvkit/` implementing `LlmAdaptor.chat(request, onDelta?)`, where
|
|
77
|
+
ignoring `onDelta` still answers whole — but for vision it no longer has to.
|
|
78
|
+
- **Three providers ship, and only two of them read a picture.** `DeepseekLlm` is the default and declares no
|
|
79
|
+
`accepts`, which is a fact about its API rather than a gap. `OpenaiLlm` speaks the same chat-completions dialect
|
|
80
|
+
— `OpenaiDialect`, shared between them so a protocol fix lands once — against `https://api.openai.com/v1` and
|
|
81
|
+
declares `{ image: true }`, sending an image as a content part. `AnthropicLlm` is the Messages API and declares
|
|
82
|
+
`{ image: true, document: true }`; it is its own file rather than a branch, because the system prompt is a field
|
|
83
|
+
and not a message, tool calls and results are content blocks, the results ride in a *user* turn, roles must
|
|
84
|
+
alternate — so two wire turns that map to one role are merged — and `max_tokens` is required. **Both new ones
|
|
85
|
+
require `model`**: a default would age into a 404, and worse, it would decide the vision claim for the app.
|
|
86
|
+
- **`accepts` is answered per model, through `option.setLlm({ accepts })`.** An adaptor answers for an API and one
|
|
87
|
+
API serves models that differ, so the override rides beside the `model` it is a fact about. It is not a table
|
|
88
|
+
the framework keeps: a table is a claim about models that ship after it, and getting this wrong is the worst
|
|
89
|
+
failure available — a provider handed bytes it cannot decode either refuses the turn or accepts it having seen
|
|
90
|
+
nothing, and the model then answers confidently about a file it never read.
|
|
78
91
|
- **An adaptor answers `null` for "not configured" and *throws* for a refusal it can explain.** The two are
|
|
79
92
|
different things to be told: collapsing both into `null`, the way the adapter convention otherwise reads, left a
|
|
80
93
|
user reading `llmUnavailable` — "no model is configured" — about a conversation that had merely outgrown the
|
|
@@ -92,8 +105,11 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
92
105
|
prompt. **What the provider cannot read is replaced by a note naming the file**, never dropped: an attachment the
|
|
93
106
|
model never saw is one it answers about from the filename. An adaptor declares `accepts: { image, document }` and
|
|
94
107
|
`AgentService.readable` degrades the rest, so a text-only provider needs no attachment code at all — DeepSeek
|
|
95
|
-
declares none, which is why an image against the default provider is refused out loud while an extracted PDF
|
|
96
|
-
works, `text` being readable by every model there is.
|
|
108
|
+
declares none, which is why an image against the *default* provider is refused out loud while an extracted PDF
|
|
109
|
+
works, `text` being readable by every model there is. Swap in `OpenaiLlm` or `AnthropicLlm` and the same image
|
|
110
|
+
arrives as an image. `accepts.document` is one boolean over every non-image type, so an adaptor whose API has a
|
|
111
|
+
block for only some of them — Anthropic's `document` is PDF and nothing else — names the rest in the text rather
|
|
112
|
+
than dropping them, which is the wire's own rule applied at the one layer that knows which blocks exist. Persisting keeps each
|
|
97
113
|
attachment's name and drops its content: web storage is a few megabytes, one screenshot fills a chunk of it, and
|
|
98
114
|
a save that fails is silent — so keeping the bytes would quietly stop keeping the transcript.
|
|
99
115
|
**The ceilings are the message's, not the file's**: 4 MB per file, 8 MB and five files per message, and the same
|
|
@@ -696,7 +696,9 @@ what every developer must know even when not building one.
|
|
|
696
696
|
every tool runs in the caller's own browser session, gated by guards and the approval card. Its guard is
|
|
697
697
|
`AgentRelayAccess`, which refuses every call until the app names a guard of its own —
|
|
698
698
|
`option.setAgentAccess(SignedIn)`. **The LLM is configured in `option.ts`, never through the environment**
|
|
699
|
-
(`option.setLlm({ apiKey, model, host })`).
|
|
699
|
+
(`option.setLlm({ apiKey, model, host })`). Three providers ship — `DeepseekLlm` (the default, text only),
|
|
700
|
+
`OpenaiLlm` and `AnthropicLlm` (both read images) — and swapping one in is
|
|
701
|
+
`option.applyAdaptor(LlmAdaptorRole, AnthropicLlm)`.
|
|
700
702
|
- **Declare the tool beside the control that already does it**, never as a separate surface:
|
|
701
703
|
`st.tool("x").desc("…").arg("id", ID).exec(fn)` returns the callable to hand to `onClick` — one handler for the
|
|
702
704
|
person and the agent. Publish it only where the screen already renders the control; a falsy name declares the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/cli",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.1",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@langchain/openai": "^1.4.6",
|
|
34
34
|
"@tailwindcss/node": "^4.3.0",
|
|
35
35
|
"@trapezedev/project": "^7.1.4",
|
|
36
|
-
"akanjs": "3.0.0-beta.
|
|
36
|
+
"akanjs": "3.0.0-beta.1",
|
|
37
37
|
"chalk": "^5.6.2",
|
|
38
38
|
"commander": "^14.0.3",
|
|
39
39
|
"dayjs": "^1.11.20",
|