@zooique/memora 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 (239) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -0
  3. package/dist/agent/agent.d.ts +343 -0
  4. package/dist/agent/agent.d.ts.map +1 -0
  5. package/dist/agent/agent.js +893 -0
  6. package/dist/agent/agent.js.map +1 -0
  7. package/dist/agent/assembler.d.ts +77 -0
  8. package/dist/agent/assembler.d.ts.map +1 -0
  9. package/dist/agent/assembler.js +115 -0
  10. package/dist/agent/assembler.js.map +1 -0
  11. package/dist/agent/builtinToolHandlers.d.ts +96 -0
  12. package/dist/agent/builtinToolHandlers.d.ts.map +1 -0
  13. package/dist/agent/builtinToolHandlers.js +388 -0
  14. package/dist/agent/builtinToolHandlers.js.map +1 -0
  15. package/dist/agent/builtinTools.d.ts +35 -0
  16. package/dist/agent/builtinTools.d.ts.map +1 -0
  17. package/dist/agent/builtinTools.js +75 -0
  18. package/dist/agent/builtinTools.js.map +1 -0
  19. package/dist/agent/constants.d.ts +67 -0
  20. package/dist/agent/constants.d.ts.map +1 -0
  21. package/dist/agent/constants.js +67 -0
  22. package/dist/agent/constants.js.map +1 -0
  23. package/dist/agent/contextManager.d.ts +130 -0
  24. package/dist/agent/contextManager.d.ts.map +1 -0
  25. package/dist/agent/contextManager.js +287 -0
  26. package/dist/agent/contextManager.js.map +1 -0
  27. package/dist/agent/loop.d.ts +288 -0
  28. package/dist/agent/loop.d.ts.map +1 -0
  29. package/dist/agent/loop.js +756 -0
  30. package/dist/agent/loop.js.map +1 -0
  31. package/dist/agent/managers/autoConfigRefiner.d.ts +39 -0
  32. package/dist/agent/managers/autoConfigRefiner.d.ts.map +1 -0
  33. package/dist/agent/managers/autoConfigRefiner.js +150 -0
  34. package/dist/agent/managers/autoConfigRefiner.js.map +1 -0
  35. package/dist/agent/managers/configManager.d.ts +114 -0
  36. package/dist/agent/managers/configManager.d.ts.map +1 -0
  37. package/dist/agent/managers/configManager.js +186 -0
  38. package/dist/agent/managers/configManager.js.map +1 -0
  39. package/dist/agent/managers/insightExtractor.d.ts +141 -0
  40. package/dist/agent/managers/insightExtractor.d.ts.map +1 -0
  41. package/dist/agent/managers/insightExtractor.js +420 -0
  42. package/dist/agent/managers/insightExtractor.js.map +1 -0
  43. package/dist/agent/managers/memoryAdvisor.d.ts +96 -0
  44. package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -0
  45. package/dist/agent/managers/memoryAdvisor.js +198 -0
  46. package/dist/agent/managers/memoryAdvisor.js.map +1 -0
  47. package/dist/agent/managers/memoryInspector.d.ts +231 -0
  48. package/dist/agent/managers/memoryInspector.d.ts.map +1 -0
  49. package/dist/agent/managers/memoryInspector.js +327 -0
  50. package/dist/agent/managers/memoryInspector.js.map +1 -0
  51. package/dist/agent/managers/sessionManager.d.ts +89 -0
  52. package/dist/agent/managers/sessionManager.d.ts.map +1 -0
  53. package/dist/agent/managers/sessionManager.js +178 -0
  54. package/dist/agent/managers/sessionManager.js.map +1 -0
  55. package/dist/agent/managers/userFactExtractor.d.ts +25 -0
  56. package/dist/agent/managers/userFactExtractor.d.ts.map +1 -0
  57. package/dist/agent/managers/userFactExtractor.js +81 -0
  58. package/dist/agent/managers/userFactExtractor.js.map +1 -0
  59. package/dist/agent/managers/workProjection.d.ts +117 -0
  60. package/dist/agent/managers/workProjection.d.ts.map +1 -0
  61. package/dist/agent/managers/workProjection.js +290 -0
  62. package/dist/agent/managers/workProjection.js.map +1 -0
  63. package/dist/agent/messageHistory.d.ts +157 -0
  64. package/dist/agent/messageHistory.d.ts.map +1 -0
  65. package/dist/agent/messageHistory.js +288 -0
  66. package/dist/agent/messageHistory.js.map +1 -0
  67. package/dist/agent/toolExecutor.d.ts +137 -0
  68. package/dist/agent/toolExecutor.d.ts.map +1 -0
  69. package/dist/agent/toolExecutor.js +209 -0
  70. package/dist/agent/toolExecutor.js.map +1 -0
  71. package/dist/agent/tracer.d.ts +122 -0
  72. package/dist/agent/tracer.d.ts.map +1 -0
  73. package/dist/agent/tracer.js +64 -0
  74. package/dist/agent/tracer.js.map +1 -0
  75. package/dist/agent/types.d.ts +98 -0
  76. package/dist/agent/types.d.ts.map +1 -0
  77. package/dist/agent/types.js +19 -0
  78. package/dist/agent/types.js.map +1 -0
  79. package/dist/config/loader.d.ts +229 -0
  80. package/dist/config/loader.d.ts.map +1 -0
  81. package/dist/config/loader.js +194 -0
  82. package/dist/config/loader.js.map +1 -0
  83. package/dist/eval/evalTypes.d.ts +118 -0
  84. package/dist/eval/evalTypes.d.ts.map +1 -0
  85. package/dist/eval/evalTypes.js +102 -0
  86. package/dist/eval/evalTypes.js.map +1 -0
  87. package/dist/index.d.ts +61 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +44 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/llm/embedding.d.ts +62 -0
  92. package/dist/llm/embedding.d.ts.map +1 -0
  93. package/dist/llm/embedding.js +162 -0
  94. package/dist/llm/embedding.js.map +1 -0
  95. package/dist/llm/factory.d.ts +39 -0
  96. package/dist/llm/factory.d.ts.map +1 -0
  97. package/dist/llm/factory.js +108 -0
  98. package/dist/llm/factory.js.map +1 -0
  99. package/dist/llm/openaiCompatible.d.ts +63 -0
  100. package/dist/llm/openaiCompatible.d.ts.map +1 -0
  101. package/dist/llm/openaiCompatible.js +340 -0
  102. package/dist/llm/openaiCompatible.js.map +1 -0
  103. package/dist/llm/provider.d.ts +91 -0
  104. package/dist/llm/provider.d.ts.map +1 -0
  105. package/dist/llm/provider.js +14 -0
  106. package/dist/llm/provider.js.map +1 -0
  107. package/dist/llm/types.d.ts +25 -0
  108. package/dist/llm/types.d.ts.map +1 -0
  109. package/dist/llm/types.js +7 -0
  110. package/dist/llm/types.js.map +1 -0
  111. package/dist/logging/logger.d.ts +39 -0
  112. package/dist/logging/logger.d.ts.map +1 -0
  113. package/dist/logging/logger.js +279 -0
  114. package/dist/logging/logger.js.map +1 -0
  115. package/dist/logging/loggerInterface.d.ts +33 -0
  116. package/dist/logging/loggerInterface.d.ts.map +1 -0
  117. package/dist/logging/loggerInterface.js +2 -0
  118. package/dist/logging/loggerInterface.js.map +1 -0
  119. package/dist/memory/inMemoryRelationStore.d.ts +51 -0
  120. package/dist/memory/inMemoryRelationStore.d.ts.map +1 -0
  121. package/dist/memory/inMemoryRelationStore.js +65 -0
  122. package/dist/memory/inMemoryRelationStore.js.map +1 -0
  123. package/dist/memory/inMemoryStorage.d.ts +97 -0
  124. package/dist/memory/inMemoryStorage.d.ts.map +1 -0
  125. package/dist/memory/inMemoryStorage.js +177 -0
  126. package/dist/memory/inMemoryStorage.js.map +1 -0
  127. package/dist/memory/loader.d.ts +49 -0
  128. package/dist/memory/loader.d.ts.map +1 -0
  129. package/dist/memory/loader.js +93 -0
  130. package/dist/memory/loader.js.map +1 -0
  131. package/dist/memory/projectManager.d.ts +182 -0
  132. package/dist/memory/projectManager.d.ts.map +1 -0
  133. package/dist/memory/projectManager.js +441 -0
  134. package/dist/memory/projectManager.js.map +1 -0
  135. package/dist/memory/recall.d.ts +77 -0
  136. package/dist/memory/recall.d.ts.map +1 -0
  137. package/dist/memory/recall.js +147 -0
  138. package/dist/memory/recall.js.map +1 -0
  139. package/dist/memory/relationStore.d.ts +78 -0
  140. package/dist/memory/relationStore.d.ts.map +1 -0
  141. package/dist/memory/relationStore.js +2 -0
  142. package/dist/memory/relationStore.js.map +1 -0
  143. package/dist/memory/sessionStore.d.ts +84 -0
  144. package/dist/memory/sessionStore.d.ts.map +1 -0
  145. package/dist/memory/sessionStore.js +2 -0
  146. package/dist/memory/sessionStore.js.map +1 -0
  147. package/dist/memory/storageInterface.d.ts +107 -0
  148. package/dist/memory/storageInterface.d.ts.map +1 -0
  149. package/dist/memory/storageInterface.js +2 -0
  150. package/dist/memory/storageInterface.js.map +1 -0
  151. package/dist/memory/store.d.ts +50 -0
  152. package/dist/memory/store.d.ts.map +1 -0
  153. package/dist/memory/store.js +160 -0
  154. package/dist/memory/store.js.map +1 -0
  155. package/dist/memory/types.d.ts +189 -0
  156. package/dist/memory/types.d.ts.map +1 -0
  157. package/dist/memory/types.js +230 -0
  158. package/dist/memory/types.js.map +1 -0
  159. package/dist/memory/userProfile.d.ts +156 -0
  160. package/dist/memory/userProfile.d.ts.map +1 -0
  161. package/dist/memory/userProfile.js +315 -0
  162. package/dist/memory/userProfile.js.map +1 -0
  163. package/dist/memory/vectorStore.d.ts +75 -0
  164. package/dist/memory/vectorStore.d.ts.map +1 -0
  165. package/dist/memory/vectorStore.js +144 -0
  166. package/dist/memory/vectorStore.js.map +1 -0
  167. package/dist/persona/personaManager.d.ts +121 -0
  168. package/dist/persona/personaManager.d.ts.map +1 -0
  169. package/dist/persona/personaManager.js +349 -0
  170. package/dist/persona/personaManager.js.map +1 -0
  171. package/dist/persona/types.d.ts +32 -0
  172. package/dist/persona/types.d.ts.map +1 -0
  173. package/dist/persona/types.js +5 -0
  174. package/dist/persona/types.js.map +1 -0
  175. package/dist/security/pathGuard.d.ts +121 -0
  176. package/dist/security/pathGuard.d.ts.map +1 -0
  177. package/dist/security/pathGuard.js +276 -0
  178. package/dist/security/pathGuard.js.map +1 -0
  179. package/dist/skill/skillManager.d.ts +82 -0
  180. package/dist/skill/skillManager.d.ts.map +1 -0
  181. package/dist/skill/skillManager.js +198 -0
  182. package/dist/skill/skillManager.js.map +1 -0
  183. package/dist/skill/types.d.ts +28 -0
  184. package/dist/skill/types.d.ts.map +1 -0
  185. package/dist/skill/types.js +5 -0
  186. package/dist/skill/types.js.map +1 -0
  187. package/dist/utils/errors.d.ts +86 -0
  188. package/dist/utils/errors.d.ts.map +1 -0
  189. package/dist/utils/errors.js +143 -0
  190. package/dist/utils/errors.js.map +1 -0
  191. package/dist/utils/eventEmitter.d.ts +87 -0
  192. package/dist/utils/eventEmitter.d.ts.map +1 -0
  193. package/dist/utils/eventEmitter.js +79 -0
  194. package/dist/utils/eventEmitter.js.map +1 -0
  195. package/dist/utils/frontmatter.d.ts +24 -0
  196. package/dist/utils/frontmatter.d.ts.map +1 -0
  197. package/dist/utils/frontmatter.js +44 -0
  198. package/dist/utils/frontmatter.js.map +1 -0
  199. package/dist/utils/json.d.ts +20 -0
  200. package/dist/utils/json.d.ts.map +1 -0
  201. package/dist/utils/json.js +65 -0
  202. package/dist/utils/json.js.map +1 -0
  203. package/dist/utils/loggerHolder.d.ts +37 -0
  204. package/dist/utils/loggerHolder.d.ts.map +1 -0
  205. package/dist/utils/loggerHolder.js +49 -0
  206. package/dist/utils/loggerHolder.js.map +1 -0
  207. package/dist/utils/math.d.ts +5 -0
  208. package/dist/utils/math.d.ts.map +1 -0
  209. package/dist/utils/math.js +19 -0
  210. package/dist/utils/math.js.map +1 -0
  211. package/dist/utils/path.d.ts +28 -0
  212. package/dist/utils/path.d.ts.map +1 -0
  213. package/dist/utils/path.js +33 -0
  214. package/dist/utils/path.js.map +1 -0
  215. package/dist/utils/safeTimer.d.ts +26 -0
  216. package/dist/utils/safeTimer.d.ts.map +1 -0
  217. package/dist/utils/safeTimer.js +49 -0
  218. package/dist/utils/safeTimer.js.map +1 -0
  219. package/dist/utils/scanner.d.ts +54 -0
  220. package/dist/utils/scanner.d.ts.map +1 -0
  221. package/dist/utils/scanner.js +115 -0
  222. package/dist/utils/scanner.js.map +1 -0
  223. package/dist/utils/segmenter.d.ts +30 -0
  224. package/dist/utils/segmenter.d.ts.map +1 -0
  225. package/dist/utils/segmenter.js +80 -0
  226. package/dist/utils/segmenter.js.map +1 -0
  227. package/dist/utils/strings.d.ts +18 -0
  228. package/dist/utils/strings.d.ts.map +1 -0
  229. package/dist/utils/strings.js +25 -0
  230. package/dist/utils/strings.js.map +1 -0
  231. package/dist/utils/time.d.ts +23 -0
  232. package/dist/utils/time.d.ts.map +1 -0
  233. package/dist/utils/time.js +31 -0
  234. package/dist/utils/time.js.map +1 -0
  235. package/dist/utils/toError.d.ts +13 -0
  236. package/dist/utils/toError.d.ts.map +1 -0
  237. package/dist/utils/toError.js +22 -0
  238. package/dist/utils/toError.js.map +1 -0
  239. package/package.json +73 -0
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Embedding Provider — 调用 OpenAI 兼容的 /embeddings 端点
3
+ *
4
+ * M-206:语义检索的核心能力
5
+ * - 将文本转为向量(embedding)
6
+ * - 支持批量嵌入(减少 API 调用次数)
7
+ * - 向量维度由模型决定(如 text-embedding-3-small: 1536 维)
8
+ *
9
+ * 设计原则:
10
+ * - 复用 OpenAI 兼容协议(与 chat 共用 baseUrl/apiKey)
11
+ * - 0 新 npm 依赖(纯 fetch 调用)
12
+ * - 缓存机制:相同文本不重复调用 API
13
+ *
14
+ * 详见 ADR-003 · LLM 适配层使用 OpenAI Chat Completions 兼容协议
15
+ */
16
+ import { logger } from '../logging/logger.js';
17
+ import { networkError, configError, toError } from '../utils/errors.js';
18
+ /**
19
+ * Embedding Provider
20
+ *
21
+ * 调用 /embeddings 端点将文本转为向量
22
+ * 支持批量嵌入和本地缓存
23
+ */
24
+ export class EmbeddingProvider {
25
+ config;
26
+ /** 缓存最大条目数(LRU 上限,防止无界增长导致内存泄漏) */
27
+ static CACHE_MAX_SIZE = 1000;
28
+ /** 本地缓存:text → vector(LRU,Map 迭代顺序 = 最近访问顺序) */
29
+ cache = new Map();
30
+ constructor(config) {
31
+ this.config = config;
32
+ }
33
+ /**
34
+ * LRU 读取:命中时把条目移到末尾,标记为最近访问
35
+ * Map 保持插入顺序,末尾即最近访问,首部即最久未访问(淘汰候选)
36
+ */
37
+ getCached(text) {
38
+ const vector = this.cache.get(text);
39
+ if (vector === undefined)
40
+ return undefined;
41
+ // 删除后重新插入,移到末尾
42
+ this.cache.delete(text);
43
+ this.cache.set(text, vector);
44
+ return vector;
45
+ }
46
+ /**
47
+ * LRU 写入:超过容量时淘汰最旧条目(首部)
48
+ */
49
+ setCache(text, vector) {
50
+ if (this.cache.size >= EmbeddingProvider.CACHE_MAX_SIZE) {
51
+ const oldest = this.cache.keys().next().value;
52
+ if (oldest !== undefined)
53
+ this.cache.delete(oldest);
54
+ }
55
+ this.cache.set(text, vector);
56
+ }
57
+ /**
58
+ * 嵌入单条文本
59
+ * @param text 待嵌入的文本
60
+ * @returns 向量
61
+ */
62
+ async embed(text) {
63
+ // 缓存命中
64
+ const cached = this.getCached(text);
65
+ if (cached)
66
+ return cached;
67
+ const results = await this.batchEmbed([text]);
68
+ const first = results[0];
69
+ if (!first)
70
+ throw new Error('embed: batchEmbed 返回空结果');
71
+ return first.vector;
72
+ }
73
+ /**
74
+ * 批量嵌入多条文本
75
+ * OpenAI 兼容 API 支持一次请求嵌入多条文本,减少 API 调用
76
+ * @param texts 待嵌入的文本数组
77
+ * @returns 嵌入结果数组(顺序与输入一致)
78
+ */
79
+ async batchEmbed(texts) {
80
+ // 过滤已缓存的
81
+ const uncached = [];
82
+ const uncachedIndices = [];
83
+ const results = texts.map((text, i) => {
84
+ const cached = this.getCached(text);
85
+ if (cached)
86
+ return { text, vector: cached };
87
+ uncached.push(text);
88
+ uncachedIndices.push(i);
89
+ return null;
90
+ });
91
+ // 全部命中缓存
92
+ if (uncached.length === 0) {
93
+ return results;
94
+ }
95
+ // 调用 /embeddings API
96
+ if (!this.config.apiKey) {
97
+ throw configError('Embedding API Key 未配置', 'embedding 需要 LLM API Key', [
98
+ '检查 ~/.memora/config.json 的 llm.apiKey 字段',
99
+ ]);
100
+ }
101
+ const url = `${this.config.baseUrl}/embeddings`;
102
+ let response;
103
+ try {
104
+ response = await fetch(url, {
105
+ method: 'POST',
106
+ headers: {
107
+ 'Content-Type': 'application/json',
108
+ Authorization: `Bearer ${this.config.apiKey}`,
109
+ },
110
+ body: JSON.stringify({
111
+ model: this.config.model,
112
+ input: uncached,
113
+ }),
114
+ });
115
+ }
116
+ catch (err) {
117
+ const e = toError(err);
118
+ throw networkError('Embedding 服务连接失败', `无法访问 ${url}:${e.message}`, ['检查网络连接', '确认 baseUrl 配置正确'], e);
119
+ }
120
+ if (!response.ok) {
121
+ const body = await response.text().catch(() => '');
122
+ throw networkError('Embedding 请求失败', `HTTP ${response.status}: ${body.slice(0, 200)}`, [
123
+ '检查 API Key 是否有效',
124
+ '确认 embedding 模型名称正确',
125
+ ]);
126
+ }
127
+ const data = (await response.json());
128
+ // 按 index 排序(API 不保证顺序)
129
+ const sorted = data.data.sort((a, b) => a.index - b.index);
130
+ // 填充结果 + 更新缓存
131
+ for (let i = 0; i < uncached.length; i++) {
132
+ // QC-17 移除非空断言:循环条件保证索引有效,null 检查兜底
133
+ const text = uncached[i];
134
+ if (!text)
135
+ continue;
136
+ const vector = sorted[i]?.embedding;
137
+ if (!vector) {
138
+ logger.warn({ text: text.slice(0, 50), index: i }, 'Embedding 缺失,跳过');
139
+ continue;
140
+ }
141
+ this.setCache(text, vector);
142
+ // QC-17 移除非空断言:null 检查兜底
143
+ const idx = uncachedIndices[i];
144
+ if (idx !== undefined)
145
+ results[idx] = { text, vector };
146
+ }
147
+ return results.filter((r) => r !== null);
148
+ }
149
+ /**
150
+ * 获取缓存大小(调试用)
151
+ */
152
+ get cacheSize() {
153
+ return this.cache.size;
154
+ }
155
+ /**
156
+ * 清空缓存
157
+ */
158
+ clearCache() {
159
+ this.cache.clear();
160
+ }
161
+ }
162
+ //# sourceMappingURL=embedding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../src/llm/embedding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * LLM Provider 工厂
3
+ * 根据配置选择具体的 LLM 实现
4
+ * 详见 ADR-003
5
+ */
6
+ import type { Config } from '../config/loader.js';
7
+ import { LlmProvider } from '../llm/provider.js';
8
+ /**
9
+ * 单个 Provider 配置(用于 createProviderFromConfig)
10
+ */
11
+ export interface ProviderConfig {
12
+ provider: string;
13
+ model: string;
14
+ baseUrl?: string;
15
+ apiKey?: string;
16
+ }
17
+ /**
18
+ * 从单个 Provider 配置创建 LlmProvider 实例
19
+ *
20
+ * 与 createLlmProvider 逻辑相同,但接收的是单个 Provider 配置而非完整 Config。
21
+ * 用于多 Provider 管理场景:Agent 为 providers 映射表中的每个条目调用此函数。
22
+ *
23
+ * @param name - Provider 别名(如 "deepseek"、"openai")
24
+ * @param providerConfig - 单个 Provider 的配置
25
+ * @returns LlmProvider 实例
26
+ */
27
+ export declare function createProviderFromConfig(name: string, providerConfig: ProviderConfig): LlmProvider;
28
+ /**
29
+ * 创建 LLM Provider(从完整 Config)
30
+ *
31
+ * 兼容两种配置格式:
32
+ * 1. 新格式:llm.providers + llm.active → 使用指定 Provider
33
+ * 2. 旧格式:llm.provider + llm.model + ... → 单 Provider 扁平字段
34
+ *
35
+ * @param config 完整配置
36
+ * @returns 当前激活的 LlmProvider 实例
37
+ */
38
+ export declare function createLlmProvider(config: Config): LlmProvider;
39
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/llm/factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAYhD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,cAAc,GAC7B,WAAW,CAiDb;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAyB7D"}
@@ -0,0 +1,108 @@
1
+ import { LlmProvider } from '../llm/provider.js';
2
+ import { OpenAICompatibleProvider } from '../llm/openaiCompatible.js';
3
+ import { logger } from '../logging/logger.js';
4
+ import { configError } from '../utils/errors.js';
5
+ // 预设 Provider 的默认 baseUrl 和 model(开箱即用)
6
+ const presets = {
7
+ deepseek: { baseUrl: 'https://api.deepseek.com/v1', defaultModel: 'deepseek-chat' },
8
+ doubao: { baseUrl: 'https://ark.cn-beijing.volces.com/api/v3', defaultModel: 'doubao-pro-32k' },
9
+ openai: { baseUrl: 'https://api.openai.com/v1', defaultModel: 'gpt-4o-mini' },
10
+ };
11
+ /**
12
+ * 从单个 Provider 配置创建 LlmProvider 实例
13
+ *
14
+ * 与 createLlmProvider 逻辑相同,但接收的是单个 Provider 配置而非完整 Config。
15
+ * 用于多 Provider 管理场景:Agent 为 providers 映射表中的每个条目调用此函数。
16
+ *
17
+ * @param name - Provider 别名(如 "deepseek"、"openai")
18
+ * @param providerConfig - 单个 Provider 的配置
19
+ * @returns LlmProvider 实例
20
+ */
21
+ export function createProviderFromConfig(name, providerConfig) {
22
+ const { provider, apiKey, baseUrl, model } = providerConfig;
23
+ if (provider === 'mock') {
24
+ logger.warn({ provider: 'mock' }, '使用 Mock LLM Provider(仅用于测试)');
25
+ return new MockProvider();
26
+ }
27
+ // 国产模型均走 OpenAI 兼容协议
28
+ const preset = presets[provider];
29
+ const resolvedBaseUrl = (baseUrl ?? preset?.baseUrl)?.replace(/\/chat\/completions\/?$/, '');
30
+ const resolvedModel = model ?? preset?.defaultModel;
31
+ if (!resolvedBaseUrl) {
32
+ throw configError('未知的 LLM provider', `provider "${provider}" 未在预设中,且未配置 baseUrl`, [
33
+ '在配置文件中显式设置 baseUrl 和 model',
34
+ `或使用预设 provider:${Object.keys(presets).join(', ')}`,
35
+ '详见 ADR-003 扩展点说明',
36
+ ]);
37
+ }
38
+ if (!resolvedModel) {
39
+ throw configError('未知的 LLM provider', `provider "${provider}" 未在预设中,且未配置 model`, [
40
+ `在配置文件中显式设置 model,或使用预设 provider:${Object.keys(presets).join(', ')}`,
41
+ ]);
42
+ }
43
+ // apiKey 缺失尽早报错(比等 chat() 失败更友好)
44
+ if (!apiKey) {
45
+ throw configError('LLM API Key 未配置', `provider "${name}" (${provider}) 缺少 apiKey`, [
46
+ `设置环境变量 MEMORA_LLM_API_KEY`,
47
+ '或在配置文件中配置 apiKey(支持 ${ENV_VAR} 占位符)',
48
+ '详见 config.example.md',
49
+ ]);
50
+ }
51
+ logger.info({ provider, baseUrl: resolvedBaseUrl, model: resolvedModel }, `创建 LLM Provider: ${name}`);
52
+ return new OpenAICompatibleProvider(name, {
53
+ baseUrl: resolvedBaseUrl,
54
+ apiKey,
55
+ defaultModel: resolvedModel,
56
+ });
57
+ }
58
+ /**
59
+ * 创建 LLM Provider(从完整 Config)
60
+ *
61
+ * 兼容两种配置格式:
62
+ * 1. 新格式:llm.providers + llm.active → 使用指定 Provider
63
+ * 2. 旧格式:llm.provider + llm.model + ... → 单 Provider 扁平字段
64
+ *
65
+ * @param config 完整配置
66
+ * @returns 当前激活的 LlmProvider 实例
67
+ */
68
+ export function createLlmProvider(config) {
69
+ const { llm } = config;
70
+ // 优先使用新的多 Provider 格式
71
+ if (llm.providers && Object.keys(llm.providers).length > 0) {
72
+ // QC-17 移除非空断言:Object.keys 已检查 length > 0
73
+ const active = llm.active ?? Object.keys(llm.providers)[0] ?? '';
74
+ const providerConfig = llm.providers[active];
75
+ if (!providerConfig) {
76
+ throw configError('无效的 active Provider', `active="${active}" 不在 providers 映射表中`, [
77
+ `可用的 Provider:${Object.keys(llm.providers).join(', ')}`,
78
+ `在配置文件中设置 llm.active 为其中之一`,
79
+ '或使用 `memora config llm use <name>` 切换',
80
+ ]);
81
+ }
82
+ return createProviderFromConfig(active, providerConfig);
83
+ }
84
+ // 旧格式:复用 createProviderFromConfig(DRY,避免重复 preset 解析逻辑)
85
+ return createProviderFromConfig(llm.provider, {
86
+ provider: llm.provider,
87
+ model: llm.model,
88
+ baseUrl: llm.baseUrl,
89
+ apiKey: llm.apiKey,
90
+ });
91
+ }
92
+ /**
93
+ * Mock LLM Provider
94
+ * 用于测试和开发
95
+ */
96
+ class MockProvider extends LlmProvider {
97
+ name = 'mock';
98
+ async *chat(messages) {
99
+ const lastUser = [...messages].reverse().find((m) => m.role === 'user');
100
+ const reply = `Mock 响应:${lastUser?.content ?? '(empty)'}`;
101
+ for (const char of reply) {
102
+ yield { content: char };
103
+ await new Promise((r) => setTimeout(r, 5));
104
+ }
105
+ yield { finishReason: 'stop' };
106
+ }
107
+ }
108
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/llm/factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * OpenAI Chat Completions 兼容实现
3
+ *
4
+ * 适用于:DeepSeek / 豆包 / 通义 / Ollama / 任何兼容 OpenAI 协议的 API
5
+ * 详见 ADR-003
6
+ */
7
+ import { LlmProvider } from '../llm/provider.js';
8
+ import type { Message, ChatOptions } from '../llm/provider.js';
9
+ import type { LlmChunk } from '../llm/types.js';
10
+ export interface OpenAICompatibleConfig {
11
+ baseUrl: string;
12
+ apiKey: string;
13
+ defaultModel: string;
14
+ }
15
+ /**
16
+ * 通用 OpenAI 兼容 Provider
17
+ * 通过 baseUrl 适配不同厂商
18
+ */
19
+ export declare class OpenAICompatibleProvider extends LlmProvider {
20
+ private readonly config;
21
+ readonly name: string;
22
+ constructor(name: string, config: OpenAICompatibleConfig);
23
+ /** 默认请求超时:120 秒 */
24
+ private static readonly DEFAULT_TIMEOUT_MS;
25
+ chat(messages: Message[], opts?: ChatOptions): AsyncIterable<LlmChunk>;
26
+ /**
27
+ * 处理 HTTP 错误响应
28
+ *
29
+ * 消费并释放 body,根据状态码抛出相应的错误类型。
30
+ */
31
+ private handleResponseError;
32
+ /**
33
+ * 格式化消息为 OpenAI 协议格式
34
+ *
35
+ * 关键兼容性处理:
36
+ * - assistant 消息带 tool_calls 时,若 content 为空字符串,转为 null
37
+ * (部分 LLM provider 对空字符串 content 处理异常,导致请求挂起或报错)
38
+ * - tool 消息必须包含 tool_call_id 关联对应的工具调用
39
+ */
40
+ private formatMessages;
41
+ /**
42
+ * 解析 SSE 流
43
+ * OpenAI 协议:data: {...}\n\n
44
+ *
45
+ * 支持解析 tool_calls delta(流式工具调用):
46
+ * OpenAI 协议中 tool_calls 以 delta 形式分片传输,
47
+ * 需要跨 chunk 累积 function.name 和 function.arguments,
48
+ * 在 finish_reason='tool_calls' 或流结束时输出完整的 toolCalls。
49
+ *
50
+ * @param body - SSE 响应流
51
+ * @param signal - 中止信号(超时/用户取消),中断 reader.read() 等待
52
+ */
53
+ private parseSseStream;
54
+ /**
55
+ * 从累积器构建完整的 toolCalls 数组(用于 finish_reason='tool_calls' 场景)
56
+ */
57
+ private buildToolCallsFromAccumulators;
58
+ /**
59
+ * 从累积器构建 LlmChunk(用于流结束时的兜底输出)
60
+ */
61
+ private buildToolCallsChunk;
62
+ }
63
+ //# sourceMappingURL=openaiCompatible.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openaiCompatible.d.ts","sourceRoot":"","sources":["../../src/llm/openaiCompatible.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,gBAAgB,CAAC;AAIzD,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,WAAW;IAKrD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGpB,IAAI,EAAE,MAAM,EACK,MAAM,EAAE,sBAAsB;IAMjD,mBAAmB;IACnB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAW;IAE9C,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,GAAE,WAAgB,GAAG,aAAa,CAAC,QAAQ,CAAC;IA0HjF;;;;OAIG;YACW,mBAAmB;IAuCjC;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAkBtB;;;;;;;;;;;OAWG;YACY,cAAc;IA4H7B;;OAEG;IACH,OAAO,CAAC,8BAA8B;IActC;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAQ5B"}