@aalis/core 0.1.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 (217) hide show
  1. package/README.md +21 -0
  2. package/dist/app.d.ts +166 -0
  3. package/dist/app.d.ts.map +1 -0
  4. package/dist/app.js +348 -0
  5. package/dist/app.js.map +1 -0
  6. package/dist/config.d.ts +174 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +377 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/constants.d.ts +31 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/constants.js +36 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/context.d.ts +328 -0
  15. package/dist/context.d.ts.map +1 -0
  16. package/dist/context.js +521 -0
  17. package/dist/context.js.map +1 -0
  18. package/dist/disposable-chain.d.ts +31 -0
  19. package/dist/disposable-chain.d.ts.map +1 -0
  20. package/dist/disposable-chain.js +66 -0
  21. package/dist/disposable-chain.js.map +1 -0
  22. package/dist/events.d.ts +64 -0
  23. package/dist/events.d.ts.map +1 -0
  24. package/dist/events.js +145 -0
  25. package/dist/events.js.map +1 -0
  26. package/dist/hooks.d.ts +49 -0
  27. package/dist/hooks.d.ts.map +1 -0
  28. package/dist/hooks.js +102 -0
  29. package/dist/hooks.js.map +1 -0
  30. package/dist/i18n.d.ts +6 -0
  31. package/dist/i18n.d.ts.map +1 -0
  32. package/dist/i18n.js +26 -0
  33. package/dist/i18n.js.map +1 -0
  34. package/dist/identity.d.ts +26 -0
  35. package/dist/identity.d.ts.map +1 -0
  36. package/dist/identity.js +36 -0
  37. package/dist/identity.js.map +1 -0
  38. package/dist/index.d.ts +17 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +29 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/init.d.ts +20 -0
  43. package/dist/init.d.ts.map +1 -0
  44. package/dist/init.js +455 -0
  45. package/dist/init.js.map +1 -0
  46. package/dist/llm-router.d.ts.map +1 -0
  47. package/dist/llm-router.js +123 -0
  48. package/dist/llm-router.js.map +1 -0
  49. package/dist/logger.d.ts +76 -0
  50. package/dist/logger.d.ts.map +1 -0
  51. package/dist/logger.js +187 -0
  52. package/dist/logger.js.map +1 -0
  53. package/dist/marketplace-bootstrap.d.ts +54 -0
  54. package/dist/marketplace-bootstrap.d.ts.map +1 -0
  55. package/dist/marketplace-bootstrap.js +132 -0
  56. package/dist/marketplace-bootstrap.js.map +1 -0
  57. package/dist/mixin-registry.d.ts +34 -0
  58. package/dist/mixin-registry.d.ts.map +1 -0
  59. package/dist/mixin-registry.js +60 -0
  60. package/dist/mixin-registry.js.map +1 -0
  61. package/dist/model-ref.d.ts +22 -0
  62. package/dist/model-ref.d.ts.map +1 -0
  63. package/dist/model-ref.js +46 -0
  64. package/dist/model-ref.js.map +1 -0
  65. package/dist/pending-buffer.d.ts +46 -0
  66. package/dist/pending-buffer.d.ts.map +1 -0
  67. package/dist/pending-buffer.js +131 -0
  68. package/dist/pending-buffer.js.map +1 -0
  69. package/dist/platform-registry.d.ts +40 -0
  70. package/dist/platform-registry.d.ts.map +1 -0
  71. package/dist/platform-registry.js +64 -0
  72. package/dist/platform-registry.js.map +1 -0
  73. package/dist/plugin-activation.d.ts +43 -0
  74. package/dist/plugin-activation.d.ts.map +1 -0
  75. package/dist/plugin-activation.js +172 -0
  76. package/dist/plugin-activation.js.map +1 -0
  77. package/dist/plugin-topology.d.ts +40 -0
  78. package/dist/plugin-topology.d.ts.map +1 -0
  79. package/dist/plugin-topology.js +126 -0
  80. package/dist/plugin-topology.js.map +1 -0
  81. package/dist/plugin.d.ts +184 -0
  82. package/dist/plugin.d.ts.map +1 -0
  83. package/dist/plugin.js +549 -0
  84. package/dist/plugin.js.map +1 -0
  85. package/dist/providers.d.ts +85 -0
  86. package/dist/providers.d.ts.map +1 -0
  87. package/dist/providers.js +2 -0
  88. package/dist/providers.js.map +1 -0
  89. package/dist/semver-mini.d.ts +20 -0
  90. package/dist/semver-mini.d.ts.map +1 -0
  91. package/dist/semver-mini.js +94 -0
  92. package/dist/semver-mini.js.map +1 -0
  93. package/dist/service-helpers.d.ts +34 -0
  94. package/dist/service-helpers.d.ts.map +1 -0
  95. package/dist/service-helpers.js +68 -0
  96. package/dist/service-helpers.js.map +1 -0
  97. package/dist/service.d.ts +145 -0
  98. package/dist/service.d.ts.map +1 -0
  99. package/dist/service.js +279 -0
  100. package/dist/service.js.map +1 -0
  101. package/dist/types/agent.d.ts +51 -0
  102. package/dist/types/agent.d.ts.map +1 -0
  103. package/dist/types/agent.js +3 -0
  104. package/dist/types/agent.js.map +1 -0
  105. package/dist/types/app.d.ts +74 -0
  106. package/dist/types/app.d.ts.map +1 -0
  107. package/dist/types/app.js +3 -0
  108. package/dist/types/app.js.map +1 -0
  109. package/dist/types/archive.d.ts +59 -0
  110. package/dist/types/archive.d.ts.map +1 -0
  111. package/dist/types/archive.js +16 -0
  112. package/dist/types/archive.js.map +1 -0
  113. package/dist/types/authority.d.ts +63 -0
  114. package/dist/types/authority.d.ts.map +1 -0
  115. package/dist/types/authority.js +3 -0
  116. package/dist/types/authority.js.map +1 -0
  117. package/dist/types/capabilities.d.ts +53 -0
  118. package/dist/types/capabilities.d.ts.map +1 -0
  119. package/dist/types/capabilities.js +87 -0
  120. package/dist/types/capabilities.js.map +1 -0
  121. package/dist/types/cli.d.ts +14 -0
  122. package/dist/types/cli.d.ts.map +1 -0
  123. package/dist/types/cli.js +3 -0
  124. package/dist/types/cli.js.map +1 -0
  125. package/dist/types/commands.d.ts +98 -0
  126. package/dist/types/commands.d.ts.map +1 -0
  127. package/dist/types/commands.js +3 -0
  128. package/dist/types/commands.js.map +1 -0
  129. package/dist/types/core.d.ts +117 -0
  130. package/dist/types/core.d.ts.map +1 -0
  131. package/dist/types/core.js +6 -0
  132. package/dist/types/core.js.map +1 -0
  133. package/dist/types/disposable-service.d.ts +31 -0
  134. package/dist/types/disposable-service.d.ts.map +1 -0
  135. package/dist/types/disposable-service.js +3 -0
  136. package/dist/types/disposable-service.js.map +1 -0
  137. package/dist/types/embedding.d.ts +7 -0
  138. package/dist/types/embedding.d.ts.map +1 -0
  139. package/dist/types/embedding.js +3 -0
  140. package/dist/types/embedding.js.map +1 -0
  141. package/dist/types/flow-control.d.ts +51 -0
  142. package/dist/types/flow-control.d.ts.map +1 -0
  143. package/dist/types/flow-control.js +12 -0
  144. package/dist/types/flow-control.js.map +1 -0
  145. package/dist/types/gateway.d.ts +24 -0
  146. package/dist/types/gateway.d.ts.map +1 -0
  147. package/dist/types/gateway.js +15 -0
  148. package/dist/types/gateway.js.map +1 -0
  149. package/dist/types/hooks.d.ts +3 -0
  150. package/dist/types/hooks.d.ts.map +1 -0
  151. package/dist/types/hooks.js +18 -0
  152. package/dist/types/hooks.js.map +1 -0
  153. package/dist/types/image-recognition.d.ts +123 -0
  154. package/dist/types/image-recognition.d.ts.map +1 -0
  155. package/dist/types/image-recognition.js +31 -0
  156. package/dist/types/image-recognition.js.map +1 -0
  157. package/dist/types/index.d.ts +8 -0
  158. package/dist/types/index.d.ts.map +1 -0
  159. package/dist/types/index.js +17 -0
  160. package/dist/types/index.js.map +1 -0
  161. package/dist/types/llm.d.ts +146 -0
  162. package/dist/types/llm.d.ts.map +1 -0
  163. package/dist/types/llm.js +27 -0
  164. package/dist/types/llm.js.map +1 -0
  165. package/dist/types/memory.d.ts +62 -0
  166. package/dist/types/memory.d.ts.map +1 -0
  167. package/dist/types/memory.js +22 -0
  168. package/dist/types/memory.js.map +1 -0
  169. package/dist/types/persona.d.ts +45 -0
  170. package/dist/types/persona.d.ts.map +1 -0
  171. package/dist/types/persona.js +3 -0
  172. package/dist/types/persona.js.map +1 -0
  173. package/dist/types/platform.d.ts +126 -0
  174. package/dist/types/platform.d.ts.map +1 -0
  175. package/dist/types/platform.js +5 -0
  176. package/dist/types/platform.js.map +1 -0
  177. package/dist/types/plugin.d.ts +84 -0
  178. package/dist/types/plugin.d.ts.map +1 -0
  179. package/dist/types/plugin.js +24 -0
  180. package/dist/types/plugin.js.map +1 -0
  181. package/dist/types/service.d.ts +43 -0
  182. package/dist/types/service.d.ts.map +1 -0
  183. package/dist/types/service.js +38 -0
  184. package/dist/types/service.js.map +1 -0
  185. package/dist/types/services.d.ts +17 -0
  186. package/dist/types/services.d.ts.map +1 -0
  187. package/dist/types/services.js +41 -0
  188. package/dist/types/services.js.map +1 -0
  189. package/dist/types/session.d.ts +153 -0
  190. package/dist/types/session.d.ts.map +1 -0
  191. package/dist/types/session.js +19 -0
  192. package/dist/types/session.js.map +1 -0
  193. package/dist/types/storage.d.ts +100 -0
  194. package/dist/types/storage.d.ts.map +1 -0
  195. package/dist/types/storage.js +29 -0
  196. package/dist/types/storage.js.map +1 -0
  197. package/dist/types/tools.d.ts +39 -0
  198. package/dist/types/tools.d.ts.map +1 -0
  199. package/dist/types/tools.js +3 -0
  200. package/dist/types/tools.js.map +1 -0
  201. package/dist/types/trigger-policy.d.ts +16 -0
  202. package/dist/types/trigger-policy.d.ts.map +1 -0
  203. package/dist/types/trigger-policy.js +6 -0
  204. package/dist/types/trigger-policy.js.map +1 -0
  205. package/dist/types/vectorstore.d.ts +23 -0
  206. package/dist/types/vectorstore.d.ts.map +1 -0
  207. package/dist/types/vectorstore.js +3 -0
  208. package/dist/types/vectorstore.js.map +1 -0
  209. package/dist/types/web-search.d.ts +88 -0
  210. package/dist/types/web-search.d.ts.map +1 -0
  211. package/dist/types/web-search.js +23 -0
  212. package/dist/types/web-search.js.map +1 -0
  213. package/dist/types/webui.d.ts +137 -0
  214. package/dist/types/webui.d.ts.map +1 -0
  215. package/dist/types/webui.js +3 -0
  216. package/dist/types/webui.js.map +1 -0
  217. package/package.json +22 -0
package/dist/init.js ADDED
@@ -0,0 +1,455 @@
1
+ /**
2
+ * 首启交互式初始化向导。
3
+ *
4
+ * 当 aalis.config.yaml 不存在时被 src/index.ts 调用。
5
+ *
6
+ * 设计:
7
+ * - 不依赖任何插件实例(只 dynamic import 各 plugin 的入口模块以读取静态导出的 provides/inject)。
8
+ * - 不再硬编码插件清单或"bundled 必装"概念:
9
+ * · 扫 packages/plugin-* 与已经位于 node_modules/@aalis/plugin-* 的本地包;
10
+ * · 用各 plugin 模块的 `provides[]` 把它们按服务分组,让用户在每个服务里多选;
11
+ * · 不 provide 任何服务的归为"工具与扩展"。
12
+ * - 配置块写空对象 `{}`,密钥等留给用户启动后从 WebUI 或 yaml 填。
13
+ * 末尾会列出"启用了但通常需要进一步配置"的插件提醒。
14
+ */
15
+ import { existsSync, writeFileSync, readdirSync, readFileSync } from 'node:fs';
16
+ import { resolve } from 'node:path';
17
+ import { pathToFileURL } from 'node:url';
18
+ import { stringify as stringifyYaml } from 'yaml';
19
+ import * as readline from 'node:readline/promises';
20
+ import { stdin as input, stdout as output } from 'node:process';
21
+ import { MarketplaceBootstrap, runRootPnpmInstall } from './marketplace-bootstrap.js';
22
+ const EXTERNAL_HINTS = {
23
+ '@aalis/plugin-deepseek': '需要 apiKey',
24
+ '@aalis/plugin-openai': '需要 apiKey 和(可选)baseURL',
25
+ '@aalis/plugin-ollama': '需要本地或远端 Ollama 服务地址',
26
+ '@aalis/plugin-embedding-ollama': '需要 Ollama 服务地址',
27
+ '@aalis/plugin-memory-mongodb': '需要 MongoDB 连接 URI',
28
+ '@aalis/plugin-adapter-onebot': '需要 OneBot 账号、wsUrl 等',
29
+ '@aalis/plugin-websearch-serper': '需要 Serper API Key',
30
+ '@aalis/plugin-image-recognition': '需要视觉模型 apiKey/endpoint',
31
+ '@aalis/plugin-okx-trading': '需要交易所 API 凭证',
32
+ '@aalis/plugin-maimai': '需要舞萌相关 token',
33
+ '@aalis/plugin-marketplace-client': '建议至少配置 1 个 registry',
34
+ };
35
+ /** 扫描仓库 packages/plugin-* 与 node_modules/@aalis/plugin-* */
36
+ async function discoverPluginMetas(cwd) {
37
+ const found = [];
38
+ const seen = new Set();
39
+ // 1) 仓库 packages/plugin-*
40
+ const pkgsDir = resolve(cwd, 'packages');
41
+ if (existsSync(pkgsDir)) {
42
+ for (const dir of readdirSync(pkgsDir)) {
43
+ if (!dir.startsWith('plugin-'))
44
+ continue;
45
+ const pkgDir = resolve(pkgsDir, dir);
46
+ const meta = await readPluginMeta(pkgDir, dir);
47
+ if (meta && !seen.has(meta.name)) {
48
+ seen.add(meta.name);
49
+ found.push(meta);
50
+ }
51
+ }
52
+ }
53
+ // 2) node_modules/@aalis/plugin-*(带 file:./packages 依赖的未在工作区连接场景)
54
+ const nmAalis = resolve(cwd, 'node_modules', '@aalis');
55
+ if (existsSync(nmAalis)) {
56
+ for (const dir of readdirSync(nmAalis)) {
57
+ if (!dir.startsWith('plugin-'))
58
+ continue;
59
+ const pkgDir = resolve(nmAalis, dir);
60
+ const meta = await readPluginMeta(pkgDir, `@aalis/${dir}`);
61
+ if (meta && !seen.has(meta.name)) {
62
+ seen.add(meta.name);
63
+ found.push(meta);
64
+ }
65
+ }
66
+ }
67
+ found.sort((a, b) => a.name.localeCompare(b.name));
68
+ return found;
69
+ }
70
+ async function readPluginMeta(pkgDir, dirHint) {
71
+ const pjPath = resolve(pkgDir, 'package.json');
72
+ if (!existsSync(pjPath))
73
+ return null;
74
+ let pkg;
75
+ try {
76
+ pkg = JSON.parse(readFileSync(pjPath, 'utf-8'));
77
+ }
78
+ catch {
79
+ return null;
80
+ }
81
+ if (!pkg.name)
82
+ return null;
83
+ if (pkg.aalis?.core || pkg.aalis?.client)
84
+ return null;
85
+ if (!(pkg.keywords ?? []).includes('aalis-plugin'))
86
+ return null;
87
+ // 尝试 dynamic import 读取 provides / inject
88
+ let provides = [];
89
+ let injectRequired = [];
90
+ const mainRel = pkg.main ?? 'dist/index.js';
91
+ const mainAbs = resolve(pkgDir, mainRel);
92
+ if (existsSync(mainAbs)) {
93
+ try {
94
+ const mod = await import(pathToFileURL(mainAbs).href);
95
+ const exp = (mod && (mod.default ?? mod));
96
+ if (Array.isArray(mod.provides)) {
97
+ provides = (mod.provides).filter(x => typeof x === 'string');
98
+ }
99
+ else if (Array.isArray(exp.provides)) {
100
+ provides = (exp.provides).filter(x => typeof x === 'string');
101
+ }
102
+ const injSrc = mod.inject ?? exp.inject;
103
+ if (injSrc && typeof injSrc === 'object') {
104
+ const req = injSrc.required;
105
+ if (Array.isArray(req))
106
+ injectRequired = req.filter(x => typeof x === 'string');
107
+ }
108
+ }
109
+ catch { /* 静默忽略 import 失败的 plugin */ }
110
+ }
111
+ return {
112
+ name: pkg.name,
113
+ dir: dirHint,
114
+ description: pkg.description ?? '',
115
+ displayName: pkg.aalis?.displayName,
116
+ provides,
117
+ injectRequired,
118
+ needsExternalConfig: pkg.name in EXTERNAL_HINTS,
119
+ origin: 'local',
120
+ };
121
+ }
122
+ /** 将 registry 返回的 BootstrapIndexEntry 转换为 PluginMeta(仅用于本地未命中的远端项) */
123
+ function remoteEntryToMeta(e) {
124
+ return {
125
+ name: e.name,
126
+ dir: pluginDirName(e.name),
127
+ description: e.description ?? '',
128
+ displayName: e.displayName,
129
+ provides: e.provides ?? [],
130
+ injectRequired: e.inject ?? [],
131
+ needsExternalConfig: e.name in EXTERNAL_HINTS,
132
+ origin: 'remote',
133
+ remoteVersion: e.latest,
134
+ };
135
+ }
136
+ function pluginDirName(manifestName) {
137
+ if (manifestName.startsWith('@')) {
138
+ const slash = manifestName.indexOf('/');
139
+ return slash > 0 ? manifestName.slice(slash + 1) : manifestName;
140
+ }
141
+ return manifestName;
142
+ }
143
+ // ─────────────────────── 服务分组 ───────────────────────
144
+ /** 已知服务的中文标签与排序优先级。未知服务用原名兜底。 */
145
+ const SERVICE_LABELS = {
146
+ storage: { label: '存储 (storage)', order: 10, recommended: true },
147
+ platform: { label: '平台基类 (platform)', order: 11, recommended: true },
148
+ gateway: { label: '消息网关 (gateway)', order: 12, recommended: true },
149
+ marketplace: { label: '插件市场客户端 (marketplace)', order: 13, recommended: true },
150
+ llm: { label: '语言模型 (llm)', order: 20 },
151
+ memory: { label: '消息记忆 (memory)', order: 30 },
152
+ embedding: { label: 'Embedding 模型 (embedding)', order: 40 },
153
+ vectorstore: { label: '向量数据库 (vectorstore)', order: 41 },
154
+ agent: { label: '对话代理 (agent)', order: 50 },
155
+ authority: { label: '权限分级 (authority)', order: 51 },
156
+ persona: { label: '人格 / 角色卡 (persona)', order: 52 },
157
+ scheduler: { label: '调度器 (scheduler)', order: 53 },
158
+ session: { label: '会话 (session)', order: 54 },
159
+ webui: { label: 'WebUI 服务 (webui)', order: 60 },
160
+ cli: { label: 'CLI REPL (cli)', order: 61 },
161
+ };
162
+ function groupByService(metas) {
163
+ // 一个 plugin 可能 provides 多个 service,会被加入多个组(用户在每个组里都能看到它)。
164
+ const groups = new Map();
165
+ const noProvides = [];
166
+ for (const m of metas) {
167
+ if (m.provides.length === 0) {
168
+ noProvides.push(m);
169
+ continue;
170
+ }
171
+ for (const svc of m.provides) {
172
+ const meta = SERVICE_LABELS[svc];
173
+ let g = groups.get(svc);
174
+ if (!g) {
175
+ g = {
176
+ service: svc,
177
+ label: meta?.label ?? `${svc} 服务`,
178
+ members: [],
179
+ recommended: meta?.recommended ?? false,
180
+ };
181
+ groups.set(svc, g);
182
+ }
183
+ g.members.push(m);
184
+ }
185
+ }
186
+ if (noProvides.length) {
187
+ groups.set('__misc__', {
188
+ service: '__misc__',
189
+ label: '工具与扩展(不提供具体服务)',
190
+ members: noProvides,
191
+ recommended: false,
192
+ });
193
+ }
194
+ return [...groups.values()].sort((a, b) => {
195
+ const oa = SERVICE_LABELS[a.service]?.order ?? (a.service === '__misc__' ? 999 : 500);
196
+ const ob = SERVICE_LABELS[b.service]?.order ?? (b.service === '__misc__' ? 999 : 500);
197
+ return oa - ob || a.service.localeCompare(b.service);
198
+ });
199
+ }
200
+ // ─────────────────────── 交互工具 ───────────────────────
201
+ class StdinClosedError extends Error {
202
+ constructor() { super('stdin closed during init wizard'); }
203
+ }
204
+ async function safeQuestion(rl, prompt) {
205
+ let onClose = null;
206
+ const closePromise = new Promise((_, reject) => {
207
+ onClose = () => reject(new StdinClosedError());
208
+ rl.once('close', onClose);
209
+ });
210
+ try {
211
+ return await Promise.race([rl.question(prompt), closePromise]);
212
+ }
213
+ finally {
214
+ if (onClose)
215
+ rl.off('close', onClose);
216
+ }
217
+ }
218
+ /**
219
+ * 多选:列出 entries,用户输入逗号分隔的编号;回车采用 defaultIdx 集合。
220
+ * 输入 'a' = 全选,'n' = 全不选。
221
+ */
222
+ async function pickMany(rl, title, entries, defaultIdx) {
223
+ console.log(`\n${title}`);
224
+ console.log(' (多选,逗号分隔编号;回车采用默认;a=全选;n=全不选)');
225
+ const defSet = new Set(defaultIdx);
226
+ for (let i = 0; i < entries.length; i++) {
227
+ const e = entries[i];
228
+ const star = defSet.has(i) ? '*' : ' ';
229
+ console.log(` ${star} ${i + 1}) ${e.label}`);
230
+ if (e.sub)
231
+ console.log(` ${e.sub}`);
232
+ }
233
+ while (true) {
234
+ const ans = (await safeQuestion(rl, `选择 [${defaultIdx.map(i => i + 1).join(',') || '无'}]: `)).trim();
235
+ if (!ans)
236
+ return [...defaultIdx];
237
+ if (ans.toLowerCase() === 'a')
238
+ return entries.map((_, i) => i);
239
+ if (ans.toLowerCase() === 'n')
240
+ return [];
241
+ const tokens = ans.split(/[,\s]+/).filter(Boolean);
242
+ const out = [];
243
+ let bad = false;
244
+ for (const t of tokens) {
245
+ const n = Number(t);
246
+ if (!Number.isInteger(n) || n < 1 || n > entries.length) {
247
+ bad = true;
248
+ break;
249
+ }
250
+ out.push(n - 1);
251
+ }
252
+ if (!bad)
253
+ return [...new Set(out)];
254
+ console.log(' 存在无效编号,请重新输入。');
255
+ }
256
+ }
257
+ async function askBool(rl, prompt, def) {
258
+ const hint = def ? 'Y/n' : 'y/N';
259
+ while (true) {
260
+ const ans = (await safeQuestion(rl, `${prompt} [${hint}]: `)).trim().toLowerCase();
261
+ if (!ans)
262
+ return def;
263
+ if (['y', 'yes'].includes(ans))
264
+ return true;
265
+ if (['n', 'no'].includes(ans))
266
+ return false;
267
+ }
268
+ }
269
+ export async function runInitWizardIfNeeded(opts = {}) {
270
+ const configPath = opts.configPath ?? resolve(process.cwd(), 'aalis.config.yaml');
271
+ if (existsSync(configPath))
272
+ return false;
273
+ if (opts.requireTty !== false && !input.isTTY) {
274
+ console.warn('[init] 检测到 aalis.config.yaml 不存在,但当前 stdin 非 TTY,跳过交互式初始化。');
275
+ console.warn('[init] 请手动创建 aalis.config.yaml 后再启动。');
276
+ return false;
277
+ }
278
+ console.log('\n========================================');
279
+ console.log(' Aalis 首次启动 · 交互式初始化');
280
+ console.log('========================================');
281
+ console.log('未检测到 aalis.config.yaml,正在扫描可用插件…');
282
+ const localMetas = await discoverPluginMetas(process.cwd());
283
+ console.log(`本地发现 ${localMetas.length} 个插件(packages/)。`);
284
+ // ── 在线 registry(可选) ──
285
+ // packages/ 下没有插件时强烈建议接入;否则询问是否补全。
286
+ let registryUrl = '';
287
+ let registryName = 'default';
288
+ let registryPublicKey = '';
289
+ let remoteEntries = [];
290
+ const rl = readline.createInterface({ input, output });
291
+ try {
292
+ const wantOnline = await askBool(rl, localMetas.length === 0
293
+ ? '本地没有任何插件,是否从在线 registry 拉取?'
294
+ : '是否从在线 registry 补全插件清单?', localMetas.length === 0);
295
+ if (wantOnline) {
296
+ const defaultUrl = 'http://127.0.0.1:7820';
297
+ registryUrl = (await safeQuestion(rl, `Registry URL [${defaultUrl}]: `)).trim() || defaultUrl;
298
+ registryName = (await safeQuestion(rl, `Registry 名称 [default]: `)).trim() || 'default';
299
+ registryPublicKey = (await safeQuestion(rl, `Registry 公钥(base64,可留空跳过签名校验): `)).trim();
300
+ try {
301
+ const bootstrap = new MarketplaceBootstrap(registryUrl);
302
+ remoteEntries = await bootstrap.listPlugins();
303
+ console.log(`在线发现 ${remoteEntries.length} 个插件。`);
304
+ }
305
+ catch (err) {
306
+ console.warn(`[init] 拉取 registry 失败: ${err instanceof Error ? err.message : String(err)}`);
307
+ console.warn(`[init] 跳过在线流程,仅使用本地插件。`);
308
+ registryUrl = '';
309
+ }
310
+ }
311
+ // 合并:本地优先(同名取本地版本)
312
+ const localNames = new Set(localMetas.map(m => m.name));
313
+ const remoteOnlyMetas = remoteEntries
314
+ .filter(e => !localNames.has(e.name))
315
+ .map(remoteEntryToMeta);
316
+ const metas = [...localMetas, ...remoteOnlyMetas]
317
+ .sort((a, b) => a.name.localeCompare(b.name));
318
+ if (metas.length === 0) {
319
+ console.error('[init] 未发现任何插件。请确认 packages/ 已 build,或正确配置 registry URL。');
320
+ return false;
321
+ }
322
+ console.log(`合并后共 ${metas.length} 个插件,按服务分组如下。\n`);
323
+ console.log('提示:Aalis 是多服务架构 —— 同一服务可以同时启用多个插件,');
324
+ console.log(' 运行时由 servicePreferences 决定首选;不需要的服务可以一个都不选。');
325
+ if (remoteOnlyMetas.length) {
326
+ console.log(` 标记 [远程] 的插件将自动从 ${registryUrl} 下载到 packages/。`);
327
+ }
328
+ console.log('');
329
+ const groups = groupByService(metas);
330
+ const enabled = new Set();
331
+ let step = 1;
332
+ const total = groups.length;
333
+ for (const g of groups) {
334
+ const defaultIdx = [];
335
+ if (g.recommended && g.members.length > 0)
336
+ defaultIdx.push(0);
337
+ const entries = g.members.map(m => {
338
+ const tag = m.origin === 'remote' ? `${dim('[远程]')} ` : '';
339
+ return {
340
+ label: `${tag}${m.displayName ?? m.name} ${dim('(' + m.name + (m.remoteVersion ? '@' + m.remoteVersion : '') + ')')}`,
341
+ sub: trim(m.description, 110) || (m.injectRequired.length ? `依赖服务: ${m.injectRequired.join(', ')}` : ''),
342
+ };
343
+ });
344
+ const picked = await pickMany(rl, `【${step}/${total}】${g.label} —— ${g.members.length} 个候选${g.recommended ? '(推荐至少选一个)' : ''}`, entries, defaultIdx);
345
+ for (const i of picked)
346
+ enabled.add(g.members[i].name);
347
+ step++;
348
+ }
349
+ // ── 下载需要的远程插件 ──
350
+ const toDownload = metas.filter(m => m.origin === 'remote' && enabled.has(m.name));
351
+ if (toDownload.length) {
352
+ console.log(`\n正在下载 ${toDownload.length} 个远程插件到 packages/ ...`);
353
+ const bootstrap = new MarketplaceBootstrap(registryUrl);
354
+ const packagesDir = resolve(process.cwd(), 'packages');
355
+ const cacheDir = resolve(process.cwd(), 'data/marketplace/cache/tarballs');
356
+ const downloadFailed = [];
357
+ for (const m of toDownload) {
358
+ const ver = m.remoteVersion ?? 'latest';
359
+ try {
360
+ await bootstrap.installToPackages(m.name, ver, { packagesDir, cacheDir });
361
+ console.log(` ✓ ${m.name}@${ver}`);
362
+ }
363
+ catch (err) {
364
+ const msg = err instanceof Error ? err.message : String(err);
365
+ console.warn(` ✗ ${m.name}@${ver}: ${msg}`);
366
+ downloadFailed.push(m.name);
367
+ enabled.delete(m.name);
368
+ }
369
+ }
370
+ if (downloadFailed.length) {
371
+ console.warn(`[init] ${downloadFailed.length} 个插件下载失败,已从启用列表移除。`);
372
+ }
373
+ // 触发 pnpm install 让 workspace 重新解析
374
+ console.log('正在运行 pnpm install 以同步 workspace ...');
375
+ try {
376
+ await runRootPnpmInstall(process.cwd());
377
+ console.log('✓ pnpm install 完成');
378
+ }
379
+ catch (err) {
380
+ console.warn(`[init] pnpm install 失败: ${err instanceof Error ? err.message : String(err)}`);
381
+ console.warn('[init] 请稍后手动运行 `pnpm install && pnpm -r build`。');
382
+ }
383
+ }
384
+ // disabledPlugins:本地已存在但未启用的(远程未启用的不写入,避免列表噪声)
385
+ const disabledPlugins = localMetas
386
+ .filter(m => !enabled.has(m.name))
387
+ .map(m => m.name)
388
+ .sort();
389
+ // plugins 配置块:全部空对象,参数留待用户填
390
+ const plugins = {};
391
+ for (const name of [...enabled].sort())
392
+ plugins[name] = {};
393
+ // 若用户配置了 registry 且启用了 marketplace-client,把 registry 自动写入它的配置
394
+ if (registryUrl && plugins['@aalis/plugin-marketplace-client']) {
395
+ plugins['@aalis/plugin-marketplace-client'] = {
396
+ registries: [{
397
+ name: registryName,
398
+ url: registryUrl,
399
+ publicKey: registryPublicKey || undefined,
400
+ priority: 0,
401
+ timeoutMs: 15000,
402
+ acceptAudit: 'approved',
403
+ }],
404
+ };
405
+ }
406
+ const cfg = {
407
+ name: 'Aalis',
408
+ logLevel: 'info',
409
+ plugins,
410
+ disabledPlugins,
411
+ };
412
+ const yaml = '# Aalis 配置文件(由 init 向导生成,可随时手改)\n' +
413
+ '# - plugins: 启用的插件及其配置\n' +
414
+ '# - disabledPlugins: 显式禁用的本地插件(启动时不加载)\n' +
415
+ '# 文档:docs/architecture.md / docs/plugin-development.md\n\n' +
416
+ stringifyYaml(cfg, { lineWidth: 0 });
417
+ writeFileSync(configPath, yaml, 'utf-8');
418
+ console.log(`\n✓ 已写入 ${configPath}`);
419
+ console.log(` 启用 ${enabled.size} 个插件,显式禁用 ${disabledPlugins.length} 个。`);
420
+ // 末尾提醒:启用了但需要外部配置的插件
421
+ const needsConfig = [];
422
+ for (const name of enabled) {
423
+ if (name in EXTERNAL_HINTS)
424
+ needsConfig.push({ name, hint: EXTERNAL_HINTS[name] });
425
+ }
426
+ if (needsConfig.length) {
427
+ console.log('\n⚠ 以下插件已启用但通常需要进一步配置(启动后请到 aalis.config.yaml 或 WebUI 填写):');
428
+ for (const n of needsConfig)
429
+ console.log(` · ${n.name}:${n.hint}`);
430
+ }
431
+ console.log('\n 即将启动 Aalis...\n');
432
+ return true;
433
+ }
434
+ catch (err) {
435
+ if (err instanceof StdinClosedError) {
436
+ console.error('\n[init] 输入流已关闭,初始化向导被中止。');
437
+ console.error('[init] 请重新运行 `pnpm start` 并完成所有问题。');
438
+ return false;
439
+ }
440
+ throw err;
441
+ }
442
+ finally {
443
+ rl.close();
444
+ }
445
+ }
446
+ // ─────────────────────── helpers ───────────────────────
447
+ function trim(s, n) {
448
+ if (!s)
449
+ return '';
450
+ return s.length > n ? s.slice(0, n - 1) + '…' : s;
451
+ }
452
+ function dim(s) {
453
+ return process.stdout.isTTY ? `\x1b[2m${s}\x1b[0m` : s;
454
+ }
455
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-router.d.ts","sourceRoot":"","sources":["../src/llm-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,eAAe;AACf,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAwB;AACxB,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAWD;;;;;;;;;;;GAWG;AACH,qBAAa,SAAS;IAOR,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAW,OAAO,CAAC,QAAQ,CAAC,MAAM;IANlE,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAA6C;IAElE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAU;gBAEd,GAAG,EAAE,OAAO,EAAmB,MAAM,EAAE,MAAM;IAE1E;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAmBrD;;;;;;;;;;OAUG;IACG,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAsBnF;;;OAGG;IACH,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAInD,4CAA4C;IAC5C,UAAU,IAAI,IAAI;IAKlB,OAAO,CAAC,YAAY;CA2BrB"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * LLM 路由器
3
+ *
4
+ * 负责:
5
+ * 1. 聚合所有已注册 'llm' 服务的模型列表。
6
+ * 2. 按 model ID 反查所属提供者(带缓存,服务变更时自动失效)。
7
+ * 3. 作为后续扩展点(负载均衡、能力过滤、成本路由等)的载体。
8
+ *
9
+ * 本类不持有全局状态:每个 Context 拥有一份实例,缓存在实例上。
10
+ * 由 ServiceContainer 共享真实数据源,所以同一 App 下不同子 Context
11
+ * 的路由结果一致。
12
+ */
13
+ export class LLMRouter {
14
+ ctx;
15
+ logger;
16
+ _cache = null;
17
+ _cacheTime = 0;
18
+ _cachePromise = null;
19
+ static CACHE_TTL = 60_000;
20
+ constructor(ctx, logger) {
21
+ this.ctx = ctx;
22
+ this.logger = logger;
23
+ }
24
+ /**
25
+ * 聚合所有 LLM 提供者的模型列表
26
+ *
27
+ * @example
28
+ * const models = await router.listAllModels();
29
+ * // [{ id: 'gpt-4o', capabilities: [...], provider: 'OpenAI', contextId: '...' }, ...]
30
+ */
31
+ async listAllModels() {
32
+ const providers = this.ctx.getAllServices('llm');
33
+ const results = [];
34
+ await Promise.all(providers.map(async ({ instance, contextId, label }) => {
35
+ if (typeof instance.listModels !== 'function')
36
+ return;
37
+ try {
38
+ const models = await instance.listModels();
39
+ for (const m of models) {
40
+ results.push({ ...m, provider: label ?? contextId, contextId });
41
+ }
42
+ }
43
+ catch (err) {
44
+ this.logger.warn(`获取模型列表失败 [${contextId}]:`, err);
45
+ }
46
+ }));
47
+ return results;
48
+ }
49
+ /**
50
+ * 按 model ID 查找拥有该模型的 LLM 提供者
51
+ *
52
+ * 解析顺序:
53
+ * 1. 若提供者实现了 `supportsModel(id)`,优先按此同步判断;
54
+ * 2. 否则回退到 `listModels()` 枚举构建缓存(TTL 60s)。
55
+ *
56
+ * @example
57
+ * const result = await router.resolveModelProvider('gpt-4o');
58
+ * if (result) await (result.instance as LLMService).chat({ messages, model: result.model });
59
+ */
60
+ async resolveModelProvider(modelId) {
61
+ // 快路径:提供者自报支持
62
+ const providers = this.ctx.getAllServices('llm');
63
+ for (const { instance, contextId } of providers) {
64
+ if (typeof instance.supportsModel === 'function') {
65
+ try {
66
+ if (await instance.supportsModel(modelId)) {
67
+ return { instance, model: modelId, contextId };
68
+ }
69
+ }
70
+ catch { /* ignore, fall back to enumeration */ }
71
+ }
72
+ }
73
+ // 慢路径:缓存 + listModels 枚举
74
+ const cache = await this._ensureCache();
75
+ const targetContextId = cache.get(modelId);
76
+ if (!targetContextId)
77
+ return undefined;
78
+ const found = providers.find(p => p.contextId === targetContextId);
79
+ return found ? { instance: found.instance, model: modelId, contextId: targetContextId } : undefined;
80
+ }
81
+ /**
82
+ * 获取完整的 model→contextId 映射(带缓存)
83
+ * 供需要批量查找或自行路由的插件使用。
84
+ */
85
+ getModelProviderMap() {
86
+ return this._ensureCache();
87
+ }
88
+ /** 使 model→provider 缓存立即失效(服务注册/注销时应当调用) */
89
+ invalidate() {
90
+ this._cache = null;
91
+ this._cachePromise = null;
92
+ }
93
+ _ensureCache() {
94
+ const now = Date.now();
95
+ if (this._cache && (now - this._cacheTime) < LLMRouter.CACHE_TTL) {
96
+ return Promise.resolve(this._cache);
97
+ }
98
+ if (this._cachePromise)
99
+ return this._cachePromise;
100
+ this._cachePromise = (async () => {
101
+ const map = new Map();
102
+ const providers = this.ctx.getAllServices('llm');
103
+ for (const { instance, contextId } of providers) {
104
+ if (typeof instance.listModels !== 'function')
105
+ continue;
106
+ try {
107
+ const models = await instance.listModels();
108
+ for (const m of models) {
109
+ if (!map.has(m.id))
110
+ map.set(m.id, contextId);
111
+ }
112
+ }
113
+ catch { /* skip unavailable provider */ }
114
+ }
115
+ this._cache = map;
116
+ this._cacheTime = Date.now();
117
+ this._cachePromise = null;
118
+ return map;
119
+ })();
120
+ return this._cachePromise;
121
+ }
122
+ }
123
+ //# sourceMappingURL=llm-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-router.js","sourceRoot":"","sources":["../src/llm-router.ts"],"names":[],"mappings":"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"}