oh-my-opencode 后台代理全局并发上限设计:maxBackgroundAgents 配置从 Zod Schema 到 ConcurrencyManager 落地的完整方案
oh-my-opencode 后台代理全局并发上限设计maxBackgroundAgents 配置从 Zod Schema 到 ConcurrencyManager 落地的完整方案【免费下载链接】oh-my-openagentOmO: Drop your tokens. Ultrawork. Done.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent本文基于仓库中的变更规格文档 code-changes.md完整讲解如何为 oh-my-opencode 的background_task配置新增全局并发上限maxBackgroundAgents从 Zod Schema 字段定义、校验测试、ConcurrencyManager全局计数器到BackgroundManager在任务启动、跟踪、完成、取消、报错全链路上的槽位获取与释放。读完本文你能掌握该项目的后台代理并发控制机制按模型/Provider 分层的 lane 限制 队列交接模式并理解一个全局资源上限类配置项从声明到运行时强制的完整设计路径。背景现有的按模型并发限制缺少全局兜底要理解这次变更的动机先看当前仓库中已经存在的并发控制实现。oh-my-opencode 的后台代理系统packages/omo-opencode包下的 background-agent 特性通过ConcurrencyManager限制每个模型/Provider同时运行的任务数。当前实现见 concurrency.tsgetConcurrencyLimit(model: string): number { const modelLimit this.config?.modelConcurrency?.[model] if (modelLimit ! undefined) { return modelLimit 0 ? Infinity : modelLimit } const provider model.split(/)[0] const providerLimit this.config?.providerConcurrency?.[provider] if (providerLimit ! undefined) { return providerLimit 0 ? Infinity : providerLimit } const defaultLimit this.config?.defaultConcurrency if (defaultLimit ! undefined) { return defaultLimit 0 ? Infinity : defaultLimit } return 5 }从源码结构看这是一套三级回退的 lane 机制modelConcurrency精确到provider/model全名→providerConcurrency按provider/model前缀切出的 provider 名→defaultConcurrency全局默认→ 硬编码兜底值 5。配置中把某一级设为0表示不限返回Infinityconcurrency.ts。acquire()的语义是限流即排队当某个 key 的计数达到上限时请求不会失败而是被压入Mapkey, QueueEntry[]等待队列concurrency.ts。release()释放槽位时优先把空位交接给队列中的等待者计数不变没有等待者才真正递减计数concurrency.ts。队列项使用settled标志防止已被 release 解决的条目再被cancelWaiters()重复拒绝这是典型的 double-resolution 防护模式concurrency.ts。这套机制的盲区正是本次变更要解决的问题所有限制都是按 lane的。一个用户在anthropic/claude-opus-4-6、openai/gpt-5、google/gemini三个 lane 各开 5 个任务时每个 lane 都没超限但整机上已经跑了 15 个后台代理——系统资源可能已经耗尽。官方文档 omo-json.md 中关于 senpi 侧global_concurrency的描述也印证了这一点OpenCodebackground_taskis unaffected (parity is a follow-up)——即 OpenCode 侧的全局上限尚属待补齐项。maxBackgroundAgents就是补齐这块的单一旋钮无论任务跑在哪个模型上同时运行的后台代理总数不得超过该值。变更一Zod Schema 新增 maxBackgroundAgents 字段规格文档针对的源文件路径写作src/config/schema/background-task.ts对应当前仓库中的 background-task.ts。规格中给出的完整 schema 快照如下包含新增的maxBackgroundAgents字段及其 JSDoc 注释import { z } from zod export const BackgroundTaskConfigSchema z.object({ defaultConcurrency: z.number().min(1).optional(), providerConcurrency: z.record(z.string(), z.number().min(0)).optional(), modelConcurrency: z.record(z.string(), z.number().min(0)).optional(), maxDepth: z.number().int().min(1).optional(), maxDescendants: z.number().int().min(1).optional(), /** Maximum number of background agents that can run simultaneously across all models/providers (default: 5, minimum: 1) */ maxBackgroundAgents: z.number().int().int().min(1).optional(), /** Stale timeout in milliseconds - interrupt tasks with no activity for this duration (default: 180000 3 minutes, minimum: 60000 1 minute) */ staleTimeoutMs: z.number().min(60000).optional(), /** Timeout for tasks that never received any progress update, falling back to startedAt (default: 1800000 30 minutes, minimum: 60000 1 minute) */ messageStalenessTimeoutMs: z.number().min(60000).optional(), syncPollTimeoutMs: z.number().min(60000).optional(), }) export type BackgroundTaskConfig z.infertypeof BackgroundTaskConfigSchema说明上述是规格文档中的 schema 快照用于展示新增字段的写法当前仓库 background-task.ts 实际还包含taskTtlMs、sessionGoneTimeoutMs、maxToolCalls、circuitBreaker等后续演进出来的字段且并发子字段名如maxDescendants对应当前的maxLiveDescendantsPerRoot已调整。本文以规格文档为准讲解maxBackgroundAgents的引入方式。三个设计要点z.number().int().min(1).optional()—— 完全复用maxDepth、maxDescendants的既有模式整数、下限 1、可选。可选意味着配置未提供时不报错运行时默认值 5 由ConcurrencyManager兜底见下文getMaxBackgroundAgents()。JSDoc 注释即文档—— 注释写明 default: 5, minimum: 1配置语义不依赖外部文档即可自解释。无需改动 barrel 导出—— 规格文档指出src/config/schema.ts已经export * from ./schema/background-task类型由z.infer自动推导加字段零侵入。变更二Schema 校验测试规格要求在 background-task.test.ts 中已有的syncPollTimeoutMsdescribe 块之后追加maxBackgroundAgents测试块覆盖合法值、下边界、低于下限、未提供、非整数五类场景describe(maxBackgroundAgents, () { describe(#given valid maxBackgroundAgents (10), () { test(#when parsed #then returns correct value, () { const result BackgroundTaskConfigSchema.parse({ maxBackgroundAgents: 10 }) expect(result.maxBackgroundAgents).toBe(10) }) }) describe(#given maxBackgroundAgents of 1 (minimum), () { test(#when parsed #then returns correct value, () { const result BackgroundTaskConfigSchema.parse({ maxBackgroundAgents: 1 }) expect(result.maxBackgroundAgents).toBe(1) }) }) describe(#given maxBackgroundAgents below minimum (0), () { test(#when parsed #then throws ZodError, () { let thrownError: unknown try { BackgroundTaskConfigSchema.parse({ maxBackgroundAgents: 0 }) } catch (error) { thrownError error } expect(thrownError).toBeInstanceOf(ZodError) }) }) describe(#given maxBackgroundAgents not provided, () { test(#when parsed #then field is undefined, () { const result BackgroundTaskConfigSchema.parse({}) expect(result.maxBackgroundAgents).toBeUndefined() }) }) describe(#given maxBackgroundAgents is non-integer (2.5), () { test(#when parsed #then throws ZodError, () { let thrownError: unknown try { BackgroundTaskConfigSchema.parse({ maxBackgroundAgents: 2.5 }) } catch (error) { thrownError error } expect(thrownError).toBeInstanceOf(ZodError) }) }) })测试命名沿用该文件既有的#given/#when/#then嵌套 describe 风格与maxDepth、maxDescendants、syncPollTimeoutMs的测试完全一致。其中两个细节值得注意0被判为非法与并发子字段不同0表示不限全局上限0没有合理语义——永远不许运行后台代理的场景应由用户干脆不启动代理来表达因此min(1)直接拒绝2.5触发 ZodError.int()约束保证上限是整数避免1.5 个代理这类歧义状态。变更三ConcurrencyManager 增加全局计数器核心实现改动集中在 concurrency.ts。规格文档给出的目标形态如下...处为未改动的既有方法当前仓库中已存在见 concurrency.tsimport type { BackgroundTaskConfig } from ../../config/schema const DEFAULT_MAX_BACKGROUND_AGENTS 5 /** * Queue entry with settled-flag pattern to prevent double-resolution. * * The settled flag ensures that cancelWaiters() doesnt reject * an entry that was already resolved by release(). */ interface QueueEntry { resolve: () void rawReject: (error: Error) void settled: boolean } export class ConcurrencyManager { private config?: BackgroundTaskConfig private counts: Mapstring, number new Map() private queues: Mapstring, QueueEntry[] new Map() private globalRunningCount 0 constructor(config?: BackgroundTaskConfig) { this.config config } getMaxBackgroundAgents(): number { return this.config?.maxBackgroundAgents ?? DEFAULT_MAX_BACKGROUND_AGENTS } getGlobalRunningCount(): number { return this.globalRunningCount } canSpawnGlobally(): boolean { return this.globalRunningCount this.getMaxBackgroundAgents() } acquireGlobal(): void { this.globalRunningCount } releaseGlobal(): void { if (this.globalRunningCount 0) { this.globalRunningCount-- } } getConcurrencyLimit(model: string): number { // ... existing implementation unchanged ... } async acquire(model: string): Promisevoid { // ... existing implementation unchanged ... } release(model: string): void { // ... existing implementation unchanged ... } cancelWaiters(model: string): void { // ... existing implementation unchanged ... } clear(): void { for (const [model] of this.queues) { this.cancelWaiters(model) } this.counts.clear() this.queues.clear() this.globalRunningCount 0 } getCount(model: string): number { return this.counts.get(model) ?? 0 } getQueueLength(model: string): number { return this.queues.get(model)?.length ?? 0 } }关键变化逐条拆解DEFAULT_MAX_BACKGROUND_AGENTS 5常量未配置时的全局上限与getConcurrencyLimit()的硬编码兜底 5 保持同一量级行为可预期globalRunningCount私有字段一个跨所有 lane 的单一计数器与 per-model 的counts: Map正交——两者可以同时生效实际并发受全局上限和所在 lane 上限中更紧的一方约束canSpawnGlobally()/acquireGlobal()/releaseGlobal()全局槽位的查/取/还三件套。与 per-model 的acquire()限流即排队不同全局槽位是立即失败语义——launch()里发现canSpawnGlobally()为 false 时直接抛错见下文不做排队等待。这个设计差异是合理的per-model 排队是为了让同 lane 任务公平轮转而全局资源耗尽时新任务再等下去只会堆积明确报错让用户等已有任务完成或调大配置才是更快的反馈releaseGlobal()的 0保护多调一次release不会让计数变成负数容忍竞态下的重复释放clear()重置全局计数manager 清理/关闭时全局计数与 per-model 状态一起归零防止幽灵槽位永久占用全局上限。变更四全局上限单元测试规格要求在 concurrency.test.ts 中追加独立的describe块用 given/when/then 注释风格覆盖默认值、配置值、上下限行为与重置describe(ConcurrencyManager global background agent limit, () { test(should default max background agents to 5 when no config, () { // given const manager new ConcurrencyManager() // when const max manager.getMaxBackgroundAgents() // then expect(max).toBe(5) }) test(should use configured maxBackgroundAgents, () { // given const config: BackgroundTaskConfig { maxBackgroundAgents: 10 } const manager new ConcurrencyManager(config) // when const max manager.getMaxBackgroundAgents() // then expect(max).toBe(10) }) test(should allow spawning when under global limit, () { // given const config: BackgroundTaskConfig { maxBackgroundAgents: 2 } const manager new ConcurrencyManager(config) // when manager.acquireGlobal() // then expect(manager.canSpawnGlobally()).toBe(true) expect(manager.getGlobalRunningCount()).toBe(1) }) test(should block spawning when at global limit, () { // given const config: BackgroundTaskConfig { maxBackgroundAgents: 2 } const manager new ConcurrencyManager(config) // when manager.acquireGlobal() manager.acquireGlobal() // then expect(manager.canSpawnGlobally()).toBe(false) expect(manager.getGlobalRunningCount()).toBe(2) }) test(should allow spawning again after release, () { // given const config: BackgroundTaskConfig { maxBackgroundAgents: 1 } const manager new ConcurrencyManager(config) manager.acquireGlobal() // when manager.releaseGlobal() // then expect(manager.canSpawnGlobally()).toBe(true) expect(manager.getGlobalRunningCount()).toBe(0) }) test(should not go below zero on extra release, () { // given const manager new ConcurrencyManager() // when manager.releaseGlobal() // then expect(manager.getGlobalRunningCount()).toBe(0) }) test(should reset global count on clear, () { // given const config: BackgroundTaskConfig { maxBackgroundAgents: 5 } const manager new ConcurrencyManager(config) manager.acquireGlobal() manager.acquireGlobal() manager.acquireGlobal() // when manager.clear() // then expect(manager.getGlobalRunningCount()).toBe(0) }) })七个用例合起来恰好锁死了全局计数的全部状态转换默认 5 → 配置 10 → 未达上限可 spawn → 达到上限被阻塞 → 释放后可再 spawn → 多余 release 不越界 →clear()归零。变更五BackgroundManager 全链路上的强制与释放计数器本身不会自动生效真正的难点在 manager.ts 中把所有任务生命周期事件与全局槽位的获取/释放正确配对。规格文档覆盖了两处入口检查和四处释放点。launch()启动前做全局检查创建后取槽async launch(input: LaunchInput): PromiseBackgroundTask { // ... existing logging ... if (!input.agent || input.agent.trim() ) { throw new Error(Agent parameter is required) } // Check global background agent limit before spawn guard if (!this.concurrencyManager.canSpawnGlobally()) { const max this.concurrencyManager.getMaxBackgroundAgents() const current this.concurrencyManager.getGlobalRunningCount() throw new Error( Background agent spawn blocked: ${current} agents running, max is ${max}. Wait for existing tasks to complete or increase background_task.maxBackgroundAgents. ) } const spawnReservation await this.reserveSubagentSpawn(input.parentSessionID) try { // ... existing code ... // After task creation, before queueing: this.concurrencyManager.acquireGlobal() // ... rest of existing code ... } catch (error) { spawnReservation.rollback() throw error } }三个设计细节报错信息自带运维指引错误消息包含当前运行数、上限值并直接提示等待现有任务完成或增大background_task.maxBackgroundAgents用户无需查文档即可自救检查放在reserveSubagentSpawn之前全局上限被拒时不产生任何 spawn 预留避免无谓占用父会话的子代理名额仓库中该预留机制见 subagent-spawn-limits.tsacquireGlobal()在任务创建成功后、入队前调用且catch分支回滚 spawn 预留——确保创建失败的任务不占全局槽位。trackTask()外部任务注册同样受全局上限约束async trackTask(input: { ... }): PromiseBackgroundTask { const existingTask this.tasks.get(input.taskId) if (existingTask) { // ... existing re-registration logic unchanged ... return existingTask } // Check global limit for new external tasks if (!this.concurrencyManager.canSpawnGlobally()) { const max this.concurrencyManager.getMaxBackgroundAgents() const current this.concurrencyManager.getGlobalRunningCount() throw new Error( Background agent spawn blocked: ${current} agents running, max is ${max}. Wait for existing tasks to complete or increase background_task.maxBackgroundAgents. ) } // ... existing task creation ... this.concurrencyManager.acquireGlobal() // ... rest unchanged ... }trackTask()是外部来源任务非launch()直接创建的登记入口。已存在的 taskId 走幂等的重注册逻辑直接返回不重复取槽新任务则与launch()完全一致地受全局上限约束。两个入口共用同一检查逻辑保证了不管任务从哪条路径进入管理器全局计数口径一致。tryCompleteTask()完成路径释放槽位private async tryCompleteTask(task: BackgroundTask, source: string): Promiseboolean { if (task.status ! running) { // ... existing guard ... return false } task.status completed task.completedAt new Date() // ... existing history record ... removeTaskToastTracking(task.id) // Release per-model concurrency if (task.concurrencyKey) { this.concurrencyManager.release(task.concurrencyKey) task.concurrencyKey undefined } // Release global slot this.concurrencyManager.releaseGlobal() // ... rest unchanged ... }注意释放的顺序与配对先释放 per-model 的concurrencyKey槽位释放即可能把 lane 空位交接给等待者再释放全局槽位task.concurrencyKey置undefined防止后续路径重复释放同一 lane 槽位。cancelTask()取消路径释放槽位pending 任务除外async cancelTask(taskId: string, options?: { ... }): Promiseboolean { // ... existing code up to concurrency release ... if (task.concurrencyKey) { this.concurrencyManager.release(task.concurrencyKey) task.concurrencyKey undefined } // Release global slot (only for running tasks, pending never acquired) if (task.status ! pending) { this.concurrencyManager.releaseGlobal() } // ... rest unchanged ... }这里有一个关键的不对称处理pending状态的任务不释放全局槽位因为尚未进入 per-model 队列、真正开始运行的任务从未执行过acquireGlobal()——对 pending 任务调用释放会造成计数漂移。这个只有 running 任务才持有全局槽位的约定是整条释放链正确性的基石。session.error 与 prompt 错误路径异常也要还槽任务因会话级错误终止时if (event.type session.error) { // ... existing error handling ... task.status error // ... if (task.concurrencyKey) { this.concurrencyManager.release(task.concurrencyKey) task.concurrencyKey undefined } // Release global slot this.concurrencyManager.releaseGlobal() // ... rest unchanged ... }startTask()内部 prompt 请求失败含模型建议重试的 catch 分支同样处理promptWithModelSuggestionRetry(this.client, { ... }).catch((error) { // ... existing error handling ... if (existingTask) { existingTask.status interrupt // ... if (existingTask.concurrencyKey) { this.concurrencyManager.release(existingTask.concurrencyKey) existingTask.concurrencyKey undefined } // Release global slot this.concurrencyManager.releaseGlobal() // ... rest unchanged ... } })如果漏掉这两个异常路径一次 provider 报错就会让全局槽位永久泄漏跑满上限后所有新任务都会被Background agent spawn blocked拒绝且永不恢复——这正是规格文档在配套 PR 描述中强调的Release global slots on task completion, cancellation, error, and interrupt to prevent slot leaks见 pr-description.md。变更汇总与验证方式规格文档给出的最终统计文件新增行数修改行数src/config/schema/background-task.ts20src/config/schema/background-task.test.ts~500src/features/background-agent/concurrency.ts~251clear()src/features/background-agent/concurrency.test.ts~700src/features/background-agent/manager.ts~200总计约 167 行新增、1 行修改横跨 5 个文件路径对应仓库中packages/omo-opencode/前缀下的同名文件。验证命令按配套 PR 描述执行bun test src/config/schema/background-task.test.ts # schema 校验 bun test src/features/background-agent/concurrency.test.ts # 全局上限 bun run typecheck bun run build用户侧的配置用法对应.opencode/oh-my-opencode.jsonc{ background_task: { maxBackgroundAgents: 10 // default: 5, min: 1 } }小结一个全局上限配置项的正确姿势这套变更示范了在 oh-my-opencode 这类插件架构里新增资源类配置的完整方法论Schema 层z.number().int().min(1).optional()可选字段 明确下限默认值不在 schema 硬编码留给运行时运行时层在ConcurrencyManager中引入与 per-model 计数正交的globalRunningCount提供查/取/还三接口且release带越界保护、clear()随 manager 生命周期归零强制层入口launch()/trackTask()统一检查并立即失败报错信息含自救指引出口完成、取消、会话错误、prompt 失败四条释放路径与acquireGlobal()严格配对且明确pending 任务不持有全局槽位的不变量测试层schema 五类边界用例 计数器七个状态转换用例两层测试独立可回归。需要说明的是规格文档位于.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/目录属于 PR 工作流工作区中产出的变更设计当前仓库主干代码background-task.ts、concurrency.ts尚未包含maxBackgroundAgents字段本文将其作为该功能的设计规格来解读实际合入状态请以仓库当前代码为准。【免费下载链接】oh-my-openagentOmO: Drop your tokens. Ultrawork. Done.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

YOLO铁轨裂纹检测数据集:工业视觉缺陷检测的完整解决方案

YOLO铁轨裂纹检测数据集:工业视觉缺陷检测的完整解决方案

简介:本资源是面向计算机视觉初学者与轨道交通智能运维实践者的YOLO铁轨裂纹检测专项数据集,解决真实工业场景下小目标裂纹识别的数据匮乏与标注格式适配难题。压缩包共2000个文件,含1000张高质量实地采集铁轨图像,配套1000份VOC&…

2026/10/31 23:09:59 阅读更多 →
3步用自然语言查数据库:Vanna 文本转SQL实操指南

3步用自然语言查数据库:Vanna 文本转SQL实操指南

3步用自然语言查数据库:Vanna 文本转SQL实操指南 【免费下载链接】vanna 🤖 Chat with your SQL database 📊. Accurate Text-to-SQL Generation via LLMs using Agentic Retrieval 🔄. 项目地址: https://gitcode.com/GitHub_T…

2026/10/25 17:36:34 阅读更多 →
UNIAPP小程序iOS音频静音问题七层修复方案

UNIAPP小程序iOS音频静音问题七层修复方案

简介:知了配音小程序源码UNIAPP-Cloud前后端源码,是一套面向个人开发者与Vue初/中级学习者的小程序商业项目实战资源,旨在帮助用户快速构建跨平台(微信、支付宝等)配音类应用,并实现广告变现闭环。资源共77…

2026/10/28 20:31:24 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/31 0:19:11 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/31 10:20:19 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/31 10:20:23 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/31 0:59:28 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/31 10:30:19 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/31 9:29:43 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 18:03:41 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 11:00:40 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 0:09:01 阅读更多 →