paseo-plugin-zcode-provider 0.3.0 → 0.4.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.
Files changed (78) hide show
  1. package/NOTICE.md +2 -2
  2. package/README.md +9 -9
  3. package/package.json +4 -4
  4. package/server/account.ts +10 -0
  5. package/server/build-info.ts +1 -1
  6. package/server/discovery/manifest.ts +2 -2
  7. package/server/mapping.ts +31 -0
  8. package/server/provider.ts +5 -18
  9. package/server/runtime/pins.ts +3 -3
  10. package/server/session.ts +7 -10
  11. package/server/unsupported-capabilities.ts +4 -1
  12. package/server/vendor/zcode/NOTICE.md +4 -1
  13. package/server/vendor/zcode/packages/rpc/src/channelClient.ts +1 -0
  14. package/server/vendor/zcode/packages/rpc/src/channelServer.ts +2 -0
  15. package/server/vendor/zcode/packages/rpc/src/channels.shared.ts +1 -0
  16. package/server/vendor/zcode/packages/rpc/src/protocol.ts +3 -2
  17. package/server/vendor/zcode/packages/shared/src/app-runtime-preferences.ts +18 -0
  18. package/server/vendor/zcode/packages/shared/src/attachment-source.ts +5 -0
  19. package/server/vendor/zcode/packages/shared/src/bots.ts +385 -2
  20. package/server/vendor/zcode/packages/shared/src/browser-use/commands.ts +3 -1
  21. package/server/vendor/zcode/packages/shared/src/channel-mention.ts +131 -0
  22. package/server/vendor/zcode/packages/shared/src/conversationSelection.ts +37 -0
  23. package/server/vendor/zcode/packages/shared/src/dynamic-workflow-feature.ts +137 -0
  24. package/server/vendor/zcode/packages/shared/src/env.ts +15 -11
  25. package/server/vendor/zcode/packages/shared/src/highspeed.ts +232 -0
  26. package/server/vendor/zcode/packages/shared/src/mcp-apps/appTools.ts +148 -0
  27. package/server/vendor/zcode/packages/shared/src/mcp-apps/contract.ts +262 -0
  28. package/server/vendor/zcode/packages/shared/src/mcp-apps/instance.ts +12 -0
  29. package/server/vendor/zcode/packages/shared/src/mcp-apps/resourceMime.ts +73 -0
  30. package/server/vendor/zcode/packages/shared/src/mcp-apps/sampling.ts +117 -0
  31. package/server/vendor/zcode/packages/shared/src/mcp-apps/schemas.ts +90 -0
  32. package/server/vendor/zcode/packages/shared/src/model-execution.ts +58 -1
  33. package/server/vendor/zcode/packages/shared/src/oauth.ts +3 -0
  34. package/server/vendor/zcode/packages/shared/src/off-peak-execution.ts +73 -0
  35. package/server/vendor/zcode/packages/shared/src/protocol.ts +78 -4
  36. package/server/vendor/zcode/packages/shared/src/remoteTarget.ts +65 -0
  37. package/server/vendor/zcode/packages/shared/src/request-security-edition/verification-policy.ts +46 -0
  38. package/server/vendor/zcode/packages/shared/src/server-remote.ts +93 -0
  39. package/server/vendor/zcode/packages/shared/src/source-server/compatibility.ts +115 -0
  40. package/server/vendor/zcode/packages/shared/src/source-server/contracts.ts +426 -0
  41. package/server/vendor/zcode/packages/shared/src/source-server/errorCodes.ts +74 -0
  42. package/server/vendor/zcode/packages/shared/src/sqlite-migrations/contract.ts +83 -0
  43. package/server/vendor/zcode/packages/shared/src/subagent-profile.ts +62 -0
  44. package/server/vendor/zcode/packages/shared/src/subagent-runtime-config.ts +51 -0
  45. package/server/vendor/zcode/packages/shared/src/subagents-types.ts +164 -0
  46. package/server/vendor/zcode/packages/shared/src/usage-stats.ts +14 -0
  47. package/server/vendor/zcode/packages/shared/src/validationAppSettings.ts +136 -3
  48. package/server/vendor/zcode/packages/shared/src/version.ts +13 -0
  49. package/server/vendor/zcode/packages/shared/src/zcode-agent-policy.ts +24 -1
  50. package/server/vendor/zcode/packages/shared/src/zcode-protocol/index.ts +697 -36
  51. package/server/vendor/zcode/packages/shared/src/zcode-protocol/trace.ts +11 -0
  52. package/server/vendor/zcode/packages/shared/src/zcode-protocol-legacy-types.ts +14 -2
  53. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/apply.ts +28 -9
  54. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/attachment-ref.ts +3 -0
  55. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/command.ts +73 -53
  56. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/create-session-config.ts +15 -0
  57. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/create-workflow-display.ts +47 -1
  58. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/delta.ts +58 -2
  59. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/input-intent.ts +31 -0
  60. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/rows.ts +28 -13
  61. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index-workflow-activity.ts +37 -3
  62. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index.ts +36 -0
  63. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/snapshot.ts +21 -0
  64. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/submission.ts +1 -1
  65. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/toolDisplay.ts +32 -4
  66. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/transport.ts +31 -6
  67. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-assembler.ts +4 -1
  68. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-fault.ts +4 -1
  69. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-artifacts.ts +62 -4
  70. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-command-rejections.ts +30 -0
  71. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-row-meta.ts +40 -3
  72. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-run-settings-command.ts +2 -2
  73. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs-delta.ts +6 -5
  74. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs.ts +103 -26
  75. package/server/vendor/zcode/packages/shared/src/zcode-task-mode-schema.ts +13 -1
  76. package/server/vendor/zcode/packages/shared/src/zcode-task-types-core.ts +31 -2
  77. package/server/vendor/zcode/packages/shared/src/zcodeEndpoint.ts +188 -73
  78. package/server/vendor/zcode/provenance.json +189 -80
@@ -1,40 +1,72 @@
1
1
  import type { ZCodeEnv } from "./env.js";
2
2
 
3
3
  export const DEFAULT_ZCODE_ENDPOINT_ORIGIN = "https://zcode.z.ai";
4
+ export const TEST_ZCODE_ENDPOINT_ORIGIN = "https://zcode.z.ai";
5
+ export const CODING_PLAN_LOCAL_WEBVIEW_ORIGIN = "http://localhost:3000";
4
6
  export const DEFAULT_BIGMODEL_API_ORIGIN = "https://bigmodel.cn";
7
+ export const TEST_BIGMODEL_API_ORIGIN = "https://bigmodel.cn";
5
8
  export const DEFAULT_ZAI_OAUTH_ORIGIN = "https://chat.z.ai";
9
+ export const TEST_ZAI_OAUTH_ORIGIN = "https://chat.z.ai";
6
10
  export const DEFAULT_ZAI_BUSINESS_BASE_URL = "https://api.z.ai";
11
+ export const TEST_ZAI_BUSINESS_BASE_URL = "https://api.z.ai";
7
12
  export const DEFAULT_ZAI_OAUTH_CLIENT_ID = "client_P8X5CMWmlaRO9gyO-KSqtg";
13
+ export const TEST_ZAI_OAUTH_CLIENT_ID = "client_P8X5CMWmlaRO9gyO-KSqtg";
14
+ export const DEFAULT_WEB_REMOTE_CONTROL_RELAY_WS_URL = "wss://zcode.z.ai/api/v1/remote/ws2";
15
+ export const WEB_REMOTE_CONTROL_V4_MIN_APP_VERSION = "3.4.0";
8
16
 
9
- // 构建仅注入公开链接;Node 调用方仍可显式传 env,避免读取另一进程的配置。
10
- declare const __ZCODE_ENDPOINT_ENV__: Record<string, string | undefined> | undefined;
11
- export function pickProductEndpointEnv(
12
- env: Record<string, string | undefined>,
13
- ): Record<string, string> {
14
- const keys = [
15
- "ZCODE_BASE_URL",
16
- "ZCODE_ENDPOINT_ORIGIN",
17
- "BIGMODEL_API_BASE_URL",
18
- "ZAI_OAUTH_ORIGIN",
19
- "ZAI_BUSINESS_BASE_URL",
20
- "ZAI_OAUTH_CLIENT_ID",
21
- "ZAI_OAUTH_APP_ID",
22
- ];
23
- return Object.fromEntries(
24
- keys.flatMap((key) => (env[key]?.trim() ? [[key, env[key]!.trim()]] : [])),
25
- );
17
+ export interface BuildZCodeEndpointUrlsOptions {
18
+ appVersion?: string;
26
19
  }
27
- export function readProductEndpointEnv(): Record<string, string | undefined> {
28
- return {
29
- ...(typeof __ZCODE_ENDPOINT_ENV__ === "undefined" ? {} : __ZCODE_ENDPOINT_ENV__),
30
- ...pickProductEndpointEnv(typeof process === "undefined" ? {} : process.env),
31
- };
20
+
21
+ function isWebRemoteControlV4AppVersion(appVersion: string | undefined): boolean {
22
+ if (!appVersion) {
23
+ return false;
24
+ }
25
+
26
+ // zcodeEndpoint 会被 Vite 配置在 Node 加载期直接导入,不能依赖源码态 `.js` runtime import。
27
+ // 这里只比较固定的稳定版门槛;高于 3.4.0 的预发布版本仍满足门槛,3.4.0 自身的预发布版本不满足。
28
+ const normalizedVersion = appVersion.trim().replace(/^v/i, "");
29
+ const match = normalizedVersion.match(
30
+ /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([^+]+))?(?:\+(.+))?$/,
31
+ );
32
+ if (!match) {
33
+ return false;
34
+ }
35
+
36
+ const prereleaseIdentifiers = match[4]?.split(".");
37
+ const hasValidPrerelease =
38
+ prereleaseIdentifiers === undefined ||
39
+ prereleaseIdentifiers.every(
40
+ (identifier) =>
41
+ /^[0-9A-Za-z-]+$/.test(identifier) &&
42
+ (!/^\d+$/.test(identifier) || /^(0|[1-9]\d*)$/.test(identifier)),
43
+ );
44
+ const buildIdentifiers = match[5]?.split(".");
45
+ const hasValidBuild =
46
+ buildIdentifiers === undefined ||
47
+ buildIdentifiers.every((identifier) => /^[0-9A-Za-z-]+$/.test(identifier));
48
+ if (!hasValidPrerelease || !hasValidBuild) {
49
+ return false;
50
+ }
51
+
52
+ const versionParts = [Number(match[1]), Number(match[2]), Number(match[3])];
53
+ const floorParts = WEB_REMOTE_CONTROL_V4_MIN_APP_VERSION.split(".").map(Number);
54
+ for (let index = 0; index < floorParts.length; index += 1) {
55
+ if (versionParts[index]! !== floorParts[index]!) {
56
+ return versionParts[index]! > floorParts[index]!;
57
+ }
58
+ }
59
+
60
+ return prereleaseIdentifiers === undefined;
32
61
  }
33
62
 
34
63
  export interface ZCodeEndpointUrls {
35
64
  origin: string;
36
65
  apiBaseUrl: string;
66
+ remoteUrl: string;
67
+ webRemoteCallbackUrl: string;
37
68
  webShareCallbackUrl: string;
69
+ relayWsUrl: string;
38
70
  zcodePlanOpenAiBaseUrl: string;
39
71
  zcodePlanAnthropicBaseUrl: string;
40
72
  zcodePlanBillingCurrentUrl: string;
@@ -46,20 +78,30 @@ export interface RuntimeZCodeEndpointEnv {
46
78
  ZCODE_ENV?: string;
47
79
  ZCODE_BASE_URL?: string;
48
80
  ZCODE_ENDPOINT_ORIGIN?: string;
81
+ ZCODE_TEST_BASE_URL?: string;
82
+ ZCODE_PRODUCTION_BASE_URL?: string;
49
83
  }
50
84
 
51
85
  export interface RuntimeBigModelApiEnv {
52
86
  [key: string]: string | undefined;
53
87
  ZCODE_ENV?: string;
54
88
  BIGMODEL_API_BASE_URL?: string;
89
+ BIGMODEL_TEST_API_BASE_URL?: string;
90
+ BIGMODEL_PRODUCTION_API_BASE_URL?: string;
55
91
  }
56
92
 
57
93
  export interface RuntimeZaiEndpointEnv {
58
94
  [key: string]: string | undefined;
59
95
  ZCODE_ENV?: string;
60
96
  ZAI_OAUTH_ORIGIN?: string;
97
+ ZAI_TEST_OAUTH_ORIGIN?: string;
98
+ ZAI_PRODUCTION_OAUTH_ORIGIN?: string;
61
99
  ZAI_BUSINESS_BASE_URL?: string;
100
+ ZAI_TEST_BUSINESS_BASE_URL?: string;
101
+ ZAI_PRODUCTION_BUSINESS_BASE_URL?: string;
62
102
  ZAI_OAUTH_CLIENT_ID?: string;
103
+ ZAI_TEST_OAUTH_CLIENT_ID?: string;
104
+ ZAI_PRODUCTION_OAUTH_CLIENT_ID?: string;
63
105
  ZAI_OAUTH_APP_ID?: string;
64
106
  }
65
107
 
@@ -84,6 +126,15 @@ function readRuntimeEnvValue(
84
126
  return value ? value : undefined;
85
127
  }
86
128
 
129
+ function readRuntimeZCodeEnvScopedValue(
130
+ env: Record<string, string | undefined>,
131
+ zcodeEnv: ZCodeEnv,
132
+ testKey: string,
133
+ productionKey: string,
134
+ ): string | undefined {
135
+ return readRuntimeEnvValue(env, zcodeEnv === "production" ? productionKey : testKey);
136
+ }
137
+
87
138
  export function normalizeZCodeEndpointOrigin(value: string): string {
88
139
  const trimmed = value.trim();
89
140
  if (!trimmed) {
@@ -112,7 +163,8 @@ export function isTrustedCodingPlanWebviewOrigin(
112
163
  const origin = normalizeZCodeEndpointOrigin(value);
113
164
  if (
114
165
  origin === DEFAULT_ZCODE_ENDPOINT_ORIGIN ||
115
- origin === resolveRuntimeZCodeEndpointOrigin()
166
+ origin === TEST_ZCODE_ENDPOINT_ORIGIN ||
167
+ origin === CODING_PLAN_LOCAL_WEBVIEW_ORIGIN
116
168
  ) {
117
169
  return true;
118
170
  }
@@ -128,95 +180,152 @@ export function resolveZCodeEndpointOrigin(options?: {
128
180
  envBaseOrigin?: string | null;
129
181
  overrideOrigin?: string | null;
130
182
  }): string {
131
- const origin = options?.overrideOrigin?.trim() || options?.envBaseOrigin?.trim();
132
- return origin ? normalizeZCodeEndpointOrigin(origin) : DEFAULT_ZCODE_ENDPOINT_ORIGIN;
183
+ const env = options?.env ?? "test";
184
+ const envBaseOrigin = options?.envBaseOrigin?.trim();
185
+ if (env === "production") {
186
+ return envBaseOrigin
187
+ ? normalizeZCodeEndpointOrigin(envBaseOrigin)
188
+ : DEFAULT_ZCODE_ENDPOINT_ORIGIN;
189
+ }
190
+
191
+ const overrideOrigin = options?.overrideOrigin?.trim();
192
+ if (overrideOrigin) {
193
+ return normalizeZCodeEndpointOrigin(overrideOrigin);
194
+ }
195
+
196
+ return envBaseOrigin ? normalizeZCodeEndpointOrigin(envBaseOrigin) : TEST_ZCODE_ENDPOINT_ORIGIN;
133
197
  }
134
198
 
135
- export function resolveRuntimeZCodeEnv(
136
- env: RuntimeZCodeEndpointEnv = readProductEndpointEnv(),
137
- ): ZCodeEnv {
138
- // 产品身份仅用于既有展示与安装标识,不参与地址解析。
199
+ export function resolveRuntimeZCodeEnv(env: RuntimeZCodeEndpointEnv = {}): ZCodeEnv {
200
+ // 独立 CLI / 服务测试未注入 ZCODE_ENV 时默认生产域;桌面测试包会显式下发 ZCODE_ENV=test。
139
201
  return env.ZCODE_ENV?.trim().toLowerCase() === "test" ? "test" : "production";
140
202
  }
141
203
 
142
204
  export function resolveRuntimeZCodeEndpointOrigin(
143
- env: RuntimeZCodeEndpointEnv = readProductEndpointEnv(),
205
+ env: RuntimeZCodeEndpointEnv = {},
144
206
  options?: { overrideOrigin?: string | null },
145
207
  ): string {
208
+ const zcodeEnv = resolveRuntimeZCodeEnv(env);
209
+ const scopedBaseOrigin =
210
+ zcodeEnv === "production"
211
+ ? readRuntimeEnvValue(env, "ZCODE_PRODUCTION_BASE_URL")
212
+ : readRuntimeEnvValue(env, "ZCODE_TEST_BASE_URL");
213
+
146
214
  return resolveZCodeEndpointOrigin({
215
+ env: zcodeEnv,
147
216
  envBaseOrigin:
148
217
  readRuntimeEnvValue(env, "ZCODE_BASE_URL") ??
149
- readRuntimeEnvValue(env, "ZCODE_ENDPOINT_ORIGIN"),
218
+ readRuntimeEnvValue(env, "ZCODE_ENDPOINT_ORIGIN") ??
219
+ scopedBaseOrigin,
150
220
  overrideOrigin: options?.overrideOrigin,
151
221
  });
152
222
  }
153
223
 
154
224
  export function buildRuntimeZCodeEndpointUrls(
155
- env: RuntimeZCodeEndpointEnv = readProductEndpointEnv(),
225
+ env: RuntimeZCodeEndpointEnv = {},
156
226
  ): ZCodeEndpointUrls {
157
227
  return buildZCodeEndpointUrls(resolveRuntimeZCodeEndpointOrigin(env));
158
228
  }
159
229
 
160
- export function buildRuntimeZCodeApiUrl(
161
- env: RuntimeZCodeEndpointEnv = readProductEndpointEnv(),
162
- path: string,
163
- ): string {
230
+ export function buildRuntimeZCodeApiUrl(env: RuntimeZCodeEndpointEnv = {}, path: string): string {
164
231
  const normalizedPath = path.startsWith("/") ? path : `/${path}`;
165
232
  return `${resolveRuntimeZCodeEndpointOrigin(env)}${normalizedPath}`;
166
233
  }
167
234
 
168
- export function resolveBigModelApiOrigin(
169
- env: RuntimeBigModelApiEnv = readProductEndpointEnv(),
170
- ): string {
235
+ export function resolveWebRemoteControlRelayWsUrl(options?: {
236
+ endpointOrigin?: string | null | undefined;
237
+ overrideUrl?: string | null | undefined;
238
+ }): string {
239
+ const overrideUrl = options?.overrideUrl?.trim();
240
+ if (overrideUrl) {
241
+ return overrideUrl;
242
+ }
243
+
244
+ const origin = new URL(
245
+ normalizeZCodeEndpointOrigin(options?.endpointOrigin?.trim() || DEFAULT_ZCODE_ENDPOINT_ORIGIN),
246
+ );
247
+ origin.protocol = origin.protocol === "https:" ? "wss:" : "ws:";
248
+ origin.pathname = "/api/v1/remote/ws2";
249
+ return origin.toString();
250
+ }
251
+
252
+ export function resolveBigModelApiOrigin(env: RuntimeBigModelApiEnv = {}): string {
253
+ const zcodeEnv = resolveRuntimeZCodeEnv(env);
254
+ const scopedBaseOrigin =
255
+ zcodeEnv === "production"
256
+ ? readRuntimeEnvValue(env, "BIGMODEL_PRODUCTION_API_BASE_URL")
257
+ : readRuntimeEnvValue(env, "BIGMODEL_TEST_API_BASE_URL");
258
+ const fallbackOrigin =
259
+ zcodeEnv === "production" ? DEFAULT_BIGMODEL_API_ORIGIN : TEST_BIGMODEL_API_ORIGIN;
260
+
171
261
  return normalizeZCodeEndpointOrigin(
172
- readRuntimeEnvValue(env, "BIGMODEL_API_BASE_URL") ?? DEFAULT_BIGMODEL_API_ORIGIN,
262
+ readRuntimeEnvValue(env, "BIGMODEL_API_BASE_URL") ?? scopedBaseOrigin ?? fallbackOrigin,
173
263
  );
174
264
  }
175
265
 
176
- export function buildBigModelApiUrl(
177
- env: RuntimeBigModelApiEnv = readProductEndpointEnv(),
178
- path: string,
179
- ): string {
266
+ export function buildBigModelApiUrl(env: RuntimeBigModelApiEnv = {}, path: string): string {
180
267
  const normalizedPath = path.startsWith("/") ? path : `/${path}`;
181
268
  return `${resolveBigModelApiOrigin(env)}${normalizedPath}`;
182
269
  }
183
270
 
184
- export function buildBigModelCodingPlanPersonalManageUrl(
185
- env: RuntimeBigModelApiEnv = readProductEndpointEnv(),
186
- ): string {
187
- // 管理页与业务 API 共用显式 origin,避免把已登录账号带到另一个部署。
271
+ export function buildBigModelCodingPlanPersonalManageUrl(env: RuntimeBigModelApiEnv = {}): string {
272
+ // 修复原因:BigModel Coding Plan 管理页要跟随 ZCODE_ENV;
273
+ // 测试环境如果继续写死 bigmodel.cn,会把测试账号带到生产套餐页。
188
274
  return buildBigModelApiUrl(env, "/coding-plan/personal/overview");
189
275
  }
190
276
 
191
- export function buildBigModelCodingPlanTeamManageUrl(
192
- env: RuntimeBigModelApiEnv = readProductEndpointEnv(),
193
- ): string {
277
+ export function buildBigModelCodingPlanTeamManageUrl(env: RuntimeBigModelApiEnv = {}): string {
194
278
  return buildBigModelApiUrl(env, "/coding-plan/team/plans");
195
279
  }
196
280
 
197
- export function resolveZaiOAuthOrigin(
198
- env: RuntimeZaiEndpointEnv = readProductEndpointEnv(),
199
- ): string {
281
+ export function resolveZaiOAuthOrigin(env: RuntimeZaiEndpointEnv = {}): string {
282
+ const zcodeEnv = resolveRuntimeZCodeEnv(env);
283
+ const scopedOrigin = readRuntimeZCodeEnvScopedValue(
284
+ env,
285
+ zcodeEnv,
286
+ "ZAI_TEST_OAUTH_ORIGIN",
287
+ "ZAI_PRODUCTION_OAUTH_ORIGIN",
288
+ );
289
+ const fallbackOrigin =
290
+ zcodeEnv === "production" ? DEFAULT_ZAI_OAUTH_ORIGIN : TEST_ZAI_OAUTH_ORIGIN;
291
+
200
292
  return normalizeZCodeEndpointOrigin(
201
- readRuntimeEnvValue(env, "ZAI_OAUTH_ORIGIN") ?? DEFAULT_ZAI_OAUTH_ORIGIN,
293
+ readRuntimeEnvValue(env, "ZAI_OAUTH_ORIGIN") ?? scopedOrigin ?? fallbackOrigin,
202
294
  );
203
295
  }
204
296
 
205
- export function resolveZaiBusinessBaseUrl(
206
- env: RuntimeZaiEndpointEnv = readProductEndpointEnv(),
207
- ): string {
297
+ export function resolveZaiBusinessBaseUrl(env: RuntimeZaiEndpointEnv = {}): string {
298
+ const zcodeEnv = resolveRuntimeZCodeEnv(env);
299
+ const scopedOrigin = readRuntimeZCodeEnvScopedValue(
300
+ env,
301
+ zcodeEnv,
302
+ "ZAI_TEST_BUSINESS_BASE_URL",
303
+ "ZAI_PRODUCTION_BUSINESS_BASE_URL",
304
+ );
305
+ const fallbackOrigin =
306
+ zcodeEnv === "production" ? DEFAULT_ZAI_BUSINESS_BASE_URL : TEST_ZAI_BUSINESS_BASE_URL;
307
+
208
308
  return normalizeZCodeEndpointOrigin(
209
- readRuntimeEnvValue(env, "ZAI_BUSINESS_BASE_URL") ?? DEFAULT_ZAI_BUSINESS_BASE_URL,
309
+ readRuntimeEnvValue(env, "ZAI_BUSINESS_BASE_URL") ?? scopedOrigin ?? fallbackOrigin,
210
310
  );
211
311
  }
212
312
 
213
- export function resolveZaiOAuthClientId(
214
- env: RuntimeZaiEndpointEnv = readProductEndpointEnv(),
215
- ): string {
313
+ export function resolveZaiOAuthClientId(env: RuntimeZaiEndpointEnv = {}): string {
314
+ const zcodeEnv = resolveRuntimeZCodeEnv(env);
315
+ const scopedClientId = readRuntimeZCodeEnvScopedValue(
316
+ env,
317
+ zcodeEnv,
318
+ "ZAI_TEST_OAUTH_CLIENT_ID",
319
+ "ZAI_PRODUCTION_OAUTH_CLIENT_ID",
320
+ );
321
+ const fallbackClientId =
322
+ zcodeEnv === "production" ? DEFAULT_ZAI_OAUTH_CLIENT_ID : TEST_ZAI_OAUTH_CLIENT_ID;
323
+
216
324
  return (
217
325
  readRuntimeEnvValue(env, "ZAI_OAUTH_CLIENT_ID") ??
326
+ scopedClientId ??
218
327
  readRuntimeEnvValue(env, "ZAI_OAUTH_APP_ID") ??
219
- DEFAULT_ZAI_OAUTH_CLIENT_ID
328
+ fallbackClientId
220
329
  );
221
330
  }
222
331
 
@@ -225,23 +334,17 @@ export function buildZaiOAuthUrl(origin: string, path: string): string {
225
334
  return `${normalizeZCodeEndpointOrigin(origin)}${normalizedPath}`;
226
335
  }
227
336
 
228
- export function buildRuntimeZaiOAuthUrl(
229
- env: RuntimeZaiEndpointEnv = readProductEndpointEnv(),
230
- path: string,
231
- ): string {
337
+ export function buildRuntimeZaiOAuthUrl(env: RuntimeZaiEndpointEnv = {}, path: string): string {
232
338
  return buildZaiOAuthUrl(resolveZaiOAuthOrigin(env), path);
233
339
  }
234
340
 
235
- export function buildRuntimeZaiBusinessUrl(
236
- env: RuntimeZaiEndpointEnv = readProductEndpointEnv(),
237
- path: string,
238
- ): string {
341
+ export function buildRuntimeZaiBusinessUrl(env: RuntimeZaiEndpointEnv = {}, path: string): string {
239
342
  const normalizedPath = path.startsWith("/") ? path : `/${path}`;
240
343
  return `${resolveZaiBusinessBaseUrl(env)}${normalizedPath}`;
241
344
  }
242
345
 
243
346
  export function resolveRuntimeProductEndpointConfig(
244
- env: RuntimeProductEndpointEnv = readProductEndpointEnv(),
347
+ env: RuntimeProductEndpointEnv = {},
245
348
  ): RuntimeProductEndpointConfig {
246
349
  const zcodeEnv = resolveRuntimeZCodeEnv(env);
247
350
  const zcodeEndpointOrigin = resolveRuntimeZCodeEndpointOrigin(env);
@@ -257,12 +360,24 @@ export function resolveRuntimeProductEndpointConfig(
257
360
  };
258
361
  }
259
362
 
260
- export function buildZCodeEndpointUrls(origin: string): ZCodeEndpointUrls {
363
+ export function buildZCodeEndpointUrls(
364
+ origin: string,
365
+ options: BuildZCodeEndpointUrlsOptions = {},
366
+ ): ZCodeEndpointUrls {
261
367
  const normalizedOrigin = normalizeZCodeEndpointOrigin(origin);
368
+ const parsed = new URL(normalizedOrigin);
369
+ const wsProtocol = parsed.protocol === "https:" ? "wss:" : "ws:";
370
+ const wsOrigin = `${wsProtocol}//${parsed.host}`;
371
+ // 无法解析或低于分界版本时保守使用 v3,避免开发版本和旧客户端进入未兼容的 v4 页面。
372
+ const remoteVersion = isWebRemoteControlV4AppVersion(options.appVersion) ? "v4" : "v3";
373
+
262
374
  return {
263
375
  origin: normalizedOrigin,
264
376
  apiBaseUrl: `${normalizedOrigin}/api/v1`,
377
+ remoteUrl: `${normalizedOrigin}/remote/${remoteVersion}`,
378
+ webRemoteCallbackUrl: `${normalizedOrigin}/remote/v4`,
265
379
  webShareCallbackUrl: `${normalizedOrigin}/cn/share/callback`,
380
+ relayWsUrl: `${wsOrigin}/api/v1/remote/ws2`,
266
381
  zcodePlanOpenAiBaseUrl: `${normalizedOrigin}/api/v1/zcode-plan`,
267
382
  zcodePlanAnthropicBaseUrl: `${normalizedOrigin}/api/v1/zcode-plan/anthropic`,
268
383
  zcodePlanBillingCurrentUrl: `${normalizedOrigin}/api/v1/zcode-plan/billing/current`,