aws-runtime-bridge 1.8.6 → 1.8.8

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 (42) hide show
  1. package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -1
  2. package/dist/adapter/AcodeSdkAdapter.js +98 -6
  3. package/dist/adapter/AcodeSdkAdapter.test.js +313 -2
  4. package/dist/adapter/OpencodeSdkAdapter.js +1 -1
  5. package/dist/adapter/types.d.ts.map +1 -1
  6. package/dist/adapter/types.js +7 -3
  7. package/dist/config.d.ts +2 -3
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +9 -10
  10. package/dist/config.test.js +1 -22
  11. package/dist/routes/ai-sources.js +5 -1
  12. package/dist/routes/ai-sources.test.js +21 -0
  13. package/dist/routes/instance.test.js +1 -70
  14. package/dist/routes/runtime-binding.d.ts.map +1 -1
  15. package/dist/routes/runtime-binding.js +36 -1
  16. package/dist/routes/terminal.d.ts +3 -0
  17. package/dist/routes/terminal.d.ts.map +1 -1
  18. package/dist/routes/terminal.js +141 -6
  19. package/dist/routes/terminal.test.js +118 -1
  20. package/dist/services/mcp-launch-binding-queue.d.ts +7 -0
  21. package/dist/services/mcp-launch-binding-queue.d.ts.map +1 -1
  22. package/dist/services/mcp-launch-binding-queue.js +25 -0
  23. package/dist/services/session-output.d.ts +8 -3
  24. package/dist/services/session-output.d.ts.map +1 -1
  25. package/dist/services/session-output.js +35 -14
  26. package/dist/services/session-output.test.js +41 -0
  27. package/package/acode/dist/runtime.d.ts +1 -0
  28. package/package/acode/dist/runtime.d.ts.map +1 -1
  29. package/package/acode/dist/runtime.js +265 -31
  30. package/package/acode/dist/types.d.ts +1 -1
  31. package/package/acode/dist/types.d.ts.map +1 -1
  32. package/package/aws-client-agent-mcp/dist/config.d.ts +4 -0
  33. package/package/aws-client-agent-mcp/dist/config.d.ts.map +1 -1
  34. package/package/aws-client-agent-mcp/dist/config.js +15 -0
  35. package/package/aws-client-agent-mcp/dist/config.js.map +1 -1
  36. package/package/aws-client-agent-mcp/dist/http-client.d.ts +10 -0
  37. package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +1 -1
  38. package/package/aws-client-agent-mcp/dist/http-client.js +79 -1
  39. package/package/aws-client-agent-mcp/dist/http-client.js.map +1 -1
  40. package/package/aws-client-agent-mcp/dist/http-client.test.js +129 -265
  41. package/package/aws-client-agent-mcp/dist/http-client.test.js.map +1 -1
  42. package/package.json +1 -1
package/dist/config.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  export declare const port: number;
8
8
  /** 默认调度器基础 URL */
9
9
  export declare const DEFAULT_SCHEDULER_BASE_URL = "http://localhost:8080";
10
- export type SchedulerBaseUrlSource = "env" | "single-auto-register-target" | "request" | "default" | "ambiguous-auto-register-targets";
10
+ export type SchedulerBaseUrlSource = "request" | "env" | "single-auto-register-target" | "default" | "ambiguous-auto-register-targets";
11
11
  export interface SchedulerBaseUrlResolution {
12
12
  url: string;
13
13
  source: SchedulerBaseUrlSource;
@@ -20,8 +20,7 @@ export interface SchedulerBaseUrlResolution {
20
20
  export declare function resolveSchedulerBaseUrl(): SchedulerBaseUrlResolution;
21
21
  /**
22
22
  * 解析调度中心基础 URL。
23
- * 主流程:bridge 本机显式配置优先;未配置时,单个自动注册目标可作为宿主机部署的零额外配置回退;
24
- * 服务端请求携带的 scheduler 地址仅作为本机无配置时的兜底,避免 Docker 容器内地址覆盖机器实例配置。
23
+ * 主流程:服务端请求携带的 scheduler 地址优先;再读显式环境变量;最后回退到单个自动注册目标或默认值。
25
24
  */
26
25
  export declare function resolveSchedulerBaseUrlFrom(requestSchedulerBaseUrl: unknown): SchedulerBaseUrlResolution;
27
26
  /** 调度器基础 URL(兼容旧导入;请求处理应优先调用 resolveSchedulerBaseUrl 获取最新值) */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -80,10 +80,17 @@ export function resolveSchedulerBaseUrl() {
80
80
  }
81
81
  /**
82
82
  * 解析调度中心基础 URL。
83
- * 主流程:bridge 本机显式配置优先;未配置时,单个自动注册目标可作为宿主机部署的零额外配置回退;
84
- * 服务端请求携带的 scheduler 地址仅作为本机无配置时的兜底,避免 Docker 容器内地址覆盖机器实例配置。
83
+ * 主流程:服务端请求携带的 scheduler 地址优先;再读显式环境变量;最后回退到单个自动注册目标或默认值。
85
84
  */
86
85
  export function resolveSchedulerBaseUrlFrom(requestSchedulerBaseUrl) {
86
+ const normalizedRequestSchedulerBaseUrl = normalizeSchedulerHttpBaseUrl(requestSchedulerBaseUrl);
87
+ if (normalizedRequestSchedulerBaseUrl) {
88
+ return {
89
+ url: normalizedRequestSchedulerBaseUrl,
90
+ source: "request",
91
+ ambiguousTargetUrls: [],
92
+ };
93
+ }
87
94
  const envSchedulerBaseUrl = normalizeSchedulerHttpBaseUrl(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL);
88
95
  if (envSchedulerBaseUrl) {
89
96
  return {
@@ -100,14 +107,6 @@ export function resolveSchedulerBaseUrlFrom(requestSchedulerBaseUrl) {
100
107
  ambiguousTargetUrls: [],
101
108
  };
102
109
  }
103
- const normalizedRequestSchedulerBaseUrl = normalizeSchedulerHttpBaseUrl(requestSchedulerBaseUrl);
104
- if (normalizedRequestSchedulerBaseUrl) {
105
- return {
106
- url: normalizedRequestSchedulerBaseUrl,
107
- source: "request",
108
- ambiguousTargetUrls: [],
109
- };
110
- }
111
110
  if (autoRegisterTargetUrls.length > 1) {
112
111
  return {
113
112
  url: DEFAULT_SCHEDULER_BASE_URL,
@@ -42,33 +42,12 @@ afterEach(() => {
42
42
  }
43
43
  });
44
44
  describe("scheduler base URL resolution", () => {
45
- it("keeps explicit AWS_RUNTIME_SCHEDULER_BASE_URL before the server request URL", async () => {
45
+ it("keeps scheduler URL supplied by the server request as the highest priority", async () => {
46
46
  const runtimeHome = createRuntimeHome();
47
47
  useRuntimeHome(runtimeHome);
48
48
  process.env.AWS_RUNTIME_SCHEDULER_BASE_URL = "http://env.local:7380";
49
49
  writeBridgeConfig(runtimeHome, [{ serverUrl: "http://target.local:7380" }]);
50
50
  const { resolveSchedulerBaseUrlFrom } = await import("./config.js");
51
- expect(resolveSchedulerBaseUrlFrom("http://server.local:7380/api")).toEqual({
52
- url: "http://env.local:7380",
53
- source: "env",
54
- ambiguousTargetUrls: [],
55
- });
56
- });
57
- it("keeps a single auto-register target before the server request URL", async () => {
58
- const runtimeHome = createRuntimeHome();
59
- useRuntimeHome(runtimeHome);
60
- writeBridgeConfig(runtimeHome, [{ serverUrl: "http://target.local:7380/api" }]);
61
- const { resolveSchedulerBaseUrlFrom } = await import("./config.js");
62
- expect(resolveSchedulerBaseUrlFrom("http://server.local:7380/api")).toEqual({
63
- url: "http://target.local:7380",
64
- source: "single-auto-register-target",
65
- ambiguousTargetUrls: [],
66
- });
67
- });
68
- it("uses scheduler URL supplied by the server request when local bridge config is absent", async () => {
69
- const runtimeHome = createRuntimeHome();
70
- useRuntimeHome(runtimeHome);
71
- const { resolveSchedulerBaseUrlFrom } = await import("./config.js");
72
51
  expect(resolveSchedulerBaseUrlFrom("http://server.local:7380/api")).toEqual({
73
52
  url: "http://server.local:7380",
74
53
  source: "request",
@@ -59,7 +59,7 @@ async function fetchRemoteModelList(baseUrl, apiKey) {
59
59
  return normalizeListedModels(anthropicResponse.data);
60
60
  }
61
61
  aiSourcesRouter.post('/cc-switch/apply-ai-sources', validateToken, async (req, res) => {
62
- const { agentId, template, ccSwitchEnabledTools, acodeTemplateId, claudecodeTemplateId, codexTemplateId, opencodeTemplateId, acode, claudecode, codex, opencode, } = req.body || {};
62
+ const { agentId, template, ccSwitchEnabledTools, acodeTemplateId, claudecodeTemplateId, codexTemplateId, opencodeTemplateId, acodeModelEffort, claudecodeModelEffort, codexModelEffort, opencodeModelEffort, acode, claudecode, codex, opencode, } = req.body || {};
63
63
  if (!agentId) {
64
64
  res.status(400).json({ error: 'agentId is required' });
65
65
  return;
@@ -81,6 +81,10 @@ aiSourcesRouter.post('/cc-switch/apply-ai-sources', validateToken, async (req, r
81
81
  claudecodeTemplateId: String(claudecodeTemplateId || ''),
82
82
  codexTemplateId: String(codexTemplateId || ''),
83
83
  opencodeTemplateId: String(opencodeTemplateId || ''),
84
+ acodeModelEffort: String(acodeModelEffort || ''),
85
+ claudecodeModelEffort: String(claudecodeModelEffort || ''),
86
+ codexModelEffort: String(codexModelEffort || ''),
87
+ opencodeModelEffort: String(opencodeModelEffort || ''),
84
88
  generatedFromUnifiedTemplate: appliedSummary.generatedFromUnifiedTemplate,
85
89
  applied: appliedSummary.applied,
86
90
  skippedTools: appliedSummary.skippedTools,
@@ -76,6 +76,14 @@ function buildModelListCandidates(baseUrl, protocol) {
76
76
  : [`${normalizedBaseUrl}/models`, `${normalizedBaseUrl}/v1/models`];
77
77
  return [...openAiCandidates, `${normalizedBaseUrl}/v1/models`];
78
78
  }
79
+ function buildApplyAiSourcesResponse(body) {
80
+ return {
81
+ acodeModelEffort: String(body.acodeModelEffort || ''),
82
+ claudecodeModelEffort: String(body.claudecodeModelEffort || ''),
83
+ codexModelEffort: String(body.codexModelEffort || ''),
84
+ opencodeModelEffort: String(body.opencodeModelEffort || ''),
85
+ };
86
+ }
79
87
  describe('ai source unified config generation', () => {
80
88
  it('builds tool-specific configs from unified template fields', () => {
81
89
  assert.deepEqual(buildUnifiedToolConfig({
@@ -145,4 +153,17 @@ describe('ai source unified config generation', () => {
145
153
  model: 'gpt-test',
146
154
  }).opencode.provider.default.options.baseURL).toBe('https://octopus.721579.xyz/v1');
147
155
  });
156
+ it('echoes selected model effort metadata in apply-ai-sources responses', () => {
157
+ expect(buildApplyAiSourcesResponse({
158
+ acodeModelEffort: 'xhigh',
159
+ claudecodeModelEffort: 'high',
160
+ codexModelEffort: 'max',
161
+ opencodeModelEffort: 'high',
162
+ })).toEqual({
163
+ acodeModelEffort: 'xhigh',
164
+ claudecodeModelEffort: 'high',
165
+ codexModelEffort: 'max',
166
+ opencodeModelEffort: 'high',
167
+ });
168
+ });
148
169
  });
@@ -40,8 +40,6 @@ vi.mock('node:child_process', async (importOriginal) => ({
40
40
  afterEach(() => {
41
41
  vi.useRealTimers();
42
42
  vi.clearAllMocks();
43
- delete process.env.AWS_RUNTIME_SCHEDULER_BASE_URL;
44
- delete process.env.AWS_TEST_HOME;
45
43
  });
46
44
  function mockSpawnResult(exitCode, stdoutText = '', stderrText = '') {
47
45
  spawnMock.mockImplementationOnce(() => {
@@ -295,7 +293,7 @@ describe('instance route validation', () => {
295
293
  });
296
294
  expect(status).not.toHaveBeenCalled();
297
295
  });
298
- it('keeps explicit local scheduler config before server ping request header', async () => {
296
+ it('uses scheduler base URL supplied by server ping request before local bridge config', async () => {
299
297
  process.env.AWS_RUNTIME_SCHEDULER_BASE_URL = 'http://localhost:8080';
300
298
  const { default: axios } = await import('axios');
301
299
  const { getRuntimeAccessToken } = await import('../services/runtime-binding.js');
@@ -309,34 +307,6 @@ describe('instance route validation', () => {
309
307
  const status = vi.fn(() => ({ json }));
310
308
  const header = vi.fn((name) => (name === 'X-Scheduler-Base-Url' ? 'http://server.local:7380/api' : ''));
311
309
  await handler?.({ header }, { json, status }, vi.fn());
312
- expect(getRuntimeAccessToken).toHaveBeenCalledWith(undefined, 'http://localhost:8080');
313
- expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/api/runtime/ping', {
314
- headers: { 'X-Runtime-Token': 'stale-runtime-token-123456' },
315
- });
316
- expect(json).toHaveBeenCalledWith({
317
- ok: true,
318
- runtimeBridge: 'healthy',
319
- schedulerReachable: true,
320
- tokenRefreshed: false,
321
- schedulerBaseUrl: 'http://localhost:8080',
322
- });
323
- expect(status).not.toHaveBeenCalled();
324
- });
325
- it('uses scheduler base URL supplied by server ping request when bridge has no local scheduler config', async () => {
326
- delete process.env.AWS_RUNTIME_SCHEDULER_BASE_URL;
327
- process.env.AWS_TEST_HOME = `${process.cwd()}/.vitest-empty-bridge-home`;
328
- const { default: axios } = await import('axios');
329
- const { getRuntimeAccessToken } = await import('../services/runtime-binding.js');
330
- const { instanceRouter } = await import('./instance.js');
331
- vi.mocked(getRuntimeAccessToken).mockReturnValue('stale-runtime-token-123456');
332
- vi.mocked(axios.get).mockReset();
333
- vi.mocked(axios.get).mockResolvedValueOnce({ status: 200 });
334
- const handler = instanceRouter.stack.find((layer) => layer.route?.path === '/ping')?.route?.stack[1]?.handle;
335
- expect(handler).toBeTypeOf('function');
336
- const json = vi.fn();
337
- const status = vi.fn(() => ({ json }));
338
- const header = vi.fn((name) => (name === 'X-Scheduler-Base-Url' ? 'http://server.local:7380/api' : ''));
339
- await handler?.({ header }, { json, status }, vi.fn());
340
310
  expect(getRuntimeAccessToken).toHaveBeenCalledWith(undefined, 'http://server.local:7380');
341
311
  expect(axios.get).toHaveBeenCalledWith('http://server.local:7380/api/runtime/ping', {
342
312
  headers: { 'X-Runtime-Token': 'stale-runtime-token-123456' },
@@ -350,45 +320,6 @@ describe('instance route validation', () => {
350
320
  });
351
321
  expect(status).not.toHaveBeenCalled();
352
322
  });
353
- it('keeps single auto-register scheduler config before server ping request header', async () => {
354
- delete process.env.AWS_RUNTIME_SCHEDULER_BASE_URL;
355
- const fs = await import('node:fs');
356
- const path = await import('node:path');
357
- const testHome = path.join(process.cwd(), '.vitest-single-target-bridge-home');
358
- const configDir = path.join(testHome, '.aws-bridge');
359
- fs.rmSync(testHome, { recursive: true, force: true });
360
- fs.mkdirSync(configDir, { recursive: true });
361
- fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify({
362
- autoRegisterTargets: [
363
- { serverUrl: 'http://bridge-config.local:7380/api' },
364
- ],
365
- }), 'utf-8');
366
- process.env.AWS_TEST_HOME = testHome;
367
- const { default: axios } = await import('axios');
368
- const { getRuntimeAccessToken } = await import('../services/runtime-binding.js');
369
- const { instanceRouter } = await import('./instance.js');
370
- vi.mocked(getRuntimeAccessToken).mockReturnValue('stale-runtime-token-123456');
371
- vi.mocked(axios.get).mockReset();
372
- vi.mocked(axios.get).mockResolvedValueOnce({ status: 200 });
373
- const handler = instanceRouter.stack.find((layer) => layer.route?.path === '/ping')?.route?.stack[1]?.handle;
374
- expect(handler).toBeTypeOf('function');
375
- const json = vi.fn();
376
- const status = vi.fn(() => ({ json }));
377
- const header = vi.fn((name) => (name === 'X-Scheduler-Base-Url' ? 'http://server.local:7380/api' : ''));
378
- await handler?.({ header }, { json, status }, vi.fn());
379
- expect(getRuntimeAccessToken).toHaveBeenCalledWith(undefined, 'http://bridge-config.local:7380');
380
- expect(axios.get).toHaveBeenCalledWith('http://bridge-config.local:7380/api/runtime/ping', {
381
- headers: { 'X-Runtime-Token': 'stale-runtime-token-123456' },
382
- });
383
- expect(json).toHaveBeenCalledWith({
384
- ok: true,
385
- runtimeBridge: 'healthy',
386
- schedulerReachable: true,
387
- tokenRefreshed: false,
388
- schedulerBaseUrl: 'http://bridge-config.local:7380',
389
- });
390
- expect(status).not.toHaveBeenCalled();
391
- });
392
323
  it('explains ambiguous auto-register scheduler targets without picking the first one', async () => {
393
324
  const { buildAmbiguousSchedulerBaseUrlResponse } = await import('./instance.js');
394
325
  const response = buildAmbiguousSchedulerBaseUrlResponse([
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-binding.d.ts","sourceRoot":"","sources":["../../src/routes/runtime-binding.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,oBAAoB,4CAAW,CAAC;AAE7C,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,wBAAwB,GAC9B,yBAAyB,CAM3B;AAqMD,wBAAgB,6BAA6B,IAAI,IAAI,CAapD"}
1
+ {"version":3,"file":"runtime-binding.d.ts","sourceRoot":"","sources":["../../src/routes/runtime-binding.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,oBAAoB,4CAAW,CAAC;AAE7C,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,wBAAwB,GAC9B,yBAAyB,CAM3B;AAgPD,wBAAgB,6BAA6B,IAAI,IAAI,CAapD"}
@@ -1,6 +1,6 @@
1
1
  import { Router } from "express";
2
2
  import { validateToken } from "../middleware/auth.js";
3
- import { claimMcpLaunchBinding, getMcpLaunchQueueSize } from "../services/mcp-launch-binding-queue.js";
3
+ import { claimMcpLaunchBinding, getLatestAgentToken, getMcpLaunchQueueSize } from "../services/mcp-launch-binding-queue.js";
4
4
  import { clearRuntimeBinding, getRuntimeAccessToken, getRuntimeBindingPublicState, getRuntimePairingCode, hasRuntimeBinding, saveRuntimeBinding, validateRuntimeBindingToken, validateRuntimePairingCode, } from "../services/runtime-binding.js";
5
5
  import { createLogger } from "../utils/logger.js";
6
6
  const log = createLogger("runtime-binding-route");
@@ -133,6 +133,41 @@ runtimeBindingRouter.post("/binding/claim-agent", (req, res) => {
133
133
  remainingQueueSize: getMcpLaunchQueueSize(workspacePath),
134
134
  });
135
135
  });
136
+ /**
137
+ * MCP node 在 401 后向 bridge 查询最新 session token 的端点。
138
+ * 仅接受本地回环请求,仅返回缓存中最新的 token。
139
+ */
140
+ runtimeBindingRouter.post("/binding/refresh-token", (req, res) => {
141
+ if (!isLoopbackRequest(req)) {
142
+ res.status(403).json({ ok: false, error: "loopback request required" });
143
+ return;
144
+ }
145
+ const { agentId, currentToken } = req.body || {};
146
+ const normalizedAgentId = String(agentId || "").trim();
147
+ if (!normalizedAgentId) {
148
+ res.status(400).json({ ok: false, error: "agentId is required" });
149
+ return;
150
+ }
151
+ const latest = getLatestAgentToken(normalizedAgentId);
152
+ if (!latest) {
153
+ res.status(404).json({ ok: false, error: "no cached token for agent" });
154
+ return;
155
+ }
156
+ // 如果最新 token 与当前 token 相同,说明服务端已撤销,bridge 侧没有更新的
157
+ const normalizedCurrent = String(currentToken || "").trim();
158
+ if (normalizedCurrent && latest.runtimeAccessToken === normalizedCurrent) {
159
+ res.status(409).json({
160
+ ok: false,
161
+ error: "token_unchanged",
162
+ message: "Bridge cached token is the same as current; token may be revoked server-side",
163
+ });
164
+ return;
165
+ }
166
+ res.json({
167
+ ok: true,
168
+ runtimeAccessToken: latest.runtimeAccessToken,
169
+ });
170
+ });
136
171
  runtimeBindingRouter.post("/binding/issue", validateToken, (req, res) => {
137
172
  const { accessToken, instanceId, userId, schedulerBaseUrl } = req.body || {};
138
173
  const nextToken = String(accessToken || "").trim();
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import { TextDecoder } from "node:util";
8
8
  import { type AdapterSessionConfig, type ProviderEvent, type RuntimeStatusActionInfo } from "../adapter/index.js";
9
+ import { type RuntimeOutputMetadata } from "../services/session-output.js";
9
10
  import type { PersistedSession } from "../types.js";
10
11
  export declare const terminalRouter: import("express-serve-static-core").Router;
11
12
  export interface SdkSessionEntry {
@@ -16,6 +17,7 @@ export interface SdkSessionEntry {
16
17
  providerId: string;
17
18
  seq: number;
18
19
  runtimeAccessToken?: string;
20
+ schedulerBaseUrl?: string;
19
21
  currentRuntimeStatus?: string;
20
22
  currentRuntimeActionType?: string;
21
23
  currentRuntimeActionLabel?: string;
@@ -91,6 +93,7 @@ export declare function buildClaudeCodeLaunchConfig(savedClaudeConfig: {
91
93
  */
92
94
  export declare function buildToolResultTimelineActionInfo(event: ProviderEvent): RuntimeStatusActionInfo | undefined;
93
95
  export declare function formatSdkOutputEvent(event: ProviderEvent): string | undefined;
96
+ export declare function buildSdkOutputMetadata(event: ProviderEvent): RuntimeOutputMetadata;
94
97
  /**
95
98
  * 主干流程:把 provider 事件转换为面板运行状态。
96
99
  *
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/routes/terminal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAKxC,OAAO,EAOL,KAAK,oBAAoB,EAEzB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAE7B,MAAM,qBAAqB,CAAC;AAsB7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,eAAO,MAAM,cAAc,4CAAW,CAAC;AAIvC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAGD,eAAO,MAAM,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAa,CAAC;AAMnE,wBAAgB,wBAAwB,CAAC,UAAU,CAAC,EAAE,uBAAuB;;;cAa5E;AA0BD,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,GAAG,OAAa,GACf,MAAM,CAoBR;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAW/D;AAED,wBAAgB,kCAAkC,CAChD,UAAU,EAAE,MAAM,EAClB,SAAS,SAA+C,GACvD,MAAM,CAER;AAED,wBAAgB,oCAAoC,CAClD,SAAS,SAAyC,GACjD,MAAM,CAIR;AAcD;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIpE;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,SAAkC,GACzC,WAAW,CAMb;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,WAAW,EACpB,KAAK,CAAC,EAAE,MAAM,EACd,GAAG,UAAQ,GACV,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,GAAG,SAAS,CAmB3B;AAmDD;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,aAAa,CAAC,EAAE,MAAM,EACtB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,MAAM,CAOR;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,YAAY,GAAG,aAAa,GAAG,UAAU,GAAG,qBAAqB,CAAC;CAC3E;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,EAC5C,YAAY,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAA0B,GACxD,6BAA6B,CAc/B;AA2BD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAErE;AAmOD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,OAAO,EAAE,MAAM,CAAC,UAAU,EAC1B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACrC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA+BxB;AAYD;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAY5E;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,iBAAiB,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EACvE,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5C,sBAAsB,CAyBxB;AAoDD;;;GAGG;AACH,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,aAAa,GACnB,uBAAuB,GAAG,SAAS,CAyCrC;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAwB7E;AAyBD;;;;;GAKG;AACH,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,aAAa,GACtE;IACE,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACtC,GACD,SAAS,CA4EZ;AAsBD,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7D"}
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/routes/terminal.ts"],"names":[],"mappings":"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"}
@@ -233,7 +233,10 @@ function appendCommandOutput(entry, output) {
233
233
  return;
234
234
  }
235
235
  entry.seq += 1;
236
- void sendOutput(entry.agentId, output, entry.sessionId, entry.seq);
236
+ void sendOutput(entry.agentId, output, entry.sessionId, entry.seq, undefined, {
237
+ runtimeAccessToken: entry.runtimeAccessToken,
238
+ schedulerBaseUrl: entry.schedulerBaseUrl,
239
+ });
237
240
  }
238
241
  /**
239
242
  * 生成显示在终端输出流中的工作目录提示符。
@@ -307,6 +310,9 @@ async function executeTerminalCommand(sessionId, commandValue) {
307
310
  actionType: "bash",
308
311
  actionLabel: "终端命令",
309
312
  actionDetail: displayCommand,
313
+ }, undefined, {
314
+ runtimeAccessToken: entry.runtimeAccessToken,
315
+ schedulerBaseUrl: entry.schedulerBaseUrl,
310
316
  });
311
317
  const child = spawn(command, {
312
318
  cwd: state.currentDirectory,
@@ -398,7 +404,10 @@ async function executeTerminalCommand(sessionId, commandValue) {
398
404
  appendCommandOutput(entry, `\r\n[signal ${signal}]\r\n`);
399
405
  }
400
406
  appendCommandOutput(entry, formatTerminalPrompt(state.currentDirectory));
401
- void sendStatus(entry.agentId, sessionId, "waiting_input");
407
+ void sendStatus(entry.agentId, sessionId, "waiting_input", undefined, undefined, {
408
+ runtimeAccessToken: entry.runtimeAccessToken,
409
+ schedulerBaseUrl: entry.schedulerBaseUrl,
410
+ });
402
411
  });
403
412
  return { started: true, cwd: state.currentDirectory };
404
413
  }
@@ -573,6 +582,115 @@ export function formatSdkOutputEvent(event) {
573
582
  }
574
583
  return undefined;
575
584
  }
585
+ export function buildSdkOutputMetadata(event) {
586
+ const logMessage = formatSdkLogMessage(event);
587
+ return {
588
+ sourceEventType: event.type,
589
+ logCategory: "acode",
590
+ ...(logMessage
591
+ ? {
592
+ logLevel: event.type === "error" ? "error" : "info",
593
+ logMessage,
594
+ }
595
+ : {}),
596
+ };
597
+ }
598
+ function formatSdkLogMessage(event) {
599
+ if (event.type === "ai_request") {
600
+ const model = event.data.model || "unknown-model";
601
+ const endpoint = event.data.endpoint ? ` @ ${event.data.endpoint}` : "";
602
+ const toolCount = typeof event.data.toolCount === "number"
603
+ ? `, tools=${event.data.toolCount}`
604
+ : "";
605
+ return `AI request started: ${model}${endpoint}${toolCount}`;
606
+ }
607
+ if (event.type === "tool_use_start") {
608
+ return formatSdkToolLogMessage(event, "开始");
609
+ }
610
+ if (event.type === "tool_use_end") {
611
+ return formatSdkToolLogMessage(event, "完成");
612
+ }
613
+ if (event.type === "turn_complete") {
614
+ const finishReason = event.data.finishReason
615
+ ? `, finish=${event.data.finishReason}`
616
+ : "";
617
+ return `Turn completed${finishReason}`;
618
+ }
619
+ if (event.type === "session_complete") {
620
+ return `Session completed: exitCode=${event.data.exitCode ?? 0}`;
621
+ }
622
+ if (event.type === "error") {
623
+ return event.data.text || "ACode runtime error";
624
+ }
625
+ return undefined;
626
+ }
627
+ function formatSdkToolLogMessage(event, phaseLabel) {
628
+ const actionInfo = getToolActionInfo(event.data.toolName, event.data.toolInput);
629
+ const actionLabel = event.data.actionLabel || actionInfo.actionLabel || "调用工具";
630
+ const detail = resolveSdkToolLogDetail(event, actionInfo);
631
+ return detail
632
+ ? `${phaseLabel}${actionLabel}: ${detail}`
633
+ : `${phaseLabel}${actionLabel}: ${event.data.actionDetail || event.data.toolName || "tool"}`;
634
+ }
635
+ function resolveSdkToolLogDetail(event, actionInfo) {
636
+ const input = event.data.toolInput;
637
+ if (actionInfo.actionType === "bash") {
638
+ return (getCommandDisplayDetail(input) ||
639
+ event.data.actionDetail ||
640
+ actionInfo.actionDetail);
641
+ }
642
+ if (actionInfo.actionType === "read_file" ||
643
+ actionInfo.actionType === "edit_file" ||
644
+ actionInfo.actionType === "write_file") {
645
+ return (getFileDisplayDetail(input) ||
646
+ event.data.actionDetail ||
647
+ actionInfo.actionDetail);
648
+ }
649
+ return event.data.actionDetail || actionInfo.actionDetail;
650
+ }
651
+ function getCommandDisplayDetail(input) {
652
+ const command = firstDisplayString(input?.command, input?.cmd);
653
+ if (command)
654
+ return command;
655
+ if (Array.isArray(input?.argv)) {
656
+ const argv = input.argv
657
+ .map((item) => String(item ?? "").trim())
658
+ .filter(Boolean)
659
+ .join(" ");
660
+ return argv ? redactTransientClipboardPastePaths(argv) : undefined;
661
+ }
662
+ return firstDisplayString(input?.args);
663
+ }
664
+ function getFileDisplayDetail(input) {
665
+ const paths = displayStringList(input?.paths);
666
+ if (paths.length > 0) {
667
+ return paths.length === 1
668
+ ? paths[0]
669
+ : `${paths.length}个文件: ${paths.join(", ")}`;
670
+ }
671
+ return firstDisplayString(input?.file_path, input?.filePath, input?.path, input?.target_file, input?.targetFile);
672
+ }
673
+ function firstDisplayString(...values) {
674
+ for (const value of values) {
675
+ if (typeof value === "string" && value.trim()) {
676
+ return redactTransientClipboardPastePaths(value.trim());
677
+ }
678
+ if (Array.isArray(value)) {
679
+ const first = displayStringList(value)[0];
680
+ if (first)
681
+ return first;
682
+ }
683
+ }
684
+ return undefined;
685
+ }
686
+ function displayStringList(value) {
687
+ if (!Array.isArray(value))
688
+ return [];
689
+ return value
690
+ .map((item) => (typeof item === "string" ? item.trim() : ""))
691
+ .filter(Boolean)
692
+ .map((item) => redactTransientClipboardPastePaths(item));
693
+ }
576
694
  function formatAiRequestDetail(data) {
577
695
  const lines = [
578
696
  data.model ? `模型: ${data.model}` : undefined,
@@ -617,6 +735,7 @@ export function resolveRuntimeStatusFromProviderEvent(event) {
617
735
  }
618
736
  if (event.type === "tool_use_start") {
619
737
  const inferredAction = getToolActionInfo(event.data.toolName, event.data.toolInput);
738
+ const actionDetail = resolveSdkToolLogDetail(event, inferredAction);
620
739
  if (event.data.actionType === "idle" ||
621
740
  inferredAction.actionType === "idle") {
622
741
  return {
@@ -624,7 +743,8 @@ export function resolveRuntimeStatusFromProviderEvent(event) {
624
743
  actionInfo: {
625
744
  actionType: event.data.actionType || inferredAction.actionType,
626
745
  actionLabel: event.data.actionLabel || inferredAction.actionLabel,
627
- actionDetail: event.data.actionDetail ||
746
+ actionDetail: actionDetail ||
747
+ event.data.actionDetail ||
628
748
  inferredAction.actionDetail ||
629
749
  event.data.toolName,
630
750
  actionId: event.data.actionId || event.data.toolUseId,
@@ -636,7 +756,8 @@ export function resolveRuntimeStatusFromProviderEvent(event) {
636
756
  actionInfo: {
637
757
  actionType: event.data.actionType || inferredAction.actionType,
638
758
  actionLabel: event.data.actionLabel || inferredAction.actionLabel,
639
- actionDetail: event.data.actionDetail ||
759
+ actionDetail: actionDetail ||
760
+ event.data.actionDetail ||
640
761
  inferredAction.actionDetail ||
641
762
  event.data.toolName,
642
763
  actionId: event.data.actionId || event.data.toolUseId,
@@ -670,7 +791,10 @@ function forwardSdkOutputEvent(event, entry) {
670
791
  return;
671
792
  }
672
793
  entry.seq += 1;
673
- void sendOutput(entry.agentId, output, event.sessionId, entry.seq, { sourceEventType: event.type }, { runtimeAccessToken: entry.runtimeAccessToken });
794
+ void sendOutput(entry.agentId, output, event.sessionId, entry.seq, buildSdkOutputMetadata(event), {
795
+ runtimeAccessToken: entry.runtimeAccessToken,
796
+ schedulerBaseUrl: entry.schedulerBaseUrl,
797
+ });
674
798
  }
675
799
  export function resolveSdkProviderId(command) {
676
800
  return resolveSdkProviderIdByCommand(command);
@@ -690,13 +814,17 @@ function wireSdkAdapterEvents(adapter, definition) {
690
814
  console.log(`[${definition.displayName} Adapter] Event: ${event.type} for session ${event.sessionId}`);
691
815
  const runtimeStatus = resolveRuntimeStatusFromProviderEvent(event);
692
816
  if (runtimeStatus) {
693
- void sendStatus(entry.agentId, event.sessionId, runtimeStatus.status, runtimeStatus.actionInfo, resolveStatusChangeUsage(runtimeStatus.actionInfo), { runtimeAccessToken: entry.runtimeAccessToken });
817
+ void sendStatus(entry.agentId, event.sessionId, runtimeStatus.status, runtimeStatus.actionInfo, resolveStatusChangeUsage(runtimeStatus.actionInfo), {
818
+ runtimeAccessToken: entry.runtimeAccessToken,
819
+ schedulerBaseUrl: entry.schedulerBaseUrl,
820
+ });
694
821
  }
695
822
  forwardSdkOutputEvent(event, entry);
696
823
  const toolResultActionInfo = buildToolResultTimelineActionInfo(event);
697
824
  if (toolResultActionInfo) {
698
825
  void sendStatus(entry.agentId, event.sessionId, "tool_result", toolResultActionInfo, undefined, {
699
826
  runtimeAccessToken: entry.runtimeAccessToken,
827
+ schedulerBaseUrl: entry.schedulerBaseUrl,
700
828
  });
701
829
  }
702
830
  }
@@ -717,6 +845,7 @@ function wireSdkAdapterEvents(adapter, definition) {
717
845
  });
718
846
  void sendStatus(entry.agentId, sessionId, status, actionInfo, resolveStatusChangeUsage(actionInfo), {
719
847
  runtimeAccessToken: entry.runtimeAccessToken,
848
+ schedulerBaseUrl: entry.schedulerBaseUrl,
720
849
  });
721
850
  }
722
851
  });
@@ -726,6 +855,7 @@ function wireSdkAdapterEvents(adapter, definition) {
726
855
  console.log(`[${definition.displayName} Adapter] AskUserQuestion for agent ${entry.agentId}`);
727
856
  void sendQuestionRequest(entry.agentId, data.sessionId, Array.isArray(data.questions) ? data.questions : [], {
728
857
  runtimeAccessToken: entry.runtimeAccessToken,
858
+ schedulerBaseUrl: entry.schedulerBaseUrl,
729
859
  });
730
860
  }
731
861
  });
@@ -772,6 +902,7 @@ async function startSdkSession(req, res) {
772
902
  let sessionId = null;
773
903
  const normalizedAgentId = String(agentId || "").trim();
774
904
  const runtimeAccessToken = String(req.body?.runtimeAccessToken || "").trim() || undefined;
905
+ const requestedSchedulerBaseUrl = String(req.body?.schedulerBaseUrl || "").trim() || undefined;
775
906
  try {
776
907
  ensureAdapterInitialized();
777
908
  if (!normalizedAgentId) {
@@ -847,6 +978,7 @@ async function startSdkSession(req, res) {
847
978
  providerId, // 记录使用的 provider
848
979
  seq: 0,
849
980
  runtimeAccessToken,
981
+ schedulerBaseUrl: requestedSchedulerBaseUrl,
850
982
  });
851
983
  // 启动 SDK 会话
852
984
  await adapter.startSession(sessionId, config);
@@ -1073,6 +1205,7 @@ terminalRouter.post("/sdk/stop", validateToken, async (req, res) => {
1073
1205
  await processManager.removeProcess(entry.agentId);
1074
1206
  await sendStatus(entry.agentId, null, "stopped", undefined, undefined, {
1075
1207
  runtimeAccessToken: entry.runtimeAccessToken,
1208
+ schedulerBaseUrl: entry.schedulerBaseUrl,
1076
1209
  });
1077
1210
  res.json({ ok: true, status: "stopped" });
1078
1211
  }
@@ -1264,6 +1397,7 @@ terminalRouter.post("/stop", validateToken, async (req, res) => {
1264
1397
  await processManager.removeProcess(agentId);
1265
1398
  await sendStatus(agentId, null, "stopped", undefined, undefined, {
1266
1399
  runtimeAccessToken: sdkEntry.runtimeAccessToken,
1400
+ schedulerBaseUrl: sdkEntry.schedulerBaseUrl,
1267
1401
  });
1268
1402
  res.json({ ok: true, status: "stopped", mode: "sdk" });
1269
1403
  }
@@ -1298,6 +1432,7 @@ terminalRouter.post("/stop-all", validateToken, async (_req, res) => {
1298
1432
  stoppedSdk.push(sessionId);
1299
1433
  await sendStatus(entry.agentId, null, "stopped", undefined, undefined, {
1300
1434
  runtimeAccessToken: entry.runtimeAccessToken,
1435
+ schedulerBaseUrl: entry.schedulerBaseUrl,
1301
1436
  });
1302
1437
  }
1303
1438
  catch (error) {