ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

OpenCreator app-server 常驻化实施指南:复用 `codex app-server --stdio` 消除重复进程启动

OpenCreator app-server 常驻化实施指南:复用 `codex app-server --stdio` 消除重复进程启动 OpenCreator app-server 常驻化实施指南复用codex app-server --stdio消除重复进程启动【免费下载链接】OpenCreatorFormerly KrillinAI. Open-source AI workspace for creators, powered by Codex. Create videos, images, voice, avatars, translations, and edits with Agents in one place.项目地址: https://gitcode.com/GitHub_Trending/kr/OpenCreator导读本文基于 OpenCreator 仓库的 实施计划文档完整还原app-server 常驻化这一架构改造的契约、设计与验收全过程让用户主动发起的对话复用一个由 Daemon 管理的常驻codex app-server --stdio消除同 profile 热路径中的重复进程启动、重复initialize与固定 MCP 初始化同时保证后台定时任务继续走一次性进程、手动对话权限不扩大、Daemon 退出不残留 Codex 子进程。读完本文你将掌握进程级凭证租约、Host 单 turn 状态机、全局 FIFO 串行队列、有界关闭升级等实现细节并能直接使用仓库中的测试命令复现全部验收证据。背景为什么要让 app-server 常驻在常驻化改造之前用户每发起一轮手动对话Daemon 都会调用startCodexAppServer启动一个全新的codex app-server --stdio子进程依次完成进程 spawn、initialize握手、线程 start/resume、固定 MCP 工具初始化后才执行 turn。同一 profile 下的连续对话因此反复承受冷启动开销。本计划的目标非常聚焦让用户手动运行复用同一个已初始化子进程将进程启动、initialize与 MCP 初始化从每轮热路径中移除而后台定时任务继续使用现有的一次性 app-server两者共享同一套协议与发布边界但不合并执行客户端。从源码看常驻路径的最终落点是两个新文件app-server-host-2026-07-28.ts进程级 Host与 persistent-app-server-executor-2026-07-28.ts单活动 job 执行器并配套进程凭证、动态工具注入与 RunManager 队列改造。下面的章节按契约 → 凭证 → 工具注入 → Host → 执行器 → 队列 → 关闭 → 验收的顺序展开。契约快照目标、非目标与需求规则目标让用户主动发起的 OpenCreator 对话复用一个由 Daemon 管理的常驻codex app-server --stdio消除同 profile 热路径中的重复进程启动、initialize和固定 MCP 初始化后台定时任务继续使用现有一次性 app-server。非目标明确不做的事不实现多 app-server 进程池或多 turn 并发。不将后台定时任务常驻化。不自动恢复或重放已经提交的 turn。不合并会话查询app-server-client与执行客户端。不接入codex app-server daemon/proxy、系统服务或全局 socket。不修改 Web/Desktop 页面、组件、样式或业务接口。不迁移数据库、项目或会话数据。需求与规则不可降低的执行约束ID优先级约束FR-1P0同 profile 的用户手动运行复用一个常驻执行 app-server单个 turn 完成后进程保持运行。FR-2P0cwd/model/sandbox/reasoning/approvalPolicy按运行发送项目切换不重启profile 改变时受控重启。FR-3P0新建/续接会话、事件输出、两档权限、审批和取消的外部语义保持不变。FR-4P0手动对话保留日程工具后台定时任务继续使用一次性进程和受限运行令牌。FR-5P0常驻进程异常只终止当前 run下一次手动运行自动创建新进程。BR-1P0常驻执行器同一时刻只有一个活动 turn后续 run 必须保持queued直到真正获得执行槽。BR-2P0已提交的turn/start不得自动重放profile 切换和进程替换只在当前 turn 结束后发生。NFR-1P0不扩大后台权限不产生 Web/Desktop 分叉Daemon 退出后不残留 Codex 子进程。NFR-2P1可追踪 app-server 的启动、初始化、复用、重启、退出原因及关键运行时间点。关键设计决策不得改变ID决定DEC-1用户手动运行走一个常驻执行器后台定时任务继续走现有一次性startCodexAppServer。DEC-2第一版由 RunManager 维护唯一 FIFO 串行队列执行器只维护唯一activeRun不实现并发事件路由表。DEC-3交互式进程使用进程级凭证凭证只有绑定当前活动 run 后才能授权空闲时拒绝 MCP 请求。DEC-4运行参数按 thread/turn 发送profile 作为进程键变化时关闭并重建进程。DEC-5崩溃、协议错误或 interrupt 失败时不重放 turn清除进程后由下一轮重新创建。其中 DEC-2 在代码中体现得十分明确执行器持有busy标志并在第二次start时直接抛错Persistent app-server executor is busy让双重排队成为测试可见的错误见 persistent-app-server-executor-2026-07-28.ts从而把队列所有权完整收敛到 RunManager 一处。进程凭证进程租约与活动 grant 的生命周期分离这是整个权限模型的核心。改造前的运行令牌是每轮签发、带五分钟活动 TTL 的常驻进程需要跨轮存活因此计划在AgentCapabilityTokenStore上新增进程租约process lease但不改变现有运行令牌的任何行为。计划给出的接口契约见文档进程凭证一节export type AgentCapabilityProcessLease { token: string; activate(input: { runId: string; threadId: string; createdBy: api; scopes: AgentCapabilityScope[]; }): AgentCapabilityGrant; deactivate(runId: string): boolean; revoke(): boolean; }; export type AgentCapabilityTokenStore { // 现有方法保持 issueProcess(input: { createdBy: api; maxScopes: AgentCapabilityScope[]; }): AgentCapabilityProcessLease; };对照实际源码 capability-token.ts实现与契约完全吻合并且activate额外接收processGeneration、jobId、projectId等上下文用于归属校验。核心约束包括两个生命周期租约 token 只在lease.revoke()、进程退出或 Storeclose()时失效不受五分钟活动 TTL 影响activate每次创建新的活动 grant已有未过期活动 grant 时必须拒绝重复激活抛CAPABILITY_CONTEXT_ACTIVE。scopes 必须是maxScopes的子集自动后台身份createdBy 非api不能创建进程租约issueProcess会直接拒绝。inactive 语义inspect/authorize对进程 token 返回当前活动 grant没有活动 grant 时抛出CAPABILITY_CONTEXT_INACTIVEHTTP 403。源码中该错误码与CAPABILITY_CONTEXT_ACTIVE、CAPABILITY_SCOPE_FORBIDDEN等并列定义在错误码联合类型中。过期只清绑定不清 token活动 grant 沿用现有 TTL过期只清除活动绑定同一 token 在下一轮可以重新activate这正是进程跨轮复用但权限逐轮收紧的关键。迟到清理隔离deactivate(runId)只有在 runId 与当前 grant 完全匹配时才清除旧 run 的迟到清理不得影响新 run。revoke 语义区分revokeRun(runId)对运行令牌保持撤销语义对匹配的进程租约只清除活动 grant不销毁租约。时序要求第一个 run 必须先activate再执行 spawn/initialize每个 run 的所有终态都在finally中调用匹配 runId 的deactivate。这套租约长寿、grant 短命的设计直接回应了风险项中进程凭证出现后台权限扩大或 run/thread 归属错误的熔断要求——空闲进程即使持有 token由于没有活动 grantMCP 请求一律 403。常驻日程工具注入动态 manifest 替代静态 enabled_tools常驻化的第二个难点是工具目录。一次性路径为每轮进程写死静态enabled_tools常驻进程跨轮存活后若沿用静态配置会把某一轮的工具目录固化到进程导致 conversation 与 schedule_task 之间工具串线。计划的解决方案是进程 MCP 配置不写静态enabled_tools每轮由allowedTools(api, thread)同时得到三样东西活动 grant 的 scopes排序后的工具名集合manifestKeyMCP HTTP route 本轮实际注册的工具集合。源码中进程注入的activate返回的正是manifestKey: JSON.stringify(scopes.slice().sort())见 run-injection.ts即以排序后的 scope 数组作为本轮工具目录的指纹。authorizeMcpRequest返回当前 grantcreateAgentScheduleMcpServer新增enabledTools输入只注册 grant scopes 对应的工具。Host 在 thread 已 start/resume、turn 尚未 start 时比较manifestKey首轮或 manifest 变化发送绑定 Codex 版本支持的config/mcpServer/reload等待成功后再发送turn/startmanifest 未变化直接复用已缓存工具目录不重复 MCP refreshrefresh 失败当前 run 失败并将 Host 标记为不可复用。计划的边界语义还包括conversation thread 在请求批准/完全访问权限之间切换不会改变日程 manifestschedule_task等 scope 变化会刷新工具目录但不得重启进程后台运行仍使用现有静态enabledTools和每轮令牌。文档同时把 Codex 侧实现定位到codex-main/codex-rs/app-server/src/request_processors/mcp_processor.rs与mcp_refresh.rs只读核验reload 为已加载 thread 刷新 MCP runtime/tool cache并在 TASK-0 中要求通过 Fake 请求先验证 reload 方法存在且返回成功。app-server Host进程级单 turn 状态机新增 app-server-host-2026-07-28.ts 承载一个已初始化子进程 JSON-RPC pending map只允许一个活动 turn。其类型契约如下export type CodexAppServerHost { readonly pid: number | undefined; run(input: CodexAppServerTurnInput): CodexAppServerProcess; close(reason?: string): Promisevoid; }; export function createCodexAppServerHost( input: CodexAppServerHostInput ): CodexAppServerHost;实际源码在run之上还增加了readonly started: Promisenumber与isReusable(): boolean并定义了完整的HostStatestarting | ready | turn_active | closing | failed | closed与计划中的状态机一一对应starting - ready - turn_active - ready | | | --------------------- closing - closed \- failed - closed每轮 job 的状态机为acquiring - thread_starting - mcp_refreshing仅 manifest 变化 - turn_start_written - turn_active - interrupting可选 - settled源码中ActiveJob的stage在实现时进一步细化为acquiring | thread_starting | mcp_refreshing | turn_preparing | turn_starting | turn_start_written | turn_active | interrupting | settled即在turn_start_written前后增加了准备阶段使stdin 实际写入成功这一不可重放边界更精确这是实施中自审修复的第二个边界问题见后文。Host 的关键状态规则每轮分配单调递增generationpending RPC 保存 generationturn/start写入 stdin 后即进入不可自动重放边界所有 response、notification 和 server request 必须匹配当前 generation审批和 turn 通知还必须匹配活动 threadId/turnId迟到或无法归属的 server request 返回错误通知丢弃并记录诊断不能进入下一 runinitialize、thread start/resume、MCP refresh、turn start、审批等待或 interrupt 任一阶段出现进程退出必须一次性拒绝全部 pending 和当前 jobJSON 解析错误、RPC 协议错误、interrupt 错误、interrupt 后未收到匹配turn/completed都把 Host 标记为不可复用并关闭只有收到当前 turn 的turn/completed含成功 interrupt 后的 interrupted 终态Host 才能回到 readyjob 的 resolve/reject/finalize 必须通过单一settleOnce禁止重复终态。源码中child.on(close)处理器对进程退出做了兜底flush 剩余 stdout frame、rejectWrites、rejectPending、对未 settled 的 activeJob 执行settleJobError并发出process_exited生命周期事件见 app-server-host-2026-07-28.ts。同时现有startCodexAppServer(input)改为兼容包装创建 Host、执行一轮、在结果 settle 后关闭 Host——后台任务和旧测试继续调用该函数行为不变。常驻执行器单活动 job、profile 重启与有界关闭新增 persistent-app-server-executor-2026-07-28.tsexport type PersistentAppServerExecution CodexAppServerProcess { started: Promise{ pid: number; reused: boolean; }; }; export type PersistentAppServerExecutor { start(input: PersistentAppServerExecutionInput): PersistentAppServerExecution; isBusy(): boolean; close(input?: { interruptGraceMs?: number; terminateGraceMs?: number; }): Promisevoid; };实现层的要点执行器只拥有当前 profile、Host、进程工具注入和唯一活动 job不再拥有第二套队列busy时拒绝第二个start。实际实现中close还额外提供invalidate(reason)并允许注入runtimeManager/runtimeInjector源码中的createPersistentAppServerExecutor已演进为基于AppServerRuntimeManager的 scope 化实现start内部通过runtimeManager.startTurn完成 turn并透出process_reused / process_started / run_assigned / run_cleared生命周期事件见 persistent-app-server-executor-2026-07-28.ts。每轮开始时先激活进程 grant再创建/复用 HostHost 完成 thread start/resume 后按manifestKey决定是否刷新 MCP再发送 turn。活动取消优先 interrupt失败时关闭 Host。profile 比较使用已验证的精确 profile 名称default始终归一为同一个进程键profile 切换时等待旧 Host 退出后再创建新 HostA→B→A 队列按顺序完成两次受控切换。close()幂等执行 interrupt → SIGTERM → SIGKILL 的有界升级默认interruptGraceMs: 1_000、terminateGraceMs: 2_000并等待 child close、lease revoke。计划要求通过结构化生命周期事件记录process_started、process_initialized、process_reused、mcp_refreshed、profile_restarted、process_exited、run_assigned、run_cleared——这 8 个事件在源码的PersistentAppServerLifecycleEvent联合类型中原样落地见 persistent-app-server-executor-2026-07-28.ts。RunManager 唯一 FIFO 队列排队、重排与取消RunManager 增加唯一的persistentRunQueue和runningPersistentRunId实现中还加入单调persistentSubmissionSequence全部规则如下所有符合常驻条件的手动 app-server run 在startRun时立即取得单调submissionSequence当前无 persistent run 时直接启动否则进入persistentRunQueue公开状态为 queued普通enqueue严格按 submissionSequence FIFOinterrupt_and_enqueue和显式steerRun是保留现有用户语义的唯一重排入口必须显式记录重排原因普通 run 不得越序源码中interrupt_and_enqueue会插入到第一个普通 enqueue 之前并触发对活动 run 的取消steerRun则把目标 queued run 移到队首同线程threadQueues不再接收 persistent 手动 run只继续服务 schedule、exec transport 和一次性回退路径resume mode、Codex thread ID、profile 和运行参数在 run 真正出队时重新解析保证同线程前一轮的绑定已经落库queuePosition只来自persistentRunQueuecancelRun能从唯一队列移除 queued run且不调用执行器、不发送 Codex 请求A1 执行中依次提交同线程 A2、另一线程 B1 时普通 enqueue 的执行顺序必须是 A1、A2、B1schedule run 或常驻执行器未启用时继续调用一次性 runner。源码判断常驻条件的逻辑位于 runs/manager.ts 的startRun附近runtimeTransport app-server且persistentAppServerExecutor存在且createdBy api且 thread 存在。对应的集成测试 run-manager.test.ts 名为preserves one global FIFO for persistent app-server runs across threads直接覆盖了文档中 AC-3 的核心断言。失败与回滚每类异常的处理路径计划的失败处理矩阵非常完整启动/initialize 失败当前 run 失败全部 pending 结算Host 和进程凭证清除。活动 turn 中进程退出当前 run 只失败一次下一个出队 run 创建新 Host。排队 run 取消从 RunManager 唯一队列移除不调用执行器。interrupt 请求成功且收到匹配 interrupted/completed 终态当前 run 取消Host 可复用。interrupt 失败、超时或无匹配终态Host 进入 failed执行 SIGTERM宽限期后仍存活则 SIGKILL并等待进程 close禁止重放。profile 改变当前 run 结束后关闭旧 Host 并等待退出再启动新 HostA→B→A 队列会按顺序完成两次受控切换。Daemon 关闭顺序9 步RunManager/执行器单一拥有子进程终止Server 标记 closing停止 scheduler 和新 run。RunManager 取消 persistent/thread queued run 并写入终态。RunManager 请求活动 run interrupt。执行器等待interruptGraceMs超时后 SIGTERM。再等待terminateGraceMs超时后 SIGKILL并等待 child close。当前 run 完成 finalization、日志落盘进程 grant deactivatelease revoke。RunManager close 返回后关闭会话codexSessionProvider。关闭 capability Store。最后关闭数据库。所有 close 操作必须幂等任一步错误不能跳过后续资源释放最终聚合并抛出首个关闭错误。无数据库迁移回滚只需将手动 run 路由恢复到保留的一次性 runner数据无需回滚。默认启用与紧急回退OPENCREATOR_PERSISTENT_APP_SERVER生产环境默认启用常驻手动路径仅提供一个紧急回退环境开关。源码证据在 main.tspersistentAppServerEnabled: process.env.OPENCREATOR_PERSISTENT_APP_SERVER ! 0,即只有显式设置OPENCREATOR_PERSISTENT_APP_SERVER0时才关闭常驻手动路径恢复为每轮一次性进程不增加 UI 设置。API Server 侧api/server.ts仅在默认 RunManager persistentAppServerEnabled ! falseruntimeTransport app-server三条件同时满足时创建常驻执行器启动层 startup.ts 默认置true。回退模式测试应证明手动 run 恢复每轮一次性进程且不改变 API 数据。诊断契约计划定义了稳定的PersistentAppServerLifecycleEventsource 固定为persistent_app_serverevent 为上文 8 个值含at、runId、pid、profile、generation、reasonrun 关联的 lifecycle 写入该 run 的diagnostics.json.appServer.lifecycle无 run 的最终关闭事件只输出结构化控制台日志。diagnostics 同时记录appServerPid、appServerReused、profile、submittedAt、executionStartedAt、turnStartSentAt、turnStartedAt、firstModelEventAt和turnStartWritten。两个口径需要特别注意首个模型事件只在首次归一化后的 reasoning/assistant/tool 业务事件出现时记录不能把turn/started当作模型事件lifecycle 和 diagnostics不得包含prompt、token、MCP bearer、env 或未脱敏 stderr——这也是测试断言does not persist process capability secret in meta, diagnostics, events or argv覆盖的内容。实施任务与 TDD 策略计划按 5 个任务TASK-0..TASK-5推进全部 TDD 策略为必须任务覆盖需求关键交付TASK-0契约核验确认 Plan 基线有效、Codex 绑定版本支持initialize/thread/start|resume/turn/start|interrupt/config/mcpServer/reloadTASK-1FR-4、NFR-1、DEC-3进程凭证租约、活动 run 权限映射、动态 enabledToolsTASK-2FR-1/2/5、BR-2、DEC-1/4/5Host、一次性 wrapper、单活动执行器TASK-3FR-1..5、BR-1/2、NFR-1RunManager 路由、唯一 FIFO、审批/续接兼容TASK-4NFR-1/2有界关闭、生命周期诊断、真实 Codex smoke、回退开关TASK-5全部全量回归 真实边界功能验收TASK-1 的代表性 RED 用例包括process lease is inactive until a run is activated and cannot exceed max scopes、reuses one process token across two sequential runs without leaking the previous actor、process token survives active grant expiry and can be activated again、late deactivate from run-1 cannot clear run-2。TASK-2 的 RED 用例以 Fake app-server 驱动reuses one initialized process for sequential turns with different cwd断言 spawn1、initialize1、turn2表驱动改变 model、sandbox、reasoning、approvalPolicy、cwd 和 manifest scopes 后断言同 PID、一次 initialize、payload 使用新值、manifest 变化只出现 MCP refresh以及restarts exactly once after normalized profile changesA→B→A旧新 PID 不重叠、drops late notifications from an older generation、interrupt terminal success keeps the Host reusable。TASK-3 的 RED 用例围绕全局 FIFOA1, A2, B1 ordinary submissions preserve one global FIFOA2 出队时读取 A1 刚写入的 Codex thread ID、排队取消不发送 thread/turn、interrupt_and_enqueue and steer are the only explicit reorder paths、routes api runs to the persistent executor and schedule runs to one-shot app-server。TASK-4 的 RED 用例覆盖有界关闭替身拒绝 interrupt 并忽略 SIGTERM 且存在 queued run断言 queued 先终态、SIGKILL 后 PID 不存在、日志落库、lease revoke、session/store/DB 顺序正确close is idempotent and releases remaining resources after an intermediate close erroruses one-shot manual execution only when OPENCREATOR_PERSISTENT_APP_SERVER0。实现中自审修复的五个边界问题计划记录的实施过程自审发现并修复了五个易错点对理解状态机设计很有价值cross-spawn成功时result.error可能为null错误判定边界。turn/start在 stdin 实际写入成功前被错误标记为已跨过不重放边界对应 job 阶段细化为turn_preparing/turn_starting。profile 切换等待旧 Host 退出时并发关闭可能在closing后创建替换 Host。同线程一次性 schedule run 完成后没有唤醒等待中的 persistent run。MCP refresh 期间取消成功 refresh 会被误判为 refresh 失败并杀掉健康 Host。验收矩阵与实测结果计划定义了 7 个 P0 验收用例AC-1..AC-7覆盖同 profile 多轮复用与参数透传AC-1、profile 切换受控重启AC-2、全局 FIFO 与事件隔离AC-3、审批/全权限/取消/续接及 Web/Desktop 一致AC-4、动态工具目录与后台权限隔离AC-5、各协议阶段失败与不重放AC-6、有界 Daemon 关闭AC-7。文档记录的实测门禁结果全部 PASS门禁实际结果Daemon 全量测试714 passed / 23 skipped仓库全量类型检查pnpm typecheckPASS真实 Codex Daemon smoke14/14Web production buildPASSDesktop 单元测试69/69Desktop packaged E2E10/10Desktop 真实 Codex E2E2/2差异格式检查git diff --checkPASS发布结论为本地功能与目录包验收通过可以进入签名发布流程同时明确两个遗留事项App 未签名本机无有效Developer ID Application身份不应直接作为正式签名包发布、本轮未执行 Git 提交或推送。AC 中 A1→A2→B1 全局 FIFO 的测试证据可直接在 run-manager.test.ts 中找到。验证命令速查以下命令均可在仓库根目录执行取自文档公共命令一节用于复现上述验收# Capability 测试进程凭证与权限隔离 pnpm --filter opencreator/daemon test -- test/unit/agent-capability-token.test.ts test/unit/agent-tool-run-injection.test.ts test/integration/agent-tool-api.test.ts # Runner 测试Host 复用与一次性 wrapper 回归 pnpm --filter opencreator/daemon test -- test/unit/codex-app-server-runner.test.ts test/unit/persistent-app-server-executor-2026-07-28.test.ts # RunManager 回归全局 FIFO、审批、续接 pnpm --filter opencreator/daemon test -- test/integration/run-manager.test.ts test/integration/approval-runtime.test.ts # Daemon 全量测试与类型检查 pnpm --filter opencreator/daemon test pnpm --filter opencreator/daemon typecheck pnpm typecheck # 真实 Codex smoke需要真实 Codex 运行环境 OPENCREATOR_RUN_REAL_CODEX_SMOKE1 pnpm --filter opencreator/daemon test -- test/smoke/real-codex-smoke.test.ts # Web/Desktop 回归 pnpm --filter opencreator/web build pnpm --filter opencreator/desktop test pnpm --filter opencreator/desktop package pnpm --filter opencreator/desktop verify:package pnpm --filter opencreator/desktop e2e:package注意真实 Codex smoke 与 Desktop 真实 Codex E2E 依赖真实 Codex 运行环境、账号或网络文档明确要求真实账号/网络不可用时明确标记 BLOCKED不得伪造完成。已接受风险与失败熔断本方案的特殊之处在于来源方案未获得实质性独立代码审核Reviewer 环境缺少文件读取能力用户知情批准后进入实施。因此文档明确把以下内容作为熔断项任一出现立即停止并返回方案修订不得通过放宽断言继续进程凭证出现后台权限扩大或 run/thread 归属错误排队 run 被错误显示为运行中或事件串线关闭顺序导致凭证提前失效或 Codex 子进程残留为实现常驻而改变 FR/BR/NFR/DEC/AC。偏差规则同样严格允许不改变职责的局部命名、测试夹具位置或帮助函数拆分必须记录原因不允许新增进程池、并发 turn、自动重放、前端平台分支、数据库迁移或旧 Codex 兼容层。新建文件必须遵守项目全局命名要求文件名末尾保留日期本计划新文件统一使用2026-07-28且不得还原或提交用户现有的图标、Desktop、Web 资源、Skill 和.tmp/修改。小结app-server 常驻化是 OpenCreator Daemon 的一次进程复用架构收敛通过进程租约与活动 grant 分离保证权限不扩大通过 manifestKey 驱动的 MCP refresh 保证工具目录逐轮准确通过 Host 单 turn 状态机与 generation 归属保证不重放、不串线通过 RunManager 唯一 FIFO 保证全局有序通过 interrupt→SIGTERM→SIGKILL 的有界升级保证不残留子进程。最终用户手动会话默认复用 Daemon 内唯一常驻codex app-server --stdioschedule 与紧急回退路径继续使用一次性 app-serverWeb/Desktop 平台分支为零、数据库零迁移OPENCREATOR_PERSISTENT_APP_SERVER0即可一键回退。【免费下载链接】OpenCreatorFormerly KrillinAI. Open-source AI workspace for creators, powered by Codex. Create videos, images, voice, avatars, translations, and edits with Agents in one place.项目地址: https://gitcode.com/GitHub_Trending/kr/OpenCreator创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表