jishushell 0.4.24 → 0.4.30

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.
Files changed (167) hide show
  1. package/INSTALL-NOTICE +11 -0
  2. package/apps/browserless-chromium-container.yaml +78 -0
  3. package/apps/hermes-container.yaml +36 -2
  4. package/apps/ollama-binary.yaml +91 -90
  5. package/apps/ollama-cpu-container.yaml +8 -1
  6. package/apps/ollama-with-hollama-binary.yaml +91 -90
  7. package/apps/openclaw-binary.yaml +30 -1
  8. package/apps/openclaw-container.yaml +37 -2
  9. package/apps/openclaw-with-ollama-container.yaml +11 -2
  10. package/apps/openclaw-with-searxng-container.yaml +22 -2
  11. package/apps/openwebui-container.yaml +45 -1
  12. package/apps/playwright-container.yaml +7 -1
  13. package/apps/searxng-container.yaml +54 -4
  14. package/dist/cli/app.js +79 -9
  15. package/dist/cli/app.js.map +1 -1
  16. package/dist/cli/doctor.d.ts +12 -12
  17. package/dist/cli/doctor.js +242 -55
  18. package/dist/cli/doctor.js.map +1 -1
  19. package/dist/cli/llm.d.ts +4 -3
  20. package/dist/cli/llm.js +4 -3
  21. package/dist/cli/llm.js.map +1 -1
  22. package/dist/cli/panel.d.ts +6 -5
  23. package/dist/cli/panel.js +10 -9
  24. package/dist/cli/panel.js.map +1 -1
  25. package/dist/control.d.ts +7 -6
  26. package/dist/control.js +7 -6
  27. package/dist/control.js.map +1 -1
  28. package/dist/routes/agent-apps.d.ts +1 -1
  29. package/dist/routes/agent-apps.js +1 -1
  30. package/dist/routes/apps.js +44 -11
  31. package/dist/routes/apps.js.map +1 -1
  32. package/dist/routes/auth.js +3 -0
  33. package/dist/routes/auth.js.map +1 -1
  34. package/dist/routes/instances.js +787 -16
  35. package/dist/routes/instances.js.map +1 -1
  36. package/dist/routes/llm.js +24 -35
  37. package/dist/routes/llm.js.map +1 -1
  38. package/dist/routes/setup.js +1 -1
  39. package/dist/routes/setup.js.map +1 -1
  40. package/dist/server.d.ts +9 -0
  41. package/dist/server.js +410 -17
  42. package/dist/server.js.map +1 -1
  43. package/dist/services/agent-apps/catalog.js +4 -3
  44. package/dist/services/agent-apps/catalog.js.map +1 -1
  45. package/dist/services/agent-apps/index.d.ts +1 -1
  46. package/dist/services/agent-apps/index.js +1 -1
  47. package/dist/services/agent-apps/installers/adapter.d.ts +1 -1
  48. package/dist/services/agent-apps/installers/adapter.js +1 -1
  49. package/dist/services/agent-apps/installers/shell-script.d.ts +1 -1
  50. package/dist/services/agent-apps/installers/shell-script.js +3 -3
  51. package/dist/services/agent-apps/installers/shell-script.js.map +1 -1
  52. package/dist/services/agent-apps/types.d.ts +2 -2
  53. package/dist/services/agent-apps/types.js +1 -1
  54. package/dist/services/app/app-manager.d.ts +24 -1
  55. package/dist/services/app/app-manager.js +664 -116
  56. package/dist/services/app/app-manager.js.map +1 -1
  57. package/dist/services/app/hermes-agent-manager.js +6 -4
  58. package/dist/services/app/hermes-agent-manager.js.map +1 -1
  59. package/dist/services/app/provide-resolver.d.ts +29 -0
  60. package/dist/services/app/provide-resolver.js +112 -0
  61. package/dist/services/app/provide-resolver.js.map +1 -0
  62. package/dist/services/capability-endpoint-validator.d.ts +41 -0
  63. package/dist/services/capability-endpoint-validator.js +104 -0
  64. package/dist/services/capability-endpoint-validator.js.map +1 -0
  65. package/dist/services/capability-health.d.ts +16 -0
  66. package/dist/services/capability-health.js +121 -0
  67. package/dist/services/capability-health.js.map +1 -0
  68. package/dist/services/capability-registry.d.ts +106 -0
  69. package/dist/services/capability-registry.js +313 -0
  70. package/dist/services/capability-registry.js.map +1 -0
  71. package/dist/services/connection-apply.d.ts +89 -0
  72. package/dist/services/connection-apply.js +421 -0
  73. package/dist/services/connection-apply.js.map +1 -0
  74. package/dist/services/connection-resolver.d.ts +65 -0
  75. package/dist/services/connection-resolver.js +281 -0
  76. package/dist/services/connection-resolver.js.map +1 -0
  77. package/dist/services/connection-transactor.d.ts +37 -0
  78. package/dist/services/connection-transactor.js +341 -0
  79. package/dist/services/connection-transactor.js.map +1 -0
  80. package/dist/services/instance-manager.d.ts +13 -0
  81. package/dist/services/instance-manager.js +137 -23
  82. package/dist/services/instance-manager.js.map +1 -1
  83. package/dist/services/llm-proxy/index.d.ts +16 -2
  84. package/dist/services/llm-proxy/index.js +48 -44
  85. package/dist/services/llm-proxy/index.js.map +1 -1
  86. package/dist/services/llm-proxy/probe.d.ts +6 -0
  87. package/dist/services/llm-proxy/probe.js +85 -0
  88. package/dist/services/llm-proxy/probe.js.map +1 -0
  89. package/dist/services/llm-proxy/ssrf.d.ts +1 -0
  90. package/dist/services/llm-proxy/ssrf.js +18 -7
  91. package/dist/services/llm-proxy/ssrf.js.map +1 -1
  92. package/dist/services/nomad-manager.js +375 -16
  93. package/dist/services/nomad-manager.js.map +1 -1
  94. package/dist/services/process-manager.js +1 -1
  95. package/dist/services/process-manager.js.map +1 -1
  96. package/dist/services/runtime/adapters/hermes.d.ts +30 -1
  97. package/dist/services/runtime/adapters/hermes.js +218 -5
  98. package/dist/services/runtime/adapters/hermes.js.map +1 -1
  99. package/dist/services/runtime/adapters/openclaw-mcporter.d.ts +45 -0
  100. package/dist/services/runtime/adapters/openclaw-mcporter.js +108 -0
  101. package/dist/services/runtime/adapters/openclaw-mcporter.js.map +1 -0
  102. package/dist/services/runtime/adapters/openclaw.d.ts +87 -0
  103. package/dist/services/runtime/adapters/openclaw.js +250 -2
  104. package/dist/services/runtime/adapters/openclaw.js.map +1 -1
  105. package/dist/services/runtime/mcp-shims/firewall.d.ts +26 -0
  106. package/dist/services/runtime/mcp-shims/firewall.js +129 -0
  107. package/dist/services/runtime/mcp-shims/firewall.js.map +1 -0
  108. package/dist/services/runtime/mcp-shims/searxng-shim.d.ts +27 -0
  109. package/dist/services/runtime/mcp-shims/searxng-shim.js +125 -0
  110. package/dist/services/runtime/mcp-shims/searxng-shim.js.map +1 -0
  111. package/dist/services/runtime/mcp-shims/write-mcp-entry.d.ts +83 -0
  112. package/dist/services/runtime/mcp-shims/write-mcp-entry.js +127 -0
  113. package/dist/services/runtime/mcp-shims/write-mcp-entry.js.map +1 -0
  114. package/dist/services/runtime/migrations.d.ts +8 -0
  115. package/dist/services/runtime/migrations.js +100 -0
  116. package/dist/services/runtime/migrations.js.map +1 -1
  117. package/dist/services/runtime/types.d.ts +15 -0
  118. package/dist/services/setup-manager.js +6 -6
  119. package/dist/services/setup-manager.js.map +1 -1
  120. package/dist/services/suggestions.d.ts +27 -0
  121. package/dist/services/suggestions.js +133 -0
  122. package/dist/services/suggestions.js.map +1 -0
  123. package/dist/services/task-registry.js +4 -2
  124. package/dist/services/task-registry.js.map +1 -1
  125. package/dist/services/telemetry/device-fingerprint.d.ts +1 -1
  126. package/dist/services/telemetry/device-fingerprint.js +1 -1
  127. package/dist/services/types-shim.d.ts +16 -0
  128. package/dist/services/types-shim.js +2 -0
  129. package/dist/services/types-shim.js.map +1 -0
  130. package/dist/types.d.ts +171 -1
  131. package/dist/utils/instance-lock.d.ts +22 -0
  132. package/dist/utils/instance-lock.js +48 -0
  133. package/dist/utils/instance-lock.js.map +1 -0
  134. package/dist/utils/safe-json.js +55 -22
  135. package/dist/utils/safe-json.js.map +1 -1
  136. package/install/jishu-install.sh +323 -27
  137. package/install/jishu-uninstall.sh +353 -20
  138. package/package.json +3 -1
  139. package/public/assets/Dashboard-rkWp-CXd.js +1 -0
  140. package/public/assets/{HermesChatPanel-mFSureyc.js → HermesChatPanel-_GHoklgo.js} +1 -1
  141. package/public/assets/HermesConfigForm-anDnwUp_.js +4 -0
  142. package/public/assets/{InitPassword-CVA8wQA6.js → InitPassword-ZU9_-hDr.js} +1 -1
  143. package/public/assets/InstanceDetail-CN0FH1aw.js +92 -0
  144. package/public/assets/{Login-BWsZH2mu.js → Login-BItXqYAJ.js} +1 -1
  145. package/public/assets/NewInstance-BousE6kY.js +1 -0
  146. package/public/assets/ProviderRecommendations-DFYj7Fb6.js +1 -0
  147. package/public/assets/Settings-Bttc6QmM.js +1 -0
  148. package/public/assets/Setup-Bsxx1zgj.js +1 -0
  149. package/public/assets/{WeixinLoginPanel-CnjR8xMu.js → WeixinLoginPanel-DPZpAKgO.js} +2 -2
  150. package/public/assets/index-8xZy1z5k.css +1 -0
  151. package/public/assets/index-Dw3HhUYE.js +19 -0
  152. package/public/assets/providers-DtNXh9JD.js +1 -0
  153. package/public/assets/registry-5s2UB6is.js +2 -0
  154. package/public/index.html +2 -2
  155. package/scripts/check-app-spec.mjs +443 -0
  156. package/scripts/check-i18n.mjs +154 -0
  157. package/scripts/run.sh +4 -4
  158. package/public/assets/Dashboard-B-JoOjBQ.js +0 -1
  159. package/public/assets/HermesConfigForm-DvR05LK1.js +0 -4
  160. package/public/assets/InstanceDetail-DcZW2QGO.js +0 -91
  161. package/public/assets/NewInstance-BCIrAd86.js +0 -1
  162. package/public/assets/Settings-xkDcduFz.js +0 -1
  163. package/public/assets/Setup-Cfuwj4gV.js +0 -1
  164. package/public/assets/index-CPhVFEsx.css +0 -1
  165. package/public/assets/index-DQsM6Joa.js +0 -19
  166. package/public/assets/providers-V-vwrExZ.js +0 -1
  167. package/public/assets/registry-B4UFJdpA.js +0 -2
@@ -0,0 +1,421 @@
1
+ // ── URL builders (§7.0) ─────────────────────────────────────────────────
2
+ function isIPv6(host) {
3
+ return /:.*:/.test(host) && !host.startsWith("[");
4
+ }
5
+ function bracketIPv6(host) {
6
+ return isIPv6(host) ? `[${host}]` : host;
7
+ }
8
+ export function buildHttpBaseUrl(entry, opts = {}) {
9
+ const protocol = entry.protocol === "https" ? "https" : "http";
10
+ const url = new URL(`${protocol}://${bracketIPv6(entry.host)}:${entry.hostPort}`);
11
+ if (entry.path && entry.path !== "/")
12
+ url.pathname = entry.path;
13
+ const suffix = opts.suffix ?? "";
14
+ if (suffix) {
15
+ const norm = (s) => s.replace(/^\/+|\/+$/g, "");
16
+ if (!norm(url.pathname).endsWith(norm(suffix))) {
17
+ url.pathname = `${url.pathname.replace(/\/+$/, "")}/${suffix.replace(/^\/+/, "")}`;
18
+ }
19
+ }
20
+ return url.toString().replace(/\/$/, "");
21
+ }
22
+ export function buildWsUrl(entry, opts = {}) {
23
+ const protocol = entry.protocol === "wss" ? "wss" : "ws";
24
+ let url = `${protocol}://${bracketIPv6(entry.host)}:${entry.hostPort}`;
25
+ if (entry.path && entry.path !== "/")
26
+ url += entry.path;
27
+ if (opts.suffix)
28
+ url += opts.suffix.startsWith("/") ? opts.suffix : `/${opts.suffix}`;
29
+ return url;
30
+ }
31
+ // ── providerKindFromCapability for LLM proxy-upstream mode ─────────────
32
+ function providerKindFromCapability(cap) {
33
+ const m = cap.match(/^llm-(ollama|vllm|sglang)$/);
34
+ if (m)
35
+ return m[1];
36
+ return "custom";
37
+ }
38
+ // ── LLM proxy-upstream mode ────────────────────────────────────────────
39
+ const persistLlmProxyUpstream = async (instance, binding, _ctx) => {
40
+ if (binding.entries.length !== 1)
41
+ return;
42
+ const entry = binding.entries[0];
43
+ const baseUrl = buildHttpBaseUrl(entry, { suffix: "/v1" });
44
+ const providerKind = providerKindFromCapability(entry.capability);
45
+ // Probe the upstream so the user gets a "one-click connect" experience on
46
+ // the Connections tab: without this, models[] is empty and selectedModelId
47
+ // ends up as the placeholder "default", causing an immediate 404 from
48
+ // ollama / any sane backend on the very first chat request.
49
+ //
50
+ // probeProviderModels reuses the same path the LLM-Provider tab's "拉取
51
+ // 模型" button uses; failure (network, 4xx, etc.) is logged and swallowed
52
+ // — bind itself must not be blocked by transient probe issues. When the
53
+ // probe succeeds we also pre-pick the first model so the chat works
54
+ // without the user touching anything else.
55
+ let models;
56
+ let selectedModelId = binding.selectedModelId;
57
+ try {
58
+ const { probeProviderModels } = await import("./llm-proxy/probe.js");
59
+ const probed = await probeProviderModels(baseUrl, "", "Authorization", providerKind);
60
+ if (probed && probed.length > 0) {
61
+ models = probed
62
+ .map((m) => ({ id: String(m.id ?? m.name ?? ""), name: String(m.name ?? m.id ?? "") }))
63
+ .filter((m) => m.id);
64
+ if (!selectedModelId && models.length > 0)
65
+ selectedModelId = models[0].id;
66
+ }
67
+ }
68
+ catch (e) {
69
+ console.warn(`[connection-apply] probe upstream failed for ${instance.id} (${providerKind}, ${baseUrl}): ${e?.message ?? e}`);
70
+ }
71
+ // saveInstanceConfig encrypts apiKey itself — pass plaintext (empty for
72
+ // local LOCAL_PROVIDER_IDS ollama / vllm / sglang / custom).
73
+ const llmProxy = await import("./llm-proxy/index.js");
74
+ const config = llmProxy.getInstanceConfig(instance.id) ?? {};
75
+ const xj = (config["x-jishushell"] ??= {});
76
+ xj.proxy = xj.proxy ?? {};
77
+ xj.proxy.upstream = {
78
+ providerId: providerKind,
79
+ baseUrl,
80
+ api: "openai-completions",
81
+ authHeader: false,
82
+ apiKey: "",
83
+ ...(models && models.length ? { models } : {}),
84
+ ...(selectedModelId ? { selectedModelId } : {}),
85
+ };
86
+ await llmProxy.saveInstanceConfig(instance.id, config);
87
+ };
88
+ // ── resolveProviderToken (§7, PR B) ────────────────────────────────────
89
+ /**
90
+ * §7 — resolve the auth token for a provider instance at apply time.
91
+ *
92
+ * Returns the bare token string (no "Bearer " prefix — that's the consumer's
93
+ * call to format). Returns `null` when:
94
+ * - entry.auth is absent or kind === "none"
95
+ * - tokenSource refers to data that doesn't exist on disk
96
+ *
97
+ * Supported tokenSource patterns:
98
+ * instance.env.<NAME> → read from `~/.jishushell/instances/<provider-id>/{model.env,provider.env,.env}`
99
+ * instance.config.<path> → read from openclaw.json via dotted path (e.g. "x-jishushell.proxy.token")
100
+ * proxy.token → read llmProxy.getInstanceToken(provider-id)
101
+ */
102
+ export async function resolveProviderToken(entry) {
103
+ const auth = entry.auth;
104
+ if (!auth || auth.kind === "none")
105
+ return null;
106
+ const src = auth.tokenSource;
107
+ if (!src)
108
+ return null;
109
+ // instance.env.<NAME>
110
+ const envMatch = src.match(/^instance\.env\.([A-Z][A-Z0-9_]*)$/);
111
+ if (envMatch) {
112
+ const name = envMatch[1];
113
+ return readEnvVarFromInstanceDir(entry.instanceId, name);
114
+ }
115
+ // proxy.token — deferred to PR C (getInstanceToken not yet exported)
116
+ if (src === "proxy.token") {
117
+ const llmProxy = await import("./llm-proxy/index.js");
118
+ if (typeof llmProxy.getInstanceToken === "function") {
119
+ const tok = llmProxy.getInstanceToken(entry.instanceId);
120
+ return typeof tok === "string" && tok ? tok : null;
121
+ }
122
+ return null;
123
+ }
124
+ // instance.config.<dotted.path>
125
+ const cfgMatch = src.match(/^instance\.config\.(.+)$/);
126
+ if (cfgMatch) {
127
+ const path = cfgMatch[1];
128
+ return readConfigPathFromInstanceDir(entry.instanceId, path);
129
+ }
130
+ return null;
131
+ }
132
+ async function readEnvVarFromInstanceDir(instanceId, name) {
133
+ const { readFile } = await import("node:fs/promises");
134
+ const { join } = await import("node:path");
135
+ const { homedir } = await import("node:os");
136
+ const root = join(homedir(), ".jishushell");
137
+ // Priority order: app-manager apps (newer layout) first, then legacy instance layout.
138
+ const candidates = [
139
+ join(root, "apps", instanceId, "agent-home", ".env"),
140
+ join(root, "apps", instanceId, ".env"),
141
+ join(root, "instances", instanceId, "model.env"),
142
+ join(root, "instances", instanceId, "provider.env"),
143
+ join(root, "instances", instanceId, ".env"),
144
+ ];
145
+ for (const filePath of candidates) {
146
+ try {
147
+ const content = await readFile(filePath, "utf8");
148
+ for (const line of content.split("\n")) {
149
+ const m = line.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*?)\s*$/);
150
+ if (!m)
151
+ continue;
152
+ if (m[1] !== name)
153
+ continue;
154
+ let val = m[2];
155
+ if ((val.startsWith('"') && val.endsWith('"')) ||
156
+ (val.startsWith("'") && val.endsWith("'"))) {
157
+ val = val.slice(1, -1);
158
+ }
159
+ if (!val)
160
+ continue;
161
+ return val;
162
+ }
163
+ }
164
+ catch {
165
+ // file missing — try next
166
+ }
167
+ }
168
+ return null;
169
+ }
170
+ async function readConfigPathFromInstanceDir(instanceId, path) {
171
+ const { readFile } = await import("node:fs/promises");
172
+ const { join } = await import("node:path");
173
+ const { homedir } = await import("node:os");
174
+ const root = join(homedir(), ".jishushell");
175
+ const candidates = [
176
+ join(root, "apps", instanceId, "openclaw-home", ".openclaw", "openclaw.json"),
177
+ join(root, "instances", instanceId, "openclaw-home", ".openclaw", "openclaw.json"),
178
+ ];
179
+ for (const filePath of candidates) {
180
+ try {
181
+ const content = await readFile(filePath, "utf8");
182
+ const obj = JSON.parse(content);
183
+ let cur = obj;
184
+ for (const part of path.split(".")) {
185
+ if (cur == null || typeof cur !== "object")
186
+ return null;
187
+ cur = cur[part];
188
+ }
189
+ return typeof cur === "string" && cur ? cur : null;
190
+ }
191
+ catch {
192
+ // try next
193
+ }
194
+ }
195
+ return null;
196
+ }
197
+ // ── LLM openai-env mode ────────────────────────────────────────────────
198
+ async function llmOpenaiEnv(binding) {
199
+ if (binding.entries.length !== 1)
200
+ return {};
201
+ const entry = binding.entries[0];
202
+ const baseUrl = buildHttpBaseUrl(entry, { suffix: "/v1" });
203
+ const token = await resolveProviderToken(entry);
204
+ return {
205
+ [binding.slot]: baseUrl,
206
+ OPENAI_API_KEY: token ?? "",
207
+ OPENAI_API_BASE: baseUrl,
208
+ OPENAI_BASE_URL: baseUrl,
209
+ };
210
+ }
211
+ const persistLlmOpenaiEnv = async (instance, binding, ctx) => {
212
+ await ctx.writeConnectionEnv(instance, await llmOpenaiEnv(binding));
213
+ };
214
+ const runtimeLlmOpenaiEnv = async (_instance, binding) => llmOpenaiEnv(binding);
215
+ // ── LLM dispatch ───────────────────────────────────────────────────────
216
+ export const persistLlmConnection = async (instance, binding, ctx) => {
217
+ const mode = binding.apply ?? defaultLlmMode(ctx);
218
+ if (mode === "proxy-upstream")
219
+ return persistLlmProxyUpstream(instance, binding, ctx);
220
+ return persistLlmOpenaiEnv(instance, binding, ctx);
221
+ };
222
+ export const runtimeLlmConnection = async (_instance, binding) => {
223
+ const mode = binding.apply ?? "openai-env"; // adapter-typed defaults handled at persist time
224
+ if (mode === "proxy-upstream")
225
+ return {}; // runtime env already pinned by adapter
226
+ return llmOpenaiEnv(binding);
227
+ };
228
+ function defaultLlmMode(ctx) {
229
+ // adapter-managed consumers (OpenClaw / Hermes) default to proxy-upstream;
230
+ // generic container consumers (no adapter) default to openai-env.
231
+ return ctx.adapter ? "proxy-upstream" : "openai-env";
232
+ }
233
+ // ── Search ─────────────────────────────────────────────────────────────
234
+ function searchEnv(binding) {
235
+ if (binding.entries.length !== 1)
236
+ return {};
237
+ const entry = binding.entries[0];
238
+ const url = buildHttpBaseUrl(entry, { suffix: entry.path && entry.path !== "/" ? "" : "/search" });
239
+ return { [binding.slot]: url };
240
+ }
241
+ export const persistSearchConnection = async (instance, binding, ctx) => {
242
+ await ctx.writeConnectionEnv(instance, searchEnv(binding));
243
+ };
244
+ export const runtimeSearchConnection = (_instance, binding) => searchEnv(binding);
245
+ // ── Browser (PR 5 fills CDP/MCP — for now, raw env injection) ──────────
246
+ function browserEnv(binding) {
247
+ if (binding.entries.length !== 1)
248
+ return {};
249
+ const entry = binding.entries[0];
250
+ const url = entry.protocol === "ws" || entry.protocol === "wss"
251
+ ? buildWsUrl(entry)
252
+ : buildHttpBaseUrl(entry);
253
+ return { [binding.slot]: url };
254
+ }
255
+ export const persistBrowserConnection = async (instance, binding, ctx) => {
256
+ await ctx.writeConnectionEnv(instance, browserEnv(binding));
257
+ };
258
+ export const runtimeBrowserConnection = (_instance, binding) => browserEnv(binding);
259
+ // ── Default ENV (legacy bindable exact + unknown categories) ──────────
260
+ function defaultEnv(binding) {
261
+ if (binding.entries.length === 0)
262
+ return {};
263
+ // For default-ENV legacy fallback we serialize entry.address (host:port[/path]).
264
+ return { [binding.slot]: binding.entries.map((e) => e.address).join(",") };
265
+ }
266
+ export const persistDefaultConnection = async (instance, binding, ctx) => {
267
+ await ctx.writeConnectionEnv(instance, defaultEnv(binding));
268
+ };
269
+ export const runtimeDefaultConnection = (_instance, binding) => defaultEnv(binding);
270
+ // ── MCP — merges into mcporter.json with an explicit __source marker so
271
+ // we can later (un)bind without touching user-managed entries (§7.2).
272
+ export const persistMcpConnection = async (instance, binding, _ctx) => {
273
+ if (binding.entries.length === 0)
274
+ return;
275
+ const { mergeMcporterServers, removeMcporterServers } = await import("./runtime/adapters/openclaw-mcporter.js");
276
+ // Replace-style: drop any prior connection-managed entries for this
277
+ // (slot, consumer) pair, then re-merge the current set.
278
+ removeMcporterServers(instance.id, {
279
+ source: { kind: "connection", slot: binding.slot, consumerInstanceId: instance.id },
280
+ });
281
+ const servers = {};
282
+ for (const entry of binding.entries) {
283
+ const name = sanitize(`${entry.capability}-${entry.instanceId}`);
284
+ const transport = mcporterTransport(entry.protocol);
285
+ const url = transport === "stdio" ? undefined : buildHttpBaseUrl(entry);
286
+ servers[name] = {
287
+ ...(transport ? { transport } : {}),
288
+ ...(url ? { url } : {}),
289
+ __source: {
290
+ kind: "connection",
291
+ slot: binding.slot,
292
+ consumerInstanceId: instance.id,
293
+ },
294
+ };
295
+ }
296
+ mergeMcporterServers(instance.id, servers);
297
+ };
298
+ export const runtimeMcpConnection = (_instance, _binding) => {
299
+ // mcporter.json is read by the runtime directly; no env injection needed.
300
+ return {};
301
+ };
302
+ function sanitize(name) {
303
+ return name.replace(/[^a-zA-Z0-9_-]/g, "-").slice(0, 64);
304
+ }
305
+ function mcporterTransport(protocol) {
306
+ switch ((protocol || "").toLowerCase()) {
307
+ case "http":
308
+ case "https":
309
+ return "http";
310
+ case "sse":
311
+ case "ws":
312
+ case "wss":
313
+ return "sse";
314
+ default:
315
+ return undefined;
316
+ }
317
+ }
318
+ const unpersistLlmConnection = async (instance, _slot, ctx) => {
319
+ // Adapter-managed (proxy-upstream) consumers — OpenClaw / Hermes — keep
320
+ // their LLM target on `x-jishushell.proxy.upstream`. When the binding
321
+ // disappears, fall back to the panel-wide default provider so the chat
322
+ // path stays usable. Generic openai-env consumers just have their env
323
+ // cleared — there's nothing to "fall back" to for them.
324
+ if (!ctx.adapter) {
325
+ await ctx.writeConnectionEnv(instance, { OPENAI_BASE_URL: "", OPENAI_API_KEY: "" });
326
+ return;
327
+ }
328
+ const { getPanelConfig } = await import("../config.js");
329
+ const { decryptApiKey } = await import("./llm-proxy/encryption.js");
330
+ const { pushDefaultProviderToInstance } = await import("./llm-proxy/index.js");
331
+ const panel = getPanelConfig();
332
+ const providers = Array.isArray(panel?.providers) ? panel.providers : [];
333
+ const dp = panel?.default_provider && !panel.default_provider.skipped
334
+ ? panel.default_provider
335
+ : providers.find((p) => p?.isDefault) || providers[0];
336
+ if (!dp || dp.skipped) {
337
+ // No default to fall back to — leave the upstream as-is. The
338
+ // Connections badge already surfaces "未绑定" for the consumer; the
339
+ // proxy will return 401/4xx until the user picks a provider.
340
+ return;
341
+ }
342
+ await pushDefaultProviderToInstance(instance.id, {
343
+ providerId: dp.providerId,
344
+ baseUrl: dp.baseUrl,
345
+ api: dp.api,
346
+ authHeader: !!dp.authHeader,
347
+ models: dp.models ?? [],
348
+ selectedModelId: dp.selectedModelId ?? "",
349
+ apiKey: dp.apiKey ? decryptApiKey(dp.apiKey) : "",
350
+ });
351
+ };
352
+ const unpersistEnvSlotConnection = async (instance, slot, ctx) => {
353
+ // Search / browser / default-ENV all inject a single env var with key
354
+ // === slot. Empty-string overwrites the previous value so consumers see
355
+ // an unset binding instead of the stale URL.
356
+ await ctx.writeConnectionEnv(instance, { [slot]: "" });
357
+ };
358
+ const unpersistMcpConnection = async (instance, slot, _ctx) => {
359
+ const { removeMcporterServers } = await import("./runtime/adapters/openclaw-mcporter.js");
360
+ removeMcporterServers(instance.id, {
361
+ source: { kind: "connection", slot, consumerInstanceId: instance.id },
362
+ });
363
+ };
364
+ // ── Hook registries ────────────────────────────────────────────────────
365
+ export const PERSIST_HOOKS = {
366
+ llm: persistLlmConnection,
367
+ search: persistSearchConnection,
368
+ browser: persistBrowserConnection,
369
+ mcp: persistMcpConnection,
370
+ default: persistDefaultConnection,
371
+ };
372
+ export const UNPERSIST_HOOKS = {
373
+ llm: unpersistLlmConnection,
374
+ search: unpersistEnvSlotConnection,
375
+ browser: unpersistEnvSlotConnection,
376
+ mcp: unpersistMcpConnection,
377
+ default: unpersistEnvSlotConnection,
378
+ };
379
+ export const RUNTIME_HOOKS = {
380
+ llm: runtimeLlmConnection,
381
+ search: runtimeSearchConnection,
382
+ browser: runtimeBrowserConnection,
383
+ mcp: runtimeMcpConnection,
384
+ default: runtimeDefaultConnection,
385
+ };
386
+ /**
387
+ * Re-resolve `connections` for a consumer instance against the live capability
388
+ * registry and render every binding through RUNTIME_HOOKS into a flat env map.
389
+ *
390
+ * Use this at every start (not at PUT time) so that provider port / address
391
+ * changes propagate without requiring the user to re-bind. preCreate mode is
392
+ * used to stay tolerant: a missing required binding is surfaced via the
393
+ * Connections badge, not by failing start with a stale provider URL.
394
+ *
395
+ * Failures are caught and logged — start should never block on env merging.
396
+ */
397
+ export async function renderRuntimeConnectionsEnv(spec, instance) {
398
+ try {
399
+ const connections = instance.connections;
400
+ if (!connections || Object.keys(connections).length === 0)
401
+ return {};
402
+ const { resolveConnections } = await import("./connection-resolver.js");
403
+ const { resolved } = resolveConnections(spec, { connections }, "preCreate");
404
+ if (resolved.length === 0)
405
+ return {};
406
+ const merged = {};
407
+ for (const binding of resolved) {
408
+ const hook = RUNTIME_HOOKS[binding.category];
409
+ if (!hook)
410
+ continue;
411
+ const env = await hook(instance, binding);
412
+ Object.assign(merged, env);
413
+ }
414
+ return merged;
415
+ }
416
+ catch (e) {
417
+ console.warn(`[connection-apply] renderRuntimeConnectionsEnv failed for ${instance.id}: ${e?.message ?? e}`);
418
+ return {};
419
+ }
420
+ }
421
+ //# sourceMappingURL=connection-apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-apply.js","sourceRoot":"","sources":["../../src/services/connection-apply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import type { CapabilityEntry } from "./capability-registry.js";
2
+ import type { AppSpec, InstanceConnections } from "../types.js";
3
+ export declare function isCategoryToken(s: string): boolean;
4
+ /**
5
+ * Extract the category of a provide-side capability name. Returns the
6
+ * category token ("llm" / "search" / "browser" / "mcp") when the name is
7
+ * `<token>-something`; null for legacy exact names like `ollama-api`.
8
+ */
9
+ export declare function categoryFromProviderCapability(cap: string): string | null;
10
+ /**
11
+ * For LLM `proxy-upstream` mode: convert a provide capability like
12
+ * `llm-ollama` to the providerKind token (`ollama` / `vllm` / `sglang` /
13
+ * `custom`) the embedded llm-proxy expects on `x-jishushell.proxy.upstream.providerId`.
14
+ */
15
+ export declare function providerKindFromCapability(cap: string): string;
16
+ export interface ResolvedConnection {
17
+ slot: string;
18
+ capability: string;
19
+ category: string;
20
+ required: boolean;
21
+ apply?: "proxy-upstream" | "openai-env";
22
+ cardinality: "one" | "many";
23
+ /** Provider entries (single-candidate has length 1; many can be ≥1). */
24
+ entries: CapabilityEntry[];
25
+ /** Source of the binding — affects how apply hooks render the change. */
26
+ source: "ui-binding" | "legacy-fallback";
27
+ }
28
+ export interface PendingRequire {
29
+ slot: string;
30
+ capability: string;
31
+ required: boolean;
32
+ reason: "no-candidate" | "ambiguous" | "user-disconnected" | "needs-ui-binding";
33
+ }
34
+ export interface ResolveResult {
35
+ resolved: ResolvedConnection[];
36
+ pending: PendingRequire[];
37
+ }
38
+ export type ResolveMode = "preCreate" | "runtime";
39
+ export declare class ConnectionError extends Error {
40
+ code: string;
41
+ statusCode: number;
42
+ details?: any;
43
+ constructor(code: string, statusCode: number, message: string, details?: any);
44
+ }
45
+ /**
46
+ * Resolve all `requires` on `spec` against the registry + the instance's
47
+ * persisted bindings.
48
+ *
49
+ * @param spec Consumer app spec (`requires[]` is the input)
50
+ * @param instance Consumer app instance shape — may be a stub
51
+ * `{ connections: {} }` during create-instance / install
52
+ * (preCreate mode) or the live instance.json (runtime).
53
+ * @param mode Affects error semantics: preCreate never throws on
54
+ * missing/ambiguous; runtime throws.
55
+ */
56
+ export declare function resolveConnections(spec: AppSpec, instance: {
57
+ connections?: InstanceConnections;
58
+ }, mode: ResolveMode): ResolveResult;
59
+ /**
60
+ * Convenience helper: resolved → flat env map (for default-ENV legacy
61
+ * fallback path used in install Phase 1, see §6.4 lazy materialization).
62
+ * Only entries with category=="default" are projected; LLM/MCP/Search/Browser
63
+ * categories use their own apply hooks (PR 4) and are skipped here.
64
+ */
65
+ export declare function resolvedToLegacyEnv(resolved: ResolvedConnection[]): Record<string, string>;