@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
@@ -0,0 +1,76 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+ export interface LogEntry {
3
+ /** 进程内单调递增的稳定序号(每个 LogHub 实例独立计数)。用作下游 React/UI key 与分页 cursor。 */
4
+ seq: number;
5
+ /** 本地时区 ISO-8601 时间戳(如 `2026-05-27T09:09:16.028+01:00`)。
6
+ * 保留完整日期与偏移,便于人读与机器解析;sink 按需截取显示。 */
7
+ timestamp: string;
8
+ level: LogLevel;
9
+ scope: string;
10
+ message: string;
11
+ }
12
+ /** 把一条 LogEntry 序列化为单行文本(含结尾换行)。 */
13
+ export declare function formatLogLine(entry: LogEntry): string;
14
+ /** 反向解析单行日志;格式错乱时返回 null。与 {@link formatLogLine} 对偶。 */
15
+ export declare function parseLogLine(line: string): LogEntry | null;
16
+ /**
17
+ * 日志中枢:纯 pub-sub 通道。
18
+ *
19
+ * 设计原则:
20
+ * - **零 I/O 知识**:LogHub 不感知 stdout / 文件 / TTY / 染色等任何渲染细节
21
+ * - **零状态**:不持有任何 buffer。启动期日志暂存由 runtime 的 bootstrap-buffer 负责
22
+ * - **写一次,多处订阅**:`push` 同步广播给所有 `onEntry` 订阅者
23
+ *
24
+ * 每个 `App` 拥有自己的 LogHub(沙盒、集成测试可独立通道);
25
+ * `LogHub.default` 是进程级共享中枢,供未注入自定义 hub 的 Logger 使用。
26
+ */
27
+ export declare class LogHub {
28
+ /** 进程级默认中枢——所有未显式传 hub 的 Logger 都用它 */
29
+ static readonly default: LogHub;
30
+ private listeners;
31
+ /** 单调递增的 entry seq;首条 = 0。 */
32
+ private nextSeq;
33
+ /** 分配下一个 seq 给即将 push 的 entry(Logger 内部使用)。 */
34
+ allocSeq(): number;
35
+ onEntry(listener: (entry: LogEntry) => void): () => void;
36
+ /** 接收一条日志(Logger 内部调用) */
37
+ push(entry: LogEntry): void;
38
+ }
39
+ /**
40
+ * 日志接口 —— core 各子系统与插件持有的最小日志面。
41
+ *
42
+ * core 不绑定具体实现:宿主可经 `AppOptions.logger` 注入任意实现
43
+ * (如 pino/winston 适配对象);缺省使用 {@link DefaultLogger}(写入
44
+ * LogHub 管线,runtime 的 console/file/webui sink 监听该管线)。
45
+ * 注入自定义实现后 LogHub 管线不再由 core 写入,日志后端由注入方自理。
46
+ */
47
+ export interface Logger {
48
+ debug(message: string, ...args: unknown[]): void;
49
+ info(message: string, ...args: unknown[]): void;
50
+ warn(message: string, ...args: unknown[]): void;
51
+ error(message: string, ...args: unknown[]): void;
52
+ /** 派生带子作用域的 Logger(Context fork/createScope 时由 core 调用) */
53
+ child(scope: string): Logger;
54
+ }
55
+ /**
56
+ * 缺省 Logger 实现:按级别过滤后写入 {@link LogHub}。
57
+ */
58
+ export declare class DefaultLogger implements Logger {
59
+ private scope;
60
+ private readonly minLevel;
61
+ private readonly hub;
62
+ /**
63
+ * @param scope 日志作用域(构造前缀)
64
+ * @param minLevel 最低输出级别
65
+ * @param hub 日志中枢;缺省使用 `LogHub.default`。
66
+ * 多 App / 沙盒场景可注入独立 `new LogHub()` 实现隔离。
67
+ */
68
+ constructor(scope: string, minLevel?: LogLevel, hub?: LogHub);
69
+ child(scope: string): Logger;
70
+ debug(message: string, ...args: unknown[]): void;
71
+ info(message: string, ...args: unknown[]): void;
72
+ warn(message: string, ...args: unknown[]): void;
73
+ error(message: string, ...args: unknown[]): void;
74
+ private log;
75
+ }
76
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,QAAQ;IACvB,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;IACZ;2CACuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAoBD,oCAAoC;AACpC,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAGrD;AAED,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAkB1D;AAED;;;;;;;;;;GAUG;AACH,qBAAa,MAAM;IACjB,uCAAuC;IACvC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAgB;IAE/C,OAAO,CAAC,SAAS,CAA6C;IAC9D,8BAA8B;IAC9B,OAAO,CAAC,OAAO,CAAK;IAEpB,+CAA+C;IAC/C,QAAQ,IAAI,MAAM;IAIlB,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,MAAM,IAAI;IAOxD,0BAA0B;IAC1B,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;CAG5B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,2DAA2D;IAC3D,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,MAAM;IAWxC,OAAO,CAAC,KAAK;IAVf,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B;;;;;OAKG;gBAEO,KAAK,EAAE,MAAM,EACrB,QAAQ,GAAE,QAAiB,EAC3B,GAAG,GAAE,MAAuB;IAM9B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI5B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,OAAO,CAAC,GAAG;CAmBZ"}
package/dist/logger.js ADDED
@@ -0,0 +1,187 @@
1
+ const LEVEL_PRIORITY = {
2
+ debug: 0,
3
+ info: 1,
4
+ warn: 2,
5
+ error: 3,
6
+ };
7
+ // ════════════════════════════════════════════════════════════
8
+ // 单行日志序列化契约(format ↔ parse 对偶)
9
+ //
10
+ // 行格式:`seq|timestamp|level|scope|message\n`
11
+ // - message 内部换行被转义为字面 `\n`,保证「一行一条」可逐行解析
12
+ // - 与 LogHub 一样零 I/O 知识:纯字符串变换,不感知文件/路径/编码
13
+ //
14
+ // 唯一权威:runtime 的 file-logger 写、webui-server / cli 读历史,全部复用这一对函数,
15
+ // 避免格式契约在多个插件里各抄一份后悄然漂移。
16
+ // ════════════════════════════════════════════════════════════
17
+ /** 把一条 LogEntry 序列化为单行文本(含结尾换行)。 */
18
+ export function formatLogLine(entry) {
19
+ const safeMsg = entry.message.replace(/\r?\n/g, '\\n');
20
+ return `${entry.seq}|${entry.timestamp}|${entry.level}|${entry.scope}|${safeMsg}\n`;
21
+ }
22
+ /** 反向解析单行日志;格式错乱时返回 null。与 {@link formatLogLine} 对偶。 */
23
+ export function parseLogLine(line) {
24
+ const i1 = line.indexOf('|');
25
+ if (i1 < 0)
26
+ return null;
27
+ const i2 = line.indexOf('|', i1 + 1);
28
+ if (i2 < 0)
29
+ return null;
30
+ const i3 = line.indexOf('|', i2 + 1);
31
+ if (i3 < 0)
32
+ return null;
33
+ const i4 = line.indexOf('|', i3 + 1);
34
+ if (i4 < 0)
35
+ return null;
36
+ const seq = Number(line.slice(0, i1));
37
+ if (!Number.isFinite(seq))
38
+ return null;
39
+ return {
40
+ seq,
41
+ timestamp: line.slice(i1 + 1, i2),
42
+ level: line.slice(i2 + 1, i3),
43
+ scope: line.slice(i3 + 1, i4),
44
+ message: line.slice(i4 + 1).replace(/\\n/g, '\n'),
45
+ };
46
+ }
47
+ /**
48
+ * 日志中枢:纯 pub-sub 通道。
49
+ *
50
+ * 设计原则:
51
+ * - **零 I/O 知识**:LogHub 不感知 stdout / 文件 / TTY / 染色等任何渲染细节
52
+ * - **零状态**:不持有任何 buffer。启动期日志暂存由 runtime 的 bootstrap-buffer 负责
53
+ * - **写一次,多处订阅**:`push` 同步广播给所有 `onEntry` 订阅者
54
+ *
55
+ * 每个 `App` 拥有自己的 LogHub(沙盒、集成测试可独立通道);
56
+ * `LogHub.default` 是进程级共享中枢,供未注入自定义 hub 的 Logger 使用。
57
+ */
58
+ export class LogHub {
59
+ /** 进程级默认中枢——所有未显式传 hub 的 Logger 都用它 */
60
+ static default = new LogHub();
61
+ listeners = new Set();
62
+ /** 单调递增的 entry seq;首条 = 0。 */
63
+ nextSeq = 0;
64
+ /** 分配下一个 seq 给即将 push 的 entry(Logger 内部使用)。 */
65
+ allocSeq() {
66
+ return this.nextSeq++;
67
+ }
68
+ onEntry(listener) {
69
+ this.listeners.add(listener);
70
+ return () => {
71
+ this.listeners.delete(listener);
72
+ };
73
+ }
74
+ /** 接收一条日志(Logger 内部调用) */
75
+ push(entry) {
76
+ for (const fn of this.listeners)
77
+ fn(entry);
78
+ }
79
+ }
80
+ /**
81
+ * 缺省 Logger 实现:按级别过滤后写入 {@link LogHub}。
82
+ */
83
+ export class DefaultLogger {
84
+ scope;
85
+ minLevel;
86
+ hub;
87
+ /**
88
+ * @param scope 日志作用域(构造前缀)
89
+ * @param minLevel 最低输出级别
90
+ * @param hub 日志中枢;缺省使用 `LogHub.default`。
91
+ * 多 App / 沙盒场景可注入独立 `new LogHub()` 实现隔离。
92
+ */
93
+ constructor(scope, minLevel = 'info', hub = LogHub.default) {
94
+ this.scope = scope;
95
+ this.minLevel = minLevel;
96
+ this.hub = hub;
97
+ }
98
+ child(scope) {
99
+ return new DefaultLogger(`${this.scope}:${scope}`, this.minLevel, this.hub);
100
+ }
101
+ debug(message, ...args) {
102
+ this.log('debug', message, ...args);
103
+ }
104
+ info(message, ...args) {
105
+ this.log('info', message, ...args);
106
+ }
107
+ warn(message, ...args) {
108
+ this.log('warn', message, ...args);
109
+ }
110
+ error(message, ...args) {
111
+ this.log('error', message, ...args);
112
+ }
113
+ log(level, message, ...args) {
114
+ if (LEVEL_PRIORITY[level] < LEVEL_PRIORITY[this.minLevel])
115
+ return;
116
+ // 本地时区 ISO 时间戳(YYYY-MM-DDTHH:mm:ss.sss±HH:mm)——信息保真且贴近人读。
117
+ // sink(console / CLI / WebUI)按显示需求自行截取,不在源头丢日期。
118
+ const timestamp = formatLocalIso(new Date());
119
+ // 将额外参数(错误对象 / 上下文等)序列化并拼到 message 末尾,
120
+ // 避免 sink 只读 message 时丢失错误细节。**保持运行时中立**:只用纯 ES
121
+ // 原语,不依赖 node:util / window 等任何宿主 API。
122
+ const tail = args.length === 0 ? '' : ` ${args.map(stringifyArg).join(' ')}`;
123
+ const entry = {
124
+ seq: this.hub.allocSeq(),
125
+ timestamp,
126
+ level,
127
+ scope: this.scope,
128
+ message: `${message}${tail}`,
129
+ };
130
+ this.hub.push(entry);
131
+ }
132
+ }
133
+ /**
134
+ * 把 logger.xxx(message, ...args) 里的 args 元素渲染成字符串。
135
+ *
136
+ * 设计目标:**零运行时依赖**——只用 ECMAScript 标准原语,Node/Deno/Bun/Browser
137
+ * 都能跑。需要 `util.inspect` 级别的深度对象渲染时,由外层 sink 自行处理
138
+ * (sink 可订阅 LogHub 后用宿主 API 二次格式化)。
139
+ *
140
+ * - `Error` / 任何带 `stack` 的对象:尽量打印 stack;否则退化为 name + message
141
+ * - `string`:原样
142
+ * - `null` / `undefined` / 原始值:`String(v)`
143
+ * - 普通对象 / 数组:尝试 `JSON.stringify`,遇到循环引用或不可序列化值时退化
144
+ * 为 `String(v)`(一般得到 `[object Object]`,但至少不会抛)
145
+ */
146
+ /**
147
+ * 把 `Date` 渲染成本地时区 ISO-8601(带显式偏移),如:
148
+ * `2026-05-27T09:09:16.028+01:00` / `2026-05-27T00:09:16.028Z`(UTC)
149
+ *
150
+ * 设计:日志默认以"运维所在地"读,避免把伦敦同事的 09:00 印成 08:00;
151
+ * 偏移段保证仍是合法 ISO-8601,下游解析器 (`new Date(...)`) 也能精确还原。
152
+ * 偏移 0 时输出 `Z` 以贴近通用习惯。零运行时依赖。
153
+ */
154
+ function formatLocalIso(d) {
155
+ const pad = (n, w = 2) => String(n).padStart(w, '0');
156
+ const offMin = -d.getTimezoneOffset();
157
+ const sign = offMin >= 0 ? '+' : '-';
158
+ const abs = Math.abs(offMin);
159
+ const offStr = offMin === 0 ? 'Z' : `${sign}${pad(Math.floor(abs / 60))}:${pad(abs % 60)}`;
160
+ return (`${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +
161
+ `T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${pad(d.getMilliseconds(), 3)}` +
162
+ offStr);
163
+ }
164
+ function stringifyArg(value) {
165
+ if (typeof value === 'string')
166
+ return value;
167
+ if (value === null || value === undefined)
168
+ return String(value);
169
+ if (value instanceof Error) {
170
+ const head = `${value.name}: ${value.message}`;
171
+ return value.stack ? value.stack : head;
172
+ }
173
+ // 鸭子类型:异步链路里 Error 可能跨 realm,instanceof 失效;只要含 stack 就尽量打 stack
174
+ if (typeof value === 'object' && typeof value.stack === 'string') {
175
+ return value.stack;
176
+ }
177
+ if (typeof value === 'object') {
178
+ try {
179
+ return JSON.stringify(value);
180
+ }
181
+ catch {
182
+ return String(value);
183
+ }
184
+ }
185
+ return String(value);
186
+ }
187
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * 最小化 marketplace HTTP 客户端,专供 init 向导/全新工程的 bootstrap 使用。
3
+ *
4
+ * 与 plugin-marketplace-client 的关系:
5
+ * - core 不依赖任何 plugin 包,因此这里独立实现一份"够用就好"的 HTTP fetch + 解压。
6
+ * - 不做签名校验(仅 sha256 对比 tarball.size/sha256,签名留给运行时插件)。
7
+ * - 安装目标固定为 packages/<dir>/,与 plugin-marketplace-client 的 install-pipeline 对齐。
8
+ *
9
+ * 路由与 plugin-marketplace-client/src/protocol.ts 的 ROUTES 保持一致:
10
+ * GET /v1/plugins
11
+ * GET /v1/plugins/:name/:version/tarball
12
+ */
13
+ export interface BootstrapIndexEntry {
14
+ name: string;
15
+ latest: string;
16
+ versions: string[];
17
+ displayName?: string;
18
+ description?: string;
19
+ keywords?: string[];
20
+ provides?: string[];
21
+ inject?: string[];
22
+ }
23
+ export interface BootstrapListResponse {
24
+ protocol: string;
25
+ total: number;
26
+ items: BootstrapIndexEntry[];
27
+ }
28
+ /** 把 manifest.name 转成 packages/<dir> 的目录名(与 install-pipeline.pluginDirName 对齐)。 */
29
+ export declare function pluginDirName(manifestName: string): string;
30
+ export declare class MarketplaceBootstrap {
31
+ readonly baseUrl: string;
32
+ readonly timeoutMs: number;
33
+ constructor(baseUrl: string, timeoutMs?: number);
34
+ private get base();
35
+ /** 拉取插件列表 */
36
+ listPlugins(): Promise<BootstrapIndexEntry[]>;
37
+ /** 下载指定版本 tarball */
38
+ fetchTarball(name: string, version: string): Promise<Buffer>;
39
+ /**
40
+ * 下载 + 校验 + 解压到 packages/<dir>/。
41
+ * 调用方须自行决定是否在所有插件下载完毕后跑一次 pnpm install。
42
+ */
43
+ installToPackages(name: string, version: string, opts: {
44
+ packagesDir: string;
45
+ cacheDir?: string;
46
+ expectedSha256?: string;
47
+ }): Promise<{
48
+ pluginDir: string;
49
+ tarballPath?: string;
50
+ }>;
51
+ }
52
+ /** 在项目根触发 pnpm install(让 workspace 重新解析 deps) */
53
+ export declare function runRootPnpmInstall(projectRoot: string, timeoutMs?: number): Promise<void>;
54
+ //# sourceMappingURL=marketplace-bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplace-bootstrap.d.ts","sourceRoot":"","sources":["../src/marketplace-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAWH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,qBAAa,oBAAoB;aAEb,OAAO,EAAE,MAAM;aACf,SAAS,EAAE,MAAM;gBADjB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAe;IAG5C,OAAO,KAAK,IAAI,GAAuD;IAEvE,aAAa;IACP,WAAW,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAgBnD,qBAAqB;IACf,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAalE;;;OAGG;IACG,iBAAiB,CACrB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GACA,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CA2CxD;AAMD,iDAAiD;AACjD,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,SAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhG"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * 最小化 marketplace HTTP 客户端,专供 init 向导/全新工程的 bootstrap 使用。
3
+ *
4
+ * 与 plugin-marketplace-client 的关系:
5
+ * - core 不依赖任何 plugin 包,因此这里独立实现一份"够用就好"的 HTTP fetch + 解压。
6
+ * - 不做签名校验(仅 sha256 对比 tarball.size/sha256,签名留给运行时插件)。
7
+ * - 安装目标固定为 packages/<dir>/,与 plugin-marketplace-client 的 install-pipeline 对齐。
8
+ *
9
+ * 路由与 plugin-marketplace-client/src/protocol.ts 的 ROUTES 保持一致:
10
+ * GET /v1/plugins
11
+ * GET /v1/plugins/:name/:version/tarball
12
+ */
13
+ import { execFile } from 'node:child_process';
14
+ import { createHash } from 'node:crypto';
15
+ import { existsSync } from 'node:fs';
16
+ import { mkdir, rm, writeFile } from 'node:fs/promises';
17
+ import { resolve } from 'node:path';
18
+ import { promisify } from 'node:util';
19
+ const execFileAsync = promisify(execFile);
20
+ /** 把 manifest.name 转成 packages/<dir> 的目录名(与 install-pipeline.pluginDirName 对齐)。 */
21
+ export function pluginDirName(manifestName) {
22
+ if (manifestName.startsWith('@')) {
23
+ const slash = manifestName.indexOf('/');
24
+ return slash > 0 ? manifestName.slice(slash + 1) : manifestName;
25
+ }
26
+ return manifestName;
27
+ }
28
+ export class MarketplaceBootstrap {
29
+ baseUrl;
30
+ timeoutMs;
31
+ constructor(baseUrl, timeoutMs = 15_000) {
32
+ this.baseUrl = baseUrl;
33
+ this.timeoutMs = timeoutMs;
34
+ }
35
+ get base() { return this.baseUrl.replace(/\/+$/, ''); }
36
+ /** 拉取插件列表 */
37
+ async listPlugins() {
38
+ const ac = new AbortController();
39
+ const timer = setTimeout(() => ac.abort(), this.timeoutMs);
40
+ try {
41
+ const res = await fetch(this.base + '/v1/plugins', {
42
+ signal: ac.signal,
43
+ headers: { accept: 'application/json' },
44
+ });
45
+ if (!res.ok)
46
+ throw new Error(`registry list ${res.status}`);
47
+ const data = (await res.json());
48
+ return data.items ?? [];
49
+ }
50
+ finally {
51
+ clearTimeout(timer);
52
+ }
53
+ }
54
+ /** 下载指定版本 tarball */
55
+ async fetchTarball(name, version) {
56
+ const ac = new AbortController();
57
+ const timer = setTimeout(() => ac.abort(), this.timeoutMs * 4);
58
+ try {
59
+ const url = this.base + `/v1/plugins/${encodeURIComponent(name)}/${encodeURIComponent(version)}/tarball`;
60
+ const res = await fetch(url, { signal: ac.signal });
61
+ if (!res.ok)
62
+ throw new Error(`tarball ${name}@${version} ${res.status}`);
63
+ return Buffer.from(await res.arrayBuffer());
64
+ }
65
+ finally {
66
+ clearTimeout(timer);
67
+ }
68
+ }
69
+ /**
70
+ * 下载 + 校验 + 解压到 packages/<dir>/。
71
+ * 调用方须自行决定是否在所有插件下载完毕后跑一次 pnpm install。
72
+ */
73
+ async installToPackages(name, version, opts) {
74
+ const dir = pluginDirName(name);
75
+ const finalDir = resolve(opts.packagesDir, dir);
76
+ if (existsSync(finalDir)) {
77
+ throw new Error(`packages/${dir}/ 已存在,拒绝覆盖`);
78
+ }
79
+ const tarball = await this.fetchTarball(name, version);
80
+ if (opts.expectedSha256) {
81
+ const got = sha256Hex(tarball);
82
+ if (got !== opts.expectedSha256) {
83
+ throw new Error(`sha256 mismatch: expected ${opts.expectedSha256}, got ${got}`);
84
+ }
85
+ }
86
+ let tarballPath;
87
+ if (opts.cacheDir) {
88
+ await mkdir(opts.cacheDir, { recursive: true });
89
+ tarballPath = resolve(opts.cacheDir, `${name.replace(/[\/@]/g, '-')}-${version}.tgz`);
90
+ await writeFile(tarballPath, tarball);
91
+ }
92
+ else {
93
+ // 没有 cacheDir 也得有个临时落点供 system tar 读取
94
+ tarballPath = resolve(opts.packagesDir, `.aalis-bootstrap-${Date.now()}.tgz`);
95
+ await writeFile(tarballPath, tarball);
96
+ }
97
+ await mkdir(finalDir, { recursive: true });
98
+ try {
99
+ await execFileAsync('tar', ['-xzf', tarballPath, '-C', finalDir, '--strip-components=1'], {
100
+ timeout: 60_000,
101
+ maxBuffer: 128 * 1024 * 1024,
102
+ });
103
+ }
104
+ catch (e) {
105
+ await rm(finalDir, { recursive: true, force: true });
106
+ throw e;
107
+ }
108
+ finally {
109
+ // 临时 tarball 用完即删
110
+ if (!opts.cacheDir && tarballPath && existsSync(tarballPath)) {
111
+ try {
112
+ await rm(tarballPath, { force: true });
113
+ }
114
+ catch { /* ignore */ }
115
+ }
116
+ }
117
+ return { pluginDir: finalDir, tarballPath: opts.cacheDir ? tarballPath : undefined };
118
+ }
119
+ }
120
+ function sha256Hex(data) {
121
+ return createHash('sha256').update(data).digest('hex');
122
+ }
123
+ /** 在项目根触发 pnpm install(让 workspace 重新解析 deps) */
124
+ export async function runRootPnpmInstall(projectRoot, timeoutMs = 180_000) {
125
+ await execFileAsync('pnpm', ['install', '--silent'], {
126
+ cwd: projectRoot,
127
+ timeout: timeoutMs,
128
+ maxBuffer: 32 * 1024 * 1024,
129
+ env: process.env,
130
+ });
131
+ }
132
+ //# sourceMappingURL=marketplace-bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplace-bootstrap.js","sourceRoot":"","sources":["../src/marketplace-bootstrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { Logger } from './logger.js';
2
+ /** Mixin 条目记录 */
3
+ export interface MixinEntry {
4
+ service: string;
5
+ methods: string[];
6
+ contextId: string;
7
+ }
8
+ /** 承载 mixin 方法的目标 prototype(一般是 Context.prototype) */
9
+ type MixinTarget = object;
10
+ /**
11
+ * Mixin 注册表(进程级)
12
+ *
13
+ * 职责:
14
+ * - 维护 mixin 条目列表(哪些服务的哪些方法被代理到了 target prototype 上)
15
+ * - 在 target prototype 上安装 getter,按 `this` 运行时解析服务实例并 bind
16
+ * - `dispose()` 时如该方法已无其他 mixin 引用则清除
17
+ *
18
+ * 设计:静态类而非单例——因为 Context.prototype 是进程级共享资源,
19
+ * 不存在"每实例一个 registry"的语义;集中成静态便于测试和管理。
20
+ */
21
+ export declare class MixinRegistry {
22
+ private static _entries;
23
+ /**
24
+ * 注册 mixin:把 `serviceName` 指代的服务实例的若干方法
25
+ * 代理到 `target` prototype 上。
26
+ *
27
+ * @returns 卸载函数
28
+ */
29
+ static register(target: MixinTarget, serviceName: string, methods: string[], contextId: string, logger: Logger): () => void;
30
+ /** 当前所有 mixin 注册信息(快照) */
31
+ static list(): MixinEntry[];
32
+ }
33
+ export {};
34
+ //# sourceMappingURL=mixin-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mixin-registry.d.ts","sourceRoot":"","sources":["../src/mixin-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,iBAAiB;AACjB,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAOD,sDAAsD;AACtD,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAoB;IAE3C;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CACb,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,MAAM,IAAI;IAoCb,0BAA0B;IAC1B,MAAM,CAAC,IAAI,IAAI,UAAU,EAAE;CAG5B"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Mixin 注册表(进程级)
3
+ *
4
+ * 职责:
5
+ * - 维护 mixin 条目列表(哪些服务的哪些方法被代理到了 target prototype 上)
6
+ * - 在 target prototype 上安装 getter,按 `this` 运行时解析服务实例并 bind
7
+ * - `dispose()` 时如该方法已无其他 mixin 引用则清除
8
+ *
9
+ * 设计:静态类而非单例——因为 Context.prototype 是进程级共享资源,
10
+ * 不存在"每实例一个 registry"的语义;集中成静态便于测试和管理。
11
+ */
12
+ export class MixinRegistry {
13
+ static _entries = [];
14
+ /**
15
+ * 注册 mixin:把 `serviceName` 指代的服务实例的若干方法
16
+ * 代理到 `target` prototype 上。
17
+ *
18
+ * @returns 卸载函数
19
+ */
20
+ static register(target, serviceName, methods, contextId, logger) {
21
+ const entry = { service: serviceName, methods, contextId };
22
+ MixinRegistry._entries.push(entry);
23
+ for (const method of methods) {
24
+ if (method in target) {
25
+ logger.warn(`mixin: 方法 "${method}" 已存在于 target,跳过`);
26
+ continue;
27
+ }
28
+ Object.defineProperty(target, method, {
29
+ configurable: true,
30
+ enumerable: false,
31
+ get() {
32
+ const svc = this.getService(serviceName);
33
+ if (!svc)
34
+ return undefined;
35
+ const val = svc[method];
36
+ if (typeof val === 'function')
37
+ return val.bind(svc);
38
+ return val;
39
+ },
40
+ });
41
+ }
42
+ logger.debug(`mixin: ${methods.join(', ')} → ${serviceName}`);
43
+ return () => {
44
+ const idx = MixinRegistry._entries.indexOf(entry);
45
+ if (idx >= 0)
46
+ MixinRegistry._entries.splice(idx, 1);
47
+ for (const method of methods) {
48
+ const stillUsed = MixinRegistry._entries.some(e => e.methods.includes(method));
49
+ if (!stillUsed) {
50
+ delete target[method];
51
+ }
52
+ }
53
+ };
54
+ }
55
+ /** 当前所有 mixin 注册信息(快照) */
56
+ static list() {
57
+ return MixinRegistry._entries.map(e => ({ ...e }));
58
+ }
59
+ }
60
+ //# sourceMappingURL=mixin-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mixin-registry.js","sourceRoot":"","sources":["../src/mixin-registry.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,aAAa;IAChB,MAAM,CAAC,QAAQ,GAAiB,EAAE,CAAC;IAE3C;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CACb,MAAmB,EACnB,WAAmB,EACnB,OAAiB,EACjB,SAAiB,EACjB,MAAc;QAEd,MAAM,KAAK,GAAe,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QACvE,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEnC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;gBACrB,MAAM,CAAC,IAAI,CAAC,cAAc,MAAM,kBAAkB,CAAC,CAAC;gBACpD,SAAS;YACX,CAAC;YACD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE;gBACpC,YAAY,EAAE,IAAI;gBAClB,UAAU,EAAE,KAAK;gBACjB,GAAG;oBACD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAA0B,WAAW,CAAC,CAAC;oBAClE,IAAI,CAAC,GAAG;wBAAE,OAAO,SAAS,CAAC;oBAC3B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;oBACxB,IAAI,OAAO,GAAG,KAAK,UAAU;wBAAE,OAAQ,GAAuC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACzF,OAAO,GAAG,CAAC;gBACb,CAAC;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,WAAW,EAAE,CAAC,CAAC;QAE9D,OAAO,GAAG,EAAE;YACV,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,GAAG,IAAI,CAAC;gBAAE,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACpD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/E,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,OAAQ,MAAkC,CAAC,MAAM,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAED,0BAA0B;IAC1B,MAAM,CAAC,IAAI;QACT,OAAO,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC"}
@@ -0,0 +1,22 @@
1
+ export interface ModelRef {
2
+ /** provider 的 contextId(instanceId)。未指定则 router 走"按 model id 在所有 provider listModels 中查找" */
3
+ provider?: string;
4
+ /** 模型 id;未指定则 provider 用其默认模型 */
5
+ model?: string;
6
+ }
7
+ /**
8
+ * 解析复合 model 引用字符串。
9
+ *
10
+ * - `"@aalis/plugin-openai::gpt-4o"` → `{ provider: "@aalis/plugin-openai", model: "gpt-4o" }`
11
+ * - `"gpt-4o"` (无 `::`)→ `{ model: "gpt-4o" }`(旧风格,仅 model)
12
+ * - `""` / null / undefined → `{}`(让调用方走默认 provider/model)
13
+ *
14
+ * 注意:分隔符使用 `::` 而非 `:`,因为 model id 中允许包含 `:`(如 ollama 的 `qwen2.5:7b`)。
15
+ */
16
+ export declare function parseModelRef(value: string | null | undefined): ModelRef;
17
+ /**
18
+ * 将 (provider, model) 编码为复合 string,用于持久化或 UI 选项 value。
19
+ * 任一方缺失时不输出分隔符(避免产生 `::xxx` 或 `xxx::` 这种不规整形式)。
20
+ */
21
+ export declare function formatModelRef(ref: ModelRef): string;
22
+ //# sourceMappingURL=model-ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-ref.d.ts","sourceRoot":"","sources":["../src/model-ref.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,QAAQ;IACvB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,CAUxE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAGpD"}