shadok-ai 0.15.43 → 0.15.45

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/README.md CHANGED
@@ -76,20 +76,18 @@ Enter to skip; you can add it later from the web UI).
76
76
  - **Channels** — one `claude` process each, running in parallel. Renaming,
77
77
  grouping, and closing all sync live between the browser and Telegram: it's
78
78
  one list, server-owned, not two copies.
79
- - **Groups** — on a desktop the cockpit is laid out like Microsoft Teams: an
80
- app bar on the left (Activity — a click opens the next agent waiting for you —
81
- then Profiles, Ledger, Secrets, Users, Security, Telegram, Sound), a search box
82
- in the title bar that narrows the agents list as you type (Enter opens the first
83
- match), and an agents pane where **every group is a collapsible section**, each
84
- agent a round avatar with a presence dot (green ready, red working, hollow
79
+ - **Groups** — on a desktop the groups live in their own **left column**: pick
80
+ one to narrow the agents pane to it, and the global tools (Profiles, Ledger,
81
+ Secrets, Users, Security, Telegram, Sound) stay in the header at the top. Each
82
+ agent is a round avatar with a presence dot (green ready, red working, hollow
85
83
  offline). A group's icon opens the icon picker: choose from the grid, type any
86
84
  emoji, or **type a word** (`rocket`, `bug`, `money`…) to search for one; its
87
85
  **+** creates the new agent straight into that group. Dragging an agent onto a
88
86
  group files it there, dragging groups reorders them, and double-clicking a name
89
- renames it. The agent's header carries Chat / Changes / Schedule / Terminal as
90
- tabs, and a question the agent asks shows as an *Approval requested* card. On a
91
- phone nothing changes: the tools sit in the ⋯ menu and the agents sheet lists
92
- every group.
87
+ renames it. A question the agent asks shows as an *Approval requested* card. The
88
+ whole cockpit is skinned like Microsoft Teams (grey light mode / near-black dark
89
+ mode, the Shadok mark in the header). On a phone the tools sit in the ⋯ menu and
90
+ the agents sheet lists every group.
93
91
  - **Worktree isolation** — spawned agents get their own git worktree and branch
94
92
  by default, so parallel agents never collide. Work is never auto-discarded:
95
93
  an empty worktree is reclaimed on close, anything with changes or commits
@@ -604,6 +602,55 @@ file *before* starting the container (`docker create` → `docker cp` →
604
602
  `docker start`). That ordering is no longer necessary: shadok writes the file
605
603
  itself, before any session spawns.
606
604
 
605
+ ### Running on a self-hosted model
606
+
607
+ shadok drives Claude Code, and Claude Code can talk to any server that speaks
608
+ the Anthropic Messages API: Ollama, llama.cpp's `llama-server`, vLLM, or a
609
+ LiteLLM proxy in front of anything else. Point it there with
610
+ `ANTHROPIC_BASE_URL`, and agents on that backend need **no Claude sign-in** and
611
+ are **never held by the quota guard** (they don't spend your subscription).
612
+
613
+ Three ways to do it:
614
+
615
+ - **From the cockpit — the easy one.** The sign-in card a fresh instance opens
616
+ has a second side, **Another model**: pick a provider (Ollama, a llama.cpp
617
+ server, DeepSeek, Z.ai/GLM, Moonshot/Kimi, or any Anthropic-compatible
618
+ server), the address and model are pre-filled, the models a local server
619
+ serves are listed for you, and **Test** sends one real request before
620
+ anything is saved. The lead agent starts as soon as you save. Change it later
621
+ from the version menu, **⚙ Model backend…** (which also offers to go back to
622
+ the subscription). The choice is stored per launch directory in
623
+ `~/.shadok-ai/config.json` and takes precedence over the environment; running
624
+ agents keep the model they were started with until they are reloaded.
625
+ - **The whole instance, from the environment.** Launch shadok with the variables:
626
+
627
+ ```bash
628
+ ANTHROPIC_BASE_URL=http://localhost:11434 ANTHROPIC_AUTH_TOKEN=ollama ANTHROPIC_MODEL=qwen3-coder:30b SHADOK_CONTEXT_WINDOW=64k npx shadok-ai
629
+ ```
630
+
631
+ - **One role.** Store the same names as vault secrets and attach them to a
632
+ profile: agents on that profile use the local model, the rest stay on the
633
+ subscription. A profile's secrets win over the instance's environment.
634
+
635
+ | Variable | Meaning |
636
+ |---|---|
637
+ | `ANTHROPIC_BASE_URL` | The server. Anything that is not `*.anthropic.com` counts as a custom backend. |
638
+ | `ANTHROPIC_AUTH_TOKEN` | Sent as a bearer token. Any value when the server checks none. Prefer it to `ANTHROPIC_API_KEY`, which makes Claude Code ask for confirmation. |
639
+ | `ANTHROPIC_MODEL` | The model to run. Also fills every unset `ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODEL` and `ANTHROPIC_SMALL_FAST_MODEL`, so the model picker and Claude Code's background calls reach it too. |
640
+ | `SHADOK_CONTEXT_WINDOW` | The window the context gauge measures against (`64000`, `64k`, `1m`). Without it the gauge assumes Claude's 200k. |
641
+
642
+ Hugging Face Inference, Together, Groq and the other **OpenAI-only** APIs are
643
+ not in the list on purpose: Claude Code speaks only the Anthropic format, so
644
+ they need a translating proxy (LiteLLM, claude-code-router) in front — then
645
+ point *Another Anthropic-compatible server* at the proxy. The Test button tells
646
+ the two cases apart and says so.
647
+
648
+ Two things are on you. The model needs **reliable tool calling and a long
649
+ context**: Claude Code's own prompt and tool list take ~15–20k tokens before
650
+ your first word. And the server must actually *serve* that context: Ollama's
651
+ default is a few thousand tokens, so set `OLLAMA_CONTEXT_LENGTH` (64k is a sane
652
+ floor) or the agent will lose its instructions without any error.
653
+
607
654
  ### SSH identity in Docker
608
655
 
609
656
  When shadok-ai runs **in a container** it gives itself an SSH key on first boot
@@ -859,10 +906,15 @@ right now), `/version`, `/autoupdate`,
859
906
  returns the cwd to start the tweak agent in), `/media/<name>` (GET — serves a
860
907
  pasted/dropped or Telegram attachment back for inline display; sandboxed, basename
861
908
  only), and the sign-in group: `/auth` (GET
862
- — `{loggedIn, email?, subscriptionType?, tokenExpiresAt?, accessExpiresAt?}`;
863
- the expiries come from the credentials store, never a token value), `/auth/login`
909
+ — `{loggedIn, email?, subscriptionType?, tokenExpiresAt?, accessExpiresAt?, backend?, backendModel?}`;
910
+ the expiries come from the credentials store, never a token value; `backend:
911
+ "custom"` when the instance runs on another model), `/auth/login`
864
912
  (POST — start a flow, returns `{url}`; DELETE — cancel it), `/auth/code`
865
- (POST `{code}`).
913
+ (POST `{code}`); and the model-backend group (admin, browser only for writes):
914
+ `/backend` (GET — the backend in use without its key, plus the presets; PUT —
915
+ `{baseUrl, model, authToken?, contextWindow?}` or `{clear: true}`),
916
+ `/backend/test` (POST — one real `/v1/messages` round trip) and
917
+ `/backend/models` (POST — the models a server offers).
866
918
 
867
919
  ## Library
868
920
 
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Which model backend an agent talks to: the Claude subscription, or a CUSTOM
3
+ * one — a self-hosted open model (Ollama, llama.cpp, vLLM) or a gateway
4
+ * (LiteLLM) that speaks the Anthropic Messages API.
5
+ *
6
+ * shadok never calls a model itself; it drives the `claude` TUI. So "plugging
7
+ * in another model" is Claude Code's own mechanism — `ANTHROPIC_BASE_URL` plus
8
+ * a token and a model name — and all shadok has to do is (a) carry those
9
+ * variables to the agent and (b) stop treating that agent as a subscription
10
+ * agent: no sign-in required, no quota guard, a context window that is not
11
+ * Claude's.
12
+ *
13
+ * Two sources, the same order as everything else an agent gets: the
14
+ * environment shadok was launched with (a whole instance on a local model),
15
+ * then the profile's vault secrets (one role on a local model, the rest on the
16
+ * subscription). Secrets win, like they do for every other variable.
17
+ *
18
+ * Pure: takes plain records, so the rules are tested without a process.
19
+ */
20
+ /** The variables that select and configure a backend. Only these are carried
21
+ * over from shadok's own environment — never the whole env. */
22
+ export declare const BACKEND_VARS: readonly ["ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_API_KEY", "ANTHROPIC_MODEL", "ANTHROPIC_DEFAULT_OPUS_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL", "ANTHROPIC_SMALL_FAST_MODEL", "SHADOK_CONTEXT_WINDOW"];
23
+ export type Backend = {
24
+ kind: "subscription";
25
+ } | {
26
+ kind: "custom";
27
+ baseUrl: string;
28
+ model: string | null;
29
+ contextWindow: number | null;
30
+ };
31
+ /**
32
+ * Is `ANTHROPIC_BASE_URL` pointing somewhere that is NOT Anthropic?
33
+ *
34
+ * Anthropic's own host is excluded so that a user who happens to export the
35
+ * default URL is not silently taken off the sign-in and quota guards. A URL
36
+ * that does not parse is NOT treated as custom: guessing "custom" would drop
37
+ * the sign-in check for an agent that will then fail to reach anything.
38
+ */
39
+ export declare function isCustomBaseUrl(raw: string | undefined): boolean;
40
+ /** A positive integer window, or null. Accepts `64000`, `64k`, `1m`. */
41
+ export declare function parseContextWindow(raw: string | undefined): number | null;
42
+ /** Which backend an agent with this environment talks to. */
43
+ export declare function backendFor(env: Record<string, string | undefined>): Backend;
44
+ /**
45
+ * The backend variables to hand an agent, from shadok's own environment and
46
+ * the profile's secrets.
47
+ *
48
+ * Shadok's environment contributes ONLY when it points at a custom backend.
49
+ * A developer's shell commonly carries an `ANTHROPIC_API_KEY` for other work;
50
+ * forwarding it to a subscription instance would quietly move every agent onto
51
+ * API billing. (A node-pty agent inherits the whole env anyway — that was
52
+ * already true and is not widened here; a tmux pane does NOT reliably inherit
53
+ * it, since tmux hands a new session its server's environment, which is why
54
+ * the variables are passed explicitly.)
55
+ *
56
+ * On a custom backend with a model named, every alias that is not mapped is
57
+ * mapped to it, so `opus` in the picker and Claude Code's background
58
+ * small-model calls land on the one model the server serves.
59
+ */
60
+ export declare function backendEnv(processEnv: Record<string, string | undefined>, secretEnv: Record<string, string>): Record<string, string>;
61
+ /** What config.json stores for one launch directory. */
62
+ export interface ConfiguredBackend {
63
+ baseUrl: string;
64
+ model: string;
65
+ /** Sent as a bearer token. Absent for a local server that checks none. */
66
+ authToken?: string;
67
+ /** For the gauge, e.g. 64000. */
68
+ contextWindow?: number;
69
+ }
70
+ /** The ready-made choices the onboarding card offers. ONLY servers that speak
71
+ * the Anthropic Messages API: Claude Code speaks nothing else, so an
72
+ * OpenAI-only provider (Hugging Face Inference, Together, Groq) needs a
73
+ * translating proxy such as LiteLLM in front, and goes through "custom". The
74
+ * model names are starting points — the Test button is what proves them. */
75
+ export declare const BACKEND_PRESETS: readonly [{
76
+ readonly id: "ollama";
77
+ readonly label: "Ollama (on this machine)";
78
+ readonly baseUrl: "http://localhost:11434";
79
+ readonly needsKey: false;
80
+ readonly model: "";
81
+ }, {
82
+ readonly id: "llamacpp";
83
+ readonly label: "llama.cpp server (on this machine)";
84
+ readonly baseUrl: "http://localhost:8080";
85
+ readonly needsKey: false;
86
+ readonly model: "";
87
+ }, {
88
+ readonly id: "deepseek";
89
+ readonly label: "DeepSeek";
90
+ readonly baseUrl: "https://api.deepseek.com/anthropic";
91
+ readonly needsKey: true;
92
+ readonly model: "deepseek-chat";
93
+ }, {
94
+ readonly id: "zai";
95
+ readonly label: "Z.ai (GLM)";
96
+ readonly baseUrl: "https://api.z.ai/api/anthropic";
97
+ readonly needsKey: true;
98
+ readonly model: "glm-4.6";
99
+ }, {
100
+ readonly id: "moonshot";
101
+ readonly label: "Moonshot (Kimi)";
102
+ readonly baseUrl: "https://api.moonshot.ai/anthropic";
103
+ readonly needsKey: true;
104
+ readonly model: "kimi-k2-0905-preview";
105
+ }, {
106
+ readonly id: "custom";
107
+ readonly label: "Another Anthropic-compatible server";
108
+ readonly baseUrl: "";
109
+ readonly needsKey: false;
110
+ readonly model: "";
111
+ }];
112
+ /** The env a configured backend hands an agent (before alias mapping). */
113
+ export declare function configuredBackendEnv(b: ConfiguredBackend): Record<string, string>;
114
+ /** The instance-wide source: the configured backend if any, else shadok's env. */
115
+ export declare function instanceEnv(processEnv: Record<string, string | undefined>, configured: ConfiguredBackend | null | undefined): Record<string, string | undefined>;
116
+ export type SaveVerdict = {
117
+ ok: true;
118
+ value: ConfiguredBackend;
119
+ } | {
120
+ ok: false;
121
+ error: string;
122
+ };
123
+ /** Validate a PUT /backend body. `savedToken` is kept when the body leaves the
124
+ * key empty for the SAME server — the field shows no secret, so an empty box
125
+ * means "unchanged", never "remove it". */
126
+ export declare function backendSaveVerdict(body: unknown, saved?: ConfiguredBackend | null): SaveVerdict;
127
+ /** `base` + `path`, without doubling or dropping a slash. */
128
+ export declare function joinUrl(base: string, p: string): string;
129
+ /** Model names out of an Ollama `/api/tags` or an OpenAI-style `/v1/models`
130
+ * answer; anything else is an empty list, never a throw. */
131
+ export declare function parseModelList(json: unknown): string[];
132
+ /** The smallest request that proves the whole chain: URL, key, model, and the
133
+ * Anthropic format itself. */
134
+ export declare function testRequestBody(model: string): Record<string, unknown>;
135
+ /** A test that failed, in words that say what to change. */
136
+ export declare function testFailure(status: number, bodyText: string): string;
137
+ /** Did a /v1/messages answer look like an Anthropic message? */
138
+ export declare function looksLikeMessage(json: unknown): boolean;
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Which model backend an agent talks to: the Claude subscription, or a CUSTOM
3
+ * one — a self-hosted open model (Ollama, llama.cpp, vLLM) or a gateway
4
+ * (LiteLLM) that speaks the Anthropic Messages API.
5
+ *
6
+ * shadok never calls a model itself; it drives the `claude` TUI. So "plugging
7
+ * in another model" is Claude Code's own mechanism — `ANTHROPIC_BASE_URL` plus
8
+ * a token and a model name — and all shadok has to do is (a) carry those
9
+ * variables to the agent and (b) stop treating that agent as a subscription
10
+ * agent: no sign-in required, no quota guard, a context window that is not
11
+ * Claude's.
12
+ *
13
+ * Two sources, the same order as everything else an agent gets: the
14
+ * environment shadok was launched with (a whole instance on a local model),
15
+ * then the profile's vault secrets (one role on a local model, the rest on the
16
+ * subscription). Secrets win, like they do for every other variable.
17
+ *
18
+ * Pure: takes plain records, so the rules are tested without a process.
19
+ */
20
+ /** The variables that select and configure a backend. Only these are carried
21
+ * over from shadok's own environment — never the whole env. */
22
+ export const BACKEND_VARS = [
23
+ "ANTHROPIC_BASE_URL",
24
+ "ANTHROPIC_AUTH_TOKEN",
25
+ "ANTHROPIC_API_KEY",
26
+ "ANTHROPIC_MODEL",
27
+ "ANTHROPIC_DEFAULT_OPUS_MODEL",
28
+ "ANTHROPIC_DEFAULT_SONNET_MODEL",
29
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL",
30
+ "ANTHROPIC_SMALL_FAST_MODEL",
31
+ "SHADOK_CONTEXT_WINDOW",
32
+ ];
33
+ /** The aliases a model picker or Claude Code itself may resolve. Each needs a
34
+ * local name, or the request reaches the custom server as `claude-opus-…`, a
35
+ * model it has never heard of. */
36
+ const ALIAS_VARS = [
37
+ "ANTHROPIC_DEFAULT_OPUS_MODEL",
38
+ "ANTHROPIC_DEFAULT_SONNET_MODEL",
39
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL",
40
+ // Claude Code's background calls (titles, summaries) use the small model.
41
+ // Left unmapped, every one of them fails against a server that only has one.
42
+ "ANTHROPIC_SMALL_FAST_MODEL",
43
+ ];
44
+ /**
45
+ * Is `ANTHROPIC_BASE_URL` pointing somewhere that is NOT Anthropic?
46
+ *
47
+ * Anthropic's own host is excluded so that a user who happens to export the
48
+ * default URL is not silently taken off the sign-in and quota guards. A URL
49
+ * that does not parse is NOT treated as custom: guessing "custom" would drop
50
+ * the sign-in check for an agent that will then fail to reach anything.
51
+ */
52
+ export function isCustomBaseUrl(raw) {
53
+ const v = raw?.trim();
54
+ if (!v)
55
+ return false;
56
+ let host;
57
+ try {
58
+ const u = new URL(v);
59
+ // `localhost:11434` parses too — with `localhost:` as its SCHEME. Only an
60
+ // http(s) URL is a server Claude Code can reach.
61
+ if (u.protocol !== "http:" && u.protocol !== "https:")
62
+ return false;
63
+ host = u.hostname.toLowerCase();
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ return host !== "anthropic.com" && !host.endsWith(".anthropic.com");
69
+ }
70
+ /** A positive integer window, or null. Accepts `64000`, `64k`, `1m`. */
71
+ export function parseContextWindow(raw) {
72
+ const m = raw?.trim().toLowerCase().match(/^(\d+(?:\.\d+)?)\s*([km]?)$/);
73
+ if (!m)
74
+ return null;
75
+ const n = Number(m[1]) * (m[2] === "k" ? 1_000 : m[2] === "m" ? 1_000_000 : 1);
76
+ return Number.isFinite(n) && n >= 1_000 ? Math.round(n) : null;
77
+ }
78
+ /** Which backend an agent with this environment talks to. */
79
+ export function backendFor(env) {
80
+ if (!isCustomBaseUrl(env.ANTHROPIC_BASE_URL))
81
+ return { kind: "subscription" };
82
+ return {
83
+ kind: "custom",
84
+ baseUrl: env.ANTHROPIC_BASE_URL.trim(),
85
+ model: env.ANTHROPIC_MODEL?.trim() || null,
86
+ contextWindow: parseContextWindow(env.SHADOK_CONTEXT_WINDOW),
87
+ };
88
+ }
89
+ /**
90
+ * The backend variables to hand an agent, from shadok's own environment and
91
+ * the profile's secrets.
92
+ *
93
+ * Shadok's environment contributes ONLY when it points at a custom backend.
94
+ * A developer's shell commonly carries an `ANTHROPIC_API_KEY` for other work;
95
+ * forwarding it to a subscription instance would quietly move every agent onto
96
+ * API billing. (A node-pty agent inherits the whole env anyway — that was
97
+ * already true and is not widened here; a tmux pane does NOT reliably inherit
98
+ * it, since tmux hands a new session its server's environment, which is why
99
+ * the variables are passed explicitly.)
100
+ *
101
+ * On a custom backend with a model named, every alias that is not mapped is
102
+ * mapped to it, so `opus` in the picker and Claude Code's background
103
+ * small-model calls land on the one model the server serves.
104
+ */
105
+ export function backendEnv(processEnv, secretEnv) {
106
+ const out = {};
107
+ if (isCustomBaseUrl(processEnv.ANTHROPIC_BASE_URL)) {
108
+ for (const k of BACKEND_VARS) {
109
+ const v = processEnv[k];
110
+ if (v !== undefined && v !== "")
111
+ out[k] = v;
112
+ }
113
+ }
114
+ for (const k of BACKEND_VARS)
115
+ if (k in secretEnv)
116
+ out[k] = secretEnv[k];
117
+ const b = backendFor(out);
118
+ if (b.kind === "custom" && b.model) {
119
+ for (const k of ALIAS_VARS)
120
+ if (!out[k])
121
+ out[k] = b.model;
122
+ }
123
+ return out;
124
+ }
125
+ /** The ready-made choices the onboarding card offers. ONLY servers that speak
126
+ * the Anthropic Messages API: Claude Code speaks nothing else, so an
127
+ * OpenAI-only provider (Hugging Face Inference, Together, Groq) needs a
128
+ * translating proxy such as LiteLLM in front, and goes through "custom". The
129
+ * model names are starting points — the Test button is what proves them. */
130
+ export const BACKEND_PRESETS = [
131
+ { id: "ollama", label: "Ollama (on this machine)", baseUrl: "http://localhost:11434", needsKey: false, model: "" },
132
+ { id: "llamacpp", label: "llama.cpp server (on this machine)", baseUrl: "http://localhost:8080", needsKey: false, model: "" },
133
+ { id: "deepseek", label: "DeepSeek", baseUrl: "https://api.deepseek.com/anthropic", needsKey: true, model: "deepseek-chat" },
134
+ { id: "zai", label: "Z.ai (GLM)", baseUrl: "https://api.z.ai/api/anthropic", needsKey: true, model: "glm-4.6" },
135
+ { id: "moonshot", label: "Moonshot (Kimi)", baseUrl: "https://api.moonshot.ai/anthropic", needsKey: true, model: "kimi-k2-0905-preview" },
136
+ { id: "custom", label: "Another Anthropic-compatible server", baseUrl: "", needsKey: false, model: "" },
137
+ ];
138
+ /** The env a configured backend hands an agent (before alias mapping). */
139
+ export function configuredBackendEnv(b) {
140
+ const env = { ANTHROPIC_BASE_URL: b.baseUrl, ANTHROPIC_MODEL: b.model };
141
+ // Claude Code wants SOME credential to skip its own sign-in; a local server
142
+ // ignores it. A placeholder is safer than leaving the field empty.
143
+ env.ANTHROPIC_AUTH_TOKEN = b.authToken || "none";
144
+ if (b.contextWindow)
145
+ env.SHADOK_CONTEXT_WINDOW = String(b.contextWindow);
146
+ return env;
147
+ }
148
+ /** The instance-wide source: the configured backend if any, else shadok's env. */
149
+ export function instanceEnv(processEnv, configured) {
150
+ return configured ? configuredBackendEnv(configured) : processEnv;
151
+ }
152
+ /** Validate a PUT /backend body. `savedToken` is kept when the body leaves the
153
+ * key empty for the SAME server — the field shows no secret, so an empty box
154
+ * means "unchanged", never "remove it". */
155
+ export function backendSaveVerdict(body, saved) {
156
+ const b = (body ?? {});
157
+ const baseUrl = typeof b.baseUrl === "string" ? b.baseUrl.trim().replace(/\/+$/, "") : "";
158
+ const model = typeof b.model === "string" ? b.model.trim() : "";
159
+ if (!isCustomBaseUrl(baseUrl))
160
+ return { ok: false, error: "the server address must be an http(s) URL, and not Anthropic's (that is the subscription)" };
161
+ if (!model)
162
+ return { ok: false, error: "name the model to run" };
163
+ const out = { baseUrl, model };
164
+ const token = typeof b.authToken === "string" ? b.authToken.trim() : "";
165
+ if (token)
166
+ out.authToken = token;
167
+ else if (saved?.authToken && saved.baseUrl === baseUrl)
168
+ out.authToken = saved.authToken;
169
+ const rawWindow = b.contextWindow;
170
+ if (rawWindow !== undefined && rawWindow !== null && String(rawWindow).trim() !== "") {
171
+ const w = parseContextWindow(String(rawWindow));
172
+ if (!w)
173
+ return { ok: false, error: "context window: a number of tokens such as 64000 or 64k" };
174
+ out.contextWindow = w;
175
+ }
176
+ return { ok: true, value: out };
177
+ }
178
+ /** `base` + `path`, without doubling or dropping a slash. */
179
+ export function joinUrl(base, p) {
180
+ return base.replace(/\/+$/, "") + "/" + p.replace(/^\/+/, "");
181
+ }
182
+ /** Model names out of an Ollama `/api/tags` or an OpenAI-style `/v1/models`
183
+ * answer; anything else is an empty list, never a throw. */
184
+ export function parseModelList(json) {
185
+ const j = (json ?? {});
186
+ const rows = Array.isArray(j.models) ? j.models : Array.isArray(j.data) ? j.data : [];
187
+ const names = rows
188
+ .map((r) => (r && typeof r === "object" ? (r.name ?? r.id) : null))
189
+ .filter((n) => typeof n === "string" && n.trim() !== "");
190
+ return [...new Set(names)].sort();
191
+ }
192
+ /** The smallest request that proves the whole chain: URL, key, model, and the
193
+ * Anthropic format itself. */
194
+ export function testRequestBody(model) {
195
+ return { model, max_tokens: 16, messages: [{ role: "user", content: "Reply with the single word: ok" }] };
196
+ }
197
+ /** A test that failed, in words that say what to change. */
198
+ export function testFailure(status, bodyText) {
199
+ let detail = "";
200
+ try {
201
+ const j = JSON.parse(bodyText);
202
+ detail = String(j?.error?.message ?? j?.error ?? j?.message ?? "").trim();
203
+ }
204
+ catch {
205
+ detail = bodyText.trim().slice(0, 200);
206
+ }
207
+ if (status === 401 || status === 403)
208
+ return "the server refused the API key" + (detail ? ` (${detail})` : "");
209
+ if (status === 404 && !/model/i.test(detail))
210
+ return "no Anthropic API at this address (/v1/messages not found) — an OpenAI-only server needs a proxy such as LiteLLM in front";
211
+ if (/model/i.test(detail))
212
+ return `the server does not know this model: ${detail}`;
213
+ return `the server answered ${status}` + (detail ? `: ${detail}` : "");
214
+ }
215
+ /** Did a /v1/messages answer look like an Anthropic message? */
216
+ export function looksLikeMessage(json) {
217
+ const j = json;
218
+ return !!j && j.type === "message" && Array.isArray(j.content);
219
+ }
220
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { ConfiguredBackend } from "./backend.js";
1
2
  /**
2
3
  * Global CLI config at ~/.shadok-ai/config.json (mode 600). The Telegram bot
3
4
  * token is **per launch directory** (`tokens[cwd]`), so each instance you run
@@ -74,6 +75,14 @@ export interface Config {
74
75
  * break-glass when every admin has lost their device (README).
75
76
  */
76
77
  twoFactor?: Record<string, true>;
78
+ /**
79
+ * Per launch-directory model backend chosen at onboarding (or from the
80
+ * version menu), keyed by absolute cwd. Absent = the Claude subscription, or
81
+ * whatever ANTHROPIC_BASE_URL shadok was launched with. When present it is
82
+ * authoritative and REPLACES the environment wholesale — see src/backend.ts.
83
+ * May hold an API key, which is one more reason this file is 600.
84
+ */
85
+ modelBackend?: Record<string, ConfiguredBackend>;
77
86
  }
78
87
  export declare const SHADOK_DIR: string;
79
88
  export declare function loadConfig(): Config;
@@ -103,6 +112,10 @@ export declare function themeForCwd(cfg: Config, cwd: string): string | null;
103
112
  * any unknown key clear the entry, so the instance falls back to the default.
104
113
  */
105
114
  export declare function setThemeForCwd(cfg: Config, cwd: string, theme: string): void;
115
+ /** The model backend chosen for the instance launched in `cwd`, or null. */
116
+ export declare function backendForCwd(cfg: Config, cwd: string): ConfiguredBackend | null;
117
+ /** Set (or clear, with null) that backend and persist. */
118
+ export declare function setBackendForCwd(cfg: Config, cwd: string, b: ConfiguredBackend | null): void;
106
119
  /** Is two-factor sign-in on for the instance launched in `cwd`? */
107
120
  export declare function twoFactorForCwd(cfg: Config, cwd: string): boolean;
108
121
  export declare function setTwoFactorForCwd(cfg: Config, cwd: string, on: boolean): void;
package/dist/config.js CHANGED
@@ -74,6 +74,19 @@ export function setThemeForCwd(cfg, cwd, theme) {
74
74
  delete cfg.cockpitTheme[cwd];
75
75
  saveConfig(cfg);
76
76
  }
77
+ /** The model backend chosen for the instance launched in `cwd`, or null. */
78
+ export function backendForCwd(cfg, cwd) {
79
+ return cfg.modelBackend?.[cwd] ?? null;
80
+ }
81
+ /** Set (or clear, with null) that backend and persist. */
82
+ export function setBackendForCwd(cfg, cwd, b) {
83
+ cfg.modelBackend ??= {};
84
+ if (b)
85
+ cfg.modelBackend[cwd] = b;
86
+ else
87
+ delete cfg.modelBackend[cwd];
88
+ saveConfig(cfg);
89
+ }
77
90
  /** Is two-factor sign-in on for the instance launched in `cwd`? */
78
91
  export function twoFactorForCwd(cfg, cwd) {
79
92
  return cfg.twoFactor?.[cwd] === true;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,9 @@ export interface FirstAgentPlan {
29
29
  export declare function firstAgentPlan(input: {
30
30
  channelCount: number;
31
31
  authState: AuthState;
32
+ /** The whole instance runs on a custom model backend (src/backend.ts): its
33
+ * agents carry their own token, so the Claude sign-in is irrelevant. */
34
+ customBackend?: boolean;
32
35
  }): FirstAgentPlan;
33
36
  /**
34
37
  * What the cockpit is allowed to SAY while it has no agent to show.
@@ -81,6 +84,9 @@ export declare function ensureFirstAgent(deps: {
81
84
  port: number;
82
85
  cookie?: string;
83
86
  cwd: string;
87
+ /** The instance runs on a custom model backend (src/backend.ts) — decided by
88
+ * the server, which owns both the env and the saved choice. */
89
+ customBackend?: boolean;
84
90
  /** Called with the new session id once the server reports it ready. */
85
91
  onReady: (sessionId: string, name: string) => void;
86
92
  }): Promise<FirstAgentPlan["reason"]>;
@@ -26,6 +26,8 @@ export const FIRST_AGENT_NAME = "general";
26
26
  export function firstAgentPlan(input) {
27
27
  if (input.channelCount > 0)
28
28
  return { spawn: false, reason: "channels-exist" };
29
+ if (input.customBackend)
30
+ return { spawn: true, reason: "first-boot", name: FIRST_AGENT_NAME, profile: BOSS_PROFILE_NAME };
29
31
  // "unknown" is not "signed in": the probe failed. Waiting costs one boot,
30
32
  // guessing costs an agent with no credentials — the zombie shape (invariant 27).
31
33
  if (input.authState !== "signed-in")
@@ -71,9 +73,14 @@ let inFlight = false;
71
73
  export async function ensureFirstAgent(deps) {
72
74
  if (inFlight)
73
75
  return "channels-exist";
76
+ // Instance-wide only: the lead agent's profile is not consulted, so a custom
77
+ // backend reaches it through the instance's source (env or saved choice).
78
+ const customBackend = deps.customBackend ?? false;
74
79
  const plan = firstAgentPlan({
75
80
  channelCount: loadChannels().length,
76
- authState: (await authStatus()).state,
81
+ // No probe when it cannot change the answer (~850ms, and a process spawn).
82
+ authState: customBackend ? "unknown" : (await authStatus()).state,
83
+ customBackend,
77
84
  });
78
85
  if (!plan.spawn) {
79
86
  settleFirstAgent(plan.reason);
@@ -1 +1 @@
1
- {"version":3,"file":"first-agent.js","sourceRoot":"","sources":["../src/first-agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"first-agent.js","sourceRoot":"","sources":["../src/first-agent.ts"],"names":[],"mappings":"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"}