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

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 +21 -0
  7. package/dist/cli.js +353 -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,231 @@
1
+ /**
2
+ * `WsHub` —— 一条 WebSocket 上的接线层(architecture A2 / §6)。
3
+ *
4
+ * 它只做四件事,一件也不多做:
5
+ *
6
+ * 1. **握手**:首帧必须是 `hello`(`{ token, language?, clientInfo }`)。没通过之前除了 `hello`
7
+ * 什么都不接(一律 `unauthorized`),凭证不放在 URL 查询串里。`language` 挂在这条连接上、
8
+ * 断开即忘(PRD D8)。
9
+ * 2. **分发**:`MethodMap` 里的方法交给注入的 handler 表;没注册的方法回 `unsupported`
10
+ * (接线层自己代管的只有 `host.hello` / `host.setLanguage` 与上传三段)。
11
+ * 业务逻辑一律不在本文件里。
12
+ * 3. **推送**:JSON-RPC 通知(无 id),`params` 就是事件载荷。不重放、不需要 ack(PRD L5:
13
+ * 断线重连由客户端自己拉)。受理即返回的方法(`conversation.send` 这类)会产生「事件早于回包」
14
+ * 的顺序问题,所以按 `conversationId` 缓冲,回包写完再按序放行(裁定 R47)。
15
+ * 4. **上传帧**:二进制帧交给 `UploadReceiver` 落盘;连接断开时把它名下未完成的上传清掉。
16
+ *
17
+ * 错误一律走 JSON-RPC `error`:`data.code` 是稳定业务码、`data.message` 是按**这条连接的语言**
18
+ * 渲染好的句子、`data.detail` 是结构化事实。非 `HostError` 的抛出收敛成 `internal` ——
19
+ * 细节只进日志,栈与内部路径不出网。
20
+ */
21
+ import type { ListenTarget } from "../config.js";
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";
24
+ import type { TokenVerifier } from "./auth.js";
25
+ import { type UploadReceiver } from "./UploadReceiver.js";
26
+ /** 一条连接对 handler 可见的事实(不把 socket 漏给业务层) */
27
+ export interface ConnectionInfo {
28
+ /** 宿主分配的连接 id(问题对象的 `answeredBy` 这类「哪条连接」的事实用它) */
29
+ id: string;
30
+ /** 这条连接协商出的语言 */
31
+ language: Language;
32
+ /** 客户端自报的身份(`hello` 之后才有值) */
33
+ clientInfo: ClientInfo | null;
34
+ /** 这条连接用的是哪一串凭证(`hello` 之后才有值) */
35
+ credentialId: string | null;
36
+ }
37
+ /** 一个方法的调用现场 */
38
+ export interface MethodCallContext<M extends MethodName> {
39
+ method: M;
40
+ /** 入参:以契约为准(`MethodMap[M]["params"]`),业务层自己按字段取值校验 */
41
+ params: MethodParams<M>;
42
+ connection: ConnectionInfo;
43
+ }
44
+ /**
45
+ * 方法实现。
46
+ *
47
+ * 抛 `HostError` 表达「可以给用户看的原因」,抛别的会被收敛成 `internal` 并进日志。
48
+ */
49
+ export type MethodHandler<M extends MethodName> = (context: MethodCallContext<M>) => MethodResult<M> | Promise<MethodResult<M>>;
50
+ /**
51
+ * handler 表:注册哪些方法就有哪些方法,其余一律 `unsupported`。
52
+ *
53
+ * 用 `Partial` + 映射类型,是为了让「注册时的入参/出参类型」跟着方法名走 ——
54
+ * 写错一个字段名在编译期就露出来,而不是等客户端连上来才发现。
55
+ */
56
+ export type HandlerTable = {
57
+ [M in MethodName]?: MethodHandler<M>;
58
+ };
59
+ /** 日志口子:连接事件与内部错误往哪写 */
60
+ export interface HubLogger {
61
+ warn(message: string, detail?: unknown): void;
62
+ error(message: string, detail?: unknown): void;
63
+ }
64
+ /**
65
+ * 推送的按连接本地化(PRD D8):事件里的 `LocalizedText` 在产生现场渲染,而语言挂在连接上,
66
+ * 所以出网前最后一道是「按这条连接的语言把句子换掉」。注入方(W4 的通知/问题层)重渲染
67
+ * `message` 字段后原样返回;不改载荷时直接返回 `payload`。
68
+ */
69
+ export type EventLocalizer = <E extends EventName>(event: E, payload: EventMap[E], language: Language) => EventMap[E];
70
+ /**
71
+ * 连接未声明语言时的缺省语言来源。
72
+ *
73
+ * 给函数时在每次握手那一刻求值:缺省语言是「配置里的那一项」(PRD D8 / R58),而配置可以在
74
+ * 进程跑着的时候改,存成构造时的快照会让「刚改的缺省语言」对下一条连接不生效。
75
+ */
76
+ export type DefaultLanguageSource = Language | (() => Language | Promise<Language>);
77
+ export interface WsHubOptions {
78
+ /** 监听地址(由调用方按 `resolveListenTarget` 算好传进来,本文件不判断本地/对外) */
79
+ host: string;
80
+ /** 监听端口;`0` 表示由系统分配(用例与「端口被占时退回临时端口」都靠它) */
81
+ port: number;
82
+ /** 凭证校验(`auth.createTokenVerifier`;用例注入假实现) */
83
+ verifyToken: TokenVerifier;
84
+ /** 方法表 */
85
+ handlers: HandlerTable;
86
+ /** 上传接收器;不给时 `asset.begin` / `asset.end` 与二进制帧都按 `unsupported` 处理 */
87
+ uploads?: UploadReceiver;
88
+ /** 宿主版本(`hello` 的 `hostVersion`,升级判定要向客户端报这个) */
89
+ hostVersion: string;
90
+ /** 进程启动时刻(ISO 8601);缺省取构造时的时钟 */
91
+ startedAt?: string;
92
+ /**
93
+ * 能力清单(PRD F-E5:帮助页与指令菜单从这一份渲染);缺省为空。
94
+ *
95
+ * 入参是这条连接的语言(裁定 R58):句子按收件人的语言给,id 列表与顺序不变(R57)。
96
+ */
97
+ capabilities?: (language: Language) => CapabilityView[];
98
+ /** 连接未声明语言时的缺省语言(PRD D8:缺省英文);给函数时每次握手现算 */
99
+ defaultLanguage?: DefaultLanguageSource;
100
+ /** 推送出网前的按连接本地化(不注入则原样搬运) */
101
+ localizeEvent?: EventLocalizer;
102
+ /**
103
+ * 连接数变化时回调(参数是这一刻的连接数)。
104
+ *
105
+ * 单根靠它发现「最后一条连接走了」:那正是退出判据的一个触发源(PRD L4 / A10:
106
+ * 回收计时只有一处,所以这里只报事实、不自带定时器)。
107
+ */
108
+ onConnectionsChanged?: (count: number) => void;
109
+ /** 时钟,缺省 `Date.now` */
110
+ clock?: () => number;
111
+ /** 日志;缺省安静 */
112
+ logger?: HubLogger;
113
+ }
114
+ export declare class WsHub {
115
+ private readonly options;
116
+ private readonly logger;
117
+ private readonly clock;
118
+ private readonly startedAt;
119
+ /** 缺省语言来源(可能是函数:配置里的那一项可改,每次握手现算) */
120
+ private readonly defaultLanguageSource;
121
+ /** connectionId → 连接状态(关闭即移除;推送只发给还在这里面的连接) */
122
+ private readonly connections;
123
+ private server;
124
+ private closing;
125
+ constructor(options: WsHubOptions);
126
+ /**
127
+ * 开始监听。
128
+ *
129
+ * 返回**实际**监听地址:端口给 `0` 时由系统分配,回调里拿到的才是真端口 ——
130
+ * 调用方要把它写进发现文件(客户端读的是那里,不是启动参数)。
131
+ */
132
+ listen(): Promise<ListenTarget>;
133
+ /** 实际监听地址;没在监听时为 `null` */
134
+ address(): ListenTarget | null;
135
+ /**
136
+ * 收尾:先给每条连接一个正常的关闭帧,再关服务器;有连接迟迟不断就强制断开。
137
+ *
138
+ * 收尾之后不再接受新连接,也不再持有任何连接状态与上传状态。
139
+ */
140
+ close(): Promise<void>;
141
+ private doClose;
142
+ /**
143
+ * 推一个事件给所有已握手的连接。
144
+ *
145
+ * 形状与 `ChatRunner` 的 `ChatEventEmitter` 一致,所以单根可以把它直接当 `emit` 注入。
146
+ * 事件里带 `conversationId` 的(全部事件都带)会受该对话的缓冲控制:有请求还没回包时先排队。
147
+ */
148
+ push<E extends EventName>(event: E, payload: EventMap[E]): void;
149
+ /** 推一个事件给指定连接;连接不在(已断开)时返回 `false` */
150
+ pushTo<E extends EventName>(connectionId: string, event: E, payload: EventMap[E]): boolean;
151
+ /**
152
+ * 把事件载荷变成这条连接要收的通知帧。
153
+ *
154
+ * 注入了 `localizeEvent` 时先过一道:事件里的 `LocalizedText` 是在产生现场渲染的(那时不知道
155
+ * 收件人是谁),而语言挂在连接上(D8),所以真正的「按这条连接的语言说这句话」发生在这里。
156
+ * 没注入时原样搬运(测试与不关心多语言的场合)。
157
+ */
158
+ private frameFor;
159
+ /** 当前在线的连接(只给事实,不给 socket) */
160
+ connectionInfos(): ConnectionInfo[];
161
+ /** 报一次连接数变化;回调自己抛错不影响连接本身 */
162
+ private notifyConnectionsChanged;
163
+ private accept;
164
+ /** 连接断开:把它的上传与缓冲一起扔掉(订阅就是「它在不在这个集合里」) */
165
+ private drop;
166
+ private onFrame;
167
+ /** 二进制帧:只可能是上传分片 */
168
+ private onBinary;
169
+ /**
170
+ * 分片帧的错误帧。
171
+ *
172
+ * 二进制帧没有 `id`,所以「哪一趟上传被拒了」只能靠 `detail.uploadId` 认出来:这里尽力从帧头
173
+ * 取一次 `uploadId` 补进 `detail`(原有的结构化事实不动,已经有 `uploadId` 就不覆盖)。
174
+ * 业务错误原样出网;非业务错误按 `internal` 出网、细节只进日志。帧头坏到解不出 `uploadId` 时
175
+ * 与原来一样,什么也不补。
176
+ */
177
+ private chunkErrorFrame;
178
+ /**
179
+ * 请求帧:先按对话挂起推送,再分发,最后写回包,回包写完按序放行该对话的推送(R47)。
180
+ *
181
+ * 「先挂起再分发」是关键:事件可能在分发的第一行就产生(受理即返回的方法正是这样),
182
+ * 挂起晚一步就会出现「客户端还没拿到 id 就收到事件」。
183
+ */
184
+ private onRequest;
185
+ /** 通知帧(客户端发来的、不需要回包):照常执行,出错时用 `id: null` 报一次 */
186
+ private onNotification;
187
+ /**
188
+ * 方法名 → 结果。
189
+ *
190
+ * 顺序是有意的:`hello` 永远放行(握手本身不需要先握手);其余方法在未握手时一律
191
+ * `unauthorized`(连方法名都不判断,免得「未授权的连接能探出宿主有哪些方法」)。
192
+ */
193
+ private invoke;
194
+ /**
195
+ * 握手。
196
+ *
197
+ * `language` 认不出来时回落英文(PRD D8);不传就用配置的默认语言。
198
+ * 失败不改变这条连接已经有的授权状态(重复握手是客户端自己的选择,失败不该把现有连接打回未授权)。
199
+ */
200
+ private handleHello;
201
+ /**
202
+ * 连接没声明语言时用哪一种(PRD D8 / 裁定 R58)。
203
+ *
204
+ * 来源可以是函数(配置里的缺省语言可改),所以每次握手现算一次;算不出来就用英文 ——
205
+ * 语言这件事不该让握手失败。
206
+ */
207
+ private resolveDefaultLanguage;
208
+ /** 握手之前的语言:来源不是函数时就是它,是函数时先用英文(拿不到同步值) */
209
+ private initialLanguage;
210
+ /** `host.setLanguage`:改这条连接的语言,断开即忘(PRD D8 / F-E4) */
211
+ private handleSetLanguage;
212
+ private transferLimits;
213
+ private hold;
214
+ /**
215
+ * 放行一段对话的推送。
216
+ *
217
+ * 只有最后一层请求回包之后才真的放(同一对话同时有两个请求在飞时,先回包的那一个不该把
218
+ * 后一个还没回包时产生的事件抢在前面发出去)。
219
+ */
220
+ private release;
221
+ /** 发一帧:按对话的缓冲、连接状态一起看,该排队就排队 */
222
+ private deliver;
223
+ private send;
224
+ /**
225
+ * 抛出的东西 → 错误帧。
226
+ *
227
+ * `HostError` 原样出网(业务码 + 按连接语言渲染的句子 + detail);其余一律收敛成 `internal`,
228
+ * 细节(含栈)只进日志 —— 客户端看到的是「宿主出错了,日志里有细节」。
229
+ */
230
+ private errorFrame;
231
+ }