my-ai-chat-framework 2.7.0 → 3.0.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.
@@ -1,187 +1,223 @@
1
- /**
2
- * model-registry 插件
3
- *
4
- * 职责:
5
- * 1. 内置常用模型的能力标签表(model → capabilities 映射)
6
- * 2. 安装时自动根据 config.model 查表,写入 config.capabilities
7
- * 3. 监听 config-updated 事件,切换模型时自动同步能力
8
- * 4. 提供 chat.registerModel(),允许用户追加/覆盖自定义模型
9
- *
10
- * 能力标签字段(全部可选,缺失视为 false / 未知):
11
- * {
12
- * reasoning: boolean — 是否返回 reasoning_content(思维链)
13
- * vision: boolean — 是否支持图片输入
14
- * toolCalling: boolean — 是否支持 function calling
15
- * streaming: boolean — 是否支持流式传输
16
- * maxInputTokens: number — 最大输入 token 数
17
- * maxOutputTokens: number — 最大输出 token 数
18
- * }
19
- *
20
- * 使用:
21
- * chat.use(modelRegistryPlugin);
22
- * // config.capabilities 现在已自动填充
23
- * chat.registerModel('my-custom-model', { toolCalling: true });
24
- */
25
-
26
- // ====== 内置模型能力表 ======
27
- // 数据来源:各厂商官方文档(2026-05 快照),用户可通过 registerModel() 覆盖
28
- const BUILTIN_MODELS = {
29
- // ---- DeepSeek ----
30
- 'deepseek-chat': {
31
- reasoning: false,
32
- vision: false,
33
- toolCalling: true,
34
- streaming: true,
35
- maxInputTokens: 128000,
36
- maxOutputTokens: 8192
37
- },
38
- 'deepseek-reasoner': {
39
- reasoning: true,
40
- vision: false,
41
- toolCalling: true,
42
- streaming: true,
43
- maxInputTokens: 128000,
44
- maxOutputTokens: 8192
45
- },
46
-
47
- // ---- OpenAI ----
48
- 'gpt-4o': {
49
- reasoning: false,
50
- vision: true,
51
- toolCalling: true,
52
- streaming: true,
53
- maxInputTokens: 128000,
54
- maxOutputTokens: 16384
55
- },
56
- 'gpt-4o-mini': {
57
- reasoning: false,
58
- vision: true,
59
- toolCalling: true,
60
- streaming: true,
61
- maxInputTokens: 128000,
62
- maxOutputTokens: 16384
63
- },
64
- 'gpt-3.5-turbo': {
65
- reasoning: false,
66
- vision: false,
67
- toolCalling: true,
68
- streaming: true,
69
- maxInputTokens: 16385,
70
- maxOutputTokens: 4096
71
- },
72
- 'o1': {
73
- reasoning: true,
74
- vision: false,
75
- toolCalling: false,
76
- streaming: false,
77
- maxInputTokens: 200000,
78
- maxOutputTokens: 100000
79
- },
80
- 'o3-mini': {
81
- reasoning: true,
82
- vision: false,
83
- toolCalling: true,
84
- streaming: true,
85
- maxInputTokens: 200000,
86
- maxOutputTokens: 100000
87
- },
88
-
89
- // ---- Anthropic ----
90
- 'claude-3.5-sonnet': {
91
- reasoning: false,
92
- vision: true,
93
- toolCalling: true,
94
- streaming: true,
95
- maxInputTokens: 200000,
96
- maxOutputTokens: 8192
97
- },
98
- 'claude-3.5-haiku': {
99
- reasoning: false,
100
- vision: true,
101
- toolCalling: true,
102
- streaming: true,
103
- maxInputTokens: 200000,
104
- maxOutputTokens: 8192
105
- }
106
- };
107
-
108
- const DEFAULT_CAPABILITIES = {
109
- streaming: true,
110
- toolCalling: false,
111
- reasoning: false,
112
- vision: false
113
- };
114
-
115
- export const modelRegistryPlugin = {
116
- name: 'model-registry',
117
-
118
- install(chatService) {
119
- this.chat = chatService;
120
- // 合并内置表 + 用户通过 registerModel 追加的
121
- this._registry = new Map(Object.entries(BUILTIN_MODELS));
122
-
123
- /**
124
- * 注册/覆盖一个模型的能力标签
125
- * @param {string} name — 模型名称
126
- * @param {Object} capabilities — 能力标签对象(部分字段即可,未提供的取默认值)
127
- * @returns {ChatService}
128
- */
129
- chatService.registerModel = (name, capabilities = {}) => {
130
- if (!name || typeof name !== 'string' || !name.trim()) {
131
- throw new Error('[model-registry] 模型名称必须是非空字符串');
132
- }
133
- const merged = { ...DEFAULT_CAPABILITIES, ...capabilities };
134
- this._registry.set(name.trim(), merged);
135
- // 如果注册的模型与当前使用的模型同名,立即同步
136
- if (chatService.config.model === name.trim()) {
137
- this._syncCapabilities();
138
- }
139
- return chatService;
140
- };
141
-
142
- /**
143
- * 列出所有已注册的模型名称
144
- * @returns {Array<string>}
145
- */
146
- chatService.listModels = () => {
147
- return [...this._registry.keys()];
148
- };
149
-
150
- // 安装时立即同步一次
151
- this._syncCapabilities();
152
-
153
- // 监听配置变更:model 变了就重新同步
154
- chatService.on('config-updated', ({ changes }) => {
155
- if ('model' in changes) {
156
- this._syncCapabilities();
157
- }
158
- // 如果用户手动改了 capabilities,用 merge 保留未指定的字段
159
- if ('capabilities' in changes && !('model' in changes)) {
160
- const current = this._lookupCapabilities();
161
- if (current) {
162
- chatService.config.capabilities = { ...current, ...changes.capabilities };
163
- }
164
- }
165
- });
166
- },
167
-
168
- // ---- 内部方法 ----
169
-
170
- /** 查表获取模型能力,未注册返回 null */
171
- _lookupCapabilities() {
172
- const model = this.chat.config.model;
173
- if (!model) return null;
174
- return this._registry.get(model) || null;
175
- },
176
-
177
- /** 将查到的能力写入 config.capabilities */
178
- _syncCapabilities() {
179
- const caps = this._lookupCapabilities();
180
- if (caps) {
181
- // 若用户已手动设了 capabilities,用模型的合并(用户值优先?还是模型优先?)
182
- // 策略:模型优先,因为换了模型能力应该重置
183
- this.chat.config.capabilities = { ...caps };
184
- }
185
- // 未注册的模型:不清除已有 capabilities,保留用户手动设的值
186
- }
187
- };
1
+ /**
2
+ * model-registry 插件
3
+ *
4
+ * 职责:
5
+ * 1. 内置常用模型的能力标签表(model → capabilities 映射)
6
+ * 2. 安装时自动根据 config.model 查表,写入 config.capabilities
7
+ * 3. 监听 config-updated 事件,切换模型时自动同步能力
8
+ * 4. 提供 chat.registerModel(),允许用户追加/覆盖自定义模型
9
+ *
10
+ * 能力标签字段(全部可选,缺失视为 false / 未知):
11
+ * {
12
+ * reasoning: boolean — 是否返回 reasoning_content(思维链)
13
+ * vision: boolean — 是否支持图片输入
14
+ * toolCalling: boolean — 是否支持 function calling
15
+ * streaming: boolean — 是否支持流式传输
16
+ * maxInputTokens: number — 最大输入 token 数
17
+ * maxOutputTokens: number — 最大输出 token 数
18
+ * }
19
+ *
20
+ * 使用:
21
+ * chat.use(modelRegistryPlugin);
22
+ * // config.capabilities 现在已自动填充
23
+ * chat.registerModel('my-custom-model', { toolCalling: true });
24
+ */
25
+
26
+ // ====== 内置模型能力表 ======
27
+ // 数据来源:各厂商官方文档(2026-05 快照),用户可通过 registerModel() 覆盖
28
+ const BUILTIN_MODELS = {
29
+ // ---- DeepSeek ----
30
+ 'deepseek-chat': {
31
+ reasoning: false,
32
+ vision: false,
33
+ toolCalling: true,
34
+ streaming: true,
35
+ maxInputTokens: 128000,
36
+ maxOutputTokens: 8192
37
+ },
38
+ 'deepseek-reasoner': {
39
+ reasoning: true,
40
+ vision: false,
41
+ toolCalling: true,
42
+ streaming: true,
43
+ maxInputTokens: 128000,
44
+ maxOutputTokens: 8192
45
+ },
46
+
47
+ // ---- OpenAI ----
48
+ 'gpt-4o': {
49
+ reasoning: false,
50
+ vision: true,
51
+ toolCalling: true,
52
+ streaming: true,
53
+ maxInputTokens: 128000,
54
+ maxOutputTokens: 16384
55
+ },
56
+ 'gpt-4o-mini': {
57
+ reasoning: false,
58
+ vision: true,
59
+ toolCalling: true,
60
+ streaming: true,
61
+ maxInputTokens: 128000,
62
+ maxOutputTokens: 16384
63
+ },
64
+ 'gpt-3.5-turbo': {
65
+ reasoning: false,
66
+ vision: false,
67
+ toolCalling: true,
68
+ streaming: true,
69
+ maxInputTokens: 16385,
70
+ maxOutputTokens: 4096
71
+ },
72
+ 'o1': {
73
+ reasoning: true,
74
+ vision: false,
75
+ toolCalling: false,
76
+ streaming: false,
77
+ maxInputTokens: 200000,
78
+ maxOutputTokens: 100000
79
+ },
80
+ 'o3-mini': {
81
+ reasoning: true,
82
+ vision: false,
83
+ toolCalling: true,
84
+ streaming: true,
85
+ maxInputTokens: 200000,
86
+ maxOutputTokens: 100000
87
+ },
88
+
89
+ // ---- Anthropic ----
90
+ 'claude-3.5-sonnet': {
91
+ reasoning: false,
92
+ vision: true,
93
+ toolCalling: true,
94
+ streaming: true,
95
+ maxInputTokens: 200000,
96
+ maxOutputTokens: 8192
97
+ },
98
+ 'claude-3.5-haiku': {
99
+ reasoning: false,
100
+ vision: true,
101
+ toolCalling: true,
102
+ streaming: true,
103
+ maxInputTokens: 200000,
104
+ maxOutputTokens: 8192
105
+ }
106
+ };
107
+
108
+ const DEFAULT_CAPABILITIES = {
109
+ streaming: true,
110
+ toolCalling: false,
111
+ reasoning: false,
112
+ vision: false
113
+ };
114
+
115
+ /**
116
+ * 注意:请使用 createModelRegistryPlugin() 工厂创建实例。
117
+ * 默认导出的 modelRegistryPlugin 是兼容用的模块级单例,装到多个 ChatService
118
+ * 实例会互相覆盖(注册表、实例引用),新代码不要直接用单例。
119
+ */
120
+ export const modelRegistryPlugin = createModelRegistryPlugin();
121
+
122
+ /**
123
+ * 创建模型能力注册表插件实例(工厂)。
124
+ * @param {Object} [options] — { models: { '模型名': capabilities } }(合并进内置表)
125
+ */
126
+ export function createModelRegistryPlugin(options = {}) {
127
+ return {
128
+ name: 'model-registry',
129
+
130
+ _options: { ...options },
131
+ _registry: new Map([
132
+ ...Object.entries(BUILTIN_MODELS),
133
+ ...Object.entries(options.models || {})
134
+ ]),
135
+ chat: null,
136
+
137
+ /**
138
+ * 安装插件
139
+ * @param {ChatService} chatService - ChatService 实例
140
+ * @param {Object} [options] - 安装时配置(合并进 _options)
141
+ */
142
+ install(chatService, options = {}) {
143
+ this._options = { ...this._options, ...options };
144
+ this.chat = chatService;
145
+
146
+ /**
147
+ * 注册/覆盖一个模型的能力标签
148
+ * @param {string} name — 模型名称
149
+ * @param {Object} capabilities — 能力标签对象(部分字段即可,未提供的取默认值)
150
+ * @returns {ChatService}
151
+ */
152
+ chatService.registerModel = (name, capabilities = {}) => {
153
+ if (!name || typeof name !== 'string' || !name.trim()) {
154
+ throw new Error('[model-registry] 模型名称必须是非空字符串');
155
+ }
156
+ const merged = { ...DEFAULT_CAPABILITIES, ...capabilities };
157
+ this._registry.set(name.trim(), merged);
158
+ // 如果注册的模型与当前使用的模型同名,立即同步
159
+ if (chatService.config.model === name.trim()) {
160
+ this._syncCapabilities();
161
+ }
162
+ return chatService;
163
+ };
164
+
165
+ /**
166
+ * 列出所有已注册的模型名称
167
+ * @returns {Array<string>}
168
+ */
169
+ chatService.listModels = () => {
170
+ return [...this._registry.keys()];
171
+ };
172
+
173
+ // 安装时立即同步一次
174
+ this._syncCapabilities();
175
+
176
+ // 每次请求时按"本次生效的 model"(含请求级覆盖)解析 capabilities
177
+ // v3.0:beforeSend 车间,不再用 _hooks 钩子(时机与之前一致)
178
+ chatService.pipe({
179
+ name: 'model-registry-caps',
180
+ phase: 'beforeSend',
181
+ run: ({ config }) => {
182
+ if (!config.model) return;
183
+ const caps = this._registry.get(config.model);
184
+ if (caps) config.capabilities = { ...caps };
185
+ }
186
+ });
187
+
188
+ // 监听配置变更:model 变了就重新同步(兼容路径;请求时按生效 model 实时查表)
189
+ chatService.on('config-updated', ({ changes }) => {
190
+ if ('model' in changes) {
191
+ this._syncCapabilities();
192
+ }
193
+ // 如果用户手动改了 capabilities,用 merge 保留未指定的字段
194
+ if ('capabilities' in changes && !('model' in changes)) {
195
+ const current = this._lookupCapabilities();
196
+ if (current) {
197
+ chatService.config.capabilities = { ...current, ...changes.capabilities };
198
+ }
199
+ }
200
+ });
201
+ },
202
+
203
+ // ---- 内部方法 ----
204
+
205
+ /** 查表获取模型能力,未注册返回 null */
206
+ _lookupCapabilities() {
207
+ const model = this.chat.config.model;
208
+ if (!model) return null;
209
+ return this._registry.get(model) || null;
210
+ },
211
+
212
+ /** 将查到的能力写入 config.capabilities */
213
+ _syncCapabilities() {
214
+ const caps = this._lookupCapabilities();
215
+ if (caps) {
216
+ // 若用户已手动设了 capabilities,用模型的合并(用户值优先?还是模型优先?)
217
+ // 策略:模型优先,因为换了模型能力应该重置
218
+ this.chat.config.capabilities = { ...caps };
219
+ }
220
+ // 未注册的模型:不清除已有 capabilities,保留用户手动设的值
221
+ }
222
+ };
223
+ }