# Cetas > A coding agent for your terminal, editor, and scripts. Index: https://colmugx.github.io/cetas/llms.txt # 自动化 > 一次进程调用只跑一个用户回合,适合调用方是脚本、CI 或流水线。 Source: https://colmugx.github.io/cetas/automation/ · Markdown: https://colmugx.github.io/cetas/automation/index.md `cetas-run` 是一次性入口:一次进程调用,只跑一个用户回合。它和终端、编辑器入口组合同一个内核,适合"调用方是脚本而不是人"的场景。 ## 命令形状 ```text cetas-run [--model ] [--effort ] [--session ] [--yolo | --permission ] [--stream] [--verbose] [--show-thinking] [--jsonl] [-- ""] ``` 任务写在 `--` 之后。如果 argv 里没有任务,Cetas 会从 stdin 读恰好一行。另外两种形式: ```text cetas-run --login [provider] cetas-run --help | -h | --version ``` help 和 version 不写配置、不读 stdin、不联系任何供应商。 ## 输出契约 文本模式下,stdout 上只有答案,别的一律不掺。诊断按固定规则分流,这也是它能被管道处理的原因: | 模式 | stdout | stderr | | --- | --- | --- | | 默认 | 最终答案 | 会话元数据、生命周期标记、审批提示 | | `--stream` | 答案增量,边到边发 | 事件与标记 | | `--verbose` | 答案 | 事件与标记(更啰嗦) | | `--show-thinking` | 答案 | 推理过程,然后是事件 | | `--jsonl` | 结构化事件流 | 标记 | `--jsonl` 优先于所有文本模式。 ## 会话 不带 `--session` 时,每次调用都会新建一个会话 id,并在 stderr 上报出来。用 `--session ` 接着跑: ```bash cetas-run -- "讲一下这个仓库" cetas-run --session cetas-42 -- "现在把挂掉的测试修好" ``` 这是同宿主内的续接,不代表一个对话能在不同入口之间搬 —— 见[入口(Surfaces)](/cetas/concepts/surfaces/)。 ## 权限 `--permission` 接受 `readonly`、`workspace_write`、`interactive`、`auto`。`--yolo` 是无人值守模式,不能和 `--permission` 同时用。 `--model` 和 `--effort` 是本次运行内的覆盖:不落盘,所以定时任务不会悄悄改掉下一个人打开终端时看到的配置。 ## 退出码 | 码 | 含义 | | --- | --- | | `0` | 回合完成 | | `1` | 跑完了但失败 | | `2` | 启动、用法或登录失败 | 把 `1` 和 `2` 分开,是为了让管线能重试真正的失败,而不会把一个配置错误无限重试下去。 ## 配置 供应商配置和凭据来自共享 home,通常是 `/.cetas/`;`CETAS_HOME` 覆盖的是平台 home(也就是 `.cetas` 的**父目录**,不是它本身)。凭据和其他入口共用:已经登录过了,那就直接跑。 机器上没有终端会话时,原生构建可以用 `cetas-run --login` 完成首次登录。 ## 从 Mooncakes 运行 runner 同时以 Mooncakes 模块发布: ```bash moonx colmugx/cetas-run -- -- "把挂掉的测试修好" moonx colmugx/cetas-run -- --session -- "继续" ``` ## 在 CI 里 两条让自动化稳定运行的习惯: - 锁住装的版本(`npm install -g @posoco/cetas@`),升版本是一个有意的动作 —— 升之前先读[更新日志](/cetas/changelog/)。 - 审阅类、汇报类的任务用 `--permission readonly`;这样一次意外的写尝试会硬停,而不是悄悄变成一次提交。 # 概念 > 概念区回答「它是什么」:目前只讲一件事——入口,也就是终端、编辑器与自动化怎么组合同一个 agent。 Source: https://colmugx.github.io/cetas/concepts/ · Markdown: https://colmugx.github.io/cetas/concepts/index.md 概念区回答"它是什么"。目前只有一篇:[入口(Surfaces)](/cetas/concepts/surfaces/) —— 终端、编辑器、自动化怎么组合同一个 agent。 # 入口(Surfaces) > JS 和 Native 两种终端实现,以及独立的 ACP/Run 入口。 Source: https://colmugx.github.io/cetas/concepts/surfaces/ · Markdown: https://colmugx.github.io/cetas/concepts/surfaces/index.md Cetas 有三种**使用场景**——终端、编辑器和自动化;其中终端有 **JS 和 Native 两种实现**。默认推荐 npm 发布的 Cetas JS,Native 则是 Go/Bubble Tea 终端的第二选择,两者共享 MoonBit Cetas/Posoco 内核。 | 实现 / 入口 | 交互方式 | 安装或分发 | | --- | --- | --- | | **终端 · JS(首选)** `cetas-js` | 功能完整的交互式终端,包括 Board 等 JS 专属功能 | `npm install -g @posoco/cetas` | | **终端 · Native(第二选择)** `cetas-native` | Go/Bubble Tea v2,功能依宿主实现而不同 | Homebrew(macOS/Linux)、Scoop(Windows)或[发布文件](/cetas/getting-started/installation/) | | **编辑器 · ACP** `cetas-acp` | stdio ACP 服务,适配 Lody、Zed | 单独下载 `cetas-acp-*` | | **自动化 · Run** `cetas-run` | 每进程一个任务 | 单独下载 `cetas-run-*` | ## 共享的部分 各入口基于相同的内核,通常共享 [Cetas Home](/cetas/configuration/cetas-home/) 下的供应商设置、凭据和会话文件,但**不代表** UI 或跨入口会话操作完全一致。 ## 不同的部分 - JS 是功能覆盖最完整的终端;Pi/Node/Bun 集成及 Board 工作流目前不在 Native 中。 - Native 使用 Go 终端和 MoonBit Runtime(Unix 静态桥接,Windows 相邻 DLL),不需要 Node.js。 - ACP 单独服务于编辑器,由编辑器负责交互和审批 UI;无需安装完整 Native 就能使用。 - Run 专为脚本/一次性任务设计,也能单独下载。 - JS 和 Native 都可能注册名为 `cetas` 的命令,取决于 `PATH` 的先后顺序。 跨入口续接会话并不是受支持的契约。各平台安装方式见[安装与首次运行](/cetas/getting-started/installation/)。 # 配置 > 配置 Cetas 的三条路:会话里用一句话让 agent 代写、用命令改选择项,或按参考手写 settings 文件。 Source: https://colmugx.github.io/cetas/configuration/ · Markdown: https://colmugx.github.io/cetas/configuration/index.md ## 先试最省事的一条路 装好后直接在会话里描述你要的改动,agent 替你写 settings: ```text 加一个叫 my-gateway 的供应商,接到 https://llm.internal.example/v1, 声明模型 qwen3-32b,然后把它设成我的模型。 ``` 改完可以让它把 diff 给你看。供应商条目、模型元数据、子代理 kind、工作流预算,都能这么配——多数配置到这一步就完成了,见[用对话做配置](/cetas/configuration/natural-language/)。 ## 选择器覆盖的,用命令 `/login`、`/model`、`/decision`、`/effort` 写的是当前供应商期望的形状,不用你学 schema。命令清单在[命令速查](/cetas/reference/commands/)。 ## 手写文件的参考页 要逐项核对字段、在机器之间复制配置、或者给一批环境开通时,下面这些页面按 settings.json 的结构组织: - [Settings 参考](/cetas/reference/settings/) —— settings.json 的完整字段:每个 key、类型、默认值,按嵌套层级展开; - [供应商](/cetas/configuration/providers/) —— 内置供应商 id 与登录; - [模型](/cetas/configuration/models/) —— 槽位、`/model` 与 `/decision`; - [自定义与私有化模型](/cetas/configuration/custom-models/) —— 私有端点与网关的条目形状; - [子代理](/cetas/configuration/subagents/) —— kind 定义与工具白名单; - [权限](/cetas/configuration/permissions/) —— agent 能碰什么; - [技能](/cetas/configuration/skills/) —— 按需加载可复用的指令包; - [MCP](/cetas/configuration/mcp/) —— 接入外部工具服务器; - [Cetas Home](/cetas/configuration/cetas-home/) —— 目录本身。 ## 什么共享,什么不共享 共享一个 home 意味着所有入口读同一份配置、凭据和会话库。但它**不**意味着所有入口行为一致:终端有选择器,编辑器有 ACP 配置项,runner 走命令行参数。每个入口的页面会写清它支持什么。 在某个入口做的选择,下一个入口看得见:终端里的 `/model`,就是编辑器下次启动时恢复的那个。 > **改动在下一个会话生效** > > 系统提示每个会话组装一次,之后冻结。会影响提示的配置 —— 指令、供应商身份、技能目录 —— 要等你开一个新会话才生效;`/model`、`/effort` 这类选择则立刻生效。 # Cetas Home > Cetas 只解析一个 home 目录存放持久状态:配置、凭据、缓存与会话都在这里,三种入口读的都是它。 Source: https://colmugx.github.io/cetas/configuration/cetas-home/ · Markdown: https://colmugx.github.io/cetas/configuration/cetas-home/index.md Cetas 只解析一个 home 目录来放持久状态。你所有的配置都在这里,所有入口都读它。 非空的 `CETAS_HOME`(环境变量)会覆盖平台用户 home;否则用平台 home(Windows 上是 `USERPROFILE`,然后 `HOMEDRIVE` + `HOMEPATH`;其他平台是 `HOME`),只有在都解析不出来时才退回当前目录。本文档用 `` 指这个解析出来的用户 home,持久状态的根是 `/.cetas`: ```text /.cetas/ ├── settings.json # 供应商、选择项、工作流、子代理 ├── credentials/ # 由 /login 写入 —— 不要手改 ├── model_lists.json # 拉到的模型目录,按供应商分开 ├── mcp.json # MCP 服务器 ├── sessions/ # 按客户端分开的会话记录 └── debug/ # 只在开了 CETAS_DEBUG_* 时出现 ``` `debug/` 默认不会创建:只有打开 `CETAS_DEBUG_WIRE` 或 `CETAS_DEBUG_MCP_CATALOG` 才出现。 > **覆盖的粒度** > > `CETAS_HOME` 替换的是**父级** home,不是 `.cetas` 目录本身。 > `CETAS_HOME=/tmp/cetas-user` 会把状态放进 `/tmp/cetas-user/.cetas/`。 ## 哪些入口认这个覆盖 | 入口 | `CETAS_HOME` | | --- | --- | | 编辑器(`cetas-acp`) | 认 | | 自动化(`cetas-run`) | 认 | | 终端(`cetas` / `cetas-bun`) | **不读** —— 直接解析平台 home | 这一点在写脚本之前值得知道:在一台你为了隔离工作而设了 `CETAS_HOME` 环境变量的机器上,终端入口不认它,仍然解析平台 home 下的 `.cetas`。排查"配置不见了"之前,先确认这个会话实际用的 home。 ## 这里放了什么,为什么共享 模型选择、凭据、MCP 配置、缓存、以及存下来的会话,共同构成了跨入口的同一个 Cetas 身份 —— 这份共享正是重点。共享状态并不承诺行为一致:每个入口有自己的交互模型、自己的续接能力。见[入口(Surfaces)](/cetas/concepts/surfaces/)。 项目也可以使用文档中写明的项目级配置 —— 例如 `/.mcp.json` 覆盖用户级 MCP 文件,以及 `/.cetas/agents/` 放项目作用域的子代理 kind。 ## 备份 把目录整个复制走就行。`settings.json` 和 `sessions/` 是最值得留的;`credentials/` 也要一起搬,但要当密钥库对待;`model_lists.json` 只是缓存,会自己重建。 # 自定义与私有化模型 > 把 Cetas 接到私有端点、企业网关或自建部署上。 Source: https://colmugx.github.io/cetas/configuration/custom-models/ · Markdown: https://colmugx.github.io/cetas/configuration/custom-models/index.md 团队很少会拿公网 API 来落地编码 agent。常见的形态是:你们已经跑着模型,前面架一个网关,key 由基础设施管而不是每个开发者自己管。Cetas 把这种用法当作一等供应商对待。 ## 工作原理 `providers` 里每一个没有被内置供应商占用的 key,都会变成一个 **自定义供应商**。不需要注册、不需要写插件:key 本身就是供应商 id,而且它和内置供应商同等对待 —— `/login`、`/model`、目录刷新、模型缓存、编辑器入口全都认得它。端点说哪种协议,由条目里的 `protocol` 声明。 ## 最小配置 ```json { "providers": { "my-gateway": { "base_url": "https://llm.internal.example/v1", "api_key": "sk-...", "models": [ { "id": "qwen3-32b", "context_window": 131072 } ] } } } ``` - `base_url` —— 必填。服务端要求 `/v1` 时就带上;大多数 OpenAI 形状的服务端已经把版本号写进 base URL。 - `api_key` —— 实际使用中必填。也可以不写在这里,改用 `/login my-gateway`,凭据会落到 `/.cetas/credentials/`,密钥不进 settings 文件。 - `models` —— 必填,且不能为空。每个条目要有 `id`,id 不能重复。 `endpoint_prefix` 是给"`base_url` 只写了裸主机"(`http://10.0.0.4:8080`)而 API 挂在 `/v1` 下的情况准备的。能把前缀写进 `base_url` 就写进去,这一项留空。 ## 选择协议 自定义端点说三种协议之一: | `protocol` | 请求 | 协议 | | --- | --- | --- | | `chat_completions`(缺省) | `POST {base_url}{endpoint_prefix}/chat/completions` | OpenAI Chat Completions | | `responses` | `POST {base_url}{endpoint_prefix}/responses` | OpenAI Responses API | | `messages` | `POST {base_url}{endpoint_prefix}/messages` | Anthropic Messages API | ```json { "providers": { "claude-proxy": { "base_url": "https://api.anthropic.com", "endpoint_prefix": "/v1", "protocol": "messages", "api_key": "sk-ant-...", "models": [{ "id": "claude-sonnet-5", "context_window": 200000 }] } } } ``` - 不写 `protocol` 就是 `chat_completions`:协议出现之前写的条目,行为一个字节都不变。 - 路径后缀接在 `base_url` + `endpoint_prefix` 之后。版本段二选一写:写进 `base_url`(`https://llm.internal.example/v1`),或者裸主机配 `endpoint_prefix: "/v1"` —— 别两边都写。 - `protocol` 是供应商级的,`models[]` 的每一条都可以覆盖它,所以「一个端点、几个模型系列各说不同协议」仍然是一个供应商 id。 - 写了不认识的值会明确报错并列出可选值,**不会**退化成 chat 协议:退化的结果是把请求发到错误形状的端点上,然后收到一个看不懂的 `400`。 ### 凭据放在哪 `auth` 决定 key 怎么上线: | `auth` | 效果 | | --- | --- | | `auto`(缺省) | `chat_completions`/`responses` 用 `Authorization: Bearer`;`messages` 用 `x-api-key` 加 `anthropic-version: 2023-06-01` | | `bearer` | 所有协议都用 `Authorization: Bearer` —— 给用 Bearer 挡在 Messages 前面的网关 | | `x_api_key` | 所有协议都用 `x-api-key` | ### 各协议的推理档位 档位的含义到处一样 ——「这个模型该想多深」—— 但每条协议写法不同,而且不会给一个不知道刻度的端点编数字: - `chat_completions` —— 顶层 `reasoning_effort`,原样发出。 - `responses` —— `reasoning.effort`;选了档位就不再发 temperature,推理端点会拒。 - `messages` —— `thinking: {"type": "enabled"}`。档位名字**不会**被换算成 `budget_tokens` 数字。 - `off` —— 哪条协议都不发,端点用自己的默认值。 `responses` 还是无状态调用(`store: false`),不回放 reasoning items:通用端点并不声明 encrypted reasoning 契约。 ### 输出上限 `max_output_tokens`(正整数,缺省 `8192`)是 `messages` 协议上的 `max_tokens`,该字段必填。回合自己带了上限就以回合为准,这一项只补缺口。 ## 声明模型能力 选择器只能列出你声明过的东西。除了 `id`,其余全是可选项,而**留空比猜一个更安全**: | 字段 | 写在 | 作用 | | --- | --- | --- | | `context_window` | 模型 | 容量(token);不写则该模型不做自动压缩 | | `compact_threshold` | 模型 | 触发比例,需满足 `> 0` 且 `<= 1`(默认 `0.88`) | | `image_input` | 模型或供应商 | 接受图像输入;供应商级作为其模型的默认值 | | `reasoning_effort` | 模型或供应商 | 固定一个档位 —— 不出现选择器 | | `reasoning_efforts` | 模型或供应商 | 选择器里要列出的档位 | ```json { "providers": { "my-gateway": { "base_url": "https://llm.internal.example/v1", "models": [ { "id": "qwen3-235b", "context_window": 262144, "compact_threshold": 0.85, "reasoning_efforts": ["low", "medium", "high"], "image_input": false } ] } } } ``` ## 安全与稳定性 - 优先用 `/login my-gateway` 而不是内联 `api_key`:凭据在 `/.cetas/credentials/`,不会跟着文件被粘进工单。 - 拒绝 `prompt_cache_key` 的网关也能用:Cetas 会在本进程内记住这次拒绝,后续不再发送,而不是让整个回合失败。 - 自定义供应商**不会**从任何公开模型库刷新。它的目录就是你声明的那些 —— 这也正是为什么写错的 `context_window` 会安静地拖低压缩质量,而不会报错。 ## 验证 ```text /login my-gateway /model ``` 然后发一条消息。如果 `/model` 是空的,要么这个供应商没组装起来(检查 id 是否合法、是否撞了内置 id),要么 `models` 数组被拒绝了 —— 写坏的段会明确报错,而不会被修补。 同一份配置编辑器入口和 runner 直接继承,不需要每个入口重配一遍。内置 id 的优先级见[供应商](/cetas/configuration/providers/)。 # 接入 Magpie 网关 > 从启动网关到跑通一次推理。 Source: https://colmugx.github.io/cetas/configuration/magpie/ · Markdown: https://colmugx.github.io/cetas/configuration/magpie/index.md Magpie 是跑在你自己机器或内网里的模型网关:模型、账号、密钥都在网关那边管,Cetas 只负责连上去、选一个模型、开始干活。 Cetas 原生支持 Magpie:`/manager` 在供应商集合与 Magpie 之间切换,`/model` 选对话模型与推理档位,`/quota` 看配额,`/status` 报网关与目录状态,`/login` 把凭据写进共享凭据库。下面按一条主线走完:启动网关 → 让 Cetas 连上 → 切管理器 → 选模型 → 验证可用,每一步都写清「看到什么才算过」。 > **这一层归 Magpie** > > 供应商选择、上游回退、配额与计价都属于 Magpie,Cetas 不重复实现这一层;`/quota` 和用量里的数字是网关报的,Cetas 不估算、不补齐——缺价格或缺缓存信息时宁可留空。同一会话内,Cetas 给网关的每个推理请求都带上 `X-Magpie-Session`,让这次会话的路由保持一贯。你能决定的只有三件事:连哪个网关、用哪个模型(含推理档位)、什么时候刷新目录。 ## 1. 启动网关,先确认它活着 Magpie 网关是独立进程,默认地址 `http://127.0.0.1:3425`。它的安装、部署与运维按 Magpie 自己的文档来;本页只负责确认一件事:Cetas 能看见它。 两种形态,要准备的东西不一样: - **本地网关**:跑在回环地址上,Cetas 用内置的本地应用令牌访问(`Authorization: Bearer magpie-posoco`),你不用准备密钥。 - **远程网关**:需要网关密钥;地址必须是 HTTPS origin 或回环 HTTP origin,其他形状在 Cetas 这一侧就被拒:`gateway must be an HTTPS origin or loopback HTTP origin`。 **成功标志**:`curl http://127.0.0.1:3425/api/hello` 返回一个 JSON 对象,其中 `"name"` 的值是 `"magpie"`;`curl http://127.0.0.1:3425/v1/models` 返回带 `data` 数组的 JSON。这两个端点正是 Cetas 刷新目录时先探的,`name` 不是 `magpie` 的应答,Cetas 一律不认。 网关自己要求鉴权时,`curl` 也得带上同样的 Bearer 令牌;这种情况下以第 5 步的 `/status` 为准。 ## 2. 让 Cetas 连上:设置项与凭据 地址和凭据分开存:地址写进 settings.json,凭据进共享凭据库。这一步先让地址可用,再让凭据可用,下面两小节各有各的成功标志。 | 要写的 | 落在哪 | 谁写 | | --- | --- | --- | | `magpie.base_url`、`magpie.enabled` | `/.cetas/settings.json` | `/login magpie` 会写,也可以手写 | | 网关凭据 | 共享凭据库(`/.cetas/credentials/`) | 只有 `/login magpie` | ### 用 `/login magpie`(推荐) ```text /login magpie ``` 先选网关形态:`Local Gateway`(`http://127.0.0.1:3425`)或 `Remote Gateway`(HTTPS with Gateway Key)。选远程会再问两项:`Gateway HTTPS origin` 与 `Gateway Key (input hidden)`。 它不只写配置:跑完会真的连一次网关,先读 `/api/hello`,再读 `/v1/models`。 **成功标志**:出现 `Magpie Gateway verified and configured`。 失败只有一句,而且故意不说细节:`/login magpie cancelled, unavailable or invalid`——取消、网关不可达、密钥不对、地址不安全,都归到这一句,排查见最后一节。正在跑回合时它会先拒绝:`/login magpie requires an idle application`。 `/login magpie` 写的是 `magpie.base_url` 与 `magpie.enabled: true`,**不写** `model_manager`。它只解决「连得上」,切不切过去是下一步的事。 ### 或者手写 settings.json ```json { "model_manager": "magpie", "magpie": { "base_url": "http://127.0.0.1:3425", "enabled": true } } ``` - `magpie.base_url` 是 **origin**:不带 path、query 或用户信息。写成 `http://127.0.0.1:3425/v1` 会被拒,错误是 `base_url must be a gateway origin without path, query or userinfo`;漏掉 `http(s)://` 也会被拒,错误是 `base_url must be an absolute http(s) URL`。 - `magpie.enabled` 必须是布尔。写成字符串 `"true"` 不会被宽松接受,而是组装直接失败:`settings.magpie.enabled must be a boolean`。 - `model` 与 `reasoning_effort` 可以一起写,当作启动时的选择;只写 `reasoning_effort` 会被拒,错误是 `selected_effort is set without selected_model`。 **成功标志**:文件里 `model_manager`、`magpie` 两段都在,`base_url` 是纯 origin,`enabled` 是裸的 `true` / `false`。 ### 凭据只走共享凭据库 网关密钥不进 settings.json。凭据只有一个来源:`/login magpie` 写进共享凭据库的那一份。写在 settings.json 里的都不会被采用。 `magpie` 段里的 `magpie.gateway_key` 会被**忽略**,并给出警告,原文是: ```text settings.json magpie.gateway_key is ignored; store the gateway credential with the shared credential store (provider id 'magpie') instead of editable configuration. ``` `providers` 里 id 为 `magpie` 的条目写 `gateway_key` 也没有用:那不是凭据的入口,读不到,凭据同样只走凭据库。 **成功标志**:settings.json 里搜不到密钥;密钥来自 `/login magpie`,落在凭据库里。 ## 3. 切到 Magpie 管理器 ```text /manager ``` 弹出 `Select model manager`:`Providers` 或 `Magpie`。切换等于用新管理器重新组装一次 agent,所以要空闲——正在跑回合时会回 `/manager requires an idle application`。 **成功标志**:出现 `model manager: magpie`;状态栏里模型名旁边那段管理器标签也从 `Posoco` 变成 `Magpie`。 还有两个副作用: - Board 服务会停(如果正开着):`Board service stopped because the model manager switched to magpie. Reopen it with /board.` - 选择被记下来:`model_manager` 记住当前管理器,`manager_selections` 记住每个管理器上次用的模型与档位,切回来时自动恢复,不用重选。 ## 4. 选模型与推理档位 ```text /model ``` 列表就是网关 `/v1/models` 的内容,归在 `magpie` 这一组下(网关的路由组单独成组);选中后左右键切推理档位。 **成功标志**:出现 `selected at effort (pending=false)`。 `pending=true` 是另一种信号:设置里记着的那个模型当前目录里没有,后面还会跟一句 `(selection '' is pending: not in the catalog yet; requests will fail until a refresh provides it)`。这时用 `/model` 另选一个,或按第 6 步刷新目录。 决策槽位那本账属于供应商集合:`/decision` 选出来的模型留在 `decision_model` 里,切到 Magpie 后原样不动,切回去继续生效,不用重选。 ## 5. 验证三条 三条都过了才算这条路走通:网关状态、配额、一次真实推理。每条都有自己的成功标志。 ### `/status`:网关、选择、目录一次看全 ```text /status ``` Magpie 管理器下,`/status` 由网关扩展回答,第一行是人话: ```text /status: connected to magpie ; selected at effort (pending=false); models; services: Route=Unknown Quotas=Unknown Limit=Unknown Usage=Unknown UsageRequests=Unknown Concurrency=Unknown ``` **成功标志**:这行以 `connected to magpie` 开头,且 ` models` 不是 0。 同一行还可能出现这几种情况,每一种都是排障入口: - `gateway offline:` 后面跟原因 —— 网关不可达; - `authentication failed:` 后面跟原因(例如 `/api/hello answered HTTP 401` 或 `403`)—— 凭据不对; - `invalid gateway response:` 后面跟原因 —— 应答的不是 Magpie,或地址指偏了; - `disabled: the manager is configured with enabled = false` —— 管理器被关掉了; - `not connected: no refresh has run yet` —— 还没成功刷新过目录。 `services:` 后面是各观测接口的可用性(`Unknown`、`Accessible`、`Forbidden`、`NotSupported`、`TemporarilyUnavailable`),没调用过就是 `Unknown`。 ### `/quota`:配额读得到 ```text /quota ``` **成功标志**:弹出 `Quotas`,列出网关报的配额卡片——供应商、账户或套餐、各个窗口的剩余与重置时间。想强制重读网关,用 `/quota refresh`。 配额读不到不影响推理。 ### 真跑一句 随便问一句。 **成功标志**:有流式回复,且 `/status` 里的 `selected` 正是刚选的那个模型。 ## 6. 排障 先看 `/status` 那一行,结论就写在里面。 | 现象 | 大概率原因 | 怎么办 | | --- | --- | --- | | `/status` 说 `gateway offline:` 后面跟原因;`/login magpie` 一直失败 | 网关没启动、端口不对、被防火墙挡住 | 回第 1 步确认进程与端口,`curl` 探 `/api/hello`;端口不是 `3425` 就把 `magpie.base_url` 改对 | | `/status` 说 `invalid gateway response:` 后面跟原因 | `base_url` 指到了别的服务、写成了带 path 的地址,或网关身份不符(`/api/hello` 的 `name` 不是 `magpie`) | `base_url` 只写 origin(`http://127.0.0.1:3425`),再 `/login magpie` 重新校验一次 | | `/status` 说 `authentication failed:` 后面跟原因;远程网关连不上 | 凭据缺失或不对 | `/login magpie` → `Remote Gateway`,重填 `Gateway Key`;顺手确认 settings.json 里的 `gateway_key` 位置写对了——写错位置只留一条警告,不会生效 | | 启动或切换直接失败,错误里带 `settings.model_manager must be providers or magpie`、`settings.magpie.enabled must be a boolean`、`settings.magpie.base_url must be a string` | 设置项类型不合法 | 按 [Settings 参考](/cetas/reference/settings/)改回严格取值:`model_manager` 只能是 `providers` 或 `magpie`,`magpie.enabled` 只能是布尔。看似合理的字符串不会被接受 | | `/model` 里没有网关刚加的模型 | 目录只在 agent 启动时与手动刷新时读;Magpie 管理器下没有后台轮询 | 跑 `/magpie_refresh`,成功标志是 `catalog refreshed: models` | | `/status` 说 `disabled: …` | `magpie.enabled` 是 `false` | 改回 `true`,或重新 `/login magpie` | 网关不可达不会让 Cetas 起不来:会话照常启动,只是 `/status` 照实说 offline,`/model` 回一条 `Model catalog unavailable`。 命令与设置项的完整清单在[命令](/cetas/reference/commands/)与 [Settings 参考](/cetas/reference/settings/)两页。 # MCP > 按用户级或项目级接入 MCP 服务器——数据库、工单系统、内部 API——把 agent 能做的事扩展到你的工具栈上。 Source: https://colmugx.github.io/cetas/configuration/mcp/ · Markdown: https://colmugx.github.io/cetas/configuration/mcp/index.md MCP 服务器扩展 agent 能做的事 —— 一个数据库、一个工单系统、一个内部 API。Cetas 从两处读取它们的配置: ```text /.cetas/mcp.json # 用户级 /.mcp.json # 项目级 ``` 同名的服务器以项目级为准,所以一个仓库可以钉住它需要的那套服务器,而不去动别人 home 目录里的东西。 > **schema 归服务器自己** > > 本页故意不定义 MCP 的 JSON schema。服务器字段由 MCP 扩展解释(编辑器提供的服务器则由编辑器解释)。请照着该服务器自己的文档抄形状,而不是照这里的通用示例。 ## 什么时候连 | 入口 | 默认 | 改动方式 | | --- | --- | --- | | 终端 | 第一个回合时连 | — | | 编辑器(ACP) | 第一个回合时懒加载 | `CETAS_MCP_MODE=eager` 改为启动时连 | | 编辑器提供的服务器 | 始终 eager | 这些服务器归编辑器所有 | 默认懒加载,是因为启动不该被你这轮根本不用的服务器卡住。连不上的服务器表现为工具失败,而不是启动失败。 ## 各入口能看到哪些服务器 - 终端和编辑器都组合了 MCP 扩展,所以两者都读上面两个文件。 - 编辑器还可以通过 ACP 直接提供服务器定义。那些服务器归编辑器:Cetas 不会写回去,终端也看不到。 ## 排查连接问题 ```bash CETAS_DEBUG_MCP_CATALOG=1 cetas-acp ``` 会把每个会话在组装时的工具目录 dump 到 `/.cetas/debug/-catalog.json` —— 回答"服务器连上了吗?它到底暴露了什么?"最快的方式。要看线上细节,用 `CETAS_DEBUG_WIRE=1`。 先看目录:一个连上了但没暴露工具的服务器,是服务器的问题,不是 Cetas 的问题,而目录能让这个区分一目了然。 # 模型 > 对话与决策两个模型槽位互不相通:怎么用 /model 与 /decision 选择,推理档位又管什么。 Source: https://colmugx.github.io/cetas/configuration/models/ · Markdown: https://colmugx.github.io/cetas/configuration/models/index.md Cetas 用 `provider/model` 形式的 id 标识一个模型槽位,例如 `deepseek/deepseek-flash` 或 `moonshot/kimi-k3`。 ## 两个槽位,互不相通 对话模型和决策模型永远不能互换,两个选择器各自守住这条线: ```text /model # 对话槽位;拒绝决策槽位 /decision # 决策槽位,并标出当前那个;拒绝对话槽位 ``` `/decision` 不带参数时,列出当前供应商能提供的决策槽位。构建里没有决策后端的,这里自然就没东西可选。 决策模型对 `permission auto` 尤其重要:语义闸门逐调用判断,而闸门自己需要一个决策模型来做判断——见[权限](/cetas/configuration/permissions/)。 ## 选择存在哪、谁能改 当前选择存在 settings 里,字段见 [Settings 参考](/cetas/reference/settings/)。三条改法: | 入口 | 行为 | | --- | --- | | 终端 | `/model`、`/effort`、`/decision` 改成功就持久化 | | 编辑器(ACP) | `model` / `effort` 配置项改成功就持久化 | | 自动化(`cetas-run`) | `--model`、`--effort` 只对本次运行生效,**不**持久化 | 供应商配置变化导致原选择不可用时,Cetas 退回可用的默认值,不会因为旧选择失效就拒绝组装。 ## 模型列表 拉到的模型目录缓存在 `/.cetas/model_lists.json`,每个供应商一个记录数组。选择器靠这份热缓存就能工作,供应商重新发现时其缓存列表会被刷新。 ## 自定义模型 不是内置之一的供应商,就是你自己声明的 OpenAI 兼容端点,模型能力(上下文窗口、图像输入、档位)也在同一处声明。见[自定义与私有化模型](/cetas/configuration/custom-models/)。 # 用对话做配置 > 不确定某个字段怎么写时,用自己的话描述改动,让 agent 读 settings、改 settings,再把 diff 给你。 Source: https://colmugx.github.io/cetas/configuration/natural-language/ · Markdown: https://colmugx.github.io/cetas/configuration/natural-language/index.md 没有什么配置 DSL 要学。Cetas 会话本来就有文件工具,而 settings 就是一个文件 —— 所以当你不确定某个形状该怎么写时,最快的路是直接描述: ```text 加一个叫 my-gateway 的供应商,接到 https://llm.internal.example/v1, 声明模型 qwen3-32b、上下文 128k,然后把它设成我的模型。 ``` agent 会读 settings、完成改动、然后告诉你改了什么。这是选择器覆盖不到的场景的正路:供应商条目、模型元数据、子代理 kind、工作流预算。 ## 为什么这条路是通的 配置就是一个文件里的普通 JSON,而 Cetas 自带一份"怎么配置自己"的手册 —— 所以 agent 是从产品手册回答配置问题,而不是凭它对某家 schema 的记忆瞎猜。这也解释了为什么**不要**期待它编造供应商专属 key:它本该在不知道形状的时候直说不知道。 ## 要 diff 配置错误审起来很便宜,调试起来很贵。说完需求,再要一次改动内容: ```text 把刚才写的内容 diff 给我看。 ``` 凡是涉及 `providers`、`workflow`、或者当前模型选择的改动,都值得要一次 diff,而不是接受一句"好了"。 ## 用命令回读验证 凡是能用命令确认的,就别用自然语言确认。命令和产品走同一条代码路径把文件读回来: | 改动 | 用什么验证 | | --- | --- | | 供应商或凭据 | `/login ` | | 可用模型 | `/model` | | 决策槽位 | `/decision` | | 推理档位 | `/effort` | | 权限姿态 | `/permission` | ## agent 仍然做不到的事 配置改不动权限。会话是 `readonly` 时,agent 连 settings 文件也写不了 —— 先 `/permission workspace_write`,或者你自己改。 另外两条边界值得知道: - 影响系统提示的改动 —— 指令、供应商身份、技能目录 —— 在**下一个**会话生效。当前会话还是用它启动时拿到的提示。 - 会话起不来、怀疑配置坏了:settings 坏了不会被自动修复,修好或恢复它,见 [Settings 参考](/cetas/reference/settings/)。 ## 什么时候用,什么时候别用 用对话:新供应商、模型元数据、子代理 kind、工作流预算,以及任何一次性的、不熟的改动。 直接编辑文件(或在机器之间复制)适用于:给一个团队批量开通、审阅一次改动、对齐一份已知可用的配置 —— 并且优先用 `/login` 而不是内联 `api_key`,让密钥留在凭据库里。 # 权限 > 决定 agent 能碰什么的五种权限姿态,从 readonly 到 yolo——按会话选择,也可以分阶段放开。 Source: https://colmugx.github.io/cetas/configuration/permissions/ · Markdown: https://colmugx.github.io/cetas/configuration/permissions/index.md 每个会话都在且只在一个权限姿态下运行。这是你要设的最重要的开关,因为它决定的是:当 agent 想做点什么(而不是读点什么)时,会发生什么。 ```text /permission readonly ``` 这个切换在回合进行中也能用。姿态属于会话 —— 谨慎的选择不需要变成一次全局决策。 ## 五种模式 | 模式 | 读 | 写、shell、未知工具 | | --- | --- | --- | | `readonly` | 预批准,包含可判定为只读的 shell | **直接拒绝** —— 没有提示,也没有绕过 | | `workspace_write` | 预批准 | 走审批提示 | | `interactive` | 预批准 | 走审批提示,包含有副作用的检查类操作 | | `auto` | 预批准 | 每次调用交给决策模型判断;被拒是引导信号,不是错误 | | `yolo` | 预批准 | 预批准 —— 审批提示根本不出现 | 其中三个值得展开。 **`readonly`**:不弹提示,也没有例外。它不需要 UI,也不需要人:改文件和只读之外的 shell 一律拒绝。审阅类任务、汇报类任务、以及团队放量的第一周,用它。 **`auto`**:语义闸门。每个非只读调用都交给决策模型;看起来有风险的操作、或者授予概率偏低的,会被拒。它没有确定性兜底:没有决策模型就组装不起来,`/permission auto` 也会拒绝切换。后端用 `/decision` 指定 —— 见[模型](/cetas/configuration/models/)。 **`yolo`**:只管工具执行。它从不批准提交上来的计划;计划是否通过,仍然归评审流程管。 ## "批准"记住了什么 当提示被回答为*本会话内允许*时,这次授权会在该 agent 生命周期内被缓存 —— 不落盘: - 写类工具和未知工具**按工具名**缓存 —— 批准过一次 `edit`,之后所有 `edit` 都算批过 - shell 工具**按命令段**缓存:命令按 `&`、`|`、`;` 和换行切段,每段以第一个词为作用域,所以批准了 `moon check` 不等于批准同一条管线里的 `rm -rf` 新会话从空的授权缓存开始。 ## 各入口怎么设 | 入口 | 方式 | | --- | --- | | 终端 | `/permission ` | | 编辑器(ACP) | 会话配置项 `permission`,或启动时的 `CETAS_PERMISSION_MODE` | | 自动化 | `--permission `,或 `--yolo` | | 启动时未设置 | ACP 入口默认 `yolo` | `CETAS_PERMISSION_MODE` 只在**一个方向**上宽容:取值不认识就警告一次、退回 `workspace_write`。笔误永远不会把姿态放宽。 ## 一条不需要开会的放量路径 1. 所有人先 `readonly`。把阅读行为验证一遍,确认答案值得照着做。 2. 把 `workspace_write` 给那些明确要求动手的人。从这刻起每次写都会先提示一次,这些提示会慢慢养成评审习惯。 3. 想要"引导"而不是"确认"的团队,上 `interactive` 或 `auto`。`auto` 需要决策模型,所以这一步正是 `/decision` 派上用场的地方。 4. `yolo` 只给无人值守、有边界的工作 —— 带 `readonly` 的 CI,或者任务非常窄的专用自动化。 要避免的失败模式是"因为安静所以从 `yolo` 起步"——出事之前,它一直是安静的。 # 供应商 > Cetas 能组合的供应商扩展都在这里:内置供应商的 id、各自的登录方式,以及自定义供应商怎么接入。 Source: https://colmugx.github.io/cetas/configuration/providers/ · Markdown: https://colmugx.github.io/cetas/configuration/providers/index.md 供应商配置在 `/.cetas/settings.json` 的 `providers` 下。Cetas 提供配置与凭据来源;端点、协议细节、模型能力、登录行为,都由各自的供应商扩展自己负责。 ## 内置供应商 下面这些 id 由内核注册。它们同时也是你传给 `/login` 的 id,以及 `provider/model` 槽位的前半段。 | Id | 供应商 | 登录方式 | | --- | --- | --- | | `deepseek` | DeepSeek | API key | | `kimi` | Kimi | API key、OAuth | | `openai` | OpenAI | API key、OAuth | | `opencode` | OpenCode Zen | API key | | `opencode-go` | OpenCode Go | OAuth | | `zai` | Z.ai | API key | | `zai-coding-plan` | Z.ai Coding Plan | API key | | `openrouter` | OpenRouter | API key | | `typesafe` | Typesafe `jev` 决策后端 | API key | 拥有多种登录方式的供应商会出现方式选择器;只有一种的会跳过选择器,直接要凭据。 ## 供应商 id 的规则 id 只允许字母、数字、`_` 和 `-`,因为它同时出现在 settings key、凭据文件名和登录目标里。 `opencode` 这个 id 归 OpenCode Zen,所以 `providers.opencode` 会解析到 Zen,而不会掉到兼容适配器里。 ## 其他一切走 OpenAI 兼容 `providers` 里任何既不在上表、也不撞 id 的 key,都会变成一个 OpenAI 兼容供应商。这是网关、代理、以及自家部署的 OpenAI 形状 API 的官方支持路径 —— 见[自定义与私有化模型](/cetas/configuration/custom-models/)。 因为兼容工厂列表是从 settings 现算的,自定义供应商和内置供应商享受完全一样的待遇:`/login`、`/model`、目录刷新、模型缓存都一视同仁。 ## 登录 ```text /login ``` 选择器列出的是这一份构建能组合出来的供应商。要登录自定义供应商,对着它的 id 登: ```text /login my-gateway ``` 凭据文件写到 `/.cetas/credentials/`,所有入口共用。手边没有终端时,`cetas-run --login` 也能对 runner 完成同样的事。 ## 关于 schema 不存在一套覆盖所有供应商的通用 JSON schema,本页也不会凭空编造供应商专属的 key。优先用 `/login` 和 `/model`;settings 里的供应商段落由各扩展自己解释。私有端点这类简单的条目形状,写在[自定义模型](/cetas/configuration/custom-models/)里。 # 技能 > 技能是带 SKILL.md 的可复用指令包:目录、激活、读资源三层披露,只在任务需要时才把指令装进上下文。 Source: https://colmugx.github.io/cetas/configuration/skills/ · Markdown: https://colmugx.github.io/cetas/configuration/skills/index.md 一个技能就是一个带 `SKILL.md` 的目录:frontmatter 加上一段针对某类工作的指令。技能是 Cetas 获得领域能力的方式 —— 不用把所有内容都塞进提示里,其中也包括"Cetas 自己怎么配、怎么用"。 ```text /skills ``` 列出本次会话里发现的技能。 ## 三层披露 启动时全部加载既浪费又吵,所以技能是分阶段打开的: 1. **目录** —— 发现阶段校验每个 `SKILL.md`,只保留元数据。指令正文根本不进上下文。 2. **激活** —— 任务需要时,agent 按名字激活**恰好一个**技能。Cetas 重新读取并校验那个文件,返回它的指令,同时列出它带的资源(但不读内容)。 3. **读资源** —— agent 按需打开该技能目录下的某一个具名资源。 最后这道边界是强制的:资源路径会经过规范化真实路径解析,必须留在这个技能目录里。 ## 技能从哪来 | 作用域 | 路径 | | --- | --- | | 用户 | `/.agents/skills//SKILL.md` | | 仓库 | `.agents/skills//SKILL.md`,从当前目录逐级向上找到仓库根 | 仓库里的技能来自一次 checkout,按定义就是不可信输入 —— 你对仓库里任何脚本的戒心,同样适用于这里。宿主可以选择完全排除仓库技能;Cetas 不会替你做信任判断。 技能目录可以是软链接,但解析后的包必须留在仓库边界内,除非宿主明确允许外部包。 ## 怎么写一个 ```markdown --- name: repo-map description: 这个仓库该怎么逛 --- ## 目录结构 ... ``` frontmatter 在发现阶段就会被校验:校验不过的技能会被跳过,而不是加载一半;同名冲突会按确定规则解决,而不是取决于目录遍历顺序。 因为正文只在激活时读取,一个很长的技能在你用不到它的时候不花任何代价。写 frontmatter 时想着发现阶段 —— 描述才是决定 agent 会不会打开这个文件的东西。 # 子代理 > 把有边界的工作交给子 agent:它们有自己的工具面、模型和权限姿态,可以并行、可以后台,父会话继续干活。 Source: https://colmugx.github.io/cetas/configuration/subagents/ · Markdown: https://colmugx.github.io/cetas/configuration/subagents/index.md 子代理是主会话为一件有边界的工作拉起的子 agent。它拿到全新的模型选择、全新的权限姿态和独立的"写前先读"状态;同时它绕不过父级 —— 只有宿主能重建的核心工具才会被继承。 典型用法:对一个 diff 做只读评审、只带两个工具的窄口径修复、允许抓取但绝不写盘的调研子代理,或者在工作能干净切分时并行开几个。 ## 工作怎么派下去 agent 通过 `subagent` 工具拉起子代理。彼此独立的子代理可以作为一波并行执行,耗时的可以放后台跑,父会话继续干活。父与子之间随时可以提问:子代理需要决策时会问,答案会回到同一个会话里。 每个子代理的记录在父会话生命周期内驻留内存,所以续接的对话能把它接回来,而不是从头再来。 ## Kind:可复用的预设 一个 *kind* 就是一份子代理预设 —— 名字、描述、工具白名单、模型、推理档位、权限模式,外加一段提示模板。定义它有两个地方。 **文件**放在 `.cetas/agents/.md`,可以按用户放,也可以按项目放: ```markdown --- name: reviewer description: 只读的 diff 评审员 tools: read, grep, glob effort: low mode: readonly --- 你在不动工作区的前提下评审改动。 来自调用方的指令: {{instructions}} ``` frontmatter 里的 `name` 必须和文件名一致。未知 key 会被忽略;缺 `name` / `description`、列表项非字符串、块没有闭合、`mode` 不认识,都是解析错误 —— 坏 frontmatter 会被拒绝,不会被修。列表可以写成逗号分隔的字符串,也可以写成短横线列表。 **settings 里的条目**更轻,写在 `settings.json` 的 `subagent.kinds` 下,字段名一致,只是换成 JSON 语法。`body` 可以省略,省略时会用 `name` 和 `description` 生成一段通用模板。 按 kind 名的优先级:项目 `.md` → 用户 `.md` → settings 条目 → 内置。 ## 工具白名单 三种状态: | `tools` | 含义 | | --- | --- | | 不写 | 继承宿主默认的核心工具集 | | `[]` | 一个工具都没有 | | 一个列表 | 就是这些工具 | ## 默认模型与限额 子代理的默认模型、推理档位和全部限额走 settings 的 `subagent` 段,每个字段的默认值见 [Settings 参考](/cetas/reference/settings/);不配就是默认值。模型选择的优先级链:显式传参 → kind 绑定 → `default_model` → 父级当前选择。 ## 注意事项 - 子代理不继承宿主动态工具和装饰器。需要某个工具的 kind 要显式写出来,并且宿主能重建它。 - 子代理的权限姿态是自己的。父级是 `yolo` 时,一个 `readonly` 子代理依然写不了。 - `spawn_budget` 是防止跑偏的计划变成一百个 agent 的护栏;要抬就明确地抬。 # 编辑器(ACP) > 在支持 Agent Client Protocol 的编辑器里用同一个 Cetas —— Zed 与 Lody 的配置步骤。 Source: https://colmugx.github.io/cetas/editor/ · Markdown: https://colmugx.github.io/cetas/editor/index.md `cetas-acp` 通过 stdio 把 Cetas 以 [Agent Client Protocol](https://agentclientprotocol.com/) 暴露出来。任何 ACP 客户端都能拉起它,于是你在终端里认识的那个 agent,会带着编辑器自己的权限 UI 出现在编辑器里。 ## 接入之前 编辑器入口读的是和其他入口同一个 home 目录,而且**没有供应商就拒绝启动** —— 没有模型的 agent 服务不了任何 prompt。所以先在终端里配好: ```text /login /model ``` 然后拿到二进制:从[发布归档](/cetas/getting-started/installation/)里解出 `cetas-acp`,或者自己从源码构建。 ## Zed 在 Zed 的 settings 里加一条顶层 `agent_servers`: ```json { "agent_servers": { "Cetas": { "type": "custom", "command": "/absolute/path/to/cetas-acp", "args": [], "env": {} } } } ``` Windows 上用 `cetas-acp.exe`。如果你的 Zed 版本要求不同的 schema,按 [Zed 的自定义 agent 文档](https://zed.dev/docs/ai/external-agents#custom-agents)来。 然后打开 agent 面板,选 **Cetas**。Zed 在 `initialize` 时会自报身份,所以这个会话的记录会落在 `/.cetas/sessions/zed/`。 ## Lody Lody 把外部 agent 当作一份 *Agent Config* 来管,靠一条启动命令注册。Cetas 只需要登记一次: 1. 打开 **Settings → Agent Config**,新增一条配置。 2. 命名为 `Cetas`。 3. **CLI Type** 选 **Custom ACP**。 4. **Launch command** 填绝对路径 —— `/absolute/path/to/cetas-acp`。 5. 需要的话,在同一个 Agent Config 里补环境变量(见下面的表)。 6. 点 **Test**。Lody 会拉起 agent、读取它的能力和模型列表;这一步失败基本就是供应商还没配好。 7. 保存,然后在新建会话时选择这条配置。 Lody 会把启动命令拆成"命令 + 参数"直接 spawn —— 引号支持,但管道、重定向、glob 和 `$VARS` 都不会被求值。所以环境变量写在 Agent Config 里,别塞进命令。 Lody 的会话落在 `/.cetas/sessions/lody/`。 ## 每个会话拿到什么 每个 ACP 会话都有自己的一套可变机制 —— 模型路由、权限策略、MCP 桥、记录存储、正在跑的回合 —— 所以不同会话上的 prompt 可以并发执行,而不会串权限、串审批。供应商配置和模型目录只组装一次,之后只读共享。 对话记录归客户端所有:客户端存会话内容和 session id,`session/resume` 时把 id 递回来。Cetas 把已提交的记录落盘,是为了重启之后从磁盘恢复,而不是靠内存。 ## 会话级配置项 ACP 会话对外提供这几项配置: - `model` —— 改成功后会持久化,作为下次启动的选择。 - `effort` —— 当前模型有推理档位时会持久化。 - `permission` —— 只在运行时、只属于这个会话,**故意不持久化**。 变更通过 `session/set_config_option` 进来。连不上时,先看编辑器的 ACP 日志,再看 agent 的 stderr —— 所有诊断都在 stderr,因为 stdout 上只有 JSON-RPC 帧。 ## 环境变量 | 变量 | 作用 | | --- | --- | | `CETAS_HOME` | 覆盖平台 home;状态落在 `/.cetas` | | `CETAS_PERMISSION_MODE` | 启动姿态:`readonly`、`workspace_write`、`interactive`、`auto`、`yolo`。不设是 `yolo`;取值不认识会警告一次并降回 `workspace_write` | | `CETAS_MCP_MODE=eager` | 启动时就连配置好的 MCP 服务器,而不是等到第一个回合 | | `CETAS_DELEGATE_FS=host` | 文件读写走编辑器的 `fs/*` 反向调用,而不是本地文件系统 | | `CETAS_DEBUG_WIRE=1` | 把这个会话的线上流量追加到 `/.cetas/debug/-wire.jsonl` | | `CETAS_DEBUG_MCP_CATALOG=1` | 把这个会话的工具目录 dump 到 `/.cetas/debug/-catalog.json` | MCP 的配置见 [MCP](/cetas/configuration/mcp/);完整的变量清单见[环境变量](/cetas/reference/environment-variables/)。 # Automation > One Cetas turn per process, for scripts, CI, and pipelines. Source: https://colmugx.github.io/cetas/en/automation/ · Markdown: https://colmugx.github.io/cetas/en/automation/index.md `cetas-run` is the one-shot host: one process invocation runs exactly one user turn. It composes the same core as the terminal and editor hosts, and it is the entrance to use when the caller is a script rather than a person. ## Command shape ```text cetas-run [--model ] [--effort ] [--session ] [--yolo | --permission ] [--stream] [--verbose] [--show-thinking] [--jsonl] [-- ""] ``` Pass the task after `--`. If argv carries no task, Cetas reads exactly one line from stdin. Two further forms: ```text cetas-run --login [provider] cetas-run --help | -h | --version ``` Help and version write no config, read no stdin, and contact no provider. ## Output contract In text modes stdout carries the answer and nothing else. Diagnostics follow a fixed split, which is what makes the output pipeable: | Mode | stdout | stderr | | --- | --- | --- | | default | final answer | session metadata, lifecycle markers, approval prompts | | `--stream` | answer deltas as they arrive | events and markers | | `--verbose` | answer | events and markers, verbosely | | `--show-thinking` | answer | reasoning, then events | | `--jsonl` | structured event stream | markers | `--jsonl` takes precedence over the text modes. ## Sessions Without `--session`, each invocation creates a fresh session id and reports it on stderr. Re-run with `--session ` to continue that session: ```bash cetas-run -- "explain this repository" cetas-run --session cetas-42 -- "now fix the failing test" ``` This is same-host resume. It does not imply that a conversation can move between surfaces — see [Surfaces](/cetas/en/concepts/surfaces/). ## Permissions `--permission` accepts `readonly`, `workspace_write`, `interactive`, or `auto`. `--yolo` is the unattended mode and cannot be combined with `--permission`. `--model` and `--effort` are run-scoped overrides: they are never persisted, so a scheduled job cannot silently change what a person sees next time they open the terminal. ## Exit codes | Code | Meaning | | --- | --- | | `0` | The turn completed | | `1` | The turn ran but failed | | `2` | Startup, usage, or login failure | Distinguishing `1` from `2` is what lets a pipeline retry a genuine failure without retrying a misconfiguration forever. ## Configuration Provider settings and credentials come from the shared home, normally `/.cetas/`; `CETAS_HOME` overrides the platform home (the *parent* of `.cetas`, not the directory itself). Credentials are shared with the other surfaces: if you are already logged in, just run the task. For a first login on a machine with no terminal session, native builds can run `cetas-run --login`. ## From Mooncakes The runner is also published as a Mooncakes module: ```bash moonx colmugx/cetas-run -- -- "fix the failing tests" moonx colmugx/cetas-run -- --session -- "continue" ``` ## In CI Two habits that keep automated runs boring: - Pin the version you install (`npm install -g @posoco/cetas@`) and bump it deliberately — read the [changelog](/cetas/en/changelog/) first. - Use `--permission readonly` for review and reporting jobs; it makes an unexpected write attempt a hard stop rather than a surprise commit. # Concepts > The Concepts section currently covers one thing — surfaces. Source: https://colmugx.github.io/cetas/en/concepts/ · Markdown: https://colmugx.github.io/cetas/en/concepts/index.md The Concepts section answers "what is it". One page today: [Surfaces](/cetas/en/concepts/surfaces/) — how the terminal, the editor, and automation compose the same agent. # Surfaces > Cetas JS and Native terminal implementations, plus independent ACP and Run entry points. Source: https://colmugx.github.io/cetas/en/concepts/surfaces/ · Markdown: https://colmugx.github.io/cetas/en/concepts/surfaces/index.md Cetas has three *usage surfaces* — terminal, editor, and automation — with **two terminal implementations**. Cetas JS from npm is the default recommendation; Cetas Native is an optional Go/Bubble Tea terminal over the same MoonBit Cetas/Posoco core. | Host | Interface | Install / distribution | | --- | --- | --- | | **Terminal · JS (recommended)** `cetas-js` | Full interactive terminal, JS-only integrations including Board | `npm install -g @posoco/cetas` | | **Terminal · Native (alternative)** `cetas-native` | Go/Bubble Tea v2 terminal, separate host capabilities | Homebrew (macOS/Linux), Scoop (Windows), or [Cetas Release](/cetas/en/getting-started/installation/) | | **Editor · ACP** `cetas-acp` | ACP server via stdio; usable with Lody and Zed | Separate `cetas-acp-*` Release asset | | **Automation · Run** `cetas-run` | One task per process | Separate `cetas-run-*` Release asset | ## What is shared The hosts compose the same core and generally reuse provider settings, credentials and session storage under [Cetas home](/cetas/en/configuration/cetas-home/). This does **not** imply UI parity or portable conversations between hosts. ## What differs - JS is the primary feature-rich TUI, with Pi/Node/Bun integrations and Board workflows not available in Native. - Native uses a Go terminal and a MoonBit runtime (Unix static bridge, Windows adjacent DLL), and can run without Node.js. - ACP is a standalone editor integration; clients own presentation and approval UI. You can download it without installing Native. - Run produces stdout/stderr-friendly one-shot results, and can also be downloaded independently. - JS and Native may both expose a command named `cetas`; the first match on `PATH` wins. Cross-host conversation resume is not a supported contract. See [Installation](/cetas/en/getting-started/installation/) for exact platform options. # Configuration > How Cetas is configured — in conversation, with commands, or by hand. Source: https://colmugx.github.io/cetas/en/configuration/ · Markdown: https://colmugx.github.io/cetas/en/configuration/index.md ## Try the lowest-effort path first Once it is installed, describe the change in the session and let the agent write the settings: ```text Add a provider named my-gateway at https://llm.internal.example/v1, declare the model qwen3-32b, and make it my model. ``` Ask for a diff of what it wrote. Provider entries, model metadata, subagent kinds, workflow budgets — all of it can be configured this way, and for most changes this is where the work ends. See [Natural-language configuration](/cetas/en/configuration/natural-language/). ## What a picker covers, do with commands `/login`, `/model`, `/decision`, and `/effort` write the shape the selected provider expects, so no schema to learn. The full list is in the [command reference](/cetas/en/reference/commands/). ## Reference pages for editing the file To check fields one by one, copy configuration between machines, or provision a batch of environments, these pages follow the structure of settings.json: - [Settings reference](/cetas/en/reference/settings/) — the complete field reference: every key, its type, its default, expanded by nesting level; - [Providers](/cetas/en/configuration/providers/) — the built-in provider set and login; - [Models](/cetas/en/configuration/models/) — slots, `/model`, and `/decision`; - [Custom and self-hosted models](/cetas/en/configuration/custom-models/) — the entry shape for private endpoints and gateways; - [Subagents](/cetas/en/configuration/subagents/) — kind definitions and tool whitelists; - [Permissions](/cetas/en/configuration/permissions/) — what the agent may touch; - [Skills](/cetas/en/configuration/skills/) — load reusable instruction packs; - [MCP](/cetas/en/configuration/mcp/) — connect external tool servers; - [Cetas Home](/cetas/en/configuration/cetas-home/) — the directory itself. ## What is shared, and what is not Sharing one home means every surface reads the same configuration, credentials, and session store. It does **not** mean every surface behaves identically: the terminal has pickers, the editor has ACP config options, and the runner takes flags. Each surface page states what it supports. Selections made in one surface are visible to the next: `/model` in the terminal is what the editor restores on its next start. > **Changes land in the next session** > > The system prompt is assembled once per session and frozen. Settings that affect > it — instructions, provider identity, skill catalog — take effect when you start > a new session, not on the running one. Selections such as `/model` and `/effort` > apply immediately. # Cetas Home > The one directory that holds settings, credentials, caches, and sessions. Source: https://colmugx.github.io/cetas/en/configuration/cetas-home/ · Markdown: https://colmugx.github.io/cetas/en/configuration/cetas-home/index.md Cetas resolves one home directory for durable state. It is the only place your configuration lives, and every surface reads it. A non-empty `CETAS_HOME` (an environment variable) overrides the platform user home; otherwise Cetas uses the platform home (`USERPROFILE`, then `HOMEDRIVE` + `HOMEPATH` on Windows; `HOME` elsewhere), falling back to the current directory only when no home can be resolved. In the docs, `` means this resolved user home, and the durable-state root is `/.cetas`: ```text /.cetas/ ├── settings.json # providers, selections, workflow, subagents ├── credentials/ # written by /login — never hand-edit ├── model_lists.json # discovered model catalogs, per provider ├── mcp.json # MCP servers ├── sessions/ # per-client session transcripts └── debug/ # only when a CETAS_DEBUG_* flag is on ``` `debug/` is not created by default: it appears when you enable `CETAS_DEBUG_WIRE` or `CETAS_DEBUG_MCP_CATALOG`. > **Override granularity** > > `CETAS_HOME` replaces the **parent** home, not the `.cetas` directory. > `CETAS_HOME=/tmp/cetas-user` puts state in `/tmp/cetas-user/.cetas/`. ## Which hosts honour the override | Surface | `CETAS_HOME` | | --- | --- | | Editor (`cetas-acp`) | Honoured | | Automation (`cetas-run`) | Honoured | | Terminal (`cetas` / `cetas-bun`) | **Not read** — resolves the platform home | This is worth knowing before you script anything: on a machine where you set `CETAS_HOME` to keep work separated, the terminal host ignores it and still resolves `.cetas` under the platform home. Check the home a session actually uses before debugging a "missing" configuration. ## What lives here, and why it is shared Model selection, credentials, MCP configuration, caches, and stored sessions are part of the same Cetas identity across surfaces — that sharing is the point. Sharing state does not promise identical behaviour: each surface has its own interaction model and its own support for resume. See [Surfaces](/cetas/en/concepts/surfaces/). Projects can also use project-local configuration where documented — for example `/.mcp.json` overriding the user-level MCP file, and `/.cetas/agents/` for project-scoped subagent kinds. ## Backing it up Copy the directory. `settings.json` and `sessions/` are the parts worth keeping; `credentials/` moves too, but treat it as a secret store, and `model_lists.json` is a cache that rebuilds itself. # Custom & Self-Hosted Models > Point Cetas at a private endpoint, gateway, or in-house deployment. Source: https://colmugx.github.io/cetas/en/configuration/custom-models/ · Markdown: https://colmugx.github.io/cetas/en/configuration/custom-models/index.md Teams rarely adopt a coding agent against a public API. The usual shape is a gateway in front of models you already run, with the key managed by infrastructure rather than by each developer. Cetas treats that as a first-class provider, not a workaround. ## How it works Every `providers` key that is not already claimed by a built-in provider becomes a **custom provider**. There is nothing to register and no plugin to build: the key is the provider id, and the provider participates exactly like a built-in one — `/login`, `/model`, catalog refresh, the model cache, and the editor host all see it. The endpoint may speak any of three wires, declared by the entry's `protocol`. ## Minimal configuration ```json { "providers": { "my-gateway": { "base_url": "https://llm.internal.example/v1", "api_key": "sk-...", "models": [ { "id": "qwen3-32b", "context_window": 131072 } ] } } } ``` - `base_url` — required. Include `/v1` when the server expects it; most OpenAI-shaped servers bake the version into the base URL. - `api_key` — required in practice. You can also omit it here and run `/login my-gateway` instead, which writes the credential to `/.cetas/credentials/` and keeps the secret out of the settings file. - `models` — required and must not be empty. Each entry needs an `id`; ids must be unique. `endpoint_prefix` exists for the case where `base_url` is a bare host (`http://10.0.0.4:8080`) and the API lives under `/v1`. Prefer putting the prefix in `base_url` and leaving this unset. ## Choose the protocol A custom endpoint speaks one of three wires: | `protocol` | Request | Wire | | --- | --- | --- | | `chat_completions` (default) | `POST {base_url}{endpoint_prefix}/chat/completions` | OpenAI Chat Completions | | `responses` | `POST {base_url}{endpoint_prefix}/responses` | OpenAI Responses API | | `messages` | `POST {base_url}{endpoint_prefix}/messages` | Anthropic Messages API | ```json { "providers": { "claude-proxy": { "base_url": "https://api.anthropic.com", "endpoint_prefix": "/v1", "protocol": "messages", "api_key": "sk-ant-...", "models": [{ "id": "claude-sonnet-5", "context_window": 200000 }] } } } ``` - Omitting `protocol` means `chat_completions`, so an entry written before protocols existed keeps its exact behavior. - The path suffix is appended after `base_url` + `endpoint_prefix`. Put the version segment in `base_url` (`https://llm.internal.example/v1`) or in `endpoint_prefix` (`/v1` with a bare host) — never in both. - `protocol` is provider-level, and any `models[]` entry may override it, so one endpoint serving several model families on different wires stays one provider id. - An unknown value fails composition and names the accepted ones. It never falls back to the chat wire: a silent fallback would answer `400` on the wrong endpoint shape. ### Credentials on the wire `auth` declares where the key rides: | `auth` | Effect | | --- | --- | | `auto` (default) | `Authorization: Bearer` on `chat_completions`/`responses`; `x-api-key` plus `anthropic-version: 2023-06-01` on `messages` | | `bearer` | `Authorization: Bearer` on every wire — for gateways fronting Messages with Bearer auth | | `x_api_key` | `x-api-key` on every wire | ### Reasoning levels per wire Effort levels mean the same thing everywhere — "how hard should this model think" — but each wire spells it differently, and nothing is invented for an endpoint whose scale is unknown: - `chat_completions` — the top-level `reasoning_effort` string, sent verbatim. - `responses` — `reasoning.effort`; temperature is dropped once a level is selected, because reasoning endpoints reject it. - `messages` — `thinking: {"type": "enabled"}`. Level names are **not** converted into a `budget_tokens` number. - `off` — nothing is sent on any wire, so the endpoint applies its own default. The Responses wire also runs stateless (`store: false`) and does not replay reasoning items: a generic endpoint declares no encrypted-reasoning contract. ### Output ceiling `max_output_tokens` (positive integer, default `8192`) is the `max_tokens` value on the `messages` wire, which requires the field. A turn that carries its own ceiling wins; this setting only fills the gap. ## Declare what the model can do The picker can only offer what you declare. Everything except `id` is optional, and omitting a value is safer than guessing it: | Field | On | Effect | | --- | --- | --- | | `context_window` | model | Capacity in tokens; without it, auto-compaction stays off for that model | | `compact_threshold` | model | Trigger point as a fraction of the window, `> 0` and `<= 1` (default `0.88`) | | `image_input` | model or provider | Accepts image input; provider-level value is the default for its models | | `reasoning_effort` | model or provider | One fixed effort level — no picker | | `reasoning_efforts` | model or provider | The levels to offer in the picker | ```json { "providers": { "my-gateway": { "base_url": "https://llm.internal.example/v1", "models": [ { "id": "qwen3-235b", "context_window": 262144, "compact_threshold": 0.85, "reasoning_efforts": ["low", "medium", "high"], "image_input": false } ] } } } ``` ## Secure it - Prefer `/login my-gateway` over an inline `api_key`: credentials live in `/.cetas/credentials/`, out of the file people paste into tickets. - A gateway that rejects `prompt_cache_key` is handled: Cetas learns the rejection per process and stops sending it, instead of failing the turn. - Nothing about a custom provider is refreshed from a public model registry. Its catalog is exactly what you declared — which is also why a wrong `context_window` silently degrades compaction rather than erroring. ## Verify it ```text /login my-gateway /model ``` Then send one message. If `/model` is empty, the provider either failed to compose (check the id is valid and not a built-in) or the `models` array was rejected — a malformed section fails composition loudly rather than being repaired. The same configuration is picked up by the editor and the runner: nothing needs to be repeated per surface. See [Providers](/cetas/en/configuration/providers/) for the built-in ids that take precedence over a compatible key. # Connecting the Magpie gateway > From starting the gateway to one real inference — which two settings to change, where the credential goes, how to switch managers, what each step should show, and where to look when it fails. Source: https://colmugx.github.io/cetas/en/configuration/magpie/ · Markdown: https://colmugx.github.io/cetas/en/configuration/magpie/index.md Magpie is a model gateway that runs on your machine or inside your network: models, accounts, and keys are managed on the gateway side, and Cetas only has to connect, pick a model, and get to work. The support is native: `/manager` switches between the provider set and Magpie, `/model` picks the conversation model and its reasoning effort, `/quota` reads quota, `/status` reports gateway and catalog state, and `/login` writes the credential into the shared credential store. This page walks one line from end to end: start the gateway → let Cetas connect → switch manager → pick a model → verify it works. Every step says what you must see before it counts as done. > **The division of labour is clear** > > Provider selection, upstream fallback, quota, and pricing belong to Magpie; Cetas does not reimplement that layer. The numbers in `/quota` and usage are reported by the gateway — Cetas never estimates or fills them in; a missing price or cache detail stays empty. Within one session, every inference request Cetas sends to the gateway carries `X-Magpie-Session`, so that session keeps a stable route. On the Cetas side you decide only three things: which gateway to connect to, which model to use (with its reasoning effort), and when to refresh the catalog. ## 1. Start the gateway and confirm it is alive The Magpie gateway is a separate process, at `http://127.0.0.1:3425` by default. Its installation, deployment, and operations follow Magpie's own documentation; this page only establishes one thing: Cetas can see it. Two shapes, with different prerequisites: - **Local gateway**: bound to a loopback address. Cetas authenticates with its built-in local application token (`Authorization: Bearer magpie-posoco`), so you do not prepare a key. - **Remote gateway**: needs a gateway key, and the address must be an HTTPS origin or a loopback HTTP origin; anything else is refused on the Cetas side: `gateway must be an HTTPS origin or loopback HTTP origin`. **Success marker**: `curl http://127.0.0.1:3425/api/hello` returns a JSON object whose `"name"` is `"magpie"`, and `curl http://127.0.0.1:3425/v1/models` returns JSON with a `data` array. Those are exactly the two endpoints Cetas probes when it refreshes the catalog; an answer whose `name` is not `magpie` is never accepted. If the gateway itself demands authentication, `curl` needs the same Bearer token; in that case treat the `/status` in step 5 as the authority. ## 2. Let Cetas connect: settings and credential The address and the credential are two different things, stored in two different places. This step has two halves: first make the address usable, then make the credential usable — each half has its own success marker, in the two subsections below. | What | Where it lives | Who writes it | | --- | --- | --- | | `magpie.base_url`, `magpie.enabled` | `/.cetas/settings.json` | `/login magpie` writes it; you may also write it by hand | | The gateway credential | The shared credential store (`/.cetas/credentials/`) | Only `/login magpie` | ### With `/login magpie` (recommended) ```text /login magpie ``` First pick the gateway shape: `Local Gateway` (`http://127.0.0.1:3425`) or `Remote Gateway` (HTTPS with Gateway Key). The remote path asks two more things: `Gateway HTTPS origin` and `Gateway Key (input hidden)`. This step does more than write configuration: it really connects to the gateway once — reading `/api/hello`, then `/v1/models`. **Success marker**: `Magpie Gateway verified and configured`. The failure is a single line and deliberately says nothing specific: `/login magpie cancelled, unavailable or invalid` — cancelling, an unreachable gateway, a wrong key, and an unsafe address all land there. See the last section for triage. While a turn is running it refuses up front: `/login magpie requires an idle application`. `/login magpie` writes `magpie.base_url` and `magpie.enabled: true`, and **does not write** `model_manager`. It only settles "can Cetas connect"; whether to switch is the next step. ### Or write settings.json by hand ```json { "model_manager": "magpie", "magpie": { "base_url": "http://127.0.0.1:3425", "enabled": true } } ``` - `magpie.base_url` is an **origin**: no path, query, or userinfo. `http://127.0.0.1:3425/v1` is rejected with `base_url must be a gateway origin without path, query or userinfo`; a missing `http(s)://` is rejected with `base_url must be an absolute http(s) URL`. - `magpie.enabled` must be a boolean. The string `"true"` is not accepted leniently — composition fails outright: `settings.magpie.enabled must be a boolean`. - `model` and `reasoning_effort` can be written together as the startup selection; `reasoning_effort` on its own is rejected with `selected_effort is set without selected_model`. **Success marker**: `model_manager` and `magpie` are both present, `base_url` is a bare origin, and `enabled` is a bare `true` / `false`. ### The credential goes only into the shared credential store The gateway key does not belong in settings.json. There is exactly one source for the credential: the copy `/login magpie` writes into the shared credential store. Whatever is written into settings.json is not used. A `magpie.gateway_key` inside the `magpie` section is **ignored**, and Cetas warns about it, with this exact text: ```text settings.json magpie.gateway_key is ignored; store the gateway credential with the shared credential store (provider id 'magpie') instead of editable configuration. ``` A `gateway_key` written on the `providers` entry whose id is `magpie` is no help either: that is not the credential's entry point, nothing reads it, and the credential still comes only from the store. **Success marker**: searching settings.json finds no key; the key came from `/login magpie` and lives in the credential store. ## 3. Switch to the Magpie manager ```text /manager ``` `Select model manager` offers `Providers` or `Magpie`. Switching recomposes the agent on the new manager, so it needs an idle application — mid-turn it answers `/manager requires an idle application`. **Success marker**: `model manager: magpie`, and the manager label next to the model name on the status bar changes from `Posoco` to `Magpie`. Two side effects worth knowing up front: - The Board service stops (if it was open): `Board service stopped because the model manager switched to magpie. Reopen it with /board.` - The choice is recorded: `model_manager` remembers the active manager, `manager_selections` remembers the model and effort each manager last used, and switching back restores them without re-picking. ## 4. Pick a model and a reasoning effort ```text /model ``` The list is the gateway's `/v1/models`, grouped under `magpie` (the gateway's routing groups get their own group); after picking, use the left/right keys to choose a reasoning effort. **Success marker**: `selected at effort (pending=false)`. `pending=true` is a different signal: the model recorded in settings is not in the current catalog, and the line continues with `(selection '' is pending: not in the catalog yet; requests will fail until a refresh provides it)`. Pick another one with `/model`, or refresh the catalog as in step 6. The decision slot is a provider-set account: the model `/decision` chose stays in `decision_model`, is left untouched while Magpie is active, and applies again when you switch back — no re-picking. ## 5. Verify three things All three must pass before this line counts as walked: gateway state, quota, and one real inference. Each has its own success marker. ### `/status`: gateway, selection, and catalog in one line ```text /status ``` Under the Magpie manager, `/status` is answered by the gateway extension, and its first line is plain language: ```text /status: connected to magpie ; selected at effort (pending=false); models; services: Route=Unknown Quotas=Unknown Limit=Unknown Usage=Unknown UsageRequests=Unknown Concurrency=Unknown ``` **Success marker**: the line starts with `connected to magpie`, and ` models` is not 0. The other possibilities on that line are exactly your triage entries: - `gateway offline:` followed by the reason — the gateway is unreachable; - `authentication failed:` followed by the reason (for example `/api/hello answered HTTP 401` or `403`) — the credential is wrong; - `invalid gateway response:` followed by the reason — the endpoint is not Magpie, or the address points elsewhere; - `disabled: the manager is configured with enabled = false` — the manager is switched off; - `not connected: no refresh has run yet` — no catalog refresh has succeeded yet. `services:` reports the availability of each observability endpoint (`Unknown`, `Accessible`, `Forbidden`, `NotSupported`, `TemporarilyUnavailable`); one you never called reads `Unknown`. A structured summary of the same facts follows the line. ### `/quota`: quota is readable ```text /quota ``` **Success marker**: a `Quotas` panel listing the quota cards the gateway reports — provider, account or plan, and each window's remaining amount and reset time. To force a re-read from the gateway, use `/quota refresh`. An unreadable quota says so explicitly: with no accessible card at all it is `No accessible quota cards.`; when the gateway refuses the call, `/quota` answers `Magpie quota unavailable or forbidden`. A failed quota read does not affect inference. ### Run one real turn Ask anything. **Success marker**: a streamed reply arrives, and the `selected` in `/status` is the model you just picked. ## 6. Troubleshooting Read the `/status` line first; it already states the conclusion. | Symptom | Most likely cause | What to do | | --- | --- | --- | | `/status` says `gateway offline:` followed by the reason; `/login magpie` keeps failing | The gateway is not running or unreachable, the port is wrong, or a firewall blocks it | Go back to step 1, check the process and the port, probe `/api/hello` with `curl`; if the port is not `3425`, correct `magpie.base_url` | | `/status` says `invalid gateway response:` followed by the reason | `base_url` is wrong: it points at another service, was written with a path, or the gateway identity does not match (`/api/hello` returns a `name` that is not `magpie`) | Write `base_url` as an origin only (`http://127.0.0.1:3425`), then re-verify with `/login magpie` | | `/status` says `authentication failed:` followed by the reason; a remote gateway never connects | The credential is missing or wrong | `/login magpie` → `Remote Gateway`, re-enter the `Gateway Key`; also confirm the `gateway_key` in settings.json sits in the right place — in the wrong place it only warns and never takes effect | | Startup or the switch fails outright, with `settings.model_manager must be providers or magpie`, `settings.magpie.enabled must be a boolean`, or `settings.magpie.base_url must be a string` in the error | A setting has the wrong type | Fix it to the strict values in the [Settings reference](/cetas/en/reference/settings/): `model_manager` is only `providers` or `magpie`, `magpie.enabled` is only a boolean. A plausible-looking string is not accepted | | `/model` does not show a model the gateway just added | The catalog is read at agent startup and on manual refresh; there is no background polling under the Magpie manager | Run `/magpie_refresh`; success is `catalog refreshed: models` | | `/status` says `disabled: …` | `magpie.enabled` is `false` | Set it back to `true`, or run `/login magpie` again | An unreachable gateway does not prevent Cetas from starting: the session comes up normally, `/status` honestly reports offline, and `/model` answers `Model catalog unavailable`. The complete lists of commands and settings are in [Commands](/cetas/en/reference/commands/) and the [Settings reference](/cetas/en/reference/settings/). # MCP > Connect external tool servers, at user or project scope. Source: https://colmugx.github.io/cetas/en/configuration/mcp/ · Markdown: https://colmugx.github.io/cetas/en/configuration/mcp/index.md MCP servers extend what the agent can do — a database, an issue tracker, an internal API. Cetas reads their configuration from two places: ```text /.cetas/mcp.json # user level /.mcp.json # project level ``` Project entries win for matching server names, so a repository can pin the server set it needs without touching anyone's home directory. > **The schema belongs to the server** > > This page deliberately does not define an MCP JSON schema. Server fields are > interpreted by the MCP extension (and, for editor-supplied servers, by your > editor). Copy the shape from the server's own documentation rather than from a > generic example here. ## When servers connect | Surface | Default | Change | | --- | --- | --- | | Terminal | Connected on the first turn | — | | Editor (ACP) | Connected lazily on the first turn | `CETAS_MCP_MODE=eager` connects at startup | | Editor-supplied | Always eager | The editor owns those servers | Lazy is the default because startup should not block on a server you may not use this session. A server that fails to connect surfaces as a tool failure, not as a broken launch. ## Which servers a surface sees - The terminal and the editor compose the MCP extension, so both read the two files above. - An editor can additionally supply server definitions over ACP. Those belong to the editor: Cetas does not write them back, and they are not visible to the terminal. ## Debugging a connection ```bash CETAS_DEBUG_MCP_CATALOG=1 cetas-acp ``` writes each session's tool catalog to `/.cetas/debug/-catalog.json` at assembly time — the fastest way to answer "did the server connect, and what did it actually expose?". For wire-level detail use `CETAS_DEBUG_WIRE=1`. Start with the catalog: a server that connects but exposes no tools is a server problem, not a Cetas problem, and the catalog makes that distinction obvious. # Models > Model slots, effort, and the decision model selection. Source: https://colmugx.github.io/cetas/en/configuration/models/ · Markdown: https://colmugx.github.io/cetas/en/configuration/models/index.md Cetas identifies a model slot with a `provider/model` id, for example `deepseek/deepseek-flash` or `moonshot/kimi-k3`. ## Two slots, never interchangeable The conversation model and the decision model cannot be swapped, and the two pickers enforce it: ```text /model # conversation slots; rejects a decision slot /decision # decision slots, with the active one marked; rejects a chat slot ``` `/decision` with no argument lists what the configured providers offer. A build that ships no decision backend simply has nothing to offer here. The decision model matters for one setting in particular: `permission auto` routes every non-read tool call through a semantic gate, and that gate needs a decision model to judge — see [Permissions](/cetas/en/configuration/permissions/). ## Where the selection lives, and who changes it The active selection lives in settings — fields in the [Settings reference](/cetas/en/reference/settings/). Three ways to change it: | Surface | Behavior | | --- | --- | | Terminal | Successful `/model`, `/effort`, `/decision` changes are persisted | | Editor (ACP) | Successful `model` / `effort` config-option changes are persisted | | Automation (`cetas-run`) | `--model` and `--effort` are run-scoped overrides and are **not** persisted | If provider configuration changes make the previous selection unavailable, Cetas falls back to an available default instead of refusing to compose. ## Model lists Discovered model catalogs are cached in `/.cetas/model_lists.json`, one record array per provider. Pickers keep working from a warm cache, and a provider's cached list is refreshed when it is re-discovered. ## Custom models A provider that is not one of the built-ins is an OpenAI-compatible endpoint you declare yourself, and model capabilities (context window, image input, efforts) are declared in the same place. See [Custom and self-hosted models](/cetas/en/configuration/custom-models/). # Configure by Conversation > Describe the change in your own words and let the agent write the settings. Source: https://colmugx.github.io/cetas/en/configuration/natural-language/ · Markdown: https://colmugx.github.io/cetas/en/configuration/natural-language/index.md There is no configuration DSL to learn. A Cetas session has file tools, and the settings file is a file — so the fastest path to a configuration change you cannot remember the shape of is to describe it: ```text Add a provider called my-gateway pointing at https://llm.internal.example/v1, declare the qwen3-32b model with a 128k context window, and set it as my model. ``` The agent reads the settings, makes the edit, and reports what it changed. This is the intended path for anything a picker does not cover: provider entries, model metadata, subagent kinds, workflow budgets. ## Why this works The configuration is ordinary JSON in one file, and Cetas ships a manual for configuring itself — so the agent answers setup questions from that manual rather than from a memorised guess about somebody's settings schema. That is also why you should not expect it to invent provider-specific keys: it is supposed to tell you when it does not know the shape. ## Ask for the diff Configuration mistakes are cheap to review and expensive to debug. Ask for the change, then ask what changed: ```text Show me the diff of what you just wrote. ``` Prefer this over accepting a "done" for anything that touches `providers`, `workflow`, or the selected model. ## Verify with a command Anything with a command should be confirmed by the command, not by prose. The command reads the file back through the same code the product uses: | Change | Verify with | | --- | --- | | Provider or credential | `/login ` | | Models available | `/model` | | Decision slot | `/decision` | | Effort | `/effort` | | Permission posture | `/permission` | ## What the agent still cannot do Tool permissions are not suspended for configuration. If the session is `readonly`, the agent cannot write the settings file either — switch posture first with `/permission workspace_write`, or make the change yourself. Two more boundaries worth knowing: - A change that affects the system prompt — instructions, provider identity, the skill catalog — lands in the **next** session. The running one keeps the prompt it started with. - The session will not start and the settings look suspect? A malformed settings file is never auto-repaired — fix or restore it; see [Settings reference](/cetas/en/reference/settings/). ## When to use it, and when not to Use conversation for: new providers, model metadata, subagent kinds, workflow budgets, anything one-off or unfamiliar. Edit the file directly (or copy it between machines) when you are provisioning a team, reviewing a change, or matching a known-good configuration — and prefer `/login` over an inline `api_key` so secrets stay in the credential store. # Permissions > The five postures that decide what the agent may touch, and how to roll them out. Source: https://colmugx.github.io/cetas/en/configuration/permissions/ · Markdown: https://colmugx.github.io/cetas/en/configuration/permissions/index.md Every session runs under exactly one permission posture. It is the single most important knob you will set, because it decides what happens when the agent wants to do something rather than read something. ```text /permission readonly ``` The switch works mid-turn. The posture belongs to the session — a cautious choice does not have to be a global decision. ## The five modes | Mode | Reads | Writes, shell, unknown tools | | --- | --- | --- | | `readonly` | Pre-approved, including provably read-only shell | **Rejected** — no prompt, no override | | `workspace_write` | Pre-approved | Gated through the approval prompt | | `interactive` | Pre-approved | Gated through the approval prompt, including inspection-level side effects | | `auto` | Pre-approved | Judged per call by the decision model; a decline is steering, not an error | | `yolo` | Pre-approved | Pre-approved — the approval prompt is never shown | Two of these deserve detail. **`readonly` is silent and absolute.** It needs no UI and no human: mutation and non-read shell are simply refused. Use it for review jobs, reporting, and the first week of a team rollout. **`auto` is a semantic gate, not a rubber stamp.** Each non-read call goes to the composed decision model; a likely-risky operation or a low grant probability is rejected. There is no deterministic fallback: without a decision model the mode cannot compose, and `/permission auto` refuses the switch. Set the backend with `/decision` — see [Models](/cetas/en/configuration/models/). **`yolo` covers tool execution only.** It never approves a submitted plan; plan verdicts stay with the review flow. ## What "approved" remembers When a prompt is answered *Yes for this session*, the grant is cached for the rest of that agent's lifetime — nothing is persisted to disk: - write-class and unknown tools cache **per tool name** — approving `edit` once approves every later `edit` - shell tools cache **per command-segment scope**: the command is split on `&`, `|`, `;` and newlines and each segment scopes to its first word, so approving `moon check` does not approve `rm -rf` in the same pipeline A new session starts with an empty grant cache. ## Choosing a posture per surface | Surface | How to set it | | --- | --- | | Terminal | `/permission ` | | Editor (ACP) | Session config option `permission`, or `CETAS_PERMISSION_MODE` at startup | | Automation | `--permission `, or `--yolo` | | Unset at startup | `yolo` for the ACP host | `CETAS_PERMISSION_MODE` is deliberately tolerant in one direction only: an unrecognised value warns once and falls back to `workspace_write`. A typo never widens the posture. ## A rollout that does not need a meeting 1. `readonly` for everyone. Prove that reading behaviour is sane and that the answers are worth acting on. 2. `workspace_write` for the people who asked to act on them. Now every write is a prompt, and the prompts become the review habit. 3. `interactive` or `auto` for teams that want steering instead of confirmation. `auto` needs a decision model, so this is where `/decision` earns its keep. 4. `yolo` only for unattended, bounded work — CI with `readonly`, or a purpose- built automation with a narrow task. The failure mode to avoid is starting at `yolo` because it is quiet. It is quiet until it is not. # Providers > The provider extensions Cetas can compose, their ids, and how login works. Source: https://colmugx.github.io/cetas/en/configuration/providers/ · Markdown: https://colmugx.github.io/cetas/en/configuration/providers/index.md Provider configuration lives under `providers` in `/.cetas/settings.json`. Cetas supplies the settings and credential sources; each provider extension owns its endpoints, protocol details, model capabilities, and login behaviour. ## Registered providers These ids are registered by the core. They are also the ids you pass to `/login` and use as the first half of a `provider/model` slot. | Id | Provider | Login methods | | --- | --- | --- | | `deepseek` | DeepSeek | API key | | `kimi` | Kimi | API key, OAuth | | `openai` | OpenAI | API key, OAuth | | `opencode` | OpenCode Zen | API key | | `opencode-go` | OpenCode Go | OAuth | | `zai` | Z.ai | API key | | `zai-coding-plan` | Z.ai Coding Plan | API key | | `openrouter` | OpenRouter | API key | | `typesafe` | Typesafe `jev` decision backend | API key | A provider that owns several login methods gets a method picker; a provider with only one skips the picker and asks for the credential directly. ## Provider ids Ids are restricted to letters, digits, `_`, and `-`, because they are also used in settings keys, credential filenames, and login targets. `opencode` is claimed by OpenCode Zen, so a `providers.opencode` settings entry resolves to that factory rather than falling through to the compatible adapter. ## Everything else is OpenAI-compatible Any `providers` key that is neither registered above nor a collision becomes an OpenAI-compatible provider. That is the supported route for a gateway, a proxy, or a self-hosted deployment with an OpenAI-shaped API — see [Custom and self-hosted models](/cetas/en/configuration/custom-models/). Because the compatible factory list is built from settings, custom providers participate exactly like built-in ones: `/login`, `/model`, catalog refresh, and the model cache all treat them the same. ## Login ```text /login ``` The picker lists providers this build can compose. For a custom provider, log in against its id: ```text /login my-gateway ``` Credential files are written under `/.cetas/credentials/` and shared by every surface. On a machine with no terminal handy, `cetas-run --login` does the same for the runner. ## On schemas There is no single generic JSON schema covering every provider, and this page does not invent provider-specific keys. Prefer `/login` and `/model`; treat the settings file as the extension's business. For a private endpoint, the compatible adapter's small shape is documented in [Custom models](/cetas/en/configuration/custom-models/). # Skills > Load reusable instruction packs only when a task needs them. Source: https://colmugx.github.io/cetas/en/configuration/skills/ · Markdown: https://colmugx.github.io/cetas/en/configuration/skills/index.md A skill is a directory with a `SKILL.md`: frontmatter plus instructions the agent can follow for a specific kind of work. Skills are how Cetas gets domain competence without putting all of it in the prompt — and access to how Cetas itself is configured and used. ```text /skills ``` lists what was discovered in this session. ## Three tiers of disclosure Loading everything at startup would be wasteful and noisy, so skills open in stages: 1. **Catalog** — at discovery, Cetas validates each `SKILL.md` and keeps only its metadata. The instruction body never enters the context. 2. **Activation** — when the task calls for it, the agent activates exactly one skill by name. Cetas re-reads and re-validates that file and returns its instructions, listing bundled resources without reading them. 3. **Resource read** — the agent opens one named resource inside that skill's directory, on demand. That last boundary is enforced: a resource path is resolved through canonical real paths and must stay inside the skill directory. ## Where skills are found | Scope | Path | | --- | --- | | User | `/.agents/skills//SKILL.md` | | Repository | `.agents/skills//SKILL.md`, walking ancestor directories up to the repository root | Repository skills come from a checkout, which is untrusted input by definition — the same caution you would apply to any script in a repository applies here. A host can exclude repository skills entirely; Cetas does not invent a trust decision on your behalf. Skill directories may be symlinks, but the resolved package must stay inside the repository boundary unless the host opts into external packages. ## Writing one ```markdown --- name: repo-map description: How to navigate this repository --- ## Layout ... ``` The frontmatter is validated at discovery: a skill that fails validation is skipped rather than partially loaded, and name collisions are resolved deterministically instead of depending on directory order. Because bodies are only read on activation, a long skill costs nothing until someone uses it. Write the frontmatter for discovery — the description is what decides whether the agent ever opens the file. # Subagents > Delegate work to child agents with their own tools, model, and permission posture. Source: https://colmugx.github.io/cetas/en/configuration/subagents/ · Markdown: https://colmugx.github.io/cetas/en/configuration/subagents/index.md A subagent is a child agent the main session spawns for a bounded piece of work. It gets a fresh model selection, a fresh permission posture, and its own read-before-write state — and it cannot reach around the parent: only core tools the host can reconstruct are inherited. Typical uses: a read-only reviewer over a diff, a narrow fixer with two tools, a research child that may fetch but never write, or several children in parallel when the work splits cleanly. ## How work is handed out The agent spawns children through its `subagent` tool. Children that are independent can run as one parallel wave, and long ones can run in the background so the parent keeps working. Parent and child can exchange questions throughout: a child that needs a decision asks, and the answer arrives in the same session. Each child's transcript lives in memory for the lifetime of the parent session, so a resumed conversation can pick the child back up rather than restart it. ## Kinds: reusable presets A *kind* is one subagent preset — name, description, tool whitelist, model, effort, permission mode, and a prompt template. Two places define them. **Files** live in `.cetas/agents/.md`, either per user or per project: ```markdown --- name: reviewer description: Read-only reviewer for diffs tools: read, grep, glob effort: low mode: readonly --- You review changes without touching the working tree. Instructions from the caller: {{instructions}} ``` The frontmatter `name` must match the file stem. Unknown keys are ignored; a missing `name` / `description`, a bad list item, an unterminated block, or an unknown `mode` is a parse error — bad frontmatter is rejected, never repaired. Lists accept a comma-separated string or a dash list. **Settings entries** are lighter and live in `settings.json` under `subagent.kinds`, with the same field names in JSON. A `body` may be omitted, in which case a generic template is built from `name` and `description`. Precedence per kind name: project `.md` → user `.md` → settings kinds → built-in. ## Tool whitelists Three states, deliberately distinct: | `tools` | Meaning | | --- | --- | | omitted | Inherit the host's default core tool set | | `[]` | No tools at all | | a list | Exactly those tools | ## Defaults and limits The subagent's default model, effort, and every limit live in the `subagent` section of settings; each field's default is in the [Settings reference](/cetas/en/reference/settings/). Unconfigured means defaults. The model-selection precedence chain: explicit argument → kind binding → `default_model` → the parent's live selection. ## Notes - Children do not inherit host-dynamic tools or decorators. A kind that needs a tool names it explicitly and gets it if the host can reconstruct it. - A child's permission posture is its own. A `readonly` child cannot write even when the parent is `yolo`. - `spawn_budget` is the guard rail that stops a runaway plan from turning into a hundred agents; raise it deliberately, not reflexively. # Editor (ACP) > Drive the same Cetas agent from an Agent Client Protocol editor — Zed and Lody walkthroughs. Source: https://colmugx.github.io/cetas/en/editor/ · Markdown: https://colmugx.github.io/cetas/en/editor/index.md `cetas-acp` serves Cetas over the [Agent Client Protocol](https://agentclientprotocol.com/) on stdio. Any ACP client can launch it, so the same agent you know from the terminal shows up inside your editor with its own permission UI. ## Before you connect The editor host reads the same home directory as every other surface, and it refuses to start without a provider — an agent with no model cannot serve a prompt. So configure once, in the terminal: ```text /login /model ``` Then get the binary: extract `cetas-acp` from a [release archive](/cetas/en/getting-started/installation/), or build it from a checkout. ## Zed Add a top-level `agent_servers` entry to Zed's settings: ```json { "agent_servers": { "Cetas": { "type": "custom", "command": "/absolute/path/to/cetas-acp", "args": [], "env": {} } } } ``` Use `cetas-acp.exe` on Windows. If your Zed version expects a different schema, follow [Zed's custom agent instructions](https://zed.dev/docs/ai/external-agents#custom-agents). Then open the agent panel and pick **Cetas**. Zed identifies itself during `initialize`, so this session's transcript files under `/.cetas/sessions/zed/`. ## Lody Lody treats external agents as an *Agent Config* with a launch command. Register Cetas once: 1. Open **Settings → Agent Config** and add a config. 2. Name it `Cetas`. 3. Set **CLI Type** to **Custom ACP**. 4. Put the absolute path in **Launch command** — `/absolute/path/to/cetas-acp`. 5. Add environment variables you need in the same Agent Config (see below). 6. Click **Test**. Lody launches the agent and reads its capabilities and model list; a provider must already be configured or this step fails. 7. Save, then pick the config when you start a conversation. Lody parses the launch command into a command plus arguments — quotes are supported, but pipes, redirects, globs, and `$VARS` are not evaluated. Put environment variables in the Agent Config instead of the command. Lody sessions land in `/.cetas/sessions/lody/`. ## What each session gets Every ACP session gets its own agent and its own mutable machinery — model router, permission policy, MCP bridge, transcript store, in-flight turn — so prompts on different sessions run concurrently without cross-wiring approvals. Provider settings and model catalogs are assembled once and shared read-only. The client owns the chat record: it stores the conversation and the session id, and hands the id back on `session/resume`. Cetas persists the committed transcript to disk so a restart resumes from there rather than from memory. ## Session configuration ACP advertises config options for: - `model` — a successful change is persisted as the next launch's selection. - `effort` — persisted when the active model exposes reasoning-effort choices. - `permission` — runtime-only and session-scoped; deliberately not persisted. Changes arrive through `session/set_config_option`. For connection failures, read the editor's ACP log first, then the agent's stderr — all diagnostics go there, because stdout carries JSON-RPC frames only. ## Environment | Variable | Effect | | --- | --- | | `CETAS_HOME` | Overrides the platform home; state lands in `/.cetas` | | `CETAS_PERMISSION_MODE` | Startup posture: `readonly`, `workspace_write`, `interactive`, `auto`, `yolo`. Unset means `yolo`; an unrecognized value warns once and falls back to `workspace_write` | | `CETAS_MCP_MODE=eager` | Connect configured MCP servers at startup instead of on the first turn | | `CETAS_DELEGATE_FS=host` | Route file reads and writes through the editor's `fs/*` reverse calls instead of the local filesystem | | `CETAS_DEBUG_WIRE=1` | Append the session's wire traffic to `/.cetas/debug/-wire.jsonl` | | `CETAS_DEBUG_MCP_CATALOG=1` | Dump the session's tool catalog to `/.cetas/debug/-catalog.json` | MCP setup is covered in [MCP](/cetas/en/configuration/mcp/); the full variable reference is in [Environment Variables](/cetas/en/reference/environment-variables/). # FAQ > Frequently asked questions about Cetas, grouped by where you start — whether it fits you, how it differs, and two things it deliberately leaves out. Source: https://colmugx.github.io/cetas/en/faq/ · Markdown: https://colmugx.github.io/cetas/en/faq/index.md Pick by where you start: - [Is Cetas for me?](/cetas/en/faq/is-cetas-for-me/) — what non-coders, developers switching agents, and source-reading experts each need from where they stand. - [How is Cetas different from other coding agents?](/cetas/en/faq/how-different/) — four structural differences, when switching is worth it, when it is not yet. - [Why doesn't Cetas bundle Caveman?](/cetas/en/faq/why-doesnt-bundle-caveman/) — of caveman's six features, which have counterparts in cetas, which do not, and how to install caveman's skills directly. - [Why does cetas no longer ship rtk?](/cetas/en/faq/why-no-rtk/) — cetas once integrated rtk; an independent benchmark explains the real cost of truncated information, and how to wire it back if you want it. # How is Cetas different from other coding agents? > Four structural differences — when switching is worth it, and when it is not yet. Source: https://colmugx.github.io/cetas/en/faq/how-different/ · Markdown: https://colmugx.github.io/cetas/en/faq/how-different/index.md This page does not compare individual products. It states four structural differences, each verifiable by hand once installed — no marketing required. ## Work leaves a trail, and handoffs rest on it Board turns one requirement into a ticket graph: tickets with unmet dependencies hold still, finished ones stop at the review gate. Every ticket keeps its diff, its test evidence, and its history; the records are local, and your agent can query them itself — ask why a piece of code exists and it can answer. Reopen the board the next day and continue; the tickets are still there. The records are the handoff document. See [Board](/cetas/en/features/board/). ## Boundaries are configuration, not pleas A subagent's tool list and permission posture live in its definition file: three properties make a read-only reviewer, and it stays powerless even under a `yolo` parent. The five permission postures are your per-session decision, from `readonly` to `yolo`; plan mode writes nothing until you approve. See [Subagents](/cetas/en/features/subagents/) and [Permissions](/cetas/en/configuration/permissions/). ## The context bill follows a different algorithm Research goes to subagents and your main window receives summaries; loops and filters go to a sandboxed program and intermediate results never enter context at all. The same batch of work, billed as a different thing entirely. See [Subagents](/cetas/en/features/subagents/) and [Bunraku](/cetas/en/features/bunraku/). ## Machine-readable is the docs' default form The site ships `llms.txt` and `llms-full.txt`, and every page has a `.md` source. Letting another agent read the docs before deciding to install is a supported way to use them. See [/llms.txt](/cetas/llms.txt). ## When switching is worth it, and when it is not yet **Worth it**: you want to know where its past work can be checked; you want reviewers that structurally cannot edit; you care about the context bill; you have scripting or CI scenarios — `cetas-run` is one turn per process, and success is an exit code. **Not yet** — these do not exist today, so do not force it: - `/sessions` lists sessions for the current project only; there is no cross-project view, and resuming across surfaces is planned behavior, not something to rely on today; - no graphical interface — the terminal is the first-class entry; - no team-collaboration features: no shared sessions, no org management, no centralized permissions; every piece of state lives on its own machine; - it does not manage provider accounts for you — models are yours to register and connect; - it says so itself: experimental. The npm build is the stable one; pin versions, read the [changelog](/cetas/en/changelog/), upgrade deliberately. For the deeper argument — what makes this kernel carry weight — see the "Why Posoco" section of the [Introduction](/cetas/en/introduction/). # Is Cetas for me? > An answer per starting point — non-coders, developers switching agents, and experts who read source. Source: https://colmugx.github.io/cetas/en/faq/is-cetas-for-me/ · Markdown: https://colmugx.github.io/cetas/en/faq/is-cetas-for-me/index.md Cetas is a coding agent that runs on your own machine: you state what you want in plain language, it reads files, edits code, and runs commands, showing you everything it does. That sentence holds for everyone; whether it *fits* depends on where you start. This page answers per starting point. ## I don't write code — can I still use it? Yes, and no programming experience is required. What individual creators do with it differs from what engineers do, but the path is the same: - Have it build a small tool or a personal website: you describe the result, it writes, you look and ask for changes; - Have it organise a batch of local files (renaming, sorting, reformatting) — stating the rules is enough; - Have it read a long document or a folder and summarise or search it for you. You need four things, each explained in the glossary: a computer, a [terminal](/cetas/en/getting-started/glossary/#terminal), [Node.js](/cetas/en/getting-started/glossary/#nodejs) for the recommended JS host (optional for Native), and an account with a model [provider](/cetas/en/getting-started/glossary/#provider). Then follow [Installation & First Run](/cetas/en/getting-started/installation/) — when a word is unfamiliar, look it up in the [glossary](/cetas/en/getting-started/glossary/). One thing to be clear about: it edits files; it is not magic. You can see every step it took, and you can rewind — which is exactly why it fits real work better than copy-pasting AI answers. ## I write code and I'm switching from another agent See the next page: [How is Cetas different from other coding agents?](/cetas/en/faq/how-different/) — four structural differences, and when switching is worth it. ## I know this space better than the author does The docs state what there is to state and stay out of your way: - A machine-readable site: [/llms.txt](/cetas/llms.txt) and [/llms-full.txt](/cetas/llms-full.txt), plus a `.md` and `.mdx` source for every docs page; - Auditable state: one [home directory](/cetas/en/configuration/cetas-home/) holding configuration, credentials, and sessions on disk — no second place for state to hide; - Five [permission postures](/cetas/en/configuration/permissions/) and session rewind, so widening or narrowing needs no product changes. Its experimental nature is stated plainly: the npm build is the stable one — pin a version, read the [changelog](/cetas/en/changelog/), upgrade deliberately. # Why doesn't Cetas bundle Caveman? > Of caveman's six features, which have counterparts in cetas, which do not, and how to install caveman's skills directly. Source: https://colmugx.github.io/cetas/en/faq/why-doesnt-bundle-caveman/ · Markdown: https://colmugx.github.io/cetas/en/faq/why-doesnt-bundle-caveman/index.md **Short answer: Cetas and Caveman share some optimization goals, but Cetas focuses on improving how the agent works rather than adding another proxy layer by default. You can still use the Caveman skill with Cetas.** [Caveman](https://github.com/JuliusBrussee/caveman) is an open-source project designed to reduce token usage in AI coding agents. Its features include shorter responses, smaller tool outputs, model routing, and reusable scripts. These are worthwhile ideas. But not every feature needs to be integrated into Cetas in the same way. ## What does Cetas already do? ### Keep unnecessary information out of context in the first place With `run_code`, Cetas can execute MoonBit programs in a sandbox. The program can call multiple tools, iterate over results, and filter data before returning a final answer to the model. Intermediate results do not need to enter the conversation context at all. Cetas can also delegate independent investigations to subagents, keeping the main conversation focused on the findings rather than every intermediate step. ### Manage context during long conversations Cetas supports automatic and manual context compaction. As a conversation approaches the model's context limit, Cetas can summarize earlier work to make room for subsequent steps without requiring you to start over. ### Reduce unnecessary tool and webpage content Cetas uses lazy tool loading to avoid exposing every available tool at once. Its built-in `webfetch` also removes some irrelevant HTML, converts pages into model-friendly Markdown, supports paginated reading, and caches fetched documents. These mechanisms are not identical to Caveman's implementations, but they address a similar problem: keeping irrelevant information out of the model's working context. ## What's still missing? There is a meaningful gap, especially in **automatic compression of tool results**. Imagine a build producing tens of thousands of log lines when only a handful of errors matter. Cetas does not yet have a universal, recoverable compression mechanism for every type of tool output. That is an area we want to improve. However, we do not want to shorten output by silently removing information that the model may need. Omitted content should be recoverable, error diagnostics should remain accessible, and improvements should be measured against the cost and success rate of complete tasks. A smaller tool response is useful only when it helps the agent finish the job reliably. ## Why doesn't Cetas automatically choose models? This is a deliberate product decision. Models differ in cost, speed, context capacity, and behavior. But there is no dependable rule that guarantees one particular model is always the right choice for a particular category of task. Even seemingly similar tasks can demand different capabilities depending on the codebase, constraints, and your preferences. **Cetas therefore leaves model selection and reasoning effort under your control.** We can help you understand model capabilities and costs, but we do not automatically replace your chosen model for each request. Our job is to make the model you choose work more effectively, not to decide which model you should use. ## Can I still use Caveman? Yes. If you prefer Caveman's shorter, more direct response style, you can install its skill: ```sh npx skills add JuliusBrussee/caveman ``` Cetas supports agent skills. Once installed, you can check that the skill is available through `/skills` and activate it when needed. Keep in mind that **installing the skill is not the same as installing Caveman's full proxy**. The skill mainly influences response style; it does not automatically enable Caveman's runtime-level tool-result compression. You can use the parts that suit your workflow without waiting for Cetas to bundle them. ## Am I missing significant token savings by not installing Caveman? That depends on your workload. If your tasks involve repeated file searches, code inspection, or programmatic data processing, Cetas already offers ways to avoid unnecessary context through `run_code`, subagents, and context management. If your workflow frequently produces large logs, JSON responses, or test output, Caveman's compression techniques may provide additional value. This is also where Cetas has room to improve. But shorter output does not always mean lower total cost. If a model has to rerun commands, reread files, or make additional calls because important details were removed, the final task may cost more—not less. **Our goal is not to make every tool response as short as possible. It is to reduce unnecessary token usage without compromising the agent's ability to complete the task.** That is why Cetas does not bundle Caveman today, while remaining open to incorporating its most useful ideas directly into the agent runtime. # Why does cetas no longer ship rtk? > cetas once integrated rtk. An independent benchmark explains why it is not shipped, and how to wire it back if you want it. Source: https://colmugx.github.io/cetas/en/faq/why-no-rtk/ · Markdown: https://colmugx.github.io/cetas/en/faq/why-no-rtk/index.md rtk (Rust Token Killer) is a command-line proxy: it rewrites commands like `pnpm test` or `go test -v ./...` into `rtk test`-style forms, compressing output before it enters the context. Its README promises 60–90% token savings — an attractive promise for anyone living in test output and build logs. cetas integrated it once. The repository's [posoco-ext-rtk](https://github.com/colmugx/cetas/tree/main/extension/posoco-ext-rtk) was written for exactly that: a tool-call hook handing every agent-initiated shell command to `rtk rewrite`, with the rewritten command then executed. We stopped shipping it. The reason is not the integration — the hook still works and the tests still pass — but rtk's premise itself. ## Compression has a price Compressing output means rtk makes editing judgments on the model's behalf: which lines matter, which can be dropped. It frequently drops the wrong ones. [JetBrains' independent benchmark](https://blog.jetbrains.com/ai/2026/07/rtk-claude-code-token-savings/) put numbers on it: Claude Code with rtk ran SkillsBench's 86 tasks in a paired A/B over 425 billed trials. The advertised 60–90% did not appear; at low reasoning effort each task was **7.6% more expensive** (p=0.004) with 13.8% more turns. Quality was unchanged — the model, fed truncated information, re-ran commands and re-read files, burning the savings back. At high reasoning effort the gap closed to zero, but rtk saved nothing at either level. The most telling detail is rtk's own scoreboard: across the whole run, `rtk gain` reported 96.2 million tokens saved while the actual bill for the same trials went up. The scoreboard measures against "raw output before compression", but most of that output would have been truncated by the host or discounted by caching anyway — the model never received it. The original article's conclusion is worth quoting: > a tool's self-reported savings are a claim about its counterfactual, not > about your bill. So we do not ship it. A tool that silently truncates information and then makes the model spend more turns recovering it saves display numbers and costs real money. ## Still want it? Two steps ```sh # Install rtk itself (brew, or per its repository) rtk --help # Wire up the cetas hook extension ``` The hook's wiring is fully demonstrated in the posoco-ext-rtk source and tests. Once connected, every shell command the agent runs passes through `rtk rewrite` first: rewritten when possible, executed verbatim otherwise. Whether it is worth it, borrow JetBrains' methodology: run it paired, measure the real bill, and ignore the tool's own scoreboard. # Features > Five things in the box, and what each one gets done for you. Source: https://colmugx.github.io/cetas/en/features/ · Markdown: https://colmugx.github.io/cetas/en/features/index.md `npm install -g @posoco/cetas` is the whole install. The five things below need no setup and no plugins. Each page covers one question: what work does it get done. - **Subagents** — The reviewer cannot edit your code. That is in its definition, not a polite request. - **Board** — One request becomes a graph you can review, with a record of every step. - **Bunraku (run\_code)** — Find 3 references in 40 files; your context only ever sees the 3. - **Model selection** — See who still has quota and what is genuinely cheaper, before you choose. - **Rate-limit guard** — A 429 at 3 a.m. waits for the reset and keeps going. ## The foundation in the box A second batch of capabilities gets no pages of its own; here they are in a few paragraphs. Permissions come in five postures. Between `readonly` and `yolo` sits `auto`: every non-read call goes to the decision model, risky ones declined, safe ones passed, no human babysitting. It requires a configured decision model and refuses to turn on without one. See [Permissions](/cetas/en/configuration/permissions/). Plan mode writes nothing until you approve. Skills open in three tiers; the catalog carries metadata, the body is read on activation. Ten skills do not add ten manuals to the prompt. Sessions land on disk throughout. `/sessions` browses, `/rewind` goes back to before a mistake, a restart continues where you were. The tool face includes astgrep, which searches code structure rather than text. Before a refactor, "where else is this interface used" returns call sites. ## Suggested order 1. [Model selection](/cetas/en/features/model-selection/) — cost and quality are decided here; you see numbers the same day. 2. [Subagents](/cetas/en/features/subagents/) — start with read-only work, the lowest risk. 3. [Board](/cetas/en/features/board/) — bring it in once the flow is stable, when you are running a pipeline. Related questions are answered in the [FAQ](/cetas/en/faq/). # Board > A local board where you create tickets, line up dependencies, run waves, and accept the work — with a record of every step. Source: https://colmugx.github.io/cetas/en/features/board/ · Markdown: https://colmugx.github.io/cetas/en/features/board/index.md Monday's standup leaves one heavy item: migrate auth from session cookies to JWT. You type `/board`, and a board opens in your browser. You break the goal into eight tickets: replace the session reader, change the middleware, move three callers, add regression tests. Each ticket carries more than a title and description — you can write the user story and the definition of done. "Tests are green" and "old cookie paths keep a compatibility layer" are two different kinds of finished. For tickets you cannot shape yet, a shaping agent refines them before work starts. Then you wire the dependencies: until the migration ticket finishes, the caller tickets stay in line. You hit run. Only the first wave moves; the blocked tickets wait quietly in Ready. The board shows where every ticket is, which agent is on it, how many attempts it took — all recorded. Forty minutes later the first wave settles. You open a ticket, read the diff and the test evidence. One is not right, so you request changes and it reworks; the rest you accept, and they move on. The next wave unlocks. By noon the work is visible on the board, not buried in a terminal's scrollback. ## What a ticket looks like A ticket has a title, a description, a user story, implementation suggestions, a priority, and a definition of done. These fields do real work: the execution agent receives the definition of done you wrote, and you accept the ticket against the same one. Tickets you cannot write clearly yet do not have to stay vague. Let the shaping agents (product owner, refiner) read the code and fill them in, then edit two lines yourself — machine drafts, you decide. ## Once it is running - **Dependencies are the scheduler.** A downstream ticket is not released until its upstream finishes; there is no "halfway through, the prerequisite wasn't done". - **Every ticket can run on its own model**: the rename on a cheap one, the hard kernel work on a strong one. - **Failure retries; interruption resumes.** An agent stuck on a ticket gets a retry with a different path; after a machine restart, unfinished tickets resume. - **Running is not finished.** A ticket rests at Review until you accept it — by design. An attempt succeeding is an execution fact; completion is your decision. ## When something goes wrong The board has three brakes. Pause withdraws the queued and lets running work settle; Stop ends the session's authorizations outright; Cancel precisely cancels a single execution. When unsure, Pause. Done with the board? `/board.stop` closes every local server. ## When to reach for it Work whose steps depend on each other and can each be accepted on its own shows the board at its best: migrations, multi-step features, batched refactors with regression tests. The ticket graph and its records are the handover document — next morning you open the board and continue where the tickets stand. A one-or-two-line change is faster said directly in the session. Don't board it. ## The switch and the budgets The first `/board` asks whether to enable the feature; confirming touches nothing but that setting — your model and provider configuration stay as they are. To set budgets by hand, every `workflow` limit is listed in the [Settings reference](/cetas/en/reference/settings/). Tickets and records live under `/.cetas/board/`, one namespace per workspace; the agent can query those records itself (`board_work`), which is why it can answer "why does this code exist" — and why it checks provenance before deleting or reverting code. # Bunraku (run_code) > Let the program do the looping; keep the context for people. Source: https://colmugx.github.io/cetas/en/features/bunraku/ · Markdown: https://colmugx.github.io/cetas/en/features/bunraku/index.md ## Why pay for 40 files when you need 3 A conventional agent reads one at a time. Forty tool calls and forty results recorded in context, even when the answer is three of them. You pay for all forty either way. `run_code` turns it around. The model writes a small MoonBit program; the program loops and filters itself, and only the 3 hits reach the conversation: ```moonbit let hits = [] for path in paths { match ctx.call("grep", {"pattern": "OldAuth", "path": path}) { {"error": _, ..} => () result => hits.push({ "path": path, "hit": result }) } } { "count": hits.length(), "hits": hits } ``` The intermediate results live and die inside the program. They never enter the context, so they never reach the bill. This is not compression; the content was never produced at all. ## Model-written code, run safely Every customer asks this, and it deserves a real answer. The program runs in a Wasm sandbox where filesystem, network, and process access are all denied. The only thing it can do is call the tools you allow; anything outside the list is an explicit error, never a quiet success. Programs are compiled. A type error is a compile error before anything runs, returned to the model as a bounded diagnostic (8K characters) it can fix itself. Return values are size-capped and programs can be cancelled. A loop written wrong does not become an invoice. ## When not to use it Two or three tool calls are faster made directly. The payoff starts with loops and filtering. Nested calls are serial for now, so this is not the tool for firing concurrent requests. # Model selection > See it before you choose: who has quota left, and what is genuinely cheaper. Source: https://colmugx.github.io/cetas/en/features/model-selection/ · Markdown: https://colmugx.github.io/cetas/en/features/model-selection/index.md ## Most choosing is done from memory Two wastes show up in every team. One keeps the priciest model on rename tasks; the other puts the smallest model on architecture work, then concludes the agent is bad. Both happen when nothing is visible at choice time. Cetas puts the information in front of the choice. ## Quota you can see before you pick ```text /model quick-pick ``` Three groups open up. **Limit** holds providers with a remaining usage window, ranked by what is left, colored by the worst window. **Balance** holds providers with money left. **Other** holds the rest. Exhausted rows sink to the bottom, disabled, so you cannot select a model that is bound to fail. The numbers are the provider's own, never estimated. A provider whose read times out drops out of the list; one name missing beats one number invented. ## Value, decided by data ```text /model openai pick ``` It ranks that provider's models by measured intelligence efficiency: real IQ minus the cost of tokens, dollars, and runtime, weighted 1.0, 2.0, and 0.5 per million tokens, per dollar, and per 10 minutes. Candidates need at least 30 measured samples to enter, and anything dominated on all three axes is dropped. No data from a provider means no ranking, and when it switches models it says so. ## Everyday browsing, enterprise gateways ```text /model ``` Tabs per provider, fuzzy search as you type, effort levels after you pick. A self-hosted gateway works the same way: add a key to `providers` and it becomes an ordinary tab beside `openai`. See [Custom models](/cetas/en/configuration/custom-models/). ## Conversation and decisions, two ledgers `/model` chooses the conversation model; `/decision` chooses the decision model that backs `permission auto` and judgment-shaped builds. A strong model to talk, a cheap one to judge, two budgets kept apart. `/manager` switches between the provider set and the Magpie gateway, each side remembering its own pick — see [Connecting the Magpie gateway](/cetas/en/configuration/magpie/) for the walkthrough from starting the gateway to a verified turn. # Rate-limit guard > A limit is waited out on its own — with a reset time, the run resumes by itself. Source: https://colmugx.github.io/cetas/en/features/rate-limits/ · Markdown: https://colmugx.github.io/cetas/en/features/rate-limits/index.md ## It is automatic When the current model comes from a subscription, the provider's limit signal carries a reset time. Cetas notes that time and resumes work on its own when it arrives — no alarm to set, no "try later" to remember, no progress bar to babysit. The boundary, stated just as plainly: the Cetas process is still running and the session has not changed. Walking away, sleeping, working on something else while it waits — all fine. Quit the process or switch sessions, and there is nothing to resume. ## 3 a.m., and nobody is watching Without the guard, long tasks die in a stupid place. Ninety minutes in, the provider answers 429, the agent says "quota exhausted, try later", and the message sits unread until breakfast. Five hours gone, and the task needs a full re-brief. The guard makes "try later" its own job. A limit without a reset time — most metered API keys — is probed on a capped backoff. You sleep. ## The wait does not lose your work Waiting is only useful if everything is still there on waking. The failed turn is written to disk before the session is marked recoverable; the other order returns a truncated context at the worst moment. While it waits you do something else, and when it resumes the task continues and the history keeps growing. You never re-describe anything. ## Do you need it Three questions: - Have you run tasks longer than an hour? - Does your provider meter quota in five-hour windows, with tasks that routinely cross one? - Have you ever set an alarm to come re-send a task? One yes and it is worth configuring. None, and you can leave it; installed, it stays out of the way. ## Two things it does not do It never moves your run to another provider or model on its own; that is `/model quick-pick`'s job, and the two do not reach into each other. And after enough failed attempts it stops and hands you the conclusion rather than knocking on the same door all night. # Subagents > The reviewer cannot edit code, and research never bills your context window. Source: https://colmugx.github.io/cetas/en/features/subagents/ · Markdown: https://colmugx.github.io/cetas/en/features/subagents/index.md ## A reviewer that cannot edit Ask an agent to review its own changes and you hit an old problem: it holds every tool you hold, and "report only, don't fix" is a polite request. Subagents make it configuration. Create `reviewer.md` under the project's `.cetas/agents/`: ```markdown --- name: reviewer description: Read-only reviewer for diffs tools: read, grep, glob mode: readonly --- You review changes without touching the working tree. ``` Three fields of front matter define a read-only reviewer. It cannot see `write` and cannot run `bash`; there is no door to reach through. A `yolo` parent changes nothing, because the posture belongs to the child. ## Research that never bills your window "Trace the auth flow across auth, billing, and jobs." The usual way reads sixty files into your context, then you pay for `/compact` three times. Hand it to subagents. Three child sessions read in parallel and the main window receives three summaries. Those sixty files never enter your context, and you are never billed for them. ## Three lines to get started - `/.cetas/agents/` for your whole machine, the project's `.cetas/agents/` to travel with the repository. - `tools` omitted inherits the defaults; `[]` means none; a list means exactly those. - Concurrency and totals have defaults (16 per wave, 4 concurrent, 64 spawns per session), tunable in `subagent.limits`. A plan gone wrong stops at the limit. There is no special command. Say what you want: "Use reviewer on my uncommitted changes, report only." When it needs a call it stops and asks; the answer lands in the same session. # Getting Started > Start with recommended Cetas JS or choose optional Cetas Native, then reach your first message. Source: https://colmugx.github.io/cetas/en/getting-started/ · Markdown: https://colmugx.github.io/cetas/en/getting-started/index.md Start with Cetas JS from npm (recommended), or choose the Native terminal via Homebrew/Scoop if you prefer no Node.js. Both use the same agent core but have different host-specific features. The guide takes you to your first message. ## New to coding agents? You do not need any programming experience from here. Cetas is an assistant that runs on your own machine: you state what you want, it reads and edits files and runs commands, showing you every step. You need four things: 1. A macOS, Linux, or Windows computer; 2. A [terminal](/cetas/en/getting-started/glossary/#terminal) — the typing window where Cetas lives; 3. [Node.js](/cetas/en/getting-started/glossary/#nodejs) 24+ for the recommended JS version; **not needed** for Native; 4. An account with a model [provider](/cetas/en/getting-started/glossary/#provider) (say DeepSeek or OpenAI); first-time users create an [API key](/cetas/en/getting-started/glossary/#api-key) on their site. If you are still deciding, read [Is Cetas for me?](/cetas/en/faq/is-cetas-for-me/). Ready? Head straight to [Installation & First Run](/cetas/en/getting-started/installation/) — it starts from zero and every term links to an explanation. ## Already familiar with these? - **Installation & First Run** — JS via npm, Native via Homebrew/Scoop or direct download, then your first message. - **Glossary** — Terminal, npm, provider, API key — one short paragraph per term. Deploying inside a company with private infrastructure? Read [Custom and self-hosted models](/cetas/en/configuration/custom-models/) first and skip a detour. For how Cetas compares with other coding agents, see [this page](/cetas/en/faq/how-different/). # Glossary > Every term you need for the first run — terminal, npm, provider, API key — explained without assuming a coding background. Source: https://colmugx.github.io/cetas/en/getting-started/glossary/ · Markdown: https://colmugx.github.io/cetas/en/getting-started/glossary/index.md This page does one thing: explain, without a coding background, every term you meet on the way from install to your first message. Three groups, in the order you meet them. When a word is unfamiliar, look it up here and continue. ## Before installing ### Terminal The window where you talk by typing: on macOS it is called Terminal (search it in Spotlight), on Windows use PowerShell (search the Start menu), and on Linux you almost certainly have one. Cetas lives there. ### Node.js The runtime that makes Cetas go — think of it as the engine. You need version 24 or newer; if you have never installed it, download the LTS build from [nodejs.org](https://nodejs.org/) and follow the installer. Installing Node.js also gives you the `npm` command. ### npm The package manager that ships with Node.js — think an app store for developer tools. `npm install -g @posoco/cetas` means: install Cetas from that store, so it is available everywhere on this machine. ### Project directory (workspace) The **one folder** you want Cetas to work in. Reads, edits, and shell commands all happen inside that folder — which is why you enter it before starting. No project yet? A freshly created empty folder works fine. ### Repository A code or documentation folder under version control (usually git). If you do not have one yet, ignore this word: an empty folder is enough to start. ## Models and providers ### Provider The company that supplies the model, such as DeepSeek, OpenAI, or Kimi. Cetas does not ship a model of its own; it calls the provider you pick. First-time users need an account with one of them. ### API key A string the provider issues to you — think key and account in one: it proves the calls are yours and bills them to you. Create it on the provider's "API Keys" page. Cetas stores it only on your own machine. ### OAuth The other way to sign in: instead of copying a key, you approve once in the browser and the provider hands the credentials to Cetas directly. If `/login` offers a browser option, that is OAuth. ### Model The "brain" a provider supplies, such as `deepseek/deepseek-flash`. One provider usually offers several, differing in capability and price; `/model` picks between them. ### Reasoning effort How hard the same model thinks: higher effort is smarter, slower, and pricier. ### Decision model A separate small model that serves judgment calls (such as the permission gate), kept apart from the conversation model. You can ignore it on day one. ### Tokens and context Models meter and bill by tokens — roughly one Chinese character or half an English word each. The context is everything the model can "see" in one session; when it fills up, Cetas compacts it automatically. ## While using it ### Permission posture The session-level safety switch that decides whether the agent asks before it acts: `readonly` look only, `workspace_write` confirm before writing, `interactive` / `auto` / `yolo` progressively looser. `workspace_write` is the right setting for day one — see [Permissions](/cetas/en/configuration/permissions/). ### Session One full conversation with the agent, automatically journaled under `/.cetas/sessions/`. `/sessions` reopens an old one and `/rewind` walks it back to before a mistake — nothing needs "saving". ### Slash command A command starting with `/` (`/login`, `/model`, `/help`). It executes immediately, without going through the model. ### Cetas home (`/.cetas`) The single directory holding all durable state: configuration, credentials, sessions, caches. `` means your user directory — `%USERPROFILE%` on Windows, `/Users/you` or `/home/you` on macOS and Linux; a non-empty `CETAS_HOME` environment variable moves it elsewhere. Backing up means copying this directory — see [Cetas Home](/cetas/en/configuration/cetas-home/). ### MCP The protocol for attaching external tool servers (databases, ticket systems, internal APIs) to the agent; configured in `mcp.json`. Not needed on day one — see [MCP](/cetas/en/configuration/mcp/). ### ACP The Agent Client Protocol — how editors such as Zed talk to an agent. You only need it for the editor surface — see the [Editor](/cetas/en/editor/). ### Skill A folder with a `SKILL.md` holding instructions for one kind of work, loaded only when a task needs it — see [Skills](/cetas/en/configuration/skills/). ### Subagent A child agent the main session spins up for one bounded piece of work, with narrower tools and permissions than the parent — a read-only reviewer, for example. See [Subagents](/cetas/en/configuration/subagents/). # Installation & First Run > Choose Cetas JS (recommended) or the Native terminal, then connect your first model. Source: https://colmugx.github.io/cetas/en/getting-started/installation/ · Markdown: https://colmugx.github.io/cetas/en/getting-started/installation/index.md > **Note** > > Cetas JS is the recommended interactive client. Native is an optional Go/Bubble Tea implementation of the same MoonBit agent core; host-specific features differ. ## Option 1: Cetas JS via npm (recommended) ```bash npm install -g @posoco/cetas cetas --version ``` Requires Node.js 24 or newer ([nodejs.org](https://nodejs.org/)). This is the primary interactive terminal, including JS-specific integrations such as Board workflows. The current stable Cetas release publishes the JS distribution through npm rather than a `cetas-bun` executable ZIP. ## Option 2: Cetas Native (no Node.js required) Native runs a Go/Bubble Tea v2 terminal backed by the same MoonBit Cetas/Posoco runtime. It is a second choice if you prefer a native CLI, not a promise of full feature parity with the npm build. ### Homebrew — macOS Apple Silicon or Linux x64 ```bash brew install colmugx/tap/cetas ``` ### Scoop — Windows x64 ```powershell scoop bucket add cetas https://github.com/colmugx/scoop-bucket scoop install cetas/cetas ``` ### Direct installation / download You can also use the repository's interactive [Unix installer](https://github.com/colmugx/cetas/blob/main/install.sh) or [PowerShell installer](https://github.com/colmugx/cetas/blob/main/install.ps1). Both show the detected OS, selected version, destination and install files, then ask for confirmation before downloading binaries. Noninteractive installation needs explicit `--yes` (Unix) or `-Yes` (PowerShell). Alternatively, choose a `cetas-v*` tag on the [GitHub Releases page](https://github.com/colmugx/cetas/releases); Memoh has its own release series. The Native archives currently cover macOS ARM64, Linux x64, and Windows x64. On Windows, `cetas-windows-x64.zip` includes `cetas.exe`, `cetas-acp.exe`, `cetas-run.exe` and `cetas_moon.dll`; **keep the DLL next to the executable**. ## Only need an editor agent or a one-off runner? These are still available as **independent** downloads in each Cetas release: | Use case | Release assets | | --- | --- | | Lody, Zed, or another ACP client | `cetas-acp-darwin-arm64.tar.gz`, `cetas-acp-linux-x64.tar.gz`, `cetas-acp-windows-x64.zip` | | One task from a script or CI | `cetas-run-darwin-arm64.tar.gz`, `cetas-run-linux-x64.tar.gz`, `cetas-run-windows-x64.zip` | You do not need to download the entire Native terminal for these use cases. Verify the selected archive using the `SHA256SUMS` file from the same release. ## When JS and Native are both installed Both may install a `cetas` command. Your shell launches whichever is first on `PATH` — check `command -v cetas` on Unix or `Get-Command cetas` in PowerShell. Configuration lives in the shared [Cetas home](/cetas/en/configuration/cetas-home/), but features, approval UI, and session flows can differ between hosts. ## From install to your first message Four steps. ### 1. Run it in your project directory ```bash cd /path/to/your/project cetas ``` Everything it reads, edits, or executes is relative to this directory. No project yet? A freshly created empty folder works just as well. ### 2. Sign in with a provider Cetas ships no model of its own — it calls a provider (a company that supplies models, like DeepSeek or OpenAI). Register on the provider's site, create an API key, then: ```text /login ``` Pick the provider, paste the key (or use browser sign-in where it is offered), done. Seeing fewer options than expected? See [Providers](/cetas/en/configuration/providers/). ### 3. Pick a model ```text /model ``` The list comes from the provider you just signed in with. Pick one and you are set. ### 4. Say the first thing ```text Explain how authentication works in this repository. ``` No repository? Any sentence works — a streaming reply means you are through. Keys worth knowing on day one: - `@path` attaches a workspace file, Tab completes; - Esc interrupts the running turn; typing while it runs queues a follow-up; - before you fully trust it, `/permission readonly` drops the session to read-only — see [Permissions](/cetas/en/configuration/permissions/); - `/help` lists the commands this build actually has. Sessions are kept automatically: `/sessions` reopens one, `/rewind` walks back to before a mistake — there is no "save" step. ## Using your company's own endpoint? Cetas supports self-hosted OpenAI-compatible endpoints natively; the walkthrough is at [Custom models](/cetas/en/configuration/custom-models/). ## Stuck? | Symptom | Fix | | --- | --- | | Node version too old at install | Upgrade Node, or use the released binaries | | `/login` or `/model` list is empty | Run `/login` again, then `/model`; still stuck, see [Providers](/cetas/en/configuration/providers/) | | The first message errors out | The sign-in usually never finished — run `/login` again | | Everything gets refused | The session is read-only; `/permission workspace_write` allows writes | Credentials, your model pick, and past sessions all land in one home directory automatically — nothing to manage day to day. Curious what it looks like or how to back it up? See [Cetas Home](/cetas/en/configuration/cetas-home/). Next: [Custom models](/cetas/en/configuration/custom-models/), [Permissions](/cetas/en/configuration/permissions/), or the [command reference](/cetas/en/reference/commands/). # Cetas > A coding agent for your terminal, your editor, and your scripts — one agent, one home, one identity; standalone by design, with no cloud sync. Source: https://colmugx.github.io/cetas/en/introduction/ · Markdown: https://colmugx.github.io/cetas/en/introduction/index.md Cetas is a coding agent that runs on your machine. You talk to it in plain language; it reads and edits files, searches the workspace, runs commands, and shows you what it did. It is built on [Posoco](https://github.com/colmugx/posoco), an agent framework for MoonBit. Single-machine is a design decision. The board, sessions, configuration, and credentials all live in one home directory on your machine; there is no cloud sync and no shared sessions. One person gets the complete product. ## Why people adopt it When a coding agent gets vetted, the first thing tested is rarely how smart it is — it is whether the work it did can be traced. All four points below can be verified by hand once installed; no marketing required. **Work you can trace.** Turn one requirement into a ticket graph: tickets whose dependencies are not done wait quietly, finished ones stop at the review gate for your call — and what you review is the diff and the test evidence, not the agent's retelling. The records stay local, and your agent can look them up itself: ask it two weeks later why a piece of code exists, and it can answer. The tickets and their records are the handoff document. See [Board](/cetas/en/features/board/). **The door for "reviewer edits code" was never installed.** When an agent reviews its own changes, "report only, touch nothing" rests on a verbal promise. Subagents turn that promise into configuration: the tool list and permission posture live in the agent's definition file — it cannot see `write`, cannot run `bash`, and stays powerless even when the parent session runs `yolo`. Sending it to research three modules takes the same road: three sub-sessions read in parallel, your main window receives three summaries. See [Subagents](/cetas/en/features/subagents/). **Middle steps never enter your window.** Finding 3 references across 40 files the ordinary way means paying for 40 tool calls. Have the model write a small program instead: it loops and filters, and only the 3 hits return to the conversation — content that was never generated never cost anything. The program runs in a Wasm sandbox and cannot touch the file system or the network. See [Bunraku](/cetas/en/features/bunraku/). **Humans and agents read the same docs.** The site ships `llms.txt` and `llms-full.txt`, and every page has a `.md` source. Having another agent read the docs before deciding to install is a supported way to use them. The foundations are all there too: five permission postures, every turn journaled with precise `/rewind`, all state in one home directory, and model choice that shows you who still has quota and what is actually cheaper before you pick. Each has its own page under [Features](/cetas/en/features/) and [Configuration](/cetas/en/configuration/); they are not re-sold here. ## Three surfaces, two terminal implementations | Surface | Best for | Entry point | | --- | --- | --- | | **Terminal · JS (recommended)** | Day-to-day work, sessions, rewind, JS-only integrations | `cetas` from npm | | **Terminal · Native (alternative)** | Go/Bubble Tea host without Node.js; different feature coverage | Homebrew, Scoop or direct release | | **Editor** | Working where the code already is, over ACP | `cetas-acp` | | **Automation** | One task per invocation, from a script or CI | `cetas-run` | These are not separate agent cores. Each host composes Cetas/Posoco, but supports its own UI and capabilities; the JS and Native terminals are alternatives, not guaranteed drop-in equivalents. See [Surfaces](/cetas/en/concepts/surfaces/). Start with [Installation & First Run](/cetas/en/getting-started/installation/). ## Why Posoco If you build agents, or are choosing an agent framework, this section is for you. If you just want to get work done with Cetas, skip it freely. Posoco's difference is not a slogan; it is four things you can verify. **On upgrade, the compiler tells you what broke.** The agent loop's event stream is a closed enum. When the kernel adds an event kind, every match that has not kept up becomes a compile error, named one by one. Upgrading does not mean reading a changelog and guessing behavior — the mismatch between your code and the kernel surfaces at compile time. **A rejection is not an apology.** When a tool call is denied, what comes back is not prose but a structured reason: not offered, owner not allowed, revoked, schema mismatch, rejected by a hook. People writing UIs and observers get facts they can match on, not prompts to parse with regex. **The capability catalog carries ownership, and can be narrowed.** Every capability registers with an owner and can be claimed by another extension and narrowed into "hidden but still callable" — out of the catalog, the call path still exists. Catalog, ownership, and narrowing are one snapshot; there is no second place for state to disagree. **Providers are independent extensions.** There is no unified router shaving every provider down to a common denominator; each provider's full potential is released in its own extension package — which is how Cetas' provider list grew. These claims need evidence, and the evidence is Cetas itself: three surfaces with different transports compose one core, with no forked agent loop. Breaking Posoco upgrades ship with an explicit migration table — what to change and what to change it to, item by item, no reverse-engineering diffs. The first claim stands on MoonBit: a closed enum plus exhaustiveness checking is what earns the compiler the role of "tells you what broke". Posoco gives you the protocol and the ports. Cetas is what it looks like when someone carries a real workload on top of them. # Reference > Commands, Settings, environment variables, and the durable paths Cetas uses. Source: https://colmugx.github.io/cetas/en/reference/ · Markdown: https://colmugx.github.io/cetas/en/reference/index.md The pages that answer "what exactly is it called?" — stable names, file locations, and the behaviour behind them. - **Commands** — Every terminal slash command and key binding. - **Settings** — The complete settings.json reference — every key, type, and default, by nesting level. - **Environment Variables** — The variables each host reads, and their scope. Durable paths are listed in [Cetas Home](/cetas/en/configuration/cetas-home/). # Commands > The terminal host's slash commands and keys, and what each one changes. Source: https://colmugx.github.io/cetas/en/reference/commands/ · Markdown: https://colmugx.github.io/cetas/en/reference/commands/index.md Slash commands are the deterministic path: they act immediately, without a model turn. `/help` is the authority for the build you are running — this page explains the ones worth knowing. ## Session and history | Command | What it does | | --- | --- | | `/new` | Start a new session | | `/sessions` | Browse and resume a past session | | `/rewind` | Walk this conversation back to an earlier message | | `/resume` | Resume this session's interrupted turn | | `/compact` | Compact the current context | `/rewind` is the recovery keystroke: when a turn goes wrong, go back to the point before it rather than arguing with the model about it. ## Models and providers | Command | What it does | | --- | --- | | `/login` | Authenticate a provider (API key or OAuth) | | `/model` | Pick the conversation model and its effort | | `/decision` | Pick the decision model — separate from `/model` | | `/effort` | Pick reasoning effort for the active model | | `/manager` | Switch between the provider set and Magpie — the walkthrough is in [Connecting the Magpie gateway](/cetas/en/configuration/magpie/) | | `/quota` | Show quota information for the active manager | | `/status` | Show agent, session, model, and manager status | ## Permission and context | Command | What it does | | --- | --- | | `/permission` | Set the session's posture — see [Permissions](/cetas/en/configuration/permissions/) | | `/ptc` | Select the programmatic tool-calling mode | | `/skills` | Browse discovered skills by scope | ## Work | Command | What it does | | --- | --- | | `/questions` | Review pending questions and answer one | | `/answer` | Answer a pending question inline: `/answer @q3 yes` | | `/board` | Open the Board dashboard in your browser (offers to enable workflows on first use) | | `/board.stop` | Stop all local Board servers | ## Housekeeping | Command | What it does | | --- | --- | | `/update` | Check for and install updates — npm installs only | | `/pi` | Manage pi packages | | `/exit`, `/quit` | Quit | > **Not every command exists in every build** > > `/effort`, `/permission`, `/decision`, and `/help` come from > composed extensions, so a build without that capability does not offer them. > The shell-owned commands above are always present. `/help` reflects the actual > set. ## Keys | Key | Effect | | --- | --- | | Esc | Interrupt the running turn (denies a pending approval first) | | Esc Esc (idle) | First clears the input, second opens `/rewind` | | Enter while running | Queues the typed message as a follow-up | | Tab / Enter | Apply the highlighted `@path` completion | | Ctrl+T | Collapse or expand thinking blocks | | Ctrl+O | Collapse or expand tool output | If the agent asks a question, type the reply directly — `/questions` and `/answer` are for the case where you want to pick one out of several. `/permission ` works mid-turn, which makes it the one command worth memorising: it is how you clamp a session that is doing more than you expected. # Environment Variables > The environment variables Cetas hosts read, and their scope. Source: https://colmugx.github.io/cetas/en/reference/environment-variables/ · Markdown: https://colmugx.github.io/cetas/en/reference/environment-variables/index.md | Variable | Scope | Behavior | | --- | --- | --- | | `CETAS_HOME` | Editor, automation | Overrides the platform user home — the **parent** of `.cetas`, not the directory itself. The terminal host does not read it. | | `CETAS_PERMISSION_MODE` | Editor (ACP) | Startup posture: `readonly`, `workspace_write`, `interactive`, `auto`, or `yolo`. Unset means `yolo`. An unrecognized value warns once and falls back to `workspace_write`, so a typo never widens the posture. | | `CETAS_MCP_MODE` | Editor (ACP) | `eager` connects configured MCP servers at startup instead of lazily on the first turn. | | `CETAS_DELEGATE_FS` | Editor (ACP) | `host` routes tool-facing filesystem reads and writes through the editor's `fs/*` reverse calls instead of the local filesystem. Unrecognized values warn and stay `local`. | | `CETAS_DEBUG_WIRE` | Editor (ACP) | `1` appends the session's wire traffic to `/.cetas/debug/-wire.jsonl`. | | `CETAS_DEBUG_MCP_CATALOG` | Editor (ACP) | `1` dumps the session's tool catalog to `/.cetas/debug/-catalog.json`. | | `CETAS_REGISTRY` | Terminal | Overrides the npm registry used by `/update` — for an internal mirror. | | `CETAS_MEMOH_HOME` | Memoh runtime | Relocates the separately versioned Memoh runtime's own state directory. | The automation host expresses model, effort, permission, and unattended behaviour through command-line flags rather than these variables — see [Automation](/cetas/en/automation/). ## Notes - **`CETAS_HOME` is not universal.** The terminal host resolves the platform home directly, so a scripted `CETAS_HOME` affects `cetas-acp` and `cetas-run` but not `cetas`. See [Cetas Home](/cetas/en/configuration/cetas-home/). - **Debug flags are per session.** They create `debug/` on first use; there is nothing to clean up beforehand. - **A typo fails toward safety** for permission values, and toward "off" for debug flags: only `1` enables a tap. # Settings Reference > The complete field reference for /.cetas/settings.json — every key, its type, and its default, organized by nesting level. Source: https://colmugx.github.io/cetas/en/reference/settings/ · Markdown: https://colmugx.github.io/cetas/en/reference/settings/index.md `/.cetas/settings.json` is one JSON object. Cetas writes it atomically and preserves every key it does not own, so keys added by other tools (or by a future version) survive a model switch. On startup, a **missing** file is created with an empty `providers` object. An **existing** file is never overwritten — including an empty or malformed one. A broken settings file is a loud failure, not something Cetas quietly repairs. ## Top-level keys | Key | Type | Purpose | | --- | --- | --- | | `model` | string | The active conversation slot, `provider/model` | | `reasoning_effort` | string, optional | Reasoning effort; absent means the slot's default | | `decision_model` | string, optional | The decision slot, independent of `model` | | `providers` | object | Provider settings; each entry is interpreted by its extension | | `subagent` | object | Subagent default model, effort, and limits | | `workflow` | object | Budgets for the Board multi-ticket execution loop | | `model_manager` | string | The terminal host's model-manager choice | | `manager_selections` | object | What each manager last had selected | | `magpie` | object | Magpie gateway settings; see [Connecting the Magpie gateway](/cetas/en/configuration/magpie/) | Expanded level by level below. ## model / reasoning_effort / decision_model | Key | Read by | Notes | | --- | --- | --- | | `model` | Every surface | The conversation slot; written by `/model` | | `reasoning_effort` | Every surface | Absent means the slot's advertised default; written by `/effort` | | `decision_model` | Terminal and editor | The decision slot; written by `/decision` | Unrelated keys are preserved verbatim when a selection is updated. If provider configuration changes make the previous selection unavailable, Cetas falls back to an available default instead of refusing to compose. ## providers Entries map a provider id to its settings. Each entry is interpreted by that provider's extension; this page does not answer for them: - Built-in ids and login methods: [Providers](/cetas/en/configuration/providers/). - An id that is not built-in becomes a custom provider whose wire is declared by the entry's `protocol` (`chat_completions` / `responses` / `messages`, default `chat_completions`); the entry shape (`base_url`, `protocol`, `auth`, `models`, model metadata) is in [Custom models](/cetas/en/configuration/custom-models/). Credentials do not belong in `providers`: a `gateway_key` written there is not read at all, and gateway credentials live only in the shared credential store (written by `/login`). The field Cetas reports as ignored, and warns about, is `magpie.gateway_key` in the `magpie` section — a credential in an editable configuration file is in the wrong place to begin with. Recording it is covered in [Connecting the Magpie gateway](/cetas/en/configuration/magpie/). ## subagent ```json { "subagent": { "default_model": "zai/glm-5.3", "default_effort": "low", "limits": { "swarm_items": 16, "concurrency": 4, "global_concurrency": 20, "timeout_ms": 1800000, "spawn_budget": 64, "answer_timeout_ms": 600000 }, "kinds": [] } } ``` | Key | Default | Notes | | --- | --- | --- | | `default_model` | — (inherit parent) | Default conversation slot for kinds that bind no model | | `default_effort` | — | Same, for reasoning effort | | `limits.swarm_items` | `16` | Maximum items in one parallel wave | | `limits.concurrency` | `4` | Children running at once in a wave | | `limits.global_concurrency` | `20` | Children running at once overall | | `limits.timeout_ms` | `1800000` | Wall clock per child (30 minutes) | | `limits.spawn_budget` | `64` | Children a session may spawn in total | | `limits.answer_timeout_ms` | `600000` | How long a child's question may wait for the parent (`0` disables) | | `kinds` | `[]` | Kind entries carried directly in settings, same fields as the `.md` frontmatter — see [Subagents](/cetas/en/configuration/subagents/) | Every field is optional; an absent section means defaults and no extra kinds. The model-selection precedence chain: explicit argument → kind binding → `default_model` → the parent's live selection. ## workflow Controls the Board multi-ticket execution loop. Disabled unless `enabled` is `true`. | Key | Default | Range | | --- | --- | --- | | `enabled` | `false` | boolean | | `max_executions` | `8` | 1–1000 | | `max_elapsed_ms` | `600000` | 1–86400000 | | `execution_timeout_ms` | `60000` | 1–86400000, and ≤ `max_elapsed_ms` | | `max_concurrency` | `2` | 1–8 | | `max_expansions` | `2` | 1–16 | | `max_generated_tasks` | `20` | 1–200 | | `max_depth` | `16` | 2–16 | | `continue_on_confirmed_failure` | `false` | boolean | This section is strict on purpose: an unknown key is a composition error, and a wrong type or out-of-range number is rejected. A typo in a budget must not silently become a different budget. ## model_manager / manager_selections / magpie Terminal host only: these remember which model manager you chose and what each manager last had selected, so switching back restores the previous slots. The end-to-end walkthrough is in [Connecting the Magpie gateway](/cetas/en/configuration/magpie/). | Key | Type | Notes | | --- | --- | --- | | `model_manager` | `"providers"` or `"magpie"` | Active manager; absent means `"providers"` | | `manager_selections` | object | manager → `{ model, reasoning_effort }`, kept separately per manager | | `magpie.base_url` | string | The Magpie gateway address | | `magpie.enabled` | boolean | Whether Magpie is enabled | > **Type checks are not advice** > > Wrong types fail loudly. `model_manager` must be exactly `providers` or > `magpie`; `magpie.enabled` must be a boolean. A value that merely looks right is > not accepted. Defaults and step-by-step instructions are in > [Connecting the Magpie gateway](/cetas/en/configuration/magpie/). # 问答 > 关于 Cetas 的常见问题 Source: https://colmugx.github.io/cetas/faq/ · Markdown: https://colmugx.github.io/cetas/faq/index.md 按起点挑着看: - [Cetas 适合我吗?](/cetas/faq/is-cetas-for-me/) — 不写代码的个人创作者、正在转型的程序员、想读源码的极客,各自的起点需要准备什么。 - [Cetas 和其他编码 agent 有什么不同?](/cetas/faq/how-different/) — 四条结构性差异,什么时候值得换,什么时候先别换。 - [为什么 Cetas 没有内置 Caveman?](/cetas/faq/why-doesnt-bundle-caveman/) — caveman 的六块功能里,cetas 哪些有对应实现,哪些没有,以及怎么把 caveman 的技能直接装进来用。 - [为什么现在不带 rtk 了?](/cetas/faq/why-no-rtk/) — cetas 集成过 rtk;一份独立实测解释了截断信息的真实代价,以及想用时怎么接回去。 # Cetas 和其他编码 agent 有什么不同? > 这一页不逐个对比产品,只讲四条结构性差异——每一条装好就能亲手验证,以及什么时候值得换、什么时候先别换。 Source: https://colmugx.github.io/cetas/faq/how-different/ · Markdown: https://colmugx.github.io/cetas/faq/how-different/index.md 这一页不逐个对比具体产品,只讲四条结构性的差异。它们好验证:装好后每一条都能亲手确认。 ## 活有出处,交接有底 Board 把一句需求变成一张任务图:依赖没齐的任务不动,跑完的停在验收门口。每条任务留下 diff、测试证据和来龙去脉,记录在本地,你的 agent 自己也查得到。第二天开板接着跑,任务还在原地,这些记录本身就是交接文档。见[Board](/cetas/features/board/)。 ## 边界是配置,不是嘱咐 子代理的工具面和权限档位写在它的定义文件里:三个属性就是一个只读评审员,父会话开 `yolo` 也改变不了它的档位。权限的五种姿态由你逐会话决定,从 `readonly` 到 `yolo`;计划模式在批准之前一个字节都写不进去。见[子代理](/cetas/features/subagents/)与[权限](/cetas/configuration/permissions/)。 ## 上下文的账单,算法不同 调研交给子代理,主窗口只收摘要;循环和过滤交给沙箱里的小程序,中间结果从头到尾没进过上下文。同样一批活,上下文的开销完全不同。见[子代理](/cetas/features/subagents/)与[Bunraku](/cetas/features/bunraku/)。 ## 文档的默认形态是机器可读 全站 `llms.txt` 与 `llms-full.txt`,每个文档页带 `.md` 源文件。让另一个 agent 先读完文档再决定装不装,是受支持的使用方式。见 [/llms.txt](/cetas/llms.txt)。 ## 什么时候值得换,什么时候先别换 **值得换**:你要知道它干过的活从哪查;你要评审的人真的改不了代码;你在意上下文的账单;你有脚本化、CI 场景——`cetas-run` 一次进程一个回合,成败由退出码说话。 **先别换** —— 下面这些现在没有: - `/sessions` 只列当前项目的会话,没有跨项目视图;跨入口续接是计划中的行为,今天别依赖; - 没有图形界面,终端是第一入口; - 没有团队协作功能:没有共享会话、组织管理、集中权限,每份状态都在各自的机器上; - 不替你管供应商账号,模型自己注册、自己接; - 它明说自己在实验期:npm 那份最稳,锁版本、读[更新日志](/cetas/changelog/)、有节奏地升。 想看更底层的论述(这个内核为什么靠得住),见[简介](/cetas/introduction/)的「为什么是 Posoco」一节。 # Cetas 适合我吗? > 按你的起点回答:不写代码的个人创作者、正在转型的程序员、想读源码的极客,各自需要准备什么、能走到哪一步。 Source: https://colmugx.github.io/cetas/faq/is-cetas-for-me/ · Markdown: https://colmugx.github.io/cetas/faq/is-cetas-for-me/index.md Cetas 是装在你自己电脑上的编码 agent:你用自然语言说需求,它读文件、改代码、执行命令,每一步都看得到。这句话对谁都成立,但"适合"取决于你的起点。这一页按三类起点回答。 ## 我不写代码,也能用吗? 能,而且不需要任何编程经验。个人创作者用它做的事和工程师不完全一样,但路径是同一条: - 让它给你搭一个小工具或个人网站,你描述想要什么,它写,你看效果再改; - 让它整理一批本地文件(重命名、归类、批量改格式),说清规则就行; - 让它读一份长文档或一个文件夹,替你总结、找信息。 你需要准备的是四样东西,每一样都有解释:一台电脑、[终端](/cetas/getting-started/glossary/#终端)、[Node.js](/cetas/getting-started/glossary/#nodejs)(推荐的 JS 版本需要,Native 不需要)、一个[供应商](/cetas/getting-started/glossary/#供应商provider)的账号。然后照着[安装与首次运行](/cetas/getting-started/installation/)走,遇到不认识的词查[词汇表](/cetas/getting-started/glossary/)。 要说清楚的一点:它做完之后你看得见每一步做了什么,不满意可以回退 —— 这正是它比"复制粘贴 AI 回答"更适合动手干活的原因。 ## 我会写代码,正在从别的 agent 换过来 见下一页:[Cetas 和其他编码 agent 有什么不同?](/cetas/faq/how-different/) —— 四条结构性差异,以及什么情况下值得换。 ## 我比作者还熟这类工具 文档把该交代的都交代了,不挡你的路: - 全站机器可读:[/llms.txt](/cetas/llms.txt) 与 [/llms-full.txt](/cetas/llms-full.txt),每个文档页也有对应的 `.md` 与 `.mdx` 源文件; - 状态审计:一个 [home 目录](/cetas/configuration/cetas-home/),配置、凭据、会话全部落盘,没有第二处隐藏状态; - 五种[权限姿态](/cetas/configuration/permissions/)与会话回退,从严到松都只是配置,不用改产品。 它的实验属性是明说的:npm 那份最稳,锁版本、读[更新日志](/cetas/changelog/)、有节奏地升。 # 为什么 Cetas 没有内置 Caveman? > caveman 的六块功能里,cetas 有哪些对应实现、缺哪些、为什么。 Source: https://colmugx.github.io/cetas/faq/why-doesnt-bundle-caveman/ · Markdown: https://colmugx.github.io/cetas/faq/why-doesnt-bundle-caveman/index.md 简短回答:Cetas 和 Caveman 有相似的优化目标,但我们选择直接优化 Agent 的工作过程,而不是默认增加一层代理。你仍然可以在 Cetas 中使用 Caveman Skill。 [Caveman](https://github.com/JuliusBrussee/caveman) 是一个优秀的开源项目。它尝试减少 AI Coding Agent 的 Token 消耗:让回答更简短,让模型少读取无关内容,并提供模型路由、脚本复用等功能。 这些能力值得借鉴。但对 Cetas 来说,并不是每项能力都需要以独立插件的形式存在。 ## Cetas 已经做了什么? ### 让不必要的信息从一开始就不进入上下文 Cetas 的 `run_code` 可以让模型编写一段 MoonBit 程序,在沙箱中完成多次工具调用、循环和过滤,只把需要的结果返回对话。中间数据不必先发送给模型,再想办法压缩。 子代理也可以承担独立的调查任务,避免把全部工作过程堆进主会话。 ### 控制长期对话的上下文大小 Cetas 支持自动和手动上下文压缩。对话接近模型上下文限制时,可以整理已有信息,继续工作,而不必从头开始。 ### 减少工具与网页带来的无关内容 Cetas 使用按需加载的工具机制。内置 `webfetch` 也会清理网页中的部分无关 HTML,将内容转换成更适合模型阅读的 Markdown,并支持分页获取。 这些机制不等同于 Caveman 的全部功能,但它们解决了同一类问题:减少模型不需要处理的信息。 ## 那么,还有哪些差距? 有。特别是**工具执行结果的自动压缩**。 例如,一次构建生成了几万行日志,但真正需要关注的可能只有几条错误。目前 Cetas 并没有为所有工具结果提供统一的、可恢复的结构化压缩机制。 这是值得继续改进的地方。 但我们不会为了缩短输出,简单地丢弃可能重要的信息。被省略的内容应当能够找回,错误诊断不能被隐藏,优化是否有效也应当用完整任务的实际成本和成功率验证。 ## 为什么不自动选择模型? 这是有意的产品选择。 不同模型在成本、速度、上下文长度和行为上存在差异,但没有一个可靠的规则能够保证:某类任务一定应该交给某个模型。 同一个任务在不同代码库、约束条件和用户偏好下,也可能需要完全不同的能力。 因此,Cetas 让你决定使用哪个模型,以及使用什么推理强度。我们可以帮助你了解模型的能力和成本,但不会在每次提问时擅自替换它。 Cetas 应该优化你选择的模型如何工作,而不是替你决定应该使用哪个模型。 ## 我还能使用 Caveman 吗? 可以。如果你喜欢 Caveman 简短直接的回复风格,可以只安装它的 Skill: ```sh npx skills add JuliusBrussee/caveman ``` 安装后可在 Cetas 的 `/skills` 中检查,通过 `/caveman` 按需启用。 这与安装 Caveman 的完整 Proxy 不同:Skill 主要调整回复风格,不会自动启用工具结果压缩等运行时优化。 你可以根据需要使用它,不必等待 Cetas 内置相同的风格。 ## 不安装 Caveman,会错过明显的成本节省吗? 这取决于你的实际工作。 如果任务主要涉及多次文件搜索、代码检查或程序化数据处理,Cetas 已有的 `run_code`、子代理和上下文管理可以减少部分冗余开销。 如果任务经常产生大量日志、JSON 或测试输出,Caveman 的工具结果压缩可能有额外价值。这也是 Cetas 仍需要改进的地方。 但压缩后的文本变短,不代表整次任务一定更便宜。若模型因缺少关键信息而重新读取文件、重复运行命令,最终成本可能反而增加。 我们的目标不是让每一条工具输出尽可能短,而是让 Cetas 在不牺牲任务质量的前提下,减少不必要的 Token 消耗。 这也是为什么 Cetas 不直接打包 Caveman,却会继续吸收其中有价值的技术思路。 # 为什么现在不带 rtk 了? > cetas 集成过 rtk,后来不再随包带它。一份独立实测解释了这个决定,以及想用时两步把它接回去的办法。 Source: https://colmugx.github.io/cetas/faq/why-no-rtk/ · Markdown: https://colmugx.github.io/cetas/faq/why-no-rtk/index.md rtk(Rust Token Killer)是一个命令行代理:把 `pnpm test`、`go test -v ./...` 这类命令重写成 `rtk test` 之类的形式,输出在进上下文之前就被压缩,README 承诺省 60–90% token。对整天跟测试输出和构建日志打交道的团队,这个承诺很有吸引力。 cetas 集成过它。仓库里的 [posoco-ext-rtk](https://github.com/colmugx/cetas/tree/main/extension/posoco-ext-rtk) 就是为这件事写的:一个工具调用钩子,把 agent 发起的 shell 命令交给 `rtk rewrite` 处理,重写后的命令才真正执行。 后来我们不再随包带它。问题不在集成侧——钩子至今还在,测试也还在过;问题在 rtk 的前提本身。 ## 压缩是有代价的 rtk 压缩输出,本质上是在替模型做编辑判断:哪些行重要,哪些可以扔。问题在于它经常扔错。 [JetBrains 的独立实测](https://blog.jetbrains.com/ai/2026/07/rtk-claude-code-token-savings/)把这件事量化了:Claude Code 加 rtk 跑 SkillsBench 的 86 个任务,配对 A/B,425 次计费试验。广告里的 60–90% 没有出现;低推理档下每个任务反而**贵了 7.6%**(p=0.004),轮数多 13.8%。质量倒是没有变化,模型被截断的信息逼着重跑命令、重读文件,把省下来的 token 又烧了回去。高推理档下差距归零,但两种档位下 rtk 都没有省过。 文章里最能说明问题的是 rtk 自己的记分牌:整轮跑完,`rtk gain` 报告省了 9620 万 token,而同一批试验的真实账单是上涨的。记分牌拿"压缩前的原始输出"当对照,可那些输出大多本来就会被宿主截断或被缓存折价,模型从来没收到过。原文的结论值得抄在这里: > a tool's self-reported savings are a claim about its counterfactual, not about your bill. 工具自报的节省,说的是它假想的对照,不是你的账单。 所以我们不再随包带它:一个会无故截断信息、再让模型花更多轮数把信息找回来的工具,省出来的只是展示数字,多花的是真实成本。 ## 还想用,两步 ```sh # 装 rtk 本体(brew 装,或按它的仓库指引) rtk --help # 接上 cetas 的钩子扩展 ``` 钩子的接法在 posoco-ext-rtk 的源码和测试里有完整示例。接上之后 agent 跑的每条 shell 命令都会先过一遍 `rtk rewrite`,能重写的就重写,重写不了的照原样执行。是否值得,JetBrains 那篇的方法论可以直接借用:配对着跑,量真实账单,别看工具自己的记分牌。 # 特色功能 > npm 装完就在的五样东西——子代理、看板、Bunraku、选模型、限流守卫——每一件帮你把什么活干成。 Source: https://colmugx.github.io/cetas/features/ · Markdown: https://colmugx.github.io/cetas/features/index.md `npm install -g @posoco/cetas` 装完就是全部安装过程。下面五样不用装、不用配,每页只讲一件事:它帮你把什么活干成。 - **子代理** — 评审代码的人改不了代码。权限写在它的定义里。 - **Board** — 一句需求变成一张可以审的图,每一步都有记录。 - **Bunraku** — 40 个文件里找 3 处引用,上下文里只出现那 3 处。 - **选模型** — 选之前先看见:哪家还有额度,哪个更划算。 - **限流守卫** — 凌晨三点的 429,自己等到重置点接着跑。 ## 出厂就在的地基 另有一批能力不单独开页,这里一并交代。 权限有五档。`readonly` 到 `yolo` 之间,值得注意的是 `auto`:每个非只读调用交给决策模型逐次判定,有风险的拦下,安全的放行,全程不用人守。它要求先配好决策模型,否则拒绝开启。见[权限](/cetas/configuration/permissions/)。 计划模式在批准之前不会写入任何内容。 技能按三层展开,目录里只带元数据,正文激活时才读。装十个技能,提示不会跟着膨胀十份。 会话全程落盘。`/sessions` 翻历史,`/rewind` 退回出错前,重启接着聊。 工具面里有 astgrep。它按代码结构搜,重构前问"这个接口还有哪里在用",得到的是调用点。 ## 建议的上手顺序 1. [选模型](/cetas/features/model-selection/),成本和质量都在这一步定。 2. [子代理](/cetas/features/subagents/),从只读的活开始,风险最低。 3. [Board](/cetas/features/board/),流程稳定后再上,那时你在管一条流水线。 更多问题见[问答](/cetas/faq/)。 # Board > 一块只在你机器上的看板:把一句需求建成任务图,排依赖、放行、验收,每一步都留下 diff 和测试证据可查。 Source: https://colmugx.github.io/cetas/features/board/ · Markdown: https://colmugx.github.io/cetas/features/board/index.md 周一早会定了三件事,其中一件最重:把鉴权从 session cookie 迁到 JWT。你输入 `/board`,浏览器里开出一块看板。 你把目标建成八条任务:替换会话读取、改中间件、迁三个调用方、补回归测试。每条任务除了标题和描述,还可以写清楚用户故事和完成定义(Definition of Done)——"测试全绿"和"旧的 cookie 路径有兼容层"是两种完成。写得含糊的任务,可以让补全 agent 先把它打磨成型再开工。 拉上依赖:迁移任务不跑完,调用方那几条就排不上。然后点运行。第一波只有能跑的任务会动,被依赖挡住的安静地在 Ready 泳道等着。你看板子上每一条任务跑到哪一步、哪个 agent 在干、试了几次,全程都记着。 四十分钟后第一波落定。你点开任务,看 diff 和测试证据,有一条不满意,直接 request changes 让它返工;其余的验收通过,标记完成。下一波解锁,继续跑。中午之前,这件事的进度和结果都摆在板面上,而不是埋在某个终端的滚动历史里。 ## 每条任务长什么样 一条任务有标题、描述、用户故事、实现建议、优先级和完成定义。这些字段会实际生效:执行 agent 拿到的就是你写的完成定义,验收时对着的也是它。 写不清的任务不用硬写。让补全 agent(product owner、refiner)先读代码把任务补全,你再改两笔——机器起草,人定稿。 ## 跑起来之后 - 依赖就是调度:上游任务没完成,下游任务不会被放行,不存在"跑了一半发现前置没做"。 - 每条任务可以单独换模型:改名的任务用便宜的,啃硬骨头的任务用强的。 - 失败就重试,中断就续跑:某条任务的 agent 卡住了,retry 换个路数再跑;机器重启后没跑完的任务可以 resume。 - 跑成功不等于完成:任务停在 Review 等你验收。Attempt 成功是执行事实,完成是你的决定。 ## 卡住了怎么办 看板上有三个刹车。Pause 撤掉排队的、让跑着的收尾;Stop 收掉本次的全部授权;Cancel 精确取消单次执行。拿不准就先 Pause。不用看板了,`/board.stop` 关掉所有本地服务。 ## 什么时候用它 任务之间有依赖、每步都能独立验收的活,Board 最能发挥:迁移、多步特性、成批的重构加回归测试。任务图和记录本身就是交接文档,第二天开板接着跑,任务还在原地。 一两步就能改完的事,直接在会话里说更快。 ## 开关与预算 第一次 `/board` 会问你要不要开启,确认即可,它不动你的模型和供应商配置。想手动控预算,`workflow` 段的每个上限都列在 [Settings 参考](/cetas/reference/settings/)。任务和记录落在 `/.cetas/board/` 下,每个工作区一份;agent 自己也能查这些记录(`board_work`),所以"这段代码为什么存在"它答得上来,删改代码前它会先查溯源。 # Bunraku > 让模型写一小段程序去循环和过滤,40 个文件里找 3 处,上下文里只出现那 3 处——循环交给程序,人只看结果。 Source: https://colmugx.github.io/cetas/features/bunraku/ · Markdown: https://colmugx.github.io/cetas/features/bunraku/index.md ## 40 个文件里找 3 处,不该付 40 个文件的钱 普通的 agent 找引用是一条一条读。40 次工具调用、40 段结果全部记进上下文,哪怕你要的只是其中 3 处。钱照付,窗口照占。 `run_code` 换了个方向。模型写一小段 MoonBit 程序,程序自己去循环、自己过滤,只把那 3 处带回对话: ```moonbit let hits = [] for path in paths { match ctx.call("grep", {"pattern": "OldAuth", "path": path}) { {"error": _, ..} => () result => hits.push({ "path": path, "hit": result }) } } { "count": hits.length(), "hits": hits } ``` 中间结果活在程序里,不进上下文,也就不进账单。这不是压缩,那些内容从头到尾没有产生过。 ## 模型写的代码,凭什么放心跑 程序跑在 Wasm 沙箱里,文件系统、网络、进程访问全部拒绝。它唯一能做的是调用你允许的工具,列表之外是一句明确的报错,不会悄悄放行。 程序是编译执行的。类型错误在运行前就是编译错误,作为有上限的诊断(8K 字符)交还给模型自己修。 返回值有大小上限,程序能被取消。一个写歪的循环不会变成一次账单事故。 ## 什么时候别用它 两三个工具调用的事,直接调更快,它的收益从循环和过滤开始。嵌套调用目前是串行的,需要并发请求时别用它。 # 选模型 > 选之前先看见:用数据算哪个真的更划算,用完的自动沉底。 Source: https://colmugx.github.io/cetas/features/model-selection/ · Markdown: https://colmugx.github.io/cetas/features/model-selection/index.md ## 大多数选法是凭印象 团队里常见两种浪费。一种一直用最贵的模型跑改名任务,另一种用最小的模型做架构改动,然后得出"agent 不行"的结论。两种都发生在看不见信息的时候。 Cetas 把信息放到选择动作的前面。 ## 额度还剩多少,选之前就看见 ```text /model quick-pick ``` 打开就是三组。**Limit** 是还剩窗口额度的供应商,按剩余排序,颜色标最差的那个窗口;**Balance** 是还剩余额的;**Other** 是两者都没有的。用完的沉底禁用,你选不到一个注定失败的模型。 数字是供应商自己报的,不做估算。哪家超时没读到,哪家就从列表里消失,宁可少显示一家,也不给一个猜出来的数。 ## 哪个更划算,让数据说 ```text /model openai pick ``` 它按实测的智能效率给这个供应商的模型排序:实测 IQ,减去每百万 token、每美元、每 10 分钟耗时三笔账,权重 1.0、2.0、0.5。候选至少要 30 次实测样本才入围,三项全不占优的直接淘汰。 没有数据的供应商它就不排,换完模型也会明说换到了哪。 ## 平时在列表里挑,企业接网关 ```text /model ``` 按供应商分页,打字就模糊搜索,选中后用左右键切推理档位。自建网关也一样:往 `providers` 里加一个 key,它就是一个普通页签,与 `openai` 同等对待。见[自定义模型](/cetas/configuration/custom-models/)。 ## 对话和决策,两本账 `/model` 管对话模型,`/decision` 管决策模型,后者给 `permission auto` 和需要判断的构建用。强模型对话,便宜模型判断,两笔账各自独立。`/manager` 还能在供应商集合和 Magpie 网关之间切换,两边各记各的选择 —— 从启动网关到验证可用,见[接入 Magpie 网关](/cetas/configuration/magpie/)。 # 限流守卫 > 限流不用人守:带重置时间的到点自动续跑,不带的按退避节奏探测;等待的那一轮先落盘,醒来接着跑、工作不丢。 Source: https://colmugx.github.io/cetas/features/rate-limits/ · Markdown: https://colmugx.github.io/cetas/features/rate-limits/index.md ## 这是自动的 当前模型来自一个订阅的话,服务端的限流信号会带重置时间。Cetas 收到信号就记下这个时间,到点自动恢复工作——不用设闹钟,也不用记着"稍后再试"。 边界是:前提是 Cetas 还开着、session 没有切换。等待期间你离开电脑做别的都行;把进程关了或换了 session,恢复就无从谈起。 ## 凌晨三点,没有人守着 没有守卫的长任务经常停在很被动的地方。跑到第 90 分钟,供应商回一个 429,agent 说"配额用尽,稍后再试",然后这条消息在第二天早上才被看到。五个小时白等,任务还得重讲一遍。守卫会自己处理"稍后再试"。 不带重置时间的限流(多数按量计费的 API key 是这种),按退避节奏探测,有封顶、不会密集重试。 ## 等待不丢工作 等的前提是醒来之后一切还在。失败的那一轮先落盘,会话才被标记为可恢复,顺序反了,恢复时拿到的就是残缺的上下文。续跑之后任务接着跑、历史接着写,不需要你重述任何东西。 ## 你需要它吗 三个问题自查: - 跑过超过一小时的任务吗? - 供应商按 5 小时窗口计额度,任务经常跨窗口吗? - 设过闹钟回来重发任务吗? 有一条命中,它就值得先配上。一条都没有,暂时用不上,装了也不会碍事。 ## 两件事它不做 撞限流时它不会自作主张换供应商或换模型,想换是 `/model quick-pick` 的事,两个机制各管各的。反复失败到次数上限,它会停下来把结论交给你,而不是整夜重试。 # 子代理 > 评审的人改不了代码:子代理的工具面和权限姿态写在定义文件里,父会话开 yolo 也越不了权;调研只回摘要,不占窗口。 Source: https://colmugx.github.io/cetas/features/subagents/ · Markdown: https://colmugx.github.io/cetas/features/subagents/index.md ## 评审的人,改不了代码 让 agent 自己评审自己的改动,有个绕不开的问题:它拿着你全部的工具,"只报告别修改"全靠口头嘱咐。子代理把这句话变成配置。 在项目的 `.cetas/agents/` 下建一个 `reviewer.md`: ```markdown --- name: reviewer description: 只读的 diff 评审员 tools: read, grep, glob mode: readonly --- 你评审改动,不动工作区。 ``` 三个属性定义一个只读评审员:它看不见 `write`,跑不了 `bash`。父会话开 `yolo` 也一样,子代理的档位是它自己的。 ## 一次调研,不占主窗口的上下文 "把 auth、billing、jobs 三个模块的鉴权流程摸清楚"。普通做法是读六十个文件,窗口里堆满中间过程,最后 `/compact` 三次。 交给子代理,三个子会话同时读,主窗口只收到三份摘要。那六十个文件的内容从来没进过你的上下文,也就不产生这部分开销。 ## 三行定义,就能用 - 放 `/.cetas/agents/` 全机器可用,放项目的 `.cetas/agents/` 跟仓库走。 - `tools` 不写就继承默认;写 `[]` 一个工具都没有;写列表就是列表。 - 并发和总量有默认值(一波 16 个、并发 4、每会话 64 次),写在 `subagent.limits` 里可以调。跑偏的计划到第 64 个会被拦下。 使用时没有任何特殊命令,直接说事:"用 reviewer 评审我未提交的改动,只报问题。"它需要你拍板时会停下来问,答案回到同一个会话。 # 入门 > 选择推荐的 JS 或第二选择 Native,再按步骤完成第一次对话。 Source: https://colmugx.github.io/cetas/getting-started/ · Markdown: https://colmugx.github.io/cetas/getting-started/index.md 建议先用 npm 安装 Cetas JS;如果不想安装 Node.js,也可以通过 Homebrew/Scoop 安装 Native。两种终端使用相同 Agent 内核,但宿主功能不同。接着按教程完成第一次对话。 ## 第一次接触编码 agent? 从这里开始不需要任何编程经验。Cetas 是装在你自己电脑上的助手:你说需求,它读文件、改文件、执行命令,每一步都看得见。你只需要四样东西: 1. 一台 macOS、Linux 或 Windows 的电脑; 2. [终端](/cetas/getting-started/glossary/#终端)—— Cetas 住的那个打字窗口; 3. [Node.js](/cetas/getting-started/glossary/#nodejs) 24+ —— 推荐的 JS 版本需要,Native 不需要; 4. 一个[模型供应商](/cetas/getting-started/glossary/#供应商provider)的账号(比如 DeepSeek 或 OpenAI),第一次用去官网注册、建一个 [API key](/cetas/getting-started/glossary/#api-key)。 拿不准它适不适合自己?先看[「Cetas 适合我吗?」](/cetas/faq/is-cetas-for-me/)。准备好了就直接进[安装与首次运行](/cetas/getting-started/installation/) —— 那一页从零开始,出现的每个术语都有解释。 ## 已经熟悉这些? - **安装与首次运行** — npm 的 JS、Homebrew/Scoop 的 Native 或直接下载,以及首次对话步骤。 - **词汇表** — 终端、npm、供应商、API key —— 每个词的一句话解释,可查可链接。 第一次在企业的私有化环境里落地,直接看[自定义与私有化模型](/cetas/configuration/custom-models/)。想知道和其他编码 agent 的差异,看[这一页](/cetas/faq/how-different/)。 # 词汇表 > 从安装走到第一条消息需要的每个词——终端、npm、供应商、API key——都用不需要编程背景的话讲一遍,按出现顺序分组。 Source: https://colmugx.github.io/cetas/getting-started/glossary/ · Markdown: https://colmugx.github.io/cetas/getting-started/glossary/index.md 这一页只做一件事:把走完「从安装到第一条消息」会用到的每个词,用不需要编程背景的话讲一遍。按出现顺序分三组。遇到不认识的词回到这里查,查完接着走。 ## 装之前 ### 终端 那个靠打字对话的窗口:macOS 上叫「终端」(聚焦搜索里输"终端"就能打开),Windows 上是 PowerShell(开始菜单搜 PowerShell),Linux 上你大概率已经有了。Cetas 平时就住在里面。 ### Node.js 让 Cetas 跑起来的运行时 —— 可以理解成"引擎"。版本要 24 或更高;没装过就去 [nodejs.org](https://nodejs.org/) 下载 LTS 版本,一路下一步。装完 Node.js,`npm` 命令也就有了。 ### npm Node.js 自带的包管理器,角色类似手机上的应用商店,只是装的是开发者工具。`npm install -g @posoco/cetas` 的意思就是:从这个商店把 Cetas 装成全机可用。 ### 项目目录(工作区) 你打算让 Cetas 干活的那**一个**文件夹。它读文件、改文件、执行命令,都只发生在这个文件夹里 —— 所以启动前要先进入它。没有现成的项目,新建一个空文件夹也完全可以。 ### 仓库 受版本管理(通常是 git)的代码或文档目录。如果你还没有仓库,忽略这个词:空文件夹一样能开始。 ## 模型与供应商 ### 供应商(Provider) 给你提供模型的公司,比如 DeepSeek、OpenAI、Kimi。Cetas 本身不带模型,它调用你选的供应商。第一次用,需要去其中一家注册账号。 ### API key 供应商发给你的一串字符,相当于「钥匙 + 账号」:证明这些调用是你发起的,费用记在你的账上。在供应商网站的「API Keys」页面创建。Cetas 只把它存到你自己的电脑上。 ### OAuth 另一种登录方式:不用复制 key,点一下浏览器登录,供应商直接把凭据交给 Cetas。`/login` 里出现"用浏览器打开"选项的就是它。 ### 模型 供应商提供的那个"大脑",比如 `deepseek/deepseek-flash`。同一家供应商通常有多个模型,能力和价格不同,`/model` 负责挑。 ### 推理档位(effort) 同一个模型"想多深"的档位:越高越聪明,也越慢、越贵。 ### 决策模型 一个独立的小模型,专门服务"做判断"的场合(比如权限闸门),和对话用的模型分开记账。第一次用可以完全不管它。 ### token 与上下文 模型按 token 计量和计费,大约一个汉字或小半个英文单词。上下文是一次会话里模型能"看见"的全部内容,超了会自动压缩,不用你管。 ## 用的时候 ### 权限姿态 会话级的安全开关,决定 agent 动手前要不要问你:`readonly` 只准看、`workspace_write` 写之前要确认、`interactive` / `auto` / `yolo` 逐步放手。第一天用 `workspace_write` 就好,见[权限](/cetas/configuration/permissions/)。 ### 会话 你和 agent 的一次完整对话,自动记录在 `/.cetas/sessions/` 下。`/sessions` 重开一段旧对话,`/rewind` 把它退回到出错之前 —— 不需要"保存"。 ### 斜杠命令 以 `/` 开头的命令(`/login`、`/model`、`/help`)。它们立即执行,不经过模型,是确定性操作。 ### Cetas home(`/.cetas`) 所有持久状态的唯一目录:配置、凭据、会话、缓存全在这。`` 指你的用户目录——Windows 上是 `%USERPROFILE%`,macOS 和 Linux 上是 `/Users/你` 或 `/home/你`;环境变量 `CETAS_HOME` 非空时换到别处。备份 = 复制这个目录,见 [Cetas Home](/cetas/configuration/cetas-home/)。 ### MCP 把外部工具服务器(数据库、工单系统、内部 API)接进 agent 的协议,配置放 `mcp.json`。第一天不需要,见 [MCP](/cetas/configuration/mcp/)。 ### ACP Agent Client Protocol —— 编辑器(比如 Zed)和 agent 之间的对话协议。想在编辑器里用 Cetas 时才需要,见[编辑器](/cetas/editor/)。 ### 技能(Skill) 一个带 `SKILL.md` 的文件夹,装着"某类活怎么干"的指令,任务需要时才加载,见[技能](/cetas/configuration/skills/)。 ### 子代理 主会话派出去干一件有边界工作的子 agent,工具和权限可以比主会话更窄 —— 比如"只读评审",见[子代理](/cetas/configuration/subagents/)。 # 安装与首次运行 > 选择推荐的 Cetas JS 或第二选择 Cetas Native,再配置模型完成首次对话。 Source: https://colmugx.github.io/cetas/getting-started/installation/ · Markdown: https://colmugx.github.io/cetas/getting-started/installation/index.md > **Note** > > 默认推荐 Cetas JS。Native 是另一种 Go/Bubble Tea 终端,使用相同的 MoonBit Agent 内核,但两者的功能并不完全一致。 ## 方案一:通过 npm 安装 Cetas JS(推荐) ```bash npm install -g @posoco/cetas cetas --version ``` 需要 Node.js 24 或更高版本([nodejs.org](https://nodejs.org/))。这是默认推荐的交互式终端,包含 Board 等 JS 专属集成。当前稳定 Cetas 发布版通过 npm 分发 JS 终端,不再把 `cetas-bun` 直接下载包作为首选入口。 ## 方案二:Cetas Native(无需 Node.js) Native 使用 Go/Bubble Tea v2 实现终端,底层同样运行 MoonBit Cetas/Posoco。它是第二种实现,不承诺与 JS 完全相同的功能。 ### Homebrew:macOS Apple Silicon / Linux x64 ```bash brew install colmugx/tap/cetas ``` ### Scoop:Windows x64 ```powershell scoop bucket add cetas https://github.com/colmugx/scoop-bucket scoop install cetas/cetas ``` ### 直接安装或下载 也可以使用仓库中的 [Unix 安装脚本](https://github.com/colmugx/cetas/blob/main/install.sh) 或 [PowerShell 安装脚本](https://github.com/colmugx/cetas/blob/main/install.ps1)。它们会先显示检测到的系统、版本、目标目录和文件清单,得到终端确认后才下载二进制。非交互场景需明确指定 `--yes`(Unix)或 `-Yes`(PowerShell)。 手工下载请在 [GitHub Releases](https://github.com/colmugx/cetas/releases) 选择 `cetas-v*` 版本(Memoh 使用独立版本系列)。当前 Native 支持 macOS ARM64、Linux x64 和 Windows x64。Windows 的 `cetas-windows-x64.zip` 含三个 EXE 和 `cetas_moon.dll`;**DLL 必须与 `cetas.exe` 放在一起**。 ## 只需要编辑器 ACP 或一次性 Runner? 每个 Cetas Release 都继续保留**可独立下载**的资产: | 用途 | 独立发布文件 | | --- | --- | | Lody、Zed 等 ACP 客户端 | `cetas-acp-darwin-arm64.tar.gz`、`cetas-acp-linux-x64.tar.gz`、`cetas-acp-windows-x64.zip` | | 脚本/CI 的一次性任务 | `cetas-run-darwin-arm64.tar.gz`、`cetas-run-linux-x64.tar.gz`、`cetas-run-windows-x64.zip` | 这两种用途不必下载整个 Native 终端。校验文件使用同一个 Release 的 `SHA256SUMS`。 ## JS 与 Native 同时安装 两者都可能提供 `cetas` 命令,Shell 会运行 `PATH` 中排在前面的那一份。Unix 用 `command -v cetas`,PowerShell 用 `Get-Command cetas` 检查。配置共享 [Cetas Home](/cetas/configuration/cetas-home/),但功能、确认界面和会话流程不保证一致。 ## 从装好到第一条消息 四步。 ### 1. 在你的项目目录里启动 ```bash cd /path/to/your/project cetas ``` 它读、改、执行的每一样东西都相对这个目录。还没有项目?新建一个空文件夹,进去一样能开始。 ### 2. 登录一家供应商 Cetas 不带模型,调用的是供应商(DeepSeek、OpenAI 这类提供模型的公司)的接口。去供应商官网注册账号、建一个 API key,然后: ```text /login ``` 选供应商,粘贴 key(或走它支持的浏览器授权),完成。列表比你预期的短?见[供应商](/cetas/configuration/providers/)。 ### 3. 选一个模型 ```text /model ``` 列表来自你刚登录的供应商,选一个就能用了。 ### 4. 说第一句话 ```text 这个仓库的鉴权是怎么工作的? ``` 没有仓库也一样,说什么都行——它能流式回答,就算通了。第一天用得上的几个键: - `@路径` 挂一个工作区文件,Tab 补全; - Esc 打断当前回合,运行中接着打字会排队; - 完全信任它之前,`/permission readonly` 先把会话降到只读,见[权限](/cetas/configuration/permissions/); - `/help` 列出这份构建真正有的命令。 会话自动保留:`/sessions` 随时重开,`/rewind` 退回出错之前——没有"保存"这一步。 ## 要用自己公司的端点? Cetas 原生支持私有化部署的 OpenAI 兼容端点,走法在[自定义模型](/cetas/configuration/custom-models/)。 ## 卡住了 | 现象 | 处理 | | --- | --- | | 安装时报 Node 版本太旧 | 升级 Node,或改用发布制品 | | `/login` 或 `/model` 列表是空的 | 重新 `/login` 再 `/model`;还不行见[供应商](/cetas/configuration/providers/) | | 第一句话就报错 | 多半是登录没完成,重来一遍 `/login` | | 说什么都被拒绝 | 权限在只读档,`/permission workspace_write` 放开写入 | 登录的凭据、选好的模型、聊过的会话,都自动收在一个 home 目录里,平时不用管;好奇它长什么样、怎么备份,见 [Cetas Home](/cetas/configuration/cetas-home/)。 接下来:[自定义模型](/cetas/configuration/custom-models/)、[权限](/cetas/configuration/permissions/)、[命令速查](/cetas/reference/commands/)。 # Cetas > 运行在你终端、编辑器与脚本里的编码 agent——一个 agent、一份配置、同一个身份,单机设计,没有云同步。 Source: https://colmugx.github.io/cetas/introduction/ · Markdown: https://colmugx.github.io/cetas/introduction/index.md Cetas 是跑在你自己机器上的编码 agent。你用自然语言说话,它读文件、改代码、搜仓库、执行命令,边做边把过程摊开给你看。它构建于 [Posoco](https://github.com/colmugx/posoco) —— 一个面向 MoonBit 的 agent 框架。 它是单机设计。看板、会话、配置、凭据,全部落在你机器的一个 home 目录里;没有云同步,也没有共享会话。一个人用就是完整的。 ## 为什么采用它 引入一个编码 agent,最先要验证的往往不是它多聪明,而是它干过的活你能不能查。下面四条,装完就能亲手验证。 干过的活查得到出处:把一句需求建成一张任务图,依赖没跑完的任务安静等着,跑完的停在验收门口等你点头,你看的是 diff 和测试证据,不是它的转述。记录落在本地,你的 agent 自己也查得到——半个月后问它"这段代码为什么存在",它答得上来;这些任务和记录,就是交接文档。见[Board](/cetas/features/board/)。 让 agent 评审自己的改动,"只报告别修改"全靠口头嘱咐。子代理把这句话变成配置:工具面和权限档位写在它的定义文件里,看不见 `write`,跑不了 `bash`,父会话开 `yolo` 也越不了权。让它调研三个模块也是同一条路——三个子会话同时读,主窗口只收三份摘要。见[子代理](/cetas/features/subagents/)。 40 个文件里找 3 处引用,逐条读就是付 40 次的钱。换成让模型写一小段程序去循环、过滤,只把那 3 处带回对话——那些内容从头到尾没产生过,也就没产生过费用。程序跑在 Wasm 沙箱里,文件系统和网络都碰不到。见[Bunraku](/cetas/features/bunraku/)。 人和 agent 读的是同一份文档:全站有 `llms.txt` 和 `llms-full.txt`,每个文档页带 `.md` 源文件。让另一个 agent 先读完这套文档再决定装不装,是受支持的使用方式。 基础能力也都齐备:权限有五档姿态,会话每轮落盘、`/rewind` 精确回退,全部状态在一个 home 目录,选模型之前先看见哪家有额度、哪个更划算。这些在[特色功能](/cetas/features/)与[配置](/cetas/configuration/)里各有其页,这里不再展开。 ## 三种入口、两种终端实现 | 入口 | 适合什么 | 怎么装 | | --- | --- | --- | | **终端 · JS(首选)** | 日常交互、会话回退、JS 专属功能 | npm 的 `cetas` | | **终端 · Native(第二选择)** | 不需要 Node.js 的 Go/Bubble Tea 终端,功能范围有所不同 | Homebrew、Scoop 或发布文件 | | **编辑器** | 在代码已经在的地方工作,走 ACP | `cetas-acp` | | **自动化** | 一次调用一个任务,脚本或 CI | `cetas-run` | 这些入口不是分叉的 Agent 内核:它们组合同一个 Cetas/Posoco,但 UI 和宿主能力不同,JS 与 Native 终端不保证完全互换。详见[入口(Surfaces)](/cetas/concepts/surfaces/)。 从[安装与首次运行](/cetas/getting-started/installation/)开始。 ## 为什么是 Posoco 如果你在写 agent,或者正在挑一个 agent 框架,这一节是给你的;只想用 Cetas 干活,可以放心跳过。 它和常见框架的差异,落在四件可以验证的事上: agent 循环的事件流是封闭枚举。内核新增一种事件,所有没跟上的分支立刻变成编译错误,指到具体的分支——升级时不用通读更新日志去猜行为,编译器会直接告诉你哪里断了。 工具调用被拒时,返回的是结构化原因:没被提供、owner 不允许、已被撤销、schema 不匹配、被钩子拒绝。写 UI 和 observer 的人拿到的是可以 match 的数据,不用拿正则去解析提示词。 每个能力登记时都带着 owner,可以被另一个扩展领走,收窄成"藏而不废"——从目录里退场,调用通道还在。目录、归属、收窄是同一份快照,没有第二处状态。 供应商是各自独立的扩展。没有一张统一 router 把各家压成同一个形状,每家的完整能力在自己的扩展包里实现,Cetas 的供应商清单就是这样一个个攒出来的。 这些话需要证据,证据是 Cetas 本身:三个传输方式不同的入口组合同一个内核,没有分叉的 agent 循环。Posoco 的破坏性升级附带一张显式的迁移映射表,该改什么、改成什么逐条写明,不靠读 diff 反推。第一条能成立的前提是 MoonBit——封闭枚举加穷尽检查,"编译器告诉你哪里断"靠的就是这个。 Posoco 提供协议和端口;Cetas 是在它上面扛过真实负载的那个实现。 # 参考 > 参考区收的都是稳定的东西:命令的名字、settings.json 的字段、环境变量,以及 Cetas 使用的持久路径。 Source: https://colmugx.github.io/cetas/reference/ · Markdown: https://colmugx.github.io/cetas/reference/index.md 这里收的都是稳定的东西:命令的名字、文件的位置,以及背后的行为。 - **命令** — 终端里的每一个斜杠命令和按键。 - **Settings** — settings.json 的完整字段:每个 key、类型、默认值,按嵌套层级展开。 - **环境变量** — 各入口读取的变量,以及它们的作用域。 持久路径在 [Cetas Home](/cetas/configuration/cetas-home/)。 # 命令 > 终端入口的全部斜杠命令与按键 Source: https://colmugx.github.io/cetas/reference/commands/ · Markdown: https://colmugx.github.io/cetas/reference/commands/index.md 斜杠命令是确定性的那条路:立即执行,不经过模型回合。`/help` 才是你手上这份构建的权威 —— 本页讲的是其中值得记住的那些。 ## 会话与历史 | 命令 | 作用 | | --- | --- | | `/new` | 开一个新会话 | | `/sessions` | 浏览并续接历史会话 | | `/rewind` | 把这次对话退回到更早的某条消息 | | `/resume` | 续接本会话被中断的那个回合 | | `/compact` | 压缩当前上下文 | `/rewind` 是那个"救命键":一个回合搞砸了,退回到它之前,而不是跟模型反复解释。 ## 模型与供应商 | 命令 | 作用 | | --- | --- | | `/login` | 认证供应商(API key 或 OAuth) | | `/model` | 选对话模型,以及它的推理档位 | | `/decision` | 选决策模型 —— 和 `/model` 相互独立 | | `/effort` | 选当前模型的推理档位 | | `/manager` | 在供应商集合与 Magpie 之间切换 —— 走法与判据见[接入 Magpie 网关](/cetas/configuration/magpie/) | | `/quota` | 显示当前管理器的配额信息 | | `/status` | 显示 agent、会话、模型与管理器状态 | ## 权限与上下文 | 命令 | 作用 | | --- | --- | | `/permission` | 设置本会话的权限姿态 —— 见[权限](/cetas/configuration/permissions/) | | `/ptc` | 选择程序化工具调用模式 | | `/skills` | 按作用域浏览已发现的技能 | ## 干活 | 命令 | 作用 | | --- | --- | | `/questions` | 查看待回答的问题并回答一个 | | `/answer` | 就地回答待答问题:`/answer @q3 是` | | `/board` | 在浏览器里打开 Board 看板(未开启工作流时会询问是否开启) | | `/board.stop` | 停掉所有本地 Board 服务 | ## 杂项 | 命令 | 作用 | | --- | --- | | `/update` | 检查并安装更新 —— 只支持 npm 安装 | | `/pi` | 管理 pi 包 | | `/exit`、`/quit` | 退出 | > **不是每份构建都有全部命令** > > `/effort`、`/permission`、`/decision`、`/help` 来自组合进来的扩展,所以没有该能力的构建就不会提供它们。上面由 shell 自己拥有的命令则始终存在。`/help` 反映的是真实集合。 ## 按键 | 按键 | 效果 | | --- | --- | | Esc | 打断当前回合(若有待审批,先拒绝它) | | Esc Esc(空闲时) | 第一次清空输入,第二次打开 `/rewind` | | 运行中按 Enter | 把输入的内容作为后续消息排队 | | Tab / Enter | 应用高亮的 `@path` 补全 | | Ctrl+T | 折叠 / 展开思考块 | | Ctrl+O | 折叠 / 展开工具输出 | 如果 agent 在问你问题,直接打字回复即可 —— `/questions` 和 `/answer` 是给"想从几个里挑一个"的场景用的。 `/permission ` 在回合进行中也能用。会话做得比你预期多时,它就是随时踩刹车的方式。 # 环境变量 > 各 Cetas 入口会读取的环境变量——CETAS_HOME、权限启动姿态、MCP 连接时机、调试开关——以及各自的作用域。 Source: https://colmugx.github.io/cetas/reference/environment-variables/ · Markdown: https://colmugx.github.io/cetas/reference/environment-variables/index.md | 变量 | 作用域 | 行为 | | --- | --- | --- | | `CETAS_HOME` | 编辑器、自动化 | 覆盖平台用户 home —— 是 `.cetas` 的**父目录**,不是目录本身。终端入口不读它。 | | `CETAS_PERMISSION_MODE` | 编辑器(ACP) | 启动姿态:`readonly`、`workspace_write`、`interactive`、`auto`、`yolo`。不设是 `yolo`。取值不认识会警告一次并退回 `workspace_write`,所以笔误不会放宽姿态。 | | `CETAS_MCP_MODE` | 编辑器(ACP) | `eager` 表示启动时就连接配置好的 MCP 服务器,而不是等到第一个回合。 | | `CETAS_DELEGATE_FS` | 编辑器(ACP) | `host` 表示面向工具的文件读写走编辑器的 `fs/*` 反向调用,而不是本地文件系统。取值不认识会警告并保持 `local`。 | | `CETAS_DEBUG_WIRE` | 编辑器(ACP) | `1` 时把这个会话的线上流量追加到 `/.cetas/debug/-wire.jsonl`。 | | `CETAS_DEBUG_MCP_CATALOG` | 编辑器(ACP) | `1` 时把这个会话的工具目录 dump 到 `/.cetas/debug/-catalog.json`。 | | `CETAS_REGISTRY` | 终端 | 覆盖 `/update` 用的 npm registry —— 用于内部镜像。 | | `CETAS_MEMOH_HOME` | Memoh 运行时 | 迁移独立版本的 Memoh 运行时自己的状态目录。 | 自动化入口用命令行参数表达模型、档位、权限和无人值守行为,而不是这些变量 —— 见[自动化](/cetas/automation/)。 ## 说明 - `CETAS_HOME` 不是通用的:终端入口直接解析平台 home,所以脚本里设的 `CETAS_HOME` 只影响 `cetas-acp` 和 `cetas-run`,不影响 `cetas`。见 [Cetas Home](/cetas/configuration/cetas-home/)。 - 调试开关是按会话的:首次使用时才创建 `debug/`,事前不需要清理任何东西。 - 笔误一律往安全侧失败:权限取值错了退回更窄的姿态,调试开关错了就当没开(只有 `1` 才开启)。 # Settings 参考 > /.cetas/settings.json 的完整字段 —— 每个 key、类型、默认值,按嵌套层级组织。 Source: https://colmugx.github.io/cetas/reference/settings/ · Markdown: https://colmugx.github.io/cetas/reference/settings/index.md `/.cetas/settings.json` 是一个 JSON 对象。Cetas 原子写入,并保留它不负责的每一个 key——别的工具(或将来版本)写进去的东西,不会因为一次切模型就被抹掉。启动时,**缺失**的文件会带着空的 `providers` 对象被创建;**已存在**的文件永远不会被覆盖——包括空的或坏掉的。settings 坏掉会直接报错,Cetas 不会悄悄替你修好。 ## 顶层 key | Key | 类型 | 作用 | | --- | --- | --- | | `model` | 字符串 | 当前对话槽位,`provider/model` | | `reasoning_effort` | 字符串,可选 | 推理档位;不填用槽位默认 | | `decision_model` | 字符串,可选 | 决策槽位,与 `model` 相互独立 | | `providers` | 对象 | 供应商配置,条目由各供应商扩展解释 | | `subagent` | 对象 | 子代理的默认模型、推理档位与限额 | | `workflow` | 对象 | Board 多任务执行的预算 | | `model_manager` | 字符串 | 终端入口的模型管理器选择 | | `manager_selections` | 对象 | 各管理器记住的上次选择 | | `magpie` | 对象 | Magpie 网关设置,见[接入 Magpie 网关](/cetas/configuration/magpie/) | 下面按层级展开。 ## model / reasoning_effort / decision_model | Key | 谁读 | 说明 | | --- | --- | --- | | `model` | 所有入口 | 对话槽位;`/model` 写它 | | `reasoning_effort` | 所有入口 | 不填用该槽位广告的默认档位;`/effort` 写它 | | `decision_model` | 终端与编辑器 | 决策槽位;`/decision` 写它 | 更新选择时,无关的 key 原样保留。供应商配置变化导致原选择不可用时,Cetas 退回可用的默认值,不会卡在失效的旧选择上。 ## providers 条目是"供应商 id → 供应商配置"。每个条目由对应扩展解释,本页不代答: - 内置 id 与登录方式:[供应商](/cetas/configuration/providers/); - 非内置 id 会成为自定义供应商,协议由条目里的 `protocol`(`chat_completions` / `responses` / `messages`,缺省 `chat_completions`)声明;条目形状(`base_url`、`protocol`、`auth`、`models`、模型元数据)见[自定义模型](/cetas/configuration/custom-models/)。 凭据不放 `providers`:那里写的 `gateway_key` 不会被读取,网关凭据只走共享凭据库(`/login` 写入)。会被忽略并给出警告的是 `magpie` 段里的 `magpie.gateway_key`——凭据写进可编辑的配置文件,本身就是错的位置。怎么录,见[接入 Magpie 网关](/cetas/configuration/magpie/)。 ## subagent ```json { "subagent": { "default_model": "zai/glm-5.3", "default_effort": "low", "limits": { "swarm_items": 16, "concurrency": 4, "global_concurrency": 20, "timeout_ms": 1800000, "spawn_budget": 64, "answer_timeout_ms": 600000 }, "kinds": [] } } ``` | Key | 默认 | 说明 | | --- | --- | --- | | `default_model` | —(继承父级) | 所有未绑定模型的 kind 的默认对话槽位 | | `default_effort` | — | 同上的推理档位 | | `limits.swarm_items` | `16` | 一波并行里最多几项 | | `limits.concurrency` | `4` | 一波里同时跑几个 | | `limits.global_concurrency` | `20` | 全局同时跑几个 | | `limits.timeout_ms` | `1800000` | 单个子代理的实际耗时上限(30 分钟) | | `limits.spawn_budget` | `64` | 一个会话总共能拉起多少个子代理 | | `limits.answer_timeout_ms` | `600000` | 子代理的提问最多等父级多久(`0` 表示不限) | | `kinds` | `[]` | 直接写在 settings 里的 kind 条目,字段与 `.md` frontmatter 一致,见[子代理](/cetas/configuration/subagents/) | 每个字段都可选;整段不存在就是"用默认值、不额外加 kind"。模型选择的优先级链:显式传参 → kind 绑定 → `default_model` → 父级当前选择。 ## workflow 控制 Board 的多任务执行循环。不写 `enabled: true` 就是关闭。 | Key | 默认 | 范围 | | --- | --- | --- | | `enabled` | `false` | 布尔 | | `max_executions` | `8` | 1–1000 | | `max_elapsed_ms` | `600000` | 1–86400000 | | `execution_timeout_ms` | `60000` | 1–86400000,且 ≤ `max_elapsed_ms` | | `max_concurrency` | `2` | 1–8 | | `max_expansions` | `2` | 1–16 | | `max_generated_tasks` | `20` | 1–200 | | `max_depth` | `16` | 2–16 | | `continue_on_confirmed_failure` | `false` | 布尔 | 这一段故意严格:未知 key、类型不对、越界,都是组装错误——预算里的一个笔误,不能悄悄变成另一个预算。 ## model_manager / manager_selections / magpie 只属于终端入口:记住你选了哪个模型管理器、以及各自上次选了什么,切回来时能恢复原来的槽位。从启动网关到验证可用的一条主线,见[接入 Magpie 网关](/cetas/configuration/magpie/)。 | Key | 类型 | 说明 | | --- | --- | --- | | `model_manager` | `"providers"` 或 `"magpie"` | 当前管理器;不写等于 `"providers"` | | `manager_selections` | 对象 | 管理器 → `{ model, reasoning_effort }`,各记各的 | | `magpie.base_url` | 字符串 | Magpie 网关地址 | | `magpie.enabled` | 布尔 | 是否启用 Magpie | > **类型校验不是建议** > > 类型不对就是直接失败。`model_manager` 必须正好是 `providers` 或 `magpie`;`magpie.enabled` 必须是布尔。看似合理的取值也不会被接受。各字段的默认值与操作步骤见[接入 Magpie 网关](/cetas/configuration/magpie/)。