@ai-zen/agents-host 0.0.0-stage → 0.1.0-alpha.1

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 (146) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/LICENSE +21 -0
  3. package/README.md +759 -2
  4. package/dist/app.d.ts +384 -0
  5. package/dist/app.js +1148 -0
  6. package/dist/cli.d.ts +22 -0
  7. package/dist/cli.js +354 -0
  8. package/dist/config.d.ts +97 -0
  9. package/dist/config.js +171 -0
  10. package/dist/handlers/agentHandlers.d.ts +18 -0
  11. package/dist/handlers/agentHandlers.js +20 -0
  12. package/dist/handlers/assetHandlers.d.ts +29 -0
  13. package/dist/handlers/assetHandlers.js +35 -0
  14. package/dist/handlers/capabilities.d.ts +26 -0
  15. package/dist/handlers/capabilities.js +138 -0
  16. package/dist/handlers/completionHandlers.d.ts +18 -0
  17. package/dist/handlers/completionHandlers.js +13 -0
  18. package/dist/handlers/configHandlers.d.ts +31 -0
  19. package/dist/handlers/configHandlers.js +59 -0
  20. package/dist/handlers/conversationHandlers.d.ts +118 -0
  21. package/dist/handlers/conversationHandlers.js +314 -0
  22. package/dist/handlers/handoffHandlers.d.ts +17 -0
  23. package/dist/handlers/handoffHandlers.js +14 -0
  24. package/dist/handlers/hostHandlers.d.ts +39 -0
  25. package/dist/handlers/hostHandlers.js +56 -0
  26. package/dist/handlers/index.d.ts +128 -0
  27. package/dist/handlers/index.js +92 -0
  28. package/dist/handlers/messageHandlers.d.ts +11 -0
  29. package/dist/handlers/messageHandlers.js +10 -0
  30. package/dist/handlers/modelHandlers.d.ts +17 -0
  31. package/dist/handlers/modelHandlers.js +19 -0
  32. package/dist/handlers/noticeHandlers.d.ts +24 -0
  33. package/dist/handlers/noticeHandlers.js +24 -0
  34. package/dist/handlers/questionHandlers.d.ts +16 -0
  35. package/dist/handlers/questionHandlers.js +16 -0
  36. package/dist/handlers/searchHandlers.d.ts +12 -0
  37. package/dist/handlers/searchHandlers.js +12 -0
  38. package/dist/handlers/workspaceHandlers.d.ts +29 -0
  39. package/dist/handlers/workspaceHandlers.js +47 -0
  40. package/dist/i18n/en.d.ts +243 -0
  41. package/dist/i18n/en.js +270 -0
  42. package/dist/i18n/index.d.ts +43 -0
  43. package/dist/i18n/index.js +72 -0
  44. package/dist/i18n/zh.d.ts +240 -0
  45. package/dist/i18n/zh.js +257 -0
  46. package/dist/index.d.ts +17 -0
  47. package/dist/index.js +15 -0
  48. package/dist/net/UploadReceiver.d.ts +186 -0
  49. package/dist/net/UploadReceiver.js +494 -0
  50. package/dist/net/WsHub.d.ts +231 -0
  51. package/dist/net/WsHub.js +689 -0
  52. package/dist/net/auth.d.ts +73 -0
  53. package/dist/net/auth.js +74 -0
  54. package/dist/net/discovery.d.ts +72 -0
  55. package/dist/net/discovery.js +171 -0
  56. package/dist/net/index.d.ts +14 -0
  57. package/dist/net/index.js +10 -0
  58. package/dist/runtime/ChatRunner.d.ts +374 -0
  59. package/dist/runtime/ChatRunner.js +1204 -0
  60. package/dist/runtime/ConversationDrafts.d.ts +43 -0
  61. package/dist/runtime/ConversationDrafts.js +47 -0
  62. package/dist/runtime/RunRegistry.d.ts +79 -0
  63. package/dist/runtime/RunRegistry.js +108 -0
  64. package/dist/runtime/ScopeRegistry.d.ts +153 -0
  65. package/dist/runtime/ScopeRegistry.js +259 -0
  66. package/dist/runtime/TransientRunner.d.ts +90 -0
  67. package/dist/runtime/TransientRunner.js +179 -0
  68. package/dist/runtime/index.d.ts +14 -0
  69. package/dist/runtime/index.js +10 -0
  70. package/dist/services/AgentService.d.ts +150 -0
  71. package/dist/services/AgentService.js +718 -0
  72. package/dist/services/AssetService.d.ts +338 -0
  73. package/dist/services/AssetService.js +739 -0
  74. package/dist/services/AutoNaming.d.ts +92 -0
  75. package/dist/services/AutoNaming.js +235 -0
  76. package/dist/services/CompletionService.d.ts +122 -0
  77. package/dist/services/CompletionService.js +442 -0
  78. package/dist/services/ConfigService.d.ts +171 -0
  79. package/dist/services/ConfigService.js +695 -0
  80. package/dist/services/ConversationService.d.ts +274 -0
  81. package/dist/services/ConversationService.js +902 -0
  82. package/dist/services/CredentialService.d.ts +33 -0
  83. package/dist/services/CredentialService.js +86 -0
  84. package/dist/services/DiscoveryService.d.ts +182 -0
  85. package/dist/services/DiscoveryService.js +998 -0
  86. package/dist/services/HandoffService.d.ts +189 -0
  87. package/dist/services/HandoffService.js +414 -0
  88. package/dist/services/Logger.d.ts +130 -0
  89. package/dist/services/Logger.js +256 -0
  90. package/dist/services/MessageService.d.ts +88 -0
  91. package/dist/services/MessageService.js +280 -0
  92. package/dist/services/ModelService.d.ts +89 -0
  93. package/dist/services/ModelService.js +489 -0
  94. package/dist/services/NoticeService.d.ts +93 -0
  95. package/dist/services/NoticeService.js +217 -0
  96. package/dist/services/QuestionService.d.ts +184 -0
  97. package/dist/services/QuestionService.js +457 -0
  98. package/dist/services/SearchService.d.ts +54 -0
  99. package/dist/services/SearchService.js +117 -0
  100. package/dist/services/WorkspaceService.d.ts +96 -0
  101. package/dist/services/WorkspaceService.js +213 -0
  102. package/dist/services/imageSize.d.ts +41 -0
  103. package/dist/services/imageSize.js +146 -0
  104. package/dist/services/index.d.ts +20 -0
  105. package/dist/services/index.js +15 -0
  106. package/dist/services/secretMask.d.ts +24 -0
  107. package/dist/services/secretMask.js +34 -0
  108. package/dist/storage/AssetRepository.d.ts +87 -0
  109. package/dist/storage/AssetRepository.js +180 -0
  110. package/dist/storage/ConversationRepository.d.ts +55 -0
  111. package/dist/storage/ConversationRepository.js +128 -0
  112. package/dist/storage/CredentialRepository.d.ts +28 -0
  113. package/dist/storage/CredentialRepository.js +47 -0
  114. package/dist/storage/Database.d.ts +95 -0
  115. package/dist/storage/Database.js +180 -0
  116. package/dist/storage/MessageRepository.d.ts +104 -0
  117. package/dist/storage/MessageRepository.js +323 -0
  118. package/dist/storage/MetaRepository.d.ts +21 -0
  119. package/dist/storage/MetaRepository.js +33 -0
  120. package/dist/storage/NoticeRepository.d.ts +31 -0
  121. package/dist/storage/NoticeRepository.js +89 -0
  122. package/dist/storage/QuestionRepository.d.ts +34 -0
  123. package/dist/storage/QuestionRepository.js +96 -0
  124. package/dist/storage/WorkspaceRepository.d.ts +25 -0
  125. package/dist/storage/WorkspaceRepository.js +44 -0
  126. package/dist/storage/dbWorker.d.ts +10 -0
  127. package/dist/storage/dbWorker.js +132 -0
  128. package/dist/storage/index.d.ts +20 -0
  129. package/dist/storage/index.js +16 -0
  130. package/dist/storage/migrations.d.ts +26 -0
  131. package/dist/storage/migrations.js +207 -0
  132. package/dist/storage/types.d.ts +298 -0
  133. package/dist/storage/types.js +14 -0
  134. package/dist/wire/errors.d.ts +105 -0
  135. package/dist/wire/errors.js +143 -0
  136. package/dist/wire/events.d.ts +102 -0
  137. package/dist/wire/events.js +13 -0
  138. package/dist/wire/frames.d.ts +106 -0
  139. package/dist/wire/frames.js +156 -0
  140. package/dist/wire/index.d.ts +31 -0
  141. package/dist/wire/index.js +31 -0
  142. package/dist/wire/methods.d.ts +1896 -0
  143. package/dist/wire/methods.js +99 -0
  144. package/dist/wire/states.d.ts +487 -0
  145. package/dist/wire/states.js +61 -0
  146. package/package.json +63 -3
@@ -0,0 +1,274 @@
1
+ /**
2
+ * 对话服务:一段对话的诞生、改名、置顶、删除、撤回,以及两个「会话级调整」(换模型、换思考档位)。
3
+ *
4
+ * 对应能力编号:F-C1(稳定 id)、F-C3(可改名字)、F-C5(置顶 + 创建时间倒序)、
5
+ * F-C7(开新会话)、F-C8 / D24(撤回硬删 + 回填输入框)、F-C10 / D17(硬删 + 警告)、
6
+ * F-B4 / D20(会话级换模型、历史有图时拒绝降级)、F-B6 / F-B7(思考档位)、
7
+ * L5(重连按 id 拉)、L6(id 宿主分配)、R18(身份创建时必须有助手与模型)、
8
+ * R22(消息原样用 core 的类型)。
9
+ *
10
+ * 两条贯穿这个文件的边界:
11
+ * 1. **项目与助手创建即定死**:`workspaceId` / `agentId` 由 `create` 解析后落库,此后没有
12
+ * 任何方法改它们。模型与思考档位不在这条线上:它们是这段会话自己的,存在会话行上、可以改。
13
+ * 2. **服务层不缓存 agent、不驻留对话状态**:`running` 与「删掉之后的现场清理」都从注入的
14
+ * {@link ConversationRuntimePort} 现取现放;模型与档位在库里,不在内存里存第二份。
15
+ */
16
+ import type { ConfigManager } from "@ai-zen/agents-sdk";
17
+ import type { ConversationDraftStore } from "../runtime/ConversationDrafts.js";
18
+ import type { ChatEventEmitter } from "../runtime/ChatRunner.js";
19
+ import type { Language } from "../i18n/index.js";
20
+ import type { AssetRepository } from "../storage/AssetRepository.js";
21
+ import type { ConversationRepository } from "../storage/ConversationRepository.js";
22
+ import type { MessageRepository } from "../storage/MessageRepository.js";
23
+ import type { QuestionRepository } from "../storage/QuestionRepository.js";
24
+ import type { WorkspaceRepository } from "../storage/WorkspaceRepository.js";
25
+ import type { Conversation } from "../storage/types.js";
26
+ import type { ConversationCreateParams, ConversationCreateResult, ConversationDeleteParams, ConversationDeleteResult, ConversationGetParams, ConversationGetResult, ConversationListParams, ConversationListResult, ConversationPinParams, ConversationPinResult, ConversationRenameParams, ConversationRenameResult, ConversationRevertParams, ConversationRevertResult, ConversationSetModelParams, ConversationSetModelResult, ConversationSetThinkingParams, ConversationSetThinkingResult, ConversationSummary } from "../wire/index.js";
27
+ /**
28
+ * 运行时注入给对话服务的窄接口。
29
+ *
30
+ * 只剩两件运行时才知道的事:
31
+ * - 这段对话现在有没有在跑一轮(PRD F-I3 / D14,真相在 `RunRegistry` 一处);
32
+ * - 对话被删掉之后,把这一轮的现场丢掉(中止在跑的轮次)。
33
+ *
34
+ * 模型与思考档位不在这里:它们存在会话行上(`modelId` / `thinkingLevel`),服务层自己读写库。
35
+ *
36
+ * 服务层只按它读写,不 import `runtime/` 里的任何实现、也不自己存一份 —— 两份状态迟早
37
+ * 有一份先漂(D28:agent 用完即弃、对话不驻留)。
38
+ */
39
+ export interface ConversationRuntimePort {
40
+ /** 这段对话现在是否在跑一轮 */
41
+ isRunning(conversationId: string): boolean;
42
+ /** 对话(或它的项目)被删掉之后,中止在跑的轮次并清掉现场 */
43
+ forget(conversationId: string): void | Promise<void>;
44
+ }
45
+ /** `conversation.delete` 的结果:wire 字段 + 交给 asset 层按引用清的文件清单 */
46
+ export interface ConversationRemovalReport extends ConversationDeleteResult {
47
+ /**
48
+ * 这段对话引用过的素材 id。
49
+ *
50
+ * 行删了(关系行随外键级联消失)之后要交给素材层再问一次「还剩几张引用」:有人还在用就留着
51
+ * 字节,归零才删。这里只交 id,不交路径 —— 还在用的那份不该被当成可删的。
52
+ */
53
+ assetIds: string[];
54
+ }
55
+ /**
56
+ * 素材归零清扫口(`AssetService.sweepUnreferenced` 结构上满足)。
57
+ *
58
+ * 服务层不碰 `assets/` 下的文件:它只说「这几个素材可能没人用了」,删行删文件归素材层。
59
+ */
60
+ export type AssetSweeper = (assetIds: string[]) => Promise<string[]>;
61
+ /** 对话服务的依赖;由单根组装后注入 */
62
+ export interface ConversationServiceDeps {
63
+ conversations: ConversationRepository;
64
+ messages: MessageRepository;
65
+ workspaces: WorkspaceRepository;
66
+ assets: AssetRepository;
67
+ /** 引用归零的素材交给它删行删文件;不注入时字节会留在盘上(引用行已经没了) */
68
+ sweepAssets?: AssetSweeper;
69
+ questions: QuestionRepository;
70
+ /** 配置唯一入口(SDK):助手定义在 `<basePath>/agents/`,模型与默认项在 `config.json` 里 */
71
+ configManager: ConfigManager;
72
+ runtime: ConversationRuntimePort;
73
+ /** 草稿(R56):`create` 只记在这里,首次 `send` 才落库;不注入时用一份自己的 */
74
+ drafts?: ConversationDraftStore;
75
+ /** 推 `conversation.changed`(多端在线同步,L5 / D22);不注入时不推 */
76
+ emit?: ChatEventEmitter;
77
+ /** 时钟,测试注入用;缺省 `Date.now` */
78
+ now?: () => number;
79
+ }
80
+ export declare class ConversationService {
81
+ private readonly conversations;
82
+ private readonly messages;
83
+ private readonly workspaces;
84
+ private readonly assets;
85
+ private readonly sweepAssets?;
86
+ private readonly questions;
87
+ private readonly configManager;
88
+ private readonly runtime;
89
+ private readonly drafts;
90
+ private readonly emit?;
91
+ private readonly now;
92
+ /** 正在落库的草稿:同一个 id 的并发调用共用同一次写入(key 是 conversationId) */
93
+ private readonly persisting;
94
+ /** 助手定义是文件(PRD F-G3:一实体一文件),按配置根下的 `agents/` 目录读 */
95
+ private readonly agents;
96
+ constructor(deps: ConversationServiceDeps);
97
+ /**
98
+ * 列表(PRD F-C5 / D13)。
99
+ *
100
+ * 顺序由仓储定死:`pinned DESC, createdAt DESC` —— 活动、打开、改名都不影响它,所以这里
101
+ * 除了按 Workspace / 置顶筛、按 `limit` / `offset` 切页之外,不再重排。
102
+ *
103
+ * 列表只给已经落库的对话:草稿(还没发过消息,R56)不在侧栏里出现 —— 建了不发就断线
104
+ * 的那段对话应该像没建过一样。
105
+ */
106
+ list(params?: ConversationListParams): Promise<ConversationListResult>;
107
+ /**
108
+ * 开一段新对话(PRD F-C7 / L7 / R18 / R56)。
109
+ *
110
+ * 项目与助手在这里定死:项目就是入参的那个已登记项目(项目只走显式添加,PRD D10),助手从
111
+ * 磁盘上的定义文件解析。模型的值也在这里算出来(SDK 的三级解析 `会话级 > 助手定义 > 配置里的
112
+ * 兜底`,唯一实现在 `resolveModel`),但它落的是**会话行**:之后可以由 `setModel` 改。解析不
113
+ * 出来就报错,不写半成品行 —— 一条没有助手或没有模型的对话没有可用的身份。
114
+ *
115
+ * **这一行现在不写库**:只把 id 与身份留在草稿里(R56 / F-C2「没有用户消息就不写」)。
116
+ * 首次 `conversation.send` 时由 {@link ensurePersisted} 用同一个 id 落库。
117
+ */
118
+ create(params: ConversationCreateParams): Promise<ConversationCreateResult>;
119
+ /**
120
+ * 把草稿落成 `conversations` 的一行(R56:首次 `send` 时用同一个 id 写)。
121
+ *
122
+ * 已经在库里就直接返回那一行(重复调用是幂等的);草稿不在、库里也没这一行就是
123
+ * `not_found`。先把草稿摘掉再写库:两次并发的调用里后到的那一次就抢不到同一份草稿,
124
+ * 不会两次插同一行;写失败时把草稿放回去,下一次还能再试。
125
+ *
126
+ * 但「抢不到草稿」不等于「这段对话不存在」:同一个 id 的并发调用(例如一次拖进四张图,
127
+ * 每个上传都在 `asset.begin` 里调一次)在这里排队共用同一次写入,免得后到的那次误报
128
+ * `not_found`、也免得那条隐藏的 cwd 消息被写两遍。
129
+ *
130
+ * 落行那一刻同时写上这段对话的第一条消息:一条 `hidden` 的 `user` 消息,告诉模型这段对话
131
+ * 对应的 cwd(PRD F-D9)。它最先写,所以 `seq` 在真实用户消息之前;之后每轮都不再重写。
132
+ * cwd 从这段对话的 Workspace 取(不是进程工作目录);`workspaceId` 建会话时就定死了,
133
+ * 这里只读不改。
134
+ *
135
+ * `language` 是这条消息正文的渲染语言(D8:调用方传发起这条连接的语言;不传时用缺省语言)。
136
+ */
137
+ ensurePersisted(conversationId: string, language?: Language): Promise<Conversation>;
138
+ /** 草稿 → 库里那一行(含那条隐藏的 cwd 消息);并发去重由 {@link ensurePersisted} 负责 */
139
+ private persistDraft;
140
+ /**
141
+ * 写会话开头那条 `hidden` 的 cwd 消息(PRD F-D9)。
142
+ *
143
+ * 它是一条普通的 `user` 消息,只是 `hidden` 为真:模型在上下文里能看到它,界面上不展示
144
+ * 它(core 的 `Message.hidden`)。内容用的是 i18n 里那两条既有键的拼装(与临时对话共用
145
+ * `injectedContextOf`)。
146
+ *
147
+ * cwd 来自这段对话所属的 Workspace(PRD D9:一段对话绑一个项目,cwd 创建即定死),
148
+ * 不读进程工作目录。
149
+ */
150
+ private writeCwdMessage;
151
+ /** 按 id 打开一段对话(PRD F-A6:宿主只提供「按 id 打开」) */
152
+ get(params: ConversationGetParams): Promise<ConversationGetResult>;
153
+ /** 改名(PRD D1 / F-C3):只换名字,id、身份与排序都不动;名字从此归用户(R35) */
154
+ rename(params: ConversationRenameParams): Promise<ConversationRenameResult>;
155
+ /** 手动置顶(PRD F-C5 / D13):只动 `pinned`,不碰创建时间 */
156
+ pin(params: ConversationPinParams): Promise<ConversationPinResult>;
157
+ /**
158
+ * 硬删一段对话(PRD F-C10 / D17 / F-F9 / R7)。
159
+ *
160
+ * `dryRun` 先算账(消息数、素材数),客户端据此警告用户。真删是 delete 语句 + 外键级联:
161
+ * 消息行、问题行、素材的引用关系(`conversation_assets`)随对话一起消失。素材行与 `assets/`
162
+ * 下的文件不一定:那张图可能还有别的对话在用,所以把「这段对话引用过哪几份素材」交给
163
+ * asset 层在删完之后再问一次「还剩几张引用」,归零才删(PRD D17「图片按引用清理」)。
164
+ *
165
+ * 还没落库的草稿也能删:没有行、没有消息、没有素材,代价是零。
166
+ */
167
+ delete(params: ConversationDeleteParams): Promise<ConversationRemovalReport>;
168
+ /**
169
+ * 撤回(PRD F-C8 / D24 / R10)。
170
+ *
171
+ * 撤回到某条**用户消息之前**:那条消息及其后全部硬删,被撤回的内容按 core 的内容形状
172
+ * 回给客户端填回输入框(只有纯文本段 + 当时带的素材 id,R62 / F-H3「带图消息连图一起
173
+ * 恢复」)。不留删除痕迹(R10);正在跑一轮时拒绝,不然删的正是流式还在写的那几条。
174
+ */
175
+ revert(params: ConversationRevertParams): Promise<ConversationRevertResult>;
176
+ /**
177
+ * 换这段会话的模型(PRD F-B4 / F-B8 / D20)。
178
+ *
179
+ * 写的是**会话行**上的 `modelId`:这一段对话以后都用新模型,重开、重启都还是它。换模型
180
+ * 同时把这段会话的思考档位清成「跟随助手定义」—— 档位是模型的档位,同一个名字在不同
181
+ * 模型上对应不同参数,留着就变成把旧模型的参数发给新模型。
182
+ *
183
+ * `modelId: null` 表示回到助手定义上那个模型(它也没绑时用配置里的兜底)。
184
+ * 历史里已经有图、而新模型不看图时拒绝(D20),并说明原因。
185
+ */
186
+ setModel(params: ConversationSetModelParams): Promise<ConversationSetModelResult>;
187
+ /**
188
+ * 调这段会话的思考档位(PRD F-B6 / F-B7)。
189
+ *
190
+ * 写的是档位名(不是展开后的参数):档位属于模型,同一个名字在不同模型的策略表里对应
191
+ * 不同参数。`level: null` 表示回到「跟随助手定义」。改助手默认档是另一个动作
192
+ * (`agent.setThinking`)。
193
+ *
194
+ * 档位名必须在该模型引用的策略表里 —— 表里没有的档发出去只会换来一句 400;模型没有
195
+ * 可调档位时整件事不成立(`unsupported`)。
196
+ */
197
+ setThinking(params: ConversationSetThinkingParams): Promise<ConversationSetThinkingResult>;
198
+ /**
199
+ * 把一批对话行拼成侧栏用的摘要(列表与搜索共用同一份口径)。
200
+ *
201
+ * `nameIsAuto` 直接读库里的那一列(R35):它是「这个名字是不是自动起的」的唯一真值,
202
+ * 不由名字内容反推。
203
+ */
204
+ summarize(rows: Conversation[]): Promise<ConversationSummary[]>;
205
+ /** 一行对话 → 侧栏摘要;`pendingCount` 是挂在这段对话上还没答的问题数 */
206
+ private toSummary;
207
+ /** 拼一段对话的完整形状,顺带把 `setModel` 要的上下文占用一起算出来 */
208
+ private composeView;
209
+ /** 改完之后重新读一遍再拼视图:改名与置顶都要回写后的完整对象 */
210
+ private reloadView;
211
+ /**
212
+ * 推一条 `conversation.changed`(L5 / D22:两个窗口同时开着时,对方界面靠它去拉)。
213
+ *
214
+ * 只报「什么变了 + 够用的定位信息」,不搬整个对象(architecture §7)。
215
+ */
216
+ private emitChanged;
217
+ /**
218
+ * 读配置。
219
+ *
220
+ * `config.json` 是手改得了的文件(F-G3 的同款思路):它坏了要让用户看见「配置用不了 +
221
+ * 哪一步读不动」,而不是一句「宿主内部错误」——所以解析失败在这里就折成 `config_invalid`。
222
+ */
223
+ private readConfig;
224
+ private viewContext;
225
+ /**
226
+ * 按 id 取一段对话:先看库里那一行,再看草稿(R56)。两者用同一份行形状,
227
+ * 于是视图拼装、换模型、写档位这些路径对草稿一字不改。
228
+ */
229
+ private requireConversation;
230
+ private requireWorkspace;
231
+ private loadWorkspace;
232
+ private loadAgent;
233
+ /** 读一个助手定义文件;不存在就是「没有这个助手」(PRD F-B5:不可用的也要说明原因) */
234
+ private readAgent;
235
+ private readAgentOrNull;
236
+ /**
237
+ * 这段对话**现在**用哪个模型:就是会话行上那个 `modelId`。
238
+ *
239
+ * 它可能已经从配置里删掉了 —— 那时 `model` 为空,调用方按 ID 显示。
240
+ */
241
+ private effectiveModel;
242
+ /**
243
+ * 这个模型是谁定的(PRD F-B4 两个动作的区别)。
244
+ *
245
+ * 会话行上的模型与助手定义绑的那个一致时算「跟着助手走」;否则算「会话自己定的」
246
+ * (创建时点名,或 `setModel` 改过)。助手没绑模型时它实际上用配置里的兜底,那一档也算
247
+ * 「跟着助手走」:装配时用的参数口径与这里同一个判断(见 `ChatRunner` 的 `conversationModelParams`)。
248
+ */
249
+ private modelSource;
250
+ /** 助手定义上那个模型(`/model` 不带 id 时回到它);它没绑且没有兜底时报错 */
251
+ private agentModelIdOf;
252
+ /**
253
+ * 把模型写进会话(草稿还没落库时写进草稿,落库那一刻跟着写进去)。
254
+ *
255
+ * 与仓储的 `setModel` 一个口径:档位跟着清掉(档位是模型的档位)。
256
+ */
257
+ private writeModel;
258
+ /** 把思考档位写进会话(`null` = 回到跟随助手定义),回写后的行 */
259
+ private writeThinkingLevel;
260
+ /** 模型引用的思考策略(表里没有、或没有档位,就是「这个模型不可调」,F-B7) */
261
+ private presetOf;
262
+ /**
263
+ * 思考强度状态(PRD F-B6 / F-B7)。
264
+ *
265
+ * 三种来源:会话行上选了某一档(`manual`);没选、而助手定义上的参数正好是某一档
266
+ * (`following_default`);模型没有思考策略(`not_adjustable`)。
267
+ * 行上那个档位名在当前模型的策略表里不存在(换过模型、或策略表被改)时退回「跟随助手」。
268
+ */
269
+ private buildThinking;
270
+ /** 历史里有没有图(D20 的依据:消息内容里的图片段,或这段对话名下带图的素材) */
271
+ private hasImages;
272
+ /** 一批消息引用过的素材 id(删消息之前读一次:关系行随消息级联消失) */
273
+ private collectAssetsOfMessages;
274
+ }