zcode-acp-server 0.1.0 → 0.3.0
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 +192 -9
- package/README.zh-CN.md +143 -8
- package/dist/backend/client.d.ts +12 -4
- package/dist/backend/client.d.ts.map +1 -1
- package/dist/backend/client.js +72 -7
- package/dist/backend/client.js.map +1 -1
- package/dist/backend/credentials.d.ts.map +1 -1
- package/dist/backend/credentials.js +2 -1
- package/dist/backend/credentials.js.map +1 -1
- package/dist/backend/listener.d.ts +12 -4
- package/dist/backend/listener.d.ts.map +1 -1
- package/dist/backend/listener.js +68 -12
- package/dist/backend/listener.js.map +1 -1
- package/dist/backend/types.d.ts +1 -1
- package/dist/backend/types.d.ts.map +1 -1
- package/dist/bin/hub.d.ts +16 -0
- package/dist/bin/hub.d.ts.map +1 -0
- package/dist/bin/hub.js +41 -0
- package/dist/bin/hub.js.map +1 -0
- package/dist/bin/quota.d.ts +54 -0
- package/dist/bin/quota.d.ts.map +1 -0
- package/dist/bin/quota.js +333 -0
- package/dist/bin/quota.js.map +1 -0
- package/dist/config/auto-compact.d.ts +23 -0
- package/dist/config/auto-compact.d.ts.map +1 -0
- package/dist/config/auto-compact.js +67 -0
- package/dist/config/auto-compact.js.map +1 -0
- package/dist/config/mcp-discovery.d.ts +34 -0
- package/dist/config/mcp-discovery.d.ts.map +1 -0
- package/dist/config/mcp-discovery.js +153 -0
- package/dist/config/mcp-discovery.js.map +1 -0
- package/dist/config/model-cache.d.ts +12 -1
- package/dist/config/model-cache.d.ts.map +1 -1
- package/dist/config/model-cache.js +30 -8
- package/dist/config/model-cache.js.map +1 -1
- package/dist/config/options.d.ts +87 -9
- package/dist/config/options.d.ts.map +1 -1
- package/dist/config/options.js +248 -45
- package/dist/config/options.js.map +1 -1
- package/dist/config/plugin-commands.d.ts +24 -0
- package/dist/config/plugin-commands.d.ts.map +1 -0
- package/dist/config/plugin-commands.js +107 -0
- package/dist/config/plugin-commands.js.map +1 -0
- package/dist/config/provider-registry.d.ts +60 -0
- package/dist/config/provider-registry.d.ts.map +1 -0
- package/dist/config/provider-registry.js +128 -0
- package/dist/config/provider-registry.js.map +1 -0
- package/dist/config/runtime-model.d.ts +54 -18
- package/dist/config/runtime-model.d.ts.map +1 -1
- package/dist/config/runtime-model.js +105 -61
- package/dist/config/runtime-model.js.map +1 -1
- package/dist/config/skill-discovery.d.ts +35 -0
- package/dist/config/skill-discovery.d.ts.map +1 -0
- package/dist/config/skill-discovery.js +188 -0
- package/dist/config/skill-discovery.js.map +1 -0
- package/dist/handlers/account.d.ts +43 -0
- package/dist/handlers/account.d.ts.map +1 -0
- package/dist/handlers/account.js +59 -0
- package/dist/handlers/account.js.map +1 -0
- package/dist/handlers/background-tasks.d.ts +72 -0
- package/dist/handlers/background-tasks.d.ts.map +1 -0
- package/dist/handlers/background-tasks.js +330 -0
- package/dist/handlers/background-tasks.js.map +1 -0
- package/dist/handlers/dispatch.d.ts.map +1 -1
- package/dist/handlers/dispatch.js +134 -22
- package/dist/handlers/dispatch.js.map +1 -1
- package/dist/handlers/extensions.d.ts +15 -0
- package/dist/handlers/extensions.d.ts.map +1 -1
- package/dist/handlers/extensions.js +43 -27
- package/dist/handlers/extensions.js.map +1 -1
- package/dist/handlers/io.d.ts +31 -3
- package/dist/handlers/io.d.ts.map +1 -1
- package/dist/handlers/io.js +108 -9
- package/dist/handlers/io.js.map +1 -1
- package/dist/handlers/replay.d.ts +79 -0
- package/dist/handlers/replay.d.ts.map +1 -0
- package/dist/handlers/replay.js +252 -0
- package/dist/handlers/replay.js.map +1 -0
- package/dist/handlers/server-requests.d.ts +20 -4
- package/dist/handlers/server-requests.d.ts.map +1 -1
- package/dist/handlers/server-requests.js +293 -63
- package/dist/handlers/server-requests.js.map +1 -1
- package/dist/handlers/session.d.ts +113 -10
- package/dist/handlers/session.d.ts.map +1 -1
- package/dist/handlers/session.js +932 -277
- package/dist/handlers/session.js.map +1 -1
- package/dist/handlers/slash.d.ts +37 -1
- package/dist/handlers/slash.d.ts.map +1 -1
- package/dist/handlers/slash.js +143 -8
- package/dist/handlers/slash.js.map +1 -1
- package/dist/index.js +76 -12
- package/dist/index.js.map +1 -1
- package/dist/interaction/adapter.d.ts +19 -33
- package/dist/interaction/adapter.d.ts.map +1 -1
- package/dist/interaction/adapter.js +80 -79
- package/dist/interaction/adapter.js.map +1 -1
- package/dist/lazy-sessions.d.ts +35 -0
- package/dist/lazy-sessions.d.ts.map +1 -0
- package/dist/lazy-sessions.js +98 -0
- package/dist/lazy-sessions.js.map +1 -0
- package/dist/quota/cache.d.ts +18 -0
- package/dist/quota/cache.d.ts.map +1 -0
- package/dist/quota/cache.js +32 -0
- package/dist/quota/cache.js.map +1 -0
- package/dist/quota/client.d.ts +30 -0
- package/dist/quota/client.d.ts.map +1 -0
- package/dist/quota/client.js +57 -0
- package/dist/quota/client.js.map +1 -0
- package/dist/quota/color.d.ts +58 -0
- package/dist/quota/color.d.ts.map +1 -0
- package/dist/quota/color.js +95 -0
- package/dist/quota/color.js.map +1 -0
- package/dist/quota/combined.d.ts +66 -0
- package/dist/quota/combined.d.ts.map +1 -0
- package/dist/quota/combined.js +179 -0
- package/dist/quota/combined.js.map +1 -0
- package/dist/quota/format.d.ts +105 -0
- package/dist/quota/format.d.ts.map +1 -0
- package/dist/quota/format.js +219 -0
- package/dist/quota/format.js.map +1 -0
- package/dist/quota/index.d.ts +23 -0
- package/dist/quota/index.d.ts.map +1 -0
- package/dist/quota/index.js +42 -0
- package/dist/quota/index.js.map +1 -0
- package/dist/quota/opencode-go/cache.d.ts +17 -0
- package/dist/quota/opencode-go/cache.d.ts.map +1 -0
- package/dist/quota/opencode-go/cache.js +31 -0
- package/dist/quota/opencode-go/cache.js.map +1 -0
- package/dist/quota/opencode-go/client.d.ts +28 -0
- package/dist/quota/opencode-go/client.d.ts.map +1 -0
- package/dist/quota/opencode-go/client.js +48 -0
- package/dist/quota/opencode-go/client.js.map +1 -0
- package/dist/quota/opencode-go/config.d.ts +37 -0
- package/dist/quota/opencode-go/config.d.ts.map +1 -0
- package/dist/quota/opencode-go/config.js +58 -0
- package/dist/quota/opencode-go/config.js.map +1 -0
- package/dist/quota/opencode-go/format.d.ts +36 -0
- package/dist/quota/opencode-go/format.d.ts.map +1 -0
- package/dist/quota/opencode-go/format.js +87 -0
- package/dist/quota/opencode-go/format.js.map +1 -0
- package/dist/quota/opencode-go/index.d.ts +30 -0
- package/dist/quota/opencode-go/index.d.ts.map +1 -0
- package/dist/quota/opencode-go/index.js +108 -0
- package/dist/quota/opencode-go/index.js.map +1 -0
- package/dist/quota/opencode-go/parse.d.ts +41 -0
- package/dist/quota/opencode-go/parse.d.ts.map +1 -0
- package/dist/quota/opencode-go/parse.js +75 -0
- package/dist/quota/opencode-go/parse.js.map +1 -0
- package/dist/quota/opencode-go/types.d.ts +48 -0
- package/dist/quota/opencode-go/types.d.ts.map +1 -0
- package/dist/quota/opencode-go/types.js +11 -0
- package/dist/quota/opencode-go/types.js.map +1 -0
- package/dist/quota/parse.d.ts +33 -0
- package/dist/quota/parse.d.ts.map +1 -0
- package/dist/quota/parse.js +200 -0
- package/dist/quota/parse.js.map +1 -0
- package/dist/quota/types.d.ts +72 -0
- package/dist/quota/types.d.ts.map +1 -0
- package/dist/quota/types.js +10 -0
- package/dist/quota/types.js.map +1 -0
- package/dist/remote/broadcast.d.ts +47 -0
- package/dist/remote/broadcast.d.ts.map +1 -0
- package/dist/remote/broadcast.js +121 -0
- package/dist/remote/broadcast.js.map +1 -0
- package/dist/remote/config.d.ts +32 -0
- package/dist/remote/config.d.ts.map +1 -0
- package/dist/remote/config.js +65 -0
- package/dist/remote/config.js.map +1 -0
- package/dist/remote/endpoint.d.ts +30 -0
- package/dist/remote/endpoint.d.ts.map +1 -0
- package/dist/remote/endpoint.js +213 -0
- package/dist/remote/endpoint.js.map +1 -0
- package/dist/remote/hub-server.d.ts +41 -0
- package/dist/remote/hub-server.d.ts.map +1 -0
- package/dist/remote/hub-server.js +346 -0
- package/dist/remote/hub-server.js.map +1 -0
- package/dist/server.d.ts +139 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +179 -4
- package/dist/server.js.map +1 -1
- package/dist/tasks-index.d.ts +14 -4
- package/dist/tasks-index.d.ts.map +1 -1
- package/dist/tasks-index.js +145 -46
- package/dist/tasks-index.js.map +1 -1
- package/dist/translators/event-translator.d.ts +33 -0
- package/dist/translators/event-translator.d.ts.map +1 -1
- package/dist/translators/event-translator.js +101 -0
- package/dist/translators/event-translator.js.map +1 -1
- package/dist/translators/index.d.ts +1 -1
- package/dist/translators/index.d.ts.map +1 -1
- package/dist/translators/index.js +1 -1
- package/dist/translators/index.js.map +1 -1
- package/dist/translators/projection-differ.d.ts +8 -0
- package/dist/translators/projection-differ.d.ts.map +1 -1
- package/dist/translators/projection-differ.js +19 -9
- package/dist/translators/projection-differ.js.map +1 -1
- package/dist/translators/tool-helpers.d.ts +28 -0
- package/dist/translators/tool-helpers.d.ts.map +1 -1
- package/dist/translators/tool-helpers.js +104 -0
- package/dist/translators/tool-helpers.js.map +1 -1
- package/dist/translators/types.d.ts +38 -1
- package/dist/translators/types.d.ts.map +1 -1
- package/dist/translators/types.js.map +1 -1
- package/dist/utils.d.ts +36 -7
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +69 -5
- package/dist/utils.js.map +1 -1
- package/docs/ARCHITECTURE.md +130 -40
- package/docs/BACKLOG.md +59 -0
- package/docs/DEVELOPMENT.md +31 -0
- package/docs/PROTOCOL.md +328 -23
- package/docs/REMOTE-CLIENTS.md +260 -0
- package/docs/REPLAY-GUIDE.md +131 -0
- package/docs/TROUBLESHOOTING.md +131 -14
- package/docs/adr/0001-bridge-lifetime-follows-primary-client.md +14 -0
- package/docs/adr/0002-stateless-hub-over-per-bridge-acp-endpoints.md +23 -0
- package/docs/adr/0003-tail-replay-meta-and-cursor-pagination.md +40 -0
- package/docs/agents/domain.md +51 -0
- package/docs/agents/issue-tracker.md +22 -0
- package/docs/agents/triage-labels.md +15 -0
- package/docs/proposals/0001-tail-session-replay.md +136 -0
- package/docs/proposals/0002-plan-quota-usage.md +81 -0
- package/package.json +10 -6
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin command discovery — reads enabled plugins from `~/.zcode/cli/config.json`
|
|
3
|
+
* and scans their `commands/*.md` frontmatter to build slash-command entries.
|
|
4
|
+
*
|
|
5
|
+
* Plugin commands (e.g. `/code-review`) are resolved by the ZCode backend's
|
|
6
|
+
* `customCommandPromptResolver` before the model sees them, so they work in
|
|
7
|
+
* app-server mode without bridge interception.
|
|
8
|
+
*/
|
|
9
|
+
/** A slash-command entry compatible with `sendAvailableCommands`. */
|
|
10
|
+
export interface PluginCommandEntry {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
input?: {
|
|
14
|
+
hint: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Read enabled plugin commands from `~/.zcode/cli/config.json` + the plugin
|
|
19
|
+
* cache directory. Returns entries suitable for `available_commands_update`.
|
|
20
|
+
*
|
|
21
|
+
* Best-effort: failures are logged and swallowed (returns []).
|
|
22
|
+
*/
|
|
23
|
+
export declare function loadPluginCommands(): PluginCommandEntry[];
|
|
24
|
+
//# sourceMappingURL=plugin-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-commands.d.ts","sourceRoot":"","sources":["../../src/config/plugin-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAyBH,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1B;AA+BD;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,kBAAkB,EAAE,CAyDzD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin command discovery — reads enabled plugins from `~/.zcode/cli/config.json`
|
|
3
|
+
* and scans their `commands/*.md` frontmatter to build slash-command entries.
|
|
4
|
+
*
|
|
5
|
+
* Plugin commands (e.g. `/code-review`) are resolved by the ZCode backend's
|
|
6
|
+
* `customCommandPromptResolver` before the model sees them, so they work in
|
|
7
|
+
* app-server mode without bridge interception.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { compareVersions, log } from "../utils.js";
|
|
13
|
+
/** Path to the ZCode CLI config (plugins, skills, mcp). */
|
|
14
|
+
const CLI_CONFIG_PATH = path.join(homedir(), ".zcode", "cli", "config.json");
|
|
15
|
+
/** Root of the plugin cache directory. */
|
|
16
|
+
const PLUGIN_CACHE_DIR = path.join(homedir(), ".zcode", "cli", "plugins", "cache");
|
|
17
|
+
/** Parse YAML-like frontmatter from a plugin command .md file. */
|
|
18
|
+
function parseFrontmatter(content) {
|
|
19
|
+
const fm = {};
|
|
20
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
21
|
+
if (!match)
|
|
22
|
+
return fm;
|
|
23
|
+
const lines = match[1].split(/\r?\n/);
|
|
24
|
+
for (const line of lines) {
|
|
25
|
+
const idx = line.indexOf(":");
|
|
26
|
+
if (idx <= 0)
|
|
27
|
+
continue;
|
|
28
|
+
const key = line.slice(0, idx).trim();
|
|
29
|
+
// Strip surrounding quotes from the value (YAML scalar style).
|
|
30
|
+
let val = line.slice(idx + 1).trim();
|
|
31
|
+
if ((val.startsWith('"') && val.endsWith('"')) ||
|
|
32
|
+
(val.startsWith("'") && val.endsWith("'"))) {
|
|
33
|
+
val = val.slice(1, -1);
|
|
34
|
+
}
|
|
35
|
+
if (key)
|
|
36
|
+
fm[key] = val;
|
|
37
|
+
}
|
|
38
|
+
return fm;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Read enabled plugin commands from `~/.zcode/cli/config.json` + the plugin
|
|
42
|
+
* cache directory. Returns entries suitable for `available_commands_update`.
|
|
43
|
+
*
|
|
44
|
+
* Best-effort: failures are logged and swallowed (returns []).
|
|
45
|
+
*/
|
|
46
|
+
export function loadPluginCommands() {
|
|
47
|
+
if (!existsSync(CLI_CONFIG_PATH) || !existsSync(PLUGIN_CACHE_DIR))
|
|
48
|
+
return [];
|
|
49
|
+
try {
|
|
50
|
+
const cfg = JSON.parse(readFileSync(CLI_CONFIG_PATH, "utf8"));
|
|
51
|
+
const enabled = cfg.plugins?.enabledPlugins ?? {};
|
|
52
|
+
const entries = [];
|
|
53
|
+
// enabledPlugins keys are "pluginName@marketplace"
|
|
54
|
+
for (const [pluginKey, enabledFlag] of Object.entries(enabled)) {
|
|
55
|
+
if (!enabledFlag)
|
|
56
|
+
continue;
|
|
57
|
+
const atIdx = pluginKey.indexOf("@");
|
|
58
|
+
if (atIdx <= 0)
|
|
59
|
+
continue;
|
|
60
|
+
const pluginName = pluginKey.slice(0, atIdx);
|
|
61
|
+
const marketplace = pluginKey.slice(atIdx + 1);
|
|
62
|
+
// Scan all versions of this plugin in the cache (use latest found).
|
|
63
|
+
const marketDir = path.join(PLUGIN_CACHE_DIR, marketplace);
|
|
64
|
+
if (!existsSync(marketDir))
|
|
65
|
+
continue;
|
|
66
|
+
const pluginDir = path.join(marketDir, pluginName);
|
|
67
|
+
if (!existsSync(pluginDir))
|
|
68
|
+
continue;
|
|
69
|
+
// Find the latest version directory.
|
|
70
|
+
let latestVersion = "";
|
|
71
|
+
for (const entry of readdirSync(pluginDir)) {
|
|
72
|
+
const vDir = path.join(pluginDir, entry);
|
|
73
|
+
if (statSync(vDir).isDirectory() && compareVersions(entry, latestVersion) > 0) {
|
|
74
|
+
latestVersion = entry;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!latestVersion)
|
|
78
|
+
continue;
|
|
79
|
+
const commandsDir = path.join(pluginDir, latestVersion, "commands");
|
|
80
|
+
if (!existsSync(commandsDir))
|
|
81
|
+
continue;
|
|
82
|
+
for (const file of readdirSync(commandsDir)) {
|
|
83
|
+
if (!file.endsWith(".md"))
|
|
84
|
+
continue;
|
|
85
|
+
const cmdPath = path.join(commandsDir, file);
|
|
86
|
+
const content = readFileSync(cmdPath, "utf8");
|
|
87
|
+
const fm = parseFrontmatter(content);
|
|
88
|
+
const name = file.replace(/\.md$/, "");
|
|
89
|
+
const description = fm["description"] ?? "";
|
|
90
|
+
if (!description)
|
|
91
|
+
continue;
|
|
92
|
+
const entry = { name, description };
|
|
93
|
+
const hint = fm["argument-hint"];
|
|
94
|
+
if (hint)
|
|
95
|
+
entry.input = { hint };
|
|
96
|
+
entries.push(entry);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
log(`plugin-commands: loaded ${entries.length} plugin command(s)`);
|
|
100
|
+
return entries;
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
log(`plugin-commands: load failed (${e instanceof Error ? e.message : String(e)})`);
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=plugin-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-commands.js","sourceRoot":"","sources":["../../src/config/plugin-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a provider-registry payload for `workspace/updateProviderRegistry`.
|
|
3
|
+
*
|
|
4
|
+
* The V4 backend doesn't auto-load providers from config.json — the host must
|
|
5
|
+
* push them via this RPC after `session/create`, otherwise third-party
|
|
6
|
+
* providers fail with `provider_not_configured` (misclassified as a network
|
|
7
|
+
* error after turn-retry exhausts). ZCode app does this from its
|
|
8
|
+
* ModelProviderService; the bridge mirrors it by reading config.json directly.
|
|
9
|
+
*
|
|
10
|
+
* Provider element schema (from the backend's `j7t` converter in zcode.cjs):
|
|
11
|
+
* { providerId, apiKey?, apiKeyRequired?, apiFormat?, baseURL?, headers?,
|
|
12
|
+
* kind?, label?, models?, providerOptions?, source? }
|
|
13
|
+
* `apiKey` is a discriminated union `{source:"inline", value:"<key>"}` — a
|
|
14
|
+
* bare string is rejected. `apiFormat` maps from `kind`:
|
|
15
|
+
* anthropic → "anthropic-messages", openai-compatible → "openai-chat-completions".
|
|
16
|
+
*/
|
|
17
|
+
/** A model entry in config.json (`provider.<id>.models.<modelId>`). */
|
|
18
|
+
export interface ModelEntry {
|
|
19
|
+
name?: string;
|
|
20
|
+
limit?: {
|
|
21
|
+
context?: number;
|
|
22
|
+
output?: number;
|
|
23
|
+
};
|
|
24
|
+
reasoning?: {
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
variants?: string[];
|
|
27
|
+
defaultVariant?: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Registry payload for `workspace/updateProviderRegistry`. */
|
|
31
|
+
export interface ProviderRegistryPayload {
|
|
32
|
+
providers: ReadonlyArray<Record<string, unknown>>;
|
|
33
|
+
generatedAt: number;
|
|
34
|
+
revision: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build a single model element from a config.json model entry.
|
|
38
|
+
*
|
|
39
|
+
* Beyond `{modelId}`, the backend's schema accepts label / contextWindow /
|
|
40
|
+
* maxOutputTokens / reasoning. `reasoning` is the important one: without it
|
|
41
|
+
* the backend falls back to the apiFormat's default thought levels (a 2-state
|
|
42
|
+
* enabled/disabled for anthropic-messages), losing the provider's real
|
|
43
|
+
* variants (e.g. max/high/low) — the session then shows a wrong thought-level
|
|
44
|
+
* dropdown. config.json's `variants`/`defaultVariant` map to the protocol's
|
|
45
|
+
* `levels`/`defaultLevel`.
|
|
46
|
+
*
|
|
47
|
+
* Exported: runtime-model.ts reuses it for the `runtimeModel` overlay — both
|
|
48
|
+
* paths must carry identical model definitions or the overlay (resume /
|
|
49
|
+
* setModel) silently downgrades the session back to the 2-state default.
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildModelElement(modelId: string, m: ModelEntry): Record<string, unknown>;
|
|
52
|
+
/**
|
|
53
|
+
* Build the registry payload from ALL providers in config.json.
|
|
54
|
+
*
|
|
55
|
+
* Unlike `loadAllModels` (dropdown, enabled-only), the registry pushes every
|
|
56
|
+
* configured provider so the backend recognises any of them when a session
|
|
57
|
+
* switches to it. The backend applies its own enable/availability rules.
|
|
58
|
+
*/
|
|
59
|
+
export declare function buildProviderRegistry(): ProviderRegistryPayload;
|
|
60
|
+
//# sourceMappingURL=provider-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-registry.d.ts","sourceRoot":"","sources":["../../src/config/provider-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,uEAAuE;AACvE,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,SAAS,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjF;AAgBD,+DAA+D;AAC/D,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAUD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAezF;AAmCD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,uBAAuB,CAe/D"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a provider-registry payload for `workspace/updateProviderRegistry`.
|
|
3
|
+
*
|
|
4
|
+
* The V4 backend doesn't auto-load providers from config.json — the host must
|
|
5
|
+
* push them via this RPC after `session/create`, otherwise third-party
|
|
6
|
+
* providers fail with `provider_not_configured` (misclassified as a network
|
|
7
|
+
* error after turn-retry exhausts). ZCode app does this from its
|
|
8
|
+
* ModelProviderService; the bridge mirrors it by reading config.json directly.
|
|
9
|
+
*
|
|
10
|
+
* Provider element schema (from the backend's `j7t` converter in zcode.cjs):
|
|
11
|
+
* { providerId, apiKey?, apiKeyRequired?, apiFormat?, baseURL?, headers?,
|
|
12
|
+
* kind?, label?, models?, providerOptions?, source? }
|
|
13
|
+
* `apiKey` is a discriminated union `{source:"inline", value:"<key>"}` — a
|
|
14
|
+
* bare string is rejected. `apiFormat` maps from `kind`:
|
|
15
|
+
* anthropic → "anthropic-messages", openai-compatible → "openai-chat-completions".
|
|
16
|
+
*/
|
|
17
|
+
import { readFileSync } from "node:fs";
|
|
18
|
+
import { ZCODE_CREDS_PATH, log } from "../utils.js";
|
|
19
|
+
/** Map config.json `kind` → backend `apiFormat`. */
|
|
20
|
+
function apiFormatForKind(kind) {
|
|
21
|
+
if (!kind)
|
|
22
|
+
return undefined;
|
|
23
|
+
if (kind.includes("anthropic"))
|
|
24
|
+
return "anthropic-messages";
|
|
25
|
+
if (kind.includes("openai"))
|
|
26
|
+
return "openai-chat-completions";
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Build a single model element from a config.json model entry.
|
|
31
|
+
*
|
|
32
|
+
* Beyond `{modelId}`, the backend's schema accepts label / contextWindow /
|
|
33
|
+
* maxOutputTokens / reasoning. `reasoning` is the important one: without it
|
|
34
|
+
* the backend falls back to the apiFormat's default thought levels (a 2-state
|
|
35
|
+
* enabled/disabled for anthropic-messages), losing the provider's real
|
|
36
|
+
* variants (e.g. max/high/low) — the session then shows a wrong thought-level
|
|
37
|
+
* dropdown. config.json's `variants`/`defaultVariant` map to the protocol's
|
|
38
|
+
* `levels`/`defaultLevel`.
|
|
39
|
+
*
|
|
40
|
+
* Exported: runtime-model.ts reuses it for the `runtimeModel` overlay — both
|
|
41
|
+
* paths must carry identical model definitions or the overlay (resume /
|
|
42
|
+
* setModel) silently downgrades the session back to the 2-state default.
|
|
43
|
+
*/
|
|
44
|
+
export function buildModelElement(modelId, m) {
|
|
45
|
+
const el = { modelId };
|
|
46
|
+
if (m.name)
|
|
47
|
+
el.label = m.name;
|
|
48
|
+
if (m.limit?.context)
|
|
49
|
+
el.contextWindow = m.limit.context;
|
|
50
|
+
if (m.limit?.output)
|
|
51
|
+
el.maxOutputTokens = m.limit.output;
|
|
52
|
+
const variants = m.reasoning?.variants ?? [];
|
|
53
|
+
if (m.reasoning?.enabled && variants.length > 0) {
|
|
54
|
+
const reasoning = {
|
|
55
|
+
enabled: true,
|
|
56
|
+
levels: variants.map((v) => ({ value: v, label: v })),
|
|
57
|
+
};
|
|
58
|
+
if (m.reasoning.defaultVariant)
|
|
59
|
+
reasoning.defaultLevel = m.reasoning.defaultVariant;
|
|
60
|
+
el.reasoning = reasoning;
|
|
61
|
+
}
|
|
62
|
+
return el;
|
|
63
|
+
}
|
|
64
|
+
/** Build a single provider element from a config.json entry. */
|
|
65
|
+
function buildProviderElement(providerId, p) {
|
|
66
|
+
// models MUST be an array — the backend's strict schema rejects the object
|
|
67
|
+
// form ({modelId: {...}}) that config.json uses.
|
|
68
|
+
const models = Object.entries(p.models ?? {}).map(([modelId, m]) => buildModelElement(modelId, m ?? {}));
|
|
69
|
+
const el = {
|
|
70
|
+
providerId,
|
|
71
|
+
kind: p.kind,
|
|
72
|
+
apiFormat: apiFormatForKind(p.kind),
|
|
73
|
+
baseURL: p.options?.baseURL,
|
|
74
|
+
label: p.name ?? providerId,
|
|
75
|
+
models,
|
|
76
|
+
source: p.source ?? "custom",
|
|
77
|
+
};
|
|
78
|
+
if (p.options?.apiKeyRequired !== undefined) {
|
|
79
|
+
el.apiKeyRequired = p.options.apiKeyRequired;
|
|
80
|
+
}
|
|
81
|
+
// apiKey MUST be the inline union shape — a bare string is rejected by the
|
|
82
|
+
// backend's strict schema. When present, the backend stores it into its
|
|
83
|
+
// session secrets and resolves auth from there (no separate headers callback
|
|
84
|
+
// needed for these providers).
|
|
85
|
+
if (p.options?.apiKey) {
|
|
86
|
+
el.apiKey = { source: "inline", value: p.options.apiKey };
|
|
87
|
+
}
|
|
88
|
+
// Omit undefined values so the payload stays clean.
|
|
89
|
+
for (const k of Object.keys(el)) {
|
|
90
|
+
if (el[k] === undefined)
|
|
91
|
+
delete el[k];
|
|
92
|
+
}
|
|
93
|
+
return el;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Build the registry payload from ALL providers in config.json.
|
|
97
|
+
*
|
|
98
|
+
* Unlike `loadAllModels` (dropdown, enabled-only), the registry pushes every
|
|
99
|
+
* configured provider so the backend recognises any of them when a session
|
|
100
|
+
* switches to it. The backend applies its own enable/availability rules.
|
|
101
|
+
*/
|
|
102
|
+
export function buildProviderRegistry() {
|
|
103
|
+
const cfg = JSON.parse(readFileSync(ZCODE_CREDS_PATH, "utf8"));
|
|
104
|
+
const providers = Object.entries(cfg.provider ?? {}).map(([pid, p]) => buildProviderElement(pid, p ?? {}));
|
|
105
|
+
const generatedAt = Date.now();
|
|
106
|
+
// revision is a content hash; the backend skips unchanged revisions. A stable
|
|
107
|
+
// JSON hash over provider ids+kinds+baseURLs is enough — apiKey changes are
|
|
108
|
+
// rare and a generatedAt bump alone won't force re-apply (revision is the gate).
|
|
109
|
+
const revision = hashRevision(providers);
|
|
110
|
+
log(`provider-registry: built ${providers.length} provider(s) ` +
|
|
111
|
+
`(ids: ${providers.map((p) => p.providerId).join(", ") || "none"})`);
|
|
112
|
+
return { providers, generatedAt, revision };
|
|
113
|
+
}
|
|
114
|
+
/** Stable short hash over provider ids + kind + baseURL + models (revision gate). */
|
|
115
|
+
function hashRevision(providers) {
|
|
116
|
+
const sig = providers
|
|
117
|
+
.map((p) => `${p.providerId}|${p.kind ?? ""}|${p.baseURL ?? ""}|${JSON.stringify(p.models ?? [])}`)
|
|
118
|
+
.sort()
|
|
119
|
+
.join("\n");
|
|
120
|
+
// FNV-1a 32-bit → hex; cheap, dependency-free, stable.
|
|
121
|
+
let h = 0x811c9dc5;
|
|
122
|
+
for (let i = 0; i < sig.length; i++) {
|
|
123
|
+
h ^= sig.charCodeAt(i);
|
|
124
|
+
h = Math.imul(h, 0x01000193);
|
|
125
|
+
}
|
|
126
|
+
return (h >>> 0).toString(16).padStart(8, "0");
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=provider-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-registry.js","sourceRoot":"","sources":["../../src/config/provider-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,33 +1,69 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* runtimeModel overlay plumbing.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* The runtimeModel names the provider+model a session should use. For THIRD-
|
|
5
|
+
* PARTY providers it also carries `apiKey` as `{source:"inline", value:"<key>"}`;
|
|
6
|
+
* the backend resolves model-call auth from the overlay itself, so omitting it
|
|
7
|
+
* yields HTTP 401 "Missing API key". Builtin providers keep using their own
|
|
8
|
+
* OAuth/config auth and never inline a key. `apiFormat` mirrors `kind`.
|
|
7
9
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Two uses:
|
|
11
|
+
*
|
|
12
|
+
* 1. Resume/load overlay (`buildResumeRuntimeModel`): a resumed session may
|
|
13
|
+
* carry a stale/revoked model in its history → send fails with "历史模型
|
|
14
|
+
* 不可用". The overlay pins the session onto the default model — the FIRST
|
|
15
|
+
* enabled provider's FIRST model, the same one a fresh `session/new` lands
|
|
16
|
+
* on — so resume never inherits the session's last-used (possibly
|
|
17
|
+
* third-party / unavailable) model.
|
|
12
18
|
*
|
|
13
19
|
* 2. Model switch (`applyModelSwitch`): UI/slash model switching goes through
|
|
14
|
-
* `session/
|
|
15
|
-
* runtime-only
|
|
16
|
-
*
|
|
20
|
+
* `session/setModel` with both a `model` ref and a `runtimeModel` provider
|
|
21
|
+
* definition (runtime-only via `persistAsWorkspaceLastUsed:false`).
|
|
22
|
+
*
|
|
23
|
+
* Note: a provider registry push (`workspace/updateProviderRegistry`) is ALSO
|
|
24
|
+
* required for the backend to recognise third-party providers at all — without
|
|
25
|
+
* it the turn fails with `provider_not_configured` before auth is even tried.
|
|
26
|
+
* See provider-registry.ts.
|
|
17
27
|
*/
|
|
28
|
+
import { formatModelValue } from "./options.js";
|
|
29
|
+
import type { ModelRef } from "./options.js";
|
|
18
30
|
import type { ZcodeAcpServer } from "../server.js";
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Build a runtimeModel overlay for the given provider+model.
|
|
33
|
+
*
|
|
34
|
+
* For THIRD-PARTY providers the overlay MUST carry `apiKey` as the inline union
|
|
35
|
+
* `{source:"inline", value:"<key>"}` — the backend resolves model-call auth from
|
|
36
|
+
* the runtimeModel itself, so omitting it yields HTTP 401 "Missing API key".
|
|
37
|
+
* (This was previously believed unnecessary; live probing proved otherwise.)
|
|
38
|
+
* Builtin providers resolve auth from their own OAuth/config store, so no
|
|
39
|
+
* apiKey is sent for them. `apiFormat` mirrors `kind` per the backend's catalog.
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildRuntimeModel(ref: ModelRef, revision?: string): unknown | null;
|
|
42
|
+
/**
|
|
43
|
+
* Build the resume-time overlay pinned to the default model: the FIRST enabled
|
|
44
|
+
* provider's FIRST model (the same one a fresh `session/new` lands on). This
|
|
45
|
+
* ensures resume never inherits the session's last-used model, which may be a
|
|
46
|
+
* now-unavailable third-party model (e.g. Nvidia) and cause "历史模型不可用".
|
|
47
|
+
*/
|
|
22
48
|
export declare function buildResumeRuntimeModel(): unknown | null;
|
|
23
49
|
/**
|
|
24
|
-
* Switch a session's model via session/
|
|
50
|
+
* Switch a session's model via `session/setModel`.
|
|
51
|
+
*
|
|
52
|
+
* `value` is the configOption value: either `"providerId\modelId"` (encoded) or
|
|
53
|
+
* a legacy plain modelId (resolved to the first enabled builtin provider).
|
|
54
|
+
*
|
|
55
|
+
* Sends BOTH a `model` ref (the target) AND a `runtimeModel` (the full provider
|
|
56
|
+
* definition). The runtimeModel lets the backend register the provider into its
|
|
57
|
+
* workspace catalog (so even third-party / non-default models are recognised),
|
|
58
|
+
* while `model` names the selection. `persistAsWorkspaceLastUsed:false` keeps
|
|
59
|
+
* this a runtime-only change. Invalidates the model cache on success.
|
|
25
60
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
61
|
+
* NOTE: the older `session/updateRuntimeModelConfig` path returns `changed:false`
|
|
62
|
+
* on current backends without applying — `session/setModel` is the working
|
|
63
|
+
* protocol since the backend model-management refactor.
|
|
29
64
|
*/
|
|
30
|
-
export declare function applyModelSwitch(server: ZcodeAcpServer, zcodeSid: string,
|
|
65
|
+
export declare function applyModelSwitch(server: ZcodeAcpServer, zcodeSid: string, value: string): Promise<boolean>;
|
|
31
66
|
/** Invalidate the session-level model cache after a switch. */
|
|
32
67
|
export declare function invalidateModelCache(server: ZcodeAcpServer, zcodeSid: string): void;
|
|
68
|
+
export { formatModelValue };
|
|
33
69
|
//# sourceMappingURL=runtime-model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-model.d.ts","sourceRoot":"","sources":["../../src/config/runtime-model.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"runtime-model.d.ts","sourceRoot":"","sources":["../../src/config/runtime-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAEL,gBAAgB,EAIjB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAWnD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,SAAW,GAAG,OAAO,GAAG,IAAI,CAkCpF;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,GAAG,IAAI,CAOxD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAyBlB;AAED,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEnF;AAGD,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|