资讯动态

Cherry Studio API Gateway 为什么不再自动启动?显式开关、意图持久化与 Agent 许可流程完整解析

发布时间:2026/9/20 15:03:11 来源:尧图企业网站定制
Cherry Studio API Gateway 为什么不再自动启动显式开关、意图持久化与 Agent 许可流程完整解析【免费下载链接】cc-switchA cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build Hermes Agent. Only official website: ccswitch.io项目地址: https://gitcode.com/GitHub_Trending/cc/cc-switch我明明在设置里把它关了重启之后端口 23333 怎么又在监听——这是 Cherry Studio 用户在 issue #18521 里遇到的典型场景。API Gateway 是 Cherry Studio 内置的本地 HTTP 网关默认绑定127.0.0.1:23333为 OpenAI、Anthropic、Gemini 等协议客户端提供统一入口。旧版中它在设置页的开关从未真正生效只要存在任意 Agent每次启动它都会自行拉起用户手动关闭后还会被静默改回开启。本次 breaking change 把它改为显式开关 意图持久化并给 Agent 桥接场景加了一道许可consent流程。这次到底改了什么关闭即持久Agent 不再静默拉起场景旧行为新行为启动时机只要存在任意 Agent 就自动拉起仅当持久化enabled为true时启动用户在设置页关闭开关被静默改回开启关闭从不生效跨重启保持关闭本地端口不再监听Agent 模型必须经 Gateway 桥接运行时静默启动 Gateway先弹窗征求许可接受后才启动并持久化意图Code 页配置为 Cherry Gateway 的外部 CLI 工具启动时拉起有意保留仍启动时拉起这一变更对应 issue #18521由 PR #18523 修复完整记录在 2026-08-13-api-gateway-never-autostarts.md。值得注意的是 CLI 工具场景的保留是有意为之该场景依赖 Gateway 常驻属于显式选择而非隐式自启动。一个开关两套状态运行时状态与持久化意图如何重新划界旧缺陷的根因是运行时状态与持久化意图的脱节。用户点关闭只改了运行时状态enabled偏好被静默写回true更糟的是若某次偏好写入失败意图未落库enabled: true会残留到下一次启动端口随之重新打开。从源码注释看ApiGatewayService.ts 明确把这种持久化意图从未落库的运行时转换标注为 #18521 的根源。新实现重新划界持久化的feature.api_gateway.enabled偏好是期望状态的唯一来源启动时 Gateway 是否运行只取决于它与是否存在 Agent彻底解耦。服务在onInit订阅该偏好变化、onReady读取持久化值并驱动收敛收敛 把实际运行状态拉到期望状态// onInit任何偏好修改都触发收敛 application.get(PreferenceService).subscribeChange(feature.api_gateway.enabled, (enabled) { this.desiredEnabled enabled this.reconciler.request() }) // onReady启动时读取持久化意图 const config this.getCurrentConfig() this.desiredEnabled config.enabled await this.reconciler.flush()ApiGatewayService.ts启停统一走applyIntent意图先落库再动作。偏好写入若抛错调用方立即得知意图未生效从根上杜绝运行时停了、偏好还是true的漂移private async applyIntent(enabled: boolean): Promisevoid { await application.get(PreferenceService).set(feature.api_gateway.enabled, enabled) await this.converge(enabled) }ApiGatewayService.ts真正的activate/deactivate只由内部的LatestReconciler调用ApiGatewayService.ts。它是 level-triggered 的——以实际isActivated为基准比较期望与实际不一致才动作latest-wins——过渡中途反向切换时下一轮遵从最新意图两个操作者不会并发竞争造成状态漂移持续失败的转换如端口被占用只记录、不重试避免死循环刷日志。stop()还会区分stopped | deferred若仍有临时租约见下节意图已持久化清除但服务暂不关闭。Agent 想借道先举手桥接许可为什么先问再启部分模型不由 Anthropic 兼容端点原生服务Agent 会话必须经本地 Gateway 做协议翻译。判定集中在 agentApiGateway.ts 的requiresAgentGateway(providerId)目前当 provider 为 Cherry 云时返回必须桥接L14-L16。所有此类路由都经过resolveApiGatewayRuntime(sessionId)固定顺序为许可 → 收敛 → 密钥L54-L82许可看持久化意图不看运行态if (!config.enabled) throw new ApiGatewayNotRunningError()。源码注释L63-L66解释了原因Gateway 在启动绑定中、重启中或激活失败后会短暂不监听若以isRunning()为准会对早已启用的用户反复弹请启用的荒谬提示。// 许可检查依据持久化 enabled if (!config.enabled) { throw new ApiGatewayNotRunningError() }收敛而非隐式启动已启用但未运行时调用ensureRunning()。它与start()的关键边界在于绝不重新持久化意图ApiGatewayService.ts因此无法复活用户已禁用的 Gateway。密钥最后生成前两步都通过后才调用ensureValidApiKey()首次使用生成cs-sk-uuid并持久化失败的路由不会留下这个副作用。ApiGatewayNotRunningError携带i18nKey序列化后可在回合错误块中渲染本地化文案L46-L52。用户保持禁用时各运行时驱动Claude Code、DSh、Pi 等广播api_gateway.required事件并携带sessionId渲染端据此弹窗。两处后果要明确弹窗启用不会自动重发消息Gateway 就绪后需手动再发一次而接受即持久化未来启动默认拉起除非用户再次关闭。临时借用不打扰设置租约机制与运行态发布为何分离PDF 翻译这类瞬时消费者需要 Gateway 临时在跑却不应把enabled永久置真。acquireLease()/releaseLease()只增减leaseCount抬高有效运行目标desiredEnabled || leaseCount 0绝不改写desiredEnabledApiGatewayService.ts。租约只抬不写用户中途关闭不会切断正在运行的租约持有者租约放完后只要desiredEnabled为false协调器自动停服租约期间拒绝restart()避免重启打断瞬时任务。运行态则走另一条发布链路publishRunningState()把feature.api_gateway.running布尔写入 Shared Cache主进程是权威方渲染端通过useSharedCacheValue只读订阅useApiGateway.ts没有专门的拉取状态IPC。apiGatewayLoading初始为true、Shared Cache 就绪才置false防止 Agent 页面在值到达前闪现已停止的错误界面。设置页也会依据运行态在监听期间禁用端口/密钥编辑ApiGatewayService.ts。这正是运行态与意图态必须分离的原因意图回答用户想要什么运行态回答此刻实际发生了什么——租约期间两者天然不同步混写就会复现 #18521 式的漂移。 配置速查feature.api_gateway 偏好键与调试提示Gateway 配置全部位于feature.api_gateway.*命名空间由 v1 的redux/settings/apiServer.*经偏好迁移器迁移来源见 API Gateway 参考文档 与getCurrentConfig()/ensureValidApiKey()L272-L292。偏好键类型默认值说明feature.api_gateway.enabledbooleanfalse总开关期望状态唯一来源feature.api_gateway.hoststring127.0.0.1绑定地址feature.api_gateway.portnumber23333TCP 端口UI 限制 1000–65535feature.api_gateway.api_keystring \| nullnull首次激活自动生成cs-sk-uuid调试提示端口被占用这类启动失败会如实呈现在 IPC 结果与运行态中不再被静默复活掩盖。enabled键的写入只允许主进程在 start/stop 内部完成渲染端仅暴露start/stop/restart三个命令式 IPCschemas/apiGateway.ts且严禁回写——useApiGateway.ts 的注释指出#18521 中一次未 await 的第二写入正是漂移根源之一。三类角色各要做什么普通用户无需任何操作行为自动生效想关闭就在设置 → API Gateway 关一次它会保持关闭、端口保持关闭。Agent 用户首次运行必须桥接的模型会遇启用确认弹窗接受一次即持久生效注意 Gateway 就绪后需手动重发消息。Release 管理人员本变更修复 issue #18521Code 页配置为 Cherry Gateway 的外部 CLI 工具不受影响变更记录明确该场景仍会在启动时拉起 Gateway变更文档。防线在哪里四个回归测试守住的契约ApiGatewayService.test.ts命令与持久化意图必须同时落库偏好写入失败时报告失败而非停止serverShutdown.test.ts活动 SSE/MCP 流下stop()及时返回且isRunning() false客户端不被遗弃在无人服务的流上PiRuntimeConnection.test.tsGateway 禁用时正确广播api_gateway.requiredagentSessionWarmup.test.ts许可流程只调用ensureRunning、绝不调用start收敛不得重新持久化意图。延伸阅读API Gateway 参考文档HTTP 路由面、认证、请求流转与关键不变量agentApiGateway.tsrequiresAgentGateway、resolveApiGatewayRuntime与ApiGatewayNotRunningError服务生命周期文档BaseService、Activatable、ServicePhaselatestReconciler.tslevel-triggered / latest-wins 语义的实现变更记录原文本次行为变更的完整背景与 Release 注意事项。【免费下载链接】cc-switchA cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build Hermes Agent. Only official website: ccswitch.io项目地址: https://gitcode.com/GitHub_Trending/cc/cc-switch创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价