@aalis/plugin-llm-openai 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ace Nyan <ace@acenyan.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # @aalis/plugin-llm-openai
2
+
3
+ OpenAI / 兼容接口 LLM 提供者(对话、工具、流式)
4
+ ## 角色
5
+
6
+ 运行时插件
7
+
8
+ ## 安装
9
+
10
+ ```bash
11
+ pnpm add @aalis/plugin-llm-openai
12
+ ```
13
+
14
+ ## 文档
15
+
16
+ 详见 [docs/plugins/plugin-llm-openai.md](../../docs/plugins/plugin-llm-openai.md)。
17
+
18
+ ## 许可
19
+
20
+ 见仓库根目录 LICENSE。
@@ -0,0 +1,20 @@
1
+ import type { Context } from '@aalis/core';
2
+ import type { ConfigSchema } from '@aalis/schema-config';
3
+ export declare const name = "@aalis/plugin-llm-openai";
4
+ export declare const displayName = "OpenAI";
5
+ export declare const subsystem = "llm";
6
+ export declare const provides: string[];
7
+ export declare const reusable = true;
8
+ export declare const configSchema: ConfigSchema;
9
+ export declare const defaultConfig: {
10
+ baseUrl: string;
11
+ customModels: string;
12
+ modelCapabilities: string;
13
+ providerCapabilities: string;
14
+ timeout: number;
15
+ temperature: number;
16
+ maxTokens: number;
17
+ contextLength: number;
18
+ };
19
+ export declare function apply(ctx: Context, config: Record<string, unknown>): Promise<void>;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAwBzD,eAAO,MAAM,IAAI,6BAA6B,CAAC;AAC/C,eAAO,MAAM,WAAW,WAAW,CAAC;AACpC,eAAO,MAAM,SAAS,QAAQ,CAAC;AAC/B,eAAO,MAAM,QAAQ,UAAU,CAAC;AAChC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAE7B,eAAO,MAAM,YAAY,EAAE,YAsC1B,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;;;CASzB,CAAC;AAogBF,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgHxF"}
package/dist/index.js ADDED
@@ -0,0 +1,585 @@
1
+ import { LLMCapabilities } from '@aalis/api-llm';
2
+ import { prepareLLMMessages, toLLMRole } from '@aalis/schema-message';
3
+ // ===== 插件元数据 =====
4
+ /** 已知的内容审查错误关键词 */
5
+ const CONTENT_FILTER_PATTERNS = [
6
+ 'content exists risk',
7
+ 'content_filter',
8
+ 'content_policy',
9
+ 'sensitive content',
10
+ 'risk control',
11
+ ];
12
+ /** 解析 API 错误,对内容审查类错误返回友好提示 */
13
+ function parseApiError(provider, status, body) {
14
+ const lower = body.toLowerCase();
15
+ if (status === 400 && CONTENT_FILTER_PATTERNS.some(p => lower.includes(p))) {
16
+ return `${provider} 拒绝了此次请求(内容安全策略),请尝试换一个话题或缩短上下文`;
17
+ }
18
+ return `${provider} API 错误 (${status}): ${body}`;
19
+ }
20
+ export const name = '@aalis/plugin-llm-openai';
21
+ export const displayName = 'OpenAI';
22
+ export const subsystem = 'llm';
23
+ export const provides = ['llm'];
24
+ export const reusable = true;
25
+ export const configSchema = {
26
+ apiKey: { type: 'string', label: 'API Key', secret: true, description: 'OpenAI API 密钥(本地服务可留空)' },
27
+ baseUrl: {
28
+ type: 'string',
29
+ label: 'API 地址',
30
+ default: 'https://api.openai.com',
31
+ description: 'API 端点地址,可替换为兼容的第三方服务',
32
+ },
33
+ customModels: {
34
+ type: 'textarea',
35
+ label: '自定义模型',
36
+ default: '',
37
+ description: '手动添加的模型名称(每行一个或逗号分隔)。用于补充自动发现列表中未出现的模型。与自动发现重复时会提示去重。',
38
+ },
39
+ modelCapabilities: {
40
+ type: 'textarea',
41
+ label: '单模型能力覆盖',
42
+ default: '',
43
+ description: '按行指定某个模型的能力集。有该模型的表项时**覆盖**插件启发式推断,与 adapter 默认能力仍取并集。\n格式:`<modelId>: <cap1>,<cap2>,...`,每行一条。如:gpt-4o: chat,tool_calling,vision,streaming\n可用能力:chat / tool_calling / vision / streaming / thinking / json_mode 等。',
44
+ },
45
+ providerCapabilities: {
46
+ type: 'string',
47
+ label: '适配器默认能力(逗号分隔)',
48
+ default: '',
49
+ description: '为本适配器下所有模型额外补充的能力。最终某模型的能力 = 此处能力 ∪ 模型级别能力。例:chat,tool_calling,streaming',
50
+ },
51
+ timeout: {
52
+ type: 'number',
53
+ label: '请求超时 (秒)',
54
+ default: 120,
55
+ description: 'LLM 请求超时时间(秒)。思考模式或长文本建议适当调大。0 = 不限制。',
56
+ },
57
+ temperature: { type: 'number', label: '温度', default: 0.7, description: '0-2,越高越随机' },
58
+ maxTokens: { type: 'number', label: '最大 Token', default: 4096, description: '单次回复最大生成 token 数' },
59
+ contextLength: { type: 'number', label: '上下文长度', default: 128000, description: '模型上下文窗口大小' },
60
+ };
61
+ export const defaultConfig = {
62
+ baseUrl: 'https://api.openai.com',
63
+ customModels: '',
64
+ modelCapabilities: '',
65
+ providerCapabilities: '',
66
+ timeout: 120,
67
+ temperature: 0.7,
68
+ maxTokens: 4096,
69
+ contextLength: 128000,
70
+ };
71
+ /** OpenAI 推理模型(o 系列:o1/o3/o4…):拒 max_tokens(需 max_completion_tokens)、拒非默认 temperature。 */
72
+ function isReasoningModel(model) {
73
+ return /^o\d/i.test(model);
74
+ }
75
+ // ===== OpenAI 客户端(不是 service、仅是底层 fetch 封装,多个 ModelHandle 共享) =====
76
+ class OpenAIClient {
77
+ apiKey;
78
+ baseUrl;
79
+ timeout;
80
+ temperature;
81
+ maxTokens;
82
+ logger;
83
+ constructor(config, logger) {
84
+ this.apiKey = config.apiKey;
85
+ this.baseUrl = config.baseUrl.replace(/\/$/, '');
86
+ // schema 中 timeout 单位为「秒」,存储为毫秒;0 视为不限制 → 用一个非常大的值
87
+ this.timeout = config.timeout && config.timeout > 0 ? config.timeout * 1000 : 2_147_483_647;
88
+ this.temperature = config.temperature;
89
+ this.maxTokens = config.maxTokens;
90
+ this.logger = logger;
91
+ }
92
+ /** 构造请求头(无 apiKey 时不发 Authorization) */
93
+ get headers() {
94
+ const h = { 'Content-Type': 'application/json' };
95
+ if (this.apiKey)
96
+ h.Authorization = `Bearer ${this.apiKey}`;
97
+ return h;
98
+ }
99
+ /** 发现远端模型列表(仅含 id) */
100
+ async fetchRemoteModelIds() {
101
+ try {
102
+ const res = await fetch(`${this.baseUrl}/v1/models`, {
103
+ headers: this.headers,
104
+ });
105
+ if (!res.ok)
106
+ return [];
107
+ const data = (await res.json());
108
+ return data.data.map(m => m.id);
109
+ }
110
+ catch {
111
+ return [];
112
+ }
113
+ }
114
+ async chat(model, request) {
115
+ const messages = prepareLLMMessages(request.messages).map(m => this.toAPIMessage(m));
116
+ const tools = request.tools?.map(t => this.toAPITool(t));
117
+ const reasoning = isReasoningModel(model);
118
+ const body = {
119
+ model,
120
+ messages,
121
+ // 推理模型(o 系列)拒 max_tokens(需 max_completion_tokens)且只接受默认 temperature → 分支处理;
122
+ // 缺省回退到配置的 this.maxTokens,而非字面量 4096(遵守 llm-api 契约)。
123
+ [reasoning ? 'max_completion_tokens' : 'max_tokens']: request.maxTokens ?? this.maxTokens,
124
+ ...(reasoning ? {} : { temperature: request.temperature ?? this.temperature }),
125
+ };
126
+ if (tools && tools.length > 0) {
127
+ body.tools = tools;
128
+ }
129
+ this.logger.debug(`请求 LLM: ${body.model}, ${messages.length} 条消息, ${tools?.length ?? 0} 个工具`);
130
+ const signals = [AbortSignal.timeout(this.timeout)];
131
+ if (request.signal)
132
+ signals.push(request.signal);
133
+ const response = await fetch(`${this.baseUrl}/v1/chat/completions`, {
134
+ method: 'POST',
135
+ headers: this.headers,
136
+ body: JSON.stringify(body),
137
+ signal: AbortSignal.any(signals),
138
+ });
139
+ if (!response.ok) {
140
+ const errorText = await response.text();
141
+ throw new Error(parseApiError('LLM', response.status, errorText));
142
+ }
143
+ const data = (await response.json());
144
+ const choice = data.choices[0];
145
+ if (!choice) {
146
+ throw new Error('LLM 返回了空的 choices');
147
+ }
148
+ const result = {
149
+ content: choice.message.content,
150
+ };
151
+ if (choice.message.tool_calls && choice.message.tool_calls.length > 0) {
152
+ result.toolCalls = choice.message.tool_calls.map(tc => ({
153
+ id: tc.id,
154
+ type: 'function',
155
+ function: {
156
+ name: tc.function.name,
157
+ arguments: tc.function.arguments,
158
+ },
159
+ }));
160
+ }
161
+ if (data.usage) {
162
+ result.usage = {
163
+ promptTokens: data.usage.prompt_tokens,
164
+ completionTokens: data.usage.completion_tokens,
165
+ totalTokens: data.usage.prompt_tokens + data.usage.completion_tokens,
166
+ cachedPromptTokens: data.usage.prompt_tokens_details?.cached_tokens,
167
+ };
168
+ }
169
+ return result;
170
+ }
171
+ async *chatStream(model, request) {
172
+ const messages = prepareLLMMessages(request.messages).map(m => this.toAPIMessage(m));
173
+ const tools = request.tools?.map(t => this.toAPITool(t));
174
+ const reasoning = isReasoningModel(model);
175
+ const body = {
176
+ model,
177
+ messages,
178
+ // 同 chat():推理模型分支 max_completion_tokens / 略去 temperature,缺省回退 this.maxTokens。
179
+ [reasoning ? 'max_completion_tokens' : 'max_tokens']: request.maxTokens ?? this.maxTokens,
180
+ ...(reasoning ? {} : { temperature: request.temperature ?? this.temperature }),
181
+ stream: true,
182
+ };
183
+ if (tools && tools.length > 0) {
184
+ body.tools = tools;
185
+ }
186
+ this.logger.debug(`流式请求 LLM: ${body.model}, ${messages.length} 条消息`);
187
+ const signals = [AbortSignal.timeout(this.timeout)];
188
+ if (request.signal)
189
+ signals.push(request.signal);
190
+ const reqStart = Date.now();
191
+ const slowConnectTimer = setTimeout(() => {
192
+ this.logger.warn(`LLM 连接慢:已等待 15s 仍未收到响应头 (url=${this.baseUrl}/v1/chat/completions)`);
193
+ }, 15_000);
194
+ let response;
195
+ try {
196
+ response = await fetch(`${this.baseUrl}/v1/chat/completions`, {
197
+ method: 'POST',
198
+ headers: this.headers,
199
+ body: JSON.stringify(body),
200
+ signal: AbortSignal.any(signals),
201
+ });
202
+ }
203
+ catch (err) {
204
+ clearTimeout(slowConnectTimer);
205
+ const elapsed = Date.now() - reqStart;
206
+ const msg = err instanceof Error ? err.message : String(err);
207
+ this.logger.warn(`LLM fetch 失败 (耗时 ${elapsed}ms): ${msg}`);
208
+ throw err;
209
+ }
210
+ clearTimeout(slowConnectTimer);
211
+ this.logger.debug(`LLM 响应头到达: status=${response.status}, 耗时 ${Date.now() - reqStart}ms`);
212
+ if (!response.ok) {
213
+ const errorText = await response.text();
214
+ throw new Error(parseApiError('LLM', response.status, errorText));
215
+ }
216
+ const toolCallBuffers = new Map();
217
+ if (!response.body) {
218
+ throw new Error('LLM API 返回了空的响应体,无法进行流式读取');
219
+ }
220
+ const reader = response.body.getReader();
221
+ const decoder = new TextDecoder();
222
+ let buffer = '';
223
+ let firstChunkLogged = false;
224
+ const streamStart = Date.now();
225
+ const streamStallTimer = setTimeout(() => {
226
+ if (!firstChunkLogged) {
227
+ this.logger.warn(`LLM 流停滞:响应头已到但 30s 仍未收到首帧 SSE`);
228
+ }
229
+ }, 30_000);
230
+ try {
231
+ while (true) {
232
+ const { done, value } = await reader.read();
233
+ if (done)
234
+ break;
235
+ if (!firstChunkLogged) {
236
+ firstChunkLogged = true;
237
+ clearTimeout(streamStallTimer);
238
+ this.logger.debug(`LLM 首帧到达: 耗时 ${Date.now() - streamStart}ms (从响应头算起)`);
239
+ }
240
+ buffer += decoder.decode(value, { stream: true });
241
+ const lines = buffer.split('\n');
242
+ buffer = lines.pop();
243
+ for (const line of lines) {
244
+ const trimmed = line.trim();
245
+ if (!trimmed?.startsWith('data: '))
246
+ continue;
247
+ const payload = trimmed.slice(6);
248
+ if (payload === '[DONE]') {
249
+ // 组装工具调用
250
+ const toolCalls = [];
251
+ for (const [, tc] of [...toolCallBuffers.entries()].sort((a, b) => a[0] - b[0])) {
252
+ toolCalls.push({ id: tc.id, type: 'function', function: { name: tc.name, arguments: tc.args } });
253
+ }
254
+ yield { done: true, toolCalls: toolCalls.length > 0 ? toolCalls : undefined };
255
+ return;
256
+ }
257
+ try {
258
+ const data = JSON.parse(payload);
259
+ const chunk = {};
260
+ // usage 必须在 delta 守卫**之前**取:OpenAI 的 include_usage 形态把
261
+ // usage 挂在 `choices: []` 的收尾帧上,等到守卫之后再取整帧已被跳过。
262
+ if (data.usage) {
263
+ chunk.usage = {
264
+ promptTokens: data.usage.prompt_tokens,
265
+ completionTokens: data.usage.completion_tokens,
266
+ totalTokens: data.usage.prompt_tokens + data.usage.completion_tokens,
267
+ cachedPromptTokens: data.usage.prompt_tokens_details?.cached_tokens,
268
+ };
269
+ }
270
+ const delta = data.choices?.[0]?.delta;
271
+ if (!delta) {
272
+ if (chunk.usage)
273
+ yield chunk; // 纯 usage 收尾帧照样上报
274
+ continue;
275
+ }
276
+ if (delta.content)
277
+ chunk.contentDelta = delta.content;
278
+ // 累积工具调用
279
+ if (delta.tool_calls) {
280
+ for (const tc of delta.tool_calls) {
281
+ const idx = tc.index ?? 0;
282
+ if (tc.id) {
283
+ toolCallBuffers.set(idx, { id: tc.id, name: tc.function?.name ?? '', args: '' });
284
+ }
285
+ const entry = toolCallBuffers.get(idx);
286
+ if (entry) {
287
+ if (tc.function?.name)
288
+ entry.name = tc.function.name;
289
+ if (tc.function?.arguments)
290
+ entry.args += tc.function.arguments;
291
+ // 每次 delta 都 yield 进度(不影响最终 done chunk)
292
+ chunk.toolCallProgress = {
293
+ index: idx,
294
+ name: entry.name,
295
+ charsAccumulated: entry.args.length,
296
+ };
297
+ }
298
+ }
299
+ }
300
+ if (chunk.contentDelta || chunk.usage || chunk.toolCallProgress) {
301
+ yield chunk;
302
+ }
303
+ }
304
+ catch {
305
+ /* skip malformed JSON */
306
+ }
307
+ }
308
+ }
309
+ }
310
+ finally {
311
+ clearTimeout(streamStallTimer);
312
+ reader.releaseLock();
313
+ }
314
+ // If we get here without [DONE], yield done
315
+ const toolCalls = [];
316
+ for (const [, tc] of [...toolCallBuffers.entries()].sort((a, b) => a[0] - b[0])) {
317
+ toolCalls.push({ id: tc.id, type: 'function', function: { name: tc.name, arguments: tc.args } });
318
+ }
319
+ yield { done: true, toolCalls: toolCalls.length > 0 ? toolCalls : undefined };
320
+ }
321
+ toAPIMessage(msg) {
322
+ // 调用方已经 prepareLLMMessages 处理过:role 已是 WellKnownRole,
323
+ // 自定义 role / kind 的前缀([系统通知] / [跨会话委派] 等)已拼接进 content。
324
+ // 这里只需透传。toLLMRole 作为防御性幂等调用。
325
+ const apiMsg = {
326
+ role: toLLMRole(msg.role),
327
+ content: msg.content,
328
+ };
329
+ // 多模态:如果消息包含图片,构造 content 数组
330
+ if (msg.images && msg.images.length > 0 && msg.role === 'user') {
331
+ const parts = [];
332
+ if (msg.content) {
333
+ parts.push({ type: 'text', text: msg.content });
334
+ }
335
+ for (const img of msg.images) {
336
+ parts.push({ type: 'image_url', image_url: { url: img } });
337
+ }
338
+ apiMsg.content = parts;
339
+ }
340
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
341
+ apiMsg.tool_calls = msg.toolCalls.map(tc => ({
342
+ id: tc.id,
343
+ type: 'function',
344
+ function: {
345
+ name: tc.function.name,
346
+ arguments: tc.function.arguments,
347
+ },
348
+ }));
349
+ }
350
+ if (msg.toolCallId) {
351
+ apiMsg.tool_call_id = msg.toolCallId;
352
+ }
353
+ if (msg.name) {
354
+ apiMsg.name = msg.name;
355
+ }
356
+ return apiMsg;
357
+ }
358
+ toAPITool(tool) {
359
+ return {
360
+ type: 'function',
361
+ function: {
362
+ name: tool.function.name,
363
+ strict: tool.function.strict,
364
+ description: tool.function.description,
365
+ parameters: tool.function.parameters,
366
+ },
367
+ };
368
+ }
369
+ }
370
+ // ===== 模型能力映射 =====
371
+ const { Chat, ToolCalling, Streaming, Vision, Thinking } = LLMCapabilities;
372
+ const MODEL_CAPABILITIES = {
373
+ 'gpt-4o': [Chat, ToolCalling, Streaming, Vision],
374
+ 'gpt-4o-mini': [Chat, ToolCalling, Streaming, Vision],
375
+ 'gpt-4-turbo': [Chat, ToolCalling, Streaming],
376
+ 'gpt-4': [Chat, ToolCalling, Streaming],
377
+ 'gpt-3.5-turbo': [Chat, ToolCalling, Streaming],
378
+ o1: [Chat, Thinking],
379
+ 'o1-mini': [Chat, Thinking],
380
+ 'o1-preview': [Chat, Thinking],
381
+ o3: [Chat, ToolCalling, Streaming, Thinking],
382
+ 'o3-mini': [Chat, ToolCalling, Streaming, Thinking],
383
+ 'o4-mini': [Chat, ToolCalling, Streaming, Thinking],
384
+ };
385
+ const DEFAULT_CAPABILITIES = [Chat];
386
+ function resolveCapabilities(model, userOverride, providerCaps) {
387
+ const out = new Set(providerCaps ?? []);
388
+ // 用户显式声明优先(覆盖启发式)
389
+ if (Array.isArray(userOverride) && userOverride.length > 0) {
390
+ for (const c of userOverride)
391
+ out.add(c);
392
+ return [...out];
393
+ }
394
+ // 精确匹配
395
+ if (MODEL_CAPABILITIES[model]) {
396
+ for (const c of MODEL_CAPABILITIES[model])
397
+ out.add(c);
398
+ return [...out];
399
+ }
400
+ // 模糊匹配
401
+ const lower = model.toLowerCase();
402
+ for (const [known, caps] of Object.entries(MODEL_CAPABILITIES)) {
403
+ if (lower.startsWith(known)) {
404
+ for (const c of caps)
405
+ out.add(c);
406
+ return [...out];
407
+ }
408
+ }
409
+ for (const c of DEFAULT_CAPABILITIES)
410
+ out.add(c);
411
+ return [...out];
412
+ }
413
+ // ===== 插件入口 =====
414
+ /** 解析自定义模型列表:支持逗号分隔和换行分隔 */
415
+ function parseCustomModels(raw) {
416
+ if (!raw || typeof raw !== 'string')
417
+ return [];
418
+ return raw
419
+ .split(/[,\n]/)
420
+ .map(s => s.trim())
421
+ .filter(Boolean);
422
+ }
423
+ /**
424
+ * 解析用户能力覆盖配置(textarea)。格式:每行 `<modelId>: cap1,cap2,...`。
425
+ * 返回 Map,供 resolveCapabilities() 作为 userOverride(覆盖而非叠加)。
426
+ */
427
+ function parseModelCapabilities(raw) {
428
+ const out = new Map();
429
+ if (!raw || typeof raw !== 'string')
430
+ return out;
431
+ for (const line of raw.split(/\r?\n/)) {
432
+ const trimmed = line.trim();
433
+ if (!trimmed || trimmed.startsWith('#'))
434
+ continue;
435
+ const colonIdx = trimmed.indexOf(':');
436
+ if (colonIdx < 0)
437
+ continue;
438
+ const modelId = trimmed.slice(0, colonIdx).trim();
439
+ const caps = trimmed
440
+ .slice(colonIdx + 1)
441
+ .split(',')
442
+ .map(s => s.trim())
443
+ .filter(Boolean);
444
+ if (modelId && caps.length > 0)
445
+ out.set(modelId, caps);
446
+ }
447
+ return out;
448
+ }
449
+ /**
450
+ * 解析适配器级别默认能力(逗号/空格/换行分隔)。
451
+ */
452
+ function parseProviderCapabilities(raw) {
453
+ if (!raw || typeof raw !== 'string')
454
+ return [];
455
+ return raw
456
+ .split(/[,\s\n]/)
457
+ .map(s => s.trim())
458
+ .filter(Boolean);
459
+ }
460
+ // ===== Per-model handle:每个 model 独立的 LLMModel entry =====
461
+ class OpenAIModelHandle {
462
+ client;
463
+ id;
464
+ providerId;
465
+ contextLength;
466
+ maxOutputTokens;
467
+ refresh;
468
+ capabilities;
469
+ constructor(client, id, providerId, contextLength, maxOutputTokens,
470
+ /** Provider 级共享的 refresh 闭包;webui 按 contextId 找到任一 entry 调一次即可。 */
471
+ refresh,
472
+ /** 该 model 的能力元数据(供 media 发现/下拉展示读取,非 DI 选择机制)。 */
473
+ capabilities) {
474
+ this.client = client;
475
+ this.id = id;
476
+ this.providerId = providerId;
477
+ this.contextLength = contextLength;
478
+ this.maxOutputTokens = maxOutputTokens;
479
+ this.refresh = refresh;
480
+ this.capabilities = capabilities;
481
+ }
482
+ chat(request) {
483
+ return this.client.chat(this.id, request);
484
+ }
485
+ chatStream(request) {
486
+ return this.client.chatStream(this.id, request);
487
+ }
488
+ }
489
+ export async function apply(ctx, config) {
490
+ const openaiConfig = {
491
+ apiKey: config.apiKey ?? '',
492
+ baseUrl: config.baseUrl ?? 'https://api.openai.com',
493
+ customModels: parseCustomModels(config.customModels),
494
+ modelCapabilities: parseModelCapabilities(config.modelCapabilities),
495
+ providerCapabilities: parseProviderCapabilities(config.providerCapabilities),
496
+ timeout: config.timeout ?? 120,
497
+ temperature: config.temperature ?? 0.7,
498
+ maxTokens: config.maxTokens ?? 4096,
499
+ contextLength: config.contextLength ?? 128000,
500
+ };
501
+ if (!openaiConfig.apiKey && openaiConfig.baseUrl === 'https://api.openai.com') {
502
+ throw new Error('使用 OpenAI 官方 API 需要配置 apiKey');
503
+ }
504
+ const client = new OpenAIClient(openaiConfig, ctx.logger);
505
+ const baseLabel = `OpenAI (${openaiConfig.baseUrl.replace(/^https?:\/\//, '')})`;
506
+ // 已注册 model entry 的句柄表:modelId → dispose(来自 ctx.provide 返回值)
507
+ const registered = new Map();
508
+ // refresh 闭包:apply 末尾装配;先占位以打破环依赖。
509
+ let refreshFn = async () => ({
510
+ added: [],
511
+ removed: [],
512
+ total: registered.size,
513
+ });
514
+ const refresh = () => refreshFn();
515
+ function registerOne(modelId) {
516
+ if (registered.has(modelId))
517
+ return;
518
+ const capabilities = resolveCapabilities(modelId, openaiConfig.modelCapabilities.get(modelId), openaiConfig.providerCapabilities);
519
+ const handle = new OpenAIModelHandle(client, modelId, ctx.id, openaiConfig.contextLength, openaiConfig.maxTokens, refresh, capabilities);
520
+ const dispose = ctx.provide('llm', handle, {
521
+ label: `${baseLabel} / ${modelId}`,
522
+ entryId: `${ctx.id}/${modelId}`,
523
+ });
524
+ registered.set(modelId, dispose);
525
+ }
526
+ function unregisterOne(modelId) {
527
+ const d = registered.get(modelId);
528
+ if (!d)
529
+ return;
530
+ try {
531
+ d();
532
+ }
533
+ catch (err) {
534
+ ctx.logger.warn(`卸载 model entry "${modelId}" 失败: ${err}`);
535
+ }
536
+ registered.delete(modelId);
537
+ }
538
+ async function discoverAllModelIds() {
539
+ const remoteIds = await client.fetchRemoteModelIds();
540
+ const remoteSet = new Set(remoteIds);
541
+ for (const cm of openaiConfig.customModels) {
542
+ if (remoteSet.has(cm)) {
543
+ ctx.logger.warn(`自定义模型 "${cm}" 与自动发现的模型重复,请在配置中去重`);
544
+ }
545
+ }
546
+ return [...remoteIds, ...openaiConfig.customModels.filter(id => !remoteSet.has(id))];
547
+ }
548
+ // 初次注册
549
+ const initialIds = await discoverAllModelIds();
550
+ if (initialIds.length === 0) {
551
+ ctx.logger.warn(`已连接: ${openaiConfig.baseUrl},但未发现任何可用模型;不注册任何 LLM entry`);
552
+ }
553
+ else {
554
+ for (const modelId of initialIds)
555
+ registerOne(modelId);
556
+ ctx.logger.info(`已连接: ${openaiConfig.baseUrl},注册 ${initialIds.length} 个 model entry`);
557
+ }
558
+ // 装配 refresh 真实实现
559
+ refreshFn = async () => {
560
+ const next = await discoverAllModelIds();
561
+ const nextSet = new Set(next);
562
+ const added = [];
563
+ const removed = [];
564
+ for (const id of next) {
565
+ if (!registered.has(id)) {
566
+ registerOne(id);
567
+ added.push(id);
568
+ }
569
+ }
570
+ for (const id of [...registered.keys()]) {
571
+ if (!nextSet.has(id)) {
572
+ unregisterOne(id);
573
+ removed.push(id);
574
+ }
575
+ }
576
+ if (added.length || removed.length) {
577
+ ctx.logger.info(`OpenAI 模型列表已刷新: +${added.length} (${added.join(',') || '-'}) / -${removed.length} (${removed.join(',') || '-'}) / 现共 ${registered.size}`);
578
+ }
579
+ else {
580
+ ctx.logger.debug(`OpenAI 模型列表已刷新: 无变化 (共 ${registered.size})`);
581
+ }
582
+ return { added, removed, total: registered.size };
583
+ };
584
+ }
585
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAMjD,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEtE,oBAAoB;AAEpB,mBAAmB;AACnB,MAAM,uBAAuB,GAAG;IAC9B,qBAAqB;IACrB,gBAAgB;IAChB,gBAAgB;IAChB,mBAAmB;IACnB,cAAc;CACf,CAAC;AAEF,+BAA+B;AAC/B,SAAS,aAAa,CAAC,QAAgB,EAAE,MAAc,EAAE,IAAY;IACnE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,MAAM,KAAK,GAAG,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,OAAO,GAAG,QAAQ,iCAAiC,CAAC;IACtD,CAAC;IACD,OAAO,GAAG,QAAQ,YAAY,MAAM,MAAM,IAAI,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,0BAA0B,CAAC;AAC/C,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;AACpC,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC;AAChC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC;AAE7B,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,wBAAwB,EAAE;IACjG,OAAO,EAAE;QACP,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,wBAAwB;QACjC,WAAW,EAAE,uBAAuB;KACrC;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EACT,uDAAuD;KAC1D;IACD,iBAAiB,EAAE;QACjB,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,EAAE;QACX,WAAW,EACT,sNAAsN;KACzN;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,eAAe;QACtB,OAAO,EAAE,EAAE;QACX,WAAW,EACT,0EAA0E;KAC7E;IACD,OAAO,EAAE;QACP,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,GAAG;QACZ,WAAW,EAAE,uCAAuC;KACrD;IACD,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE;IACpF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,kBAAkB,EAAE;IAChG,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE;CAC7F,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAE,wBAAwB;IACjC,YAAY,EAAE,EAAE;IAChB,iBAAiB,EAAE,EAAE;IACrB,oBAAoB,EAAE,EAAE;IACxB,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,GAAG;IAChB,SAAS,EAAE,IAAI;IACf,aAAa,EAAE,MAAM;CACtB,CAAC;AAwEF,0FAA0F;AAC1F,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,qEAAqE;AAErE,MAAM,YAAY;IACR,MAAM,CAAS;IACd,OAAO,CAAS;IACjB,OAAO,CAAS;IACf,WAAW,CAAS;IACpB,SAAS,CAAS;IACnB,MAAM,CAAC;IAEf,YAAY,MAAoB,EAAE,MAAyB;QACzD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACjD,mDAAmD;QACnD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC;QAC5F,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,wCAAwC;IACxC,IAAY,OAAO;QACjB,MAAM,CAAC,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QACzE,IAAI,IAAI,CAAC,MAAM;YAAE,CAAC,CAAC,aAAa,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,sBAAsB;IACtB,KAAK,CAAC,mBAAmB;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,YAAY,EAAE;gBACnD,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA+B,CAAC;YAC9D,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,OAAyB;QACjD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACrF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzD,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,IAAI,GAA4B;YACpC,KAAK;YACL,QAAQ;YACR,4EAA4E;YAC5E,qDAAqD;YACrD,CAAC,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS;YACzF,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;SAC/E,CAAC;QAEF,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,MAAM,SAAS,KAAK,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;QAE9F,MAAM,OAAO,GAAkB,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACnE,IAAI,OAAO,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,sBAAsB,EAAE;YAClE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1B,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC;SACjC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAoB,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAE/B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,MAAM,GAAiB;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO;SAChC,CAAC;QAEF,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBACtD,EAAE,EAAE,EAAE,CAAC,EAAE;gBACT,IAAI,EAAE,UAAmB;gBACzB,QAAQ,EAAE;oBACR,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI;oBACtB,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS;iBACjC;aACF,CAAC,CAAC,CAAC;QACN,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,GAAG;gBACb,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa;gBACtC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB;gBAC9C,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB;gBACpE,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,aAAa;aACpE,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,CAAC,UAAU,CAAC,KAAa,EAAE,OAAyB;QACxD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACrF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzD,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,IAAI,GAA4B;YACpC,KAAK;YACL,QAAQ;YACR,8EAA8E;YAC9E,CAAC,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS;YACzF,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC9E,MAAM,EAAE,IAAI;SACb,CAAC;QAEF,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,MAAM,MAAM,CAAC,CAAC;QAErE,MAAM,OAAO,GAAkB,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACnE,IAAI,OAAO,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,MAAM,gBAAgB,GAAG,UAAU,CAAC,GAAG,EAAE;YACvC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,IAAI,CAAC,OAAO,uBAAuB,CAAC,CAAC;QACxF,CAAC,EAAE,MAAM,CAAC,CAAC;QAEX,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,sBAAsB,EAAE;gBAC5D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC;aACjC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,gBAAgB,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC;YACtC,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,OAAO,QAAQ,GAAG,EAAE,CAAC,CAAC;YAC3D,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,YAAY,CAAC,gBAAgB,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,QAAQ,CAAC,MAAM,QAAQ,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,IAAI,CAAC,CAAC;QAEzF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,GAAG,EAAsD,CAAC;QAEtF,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,gBAAgB,GAAG,KAAK,CAAC;QAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,MAAM,gBAAgB,GAAG,UAAU,CAAC,GAAG,EAAE;YACvC,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YACpD,CAAC;QACH,CAAC,EAAE,MAAM,CAAC,CAAC;QAEX,IAAI,CAAC;YACH,OAAO,IAAI,EAAE,CAAC;gBACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC5C,IAAI,IAAI;oBAAE,MAAM;gBAChB,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,gBAAgB,GAAG,IAAI,CAAC;oBACxB,YAAY,CAAC,gBAAgB,CAAC,CAAC;oBAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,aAAa,CAAC,CAAC;gBAC3E,CAAC;gBAED,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;gBAEtB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;oBAC5B,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC;wBAAE,SAAS;oBAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACjC,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;wBACzB,SAAS;wBACT,MAAM,SAAS,GAAe,EAAE,CAAC;wBACjC,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;4BAChF,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;wBACnG,CAAC;wBACD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;wBAC9E,OAAO;oBACT,CAAC;oBAED,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBACjC,MAAM,KAAK,GAAoB,EAAE,CAAC;wBAElC,uDAAuD;wBACvD,+CAA+C;wBAC/C,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;4BACf,KAAK,CAAC,KAAK,GAAG;gCACZ,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa;gCACtC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB;gCAC9C,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB;gCACpE,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,aAAa;6BACpE,CAAC;wBACJ,CAAC;wBAED,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;wBACvC,IAAI,CAAC,KAAK,EAAE,CAAC;4BACX,IAAI,KAAK,CAAC,KAAK;gCAAE,MAAM,KAAK,CAAC,CAAC,kBAAkB;4BAChD,SAAS;wBACX,CAAC;wBAED,IAAI,KAAK,CAAC,OAAO;4BAAE,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;wBAEtD,SAAS;wBACT,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;4BACrB,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gCAClC,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC;gCAC1B,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;oCACV,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;gCACnF,CAAC;gCACD,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gCACvC,IAAI,KAAK,EAAE,CAAC;oCACV,IAAI,EAAE,CAAC,QAAQ,EAAE,IAAI;wCAAE,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;oCACrD,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS;wCAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;oCAChE,wCAAwC;oCACxC,KAAK,CAAC,gBAAgB,GAAG;wCACvB,KAAK,EAAE,GAAG;wCACV,IAAI,EAAE,KAAK,CAAC,IAAI;wCAChB,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM;qCACpC,CAAC;gCACJ,CAAC;4BACH,CAAC;wBACH,CAAC;wBAED,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;4BAChE,MAAM,KAAK,CAAC;wBACd,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,yBAAyB;oBAC3B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,gBAAgB,CAAC,CAAC;YAC/B,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC;QAED,4CAA4C;QAC5C,MAAM,SAAS,GAAe,EAAE,CAAC;QACjC,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAChF,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnG,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IAChF,CAAC;IAEO,YAAY,CAAC,GAAY;QAC/B,sDAAsD;QACtD,uDAAuD;QACvD,8BAA8B;QAC9B,MAAM,MAAM,GAAe;YACzB,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YACzB,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAC;QAEF,6BAA6B;QAC7B,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC/D,MAAM,KAAK,GAA8F,EAAE,CAAC;YAC5G,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAClD,CAAC;YACD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;YAC7D,CAAC;YACD,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;QACzB,CAAC;QAED,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC3C,EAAE,EAAE,EAAE,CAAC,EAAE;gBACT,IAAI,EAAE,UAAmB;gBACzB,QAAQ,EAAE;oBACR,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI;oBACtB,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS;iBACjC;aACF,CAAC,CAAC,CAAC;QACN,CAAC;QAED,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACnB,MAAM,CAAC,YAAY,GAAG,GAAG,CAAC,UAAU,CAAC;QACvC,CAAC;QAED,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACzB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,SAAS,CAAC,IAAoB;QACpC,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE;gBACR,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;gBACxB,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;gBAC5B,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW;gBACtC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAqC;aAChE;SACF,CAAC;IACJ,CAAC;CACF;AAED,qBAAqB;AAErB,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC;AAE3E,MAAM,kBAAkB,GAAoC;IAC1D,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC;IAChD,aAAa,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC;IACrD,aAAa,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC;IAC7C,OAAO,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC;IACvC,eAAe,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC;IAC/C,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC;IACpB,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC;IAC3B,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC;IAC9B,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;IAC5C,SAAS,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;IACnD,SAAS,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;CACpD,CAAC;AAEF,MAAM,oBAAoB,GAAoB,CAAC,IAAI,CAAC,CAAC;AAErD,SAAS,mBAAmB,CAAC,KAAa,EAAE,YAAsB,EAAE,YAA8B;IAChG,MAAM,GAAG,GAAG,IAAI,GAAG,CAAgB,YAAY,IAAI,EAAE,CAAC,CAAC;IACvD,kBAAkB;IAClB,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3D,KAAK,MAAM,CAAC,IAAI,YAA+B;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO;IACP,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO;IACP,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC/D,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,KAAK,MAAM,CAAC,IAAI,IAAI;gBAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACjC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,oBAAoB;QAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;AAClB,CAAC;AAED,mBAAmB;AAEnB,4BAA4B;AAC5B,SAAS,iBAAiB,CAAC,GAAY;IACrC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC/C,OAAO,GAAG;SACP,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SAClB,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAS,sBAAsB,CAAC,GAAY;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC/C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,QAAQ,GAAG,CAAC;YAAE,SAAS;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,OAAO;aACjB,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC;aACnB,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aAClB,MAAM,CAAC,OAAO,CAAoB,CAAC;QACtC,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAS,yBAAyB,CAAC,GAAY;IAC7C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC/C,OAAO,GAAG;SACP,KAAK,CAAC,SAAS,CAAC;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SAClB,MAAM,CAAC,OAAO,CAAoB,CAAC;AACxC,CAAC;AAED,2DAA2D;AAE3D,MAAM,iBAAiB;IAEX;IACC;IACA;IACA;IACA;IAEA;IAEA;IATX,YACU,MAAoB,EACnB,EAAU,EACV,UAAkB,EAClB,aAAqB,EACrB,eAAuB;IAChC,mEAAmE;IAC1D,OAA6E;IACtF,mDAAmD;IAC1C,YAAsC;QARvC,WAAM,GAAN,MAAM,CAAc;QACnB,OAAE,GAAF,EAAE,CAAQ;QACV,eAAU,GAAV,UAAU,CAAQ;QAClB,kBAAa,GAAb,aAAa,CAAQ;QACrB,oBAAe,GAAf,eAAe,CAAQ;QAEvB,YAAO,GAAP,OAAO,CAAsE;QAE7E,iBAAY,GAAZ,YAAY,CAA0B;IAC9C,CAAC;IAEJ,IAAI,CAAC,OAAyB;QAC5B,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,OAAyB;QAClC,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,GAAY,EAAE,MAA+B;IACvE,MAAM,YAAY,GAAiB;QACjC,MAAM,EAAG,MAAM,CAAC,MAAiB,IAAI,EAAE;QACvC,OAAO,EAAG,MAAM,CAAC,OAAkB,IAAI,wBAAwB;QAC/D,YAAY,EAAE,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC;QACpD,iBAAiB,EAAE,sBAAsB,CAAC,MAAM,CAAC,iBAAiB,CAAC;QACnE,oBAAoB,EAAE,yBAAyB,CAAC,MAAM,CAAC,oBAAoB,CAAC;QAC5E,OAAO,EAAG,MAAM,CAAC,OAAkB,IAAI,GAAG;QAC1C,WAAW,EAAG,MAAM,CAAC,WAAsB,IAAI,GAAG;QAClD,SAAS,EAAG,MAAM,CAAC,SAAoB,IAAI,IAAI;QAC/C,aAAa,EAAG,MAAM,CAAC,aAAwB,IAAI,MAAM;KAC1D,CAAC;IAEF,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,YAAY,CAAC,OAAO,KAAK,wBAAwB,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,WAAW,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,GAAG,CAAC;IAEjF,6DAA6D;IAC7D,MAAM,UAAU,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEjD,mCAAmC;IACnC,IAAI,SAAS,GAAyE,KAAK,IAAI,EAAE,CAAC,CAAC;QACjG,KAAK,EAAE,EAAE;QACT,OAAO,EAAE,EAAE;QACX,KAAK,EAAE,UAAU,CAAC,IAAI;KACvB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,GAAmE,EAAE,CAAC,SAAS,EAAE,CAAC;IAElG,SAAS,WAAW,CAAC,OAAe;QAClC,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO;QACpC,MAAM,YAAY,GAAG,mBAAmB,CACtC,OAAO,EACP,YAAY,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAC3C,YAAY,CAAC,oBAAoB,CAClC,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAClC,MAAM,EACN,OAAO,EACP,GAAG,CAAC,EAAE,EACN,YAAY,CAAC,aAAa,EAC1B,YAAY,CAAC,SAAS,EACtB,OAAO,EACP,YAAY,CACb,CAAC;QACF,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE;YACzC,KAAK,EAAE,GAAG,SAAS,MAAM,OAAO,EAAE;YAClC,OAAO,EAAE,GAAG,GAAG,CAAC,EAAE,IAAI,OAAO,EAAE;SAChC,CAAC,CAAC;QACH,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,SAAS,aAAa,CAAC,OAAe;QACpC,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,IAAI,CAAC;YACH,CAAC,EAAE,CAAC;QACN,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,OAAO,SAAS,GAAG,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,UAAU,mBAAmB;QAChC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,mBAAmB,EAAE,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;QACrC,KAAK,MAAM,EAAE,IAAI,YAAY,CAAC,YAAY,EAAE,CAAC;YAC3C,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACtB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,SAAS,EAAE,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,OAAO;IACP,MAAM,UAAU,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC/C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,YAAY,CAAC,OAAO,6BAA6B,CAAC,CAAC;IAC7E,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,OAAO,IAAI,UAAU;YAAE,WAAW,CAAC,OAAO,CAAC,CAAC;QACvD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,YAAY,CAAC,OAAO,OAAO,UAAU,CAAC,MAAM,gBAAgB,CAAC,CAAC;IACxF,CAAC;IAED,kBAAkB;IAClB,SAAS,GAAG,KAAK,IAAI,EAAE;QACrB,MAAM,IAAI,GAAG,MAAM,mBAAmB,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACxB,WAAW,CAAC,EAAE,CAAC,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACrB,aAAa,CAAC,EAAE,CAAC,CAAC;gBAClB,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,oBAAoB,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,QAAQ,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,UAAU,UAAU,CAAC,IAAI,EAAE,CAC1I,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@aalis/plugin-llm-openai",
3
+ "version": "0.9.0",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/AalisLabs/Aalis.git",
8
+ "directory": "packages/plugin-llm-openai"
9
+ },
10
+ "author": "Ace Nyan <ace@acenyan.com>",
11
+ "bugs": {
12
+ "url": "https://github.com/AalisLabs/Aalis/issues"
13
+ },
14
+ "homepage": "https://github.com/AalisLabs/Aalis#readme",
15
+ "description": "OpenAI / 兼容接口 LLM 提供者(对话、工具、流式)",
16
+ "type": "module",
17
+ "keywords": [
18
+ "aalis",
19
+ "aalis-plugin"
20
+ ],
21
+ "main": "dist/index.js",
22
+ "types": "dist/index.d.ts",
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "dependencies": {
27
+ "@aalis/schema-config": ">=0.9.0 <1.0.0",
28
+ "@aalis/api-llm": ">=0.9.0 <1.0.0",
29
+ "@aalis/schema-message": ">=0.5.1 <1.0.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.0.0",
33
+ "typescript": "^5.7.0",
34
+ "@aalis/core": "0.10.0",
35
+ "@aalis/api-webui": "0.9.0",
36
+ "@aalis/api-tools": "0.5.1"
37
+ },
38
+ "peerDependencies": {
39
+ "@aalis/core": ">=0.2.0 <1.0.0"
40
+ },
41
+ "aalis": {
42
+ "service": {
43
+ "provides": [
44
+ "llm"
45
+ ]
46
+ }
47
+ },
48
+ "scripts": {
49
+ "build": "tsc",
50
+ "dev": "tsc --watch"
51
+ }
52
+ }