@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.
- package/CHANGELOG.md +39 -0
- package/LICENSE +21 -0
- package/README.md +759 -2
- package/dist/app.d.ts +384 -0
- package/dist/app.js +1148 -0
- package/dist/cli.d.ts +21 -0
- package/dist/cli.js +353 -0
- package/dist/config.d.ts +97 -0
- package/dist/config.js +171 -0
- package/dist/handlers/agentHandlers.d.ts +18 -0
- package/dist/handlers/agentHandlers.js +20 -0
- package/dist/handlers/assetHandlers.d.ts +29 -0
- package/dist/handlers/assetHandlers.js +35 -0
- package/dist/handlers/capabilities.d.ts +26 -0
- package/dist/handlers/capabilities.js +138 -0
- package/dist/handlers/completionHandlers.d.ts +18 -0
- package/dist/handlers/completionHandlers.js +13 -0
- package/dist/handlers/configHandlers.d.ts +31 -0
- package/dist/handlers/configHandlers.js +59 -0
- package/dist/handlers/conversationHandlers.d.ts +118 -0
- package/dist/handlers/conversationHandlers.js +314 -0
- package/dist/handlers/handoffHandlers.d.ts +17 -0
- package/dist/handlers/handoffHandlers.js +14 -0
- package/dist/handlers/hostHandlers.d.ts +39 -0
- package/dist/handlers/hostHandlers.js +56 -0
- package/dist/handlers/index.d.ts +128 -0
- package/dist/handlers/index.js +92 -0
- package/dist/handlers/messageHandlers.d.ts +11 -0
- package/dist/handlers/messageHandlers.js +10 -0
- package/dist/handlers/modelHandlers.d.ts +17 -0
- package/dist/handlers/modelHandlers.js +19 -0
- package/dist/handlers/noticeHandlers.d.ts +24 -0
- package/dist/handlers/noticeHandlers.js +24 -0
- package/dist/handlers/questionHandlers.d.ts +16 -0
- package/dist/handlers/questionHandlers.js +16 -0
- package/dist/handlers/searchHandlers.d.ts +12 -0
- package/dist/handlers/searchHandlers.js +12 -0
- package/dist/handlers/workspaceHandlers.d.ts +29 -0
- package/dist/handlers/workspaceHandlers.js +47 -0
- package/dist/i18n/en.d.ts +243 -0
- package/dist/i18n/en.js +270 -0
- package/dist/i18n/index.d.ts +43 -0
- package/dist/i18n/index.js +72 -0
- package/dist/i18n/zh.d.ts +240 -0
- package/dist/i18n/zh.js +257 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +15 -0
- package/dist/net/UploadReceiver.d.ts +186 -0
- package/dist/net/UploadReceiver.js +494 -0
- package/dist/net/WsHub.d.ts +231 -0
- package/dist/net/WsHub.js +689 -0
- package/dist/net/auth.d.ts +73 -0
- package/dist/net/auth.js +74 -0
- package/dist/net/discovery.d.ts +72 -0
- package/dist/net/discovery.js +171 -0
- package/dist/net/index.d.ts +14 -0
- package/dist/net/index.js +10 -0
- package/dist/runtime/ChatRunner.d.ts +374 -0
- package/dist/runtime/ChatRunner.js +1204 -0
- package/dist/runtime/ConversationDrafts.d.ts +43 -0
- package/dist/runtime/ConversationDrafts.js +47 -0
- package/dist/runtime/RunRegistry.d.ts +79 -0
- package/dist/runtime/RunRegistry.js +108 -0
- package/dist/runtime/ScopeRegistry.d.ts +153 -0
- package/dist/runtime/ScopeRegistry.js +259 -0
- package/dist/runtime/TransientRunner.d.ts +90 -0
- package/dist/runtime/TransientRunner.js +179 -0
- package/dist/runtime/index.d.ts +14 -0
- package/dist/runtime/index.js +10 -0
- package/dist/services/AgentService.d.ts +150 -0
- package/dist/services/AgentService.js +718 -0
- package/dist/services/AssetService.d.ts +338 -0
- package/dist/services/AssetService.js +739 -0
- package/dist/services/AutoNaming.d.ts +92 -0
- package/dist/services/AutoNaming.js +235 -0
- package/dist/services/CompletionService.d.ts +122 -0
- package/dist/services/CompletionService.js +442 -0
- package/dist/services/ConfigService.d.ts +171 -0
- package/dist/services/ConfigService.js +695 -0
- package/dist/services/ConversationService.d.ts +274 -0
- package/dist/services/ConversationService.js +902 -0
- package/dist/services/CredentialService.d.ts +33 -0
- package/dist/services/CredentialService.js +86 -0
- package/dist/services/DiscoveryService.d.ts +182 -0
- package/dist/services/DiscoveryService.js +998 -0
- package/dist/services/HandoffService.d.ts +189 -0
- package/dist/services/HandoffService.js +414 -0
- package/dist/services/Logger.d.ts +130 -0
- package/dist/services/Logger.js +256 -0
- package/dist/services/MessageService.d.ts +88 -0
- package/dist/services/MessageService.js +280 -0
- package/dist/services/ModelService.d.ts +89 -0
- package/dist/services/ModelService.js +489 -0
- package/dist/services/NoticeService.d.ts +93 -0
- package/dist/services/NoticeService.js +217 -0
- package/dist/services/QuestionService.d.ts +184 -0
- package/dist/services/QuestionService.js +457 -0
- package/dist/services/SearchService.d.ts +54 -0
- package/dist/services/SearchService.js +117 -0
- package/dist/services/WorkspaceService.d.ts +96 -0
- package/dist/services/WorkspaceService.js +213 -0
- package/dist/services/imageSize.d.ts +41 -0
- package/dist/services/imageSize.js +146 -0
- package/dist/services/index.d.ts +20 -0
- package/dist/services/index.js +15 -0
- package/dist/services/secretMask.d.ts +24 -0
- package/dist/services/secretMask.js +34 -0
- package/dist/storage/AssetRepository.d.ts +87 -0
- package/dist/storage/AssetRepository.js +180 -0
- package/dist/storage/ConversationRepository.d.ts +55 -0
- package/dist/storage/ConversationRepository.js +128 -0
- package/dist/storage/CredentialRepository.d.ts +28 -0
- package/dist/storage/CredentialRepository.js +47 -0
- package/dist/storage/Database.d.ts +95 -0
- package/dist/storage/Database.js +180 -0
- package/dist/storage/MessageRepository.d.ts +104 -0
- package/dist/storage/MessageRepository.js +323 -0
- package/dist/storage/MetaRepository.d.ts +21 -0
- package/dist/storage/MetaRepository.js +33 -0
- package/dist/storage/NoticeRepository.d.ts +31 -0
- package/dist/storage/NoticeRepository.js +89 -0
- package/dist/storage/QuestionRepository.d.ts +34 -0
- package/dist/storage/QuestionRepository.js +96 -0
- package/dist/storage/WorkspaceRepository.d.ts +25 -0
- package/dist/storage/WorkspaceRepository.js +44 -0
- package/dist/storage/dbWorker.d.ts +10 -0
- package/dist/storage/dbWorker.js +132 -0
- package/dist/storage/index.d.ts +20 -0
- package/dist/storage/index.js +16 -0
- package/dist/storage/migrations.d.ts +26 -0
- package/dist/storage/migrations.js +207 -0
- package/dist/storage/types.d.ts +298 -0
- package/dist/storage/types.js +14 -0
- package/dist/wire/errors.d.ts +105 -0
- package/dist/wire/errors.js +143 -0
- package/dist/wire/events.d.ts +102 -0
- package/dist/wire/events.js +13 -0
- package/dist/wire/frames.d.ts +106 -0
- package/dist/wire/frames.js +156 -0
- package/dist/wire/index.d.ts +31 -0
- package/dist/wire/index.js +31 -0
- package/dist/wire/methods.d.ts +1896 -0
- package/dist/wire/methods.js +99 -0
- package/dist/wire/states.d.ts +487 -0
- package/dist/wire/states.js +61 -0
- package/package.json +63 -3
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `HostApp` —— 单根对象:把零件接成一台真能跑、能被连的服务(architecture §3 / §4)。
|
|
3
|
+
*
|
|
4
|
+
* 这个文件的边界是三件事:
|
|
5
|
+
*
|
|
6
|
+
* 1. **组装**:按对象图的顺序 `new` 出依赖(库 → 仓储 → 配置 → 运行时 → 服务 → 接线),
|
|
7
|
+
* 每一层都靠构造参数注入;没有模块级单例、没有反射扫描、不读进程工作目录。
|
|
8
|
+
* 2. **启停**:`start()` 决定监听在哪、把**实际**地址写进发现文件;`stop()` 对称地拆回去
|
|
9
|
+
* (摘发现文件、断连接、关上传、回收 Scope、关库)。
|
|
10
|
+
* 3. **判据**:什么时候「什么都不欠了」可以退出(PRD L4 / 裁定 R53),以及启动时
|
|
11
|
+
* 「这台机器上是不是已经有人在服务」(单实例,architecture §2)。
|
|
12
|
+
*
|
|
13
|
+
* 方法实现不在这里:每个域的 handler 在 `handlers/`,由 {@link createHandlers} 拼成一张表交给
|
|
14
|
+
* `WsHub`。本文件只给它们提供持有者(服务、运行时、配置、时钟)与几个只有它才接得起来的钩子:
|
|
15
|
+
* - **配置生效**(`ConfigApplyPort`):改完配置要回收受影响的 Scope(F-E2)并发一条通知(F-F9);
|
|
16
|
+
* - **Scope 装配**(`ScopeRegistry` 的工厂):能力目录由 `DiscoveryService` 按 cwd 算好(R54/L9);
|
|
17
|
+
* - **退出判据**(`checkExit`):连接数、在跑的轮次、Scope 三个来源都收敛到一处。
|
|
18
|
+
*/
|
|
19
|
+
import { ConfigManager } from "@ai-zen/agents-sdk";
|
|
20
|
+
import type { HandoffService } from "@ai-zen/agents-sdk";
|
|
21
|
+
import type { ListenTarget, HostPaths } from "./config.js";
|
|
22
|
+
import type { Language } from "./i18n/index.js";
|
|
23
|
+
import { UploadReceiver, WsHub } from "./net/index.js";
|
|
24
|
+
import type { HandlerTable, HubLogger } from "./net/index.js";
|
|
25
|
+
import { ChatRunner, RunRegistry, ScopeRegistry } from "./runtime/index.js";
|
|
26
|
+
import type { AgentBuildContext, AgentFactory, Clock, ScopeFactory } from "./runtime/index.js";
|
|
27
|
+
import { ConversationDrafts } from "./runtime/ConversationDrafts.js";
|
|
28
|
+
import { TransientRunner } from "./runtime/TransientRunner.js";
|
|
29
|
+
import { ConversationService, CredentialService, MessageService, SearchService, WorkspaceService } from "./services/index.js";
|
|
30
|
+
import type { ConversationRuntimePort } from "./services/index.js";
|
|
31
|
+
import { AgentService } from "./services/AgentService.js";
|
|
32
|
+
import { AssetService } from "./services/AssetService.js";
|
|
33
|
+
import { AutoNaming } from "./services/AutoNaming.js";
|
|
34
|
+
import { CompletionService } from "./services/CompletionService.js";
|
|
35
|
+
import { ConfigService } from "./services/ConfigService.js";
|
|
36
|
+
import { DiscoveryService } from "./services/DiscoveryService.js";
|
|
37
|
+
import { HandoffService as HandoffDocumentsService } from "./services/HandoffService.js";
|
|
38
|
+
import { ModelService } from "./services/ModelService.js";
|
|
39
|
+
import { NoticeService } from "./services/NoticeService.js";
|
|
40
|
+
import { QuestionService } from "./services/QuestionService.js";
|
|
41
|
+
import { AssetRepository, ConversationRepository, CredentialRepository, Database, MessageRepository, NoticeRepository, QuestionRepository, WorkspaceRepository } from "./storage/index.js";
|
|
42
|
+
import type { CapabilityView } from "./wire/index.js";
|
|
43
|
+
/**
|
|
44
|
+
* 起一个低频定时器,返回取消函数。
|
|
45
|
+
*
|
|
46
|
+
* 缺省实现是 `setInterval(...).unref()`:这个定时器不该成为「进程为什么还没退」的原因。
|
|
47
|
+
* 做成注入点是因为用例不可能真等 30 秒(假定时器又会把真套接字的关闭路径拖住)。
|
|
48
|
+
*/
|
|
49
|
+
export type RepeatTimer = (task: () => void, everyMs: number) => () => void;
|
|
50
|
+
/** 进程为什么会走到「什么都不欠了」 */
|
|
51
|
+
export type ExitReason = "idle" | "requested";
|
|
52
|
+
/** 退出那一刻的事实(判断依据 + 为什么退) */
|
|
53
|
+
export interface ExitFacts {
|
|
54
|
+
reason: ExitReason;
|
|
55
|
+
/** 那一刻还有几条连接(`idle` 时为 0) */
|
|
56
|
+
connections: number;
|
|
57
|
+
/** 那一刻还在跑的轮次数(`idle` 时为 0) */
|
|
58
|
+
runs: number;
|
|
59
|
+
/** 那一刻还持有几个 Workspace Scope(`idle` 时为 0) */
|
|
60
|
+
scopes: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 「真的退出」这个动作。
|
|
64
|
+
*
|
|
65
|
+
* 进程退不退是不可逆的事,所以做成注入点:生产缺省 `process.exit(0)`,
|
|
66
|
+
* 用例注入一个记账函数,从而能验证「判据在什么时刻成立」而不把测试进程送走。
|
|
67
|
+
*/
|
|
68
|
+
export type ExitHook = (facts: ExitFacts) => void | Promise<void>;
|
|
69
|
+
/** 组装 `HostApp` 的入参 */
|
|
70
|
+
export interface HostAppOptions {
|
|
71
|
+
/** 数据根(缺省 `AI_ZEN_DIR`,再缺省 `~/.ai-zen`,PRD F-J4) */
|
|
72
|
+
aiZenDir?: string;
|
|
73
|
+
/** 启动参数给的端口(优先级最高,D25);`0` 表示让系统分配(用例与冒烟用) */
|
|
74
|
+
port?: number;
|
|
75
|
+
/**
|
|
76
|
+
* 配置文件(`<dataRoot>/host.json`)里的端口(第二优先,D25)。
|
|
77
|
+
*
|
|
78
|
+
* 不传时由 `create()` 自己读那份文件(裁定 R67);显式传了就以传入的为准
|
|
79
|
+
* (命令行已经读过一次,不必再读)。
|
|
80
|
+
*/
|
|
81
|
+
configPort?: number;
|
|
82
|
+
/** 显式指定监听地址(优先级高于 `local` 推出的那个) */
|
|
83
|
+
host?: string;
|
|
84
|
+
/** 本地实例只监听回环(PRD A6);缺省 `true` */
|
|
85
|
+
local?: boolean;
|
|
86
|
+
/** 宿主版本;缺省读包元数据 */
|
|
87
|
+
version?: string;
|
|
88
|
+
/** 造 agent 的工厂;缺省按 SDK 口径装配(用例注入假 agent,不必连模型) */
|
|
89
|
+
createAgent?: AgentFactory;
|
|
90
|
+
/** 造 Scope 的工厂;缺省按 SDK 口径装配(用例可以给不带能力的空 Scope) */
|
|
91
|
+
createScope?: ScopeFactory;
|
|
92
|
+
/** Scope 空闲回收时长(PRD D28 缺省 10 分钟;用例调小以免真等) */
|
|
93
|
+
scopeIdleTimeoutMs?: number;
|
|
94
|
+
/** 交接服务(SDK 口径,装交接线插件用);未注入时不装插件并推一条警告通知(裁定 R50) */
|
|
95
|
+
handoff?: (context: AgentBuildContext) => HandoffService | undefined;
|
|
96
|
+
/** 时钟(Scope 回收计时与用例里的时间推进) */
|
|
97
|
+
clock?: Clock;
|
|
98
|
+
/** 真退出时做什么;缺省 `process.exit(0)` */
|
|
99
|
+
exit?: ExitHook;
|
|
100
|
+
/** 能力清单(PRD F-E5);缺省用 `handlers/capabilities.ts` 里那份与契约同步的清单 */
|
|
101
|
+
capabilities?: (language: Language) => CapabilityView[];
|
|
102
|
+
/** 连接未声明语言时的缺省语言(PRD D8);不给时用配置里的 `language`,再缺省英文 */
|
|
103
|
+
defaultLanguage?: Language;
|
|
104
|
+
/** 日志口(连接事件与内部错误);缺省写到 `<dataRoot>/logs/host.log` 并按大小轮转 */
|
|
105
|
+
logger?: HubLogger;
|
|
106
|
+
/** 读磁盘上的版本号(D4 / F-E3 的自检要比它);缺省读本包 `package.json` */
|
|
107
|
+
diskVersion?: () => string | null;
|
|
108
|
+
/** 版本自检的间隔(毫秒),缺省 30 秒;用例调小以免真等 */
|
|
109
|
+
versionCheckIntervalMs?: number;
|
|
110
|
+
/** 起低频定时器的方式(缺省 `setInterval` + `unref`);用例注入自己的,从而不必真等 30 秒 */
|
|
111
|
+
startVersionTimer?: RepeatTimer;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 宿主版本:读本包的 `package.json`。
|
|
115
|
+
*
|
|
116
|
+
* 相对 `import.meta.url` 找而不是读进程工作目录:宿主是常驻后台进程,工作目录由启动方式
|
|
117
|
+
* 决定(`src/app.ts` 与 `dist/app.js` 的上一级都是包根,两种形态都能读到同一份)。
|
|
118
|
+
*/
|
|
119
|
+
export declare function resolveHostVersion(): string;
|
|
120
|
+
/**
|
|
121
|
+
* 磁盘上的版本号:读本包的 `package.json`;读不到(或格式不对)返回 `null`。
|
|
122
|
+
*
|
|
123
|
+
* 升级判定(D4 / F-E3)要的就是「磁盘上现在是哪个版本」,所以这里与宿主版本共用
|
|
124
|
+
* 同一处读法,`null` 与 `"0.0.0"` 不混:前者是「不知道」,后者是「真的读到了 0.0.0」。
|
|
125
|
+
*/
|
|
126
|
+
export declare function readDiskVersion(): string | null;
|
|
127
|
+
export declare class HostApp {
|
|
128
|
+
readonly paths: HostPaths;
|
|
129
|
+
readonly db: Database;
|
|
130
|
+
readonly configManager: ConfigManager;
|
|
131
|
+
readonly workspaces: WorkspaceRepository;
|
|
132
|
+
readonly conversations: ConversationRepository;
|
|
133
|
+
readonly messages: MessageRepository;
|
|
134
|
+
readonly assets: AssetRepository;
|
|
135
|
+
readonly notices: NoticeRepository;
|
|
136
|
+
readonly questions: QuestionRepository;
|
|
137
|
+
readonly credentials: CredentialRepository;
|
|
138
|
+
readonly scopeRegistry: ScopeRegistry;
|
|
139
|
+
readonly runRegistry: RunRegistry;
|
|
140
|
+
/**
|
|
141
|
+
* 服务层要的两件运行时事实:忙不忙、删掉之后的中止。
|
|
142
|
+
*
|
|
143
|
+
* 模型与思考档位不在这里 —— 它们在会话行上。
|
|
144
|
+
*/
|
|
145
|
+
readonly conversationRuntime: ConversationRuntimePort;
|
|
146
|
+
/** 还没发过第一条消息的对话(R56:`create` 只发 id 与身份,首次 `send` 才落库) */
|
|
147
|
+
readonly conversationDrafts: ConversationDrafts;
|
|
148
|
+
readonly chatRunner: ChatRunner;
|
|
149
|
+
readonly transientRunner: TransientRunner;
|
|
150
|
+
readonly assetService: AssetService;
|
|
151
|
+
readonly workspaceService: WorkspaceService;
|
|
152
|
+
readonly conversationService: ConversationService;
|
|
153
|
+
readonly messageService: MessageService;
|
|
154
|
+
readonly searchService: SearchService;
|
|
155
|
+
readonly credentialService: CredentialService;
|
|
156
|
+
readonly discoveryService: DiscoveryService;
|
|
157
|
+
readonly configService: ConfigService;
|
|
158
|
+
readonly agentService: AgentService;
|
|
159
|
+
readonly modelService: ModelService;
|
|
160
|
+
readonly completionService: CompletionService;
|
|
161
|
+
readonly noticeService: NoticeService;
|
|
162
|
+
readonly questionService: QuestionService;
|
|
163
|
+
readonly handoffService: HandoffDocumentsService;
|
|
164
|
+
readonly autoNaming: AutoNaming;
|
|
165
|
+
readonly uploads: UploadReceiver;
|
|
166
|
+
readonly hub: WsHub;
|
|
167
|
+
/** 方法名 → 实现(`handlers/createHandlers` 拼出来的那张表) */
|
|
168
|
+
readonly handlers: HandlerTable;
|
|
169
|
+
/** 宿主版本(`hello` 与 `host.version` 报的那一个) */
|
|
170
|
+
readonly version: string;
|
|
171
|
+
/** 能力清单(PRD F-E5:帮助页与指令菜单按它渲染;按给定语言出句子) */
|
|
172
|
+
readonly capabilities: (language: Language) => CapabilityView[];
|
|
173
|
+
/** 进程启动时刻(ISO 8601) */
|
|
174
|
+
readonly startedAt: string;
|
|
175
|
+
/** 是不是本地实例(PRD A6:决定监听范围与要不要发本地凭证交付文件) */
|
|
176
|
+
readonly local: boolean;
|
|
177
|
+
private readonly options;
|
|
178
|
+
private readonly clock;
|
|
179
|
+
private readonly logger;
|
|
180
|
+
/** 自己拥有的文件日志(注入了外部 logger 时为 `null`:那份不归本对象关) */
|
|
181
|
+
private readonly fileLogger;
|
|
182
|
+
private readonly exitHook;
|
|
183
|
+
/** 磁盘版本的读法(D4 / F-E3 自检用;用例换成假实现) */
|
|
184
|
+
private readonly readDiskVersion;
|
|
185
|
+
/** 版本自检的间隔与定时器句柄(`stop()` 里清掉,不留悬挂定时器) */
|
|
186
|
+
private readonly versionCheckIntervalMs;
|
|
187
|
+
private readonly startVersionTimer;
|
|
188
|
+
/** 取消自检定时器(`null` 表示现在没有在跑) */
|
|
189
|
+
private stopVersionTimer;
|
|
190
|
+
/** 配置文件给出的端口(第二优先;`undefined` 表示这一档没说话) */
|
|
191
|
+
private readonly configPort;
|
|
192
|
+
/** 当前阶段:造好 / 自己监听中 / 挂靠已有实例 / 已收尾 */
|
|
193
|
+
private phase;
|
|
194
|
+
private listening;
|
|
195
|
+
/** 发现文件是不是这一份进程写的(挂靠别人的实例时不能去删它) */
|
|
196
|
+
private ownsHostFile;
|
|
197
|
+
/** 收尾只做一次(`host.shutdown`、判据、显式 `stop()` 都可能先到) */
|
|
198
|
+
private closing;
|
|
199
|
+
/** 「真的退出」只交棒一次 */
|
|
200
|
+
private exited;
|
|
201
|
+
private checking;
|
|
202
|
+
/** 这条进程至少被用过一次:没有它,刚起来的进程会在第一个客户端连上来之前就判自己该退 */
|
|
203
|
+
private served;
|
|
204
|
+
private stopAllRecycled;
|
|
205
|
+
/** 思考策略表快照(装配 agent 时要把档位名展开成参数,而那一层是同步的) */
|
|
206
|
+
private presets;
|
|
207
|
+
/** 推送入口(造好之前为 `null`:这时没有任何连接可推) */
|
|
208
|
+
private hubForPush;
|
|
209
|
+
/** 交接服务(SDK 口径):给了就装交接线插件(R59) */
|
|
210
|
+
private readonly handoffProvider;
|
|
211
|
+
/** R50 的那条警告只说一次(描述的是装配能力,不是某一轮的错) */
|
|
212
|
+
private handoffWarningSent;
|
|
213
|
+
private constructor();
|
|
214
|
+
/**
|
|
215
|
+
* 造一个 `HostApp`(不监听)。
|
|
216
|
+
*
|
|
217
|
+
* 顺序上先读配置文件、再开库:端口写得不对(`config_invalid`)时连库都不必建
|
|
218
|
+
* (裁定 R67:显式给出的非法端口报错,不静默回落)。建库与迁移失败时把库关掉再抛,
|
|
219
|
+
* 避免留下一个开着 worker 的坏实例。
|
|
220
|
+
*/
|
|
221
|
+
static create(options?: HostAppOptions): Promise<HostApp>;
|
|
222
|
+
/** 本进程是否在自己监听 */
|
|
223
|
+
get running(): boolean;
|
|
224
|
+
/** 是不是挂靠在「已经在运行」的那个实例上(本进程没监听) */
|
|
225
|
+
get attached(): boolean;
|
|
226
|
+
/** 服务地址(`port: 0` 时是系统分配的那个;没在服务时为 `null`) */
|
|
227
|
+
get address(): ListenTarget | null;
|
|
228
|
+
/**
|
|
229
|
+
* 开始服务。
|
|
230
|
+
*
|
|
231
|
+
* 两步顺序是有意的:
|
|
232
|
+
* 1. **先看这台机器上是不是已经有人在服务**(发现文件是唯一真相)。活着就挂靠它的地址,
|
|
233
|
+
* 本进程不重复监听 —— 同一个数据根起两个进程会各写一份 `host.json`,客户端连谁都不对。
|
|
234
|
+
* 陈旧的(pid 已死、或文件坏了)清掉再起。
|
|
235
|
+
* 2. 自己起:本地实例先备好凭证交付文件 → 监听 → 按**实际**地址写发现文件。客户端读的是
|
|
236
|
+
* 发现文件里的端口,端口被占退回临时端口时启动参数里的那个数已经不是真的了。
|
|
237
|
+
*/
|
|
238
|
+
start(): Promise<ListenTarget>;
|
|
239
|
+
/**
|
|
240
|
+
* 收尾:对称于 `start()` —— 摘发现文件 → 回收 Scope → 断连接 → 关上传 → 关库。
|
|
241
|
+
*
|
|
242
|
+
* 幂等:`host.shutdown`、判据、信号处理器都可能先到,只有第一次真的做事。
|
|
243
|
+
* 挂靠别人的实例时不摘发现文件(那份不属于本进程)。
|
|
244
|
+
*/
|
|
245
|
+
stop(reason?: ExitReason): Promise<ExitFacts>;
|
|
246
|
+
/** 收尾 + 交棒给「真的退出」(判据成立、`host.shutdown`、信号处理器走这条) */
|
|
247
|
+
shutdown(reason?: ExitReason): Promise<ExitFacts>;
|
|
248
|
+
/**
|
|
249
|
+
* 退出判据(PRD L4 / 裁定 R53):没有连接、没有在跑的轮次、Scope 全部回收 —— 什么都不欠了。
|
|
250
|
+
*
|
|
251
|
+
* 触发源有三个,都不另起计时器(A10:计时器只有一处,即 `ScopeRegistry` 里那份空闲计时):
|
|
252
|
+
* - `ScopeRegistry.onAllRecycled`:Scope 全部拆完那一刻;
|
|
253
|
+
* - 每轮结算(`onTurnSettled`):最后一件欠着的事可能是刚跑完的这一轮;
|
|
254
|
+
* - `WsHub.onConnectionsChanged`:最后一条连接走了。
|
|
255
|
+
*
|
|
256
|
+
* 两个防止误退的口子:
|
|
257
|
+
* 1. **还没被真正用过**时不判:只有握过手(凭证被接受)的连接才算「有人用过它」,
|
|
258
|
+
* 刚起来的进程与端口扫描器留下的空连接都不该把宿主送走;
|
|
259
|
+
* 2. 只在自己监听中判断(造好未启动、挂靠别人、已收尾时都不判)。
|
|
260
|
+
*/
|
|
261
|
+
checkExit(): Promise<void>;
|
|
262
|
+
private doStop;
|
|
263
|
+
/**
|
|
264
|
+
* 起一个低频自检:磁盘上的版本号变了(且已经是新的)就收尾退出,由启动方式重拉。
|
|
265
|
+
*
|
|
266
|
+
* 这个定时器不是退出判据的触发源(A10:计时器只有 `ScopeRegistry` 那一份负责回收),
|
|
267
|
+
* 它只把「包已经换了」这个事实变成一次重启。缺省的启动方式带 `unref()`:
|
|
268
|
+
* 只有它还在跑时,也不该拦住进程退出。
|
|
269
|
+
*/
|
|
270
|
+
private startVersionCheck;
|
|
271
|
+
/** 清掉自检定时器(`stop()` 里调:用例会断言退出后没有悬挂定时器) */
|
|
272
|
+
private stopVersionCheck;
|
|
273
|
+
/**
|
|
274
|
+
* 比一次磁盘版本与运行版本。
|
|
275
|
+
*
|
|
276
|
+
* 三条前提都成立才重启:磁盘读得出来、与正在跑的不是同一个版本、且磁盘上的那个**更新**
|
|
277
|
+
* (回退不算升级,重启只会把用户拉回旧版本)。重启前推一条通知:进程会走,界面上得有个交代。
|
|
278
|
+
*/
|
|
279
|
+
private checkDiskVersion;
|
|
280
|
+
/**
|
|
281
|
+
* 启动时的单实例自查(architecture §2:发现文件是「这台机器上谁在服务」的唯一真相)。
|
|
282
|
+
*
|
|
283
|
+
* 三种情况分开处理:
|
|
284
|
+
* - 没有文件:没人服务,正常起;
|
|
285
|
+
* - 文件在、pid 活着:有人服务,返回它的地址(调用方据此挂靠);
|
|
286
|
+
* - 文件在、pid 已死(或文件坏了):留在那儿只会让客户端连一个不存在的进程,清掉再起。
|
|
287
|
+
*/
|
|
288
|
+
private detectRunningInstance;
|
|
289
|
+
/** 把持有者交给 handler 层:它只拿引用,不 new 任何东西 */
|
|
290
|
+
private handlerDeps;
|
|
291
|
+
/**
|
|
292
|
+
* `host.shutdown` 的收尾请求。
|
|
293
|
+
*
|
|
294
|
+
* 收尾放在下一轮事件循环:回包要先把「受理了」写出去,客户端才知道它没白点。
|
|
295
|
+
*/
|
|
296
|
+
private requestStop;
|
|
297
|
+
/** 监听地址:`local` 推默认地址,显式 `host` 覆盖它;`port: 0` 原样交给系统分配 */
|
|
298
|
+
private resolveTarget;
|
|
299
|
+
/** 缺省的 Scope 工厂:按 SDK 口径装能力,能力目录由发现服务按 cwd 算好(R54 / L9) */
|
|
300
|
+
private defaultScopeFactory;
|
|
301
|
+
/** 缺省的 agent 工厂:SDK 口径装配(硬线、子 Agent 递归、交接线、工具刷新) */
|
|
302
|
+
private defaultAgentFactory;
|
|
303
|
+
/**
|
|
304
|
+
* 这一轮用哪个交接服务(R59:交接插件真的装上,不再因为「没注入」而整体不装)。
|
|
305
|
+
*
|
|
306
|
+
* 缺省实现按这一轮 Scope 的 cwd 造一个 SDK 交接服务(文档写进项目,D19)。拿不到时
|
|
307
|
+
* 说一声(R50:不静默)——这条警告描述的是装配能力,所以一个进程只说一次。
|
|
308
|
+
*/
|
|
309
|
+
private handoffFor;
|
|
310
|
+
/** 缺省的交接服务:按这一轮的 cwd 造 SDK 口径的那个(文档落 `<cwd>/.ai-zen/handoffs`) */
|
|
311
|
+
private defaultHandoffProvider;
|
|
312
|
+
/**
|
|
313
|
+
* 一轮结算之后:到了交接线就在对话停下之后问用户(R59 / F-D2 / D22)。
|
|
314
|
+
*
|
|
315
|
+
* 三个前提任缺一条都不问:模型配了交接线且这一轮真的越过了它、对话已经停下(不在流式中途)、
|
|
316
|
+
* 没有已挂着的交接问题(多端看到的是同一行)。问与答之后的事都归 `QuestionService`。
|
|
317
|
+
*/
|
|
318
|
+
private askHandoffAfterSettle;
|
|
319
|
+
/** R50 的那一条警告:交接插件没装时至少让人在通知栏里看到 */
|
|
320
|
+
private notifyMissingHandoff;
|
|
321
|
+
/**
|
|
322
|
+
* 服务层要的那个窄接口(`ConversationRuntimePort`)。
|
|
323
|
+
*
|
|
324
|
+
* `forget` 指向 `ChatRunner.forget`(中止在跑的轮次、清掉这一轮的内存现场)。它只能晚绑定:
|
|
325
|
+
* 服务比执行者先造出来,所以这里闭包住 `this`,调用那一刻才去拿 `chatRunner`。
|
|
326
|
+
*/
|
|
327
|
+
private createConversationRuntime;
|
|
328
|
+
/** 素材转换要的实发模型与端点(F-H7 的判定依据:模型能不能看图、端点有没有 Files API) */
|
|
329
|
+
private resolveModelContext;
|
|
330
|
+
/** 读配置;坏了就是 `config_invalid`(服务层读配置时也是这个口径) */
|
|
331
|
+
private readConfig;
|
|
332
|
+
/** 凭证校验:顺手记下「这条进程被用过」(握手成功即算) */
|
|
333
|
+
private buildVerifier;
|
|
334
|
+
private nowIso;
|
|
335
|
+
/**
|
|
336
|
+
* 记一条普通信息(生命周期事件这类)。
|
|
337
|
+
*
|
|
338
|
+
* 注入了外部 logger 时它就是 `HubLogger`(只有 warn / error),所以这条走文件日志那一侧;
|
|
339
|
+
* 没有文件日志时什么也不做。
|
|
340
|
+
*/
|
|
341
|
+
private logInfo;
|
|
342
|
+
/**
|
|
343
|
+
* 连接没声明语言时用哪一种(PRD D8 / 裁定 R58)。
|
|
344
|
+
*
|
|
345
|
+
* 真相在 `config.json` 的 `language`(可经 `config.setDefaults` 改),所以每一跳都现读;
|
|
346
|
+
* 配置读不出来或没写这个字段时回落英文 —— 语言这件事不该让握手失败。
|
|
347
|
+
*/
|
|
348
|
+
private configuredLanguage;
|
|
349
|
+
/**
|
|
350
|
+
* 推送一个事件(`NoticeService` / `QuestionService` / `ChatRunner` 共用同一个出口)。
|
|
351
|
+
*
|
|
352
|
+
* 造好接线层之前没有连接可推,这时的事件只写库不外发(重连之后客户端自己拉,L5)。
|
|
353
|
+
*/
|
|
354
|
+
private emitEvent;
|
|
355
|
+
/**
|
|
356
|
+
* 把「配置变了」这件事办成两件具体的事:回收受影响的能力、合成一条通知。
|
|
357
|
+
*
|
|
358
|
+
* 回收的粒度按改动范围分:只改了某个项目的 MCP(`workspace` 作用域)→ 只拆那个项目的
|
|
359
|
+
* Scope;其余改动(端点 / 模型 / 上限 / 用户级 MCP)影响所有 Scope → 全部回收。
|
|
360
|
+
* `recycleAll` 对正被持有的 Scope 是「打完标记等它释放」,所以报告里的 id 是
|
|
361
|
+
* 「将会重建的那些」—— 正在跑的那一轮不会在写到一半时被抽掉能力(R52)。
|
|
362
|
+
*/
|
|
363
|
+
private createApplyPort;
|
|
364
|
+
private recycleScopesFor;
|
|
365
|
+
/**
|
|
366
|
+
* `host.upgrade`:比一次「磁盘上的版本」与「正在跑的版本」。
|
|
367
|
+
*
|
|
368
|
+
* 三种结论(契约里的 `HostUpgradeState`):磁盘读不出来 → `not_available`;两个版本一样
|
|
369
|
+
* 且没有要求别的目标 → `already_latest`;磁盘已经是新的(或请求的目标版本已落盘)→
|
|
370
|
+
* `restart_scheduled`,随后安排一次收尾:进程退出后由启动方式重新拉起(宿主不自己装包,
|
|
371
|
+
* D4)。
|
|
372
|
+
*/
|
|
373
|
+
private upgradeHost;
|
|
374
|
+
}
|
|
375
|
+
/** 造一个 `HostApp`(`index.ts` 的 `createHost` 就是它) */
|
|
376
|
+
export declare function createHost(options?: HostAppOptions): Promise<HostApp>;
|
|
377
|
+
/**
|
|
378
|
+
* 比两个版本号(`1.2.0` 与 `1.10.0`):返回 `<0` 表示左边旧、`0` 相同、`>0` 左边新。
|
|
379
|
+
*
|
|
380
|
+
* 按 `.` 切段逐段比,两段都是数字时按数字比(`1.10.0` 比 `1.9.0` 新);不是数字的段
|
|
381
|
+
* (`alpha` 这种预发布标记)按字符串比。够用的理由:升级自检只回答「磁盘上的是不是比我新」,
|
|
382
|
+
* 不排序、不解析 semver 的完整规则。
|
|
383
|
+
*/
|
|
384
|
+
export declare function compareVersions(left: string, right: string): number;
|