zcode-acp-server 0.1.0 → 0.2.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 +98 -1
- package/README.zh-CN.md +81 -1
- 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/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/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 +11 -2
- package/dist/handlers/io.d.ts.map +1 -1
- package/dist/handlers/io.js +51 -7
- package/dist/handlers/io.js.map +1 -1
- 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 +876 -220
- package/dist/handlers/session.js.map +1 -1
- package/dist/handlers/slash.d.ts +14 -0
- package/dist/handlers/slash.d.ts.map +1 -1
- package/dist/handlers/slash.js +80 -6
- package/dist/handlers/slash.js.map +1 -1
- package/dist/index.js +38 -4
- 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/server.d.ts +104 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +119 -2
- 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 +35 -6
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +52 -4
- package/dist/utils.js.map +1 -1
- package/docs/ARCHITECTURE.md +96 -38
- package/docs/BACKLOG.md +57 -0
- package/docs/DEVELOPMENT.md +5 -0
- package/docs/PROTOCOL.md +270 -5
- package/docs/TROUBLESHOOTING.md +98 -14
- package/docs/agents/domain.md +51 -0
- package/docs/agents/issue-tracker.md +22 -0
- package/docs/agents/triage-labels.md +15 -0
- package/package.json +6 -5
|
@@ -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"}
|
|
@@ -1,87 +1,129 @@
|
|
|
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
|
*/
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
28
|
+
import { buildModelElement } from "./provider-registry.js";
|
|
29
|
+
import { findProviderConfig, formatModelValue, isBuiltinProvider, loadAllModels, parseModelValue, } from "./options.js";
|
|
30
|
+
import { log, warn } from "../utils.js";
|
|
31
|
+
const DEFAULT_KIND = "anthropic";
|
|
32
|
+
const DEFAULT_BASE_URL = "https://open.bigmodel.cn/api/anthropic";
|
|
33
|
+
/** Map config.json `kind` → backend `apiFormat`. */
|
|
34
|
+
function apiFormatForKind(kind) {
|
|
35
|
+
if (kind?.includes("anthropic"))
|
|
36
|
+
return "anthropic-messages";
|
|
37
|
+
return "openai-chat-completions";
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build a runtimeModel overlay for the given provider+model.
|
|
41
|
+
*
|
|
42
|
+
* For THIRD-PARTY providers the overlay MUST carry `apiKey` as the inline union
|
|
43
|
+
* `{source:"inline", value:"<key>"}` — the backend resolves model-call auth from
|
|
44
|
+
* the runtimeModel itself, so omitting it yields HTTP 401 "Missing API key".
|
|
45
|
+
* (This was previously believed unnecessary; live probing proved otherwise.)
|
|
46
|
+
* Builtin providers resolve auth from their own OAuth/config store, so no
|
|
47
|
+
* apiKey is sent for them. `apiFormat` mirrors `kind` per the backend's catalog.
|
|
48
|
+
*/
|
|
49
|
+
export function buildRuntimeModel(ref, revision = "bridge") {
|
|
50
|
+
const p = findProviderConfig(ref.providerId);
|
|
51
|
+
if (!p) {
|
|
52
|
+
log(`runtime-model: provider "${ref.providerId}" not in config.json`);
|
|
53
|
+
return null;
|
|
44
54
|
}
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
const baseURL = p.options?.baseURL ?? DEFAULT_BASE_URL;
|
|
56
|
+
// Model elements must carry the full definition (reasoning variants /
|
|
57
|
+
// contextWindow / label) — a bare {modelId} overlay makes the backend fall
|
|
58
|
+
// back to the apiFormat's default 2-state thought levels (enabled/disabled),
|
|
59
|
+
// silently resetting the session's max/high/low dropdown on resume/switch.
|
|
60
|
+
const models = Object.entries(p.models ?? {}).map(([modelId, m]) => buildModelElement(modelId, (m ?? {})));
|
|
61
|
+
if (models.length === 0)
|
|
62
|
+
models.push({ modelId: ref.modelId });
|
|
63
|
+
const provider = {
|
|
64
|
+
providerId: ref.providerId,
|
|
65
|
+
kind: p.kind ?? DEFAULT_KIND,
|
|
66
|
+
apiFormat: apiFormatForKind(p.kind),
|
|
67
|
+
baseURL,
|
|
68
|
+
models,
|
|
69
|
+
};
|
|
70
|
+
// Third-party providers must inline their apiKey — the backend won't resolve
|
|
71
|
+
// it from anywhere else and the call fails with 401 without it. Builtin
|
|
72
|
+
// providers use OAuth/config auth and must NOT send an inline key.
|
|
73
|
+
if (!isBuiltinProvider(ref.providerId) && p.options?.apiKey) {
|
|
74
|
+
provider.apiKey = { source: "inline", value: p.options.apiKey };
|
|
47
75
|
}
|
|
48
|
-
return DEFAULTS;
|
|
49
|
-
}
|
|
50
|
-
/** Build a runtimeModel overlay object for the enabled provider. */
|
|
51
|
-
export function buildRuntimeModel(modelId, revision = "bridge") {
|
|
52
|
-
const pc = readEnabledProvider();
|
|
53
|
-
const targetModel = modelId ?? pc.modelId;
|
|
54
76
|
return {
|
|
55
77
|
revision,
|
|
56
78
|
generatedAt: Date.now(),
|
|
57
|
-
model: { providerId:
|
|
58
|
-
provider
|
|
59
|
-
providerId: pc.providerId,
|
|
60
|
-
kind: pc.kind,
|
|
61
|
-
baseURL: pc.baseURL,
|
|
62
|
-
models: pc.models.map((m) => ({ modelId: m })),
|
|
63
|
-
},
|
|
79
|
+
model: { providerId: ref.providerId, modelId: ref.modelId },
|
|
80
|
+
provider,
|
|
64
81
|
};
|
|
65
82
|
}
|
|
66
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* Build the resume-time overlay pinned to the default model: the FIRST enabled
|
|
85
|
+
* provider's FIRST model (the same one a fresh `session/new` lands on). This
|
|
86
|
+
* ensures resume never inherits the session's last-used model, which may be a
|
|
87
|
+
* now-unavailable third-party model (e.g. Nvidia) and cause "历史模型不可用".
|
|
88
|
+
*/
|
|
67
89
|
export function buildResumeRuntimeModel() {
|
|
68
|
-
|
|
90
|
+
const first = loadAllModels()[0];
|
|
91
|
+
if (!first) {
|
|
92
|
+
log("runtime-model: no enabled provider in config.json (resume overlay skipped)");
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return buildRuntimeModel(first, "bridge-resume");
|
|
69
96
|
}
|
|
70
97
|
/**
|
|
71
|
-
* Switch a session's model via session/
|
|
98
|
+
* Switch a session's model via `session/setModel`.
|
|
99
|
+
*
|
|
100
|
+
* `value` is the configOption value: either `"providerId\modelId"` (encoded) or
|
|
101
|
+
* a legacy plain modelId (resolved to the first enabled builtin provider).
|
|
102
|
+
*
|
|
103
|
+
* Sends BOTH a `model` ref (the target) AND a `runtimeModel` (the full provider
|
|
104
|
+
* definition). The runtimeModel lets the backend register the provider into its
|
|
105
|
+
* workspace catalog (so even third-party / non-default models are recognised),
|
|
106
|
+
* while `model` names the selection. `persistAsWorkspaceLastUsed:false` keeps
|
|
107
|
+
* this a runtime-only change. Invalidates the model cache on success.
|
|
72
108
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
109
|
+
* NOTE: the older `session/updateRuntimeModelConfig` path returns `changed:false`
|
|
110
|
+
* on current backends without applying — `session/setModel` is the working
|
|
111
|
+
* protocol since the backend model-management refactor.
|
|
76
112
|
*/
|
|
77
|
-
export async function applyModelSwitch(server, zcodeSid,
|
|
78
|
-
const
|
|
113
|
+
export async function applyModelSwitch(server, zcodeSid, value) {
|
|
114
|
+
const { providerId, modelId } = parseModelValue(value);
|
|
115
|
+
const runtimeModel = buildRuntimeModel({ providerId, providerName: providerId, modelId });
|
|
79
116
|
if (runtimeModel === null) {
|
|
80
|
-
log(
|
|
117
|
+
log(`runtime-model: cannot build overlay for "${value}" (provider not found)`);
|
|
81
118
|
return false;
|
|
82
119
|
}
|
|
83
120
|
const backend = server.ensureBackend();
|
|
84
|
-
const resp = await backend.request(server.nextId(), "session/
|
|
121
|
+
const resp = await backend.request(server.nextId(), "session/setModel", {
|
|
122
|
+
sessionId: zcodeSid,
|
|
123
|
+
model: { providerId, modelId },
|
|
124
|
+
runtimeModel,
|
|
125
|
+
persistAsWorkspaceLastUsed: false,
|
|
126
|
+
}, 15000);
|
|
85
127
|
if (resp.error) {
|
|
86
128
|
warn(`runtime-model: switch failed: ${resp.error.message}`);
|
|
87
129
|
return false;
|
|
@@ -93,4 +135,6 @@ export async function applyModelSwitch(server, zcodeSid, modelId) {
|
|
|
93
135
|
export function invalidateModelCache(server, zcodeSid) {
|
|
94
136
|
server.modelCache.delete(zcodeSid);
|
|
95
137
|
}
|
|
138
|
+
// Re-exported so callers that only import runtime-model.ts can format values.
|
|
139
|
+
export { formatModelValue };
|
|
96
140
|
//# sourceMappingURL=runtime-model.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-model.js","sourceRoot":"","sources":["../../src/config/runtime-model.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"runtime-model.js","sourceRoot":"","sources":["../../src/config/runtime-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill discovery — scans the same directories ZCode uses to discover Skills,
|
|
3
|
+
* reads each SKILL.md frontmatter, and returns entries suitable for the ACP
|
|
4
|
+
* `available_commands_update` notification.
|
|
5
|
+
*
|
|
6
|
+
* Each discovered skill becomes its own `/skill-name` slash command in the
|
|
7
|
+
* editor's completion menu (matching Claude Code's behaviour). The model
|
|
8
|
+
* resolves the invocation via its `Skill` tool — the bridge just lists them
|
|
9
|
+
* and passes the text through.
|
|
10
|
+
*
|
|
11
|
+
* Discovery sources (in priority order — first occurrence wins on name clash):
|
|
12
|
+
* 1. ~/.zcode/skills/*/SKILL.md (user scope, ZCode native)
|
|
13
|
+
* 2. ~/.agents/skills/*/SKILL.md (user scope, shared agents)
|
|
14
|
+
* 3. enabled plugin <cache>/skills/*/SKILL.md
|
|
15
|
+
* 4. <cwd>/.agents/skills/*/SKILL.md (project scope)
|
|
16
|
+
*
|
|
17
|
+
* Skills explicitly disabled in `~/.zcode/cli/config.json` (skills map with
|
|
18
|
+
* `enable: false`, keyed by absolute SKILL.md path) are excluded.
|
|
19
|
+
*/
|
|
20
|
+
/** A slash-command entry compatible with `sendAvailableCommands`. */
|
|
21
|
+
export interface SkillEntry {
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
input?: {
|
|
25
|
+
hint: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Discover all enabled skills from the filesystem.
|
|
30
|
+
*
|
|
31
|
+
* Returns entries suitable for `available_commands_update`. Best-effort:
|
|
32
|
+
* failures are logged and swallowed (returns whatever was found).
|
|
33
|
+
*/
|
|
34
|
+
export declare function loadSkillCommands(): SkillEntry[];
|
|
35
|
+
//# sourceMappingURL=skill-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-discovery.d.ts","sourceRoot":"","sources":["../../src/config/skill-discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH,qEAAqE;AACrE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1B;AAkHD;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,EAAE,CAwDhD"}
|