@ai-zen/agents-host 0.1.0-alpha.3 → 0.1.0-alpha.4

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/app.d.ts +0 -5
  3. package/dist/app.js +3 -9
  4. package/dist/handlers/configHandlers.d.ts +1 -3
  5. package/dist/handlers/conversationHandlers.d.ts +0 -2
  6. package/dist/handlers/conversationHandlers.js +2 -16
  7. package/dist/handlers/hostHandlers.d.ts +4 -5
  8. package/dist/handlers/hostHandlers.js +3 -21
  9. package/dist/handlers/index.d.ts +2 -4
  10. package/dist/handlers/index.js +0 -1
  11. package/dist/handlers/noticeHandlers.d.ts +0 -8
  12. package/dist/handlers/noticeHandlers.js +0 -10
  13. package/dist/i18n/en.d.ts +0 -168
  14. package/dist/i18n/en.js +0 -171
  15. package/dist/i18n/zh.d.ts +0 -168
  16. package/dist/i18n/zh.js +0 -169
  17. package/dist/index.d.ts +1 -0
  18. package/dist/net/WsHub.d.ts +1 -2
  19. package/dist/net/WsHub.js +0 -2
  20. package/dist/services/AutoNaming.d.ts +0 -5
  21. package/dist/services/AutoNaming.js +0 -18
  22. package/dist/services/ConfigService.d.ts +2 -2
  23. package/dist/services/ConfigService.js +11 -20
  24. package/dist/services/ModelService.d.ts +1 -3
  25. package/dist/services/ModelService.js +0 -4
  26. package/dist/services/QuestionService.d.ts +0 -7
  27. package/dist/services/QuestionService.js +0 -15
  28. package/dist/storage/ConversationRepository.d.ts +0 -3
  29. package/dist/storage/ConversationRepository.js +0 -12
  30. package/dist/storage/QuestionRepository.d.ts +0 -1
  31. package/dist/storage/QuestionRepository.js +0 -4
  32. package/dist/storage/types.d.ts +0 -2
  33. package/dist/wire/methods.d.ts +4 -52
  34. package/dist/wire/methods.js +0 -5
  35. package/dist/wire/states.d.ts +5 -12
  36. package/package.json +3 -2
  37. package/dist/handlers/capabilities.d.ts +0 -26
  38. package/dist/handlers/capabilities.js +0 -138
package/dist/i18n/zh.js CHANGED
@@ -26,11 +26,7 @@ export const zh = {
26
26
  "error.questionPending": "还有一个问题没回答({question})。先回答它,再发新内容。",
27
27
  "error.contextGuard": "这段对话在第 {used} 个 token 时到了 {limit} 这条线,请求在发出去之前就停下了。",
28
28
  // ---- 通知:三档语气 + 是否到点消失(PRD L3 / F-I8)----
29
- "notice.settingsSaved": "配置已保存。",
30
29
  "notice.settingsApplied": "配置已生效,不用重启。",
31
- "notice.conversationDeleted": "对话已删除。",
32
- "notice.workspaceDeleted": "项目已移除,它名下的 {count} 段对话一起删掉了,磁盘上的目录没动。",
33
- "notice.assetsUploaded": "已上传 {count} 张图片。",
34
30
  "notice.attachmentDropped": "{name} 没能发出去,这条消息里没有它。",
35
31
  "notice.upgradeRestarting": "已更新到 {version},现在重启。",
36
32
  "notice.logWarning": "宿主警告:{summary}",
@@ -38,19 +34,7 @@ export const zh = {
38
34
  "notice.configRecovered": "配置文件 {path} 坏了,已恢复出厂设置。",
39
35
  "notice.handoffWritten": "交接文档已写到 {path}。",
40
36
  "notice.autoNamed": "给这段对话起名叫「{name}」。",
41
- "notice.languageChanged": "这条连接现在说{language}。",
42
- "notice.hardLimitHit": "这一轮在 {limit} 这条线停下了。东西都还在,对话等你继续。",
43
37
  // ---- 生成六态(PRD L8 / F-I3)----
44
- "status.connected": "已连上",
45
- "status.awaitingFirstToken": "已连上,等第一个字",
46
- "status.thinking": "在想…",
47
- "status.generating": "在输出…",
48
- "status.assemblingToolCalls": "正在拼 {count} 个工具调用…",
49
- "status.awaitingTools": "在等 {tools}",
50
- "status.idle": "空闲",
51
- "status.done": "已结束",
52
- "status.aborted": "已中止",
53
- "status.error": "出错停下",
54
38
  // ---- 问题对象(PRD D22 / F-I9)----
55
39
  "question.handoff.prompt": "这段对话已用到上下文预算的 {percent}%。接下来怎么办?",
56
40
  "question.handoff.self": "让助手自己写交接",
@@ -58,34 +42,15 @@ export const zh = {
58
42
  "question.handoff.summary": "改成摘要历史",
59
43
  "question.handoff.summaryDetail": "更便宜也更确定,但文档没那么多细节。",
60
44
  "question.handoff.decline": "就在这段对话里继续",
61
- "question.confirm.prompt": "「{action}」撤不回来。确定要做吗?",
62
- "question.confirm.accept": "确定",
63
- "question.confirm.decline": "取消",
64
45
  "question.blocking": "这段对话被这个问题挡住了,答了才能继续。",
65
46
  // ---- 消息与状态的事实叙述 ----
66
- "message.reverted": "删掉了 {count} 条消息,内容已经放回输入框。",
67
- "message.cwdMissing": "这个项目的目录已经不存在了({cwd})。对话和历史都还在。",
68
47
  "message.injectedContext": "这段是宿主加进来的,不是你输入的:{summary}",
69
48
  // 会话创建时那条 hidden 消息里的那句事实(PRD F-D9:cwd 来自对话所属项目,不是宿主进程的目录)
70
49
  "message.injectedContext.cwd": "当前目录是 {cwd}",
71
50
  "message.subagentFailed": "子 Agent {name} 失败了:{reason}",
72
- "message.subagentFinished": "子 Agent {name} 跑完了。",
73
51
  "message.imageAsText": "{model} 看不了图片,{name} 改成用文字描述发过去。",
74
- "message.attachmentTooMany": "一条消息最多带 {limit} 张图片,{name} 没放进去。",
75
52
  // ---- 用量(PRD F-I5)----
76
- "usage.turn": "本轮 {value} tokens",
77
- "usage.total": "累计 {value} tokens",
78
- "usage.rate": "{value} tokens/秒",
79
- "usage.withSubAgents": "累计里有 {value} 来自子 Agent",
80
53
  // ---- 状态栏各块的标签(PRD F-I6)----
81
- "label.agent": "助手",
82
- "label.model": "模型",
83
- "label.thinking": "思考强度",
84
- "label.context": "上下文",
85
- "label.usage": "用量",
86
- "label.cwd": "目录",
87
- "label.tools": "在跑的工具",
88
- "label.subagents": "子 Agent",
89
54
  // ---- `@` 补全(PRD F-H5 / D7)----
90
55
  "completion.scanning": "还在读项目的文件清单,再多打几个字它就出来了。",
91
56
  "completion.timedOut": "文件清单超过 {seconds} 秒才建好,可能不完整。",
@@ -96,7 +61,6 @@ export const zh = {
96
61
  "config.referenced": "还有 {count} 处引用它,所以不能删:{names}",
97
62
  "config.fileBroken": "{path} 读不成配置:{reason}",
98
63
  // ---- 端点、模型、助手的可用性(PRD F-B5:用不了也要列出来并说明原因)----
99
- "endpoint.missing": "{id} 已经不在端点列表里了,所以这里连不出去。",
100
64
  "endpoint.noKey": "{endpoint} 还没配访问密钥,它的模型答不了话。",
101
65
  "model.endpointMissing": "{model} 指向的端点({id})已经不在端点列表里了。",
102
66
  "agent.modelMissing": "这个助手绑定的模型({id})已经不在模型列表里了。",
@@ -113,13 +77,7 @@ export const zh = {
113
77
  "discovery.skillBroken": "{name} 的 SKILL.md 用不成一个 Skill:{reason}",
114
78
  "discovery.toolUnloadable": "{name} 加载不成一个工具:{reason}",
115
79
  "discovery.subAgentBroken": "{name} 不是一个能用的子 Agent 定义:{reason}",
116
- "model.unavailable": "{name} 还在列表里,但现在用不了:{reason}",
117
- "model.visionRequired": "{model} 读不了图片,而这段对话里有图片。",
118
80
  "handoff.degraded": "交接退回到了 {mode}:{reason}",
119
- "handoff.declined": "这次不交接。",
120
- "handoff.noDocuments": "这个项目里还没有交接文档。",
121
- "workspace.removalCost": "这会删掉 {conversations} 段对话和它们的 {messages} 条消息,磁盘上的目录不动。",
122
- "attachment.tooLarge": "一张图片最大 {limit},{name} 是 {size}。",
123
81
  "attachment.tooMany": "一条消息最多带 {limit} 张图片。",
124
82
  // ---- 通知 / 问题 / 交接 / 自动命名 / 临时对话(W4-H)----
125
83
  "notice.unknown": "宿主有一条通知({code})。",
@@ -128,131 +86,4 @@ export const zh = {
128
86
  "handoff.newConversationSummary": "这段对话接着上一段。交接文档在 {path},先读它,再接着做这件事。\n\n交接摘要:\n{summary}",
129
87
  "handoff.degradeReason.fallback": "这次助手自己没能把文档写出来",
130
88
  "autoName.failed": "没起出名字,保持原来的名字:{reason}",
131
- // ---- 能力清单:帮助页与指令菜单按它渲染(F-E5 / F-E6 / F-F9)----
132
- "capability.host.hello": "连上宿主",
133
- "capability.host.hello.detail": "拿一串访问密钥建立连接,并定下这条连接说哪种语言。",
134
- "capability.host.version": "看宿主版本",
135
- "capability.host.version.detail": "正在跑的版本与协议版本,升级靠它比对。",
136
- "capability.host.upgrade": "升级后重启",
137
- "capability.host.upgrade.detail": "比对磁盘上的版本与正在跑的版本,确认新版本真的落盘了才重启。",
138
- "capability.host.shutdown": "关掉宿主",
139
- "capability.host.shutdown.detail": "等手上没有欠着的事之后停止服务,已连上的连接会断开。",
140
- "capability.host.capabilities": "列出宿主能做什么",
141
- "capability.host.capabilities.detail": "帮助页就是照这份清单渲染的:每件事做什么、会不会占住对话、能不能撤。",
142
- "capability.host.reload": "从磁盘重载",
143
- "capability.host.reload.detail": "重新读一遍配置、助手、工具、技能或 MCP 条目:受影响的项日会重建能力,不用重启。",
144
- "capability.host.setLanguage": "换这条连接的语言",
145
- "capability.host.setLanguage.detail": "这条连接上的文案都按选的语言渲染;断开重连就忘掉。",
146
- "capability.workspace.list": "列出项目",
147
- "capability.workspace.list.detail": "这台机器上的全部项目,包括目录已经不在的那些。",
148
- "capability.workspace.create": "添加项目",
149
- "capability.workspace.create.detail": "把一个目录登记成项目;同一个目录只能登记一次。",
150
- "capability.workspace.get": "看一个项目",
151
- "capability.workspace.get.detail": "按 id 取一个项目,同时告诉你它的目录还在不在。",
152
- "capability.workspace.rename": "重命名项目",
153
- "capability.workspace.rename.detail": "只改显示名,目录路径不变。",
154
- "capability.workspace.remove": "移除项目",
155
- "capability.workspace.remove.detail": "把这个项目和它名下的对话一起删掉,磁盘上的目录不动。",
156
- "capability.conversation.list": "列出对话",
157
- "capability.conversation.list.detail": "新的在前、置顶的在最上;可以只看某个项目的。",
158
- "capability.conversation.create": "开一段对话",
159
- "capability.conversation.create.detail": "创建时就把项目、助手、模型定下来。",
160
- "capability.conversation.get": "打开一段对话",
161
- "capability.conversation.get.detail": "按 id 取一段对话,接着上次聊靠它。",
162
- "capability.conversation.state": "看现在到哪了",
163
- "capability.conversation.state.detail": "一份快照里给出六态运行现场、上下文阈值、待答问题与用量。",
164
- "capability.conversation.rename": "给对话改名",
165
- "capability.conversation.rename.detail": "只改名字,身份与排序不变。",
166
- "capability.conversation.pin": "置顶对话",
167
- "capability.conversation.pin.detail": "把它钉在侧栏最上面,其余不变。",
168
- "capability.conversation.delete": "删除对话",
169
- "capability.conversation.delete.detail": "把这段对话和它的消息硬删,顺带清掉它引用的图片。",
170
- "capability.conversation.send": "发一条消息",
171
- "capability.conversation.send.detail": "跑一轮:消息 id 立刻回来,回答随后流式到达。",
172
- "capability.conversation.abort": "停下这一轮",
173
- "capability.conversation.abort.detail": "把正在写的回答停下来,已经写出的那些留在库里。",
174
- "capability.conversation.revert": "撤回消息",
175
- "capability.conversation.revert.detail": "把某条消息之后的全部删掉,并把那段正文回填到输入框。",
176
- "capability.conversation.setModel": "只给这段对话换模型",
177
- "capability.conversation.setModel.detail": "不动助手的默认模型,也不重开对话。",
178
- "capability.conversation.setThinking": "调这段对话的思考强度",
179
- "capability.conversation.setThinking.detail": "把档位展开成请求参数,只对这段对话生效。",
180
- "capability.conversation.transient": "问一次、不留痕迹",
181
- "capability.conversation.transient.detail": "一次请求一次回答,不入库、不建对话。",
182
- "capability.message.list": "看消息",
183
- "capability.message.list.detail": "一段对话的全部历史,或从某条消息开始的全部;子 Agent 的消息也能取。",
184
- "capability.question.list": "看待答问题",
185
- "capability.question.list.detail": "还在等回答的问题;多端看到的是同一批。",
186
- "capability.question.answer": "回答问题",
187
- "capability.question.answer.detail": "记下答案并接着往下走:交接问题会自己把交接开起来。",
188
- "capability.notice.list": "看通知",
189
- "capability.notice.list.detail": "现在还在界面上的通知——它不进消息流。",
190
- "capability.notice.dismiss": "清掉一条通知",
191
- "capability.notice.dismiss.detail": "把一条通知手动清掉;带持续时间的会自己到点消失。",
192
- "capability.notice.clear": "清掉一批通知",
193
- "capability.notice.clear.detail": "一次清一批:整个列表,或某一对话的那些。",
194
- "capability.config.get": "看配置",
195
- "capability.config.get.detail": "一次读出端点(密钥掩码)、模型、默认项,以及哪里配错了。",
196
- "capability.config.patch": "改配置",
197
- "capability.config.patch.detail": "改完当场生效——不用重启,也没有全局保存键。",
198
- "capability.config.setDefaults": "设默认项",
199
- "capability.config.setDefaults.detail": "默认助手、兜底模型、迁移模型、图片模型、取名模型。",
200
- "capability.config.getDiscovery": "看能力从哪来",
201
- "capability.config.getDiscovery.detail": "MCP 各层、Skill、工具、子 Agent 到底找到了哪些,以及哪些文件读不出来。",
202
- "capability.config.saveMcp": "保存一条 MCP 服务器",
203
- "capability.config.saveMcp.detail": "有这一条就改、没有就建;只动这一条,传输方式与它的参数都在入参里,这一版不认识的字段原样保留。",
204
- "capability.config.deleteMcp": "删除一条 MCP 服务器",
205
- "capability.config.deleteMcp.detail": "只从可编辑的那两个作用域里删这一条;本来就没有时如实回报,不算失败。",
206
- "capability.config.saveEndpoint": "保存端点",
207
- "capability.config.saveEndpoint.detail": "新建或修改端点;密钥省略就表示保留现有的。",
208
- "capability.config.deleteEndpoint": "删除端点",
209
- "capability.config.deleteEndpoint.detail": "还有模型指着它时拒删,并把引用者列出来。",
210
- "capability.agent.list": "列出助手",
211
- "capability.agent.list.detail": "全部助手,不可用的也列出来并说明原因。",
212
- "capability.agent.get": "看一个助手",
213
- "capability.agent.get.detail": "按 id 取一份助手定义,直接来自它的文件。",
214
- "capability.agent.create": "新建助手",
215
- "capability.agent.create.detail": "写一份新的定义文件——一助手一文件,能手改、能进 git。",
216
- "capability.agent.update": "编辑助手",
217
- "capability.agent.update.detail": "改定义文件;从此它算你自己定的,不再按出厂版覆盖。",
218
- "capability.agent.delete": "删除助手",
219
- "capability.agent.delete.detail": "删掉这份定义,删前先说清还有谁指着它。",
220
- "capability.agent.setModel": "设助手默认模型",
221
- "capability.agent.setModel.detail": "改的是助手的默认模型,影响以后新开的对话。",
222
- "capability.agent.setThinking": "设助手的思考档位",
223
- "capability.agent.setThinking.detail": "把展开后的请求参数写进助手定义。",
224
- "capability.agent.restoreFactory": "恢复助手出厂设置",
225
- "capability.agent.restoreFactory.detail": "把这份助手定义整条换回宿主自带的那一份——提示词、模型、权限、思考设置一起回退;可以先看恢复之后会是什么样再决定。",
226
- "capability.model.list": "列出模型",
227
- "capability.model.list.detail": "出厂托管与自定义的模型,带两条阈值、思考档位与可用性。",
228
- "capability.model.listImages": "列出图片模型",
229
- "capability.model.listImages.detail": "用来生成图片的那些模型,以及哪个是默认。",
230
- "capability.model.create": "新建模型",
231
- "capability.model.create.detail": "新建时就绑到某个端点上,并且立刻算自定义。",
232
- "capability.model.update": "编辑模型",
233
- "capability.model.update.detail": "编辑出厂模型会把它转成自定义,以后的出厂更新不再覆盖它。",
234
- "capability.model.delete": "删除模型",
235
- "capability.model.delete.detail": "还被助手指着时拒删;删掉时把默认项一起收拾干净。",
236
- "capability.model.restoreFactory": "恢复出厂",
237
- "capability.model.restoreFactory.detail": "用出厂那一份整条替换掉现在的模型定义。",
238
- "capability.model.saveImage": "新建或修改图片模型",
239
- "capability.model.saveImage.detail": "把图片模型绑到端点上,带默认尺寸与质量。",
240
- "capability.model.deleteImage": "删除图片模型",
241
- "capability.model.deleteImage.detail": "它还是默认图片模型时拒删。",
242
- "capability.asset.begin": "开始上传",
243
- "capability.asset.begin.detail": "先声明文件的大小与类型,超限的当场就拒。",
244
- "capability.asset.end": "结束上传",
245
- "capability.asset.end.detail": "校验长度与摘要,然后把它变成消息可以引用的素材。",
246
- "capability.asset.get": "取回素材",
247
- "capability.asset.get.detail": "把存着的字节取回来,任何模型都能重放历史里的图;缩略图这一档目前等同原图。",
248
- "capability.completion.files": "补全文件路径",
249
- "capability.completion.files.detail": "`@` 菜单背后的项目文件清单;还在读的时候会说出来。",
250
- "capability.handoff.start": "写交接文档",
251
- "capability.handoff.start.detail": "写出文档,需要的话顺手开新对话;旧对话完整保留。",
252
- "capability.handoff.listDocuments": "列出交接文档",
253
- "capability.handoff.listDocuments.detail": "这个项目里已经写好的文档,可以反复打磨同一份。",
254
- "capability.search.conversations": "按名字搜对话",
255
- "capability.search.conversations.detail": "按名字找旧对话,可以只在某个项目里找。",
256
- "capability.search.messages": "搜对话内容",
257
- "capability.search.messages.detail": "对说过的话做全文搜索,每条命中带一小段原文。",
258
89
  };
package/dist/index.d.ts CHANGED
@@ -14,4 +14,5 @@ export { createHost, resolveHostVersion, HostApp } from "./app.js";
14
14
  export type { ExitFacts, ExitHook, ExitReason, HostAppOptions } from "./app.js";
15
15
  export { DEFAULT_PORT, LOOPBACK_HOST, PUBLIC_HOST, isValidPort, resolveDataRoot, resolveListenTarget, resolvePaths, } from "./config.js";
16
16
  export type { ListenTarget, ListenTargetInput, HostPaths } from "./config.js";
17
+ export type { HostFileInfo } from "./net/discovery.js";
17
18
  export * from "./wire/index.js";
@@ -20,7 +20,7 @@
20
20
  */
21
21
  import type { ListenTarget } from "../config.js";
22
22
  import { type Language } from "../i18n/index.js";
23
- import { type CapabilityView, type ClientInfo, type EventMap, type EventName, type MethodName, type MethodParams, type MethodResult } from "../wire/index.js";
23
+ import { type ClientInfo, type EventMap, type EventName, type MethodName, type MethodParams, type MethodResult } from "../wire/index.js";
24
24
  import type { TokenVerifier } from "./auth.js";
25
25
  import { type UploadReceiver } from "./UploadReceiver.js";
26
26
  /** 一条连接对 handler 可见的事实(不把 socket 漏给业务层) */
@@ -94,7 +94,6 @@ export interface WsHubOptions {
94
94
  *
95
95
  * 入参是这条连接的语言(裁定 R58):句子按收件人的语言给,id 列表与顺序不变(R57)。
96
96
  */
97
- capabilities?: (language: Language) => CapabilityView[];
98
97
  /** 连接未声明语言时的缺省语言(PRD D8:缺省英文);给函数时每次握手现算 */
99
98
  defaultLanguage?: DefaultLanguageSource;
100
99
  /** 推送出网前的按连接本地化(不注入则原样搬运) */
package/dist/net/WsHub.js CHANGED
@@ -392,8 +392,6 @@ export class WsHub {
392
392
  hostVersion: this.options.hostVersion,
393
393
  protocolVersion: PROTOCOL_VERSION,
394
394
  startedAt: this.startedAt,
395
- // 握手只给能力 id 列表(R57):清单本身按这条连接的语言渲染,但 id 与顺序固定
396
- capabilities: (this.options.capabilities?.(state.language) ?? []).map((capability) => capability.id),
397
395
  limits: this.transferLimits(),
398
396
  };
399
397
  }
@@ -77,11 +77,6 @@ export declare class AutoNaming {
77
77
  * 之后都不会多做一次请求 —— 第二轮之后 `not_first_turn` 会把后面的调用全部挡住。
78
78
  */
79
79
  afterTurn(conversationId: string, language?: Language): Promise<AutoNameOutcome>;
80
- /** 这段对话当前该不该起名(接线层在调用前想做别的判断时用;不改任何状态) */
81
- shouldName(conversationId: string): Promise<{
82
- should: boolean;
83
- reason: AutoNameSkip | null;
84
- }>;
85
80
  /**
86
81
  * 缺省的取名调用:用 SDK 的 `completeOnce`(与交接摘要共用同一份请求体形状)。
87
82
  *
@@ -173,24 +173,6 @@ export class AutoNaming {
173
173
  }
174
174
  return { named: true, name, skipped: null, problem: null };
175
175
  }
176
- /** 这段对话当前该不该起名(接线层在调用前想做别的判断时用;不改任何状态) */
177
- async shouldName(conversationId) {
178
- const conversation = await this.conversations.get(conversationId);
179
- if (!conversation)
180
- return { should: false, reason: "conversation_missing" };
181
- const config = await this.configManager.read();
182
- if (config.autoTitle === false)
183
- return { should: false, reason: "disabled" };
184
- if (!conversation.nameIsAuto)
185
- return { should: false, reason: "renamed_by_user" };
186
- const rows = await this.messages.listByConversation(conversationId);
187
- const userCount = rows.filter((row) => row.role === AgentNS.Role.User).length;
188
- if (userCount !== 1)
189
- return { should: false, reason: "not_first_turn" };
190
- if (!config.namingModel && !config.defaultModel)
191
- return { should: false, reason: "no_model" };
192
- return { should: true, reason: null };
193
- }
194
176
  /**
195
177
  * 缺省的取名调用:用 SDK 的 `completeOnce`(与交接摘要共用同一份请求体形状)。
196
178
  *
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import type { AgentRepository } from "@ai-zen/agents-sdk";
17
17
  import type { AppConfig, ConfigManager } from "@ai-zen/agents-sdk";
18
- import type { ConfigDeleteEndpointParams, ConfigDeleteEndpointResult, ConfigDeleteMcpParams, ConfigDeleteMcpResult, ConfigGetDiscoveryParams, ConfigGetDiscoveryResult, ConfigGetParams, ConfigGetResult, ConfigPatchParams, ConfigPatchResult, ConfigSaveEndpointParams, ConfigSaveEndpointResult, ConfigSaveMcpParams, ConfigSaveMcpResult, ConfigSetDefaultsParams, ConfigSetDefaultsResult, ConfigView, HostReloadParams, HostReloadResult } from "../wire/index.js";
18
+ import type { ConfigDeleteEndpointParams, ConfigDeleteEndpointResult, ConfigDeleteMcpParams, ConfigDeleteMcpResult, ConfigGetDiscoveryParams, ConfigGetDiscoveryResult, ConfigGetParams, ConfigGetResult, ConfigPatchParams, ConfigPatchResult, ConfigSaveEndpointParams, ConfigSaveEndpointResult, ConfigSaveMcpParams, ConfigSaveMcpResult, ConfigSetDefaultsParams, ConfigSetDefaultsResult, ConfigView, HostReloadResult } from "../wire/index.js";
19
19
  import { DiscoveryService, type WorkspaceCwdLookup } from "./DiscoveryService.js";
20
20
  import { ModelService } from "./ModelService.js";
21
21
  /** 改配置时用到的几类「生效」信号(→ {@link ConfigApplyReport}) */
@@ -99,7 +99,7 @@ export declare class ConfigService {
99
99
  * 把「哪几类要重新装配」交给注入的生效一跳(回收受影响的 Scope + 合成一条通知),出参与
100
100
  * `config.patch` 同一份形状,客户端于是可以用同一套提示。
101
101
  */
102
- reload(params?: HostReloadParams): Promise<HostReloadResult>;
102
+ reload(): Promise<HostReloadResult>;
103
103
  /**
104
104
  * `config.saveEndpoint`(F-F2):同一个方法兼创建与修改。
105
105
  *
@@ -19,8 +19,6 @@ import { MAX_ASSETS_PER_MESSAGE, MAX_ASSET_BYTES } from "../wire/index.js";
19
19
  import { DiscoveryService } from "./DiscoveryService.js";
20
20
  import { ModelService } from "./ModelService.js";
21
21
  import { isSecretMask, maskSecret } from "./secretMask.js";
22
- /** `host.reload` 认的几档范围(与契约同源) */
23
- const RELOAD_SCOPES = ["config", "agents", "tools", "skills", "mcp"];
24
22
  /** 可以写的三档行为开关取值(与 SDK `AppConfig` 的取值一致) */
25
23
  const ABORTED_MESSAGE_STRATEGIES = ["keep", "drop"];
26
24
  const ABORTED_TOOL_ROUND_STRATEGIES = ["fill", "drop"];
@@ -170,15 +168,8 @@ export class ConfigService {
170
168
  * 把「哪几类要重新装配」交给注入的生效一跳(回收受影响的 Scope + 合成一条通知),出参与
171
169
  * `config.patch` 同一份形状,客户端于是可以用同一套提示。
172
170
  */
173
- async reload(params = {}) {
174
- const scope = params.scope;
175
- if (scope !== undefined && !RELOAD_SCOPES.includes(scope)) {
176
- throw new HostError("invalid_params", {
177
- params: { field: "scope" },
178
- detail: { field: "scope", reason: "not_allowed", value: scope, allowed: [...RELOAD_SCOPES] },
179
- });
180
- }
181
- const reloaded = reloadedOf(scope);
171
+ async reload() {
172
+ const reloaded = reloadedOf();
182
173
  const config = await this.readConfig();
183
174
  const outcome = this.applyPort ? await this.applyPort.apply(reloadChangeOf(reloaded)) : {};
184
175
  return {
@@ -635,15 +626,15 @@ function referencesToEndpoint(config, endpointId) {
635
626
  return { referenced: items.length > 0, items };
636
627
  }
637
628
  /** 这次要求重载的范围里,哪几类东西要重新装配(不给范围 = 全部) */
638
- function reloadedOf(scope) {
639
- const all = scope === undefined;
640
- return {
641
- config: all || scope === "config",
642
- tools: all || scope === "tools",
643
- skills: all || scope === "skills",
644
- agents: all || scope === "agents",
645
- mcp: all || scope === "mcp",
646
- };
629
+ /**
630
+ * 重载报告:五类全都是 `true`。
631
+ *
632
+ * 从前这里能按 `scope` 只报一类,但那一档**没有任何入口**(客户端只会全量 `/reload`,
633
+ * 契约里也没人传 `scope`),五个取值 + 校验 + 映射都是空转。参数已删:重载就是「全部
634
+ * 重读一遍」。真要「只重载 MCP」时再加,那时它会有一条真实的命令入口。
635
+ */
636
+ function reloadedOf() {
637
+ return { config: true, tools: true, skills: true, agents: true, mcp: true };
647
638
  }
648
639
  /**
649
640
  * 重载要交给生效一跳的改动描述。
@@ -12,7 +12,7 @@
12
12
  * 默认项指向被删的那个模型时要改指或清空,不留悬空引用。
13
13
  */
14
14
  import type { AgentRepository } from "@ai-zen/agents-sdk";
15
- import type { AppConfig, ConfigManager, Endpoint, ImageModel, Model, ReasoningPreset, ReasoningPresets } from "@ai-zen/agents-sdk";
15
+ import type { AppConfig, ConfigManager, Endpoint, Model, ReasoningPreset, ReasoningPresets } from "@ai-zen/agents-sdk";
16
16
  import type { ModelCreateParams, ModelCreateResult, ModelDeleteImageParams, ModelDeleteImageResult, ModelDeleteParams, ModelDeleteResult, ModelListImagesResult, ModelListParams, ModelListResult, ModelRestoreFactoryParams, ModelRestoreFactoryResult, ModelSaveImageParams, ModelSaveImageResult, ModelUpdateParams, ModelUpdateResult, ModelView, ProblemFact } from "../wire/index.js";
17
17
  /** 模型服务的依赖;由单根组装后注入 */
18
18
  export interface ModelServiceOptions {
@@ -25,8 +25,6 @@ export interface ModelServiceOptions {
25
25
  export declare function findEndpoint(config: AppConfig, endpointId: string): Endpoint | undefined;
26
26
  /** 按 id 找模型 */
27
27
  export declare function findModel(config: AppConfig, modelId: string): Model | undefined;
28
- /** 按 id 找图片模型 */
29
- export declare function findImageModel(config: AppConfig, imageModelId: string): ImageModel | undefined;
30
28
  /**
31
29
  * 这个模型现在能不能用;能用回 `null`,不能用回一条带原因的事实(F-B5:藏着不如说清楚)。
32
30
  *
@@ -68,10 +68,6 @@ export function findEndpoint(config, endpointId) {
68
68
  export function findModel(config, modelId) {
69
69
  return config.models.find((model) => model.id === modelId);
70
70
  }
71
- /** 按 id 找图片模型 */
72
- export function findImageModel(config, imageModelId) {
73
- return (config.imageModels ?? []).find((model) => model.id === imageModelId);
74
- }
75
71
  /**
76
72
  * 这个模型现在能不能用;能用回 `null`,不能用回一条带原因的事实(F-B5:藏着不如说清楚)。
77
73
  *
@@ -158,13 +158,6 @@ export declare class QuestionService {
158
158
  * 第 3、4 两步都在写状态之前返回,所以「答不下去」不会把问题弄成一个半答的中间态。
159
159
  */
160
160
  answer(params: QuestionAnswerParams, context?: QuestionAnswerContext): Promise<QuestionAnswerResult>;
161
- /**
162
- * 显式取消一个问题(生命周期里的 `cancelled`)。
163
- *
164
- * 只有调用方明确要关掉时才用(例如对话被删、工作流换了方向)。没有任何自动取消的路径 ——
165
- * 越线拒绝之后问题要继续挂着(D23),所以「答不下去」与「关掉它」是两件事。
166
- */
167
- cancel(questionId: string, language?: Language): Promise<QuestionView>;
168
161
  /**
169
162
  * 答完之后接着往下走:交接(D22)。
170
163
  *
@@ -328,21 +328,6 @@ export class QuestionService {
328
328
  const effects = await this.applyEffects({ kind, value, handoffMode, conversationId, data: payload.data }, language);
329
329
  return { question: view, effects };
330
330
  }
331
- /**
332
- * 显式取消一个问题(生命周期里的 `cancelled`)。
333
- *
334
- * 只有调用方明确要关掉时才用(例如对话被删、工作流换了方向)。没有任何自动取消的路径 ——
335
- * 越线拒绝之后问题要继续挂着(D23),所以「答不下去」与「关掉它」是两件事。
336
- */
337
- async cancel(questionId, language = DEFAULT_LANGUAGE) {
338
- const question = await this.requireQuestion(questionId);
339
- const cancelledAt = this.now();
340
- await this.questions.update(question.id, { state: "cancelled", updatedAt: cancelledAt });
341
- const row = await this.questions.get(question.id);
342
- const view = toView(row ?? question, language);
343
- this.emit?.("question", { question: view, at: iso(cancelledAt) });
344
- return view;
345
- }
346
331
  /**
347
332
  * 答完之后接着往下走:交接(D22)。
348
333
  *
@@ -40,8 +40,6 @@ export declare class ConversationRepository {
40
40
  setModel(id: string, modelId: string, updatedAt: number): Promise<number>;
41
41
  /** 写这段会话的思考档位;`null` 表示回到「跟随助手定义」 */
42
42
  setThinkingLevel(id: string, thinkingLevel: string | null, updatedAt: number): Promise<number>;
43
- /** 只推进修改时间(新增消息等结构变化后调用) */
44
- touch(id: string, updatedAt: number): Promise<number>;
45
43
  /** 硬删对话(PRD D17),消息与素材行随之级联删除 */
46
44
  delete(id: string): Promise<number>;
47
45
  /**
@@ -51,5 +49,4 @@ export declare class ConversationRepository {
51
49
  * 也省掉维护第二张 FTS 表。
52
50
  */
53
51
  searchByName(keyword: string, workspaceId: string | undefined, limit: number): Promise<Conversation[]>;
54
- countByWorkspace(workspaceId: string): Promise<number>;
55
52
  }
@@ -87,14 +87,6 @@ export class ConversationRepository {
87
87
  const result = await this.db.run("UPDATE conversations SET thinkingLevel = ?, updatedAt = ? WHERE id = ?", [thinkingLevel, updatedAt, id]);
88
88
  return result.changes;
89
89
  }
90
- /** 只推进修改时间(新增消息等结构变化后调用) */
91
- async touch(id, updatedAt) {
92
- const result = await this.db.run("UPDATE conversations SET updatedAt = ? WHERE id = ?", [
93
- updatedAt,
94
- id,
95
- ]);
96
- return result.changes;
97
- }
98
90
  /** 硬删对话(PRD D17),消息与素材行随之级联删除 */
99
91
  async delete(id) {
100
92
  const result = await this.db.run("DELETE FROM conversations WHERE id = ?", [id]);
@@ -121,8 +113,4 @@ export class ConversationRepository {
121
113
  LIMIT ?`, [workspaceId, pattern, limit]);
122
114
  return rows.map(toConversation);
123
115
  }
124
- async countByWorkspace(workspaceId) {
125
- const row = await this.db.get("SELECT count(*) AS n FROM conversations WHERE workspaceId = ?", [workspaceId]);
126
- return row?.n ?? 0;
127
- }
128
116
  }
@@ -30,5 +30,4 @@ export declare class QuestionRepository {
30
30
  * (例如只改 state 时不会把已有的 answer 抹掉)。
31
31
  */
32
32
  update(id: string, patch: QuestionPatch): Promise<number>;
33
- delete(id: string): Promise<number>;
34
33
  }
@@ -89,8 +89,4 @@ export class QuestionRepository {
89
89
  const result = await this.db.run(`UPDATE questions SET ${assignments.join(", ")} WHERE id = ?`, params);
90
90
  return result.changes;
91
91
  }
92
- async delete(id) {
93
- const result = await this.db.run("DELETE FROM questions WHERE id = ?", [id]);
94
- return result.changes;
95
- }
96
92
  }
@@ -12,8 +12,6 @@
12
12
  * 收敛成 core 的枚举发生在服务层。
13
13
  */
14
14
  import type { AgentNS } from "@ai-zen/agents-core";
15
- /** 消息角色,取值与 core 的 `AgentNS.Role` 对齐 */
16
- export type MessageRole = "system" | "user" | "assistant" | "tool" | "function" | "unknown";
17
15
  /** 消息状态,取值与 core 的 `AgentNS.MessageStatus` 对齐 */
18
16
  export type MessageStatus = "pending" | "writing" | "completed" | "error" | "aborted" | "unknown";
19
17
  export interface WorkspaceRow {
@@ -28,27 +28,6 @@ export interface ClientInfo {
28
28
  /** 运行平台(可选,仅供展示) */
29
29
  platform?: string;
30
30
  }
31
- /**
32
- * 能力清单里的一项(PRD F-E5 帮助由能力清单渲染、F-E6 阻塞是能力属性、F-F9 二次确认)。
33
- *
34
- * `id` 用 PRD 的能力编号(如 `F-C8`),因为那份清单是「要为用户做到什么」的唯一真相;
35
- * 客户端据此接线,不必再维护第三份清单。
36
- */
37
- export interface CapabilityView {
38
- /** 稳定能力编号(PRD §4 的编号,如 `F-C8`) */
39
- id: string;
40
- domain: MethodDomain;
41
- title: LocalizedText;
42
- description: LocalizedText;
43
- /** 对应的方法名;纯事实类能力(如生成六态)没有方法,为空 */
44
- method: MethodName | null;
45
- /** 执行期间会阻塞对话(PRD F-E6:界面要能显示「正在执行什么」) */
46
- blocking: boolean;
47
- /** 有不可撤销的后果(PRD F-F9:需要二次确认) */
48
- destructive: boolean;
49
- }
50
- /** 方法的域(方法名的第一段) */
51
- export type MethodDomain = "host" | "workspace" | "conversation" | "message" | "question" | "notice" | "config" | "agent" | "model" | "asset" | "completion" | "handoff" | "search";
52
31
  /**
53
32
  * 一次删除的代价(PRD D11「删前明说代价」/ D17「先警告」/ F-F9「二次确认」)。
54
33
  *
@@ -87,7 +66,8 @@ export interface HostHelloParams {
87
66
  *
88
67
  * 除了握手成功本身,还把「这条连接以后说哪种语言」「宿主是什么版本」「有哪些能力」
89
68
  * 一次给全:客户端连上就能把界面语言定下来(D8)。能力只给 id 列表(R57):握手这一帧
90
- * 要小,完整清单(标题、说明、阻塞与不可撤销)走 `host.capabilities`,那一份按连接语言渲染。
69
+ * 要小,完整清单(编号、域、方法名、阻塞与不可撤销)走 `host.capabilities` —— 清单里没有
70
+ * 文案,与语言无关。
91
71
  */
92
72
  export interface HostHelloResult {
93
73
  /** 这条连接协商出的语言;后续这条连接上的文案都按它渲染 */
@@ -96,12 +76,6 @@ export interface HostHelloResult {
96
76
  protocolVersion: string;
97
77
  /** 宿主进程启动时间 */
98
78
  startedAt: string;
99
- /**
100
- * 能力 id 列表(PRD F-E5 / R57)
101
- *
102
- * 每一串就是 `host.capabilities` 里那一项 `CapabilityView.id`,顺序与那份清单一致。
103
- */
104
- capabilities: string[];
105
79
  /** 附件上限等客户端要先知道的事实(PRD D5) */
106
80
  limits: TransferLimits;
107
81
  }
@@ -149,21 +123,6 @@ export interface HostShutdownParams {
149
123
  export interface HostShutdownResult {
150
124
  accepted: boolean;
151
125
  }
152
- /** `capabilities` 出参(PRD F-E5:帮助与指令菜单都从这一份渲染) */
153
- export interface HostCapabilitiesResult {
154
- capabilities: CapabilityView[];
155
- }
156
- /**
157
- * `host.reload` 能重载的范围(PRD F-E1 命令清单里的「重载」)。
158
- *
159
- * 每一档对应「哪一类能力要重新装配」:改的是磁盘上的东西(配置文件 / 助手定义 / 技能目录 /
160
- * MCP 文件),所以重载不写盘,只让宿主重新读一遍。不给 `scope` 表示全部。
161
- */
162
- export type HostReloadScope = "config" | "agents" | "tools" | "skills" | "mcp";
163
- /** `host.reload` 入参:只重载某一类能力,或全部(不给) */
164
- export interface HostReloadParams {
165
- scope?: HostReloadScope;
166
- }
167
126
  /**
168
127
  * `host.reload` 出参:与 `config.patch` 同一份形状(`config` + `applied`)。
169
128
  *
@@ -1570,11 +1529,6 @@ export interface MethodMap {
1570
1529
  params: HostShutdownParams;
1571
1530
  result: HostShutdownResult;
1572
1531
  };
1573
- /** F-E5 / F-E6 / F-F9:帮助由能力清单渲染;阻塞与不可撤销是能力属性。 */
1574
- "host.capabilities": {
1575
- params: NoParams;
1576
- result: HostCapabilitiesResult;
1577
- };
1578
1532
  /**
1579
1533
  * F-E1:命令清单里的「重载」在宿主这一侧的动作。
1580
1534
  *
@@ -1582,7 +1536,7 @@ export interface MethodMap {
1582
1536
  * 手改了磁盘上的助手定义 / 技能目录 / MCP 文件之后不必重启。
1583
1537
  */
1584
1538
  "host.reload": {
1585
- params: HostReloadParams;
1539
+ params: NoParams;
1586
1540
  result: HostReloadResult;
1587
1541
  };
1588
1542
  /** D8 / F-E4:`/lang` 是连接级动作,语言挂在连接上、断开即忘。 */
@@ -1889,8 +1843,6 @@ export type MethodResult<M extends MethodName> = MethodMap[M]["result"];
1889
1843
  * 测试里做 `Exclude<MethodName, (typeof METHOD_NAMES)[number]>` 时,漏掉的名字会留在
1890
1844
  * 那个差集里而不是被抹成 `never`。
1891
1845
  */
1892
- export declare const METHOD_NAMES: readonly ["host.hello", "host.version", "host.upgrade", "host.shutdown", "host.capabilities", "host.reload", "host.setLanguage", "workspace.list", "workspace.create", "workspace.get", "workspace.rename", "workspace.remove", "conversation.list", "conversation.create", "conversation.get", "conversation.state", "conversation.rename", "conversation.pin", "conversation.delete", "conversation.send", "conversation.abort", "conversation.revert", "conversation.setModel", "conversation.setThinking", "conversation.transient", "message.list", "question.list", "question.answer", "notice.list", "notice.dismiss", "notice.clear", "config.get", "config.patch", "config.setDefaults", "config.getDiscovery", "config.saveMcp", "config.deleteMcp", "config.saveEndpoint", "config.deleteEndpoint", "agent.list", "agent.get", "agent.create", "agent.update", "agent.delete", "agent.setModel", "agent.setThinking", "agent.restoreFactory", "model.list", "model.listImages", "model.create", "model.update", "model.delete", "model.restoreFactory", "model.saveImage", "model.deleteImage", "asset.begin", "asset.end", "asset.get", "completion.files", "handoff.start", "handoff.listDocuments", "search.conversations", "search.messages"];
1846
+ export declare const METHOD_NAMES: readonly ["host.hello", "host.version", "host.upgrade", "host.shutdown", "host.reload", "host.setLanguage", "workspace.list", "workspace.create", "workspace.get", "workspace.rename", "workspace.remove", "conversation.list", "conversation.create", "conversation.get", "conversation.state", "conversation.rename", "conversation.pin", "conversation.delete", "conversation.send", "conversation.abort", "conversation.revert", "conversation.setModel", "conversation.setThinking", "conversation.transient", "message.list", "question.list", "question.answer", "notice.list", "notice.dismiss", "notice.clear", "config.get", "config.patch", "config.setDefaults", "config.getDiscovery", "config.saveMcp", "config.deleteMcp", "config.saveEndpoint", "config.deleteEndpoint", "agent.list", "agent.get", "agent.create", "agent.update", "agent.delete", "agent.setModel", "agent.setThinking", "agent.restoreFactory", "model.list", "model.listImages", "model.create", "model.update", "model.delete", "model.restoreFactory", "model.saveImage", "model.deleteImage", "asset.begin", "asset.end", "asset.get", "completion.files", "handoff.start", "handoff.listDocuments", "search.conversations", "search.messages"];
1893
1847
  /** 运行时判断一个字符串是不是已知方法名 */
1894
1848
  export declare function isMethodName(value: unknown): value is MethodName;
1895
- /** 方法名属于哪个域(`conversation.send` → `conversation`) */
1896
- export declare function methodDomain(method: MethodName): MethodDomain;
@@ -29,7 +29,6 @@ export const METHOD_NAMES = [
29
29
  "host.version",
30
30
  "host.upgrade",
31
31
  "host.shutdown",
32
- "host.capabilities",
33
32
  "host.reload",
34
33
  "host.setLanguage",
35
34
  "workspace.list",
@@ -93,7 +92,3 @@ export const METHOD_NAMES = [
93
92
  export function isMethodName(value) {
94
93
  return typeof value === "string" && METHOD_NAMES.includes(value);
95
94
  }
96
- /** 方法名属于哪个域(`conversation.send` → `conversation`) */
97
- export function methodDomain(method) {
98
- return method.slice(0, method.indexOf("."));
99
- }