@cteno/sdk-linux-x64 2.10.13 → 2.10.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/bin/cteno-host-cli
3
- size: 35741944 bytes
4
- sha256: 2d28e9a748ec6de28ef50a8c2de4494e29ef33cab365eefab9b4995665cf7cdd
3
+ size: 35893496 bytes
4
+ sha256: c1e7cc519c3c2d639eb2183018cd9a99ca7bc3c8ec7728f6f985d3a1abf96655
package/bin/cteno-wiki CHANGED
Binary file
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "sku": "sdk-core",
4
- "version": "2.10.12",
4
+ "version": "2.10.15",
5
5
  "target": "linux-x64",
6
6
  "binaries": [
7
7
  "cteno-host-cli",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cteno/sdk-linux-x64",
3
- "version": "2.10.13",
4
- "description": "Bundled Cteno daemon (cteno-host-cli 2.10.12) for @cteno/sdk on linux-x64",
3
+ "version": "2.10.15",
4
+ "description": "Bundled Cteno daemon (cteno-host-cli 2.10.15) for @cteno/sdk on linux-x64",
5
5
  "license": "SEE LICENSE IN LICENSE.daemon",
6
6
  "homepage": "https://github.com/zalan159/cteno-sdk#readme",
7
7
  "repository": {
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "preferUnplugged": true,
28
28
  "cteno": {
29
- "daemonVersion": "2.10.12"
29
+ "daemonVersion": "2.10.15"
30
30
  },
31
31
  "publishConfig": {
32
32
  "access": "public",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "id": "cteno.inbox",
4
- "version": "0.6.3",
4
+ "version": "0.6.5",
5
5
  "title": "Cteno Connector",
6
6
  "icon": "git-network-outline",
7
7
  "color": "#276EF1",
@@ -52,17 +52,17 @@
52
52
  "handler": {
53
53
  "type": "decision",
54
54
  "point": "inbox.smart-route",
55
- "version": 6,
55
+ "version": 8,
56
56
  "mode": "active",
57
57
  "title": "route=decision:投递前问决策模型 wake / note / ignore",
58
58
  "skipIf": "!/decide",
59
59
  "timeoutSecs": 15,
60
60
  "maxFieldChars": 16384,
61
- "state": "Source: {{/source}} / {{/roomName}}\nAddressed to the bot (@-mention or direct message): {{/isMention}}\nWhat the owner cares about right now (decide against this): {{rpc:/data/focus}}\n\nNew message (platform raw event JSON; read the text and sender inside it):\n{{/raw}}",
61
+ "state": "Source: {{/source}} / {{/roomName}}\nAddressed to the bot (@-mention or direct message): {{/isMention}}\nWhat the owner cares about right now (decide against this): {{rpc:/data/focus}}\n\nEarlier messages from this same conversation that were only kept as context (newest last; empty if none):\n{{/recentContext}}\n\nNew message (platform raw event JSON; read the text and sender inside it):\n{{/raw}}",
62
62
  "questions": {
63
63
  "route": {
64
64
  "type": "choice",
65
- "instructions": "A bot reads messages from this source before they reach its owner. Decide what it should do with the new message. When the message is addressed to the bot (@-mention or direct message), lean towards wake, except spam, ads, promotions and harassment, which are ignore.",
65
+ "instructions": "A bot reads messages from this source before they reach its owner. Decide what it should do with the new message, judged against what the owner cares about. A message addressed to the bot (@-mention or direct message) leans towards wake, but the owner's focus decides: when it clearly falls outside what the owner wants handled, or is spam, ads, promotions or harassment, answer ignore even for a direct message. Waking interrupts the owner, so wake only when the message itself asks for something the focus names; when unsure, choose note. A message with no readable text (only [图片], [文件], a sticker or a link card) is note, or ignore when the earlier messages show the same sender broadcasting promotions. Technical discussion, prices or news among other people in a group is note even when detailed.",
66
66
  "options": {
67
67
  "wake": "Someone wants something now: a question, a request, a complaint or bug report, or a call to the bot or the owner, matching what the owner wants handled",
68
68
  "note": "An announcement or status update nobody needs answered: a meeting time, a decision made, a result, a new account or link, a plan. Worth remembering, nothing to do now",
@@ -75,7 +75,11 @@
75
75
  "route": {
76
76
  "wake": {
77
77
  "decision": "allow",
78
- "additionalContext": "[决策模型判定需要处理;是否 @ 你见事件 isMention,回不回复按本群规则自己判断]"
78
+ "additionalContext": "[决策模型判定需要处理;是否 @ 你见事件 isMention,回不回复按本群规则自己判断]",
79
+ "minConfidence": 0.6,
80
+ "otherwise": {
81
+ "decision": "note"
82
+ }
79
83
  },
80
84
  "note": {
81
85
  "decision": "note"
@@ -293,7 +293,9 @@ cteno-host-cli inbox remove-subscription <subscriptionId> # 仅手写 gener
293
293
  | `route` 怎么分流 | `direct`(默认)/ `decision` | `decision` = 每条收进来的消息(含 @、私聊、源级事件)先过**决策小模型**:需要处理的进会话起一轮(`wake`);有用的记下来随下一条带上(`note`,不起轮);无关的略过(`ignore`) | **任何平台**都能开 |
294
294
 
295
295
  `--focus` 一句话说明什么该叫醒(不填用默认标准)。决策模型不可用时:非 @ 群消息**不投递**;@ / 私聊**照常投递**,
296
- 且决策判 ignore 的 @ 也只降级为 note、不丢。`inbox rooms` 显示 `decisionModelReady`、`smartToday`(route=decision 的房间)。
296
+ 低置信(<0.6)的 wake / ignore 都降为 note;高置信 ignore 的私聊会丢弃。判定时模型能看到同会话最近几条 note;note 随下一次唤醒只送一次(24h 内最新 10 条)。
297
+ 连接器**未挂载**时事件在判定前就被拒收(`bound=false`、`unboundRejectedEvents`),这时 `smartToday` 不再增长——看到它不动先查挂载。
298
+ `inbox rooms` 显示 `decisionModelReady`、`smartToday`(route=decision 的房间)。
297
299
  决策是本插件在 `PreConnectorDeliver` 上声明的 Hook(判定时刻 `inbox.smart-route`),`decision records --point inbox.smart-route`
298
300
  可回看每条判定;用户想加自己的筛选规则就在同一事件上挂 Hook,不要改代码。
299
301
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "cteno.models",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "title": "Cteno 模型",
6
6
  "icon": "sparkles-outline",
7
7
  "color": "#8E7CFF",
@@ -24,7 +24,7 @@
24
24
  "description": "DeepSeek 官方 Anthropic-compatible 入口,默认 V4.1 Flash(识图)+ V4 Pro。",
25
25
  "apiKeyLabel": "DeepSeek API Key",
26
26
  "purchaseUrl": "https://platform.deepseek.com/api_keys",
27
- "baseUrl": "https://api.deepseek.com/anthropic",
27
+ "baseUrl": "https://api.deepseek.com/anthropic/v1",
28
28
  "apiFormat": "anthropic",
29
29
  "defaultModelId": "deepseek-flash",
30
30
  "compressModelId": "deepseek-flash",
@@ -39,7 +39,7 @@
39
39
  "description": "OpenAI Responses API,适合 GPT-5 / GPT-4.1 系列。",
40
40
  "apiKeyLabel": "OpenAI API Key",
41
41
  "purchaseUrl": "https://platform.openai.com/api-keys",
42
- "baseUrl": "https://api.openai.com",
42
+ "baseUrl": "https://api.openai.com/v1",
43
43
  "apiFormat": "openai",
44
44
  "defaultModelId": "gpt-5.1",
45
45
  "compressModelId": "gpt-4.1-mini",
@@ -57,7 +57,7 @@
57
57
  "description": "Claude 官方 Messages API。",
58
58
  "apiKeyLabel": "Anthropic API Key",
59
59
  "purchaseUrl": "https://console.anthropic.com/settings/keys",
60
- "baseUrl": "https://api.anthropic.com",
60
+ "baseUrl": "https://api.anthropic.com/v1",
61
61
  "apiFormat": "anthropic",
62
62
  "defaultModelId": "claude-sonnet-4-20250514",
63
63
  "compressModelId": "claude-3-5-haiku-20241022",
@@ -75,7 +75,7 @@
75
75
  "description": "Google Gemini 原生 generateContent API。",
76
76
  "apiKeyLabel": "Gemini API Key",
77
77
  "purchaseUrl": "https://aistudio.google.com/apikey",
78
- "baseUrl": "https://generativelanguage.googleapis.com",
78
+ "baseUrl": "https://generativelanguage.googleapis.com/v1beta",
79
79
  "apiFormat": "gemini",
80
80
  "defaultModelId": "gemini-3-pro-preview",
81
81
  "compressModelId": "gemini-2.5-flash",
@@ -109,7 +109,7 @@
109
109
  "description": "阿里云百炼 Anthropic-compatible Coding 入口。",
110
110
  "apiKeyLabel": "DashScope API Key",
111
111
  "purchaseUrl": "https://www.alibabacloud.com/help/en/model-studio/get-api-key",
112
- "baseUrl": "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic",
112
+ "baseUrl": "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1",
113
113
  "apiFormat": "anthropic",
114
114
  "defaultModelId": "qwen3.5-plus",
115
115
  "compressModelId": "qwen3.5-plus",
@@ -125,7 +125,7 @@
125
125
  "description": "智谱 GLM Anthropic-compatible 入口。",
126
126
  "apiKeyLabel": "GLM API Key",
127
127
  "purchaseUrl": "https://docs.z.ai/guides/",
128
- "baseUrl": "https://api.z.ai/api/anthropic",
128
+ "baseUrl": "https://api.z.ai/api/anthropic/v1",
129
129
  "apiFormat": "anthropic",
130
130
  "defaultModelId": "GLM-5.2",
131
131
  "compressModelId": "GLM-4.5-Air",
@@ -141,7 +141,7 @@
141
141
  "description": "Kimi Coding Anthropic-compatible 入口。",
142
142
  "apiKeyLabel": "Kimi API Key",
143
143
  "purchaseUrl": "https://platform.kimi.ai/console/api-keys",
144
- "baseUrl": "https://api.kimi.com/coding",
144
+ "baseUrl": "https://api.kimi.com/coding/v1",
145
145
  "apiFormat": "anthropic",
146
146
  "defaultModelId": "kimi-for-coding",
147
147
  "compressModelId": "kimi-for-coding",
@@ -155,7 +155,7 @@
155
155
  "description": "MiniMax Anthropic-compatible 入口。",
156
156
  "apiKeyLabel": "MiniMax API Key",
157
157
  "purchaseUrl": "https://platform.minimax.io/docs/guides/quickstart",
158
- "baseUrl": "https://api.minimax.io/anthropic",
158
+ "baseUrl": "https://api.minimax.io/anthropic/v1",
159
159
  "apiFormat": "anthropic",
160
160
  "defaultModelId": "MiniMax-M3",
161
161
  "compressModelId": "MiniMax-M2.5",
@@ -172,7 +172,7 @@
172
172
  "description": "xAI OpenAI-compatible 入口。",
173
173
  "apiKeyLabel": "xAI API Key",
174
174
  "purchaseUrl": "https://console.x.ai/",
175
- "baseUrl": "https://api.x.ai",
175
+ "baseUrl": "https://api.x.ai/v1",
176
176
  "apiFormat": "openai",
177
177
  "defaultModelId": "grok-4",
178
178
  "compressModelId": "grok-3-mini",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "id": "jev",
4
- "version": "0.7.0",
4
+ "version": "0.7.1",
5
5
  "title": "决策模型(Jev)",
6
6
  "description": "决策模型(TypeSafe Jev)的官方内置插件:声明内核决策模型后端(Cteno 托管中转、自建、自带 Key 直连 TypeSafe 三种),并提供 jev-browser 浏览器连续动作 helper。Agent 通过 decision_evaluate 工具或 helper 调用内核当前选中的决策模型;Key 只存在保险箱,由宿主解析,不经脚本。决策按输入类型自动选后端:纯文字走默认后端(托管时为 Jev);带图片的请求自动走支持图片且排序靠前的后端(托管中转把图片转发给 NanoGPT Luna,不配 Key 也能用;自带 NanoGPT Key 时直连 Luna;TypeSafe 危险区图片排最后)。图片默认后端可用 `cteno-host-cli decision set-default --modality image --backend <id>` 指定。另声明四个判定时刻:结尾催做、网页注入检查、删除会话复核已按标注评估转为 active;开局技能隐藏仍为影子模式(只记录不执行)。用 `cteno-host-cli decision points/records/set-mode` 查看和切换。",
7
7
  "icon": "navigate-outline",
@@ -146,21 +146,25 @@
146
146
  "handler": {
147
147
  "type": "decision",
148
148
  "point": "jev.stop-continue",
149
- "version": 1,
149
+ "version": 2,
150
150
  "mode": "active",
151
151
  "title": "结尾催做:回答没做完就让 agent 继续",
152
- "skipIf": "/stop_hook_active",
152
+ "skipIf": [
153
+ "/stop_hook_active",
154
+ "!/response"
155
+ ],
153
156
  "timeoutSecs": 8,
154
157
  "maxFieldChars": 4000,
155
- "state": "The user asked an AI agent:\n{{/last_user_message}}\n\nThe agent's final reply:\n{{/response}}",
158
+ "state": "The user asked an AI agent:\n{{/last_user_message}}\n\nTools the agent called during this turn (names only):\n{{/tools_summary}}\n\nThe agent's final reply:\n{{/response}}",
156
159
  "questions": {
157
160
  "finished": {
158
161
  "type": "choice",
159
- "instructions": "Is the agent stopping with the user's request actually handled?",
162
+ "instructions": "Is the agent stopping with the user's request actually handled? Handing work to a running thread (dispatch_task / send_to_thread) or setting a loop/schedule and saying it will wait for the report is a correct way to stop, not unfinished.",
160
163
  "options": {
161
164
  "done": "The request is handled: the work is done, or the reply fully answers it",
165
+ "delegated_waiting": "The remaining work was handed to a running thread or is waiting on an external event (a dispatched task, a loop or schedule, a pending build or reply), and the reply says so",
162
166
  "blocked_on_user": "The agent stops because it genuinely needs the user (a decision, a credential, an approval) and says so",
163
- "unfinished": "The agent stops early: it only described a plan, promised to do something next, or left the asked work half done without needing the user",
167
+ "unfinished": "The agent stops early on work it could do itself right now and did not hand to anyone: it only described a plan, or left the asked work half done without needing the user",
164
168
  "none": "None of the other options fits"
165
169
  }
166
170
  }
@@ -54,7 +54,7 @@ cteno-host-cli <domain> <subcommand> --help
54
54
  - **Create 批准审查**:`public-authority create-prepare --proposal <JSON-file>` 必填 workspaceId/profileId/canonical workdir/clientInstanceId/expiresAt/tools/sessionActions;UUID 与 policyId 由 daemon 生成。省略 transport 或 local 保持 local-owner;远端 create 必须显式 transport:relay 与匹配 account/route 的 ownerBindingId,摘要绑定二者;不代替独立 pair/ticket。核对完整摘要后 owner 才能 `create-confirm --proposal-id <id> --digest <sha256> --expires-at <Unix-seconds> --confirm`。动作逐项选择 sessionSend/sessionRead/resultRead/eventSubscribe;[] 仅 create,events 指 durable polling,不授 live 或 output 文本。私有交付前后复验并原子提交;现有 create-thread 单注册项承载 public adapter,是否可用以实际 createAdvertised/认证 discovery 为准,确认不是出生成功。开发者不得替 owner 实际授权。
55
55
  - **Workspace 登记**:`public-authority workspace-register --persona-id <existing-agent-persona-id> --workdir <canonical-absolute-directory> --confirm` 仅本地 owner IPC,要求 `public-workspace-owner-v1`。personaId 不是推理 profileId;只创建新绑定,重复或覆盖拒绝。返回 workspaceId 后仍需独立 create approval,登记不授予 public 权限。
56
56
  - **一次性任务**:`run` 会等待初始 turn 完成,默认再读取 normalized trace;最终 JSON 只有 `sessionId/success`,模型回答在 trace 中。行为验收以 `session trace` 为准。
57
- - **可继续对话**:`session/thread create` 后用 `session/thread chat`。`chat` 默认等待整轮;`--no-wait` 只表示投递完成,之后仍要读状态/trace。
57
+ - **可继续对话**:`session/thread create` 后用 `session/thread chat`。`chat` 默认等待整轮,并如实返回本轮结果:daemon 有 `send.wait.turn-result.v1` 时,模型 404/401/429 重试耗尽/回合超时会回 `success:false` + `errorKind` + 原始错误(含请求 URL),CLI 以非零码退出 `turn failed [<kind>]: <error>`;`--no-wait` 只表示投递完成,之后仍要读状态/trace。
58
58
  - **报告身份验收**:`session chat --handoff-id <Message.id> -m <原始报告>` 走报告通道,忙时注入当前轮、空闲时唤醒。仅用于已授权报告投递/重放;重试复用同 ID,同文不同 ID 是两条报告。响应 `acknowledged:true` 仅代表父 canonical ledger 已接受,不代表 LLM 完成。`success:true, acknowledged:false` 仍须以同 ID 重试确认;不要改文本后复用旧 ID。
59
59
  - **中途补话**:普通 `chat --no-wait` 不等同于强制 steering。要把已排队消息立即注入 live turn,使用 queue 的 steer/dispatch 操作;普通 queue 消息默认 hold-until-idle,并在之后独立成轮。具体动作先看 `session queue --help`。
60
60
  - **结果与完成通知**:普通顶层 thread 不会像 runtime-owned subagent/DAG 一样自动向派出方回灌 `[Task Complete]`。调用方应保留 thread id,并读取 `session get/trace`。后台工具 run 的 completion 只回到其 owning session。
@@ -67,7 +67,7 @@ cteno-host-cli <domain> <subcommand> --help
67
67
  - **请求定位链接**:先查 `session card capabilities` 的 methods 包含 `card-link`,再 `session card link <card_id>`。返回同一 canonical request/machine 的 `/interact?...` 第一方相对 path(终态仍可回看);只定位,不携授权、token或secret,不凭链接执行操作。不要硬编码域名或拼外站认证链接。
68
68
  - **权限**:无人值守调用必须显式选择合适的 permission mode;默认模式可能等待无人处理的权限卡。不要无条件使用 bypass,按用户授权选择。
69
69
  - **托管 worktree 是 daemon 的,不是你的**:`dispatch_task` 的 `worktree: "<短名>"` 由 daemon 在 `<主检出>-wt-<短名>` 建、在节点终态时**自动回收**(分支 `cteno-wt/<短名>` 与其上的提交保留,只删检出目录)。所以**不要**为派活手搓 `git worktree add`,也不要在 kickoff 里写「干完记得删」——拆除责任必须落在比节点活得久的组件上。想看 daemon 当前托管着哪些树,用 `cteno-host-cli storage worktrees`(只读;`session worktrees` 是另一回事,它列的是某个 thread workdir 下的 git worktree)。
70
- - **交回要附证据、合并要过复审**:`report_to_owner(status=done)` 带 `evidence:[{command,result,files}]`;runtime 拿命令去核子线程自己账本里的 shell 调用,无证据的交回在派活方那边第一行显示「[警告:无证据交回]」。仓库 main 上有 `REVIEW.md` 时,合并只能走 `merge_review`(op=review/status/close/merge;shell 里直接往 main `git merge` 会被拒):全新上下文的只读 `merge-reviewer` 按 Important/Nit/Pre-existing 出意见,Important 必须修掉或 op=close 写理由;第 4 轮起只审新增 diff;命中高风险路径一律「需人工审」,agent 不能合并。CLI 走 `cteno-host-cli session invoke-tool <sid> merge_review --input '{"op":"status","repo":"<wt>"}'`;复审记录在 `<git common dir>/cteno-review/<branch>.json`。见 `docs/architecture/review-gates.md`。
70
+ - **交回要附证据、合并要过复审**:`report_to_owner(status=done)` 带 `evidence:[{command,result,files}]`;runtime 拿命令去核子线程自己账本里的 shell 调用,无证据的交回在派活方那边第一行显示「[警告:无证据交回]」。仓库 main 上有 `REVIEW.md` 时,合并只能走 `merge_review`(op=review/status/close/merge;shell 里直接往 main `git merge` 会被拒):全新上下文的只读 `merge-reviewer` 按 Important/Nit/Pre-existing 出意见,Important 必须修掉或 op=close 写理由;第 4 轮起只审新增 diff。本仓库的 `REVIEW.md` 未声明 `high_risk`,没有「命中高风险路径需人工审」这道拦截(声明了 `high_risk` 的仓库才有)。CLI 走 `cteno-host-cli session invoke-tool <sid> merge_review --input '{"op":"status","repo":"<wt>"}'`;复审记录在 `<git common dir>/cteno-review/<branch>.json`。见 `docs/architecture/review-gates.md`。
71
71
  - **远程机器**:先 `machines list`(账号级列表,本身不接受 `--machine`),再把顶层 `--machine <id|name>` 放在业务命令之前。它只切换 transport;auth/host/status/connect/webview 等本地命令不能远程执行。长任务注意远程 RPC deadline,异步派出后再查状态通常更稳妥。
72
72
  - **跨机派发前先预检,别凭记忆写 machine id 和路径**。跨机是盲派:你看不见那台机器的磁盘,也不知道它装了哪些模型。两个**只读、不建 session**的命令回答这件事:
73
73
  - `cteno-host-cli --machine <id|name> machines describe` —— 平台/arch、daemon 版本、capability,以及**它真正能跑的 model profile 列表**。`dispatch_task` 带 `machine` + `profile_id` 前必须看这个:对端没有的 profile 根本无法推理。
@@ -97,6 +97,12 @@ cteno-host-cli <domain> <subcommand> --help
97
97
  - `cteno-host-cli devices pending` 看待批准请求(不含配对码);`devices approve <pairId> <手机上显示的6位码>` / `devices reject <pairId>`。码只能由用户从手机读给你或自己输入,不要猜;错一次该配对作废。
98
98
  - `devices list` 列已配对设备;`devices revoke <deviceId>` 立即撤销。批准/撤销属于授权变更,按确认门禁先问用户。
99
99
 
100
+ ## 桌面驾驶权(desktop 域)
101
+
102
+ 多个 agent 共用一块屏幕时由 daemon 仲裁驾驶权(`docs/architecture/desktop-control-runtime-state.md`):真实指针/键盘的动作占整机,后台投递到窗口的动作只占那个应用;被占时 `computer_use` 返回 `DESKTOP_BUSY`(点名持有者与起始时间)或 `DESKTOP_STOPPED`(急停冷却中),不要硬抢。
103
+ - `cteno-host-cli desktop [state]`(RPC `desktop-claim-state`):当前持有者 `holders[{sessionId,label,kind:machine|app,app,sinceMs,pid}]`(含同机其他进程)与急停冷却 `cooldownUntilMs`,只读。
104
+ - `cteno-host-cli desktop estop`(RPC `desktop-claim-estop`):急停——释放所有 claim、抬起按键,并让所有进程 30 秒内拒绝驾驶。这是代用户按下停止键,只在用户要求或明显失控时用。
105
+
100
106
  ## 历史证据与压缩后取回
101
107
 
102
108
  跨 session 验收先用 `session trace --help` 和 `session messages --help` 确认公共读接口。`trace` 用于检查模型实际执行的调用与结果;仅在最终回答中出现目标文字不算取回成功,尤其不能用用户测试提示中的文字作命中证据。`trace --full` 只关闭 CLI 行截断,不恢复宿主已截断的预览;读取原始证据用 `session messages <session_id> --message-id <id>`(可重复,最多 500 个),复用公共 `get-session-messages` 的精确 ID 读取,不直读 daemon SQLite。
@@ -169,6 +175,8 @@ cteno-host-cli profile import-models --base-url <url> --api-key-env KEY \
169
175
 
170
176
  > ⚠️ **能拉到 ≠ 能用**:目录说某组支持某模型,只代表"允许",不代表该组当前有活着的通道。用户报某个模型 503/无响应时,那是**分组选错**,换组重导即可,不是 profile 配错。
171
177
 
178
+ **Coding Plan 套餐(GLM / Kimi Code / MiniMax / 百炼)不走 discover/import**:模型与区域由已启用的套餐插件声明,key 拿到后一条命令建好 `coding-plan-<provider>-*`:`cteno-host-cli profile apply-preset --plugin <glm-coding-plan|kimi-code|minimax-coding-plan|bailian-coding-plan> --api-key-env KEY [--region <id>]`。剩余额度用 `cteno-host-cli plugin quota` 读(vendor `glm`/`kimi`/`minimax`);百炼没有 API-key 用量接口,只能在百炼控制台看,如实告诉用户。
179
+
172
180
  ## 网页搜索服务商(websearch 域)
173
181
 
174
182
  `websearch` 工具的服务商由插件(内建 `cteno.websearch`:`cteno` 托管 / `tavily` 自带 Key)声明,默认 auto:已配置 Key → 登录托管 → env `TAVILY_API_KEY`。用户说"用我自己的 Tavily Key""关掉网页搜索"时在这里闭环: