evolcore 0.0.35 → 0.0.37
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/CHANGELOG.md +42 -0
- package/README.md +6 -0
- package/bin/install-codex-managed-hooks.mjs +20 -3
- package/dist/agents/baseagent-availability.js +1 -1
- package/dist/agents/baseagent.js +88 -0
- package/dist/agents/claude-runner.js +59 -12
- package/dist/agents/codex/app-server-client.js +18 -1
- package/dist/agents/codex-runner.js +262 -21
- package/dist/agents/ecagent-runner.js +47 -11
- package/dist/agents/gemini-runner.js +36 -12
- package/dist/aun/aid/client.js +4 -3
- package/dist/aun/aid/control-aid.js +270 -8
- package/dist/aun/aid/identity.js +6 -3
- package/dist/aun/aid/ownership-operation.js +58 -0
- package/dist/aun/aid/store.js +1 -0
- package/dist/aun/group/fs-download.js +67 -2
- package/dist/aun/group/history.js +20 -5
- package/dist/aun/group/operations.js +8 -2
- package/dist/aun/menu/client.js +39 -2
- package/dist/aun/menu/transport.js +1 -1
- package/dist/aun/msg/history.js +43 -4
- package/dist/aun/msg/managed-operation.js +30 -53
- package/dist/aun/msg/p2p.js +51 -15
- package/dist/aun/outbox.js +4 -0
- package/dist/channels/aun.js +260 -73
- package/dist/channels/daemon.js +6 -4
- package/dist/channels/feishu.js +3 -0
- package/dist/cli/agent-command.js +161 -223
- package/dist/cli/agent-create.js +190 -223
- package/dist/cli/agent.js +3 -1
- package/dist/cli/aid-bind-command.js +53 -0
- package/dist/cli/aun-commands.js +384 -91
- package/dist/cli/bench.js +1 -1
- package/dist/cli/cli-argv.js +74 -0
- package/dist/cli/daemon-commands.js +105 -74
- package/dist/cli/diag.js +1 -1
- package/dist/cli/fs-command.js +18 -19
- package/dist/cli/getmeta-command.js +159 -6
- package/dist/cli/index.js +6 -12
- package/dist/cli/init-channel.js +8 -55
- package/dist/cli/init.js +125 -218
- package/dist/cli/queue-command.js +11 -8
- package/dist/cli/restart-monitor.js +177 -85
- package/dist/cli/session-command.js +1 -1
- package/dist/cli/stats.js +7 -5
- package/dist/cli/thread-command.js +103 -30
- package/dist/cli/trigger-command.js +1 -1
- package/dist/cli/watch-msg-diag.js +1 -0
- package/dist/config/access-policy.js +2 -2
- package/dist/config/boot-log.js +14 -11
- package/dist/config/config-field-policy.js +9 -1
- package/dist/config/config-manager.js +176 -90
- package/dist/config/config-operation-service.js +7 -14
- package/dist/config/contact-book-store.js +142 -26
- package/dist/config/contact-book.js +4 -2
- package/dist/config/lifecycle.js +1 -1
- package/dist/config/owner-config.js +96 -0
- package/dist/config/peer-role-resolver.js +12 -18
- package/dist/config/providers-config.js +382 -0
- package/dist/config/providers-import.js +74 -0
- package/dist/config/providers-management.js +328 -0
- package/dist/config/providers.js +22 -0
- package/dist/config/resolved-config-op.js +17 -14
- package/dist/config/snapshot.js +28 -16
- package/dist/config-store.js +18 -14
- package/dist/core/agent-ipc-registration.js +21 -63
- package/dist/core/agent-runtime.js +16 -5
- package/dist/core/auth/agent-delegation.js +199 -25
- package/dist/core/auth/auth-gateway.js +44 -2
- package/dist/core/auth/authorization-denial.js +1 -1
- package/dist/core/auth/debug-context.js +2 -1
- package/dist/core/auth/delegation-authorization.js +2 -2
- package/dist/core/auth/delegation-diagnostics.js +4 -1
- package/dist/core/auth/operation-authorizer.js +10 -1
- package/dist/core/auth/operation-catalog.js +19 -1
- package/dist/core/bootstrap-service.js +43 -20
- package/dist/core/channel-loader.js +0 -1
- package/dist/core/channel-runtime.js +30 -4
- package/dist/core/command/agent-control.js +196 -37
- package/dist/core/command/cli-intent-parser.js +60 -4
- package/dist/core/command/command-handler.js +212 -60
- package/dist/core/command/connect-menu.js +1 -0
- package/dist/core/command/diag-service.js +5 -4
- package/dist/core/command/file-search.js +368 -0
- package/dist/core/command/menu-catalog.js +2 -1
- package/dist/core/command/menu-handler.js +292 -107
- package/dist/core/command/menu-protocol.js +23 -0
- package/dist/core/command/role-menu.js +7 -19
- package/dist/core/command/skill-slash.js +130 -25
- package/dist/core/command/slash-handler.js +101 -53
- package/dist/core/command/topic-slash.js +16 -5
- package/dist/core/daemon-bootstrap.js +7 -1
- package/dist/core/daemon-control.js +19 -1
- package/dist/core/daemon-lifecycle.js +2 -1
- package/dist/core/event-catalog.js +2 -0
- package/dist/core/evolagent-registry.js +13 -2
- package/dist/core/evolagent.js +3 -6
- package/dist/core/handoff/ipc-registration.js +2 -2
- package/dist/core/handoff/runtime.js +40 -6
- package/dist/core/handoff/store.js +1 -0
- package/dist/core/inference/text-inference.js +95 -6
- package/dist/core/ipc-registration.js +43 -24
- package/dist/core/memory/consolidation-context.js +4 -1
- package/dist/core/memory/consolidation.js +25 -14
- package/dist/core/message/aun-ipc-sender.js +296 -88
- package/dist/core/message/aun-request-registry.js +226 -0
- package/dist/core/message/create-status.js +33 -4
- package/dist/core/message/message-bridge.js +62 -13
- package/dist/core/message/message-log.js +0 -1
- package/dist/core/message/message-queue.js +4 -1
- package/dist/core/message/message-utils.js +8 -1
- package/dist/core/message/peer-mode.js +17 -9
- package/dist/core/message/response-engine.js +266 -124
- package/dist/core/message/retry-scheduler.js +11 -8
- package/dist/core/model/catalog-service.js +60 -18
- package/dist/core/model/model-catalog.js +112 -9
- package/dist/core/model/model-fallback.js +94 -26
- package/dist/core/ownership/owner-resolver.js +687 -0
- package/dist/core/permission/approval-gateway.js +196 -62
- package/dist/core/permission/ec-command-parser.js +138 -25
- package/dist/core/permission/filesystem-approval-scope.js +141 -0
- package/dist/core/permission/protected-paths.js +14 -1
- package/dist/core/permission/sandbox-runtime.js +171 -18
- package/dist/core/permission/tool-policy.js +13 -2
- package/dist/core/role/runtime-policy.js +3 -4
- package/dist/core/session/session-idle-monitor.js +10 -8
- package/dist/core/session/session-manager.js +72 -45
- package/dist/core/session/session-mapper.js +18 -7
- package/dist/core/session/session-renew.js +5 -4
- package/dist/core/session/session-title.js +2 -1
- package/dist/core/session/session-turn-coordinator.js +4 -2
- package/dist/core/skill/index-generator.js +2 -16
- package/dist/core/task/task-recovery-service.js +15 -2
- package/dist/core/thread/command-parser.js +28 -13
- package/dist/core/thread/index.js +1 -0
- package/dist/core/thread/ipc-operation.js +11 -8
- package/dist/core/thread/thread-operation.js +79 -44
- package/dist/core/thread/thread-route.js +54 -6
- package/dist/core/thread/thread-service.js +236 -45
- package/dist/core/thread/topic-id.js +248 -0
- package/dist/eck/kit-renderer.js +1 -1
- package/dist/eck/message-renderer.js +12 -2
- package/dist/index.js +50 -27
- package/dist/ipc.js +59 -6
- package/dist/paths.js +1 -0
- package/dist/product.js +1 -0
- package/dist/response-system/engines/v1/proactive-flow.js +10 -3
- package/dist/stats/db.js +8 -0
- package/dist/stats/writer.js +26 -4
- package/dist/trigger/authorization.js +48 -3
- package/dist/trigger/feedback.js +28 -10
- package/dist/trigger/ipc-service.js +86 -10
- package/dist/trigger/local-files.js +55 -23
- package/dist/trigger/scheduler.js +57 -11
- package/dist/trigger/system-definitions.js +1 -0
- package/dist/trigger/validation.js +44 -15
- package/dist/utils/aid-bind.js +17 -297
- package/dist/utils/avatar-upload.js +16 -4
- package/dist/utils/cross-platform.js +115 -36
- package/dist/utils/ecweb-supervisor.js +1 -1
- package/dist/utils/ecweb-utils.js +8 -1
- package/dist/utils/error-utils.js +44 -6
- package/dist/utils/instance-registry.js +12 -2
- package/dist/utils/npm-ops.js +102 -27
- package/dist/utils/package-version-info.js +72 -27
- package/dist/utils/restart-safety.js +50 -0
- package/dist/utils/upgrade-jobs.js +304 -0
- package/dist/utils/windows-autostart.js +17 -10
- package/kits/docs/INDEX.md +5 -0
- package/kits/docs/aun/ABILITY_CALLING.md +239 -0
- package/kits/docs/evolcore/INDEX.md +14 -3
- package/kits/docs/evolcore/agent-create.md +55 -141
- package/kits/docs/evolcore/agent.md +38 -16
- package/kits/docs/evolcore/aid.md +34 -0
- package/kits/docs/evolcore/config.md +20 -1
- package/kits/docs/evolcore/event.md +2 -2
- package/kits/docs/evolcore/fs.md +18 -2
- package/kits/docs/evolcore/group-collaboration.md +13 -246
- package/kits/docs/evolcore/group.md +2 -1
- package/kits/docs/evolcore/memory-consolidation-batches.md +1 -1
- package/kits/docs/evolcore/menu-protocol.md +65 -1
- package/kits/docs/evolcore/msg.md +64 -2
- package/kits/docs/evolcore/skill.md +86 -0
- package/kits/docs/evolcore/stats.md +6 -0
- package/kits/docs/evolcore/task.md +2 -0
- package/kits/docs/evolcore/thread-chain.md +145 -51
- package/kits/docs/evolcore/trigger.md +48 -3
- package/kits/eck_manifest.json +21 -0
- package/kits/eck_message_manifest.json +4 -4
- package/kits/migrations/migrate-role-config-v5.mjs +20 -7
- package/kits/rules/01-overview.md +2 -1
- package/kits/rules/03-identity.md +3 -1
- package/kits/rules/04-relation.md +1 -1
- package/kits/rules/07-memory-and-thread.md +1 -1
- package/kits/schemas/_meta.json +16 -1
- package/kits/schemas/agent-config.schema.13.json +44 -2
- package/kits/schemas/contact-book.schema.3.json +5 -0
- package/kits/schemas/daemon.schema.6.json +3 -1
- package/kits/schemas/daemon.schema.8.json +329 -0
- package/kits/schemas/defaults.schema.5.json +39 -3
- package/kits/schemas/providers.schema.1.json +76 -0
- package/kits/schemas/relation-config.schema.9.json +5 -1
- package/kits/skills/.switches.json +28 -0
- package/kits/skills/aid-ability/SKILL.md +214 -0
- package/kits/skills/ec-agent-create/SKILL.md +162 -0
- package/kits/skills/ec-group/SKILL.md +2 -1
- package/kits/skills/ec-group-collaboration/SKILL.md +228 -0
- package/kits/skills/ec-identity/SKILL.md +143 -0
- package/kits/skills/ec-skill/scripts/cli.mjs +36 -3
- package/kits/skills/ec-skill/scripts/skill.mjs +202 -15
- package/kits/skills/ec-trigger/SKILL.md +167 -0
- package/kits/skills/ec-trigger/references/examples.md +153 -0
- package/kits/skills/thread-ops/SKILL.md +108 -420
- package/kits/templates/message-fragments/thread-context.md +1 -2
- package/kits/templates/message-fragments/trigger-thread-check.md +1 -1
- package/kits/templates/roles/member.json +1 -1
- package/kits/templates/roles/visitor.json +1 -0
- package/kits/templates/system-fragments/bootstrap.md +1 -0
- package/kits/templates/system-fragments/channel.md +2 -1
- package/kits/templates/system-fragments/commands.md +5 -4
- package/kits/templates/system-fragments/identity.md +2 -0
- package/kits/templates/system-fragments/session.md +1 -1
- package/kits/templates/system-fragments/venue.md +1 -1
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,48 @@
|
|
|
5
5
|
|
|
6
6
|
## Unreleased
|
|
7
7
|
|
|
8
|
+
## 0.0.37 (2026-10-24)
|
|
9
|
+
|
|
10
|
+
### 升级与重启稳定性
|
|
11
|
+
|
|
12
|
+
- 修复升级重启过程中运行时资源版本不同步的问题,暂存运行文件时一并保留 `kits` 目录。
|
|
13
|
+
- 修复 daemon Owner 通知配置异常或发送失败时可能影响重启恢复流程的问题;通知失败会保留诊断并继续执行重启。
|
|
14
|
+
|
|
15
|
+
### 配置维护
|
|
16
|
+
|
|
17
|
+
- 改进本地 Provider 配置文件的忽略规则,避免运行时凭据文件被误加入 Git 工作区。
|
|
18
|
+
|
|
19
|
+
## 0.0.36 (2026-10-24)
|
|
20
|
+
|
|
21
|
+
### Agent 创建与所有权
|
|
22
|
+
|
|
23
|
+
- 默认使用一次性初始化创建 Agent,并提供独立的 Bootstrap 模式;初始化支持进度查询、超时识别和失败恢复。
|
|
24
|
+
- 强化 Owner 绑定与共识确认流程,避免未完成授权的 Agent 提前激活或处理普通消息。
|
|
25
|
+
- 支持创建 Agent 时上传头像,并完善创建状态、欢迎消息和多 Owner 交接。
|
|
26
|
+
- AUN 私聊支持首个配置 Owner 通过纯 `/bind` 发起 ownership 绑定;系统会持续刷新待确认状态,且不影响带渠道参数的联系人绑定。
|
|
27
|
+
|
|
28
|
+
### Provider 与模型
|
|
29
|
+
|
|
30
|
+
- 支持按 Agent 基座类型选择 Provider 服务,并统一 Provider 配置、模型目录和备用模型处理。
|
|
31
|
+
- 支持从运行环境导入 Provider 连接信息,允许在运行环境尚未配置完整时保存模型选择。
|
|
32
|
+
- 改进模型不可用、连接配置和运行时切换的诊断。
|
|
33
|
+
|
|
34
|
+
### 权限与运行稳定性
|
|
35
|
+
|
|
36
|
+
- 按操作敏感度复用 Owner 共识缓存,并在敏感操作、Owner 变更和授权材料变化时重新核验。
|
|
37
|
+
- 修复 Claude runner 未正确应用显式服务地址和 API 密钥的问题。
|
|
38
|
+
- 改进 Codex 会话恢复、AUN 断线期间的 Owner 状态保留、Trigger 重试和跨话题复查。
|
|
39
|
+
- 收紧受管临时路径识别和命令授权边界,提升权限拒绝原因的可读性。
|
|
40
|
+
- 提升 AUN SDK 兼容要求,使用经过当前版本验证的依赖版本。
|
|
41
|
+
|
|
42
|
+
### 技能与运维
|
|
43
|
+
|
|
44
|
+
- 新增 `ec skill load`、`ec skill path` 和分页技能列表,支持按来源、描述和筛选条件查看技能。
|
|
45
|
+
- 新增 `ec-agent-create` 技能,集中处理 Agent 创建、初始化、Bootstrap、恢复和验收流程。
|
|
46
|
+
- 新增 `ec-group-collaboration` 技能,集中处理 AUN 协作群创建、邀请、规则、任务分派和验收。
|
|
47
|
+
- 新增可恢复的 npm 升级任务、项目文件搜索和更完整的 EC Web 运维状态展示。
|
|
48
|
+
- 改进 Windows 启动、自启动、联系人同步和基础配置诊断。
|
|
49
|
+
|
|
8
50
|
## 0.0.35 (2026-10-19)
|
|
9
51
|
|
|
10
52
|
### 权限与记忆
|
package/README.md
CHANGED
|
@@ -105,6 +105,12 @@ npm install -g evolcore
|
|
|
105
105
|
|
|
106
106
|
Linux 全局安装会在 `postinstall` 阶段准备 Codex 受管运行所需的真实目录 `/etc/codex`。如果当前 npm 全局目录属于普通用户且该系统目录尚不存在,请先执行 `sudo install -d -m 0755 /etc/codex`,再重新安装。
|
|
107
107
|
|
|
108
|
+
Linux 托管 Codex 在外层沙箱已遮蔽真实 `data/` 并仅重新暴露 daemon IPC socket 时,内层权限配置对这棵已遮蔽的数据树使用只读投影,避免重复 `deny` 阻断 socket 挂载或连接;这不开放真实 `data/instance/`,其中的 `control.token` 等数据仍不可见,也不需要关闭沙箱或提高关系权限。
|
|
109
|
+
|
|
110
|
+
Ubuntu 24.04+ 若启用 `apparmor_restrict_unprivileged_userns=1`,Codex 受限会话启动前会运行实际 bwrap/user namespace 探针;探针失败时按 `codex_sandbox_userns_disabled_by_apparmor` fail closed,不会自动切换到全权限。请在服务实际运行环境执行 `ec diagnose --codex-sandbox`,由宿主为 EvolCore/Codex 配置最小范围的 AppArmor 允许规则,或提供等价隔离后端;不要全局关闭 AppArmor user namespace 限制。
|
|
111
|
+
|
|
112
|
+
Linux 上 Claude 的沙箱执行需要可执行的 `bubblewrap`(`bwrap`)和 `socat`。安装器、npm postinstall 和 daemon 启动会检查并提醒缺失项,不会自动安装系统包或关闭沙箱;Debian/Ubuntu 可由管理员运行 `apt install bubblewrap socat`。`bwrap` 可复用 `EVOLCORE_BWRAP_PATH` 或 Codex 自带的可执行文件。安装后在服务相同的环境中运行 `ec diagnose --claude-sandbox`,同时验证依赖路径和基础命名空间启动;工具存在不代表容器的 user namespace/seccomp 配置一定可用。缺少依赖的任务不会自动恢复重试,修复后可人工 `/resume`。
|
|
113
|
+
|
|
108
114
|
Windows 的 npm 安装和升级不会直接写入机器级 Codex 配置。配置使用 Codex 后,执行 `ec start` 或 `ec restart` 时会自动检测托管 Hook;缺失时自动请求 Windows 管理员授权(UAC),安装并复检成功后继续启动。已安装时直接继续,无需单独执行安装命令,详见 [Windows Codex 托管 Hook](docs/codex-windows-managed-hook.md)。
|
|
109
115
|
|
|
110
116
|
如果取消 UAC 或安装失败,本次启动或重启会停止;重启检查发生在停止旧服务之前。已有策略异常或安装位置变化需要管理员核对,自动安装不会覆盖这些状态。
|
|
@@ -649,10 +649,27 @@ export function provisionManagedFiles(options, acl = windowsAcl) {
|
|
|
649
649
|
}
|
|
650
650
|
}
|
|
651
651
|
|
|
652
|
-
function
|
|
652
|
+
async function checkClaudeSandboxDependencies() {
|
|
653
|
+
try {
|
|
654
|
+
const runtime = await import('../dist/core/permission/sandbox-runtime.js');
|
|
655
|
+
const check = runtime.inspectClaudeSandboxDependencies();
|
|
656
|
+
if (check.status === 'missing' || hasArgument('--check-claude-sandbox')) {
|
|
657
|
+
process.stderr.write(`[evolcore] ${runtime.formatClaudeSandboxDependencies(check)}\n`);
|
|
658
|
+
}
|
|
659
|
+
} catch (error) {
|
|
660
|
+
process.stderr.write(`[evolcore] Claude sandbox dependency check unavailable: ${error.message}. Run ec diagnose before using sandbox-required Claude sessions.\n`);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
async function main() {
|
|
665
|
+
if (hasArgument('--check-claude-sandbox')) {
|
|
666
|
+
await checkClaudeSandboxDependencies();
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
653
669
|
// An explicit package root selects provisioning, even if the elevated
|
|
654
670
|
// child inherited npm lifecycle variables. Ordinary postinstall skips it.
|
|
655
671
|
if (!argument('--package-root') && (lifecycleEvent() === 'postinstall' || isGlobalInstall())) {
|
|
672
|
+
await checkClaudeSandboxDependencies();
|
|
656
673
|
runLinuxPostinstall();
|
|
657
674
|
windowsPostinstallNotice();
|
|
658
675
|
return;
|
|
@@ -697,7 +714,7 @@ if (process.argv[1] && pathToFileURL(fs.realpathSync(process.argv[1])).href ===
|
|
|
697
714
|
const earlyRequirements = argument('--requirements')
|
|
698
715
|
? path.resolve(argument('--requirements'))
|
|
699
716
|
: path.join(process.env.ProgramData || path.join(os.homedir(), 'ProgramData'), 'OpenAI', 'Codex', 'requirements.toml');
|
|
700
|
-
|
|
717
|
+
void main().catch(error => {
|
|
701
718
|
fail(error instanceof Error ? error.message : String(error), earlyRequirements);
|
|
702
|
-
}
|
|
719
|
+
});
|
|
703
720
|
}
|
|
@@ -131,6 +131,6 @@ export async function getBaseagentSnapshot(options = {}) {
|
|
|
131
131
|
}
|
|
132
132
|
const detections = options.probe === false
|
|
133
133
|
? null
|
|
134
|
-
:
|
|
134
|
+
: detectBaseagentDetails();
|
|
135
135
|
return buildBaseagentSnapshot(config ?? {}, detections, options.loaded);
|
|
136
136
|
}
|
package/dist/agents/baseagent.js
CHANGED
|
@@ -16,6 +16,7 @@ import { buildCliLaunchCommand, commandExists, isWindows, resolvePowerShellShimP
|
|
|
16
16
|
import { execFileSync } from 'child_process';
|
|
17
17
|
import { parse as parseToml } from 'smol-toml';
|
|
18
18
|
import { readRuntimeEnvironmentVariable } from '../config/runtime-env.js';
|
|
19
|
+
import { resolveProviderServiceForBaseagent, resolveProviderService } from '../config/providers.js';
|
|
19
20
|
/** Resolve the installed Codex CLI entrypoint, including npm shims on Windows. */
|
|
20
21
|
export function resolveCodexCliPath() {
|
|
21
22
|
return resolveProbePath('codex');
|
|
@@ -138,6 +139,12 @@ function loadClaudeSettings() {
|
|
|
138
139
|
* across Agent config, the process environment, and Claude Code settings.
|
|
139
140
|
*/
|
|
140
141
|
export function resolveAnthropicDirectConfig(override, runtime) {
|
|
142
|
+
if (override?.provider !== undefined) {
|
|
143
|
+
const provider = resolveProviderService(override.provider, 'claude');
|
|
144
|
+
if (!provider.apiKey)
|
|
145
|
+
throw new Error(`Provider ${provider.providerId} has no API key`);
|
|
146
|
+
return { ...provider, apiKey: provider.apiKey };
|
|
147
|
+
}
|
|
141
148
|
const explicit = directInferencePair(override?.apiKey, override?.baseUrl);
|
|
142
149
|
if (explicit) {
|
|
143
150
|
return {
|
|
@@ -163,6 +170,22 @@ export function resolveAnthropicDirectConfig(override, runtime) {
|
|
|
163
170
|
}
|
|
164
171
|
export function resolveAnthropicConfig(config, override, runtime) {
|
|
165
172
|
const settings = loadClaudeSettings();
|
|
173
|
+
const providerId = override?.provider ?? config.agents?.claude?.provider;
|
|
174
|
+
if (providerId !== undefined) {
|
|
175
|
+
const provider = resolveProviderService(providerId, 'claude');
|
|
176
|
+
if (!provider.apiKey)
|
|
177
|
+
throw new Error(`Provider ${providerId} has no API key`);
|
|
178
|
+
return {
|
|
179
|
+
apiKey: provider.apiKey,
|
|
180
|
+
baseUrl: provider.baseUrl,
|
|
181
|
+
providerId,
|
|
182
|
+
headers: provider.headers,
|
|
183
|
+
queryParams: provider.queryParams,
|
|
184
|
+
model: override?.model || config.agents?.claude?.model || settings.model || 'sonnet',
|
|
185
|
+
effort: override?.effort || config.agents?.claude?.effort || settings.effortLevel || undefined,
|
|
186
|
+
pathToClaudeCodeExecutable: override?.pathToClaudeCodeExecutable || config.agents?.claude?.pathToClaudeCodeExecutable,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
166
189
|
const isPlaceholder = (v) => !v || v.includes('your-') || v.includes('placeholder');
|
|
167
190
|
const resolveGatewayReference = (value) => {
|
|
168
191
|
const name = value?.match(/^\$\{(ANTHROPIC_BASE_URL|ANTHROPIC_AUTH_TOKEN|ANTHROPIC_API_KEY)\}$/u)?.[1];
|
|
@@ -276,6 +299,12 @@ export function loadCodexSettings() {
|
|
|
276
299
|
* never combined with a partial Agent or process-environment configuration.
|
|
277
300
|
*/
|
|
278
301
|
export function resolveOpenaiDirectConfig(override) {
|
|
302
|
+
if (override?.provider !== undefined) {
|
|
303
|
+
const provider = resolveProviderService(override.provider, 'codex');
|
|
304
|
+
if (!provider.apiKey)
|
|
305
|
+
throw new Error(`Provider ${provider.providerId} has no API key`);
|
|
306
|
+
return { ...provider, apiKey: provider.apiKey };
|
|
307
|
+
}
|
|
279
308
|
const explicit = directInferencePair(override?.apiKey, override?.baseUrl);
|
|
280
309
|
if (explicit) {
|
|
281
310
|
return {
|
|
@@ -310,6 +339,28 @@ export function resolveOpenaiDirectConfig(override) {
|
|
|
310
339
|
}
|
|
311
340
|
export function resolveOpenaiConfig(config, override, runtime) {
|
|
312
341
|
const codexSettings = loadCodexSettings();
|
|
342
|
+
const providerId = override?.provider ?? config.agents?.codex?.provider;
|
|
343
|
+
if (providerId !== undefined) {
|
|
344
|
+
const provider = resolveProviderService(providerId, 'codex');
|
|
345
|
+
if (!provider.apiKey)
|
|
346
|
+
throw new Error(`Provider ${providerId} has no API key`);
|
|
347
|
+
return {
|
|
348
|
+
apiKey: provider.apiKey,
|
|
349
|
+
authType: 'apiKey',
|
|
350
|
+
authSource: 'agent-config',
|
|
351
|
+
baseUrl: provider.baseUrl,
|
|
352
|
+
provider: providerId,
|
|
353
|
+
providerId,
|
|
354
|
+
headers: provider.headers,
|
|
355
|
+
queryParams: provider.queryParams,
|
|
356
|
+
model: override?.model || config.agents?.codex?.model || codexSettings.model || 'gpt-5.2-codex',
|
|
357
|
+
effort: override?.effort || override?.reasoning || config.agents?.codex?.effort || undefined,
|
|
358
|
+
enableRequestUserInput: override?.enableRequestUserInput ?? config.agents?.codex?.enableRequestUserInput ?? true,
|
|
359
|
+
approvalsReviewer: override?.approvalsReviewer ?? config.agents?.codex?.approvalsReviewer,
|
|
360
|
+
agentAid: runtime?.agentAid,
|
|
361
|
+
agentConfig: runtime?.agentConfig,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
313
364
|
const isPlaceholder = (v) => !v || v.includes('your-') || v.includes('placeholder');
|
|
314
365
|
const overrideApiKey = isPlaceholder(override?.apiKey) ? undefined : override?.apiKey;
|
|
315
366
|
const globalApiKey = isPlaceholder(config.agents?.codex?.apiKey) ? undefined : config.agents?.codex?.apiKey;
|
|
@@ -388,6 +439,17 @@ export function resolveGoogleConfig(config, override) {
|
|
|
388
439
|
cliPath = commandExists('gemini') ? 'gemini' : '';
|
|
389
440
|
}
|
|
390
441
|
const model = override?.model || googleCfg?.model || 'gemini-2.5-flash';
|
|
442
|
+
const providerId = override?.provider ?? googleCfg?.provider;
|
|
443
|
+
if (providerId !== undefined) {
|
|
444
|
+
const provider = resolveProviderService(providerId, 'gemini');
|
|
445
|
+
if (!provider.apiKey)
|
|
446
|
+
throw new Error(`Provider ${providerId} has no API key`);
|
|
447
|
+
if (provider.queryParams && Object.keys(provider.queryParams).length > 0) {
|
|
448
|
+
throw new Error(`Provider ${providerId} gemini service queryParams are unsupported by the Gemini CLI runtime`);
|
|
449
|
+
}
|
|
450
|
+
return { cliPath, model, apiKey: provider.apiKey, providerId, baseUrl: provider.baseUrl, headers: provider.headers,
|
|
451
|
+
queryParams: provider.queryParams, mode: override?.mode || googleCfg?.mode || 'cli', useVertex: false };
|
|
452
|
+
}
|
|
391
453
|
const overrideApiKey = isPlaceholder(override?.apiKey) ? undefined : override?.apiKey;
|
|
392
454
|
const globalApiKey = isPlaceholder(googleCfg?.apiKey) ? undefined : googleCfg?.apiKey;
|
|
393
455
|
const apiKey = overrideApiKey
|
|
@@ -409,6 +471,32 @@ export const DEFAULT_ECAGENT_MAX_RETRIES = 2;
|
|
|
409
471
|
export const DEFAULT_ECAGENT_MAX_RETRY_DELAY_MS = 4_000;
|
|
410
472
|
export function resolveEcagentConfig(config, override) {
|
|
411
473
|
const configured = config.agents?.ecagent;
|
|
474
|
+
const providerId = override?.provider ?? configured?.provider;
|
|
475
|
+
if (providerId !== undefined) {
|
|
476
|
+
const providerServiceType = override?.providerServiceType ?? configured?.providerServiceType;
|
|
477
|
+
const provider = resolveProviderServiceForBaseagent(providerId, 'ecagent', providerServiceType);
|
|
478
|
+
if (provider.style !== 'openai-compatible') {
|
|
479
|
+
throw new Error(`Provider ${providerId} uses unsupported ecagent style: ${provider.style}`);
|
|
480
|
+
}
|
|
481
|
+
if (!provider.apiKey)
|
|
482
|
+
throw new Error(`Provider ${providerId} has no API key`);
|
|
483
|
+
const numberOr = (value, fallback) => (typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : fallback);
|
|
484
|
+
return {
|
|
485
|
+
apiKey: provider.apiKey,
|
|
486
|
+
baseUrl: provider.baseUrl,
|
|
487
|
+
headers: provider.headers,
|
|
488
|
+
queryParams: provider.queryParams,
|
|
489
|
+
model: override?.model || configured?.model || DEFAULT_ECAGENT_MODEL,
|
|
490
|
+
effort: override?.effort ?? configured?.effort,
|
|
491
|
+
timeoutMs: numberOr(override?.timeoutMs ?? configured?.timeoutMs, DEFAULT_ECAGENT_TIMEOUT_MS),
|
|
492
|
+
maxRetries: numberOr(override?.maxRetries ?? configured?.maxRetries, DEFAULT_ECAGENT_MAX_RETRIES),
|
|
493
|
+
maxRetryDelayMs: numberOr(override?.maxRetryDelayMs ?? configured?.maxRetryDelayMs, DEFAULT_ECAGENT_MAX_RETRY_DELAY_MS),
|
|
494
|
+
providerId,
|
|
495
|
+
providerServiceType: provider.serviceType,
|
|
496
|
+
providerStyle: provider.style,
|
|
497
|
+
modelOverrides: provider.modelOverrides,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
412
500
|
const isPlaceholder = (value) => !value
|
|
413
501
|
|| value.includes('your-')
|
|
414
502
|
|| value.includes('placeholder');
|
|
@@ -4,12 +4,15 @@ import { spawn, execFileSync } from 'child_process';
|
|
|
4
4
|
import { createRequire } from 'module';
|
|
5
5
|
import { ensureDir } from '../utils/atomic-write.js';
|
|
6
6
|
import { resolveAnthropicConfig } from './baseagent.js';
|
|
7
|
+
import { resolveProviderService } from '../config/providers.js';
|
|
7
8
|
import { buildModelRequestHeaders } from './request-identity.js';
|
|
8
9
|
import { DEFAULT_PERMISSION_MODE } from '../types.js';
|
|
9
10
|
import { renderActionAsText } from '../core/interaction-router.js';
|
|
11
|
+
import { sessionTopicThreadId } from '../core/thread/topic-id.js';
|
|
10
12
|
import { buildEnvelope, isInteractionSendAccepted, sendInteractionPayload } from '../core/message/message-utils.js';
|
|
11
13
|
import path from 'path';
|
|
12
14
|
import fs from 'fs';
|
|
15
|
+
import { assertOwnershipAuthorization } from '../core/ownership/owner-resolver.js';
|
|
13
16
|
import os from 'os';
|
|
14
17
|
import crypto from 'crypto';
|
|
15
18
|
import { logger } from '../utils/logger.js';
|
|
@@ -25,7 +28,7 @@ import { sanitizeSessionTitle } from '../core/session/session-title.js';
|
|
|
25
28
|
import { resolveClaudeCapabilityRunOptionsForProject } from '../core/capability/capability-manager.js';
|
|
26
29
|
import { normalizeExecutionPermissionMode, normalizePermissionMode, resolvePhaseOneExecutionSandbox } from '../core/permission/mode.js';
|
|
27
30
|
import { buildClaudeProtectedFilesystem, containsHClassReference, containsLClassReference, isHClassPath, isLClassPath, isSameOrDescendant, resolveProtectedCandidate, } from '../core/permission/protected-paths.js';
|
|
28
|
-
import { buildHClassGuardCommand, collectSandboxGuardDiagnostics, createSandboxInitializationError, getActiveSandboxInitializationFailure, isSandboxInitializationFailure, isSandboxInitializationToolResult, recordSandboxInitializationFailure, getSandboxInitializationFailureCounters, SANDBOX_INITIALIZATION_COOLDOWN_MS, SANDBOX_INITIALIZATION_FAILED, ensureClaudeGitWorktreeConfig, prependExecutableDirectory, resolveBubblewrapPath, summarizeBubblewrapArgsForLog, summarizeSandboxGuardDiagnostics, shouldEnableClaudeWeakerNestedSandbox, shouldFailIfClaudeSandboxUnavailable, shouldLogSandboxCircuitNotice, } from '../core/permission/sandbox-runtime.js';
|
|
31
|
+
import { buildHClassGuardCommand, collectSandboxGuardDiagnostics, createSandboxInitializationError, createClaudeSandboxDependencyError, inspectClaudeSandboxDependencies, getActiveSandboxInitializationFailure, isSandboxInitializationFailure, isSandboxInitializationToolResult, recordSandboxInitializationFailure, getSandboxInitializationFailureCounters, SANDBOX_INITIALIZATION_COOLDOWN_MS, SANDBOX_INITIALIZATION_FAILED, ensureClaudeGitWorktreeConfig, prependExecutableDirectory, resolveBubblewrapPath, summarizeBubblewrapArgsForLog, summarizeSandboxGuardDiagnostics, shouldEnableClaudeWeakerNestedSandbox, shouldFailIfClaudeSandboxUnavailable, shouldLogSandboxCircuitNotice, } from '../core/permission/sandbox-runtime.js';
|
|
29
32
|
import { buildClaudeUnixSocketAllowlist } from '../core/permission/unix-socket-policy.js';
|
|
30
33
|
import { auditToolInfrastructureFailure, auditToolPreflightDenial } from '../core/auth/authorization-audit.js';
|
|
31
34
|
import { getManagedTaskTempDir, isManagedSessionRuntimeDir } from '../cli/task-context.js';
|
|
@@ -158,7 +161,9 @@ export function probeBundledClaudeVersion() {
|
|
|
158
161
|
if (!executable)
|
|
159
162
|
return undefined;
|
|
160
163
|
try {
|
|
161
|
-
const raw = execFileSync(executable, ['--version'], {
|
|
164
|
+
const raw = execFileSync(executable, ['--version'], {
|
|
165
|
+
encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], windowsHide: true, timeout: 3000,
|
|
166
|
+
});
|
|
162
167
|
return raw.trim().split(/\s+/)[0] || undefined;
|
|
163
168
|
}
|
|
164
169
|
catch {
|
|
@@ -353,7 +358,7 @@ function inspectClaudePermissionExpansion(input, options, projectPath) {
|
|
|
353
358
|
: input,
|
|
354
359
|
};
|
|
355
360
|
}
|
|
356
|
-
function buildClaudeManagedLockdownSettings(capabilityOptions) {
|
|
361
|
+
function buildClaudeManagedLockdownSettings(capabilityOptions, dependencies) {
|
|
357
362
|
const settings = capabilityOptions?.settings;
|
|
358
363
|
const rawAllowedMcpServers = settings && typeof settings === 'object' && !Array.isArray(settings)
|
|
359
364
|
? settings.allowedMcpServers
|
|
@@ -371,6 +376,7 @@ function buildClaudeManagedLockdownSettings(capabilityOptions) {
|
|
|
371
376
|
disableSkillShellExecution: true,
|
|
372
377
|
allowedHttpHookUrls: [],
|
|
373
378
|
allowManagedPermissionRulesOnly: true,
|
|
379
|
+
...(dependencies?.status === 'ready' ? { sandbox: { bwrapPath: dependencies.bwrapPath, socatPath: dependencies.socatPath } } : {}),
|
|
374
380
|
...(allowedMcpServers ? {
|
|
375
381
|
allowManagedMcpServersOnly: true,
|
|
376
382
|
allowedMcpServers,
|
|
@@ -700,7 +706,7 @@ export class AgentRunner {
|
|
|
700
706
|
this.onSessionIdUpdate = onSessionIdUpdate;
|
|
701
707
|
this.claudeExecutablePath = resolveBundledClaudeExecutable();
|
|
702
708
|
if (config) {
|
|
703
|
-
const anthropic = resolveAnthropicConfig(this.getRuntimeGatewayConfig(),
|
|
709
|
+
const anthropic = resolveAnthropicConfig(this.getRuntimeGatewayConfig(), { apiKey, baseUrl }, this.getRuntimeGatewayScope());
|
|
704
710
|
this.apiKey = apiKey || anthropic.apiKey;
|
|
705
711
|
this.claudeExecutablePath = anthropic.pathToClaudeCodeExecutable || this.claudeExecutablePath;
|
|
706
712
|
this.customHeaders = buildModelRequestHeaders({
|
|
@@ -734,8 +740,14 @@ export class AgentRunner {
|
|
|
734
740
|
return this.config;
|
|
735
741
|
}
|
|
736
742
|
}
|
|
737
|
-
getAgentEnv(runtimeEnv, evolcoreSessionId, permissionMode) {
|
|
738
|
-
const
|
|
743
|
+
getAgentEnv(runtimeEnv, evolcoreSessionId, permissionMode, providerOverride) {
|
|
744
|
+
const current = this.getRuntimeGatewayConfig();
|
|
745
|
+
const providerConfigured = providerOverride !== undefined || current.agents?.claude?.provider !== undefined;
|
|
746
|
+
const connection = providerConfigured ? resolveAnthropicConfig(current, providerOverride ? { provider: providerOverride } : undefined, this.getRuntimeGatewayScope())
|
|
747
|
+
: { baseUrl: this.baseUrl, apiKey: this.apiKey, headers: this.customHeaders, queryParams: this.customQueryParams };
|
|
748
|
+
const anthropicBaseUrl = appendQueryParams(connection.baseUrl, connection.queryParams);
|
|
749
|
+
const headers = providerConfigured ? buildModelRequestHeaders({ baseagent: 'claude', baseUrl: connection.baseUrl,
|
|
750
|
+
agentAid: this.agentAid, configuredHeaders: connection.headers }) : connection.headers;
|
|
739
751
|
const env = sanitizeShellExecutionEnvironment({
|
|
740
752
|
...process.env,
|
|
741
753
|
ANTHROPIC_AUTH_TOKEN: this.apiKey,
|
|
@@ -752,6 +764,12 @@ export class AgentRunner {
|
|
|
752
764
|
...(evolcoreSessionId ? { EVOLCORE_SESSION_ID: evolcoreSessionId } : {}),
|
|
753
765
|
...(runtimeEnv ?? {}),
|
|
754
766
|
}, { lockExecutableResolution: permissionMode === 'readonly' });
|
|
767
|
+
if (providerConfigured) {
|
|
768
|
+
env.ANTHROPIC_AUTH_TOKEN = connection.apiKey;
|
|
769
|
+
env.ANTHROPIC_API_KEY = connection.apiKey;
|
|
770
|
+
env.ANTHROPIC_BASE_URL = anthropicBaseUrl;
|
|
771
|
+
env.ANTHROPIC_CUSTOM_HEADERS = Object.entries(headers ?? {}).map(([name, value]) => `${name}: ${value}`).join('\n');
|
|
772
|
+
}
|
|
755
773
|
const trustedRootFullAccess = permissionMode === 'fullaccess'
|
|
756
774
|
&& typeof process.getuid === 'function'
|
|
757
775
|
&& process.getuid() === 0
|
|
@@ -766,7 +784,7 @@ export class AgentRunner {
|
|
|
766
784
|
env.IS_SANDBOX = '1';
|
|
767
785
|
else
|
|
768
786
|
delete env.IS_SANDBOX;
|
|
769
|
-
const bubblewrapPath = resolveBubblewrapPath();
|
|
787
|
+
const bubblewrapPath = resolveBubblewrapPath(env);
|
|
770
788
|
return bubblewrapPath
|
|
771
789
|
? prependExecutableDirectory(env, bubblewrapPath)
|
|
772
790
|
: env;
|
|
@@ -817,7 +835,19 @@ export class AgentRunner {
|
|
|
817
835
|
};
|
|
818
836
|
}
|
|
819
837
|
catalogConnection() {
|
|
820
|
-
|
|
838
|
+
const current = this.getRuntimeGatewayConfig();
|
|
839
|
+
if (current.agents?.claude?.provider !== undefined) {
|
|
840
|
+
const provider = resolveProviderService(current.agents.claude.provider, 'claude');
|
|
841
|
+
return { ...provider, headers: buildModelRequestHeaders({ baseagent: 'claude', baseUrl: provider.baseUrl,
|
|
842
|
+
agentAid: this.agentAid, configuredHeaders: provider.headers }) };
|
|
843
|
+
}
|
|
844
|
+
return {
|
|
845
|
+
baseUrl: this.baseUrl,
|
|
846
|
+
apiKey: this.apiKey,
|
|
847
|
+
headers: this.customHeaders,
|
|
848
|
+
queryParams: this.customQueryParams,
|
|
849
|
+
providerId: this.config?.agents?.claude?.provider,
|
|
850
|
+
};
|
|
821
851
|
}
|
|
822
852
|
getModelCatalog() {
|
|
823
853
|
return getRunnerCatalog('claude', this.agentAid, this.catalogConnection());
|
|
@@ -2357,6 +2387,12 @@ export class AgentRunner {
|
|
|
2357
2387
|
const trustedSafeOutputCommands = new Set();
|
|
2358
2388
|
// PreToolUse Hook - 黑名单检查 + input 修正(不可绕过,所有模式都走)
|
|
2359
2389
|
const preToolUseHook = async (input, _toolUseId, hookOptions) => {
|
|
2390
|
+
try {
|
|
2391
|
+
await assertOwnershipAuthorization(this.permissionContexts.get(sessionId));
|
|
2392
|
+
}
|
|
2393
|
+
catch (error) {
|
|
2394
|
+
return hookDecision('deny', error instanceof Error ? error.message : String(error));
|
|
2395
|
+
}
|
|
2360
2396
|
const pauseController = this.permissionContexts.get(sessionId)?.pauseController;
|
|
2361
2397
|
if (pauseController) {
|
|
2362
2398
|
const pauseResult = await pauseController.waitAtToolBoundary(hookOptions?.signal);
|
|
@@ -2573,6 +2609,12 @@ export class AgentRunner {
|
|
|
2573
2609
|
};
|
|
2574
2610
|
}
|
|
2575
2611
|
// 特殊处理:AskUserQuestion 工具(SDK 内置的用户交互工具)
|
|
2612
|
+
try {
|
|
2613
|
+
await assertOwnershipAuthorization(this.permissionContexts.get(sessionId));
|
|
2614
|
+
}
|
|
2615
|
+
catch (error) {
|
|
2616
|
+
return { behavior: 'deny', message: error instanceof Error ? error.message : String(error) };
|
|
2617
|
+
}
|
|
2576
2618
|
// 这不是权限审批,而是收集用户答案,需要构造表单卡片
|
|
2577
2619
|
if (toolName === 'AskUserQuestion') {
|
|
2578
2620
|
return await this.handleAskUserQuestion(sessionId, input, options);
|
|
@@ -2777,10 +2819,14 @@ export class AgentRunner {
|
|
|
2777
2819
|
}
|
|
2778
2820
|
const catalogModel = resolveCatalogModel(runCatalog, callModel);
|
|
2779
2821
|
const { sdkModel, contextWindow } = resolveClaudeModelContext(catalogModel, runCatalog);
|
|
2822
|
+
const agentEnv = this.getAgentEnv(runtimeEnv, sessionId, callPermissionMode, modelOverride?.provider);
|
|
2823
|
+
const dependencies = executionSandbox.state !== 'off' ? inspectClaudeSandboxDependencies(agentEnv) : undefined;
|
|
2824
|
+
if (dependencies?.status === 'missing')
|
|
2825
|
+
throw createClaudeSandboxDependencyError(dependencies);
|
|
2780
2826
|
const capabilityOptions = await this.resolveCapabilityRunOptions(projectPath);
|
|
2781
2827
|
const managedSettings = callPermissionMode === 'fullaccess'
|
|
2782
2828
|
? undefined
|
|
2783
|
-
: buildClaudeManagedLockdownSettings(capabilityOptions);
|
|
2829
|
+
: buildClaudeManagedLockdownSettings(capabilityOptions, dependencies);
|
|
2784
2830
|
const sandboxOptions = executionSandbox.state === 'off'
|
|
2785
2831
|
? { enabled: false }
|
|
2786
2832
|
: await (async () => {
|
|
@@ -2879,7 +2925,7 @@ export class AgentRunner {
|
|
|
2879
2925
|
},
|
|
2880
2926
|
...(enableSummaries ? { agentProgressSummaries: true } : {}),
|
|
2881
2927
|
stderr: handleClaudeStderr,
|
|
2882
|
-
env:
|
|
2928
|
+
env: agentEnv
|
|
2883
2929
|
};
|
|
2884
2930
|
// Native Windows has a small CreateProcess command-line limit. The SDK
|
|
2885
2931
|
// normally serializes `sandbox` into inline `--settings` JSON, so preserve
|
|
@@ -3001,10 +3047,11 @@ export class AgentRunner {
|
|
|
3001
3047
|
if (sessionManager && agentSessionId) {
|
|
3002
3048
|
try {
|
|
3003
3049
|
const currentSession = await sessionManager.getSessionById?.(sessionId);
|
|
3004
|
-
|
|
3050
|
+
const currentTopicThreadId = sessionTopicThreadId(currentSession);
|
|
3051
|
+
if (currentTopicThreadId && topicBinding && typeof sessionManager.consumeTopicResumeAt === 'function') {
|
|
3005
3052
|
resumeAt = await sessionManager.consumeTopicResumeAt({
|
|
3006
3053
|
sessionId,
|
|
3007
|
-
expectedThreadId:
|
|
3054
|
+
expectedThreadId: currentTopicThreadId,
|
|
3008
3055
|
expectedAgentSessionId: agentSessionId,
|
|
3009
3056
|
});
|
|
3010
3057
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import readline from 'readline';
|
|
3
3
|
import { logger } from '../../utils/logger.js';
|
|
4
|
-
import { buildHClassGuardCommand, collectSandboxGuardDiagnostics, summarizeBubblewrapArgsForLog, summarizeSandboxGuardDiagnostics, } from '../../core/permission/sandbox-runtime.js';
|
|
4
|
+
import { buildHClassGuardCommand, collectSandboxGuardDiagnostics, createCodexSandboxAvailabilityError, inspectCodexSandboxAvailability, probeCodexSandboxAvailability, summarizeBubblewrapArgsForLog, summarizeSandboxGuardDiagnostics, } from '../../core/permission/sandbox-runtime.js';
|
|
5
5
|
import { resolveCodexLaunchCommand } from '../baseagent.js';
|
|
6
6
|
import { createHash } from 'crypto';
|
|
7
7
|
import { sanitizeShellExecutionEnvironment } from '../../core/permission/shell-environment.js';
|
|
@@ -71,6 +71,16 @@ export class CodexAppServerClient {
|
|
|
71
71
|
constructor(options) {
|
|
72
72
|
this.options = options;
|
|
73
73
|
}
|
|
74
|
+
assertCodexSandboxAvailable(config, sandbox) {
|
|
75
|
+
if (process.platform !== 'linux')
|
|
76
|
+
return;
|
|
77
|
+
if (!hasPermissionProfile(config) && (!sandbox || sandbox === 'danger-full-access'))
|
|
78
|
+
return;
|
|
79
|
+
const availability = inspectCodexSandboxAvailability({ ...process.env, ...this.options.env });
|
|
80
|
+
const probe = probeCodexSandboxAvailability(availability);
|
|
81
|
+
if (!probe.ok)
|
|
82
|
+
throw createCodexSandboxAvailabilityError(probe);
|
|
83
|
+
}
|
|
74
84
|
onNotification(handler) {
|
|
75
85
|
this.notificationHandlers.add(handler);
|
|
76
86
|
return () => this.notificationHandlers.delete(handler);
|
|
@@ -78,6 +88,7 @@ export class CodexAppServerClient {
|
|
|
78
88
|
async threadStart(projectPath, options) {
|
|
79
89
|
const effort = options?.effort ?? this.options.effort;
|
|
80
90
|
const configUsesPermissionProfile = hasPermissionProfile(options?.config);
|
|
91
|
+
this.assertCodexSandboxAvailable(options?.config, options?.sandbox);
|
|
81
92
|
return this.request('thread/start', {
|
|
82
93
|
cwd: projectPath,
|
|
83
94
|
model: options?.model ?? this.options.model ?? null,
|
|
@@ -100,6 +111,7 @@ export class CodexAppServerClient {
|
|
|
100
111
|
async threadResume(threadId, projectPath, options) {
|
|
101
112
|
const effort = options?.effort ?? this.options.effort;
|
|
102
113
|
const configUsesPermissionProfile = hasPermissionProfile(options?.config);
|
|
114
|
+
this.assertCodexSandboxAvailable(options?.config, options?.sandbox);
|
|
103
115
|
return this.request('thread/resume', {
|
|
104
116
|
threadId,
|
|
105
117
|
cwd: projectPath,
|
|
@@ -222,6 +234,7 @@ export class CodexAppServerClient {
|
|
|
222
234
|
async threadFork(threadId, projectPath, title, options) {
|
|
223
235
|
const effort = options?.effort ?? this.options.effort;
|
|
224
236
|
const configUsesPermissionProfile = hasPermissionProfile(options?.config);
|
|
237
|
+
this.assertCodexSandboxAvailable(options?.config, options?.sandbox);
|
|
225
238
|
const response = await this.request('thread/fork', {
|
|
226
239
|
threadId,
|
|
227
240
|
cwd: projectPath,
|
|
@@ -767,6 +780,10 @@ export class CodexAppServerClient {
|
|
|
767
780
|
args.push('--config', `model_provider=${JSON.stringify(providerName)}`);
|
|
768
781
|
args.push('--config', `model_providers.${provider}.name=${JSON.stringify('EvolCore runtime gateway')}`);
|
|
769
782
|
args.push('--config', `model_providers.${provider}.wire_api=${JSON.stringify('responses')}`);
|
|
783
|
+
if (this.options.isolatedProvider) {
|
|
784
|
+
args.push('--config', `model_providers.${provider}.env_key=${JSON.stringify('CODEX_API_KEY')}`);
|
|
785
|
+
args.push('--config', `model_providers.${provider}.requires_openai_auth=false`);
|
|
786
|
+
}
|
|
770
787
|
if (useRuntimeProvider || this.options.baseUrl) {
|
|
771
788
|
args.push('--config', `model_providers.${provider}.base_url=${JSON.stringify(this.options.baseUrl || 'https://api.openai.com/v1')}`);
|
|
772
789
|
}
|