@ai-workbench/remote-agent 0.9.0-toolbridge.2 → 0.9.0-toolbridge.3

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 CHANGED
@@ -1,14 +1,14 @@
1
- # AI Workbench 远程助手 · @ai-workbench/remote-agent@0.9.0-toolbridge.2 · 插件 → 添加插件
1
+ # AI Workbench 远程助手 · @ai-workbench/remote-agent@0.9.0-toolbridge.3 · 插件 → 添加插件
2
2
 
3
3
  ## 含工具桥预发布线
4
4
 
5
- 本包为 `0.9.0-toolbridge.2`,在独立 `toolbridge` 分支开发;稳定 main/0.8.x 和原总包保持原样。员工安装由连接组件提供的「AI 写作工作台(含工具桥)」总包,与不含工具桥的版本二选一。预发布渠道为 `toolbridge`,本轮仅提供本地固定包,不发布 npm。
5
+ 本包为 `0.9.0-toolbridge.3`,在独立 `toolbridge` 分支开发;稳定 main/0.8.x 和原总包保持原样。员工安装由连接组件提供的「AI 写作工作台(含工具桥)」总包,与不含工具桥的版本二选一。预发布渠道为 `toolbridge`,本轮仅提供本地固定包,不发布 npm。
6
6
 
7
7
  选择本机文件夹后,Claude 和 Codex 可以把 DSH 已启用的 MCP、web、skill、ask_user、todo/present/goal 等工具交给 DSH 原生执行和审批。内置文件/命令、子代理/agent-team、run_code 不在桥接表;原有文件和命令执行方式保留。plan 不自动放行桥接权限;default 下 Claude 的桥接原生权限由插件单次应答,员工只在 DSH 审批实际工具。主机文件夹不开放工具桥。
8
8
 
9
9
  工具表按每次主机连接生成快照,新增/移除在下一次连接生效;不承诺 Codex 当前 MCP 会话热刷新。审批期间的插话等当前主机 prompt 结束后再发,停泊中切换助手会停止原轮次并明确提示。工具主动结束DSH轮次时,已提交结果仍交回原agent;确认原生工具收到后结束原prompt,下一条沿原线程继续,不在已关闭步骤追加模型回复。取消和主机结束等待后的结果不重放;工具已执行的副作用不能因取消而撤销,请按说明核对。图片结果由官方附件组件读取后交回。
10
10
 
11
- Codex 需要 S 后续安装的独立受保护命令 `/usr/local/aw-host/bin/codex-acp-toolbridge`(aw.7),不会替换原 codex-acp/aw.6;Claude命令不变。指定桥接 server 的等待为 owner 确认的 **1800 秒**、审批交 DSH;不改其他 server 或全局策略,不新增设置项。N0.4.9、L0.7.37沿既有公开合同;真实界面/员工验收由编排安排。完整合同和证据见 `docs/contracts/codex-toolbridge.md`、`docs/evidence/2026-10-26-toolbridge/REPORT.md`。
11
+ Codex 需要 S 后续安装的独立受保护命令 `/usr/local/aw-host/bin/codex-acp-toolbridge`(aw.8),不会替换原 codex-acp/aw.6;Claude命令不变。指定桥接 server 的等待为 owner 确认的 **1800 秒**、审批交 DSH;不改其他server的调用时限,不新增插件设置项。含桥的本机Codex会话按原生规则等各扩展现有启动时限结算后再捕获工具;启动失败会明确说明,文件和命令仍按原方式执行,本轮不自动重试。N0.4.9、L0.7.37沿既有公开合同;真实界面/员工验收由编排安排。完整合同和本轮启动修复证据见 `docs/contracts/codex-toolbridge.md`、`docs/evidence/2026-10-27-toolbridge-startup/REPORT.md`。
12
12
 
13
13
  通过官方 DSH 插件入口使用 Claude(远程主机)与 Codex(远程主机)。登录和工作区来源由“远程主机连接”组件提供;员工在原生工作区和模型菜单中选择文件夹与型号。
14
14
 
package/dist/acp.d.ts CHANGED
@@ -96,6 +96,12 @@ export declare class AcpSession {
96
96
  private detail;
97
97
  private employeeNoticeNames;
98
98
  private employeeNoticeUnshown;
99
+ private employeeBridge;
100
+ private pendingBridgeStartupFailures;
101
+ private bridgeStartupFailed;
102
+ private bridgeStartupNoticeDelivered;
103
+ private confirmBridgeStartupFailure;
104
+ private flushBridgeStartupNotice;
99
105
  private employeeInfo;
100
106
  private need;
101
107
  constructor(transport: acp.Stream | acp.AgentApp | stable.AgentApp, hooks: AcpHooks);
package/dist/acp.js CHANGED
@@ -226,6 +226,27 @@ export class AcpSession {
226
226
  }
227
227
  employeeNoticeNames = new Set();
228
228
  employeeNoticeUnshown = false;
229
+ employeeBridge = false;
230
+ pendingBridgeStartupFailures = new Set();
231
+ bridgeStartupFailed = false;
232
+ bridgeStartupNoticeDelivered = false;
233
+ confirmBridgeStartupFailure() {
234
+ if (!this.sessionId)
235
+ return;
236
+ const failed = this.pendingBridgeStartupFailures.has(this.sessionId);
237
+ this.pendingBridgeStartupFailures.clear();
238
+ if (failed && !this.bridgeStartupFailed) {
239
+ this.bridgeStartupFailed = true;
240
+ this.detail({ kind: 'extension', severity: 'warning', code: 'TOOLBRIDGE_STARTUP_FAILED', summary: '本轮DSH扩展工具桥启动失败;文件和命令继续使用原生路径,没有自动重试。', method: 'session/update', payload: { server: 'employee', status: 'failed', source: 'codex-acp/mcp-startup-report', nativeSessionId: this.sessionId } });
241
+ }
242
+ this.flushBridgeStartupNotice();
243
+ }
244
+ flushBridgeStartupNotice() {
245
+ if (!this.bridgeStartupFailed || this.bridgeStartupNoticeDelivered || !this.busy || this.closeRequested || this.turnSignal?.aborted || !this.hooks.onEmployeeNotice)
246
+ return;
247
+ this.hooks.onEmployeeNotice('本轮DSH里的扩展工具未能连接到Codex,暂时不可用。文件和命令仍按原方式执行;具体原因见技术详情。本轮不会自动重试。');
248
+ this.bridgeStartupNoticeDelivered = true;
249
+ }
229
250
  employeeInfo(value) {
230
251
  const bridge = record(record(value)?.mcpBridge);
231
252
  if (bridge)
@@ -263,6 +284,11 @@ export class AcpSession {
263
284
  this.detail({ kind: 'session', severity: 'warning', code: 'ACP_FOREIGN_SESSION_UPDATE', summary: '收到不属于当前远端会话的通知,未作为正文处理', method: 'session/update', payload: notification });
264
285
  return;
265
286
  }
287
+ const update = notification.update;
288
+ if (this.employeeBridge && !this.closeRequested && (update.sessionUpdate === 'tool_call' || update.sessionUpdate === 'tool_call_update') && update.status === 'failed' && update.title === 'mcp__employee__startup' && update.toolCallId.startsWith('mcp_startup.employee.') && update.toolCallId.length > 'mcp_startup.employee.'.length) {
289
+ this.pendingBridgeStartupFailures.add(notification.sessionId);
290
+ this.confirmBridgeStartupFailure();
291
+ }
266
292
  const meta = record(notification._meta);
267
293
  if (notification.update.sessionUpdate === 'current_mode_update') {
268
294
  this.nativeModeId = notification.update.currentModeId;
@@ -482,12 +508,13 @@ export class AcpSession {
482
508
  throw new NeedError('SESSION_ALREADY_STARTED', '此连接已用于建立会话,不能转用工作区或身份', '新的独立远端连接');
483
509
  this.startAttempted = true;
484
510
  this.employeeMeta = context?.employeeExecution;
511
+ this.employeeBridge = !!this.employeeMeta && !!context?.toolBridgeServers;
485
512
  const abort = () => this.close({ layer: 'acp', initiator: 'acp.start-signal', reason: 'ABORTED', action: 'abort' }, new NeedError('ABORTED', '会话建立已取消', '重新连接主机'));
486
513
  signal?.throwIfAborted();
487
514
  signal?.addEventListener('abort', abort, { once: true });
488
515
  try {
489
516
  const hello = await this.stage('acp-initialize', () => this.connection.agent.request(acp.methods.agent.initialize, {
490
- protocolVersion: acp.PROTOCOL_VERSION, clientInfo: { name: '@ai-workbench/remote-agent', version: '0.9.0-toolbridge.2' },
517
+ protocolVersion: acp.PROTOCOL_VERSION, clientInfo: { name: '@ai-workbench/remote-agent', version: '0.9.0-toolbridge.3' },
491
518
  clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false, session: { notices: {} }, ...(this.employeeMeta ? { _meta: { awEmployeeExecution: { version: 1, closeReason: 1, ...(context?.toolBridgeServers ? { mcpBridge: 1 } : {}) } } } : {}) },
492
519
  }, { cancellationSignal: signal }));
493
520
  if (hello.protocolVersion !== acp.PROTOCOL_VERSION)
@@ -555,6 +582,7 @@ export class AcpSession {
555
582
  this.lifecycleConfiguration(result, configRevision);
556
583
  this.method = acp.methods.agent.session.new;
557
584
  }
585
+ this.confirmBridgeStartupFailure();
558
586
  await this.hooks.sessionOwnership?.bind(this.sessionId, signal);
559
587
  this.ready = true;
560
588
  this.cwd = cwd;
@@ -606,6 +634,7 @@ export class AcpSession {
606
634
  };
607
635
  signal?.addEventListener('abort', cancel, { once: true });
608
636
  try {
637
+ this.flushBridgeStartupNotice();
609
638
  const result = await this.stage('acp-prompt', () => {
610
639
  this.promptPermissions.set(params, { current, native });
611
640
  const request = this.connection.agent.request(acp.methods.agent.session.prompt, params, { cancellationSignal: signal });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-workbench/remote-agent",
3
- "version": "0.9.0-toolbridge.2",
3
+ "version": "0.9.0-toolbridge.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",