@aalis/api-llm 0.13.0 → 0.15.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/dist/index.d.ts +152 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +256 -22
- package/dist/index.js.map +1 -1
- package/dist/locales/en.d.ts +6 -0
- package/dist/locales/en.d.ts.map +1 -0
- package/dist/locales/en.js +6 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/texts.d.ts +11 -0
- package/dist/texts.d.ts.map +1 -0
- package/dist/texts.js +9 -0
- package/dist/texts.js.map +1 -0
- package/package.json +7 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ToolDefinition } from '@aalis/api-tools';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Events, ProviderEntry, ServiceSelection } from '@aalis/core';
|
|
3
|
+
import { type TextRef } from '@aalis/schema-i18n';
|
|
3
4
|
import type { Message, ToolCall } from '@aalis/schema-message';
|
|
4
5
|
export interface ChatResponse {
|
|
5
6
|
content: string | null;
|
|
@@ -18,10 +19,15 @@ export interface ChatResponse {
|
|
|
18
19
|
*/
|
|
19
20
|
cachedPromptTokens?: number;
|
|
20
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* 服务商报的结束原因:length 是在输出上限处停下(正文可能不完整),不在前四种里的原样值记 other(用 {@link finishReasonOf}
|
|
24
|
+
* 翻译)。服务商没报时没有这个字段——`undefined` 表示不可知,消费方认截断只看 `'length'`,不按用量或内容去猜
|
|
25
|
+
*/
|
|
26
|
+
finishReason?: 'stop' | 'length' | 'tool_calls' | 'content_filter' | 'other';
|
|
21
27
|
}
|
|
22
28
|
/**
|
|
23
29
|
* 工具调用增量进度(非完整 ToolCall,仅用于 UI 提示「正在生成」)。
|
|
24
|
-
* Provider
|
|
30
|
+
* Provider 每收到一个调用的增量就为它 yield 一个 chunk(一帧里有几个调用就各 yield 一个),
|
|
25
31
|
* 让上层可以渲染进度条而不必等整段 tool_calls 累积完。
|
|
26
32
|
*/
|
|
27
33
|
export interface ToolCallProgress {
|
|
@@ -46,18 +52,14 @@ export interface ChatStreamChunk {
|
|
|
46
52
|
/** 见 {@link ChatResponse.usage.cachedPromptTokens} */
|
|
47
53
|
cachedPromptTokens?: number;
|
|
48
54
|
};
|
|
55
|
+
/** 结束原因,随 done 那一段给出,见 {@link ChatResponse.finishReason} */
|
|
56
|
+
finishReason?: ChatResponse['finishReason'];
|
|
49
57
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
*/
|
|
56
|
-
capabilities: string[];
|
|
57
|
-
provider?: string;
|
|
58
|
-
contextId?: string;
|
|
59
|
-
contextLength?: number;
|
|
60
|
-
}
|
|
58
|
+
/**
|
|
59
|
+
* 服务商报的结束原因翻成 {@link ChatResponse.finishReason},给服务商用:前四种照原样,别的值记 other,没报(undefined 或 null)
|
|
60
|
+
* 时为 undefined
|
|
61
|
+
*/
|
|
62
|
+
export declare function finishReasonOf(raw: unknown): ChatResponse['finishReason'];
|
|
61
63
|
/** Per-model chat request:不再含 model/provider —— entry 已绑定。 */
|
|
62
64
|
export interface ChatModelRequest {
|
|
63
65
|
messages: Message[];
|
|
@@ -65,7 +67,11 @@ export interface ChatModelRequest {
|
|
|
65
67
|
temperature?: number;
|
|
66
68
|
maxTokens?: number;
|
|
67
69
|
signal?: AbortSignal;
|
|
68
|
-
|
|
70
|
+
/**
|
|
71
|
+
* 深度思考的档位:模型声明的 {@link LLMModel.thinking} 里某一档的 id;没带时按模型的默认档。模型不能调(没声明档位)时
|
|
72
|
+
* 不带,带了模型没有的档位提供者拒绝(见 {@link requestedThinking})
|
|
73
|
+
*/
|
|
74
|
+
think?: string;
|
|
69
75
|
/**
|
|
70
76
|
* 消息里的图片是否为必需载荷。缺省 false。
|
|
71
77
|
*
|
|
@@ -78,6 +84,12 @@ export interface ChatModelRequest {
|
|
|
78
84
|
* 这个判断只有调用方做得了,provider 无从区分两种语义。
|
|
79
85
|
*/
|
|
80
86
|
requireImages?: boolean;
|
|
87
|
+
/** 这次调用做什么用,记账用:给人看的短语,如「对话」「摘要」「识图」「子任务」。调用方填,可以缺 */
|
|
88
|
+
purpose?: string;
|
|
89
|
+
/** 这次调用所在的会话,记账用。调用方填,可以缺 */
|
|
90
|
+
sessionId?: string;
|
|
91
|
+
/** 调用方的插件实例,记账用:经 `llm` 的绑定接口调用时按调用方这次激活填上,调用方自己填的不算 */
|
|
92
|
+
caller?: string;
|
|
81
93
|
}
|
|
82
94
|
/**
|
|
83
95
|
* 单个 LLM model 的 service entry。
|
|
@@ -87,10 +99,10 @@ export interface ChatModelRequest {
|
|
|
87
99
|
* model handle 上的 capabilities 字段诚实地反映该 model 的能力。
|
|
88
100
|
*
|
|
89
101
|
* 调用约定:
|
|
90
|
-
* const handle = resolveLLMModel(llm, ref, ['vision'])?.
|
|
102
|
+
* const handle = resolveLLMModel(llm, ref, ['vision'])?.use;
|
|
91
103
|
* await handle?.chat({ messages }); // entry 已知道是哪个 model
|
|
92
104
|
*
|
|
93
|
-
*
|
|
105
|
+
* 默认 model 是 llm 服务的偏好,由用户经管理面(WebUI 或宿主配置的 `servicePreferences`)设为 `<provider>/<model>`。
|
|
94
106
|
*/
|
|
95
107
|
export interface LLMModel {
|
|
96
108
|
/** model id(provider 内唯一,如 'gpt-4o')。来源:provider plugin 注册时填入。 */
|
|
@@ -111,6 +123,8 @@ export interface LLMModel {
|
|
|
111
123
|
* **不是** DI 选择机制(服务选择一律走配置 + 按名解析)。provider 注册时填。
|
|
112
124
|
*/
|
|
113
125
|
readonly capabilities: readonly LLMCapability[];
|
|
126
|
+
/** 能调深度思考的模型允许的档位;不能调的模型不声明 */
|
|
127
|
+
readonly thinking?: ThinkingLevels;
|
|
114
128
|
chat(request: ChatModelRequest): Promise<ChatResponse>;
|
|
115
129
|
chatStream?(request: ChatModelRequest): AsyncIterable<ChatStreamChunk>;
|
|
116
130
|
/**
|
|
@@ -130,12 +144,91 @@ export interface LLMModel {
|
|
|
130
144
|
removed: string[];
|
|
131
145
|
total: number;
|
|
132
146
|
}>;
|
|
147
|
+
/**
|
|
148
|
+
* 查服务商账户的余额(可选):服务商有余额接口才实现,同一 provider 下所有 model entries 共享同一份,按 providerId
|
|
149
|
+
* 找任一 entry 调一次即可。查不到(不可达、超时、认证失败、回应认不出)时抛错,消息带原因
|
|
150
|
+
*/
|
|
151
|
+
balance?(signal?: AbortSignal): Promise<LLMBalance[]>;
|
|
152
|
+
}
|
|
153
|
+
/** 服务商账户的余额:一个币种一项 */
|
|
154
|
+
export interface LLMBalance {
|
|
155
|
+
readonly currency: string;
|
|
156
|
+
readonly amount: number;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 一次模型调用的用量,`llm:usage` 事件的内容。cachedTokens 是 inputTokens 里前缀缓存命中的部分,服务商不报时没有
|
|
160
|
+
* (与 0 不同);caller、sessionId、purpose 取请求里的同名字段
|
|
161
|
+
*/
|
|
162
|
+
export interface LLMUsageEvent {
|
|
163
|
+
/** 服务商:模型所属 provider 的实例 id({@link LLMModel.providerId}) */
|
|
164
|
+
provider: string;
|
|
165
|
+
model: string;
|
|
166
|
+
caller?: string;
|
|
167
|
+
sessionId?: string;
|
|
168
|
+
purpose?: string;
|
|
169
|
+
inputTokens: number;
|
|
170
|
+
cachedTokens?: number;
|
|
171
|
+
outputTokens: number;
|
|
172
|
+
}
|
|
173
|
+
declare module '@aalis/core' {
|
|
174
|
+
interface AalisEvents {
|
|
175
|
+
/** 一次模型调用结束、服务商报了用量:发射方是服务商登记的 {@link metered} 模型,消费方如记账插件 */
|
|
176
|
+
'llm:usage': [usage: LLMUsageEvent];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* 给登记的模型包上记账:chat 拿到用量、chatStream 结束时报过用量(取最后一次报的),就发一次 `llm:usage`,不等监听器。
|
|
181
|
+
* 服务商登记模型时套一层,`provide(llm, metered(model, events), { entryId })`,自己的 chat 与 chatStream 不用管记账。
|
|
182
|
+
* 服务商回的数运行时没人核,在这里规整一次:没报用量、输入或输出不是非负有限数的调用不记;缓存命中不是非负有限数时当没报,
|
|
183
|
+
* 比输入多时截到输入
|
|
184
|
+
*/
|
|
185
|
+
export declare function metered(model: LLMModel, events: Pick<Events, 'emit'>): LLMModel;
|
|
186
|
+
/** 定时器能表示的最长时限(2^31−1 毫秒,约 24.8 天):idleTimeout 的 ms 超过它时按它计,报错里写时限的照它截 */
|
|
187
|
+
export declare const IDLE_TIMEOUT_MAX_MS: number;
|
|
188
|
+
/**
|
|
189
|
+
* 生成请求的超时按停顿计,给服务商用:signal 交给请求,从调用起计时,每次 touch 重新计时,停顿(不算 pause 到 resume 之间)满
|
|
190
|
+
* ms 毫秒时 signal 以 TimeoutError 中止;调用方的 signal 中止时 signal 随之中止,原因照抄。ms 为 0 或负数时不限,超过
|
|
191
|
+
* IDLE_TIMEOUT_MAX_MS 时按它计,不是数(含 NaN)时抛 RangeError。流式请求每解析出一段带生成内容的增量(正文、思考、工具调用的
|
|
192
|
+
* 名字与参数)调一次 touch,保活注释、空行与没有生成内容的帧不调;交出一段之前调 pause、调用方回来取下一段时调 resume,其间不
|
|
193
|
+
* 计时、之后接着计,调用方处理一段的时间不算停顿;已暂停时再调 pause、没暂停时调 resume 都不起作用。不流式的请求都不调,即
|
|
194
|
+
* ms 内没读完整份回复就中止。计时器不拖住进程退出,请求结束后不用收尾。Node 自带的 fetch 等响应头与读响应体默认各有 300 秒
|
|
195
|
+
* 时限,生成请求要换一个不设这两个时限的 dispatcher,ms 才是唯一的时限
|
|
196
|
+
*/
|
|
197
|
+
export declare function idleTimeout(ms: number, signal?: AbortSignal): {
|
|
198
|
+
readonly signal: AbortSignal;
|
|
199
|
+
touch(): void;
|
|
200
|
+
pause(): void;
|
|
201
|
+
resume(): void;
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* 一个思考档位:id 是提供者自己的写法(请求的 think 填它),label 给人看,可以是文字对象(@aalis/schema-i18n),出口按读者语言
|
|
205
|
+
* 渲染;给模型或写日志的取 toSource
|
|
206
|
+
*/
|
|
207
|
+
export interface ThinkingLevel {
|
|
208
|
+
readonly id: string;
|
|
209
|
+
readonly label: string | TextRef;
|
|
133
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* 模型允许的思考档位:levels 由浅到深排、至少两档(开关型就是「关、开」两档),default 是请求没带档位时用的那一档,
|
|
213
|
+
* 须是 levels 里的一个。档位由各提供者按自己的协议定义并翻成线上字段,不做跨服务商的统一档位表
|
|
214
|
+
*/
|
|
215
|
+
export interface ThinkingLevels {
|
|
216
|
+
readonly levels: readonly ThinkingLevel[];
|
|
217
|
+
readonly default: string;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* 请求带的思考档位:没带时为 undefined;带了却不在模型声明的档位里(含模型不能调时带了档位)时抛给人看的错(TextError)。
|
|
221
|
+
* 提供者把档位翻成线上字段之前先过它,调用方要先按模型声明的档位选
|
|
222
|
+
*/
|
|
223
|
+
export declare function requestedThinking(model: Pick<LLMModel, 'id' | 'thinking'>, request: Pick<ChatModelRequest, 'think'>): string | undefined;
|
|
224
|
+
/** 模型最浅的一档:机械任务(摘要、标题、结构化提取)要压低思考时带它;模型不能调时为 undefined */
|
|
225
|
+
export declare function lightestThinking(model: Pick<LLMModel, 'thinking'>): string | undefined;
|
|
134
226
|
export interface LLMCapabilityRegistry {
|
|
135
227
|
Chat: 'chat';
|
|
136
228
|
ToolCalling: 'tool_calling';
|
|
137
229
|
Streaming: 'streaming';
|
|
138
230
|
Vision: 'vision';
|
|
231
|
+
/** 会思考(产出思考内容);能不能按请求调档看 {@link LLMModel.thinking} */
|
|
139
232
|
Thinking: 'thinking';
|
|
140
233
|
/** 原生音频理解(能接收音频输入,返回描述/问答,如 Gemini / GPT-4o-audio / Gemma 4 E系列) */
|
|
141
234
|
Audio: 'audio';
|
|
@@ -161,17 +254,11 @@ declare module '@aalis/schema-config' {
|
|
|
161
254
|
* LLM 模型引用:值为 {@link ModelRef},前端渲染为
|
|
162
255
|
* 联动 select(provider 列表来自 `/api/models/llm` 的 contextId 聚合;
|
|
163
256
|
* model 列表由所选 provider 决定)。运行时由消费方用
|
|
164
|
-
* `resolveLLMModel(llm, value, caps)` 解析。parseConfig 不校验这个类型的取值,除 `''`(未选)外原样透传。
|
|
257
|
+
* `resolveLLMModel(caps.llm, value, caps)` 解析。parseConfig 不校验这个类型的取值,除 `''`(未选)外原样透传。
|
|
165
258
|
*/
|
|
166
259
|
'llm-ref': ModelRef;
|
|
167
260
|
}
|
|
168
261
|
}
|
|
169
|
-
/** 一个 'llm' entry 的快照(ServiceRef.all() 所返 ServiceView 的 instance/contextId/label 子集)。 */
|
|
170
|
-
export interface LLMModelEntry {
|
|
171
|
-
instance: LLMModel;
|
|
172
|
-
contextId: string;
|
|
173
|
-
label?: string;
|
|
174
|
-
}
|
|
175
262
|
/**
|
|
176
263
|
* LLM model 引用:`{ provider, model }` 二元组。
|
|
177
264
|
* 由 ConfigSchema type='llm-ref' 字段统一编辑,YAML 中以嵌套对象形式存储。
|
|
@@ -182,24 +269,54 @@ export interface ModelRef {
|
|
|
182
269
|
/** model id(provider 内唯一,如 `gpt-4o`)。 */
|
|
183
270
|
model?: string;
|
|
184
271
|
}
|
|
272
|
+
/** 模型引用写成文字:条目 id `<提供者实例 id>/<模型 id>`,与 `/model` 列出的写法相同 */
|
|
273
|
+
export declare function entryIdOf(ref: ModelRef): string;
|
|
274
|
+
/**
|
|
275
|
+
* 条目 id 读成模型引用:开头的 npm scope(`@scope/`)跳过,到下一个 `/` 为止是提供者实例 id,余下是模型 id(模型 id 里的
|
|
276
|
+
* 斜杠留在模型里);拆不出非空的两段时为 undefined。提供者实例 id 的后缀里带 `/` 的拆不准,这类实例的模型要在界面里选
|
|
277
|
+
*/
|
|
278
|
+
export declare function modelRefOf(text: string): ModelRef | undefined;
|
|
279
|
+
/** llm-ref 字段的取值校验与文字读写:服务与模型都是非空字符串,文字是条目 id。字段定义里展开它 */
|
|
280
|
+
export declare const MODEL_REF_TEXT: {
|
|
281
|
+
validate(value: unknown): TextRef | undefined;
|
|
282
|
+
fromText: typeof modelRefOf;
|
|
283
|
+
toText: (value: unknown) => string;
|
|
284
|
+
};
|
|
285
|
+
/**
|
|
286
|
+
* 按能力过滤 llm 的提供者条目 —— 能力源为模型自带的元数据 `use.capabilities`,
|
|
287
|
+
* 不是 core 的能力选择(服务选择走配置 + 按名解析)。
|
|
288
|
+
*/
|
|
185
289
|
/**
|
|
186
|
-
* 列出(可按能力过滤的)
|
|
187
|
-
* 能力源为 `
|
|
290
|
+
* 列出(可按能力过滤的)llm 提供者条目,供 `/model` 列表与前端下拉用。
|
|
291
|
+
* 能力源为 `use.capabilities`(model 自带元数据),是展示/列举用途,非 DI 选择。
|
|
188
292
|
*/
|
|
189
|
-
export declare function listLLMModels(source:
|
|
293
|
+
export declare function listLLMModels(source: Pick<ServiceSelection<LLMModel>, 'list'>, opts?: {
|
|
190
294
|
caps?: readonly LLMCapability[];
|
|
191
|
-
}):
|
|
295
|
+
}): ProviderEntry<LLMModel>[];
|
|
192
296
|
/**
|
|
193
|
-
*
|
|
297
|
+
* 在 `list()` 上把 ref 解析为最匹配的提供者条目。
|
|
194
298
|
*
|
|
195
299
|
* 解析顺序(命中即返回):
|
|
196
|
-
* 1. ref.provider + ref.model 都有 →
|
|
197
|
-
* 2. 仅 ref.provider → 在该 provider
|
|
198
|
-
* 3. 仅 ref.model →
|
|
199
|
-
* 4. 都为空 → 取首个满足 capability
|
|
300
|
+
* 1. ref.provider + ref.model 都有 → 直接拼接条目 id `${provider}/${model}` 查找
|
|
301
|
+
* 2. 仅 ref.provider → 在该 provider 名下的条目中(按 capability 过滤后)取首个
|
|
302
|
+
* 3. 仅 ref.model → 按模型自己的 `use.id` 严格匹配
|
|
303
|
+
* 4. 都为空 → 取首个满足 capability 的条目(本插件选中的那一家在前,其余按挑选规则排)
|
|
200
304
|
*
|
|
201
|
-
* requiredCaps
|
|
305
|
+
* requiredCaps 按模型元数据 `use.capabilities` 过滤。找不到返回 undefined。
|
|
306
|
+
*/
|
|
307
|
+
export declare function resolveLLMModel(source: Pick<ServiceSelection<LLMModel>, 'list'>, ref?: ModelRef | null, requiredCaps?: LLMCapability[]): ProviderEntry<LLMModel> | undefined;
|
|
308
|
+
/**
|
|
309
|
+
* 后台功能取对话模型(摘要、提取、压缩这类插件):每次取 llm 服务给本插件挑的能对话的那一个(本插件偏好 › 全局偏好 › 优先级,
|
|
310
|
+
* 偏好指向的不在时落到下一级)。取不到时 onMissing 只在连着取不到的第一次调(一个插件只告警一次),取到之后复位
|
|
311
|
+
*/
|
|
312
|
+
export declare function chatModelPicker(source: Pick<ServiceSelection<LLMModel>, 'list'>, onMissing: () => void): () => ProviderEntry<LLMModel> | undefined;
|
|
313
|
+
/** 估算文本的 token 数(区分中文与 ASCII) */
|
|
314
|
+
export declare function estimateTextTokens(text: string): number;
|
|
315
|
+
/** 估算单条消息的 token 数(含 toolCalls + reasoningContent) */
|
|
316
|
+
export declare function estimateMsgTokens(msg: Message): number;
|
|
317
|
+
/**
|
|
318
|
+
* 调用型。业务层在请求里填上调用方这次激活的实例 id({@link ChatModelRequest.caller}),其余成员照原样转发。
|
|
319
|
+
* 按模型选就是按条目 id 选:`caps.llm.of('<provider>/<model>')`;按能力筛遍历 `caps.llm.list()`,读条目的 `use.capabilities`
|
|
202
320
|
*/
|
|
203
|
-
export declare
|
|
204
|
-
export declare const llm: import("@aalis/core").ServiceDescriptor<LLMModel, ServiceRef<LLMModel>>;
|
|
321
|
+
export declare const llm: import("@aalis/core").ServiceDescriptor<LLMModel, LLMModel>;
|
|
205
322
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,145 @@
|
|
|
3
3
|
// 提供完整的 LLM 抽象 + 能力声明框架。
|
|
4
4
|
// 任何需要调用或实现 LLM 服务的插件都应从本包导入相关类型。
|
|
5
5
|
import { defineService } from '@aalis/core';
|
|
6
|
+
import { TextError } from '@aalis/schema-i18n';
|
|
7
|
+
import { t } from './texts.js';
|
|
8
|
+
const FINISH_REASONS = ['stop', 'length', 'tool_calls', 'content_filter'];
|
|
9
|
+
/**
|
|
10
|
+
* 服务商报的结束原因翻成 {@link ChatResponse.finishReason},给服务商用:前四种照原样,别的值记 other,没报(undefined 或 null)
|
|
11
|
+
* 时为 undefined
|
|
12
|
+
*/
|
|
13
|
+
export function finishReasonOf(raw) {
|
|
14
|
+
if (raw === undefined || raw === null)
|
|
15
|
+
return undefined;
|
|
16
|
+
return FINISH_REASONS.find(reason => reason === raw) ?? 'other';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 换掉 chat 与 chatStream,其余字段与方法照原样转给 model。逐个字段列出,LLMModel 加了字段这里漏写时编译报错
|
|
20
|
+
* (chatStream 要写出来,没有时是 undefined)
|
|
21
|
+
*/
|
|
22
|
+
function withCalls(model, calls) {
|
|
23
|
+
const refresh = model.refresh?.bind(model);
|
|
24
|
+
const balance = model.balance?.bind(model);
|
|
25
|
+
return {
|
|
26
|
+
id: model.id,
|
|
27
|
+
providerId: model.providerId,
|
|
28
|
+
contextLength: model.contextLength,
|
|
29
|
+
maxOutputTokens: model.maxOutputTokens,
|
|
30
|
+
capabilities: model.capabilities,
|
|
31
|
+
thinking: model.thinking,
|
|
32
|
+
...calls,
|
|
33
|
+
refresh,
|
|
34
|
+
balance,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const isCount = (value) => typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
|
38
|
+
/**
|
|
39
|
+
* 给登记的模型包上记账:chat 拿到用量、chatStream 结束时报过用量(取最后一次报的),就发一次 `llm:usage`,不等监听器。
|
|
40
|
+
* 服务商登记模型时套一层,`provide(llm, metered(model, events), { entryId })`,自己的 chat 与 chatStream 不用管记账。
|
|
41
|
+
* 服务商回的数运行时没人核,在这里规整一次:没报用量、输入或输出不是非负有限数的调用不记;缓存命中不是非负有限数时当没报,
|
|
42
|
+
* 比输入多时截到输入
|
|
43
|
+
*/
|
|
44
|
+
export function metered(model, events) {
|
|
45
|
+
const report = (request, usage) => {
|
|
46
|
+
if (!usage || !isCount(usage.promptTokens) || !isCount(usage.completionTokens))
|
|
47
|
+
return;
|
|
48
|
+
const cached = usage.cachedPromptTokens;
|
|
49
|
+
void events.emit('llm:usage', {
|
|
50
|
+
provider: model.providerId,
|
|
51
|
+
model: model.id,
|
|
52
|
+
caller: request.caller,
|
|
53
|
+
sessionId: request.sessionId,
|
|
54
|
+
purpose: request.purpose,
|
|
55
|
+
inputTokens: usage.promptTokens,
|
|
56
|
+
...(isCount(cached) ? { cachedTokens: Math.min(cached, usage.promptTokens) } : {}),
|
|
57
|
+
outputTokens: usage.completionTokens,
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
const { chatStream } = model;
|
|
61
|
+
return withCalls(model, {
|
|
62
|
+
async chat(request) {
|
|
63
|
+
const response = await model.chat(request);
|
|
64
|
+
report(request, response.usage);
|
|
65
|
+
return response;
|
|
66
|
+
},
|
|
67
|
+
chatStream: chatStream &&
|
|
68
|
+
async function* (request) {
|
|
69
|
+
let usage;
|
|
70
|
+
try {
|
|
71
|
+
for await (const chunk of chatStream.call(model, request)) {
|
|
72
|
+
if (chunk.usage)
|
|
73
|
+
usage = chunk.usage;
|
|
74
|
+
yield chunk;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
report(request, usage);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// ----- 生成请求的超时 -----
|
|
84
|
+
/** 定时器能表示的最长时限(2^31−1 毫秒,约 24.8 天):idleTimeout 的 ms 超过它时按它计,报错里写时限的照它截 */
|
|
85
|
+
export const IDLE_TIMEOUT_MAX_MS = 2 ** 31 - 1;
|
|
86
|
+
/**
|
|
87
|
+
* 生成请求的超时按停顿计,给服务商用:signal 交给请求,从调用起计时,每次 touch 重新计时,停顿(不算 pause 到 resume 之间)满
|
|
88
|
+
* ms 毫秒时 signal 以 TimeoutError 中止;调用方的 signal 中止时 signal 随之中止,原因照抄。ms 为 0 或负数时不限,超过
|
|
89
|
+
* IDLE_TIMEOUT_MAX_MS 时按它计,不是数(含 NaN)时抛 RangeError。流式请求每解析出一段带生成内容的增量(正文、思考、工具调用的
|
|
90
|
+
* 名字与参数)调一次 touch,保活注释、空行与没有生成内容的帧不调;交出一段之前调 pause、调用方回来取下一段时调 resume,其间不
|
|
91
|
+
* 计时、之后接着计,调用方处理一段的时间不算停顿;已暂停时再调 pause、没暂停时调 resume 都不起作用。不流式的请求都不调,即
|
|
92
|
+
* ms 内没读完整份回复就中止。计时器不拖住进程退出,请求结束后不用收尾。Node 自带的 fetch 等响应头与读响应体默认各有 300 秒
|
|
93
|
+
* 时限,生成请求要换一个不设这两个时限的 dispatcher,ms 才是唯一的时限
|
|
94
|
+
*/
|
|
95
|
+
export function idleTimeout(ms, signal) {
|
|
96
|
+
if (typeof ms !== 'number' || Number.isNaN(ms))
|
|
97
|
+
throw new RangeError(`idleTimeout: ms is not a number: ${String(ms)}`);
|
|
98
|
+
const controller = new AbortController();
|
|
99
|
+
const limit = Math.min(ms, IDLE_TIMEOUT_MAX_MS);
|
|
100
|
+
const abort = () => controller.abort(new DOMException(`No new content within ${limit}ms`, 'TimeoutError'));
|
|
101
|
+
/** 到时限的时刻;暂停时 left 记着还剩多久 */
|
|
102
|
+
let deadline = performance.now() + limit;
|
|
103
|
+
let left = limit;
|
|
104
|
+
let paused = false;
|
|
105
|
+
let timer = limit > 0 ? setTimeout(abort, limit).unref() : undefined;
|
|
106
|
+
return {
|
|
107
|
+
signal: signal ? AbortSignal.any([controller.signal, signal]) : controller.signal,
|
|
108
|
+
touch: () => {
|
|
109
|
+
deadline = performance.now() + limit;
|
|
110
|
+
timer?.refresh();
|
|
111
|
+
},
|
|
112
|
+
pause: () => {
|
|
113
|
+
if (paused)
|
|
114
|
+
return;
|
|
115
|
+
paused = true;
|
|
116
|
+
clearTimeout(timer);
|
|
117
|
+
left = deadline - performance.now();
|
|
118
|
+
},
|
|
119
|
+
resume: () => {
|
|
120
|
+
if (!paused)
|
|
121
|
+
return;
|
|
122
|
+
paused = false;
|
|
123
|
+
if (!timer)
|
|
124
|
+
return;
|
|
125
|
+
deadline = performance.now() + left;
|
|
126
|
+
timer = setTimeout(abort, Math.max(left, 0)).unref();
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 请求带的思考档位:没带时为 undefined;带了却不在模型声明的档位里(含模型不能调时带了档位)时抛给人看的错(TextError)。
|
|
132
|
+
* 提供者把档位翻成线上字段之前先过它,调用方要先按模型声明的档位选
|
|
133
|
+
*/
|
|
134
|
+
export function requestedThinking(model, request) {
|
|
135
|
+
const { think } = request;
|
|
136
|
+
if (think !== undefined && !model.thinking?.levels.some(level => level.id === think)) {
|
|
137
|
+
throw new TextError(t('noSuchLevel', { model: model.id, level: think }));
|
|
138
|
+
}
|
|
139
|
+
return think;
|
|
140
|
+
}
|
|
141
|
+
/** 模型最浅的一档:机械任务(摘要、标题、结构化提取)要压低思考时带它;模型不能调时为 undefined */
|
|
142
|
+
export function lightestThinking(model) {
|
|
143
|
+
return model.thinking?.levels[0]?.id;
|
|
144
|
+
}
|
|
6
145
|
export const LLMCapabilities = {
|
|
7
146
|
Chat: 'chat',
|
|
8
147
|
ToolCalling: 'tool_calling',
|
|
@@ -13,44 +152,139 @@ export const LLMCapabilities = {
|
|
|
13
152
|
AudioTranscription: 'audio_transcription',
|
|
14
153
|
Video: 'video',
|
|
15
154
|
};
|
|
155
|
+
/** 模型引用写成文字:条目 id `<提供者实例 id>/<模型 id>`,与 `/model` 列出的写法相同 */
|
|
156
|
+
export function entryIdOf(ref) {
|
|
157
|
+
return `${ref.provider}/${ref.model}`;
|
|
158
|
+
}
|
|
16
159
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
160
|
+
* 条目 id 读成模型引用:开头的 npm scope(`@scope/`)跳过,到下一个 `/` 为止是提供者实例 id,余下是模型 id(模型 id 里的
|
|
161
|
+
* 斜杠留在模型里);拆不出非空的两段时为 undefined。提供者实例 id 的后缀里带 `/` 的拆不准,这类实例的模型要在界面里选
|
|
19
162
|
*/
|
|
20
|
-
function
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
163
|
+
export function modelRefOf(text) {
|
|
164
|
+
const start = text.startsWith('@') ? text.indexOf('/') + 1 : 0;
|
|
165
|
+
const cut = text.indexOf('/', start);
|
|
166
|
+
if (cut <= start || cut === text.length - 1)
|
|
167
|
+
return undefined;
|
|
168
|
+
return { provider: text.slice(0, cut), model: text.slice(cut + 1) };
|
|
25
169
|
}
|
|
170
|
+
/** llm-ref 字段的取值校验与文字读写:服务与模型都是非空字符串,文字是条目 id。字段定义里展开它 */
|
|
171
|
+
export const MODEL_REF_TEXT = {
|
|
172
|
+
validate(value) {
|
|
173
|
+
const ref = value;
|
|
174
|
+
return typeof ref?.provider === 'string' && ref.provider !== '' && typeof ref.model === 'string' && ref.model !== ''
|
|
175
|
+
? undefined
|
|
176
|
+
: t('badModelRef');
|
|
177
|
+
},
|
|
178
|
+
fromText: modelRefOf,
|
|
179
|
+
toText: (value) => entryIdOf(value),
|
|
180
|
+
};
|
|
26
181
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
182
|
+
* 按能力过滤 llm 的提供者条目 —— 能力源为模型自带的元数据 `use.capabilities`,
|
|
183
|
+
* 不是 core 的能力选择(服务选择走配置 + 按名解析)。
|
|
184
|
+
*/
|
|
185
|
+
/**
|
|
186
|
+
* 列出(可按能力过滤的)llm 提供者条目,供 `/model` 列表与前端下拉用。
|
|
187
|
+
* 能力源为 `use.capabilities`(model 自带元数据),是展示/列举用途,非 DI 选择。
|
|
29
188
|
*/
|
|
30
189
|
export function listLLMModels(source, opts) {
|
|
31
|
-
|
|
190
|
+
const all = source.list();
|
|
191
|
+
const caps = opts?.caps;
|
|
192
|
+
if (!caps || caps.length === 0)
|
|
193
|
+
return all;
|
|
194
|
+
return all.filter(e => caps.every(c => (e.use.capabilities ?? []).includes(c)));
|
|
32
195
|
}
|
|
33
196
|
/**
|
|
34
|
-
*
|
|
197
|
+
* 在 `list()` 上把 ref 解析为最匹配的提供者条目。
|
|
35
198
|
*
|
|
36
199
|
* 解析顺序(命中即返回):
|
|
37
|
-
* 1. ref.provider + ref.model 都有 →
|
|
38
|
-
* 2. 仅 ref.provider → 在该 provider
|
|
39
|
-
* 3. 仅 ref.model →
|
|
40
|
-
* 4. 都为空 → 取首个满足 capability
|
|
200
|
+
* 1. ref.provider + ref.model 都有 → 直接拼接条目 id `${provider}/${model}` 查找
|
|
201
|
+
* 2. 仅 ref.provider → 在该 provider 名下的条目中(按 capability 过滤后)取首个
|
|
202
|
+
* 3. 仅 ref.model → 按模型自己的 `use.id` 严格匹配
|
|
203
|
+
* 4. 都为空 → 取首个满足 capability 的条目(本插件选中的那一家在前,其余按挑选规则排)
|
|
41
204
|
*
|
|
42
|
-
* requiredCaps
|
|
205
|
+
* requiredCaps 按模型元数据 `use.capabilities` 过滤。找不到返回 undefined。
|
|
43
206
|
*/
|
|
44
207
|
export function resolveLLMModel(source, ref, requiredCaps) {
|
|
45
|
-
const all =
|
|
208
|
+
const all = listLLMModels(source, { caps: requiredCaps });
|
|
46
209
|
if (ref?.provider && ref?.model)
|
|
47
|
-
return all.find(e => e.
|
|
210
|
+
return all.find(e => e.id === `${ref.provider}/${ref.model}`);
|
|
48
211
|
if (ref?.provider)
|
|
49
|
-
return all.find(e => e.
|
|
212
|
+
return all.find(e => e.id.startsWith(`${ref.provider}/`));
|
|
50
213
|
if (ref?.model)
|
|
51
|
-
return all.find(e => e.
|
|
214
|
+
return all.find(e => e.use.id === ref.model);
|
|
52
215
|
return all[0];
|
|
53
216
|
}
|
|
54
|
-
|
|
55
|
-
|
|
217
|
+
/**
|
|
218
|
+
* 后台功能取对话模型(摘要、提取、压缩这类插件):每次取 llm 服务给本插件挑的能对话的那一个(本插件偏好 › 全局偏好 › 优先级,
|
|
219
|
+
* 偏好指向的不在时落到下一级)。取不到时 onMissing 只在连着取不到的第一次调(一个插件只告警一次),取到之后复位
|
|
220
|
+
*/
|
|
221
|
+
export function chatModelPicker(source, onMissing) {
|
|
222
|
+
let missing = false;
|
|
223
|
+
return () => {
|
|
224
|
+
const entry = resolveLLMModel(source, undefined, ['chat']);
|
|
225
|
+
if (!entry && !missing)
|
|
226
|
+
onMissing();
|
|
227
|
+
missing = entry === undefined;
|
|
228
|
+
return entry;
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
// ----- Token 估算 -----
|
|
232
|
+
//
|
|
233
|
+
// 大多数 BPE tokenizer (GPT / DeepSeek / Qwen) 经验值:
|
|
234
|
+
// - ASCII 字符 ~ 3.5 字符 / token
|
|
235
|
+
// - CJK 字符 ~ 1.5 token / 字符
|
|
236
|
+
// 保守取高,避免超限。
|
|
237
|
+
const CJK_REGEX = /[\u2E80-\u9FFF\uA000-\uA4FF\uAC00-\uD7FF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF]/;
|
|
238
|
+
/** 估算文本的 token 数(区分中文与 ASCII) */
|
|
239
|
+
export function estimateTextTokens(text) {
|
|
240
|
+
let tokens = 0;
|
|
241
|
+
let i = 0;
|
|
242
|
+
while (i < text.length) {
|
|
243
|
+
if (CJK_REGEX.test(text[i])) {
|
|
244
|
+
tokens += 1.5;
|
|
245
|
+
i++;
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
let asciiLen = 0;
|
|
249
|
+
while (i < text.length && !CJK_REGEX.test(text[i])) {
|
|
250
|
+
asciiLen++;
|
|
251
|
+
i++;
|
|
252
|
+
}
|
|
253
|
+
tokens += Math.ceil(asciiLen / 3.5);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return Math.ceil(tokens);
|
|
257
|
+
}
|
|
258
|
+
/** 单张图片的保守 token 估算(实测 800×600 静图经 ViT 编码为 500–800 visual token)。 */
|
|
259
|
+
const IMAGE_TOKENS_ESTIMATE = 800;
|
|
260
|
+
/** 估算单条消息的 token 数(含 toolCalls + reasoningContent) */
|
|
261
|
+
export function estimateMsgTokens(msg) {
|
|
262
|
+
let t = 4;
|
|
263
|
+
if (msg.content)
|
|
264
|
+
t += estimateTextTokens(msg.content);
|
|
265
|
+
if (msg.toolCalls)
|
|
266
|
+
t += estimateTextTokens(JSON.stringify(msg.toolCalls));
|
|
267
|
+
if (msg.reasoningContent)
|
|
268
|
+
t += estimateTextTokens(msg.reasoningContent);
|
|
269
|
+
// 图片不是按 base64 长度计费的:估一个保守常量,让预算/统计/裁剪看得见它们
|
|
270
|
+
if (msg.images)
|
|
271
|
+
t += msg.images.length * IMAGE_TOKENS_ESTIMATE;
|
|
272
|
+
return t;
|
|
273
|
+
}
|
|
274
|
+
// ----- 服务描述符(按激活绑定)-----
|
|
275
|
+
/**
|
|
276
|
+
* 调用型。业务层在请求里填上调用方这次激活的实例 id({@link ChatModelRequest.caller}),其余成员照原样转发。
|
|
277
|
+
* 按模型选就是按条目 id 选:`caps.llm.of('<provider>/<model>')`;按能力筛遍历 `caps.llm.list()`,读条目的 `use.capabilities`
|
|
278
|
+
*/
|
|
279
|
+
export const llm = defineService('llm', port =>
|
|
280
|
+
// chatStream 是可选成员:取的时候才看选中的那一家有没有
|
|
281
|
+
Object.create(port.provider, {
|
|
282
|
+
chat: { value: (request) => port.provider.chat({ ...request, caller: port.id }) },
|
|
283
|
+
chatStream: {
|
|
284
|
+
get: () => {
|
|
285
|
+
const chatStream = port.provider.chatStream;
|
|
286
|
+
return chatStream && ((request) => chatStream({ ...request, caller: port.id }));
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
}));
|
|
56
290
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,EAAE;AACF,yBAAyB;AACzB,kCAAkC;AAIlC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/locales/en.ts"],"names":[],"mappings":";;;;AAGA,wBAGG"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { defineLocale } from '@aalis/schema-i18n';
|
|
2
|
+
export default defineLocale()({
|
|
3
|
+
noSuchLevel: 'Model {model} has no thinking level “{level}”',
|
|
4
|
+
badModelRef: 'must be an object with provider and model, both non-empty strings',
|
|
5
|
+
});
|
|
6
|
+
//# sourceMappingURL=en.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/locales/en.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,eAAe,YAAY,EAAU,CAAC;IACpC,WAAW,EAAE,+CAA+C;IAC5D,WAAW,EAAE,mEAAmE;CACjF,CAAC,CAAC"}
|
package/dist/texts.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const SOURCE: {
|
|
2
|
+
readonly noSuchLevel: "模型 {model} 没有思考档位「{level}」";
|
|
3
|
+
readonly badModelRef: "要是带 provider 与 model 的对象,两项都是非空字符串";
|
|
4
|
+
};
|
|
5
|
+
export type Source = typeof SOURCE;
|
|
6
|
+
export declare const t: import("@aalis/schema-i18n").TextFactory<{
|
|
7
|
+
readonly noSuchLevel: "模型 {model} 没有思考档位「{level}」";
|
|
8
|
+
readonly badModelRef: "要是带 provider 与 model 的对象,两项都是非空字符串";
|
|
9
|
+
}>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=texts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texts.d.ts","sourceRoot":"","sources":["../src/texts.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM;;;CAGF,CAAC;AACX,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC;AAEnC,eAAO,MAAM,CAAC;;;EAA4F,CAAC"}
|
package/dist/texts.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// 本包自己的原文字典:请求带了模型没有的思考档位时的报错,模型引用不合形状时的原因
|
|
2
|
+
import { defineTexts } from '@aalis/schema-i18n';
|
|
3
|
+
import en from './locales/en.js';
|
|
4
|
+
const SOURCE = {
|
|
5
|
+
noSuchLevel: '模型 {model} 没有思考档位「{level}」',
|
|
6
|
+
badModelRef: '要是带 provider 与 model 的对象,两项都是非空字符串',
|
|
7
|
+
};
|
|
8
|
+
export const t = defineTexts({ ns: '@aalis/api-llm', language: 'zh-CN', source: SOURCE, locales: { en } });
|
|
9
|
+
//# sourceMappingURL=texts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texts.js","sourceRoot":"","sources":["../src/texts.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAEjC,MAAM,MAAM,GAAG;IACb,WAAW,EAAE,4BAA4B;IACzC,WAAW,EAAE,oCAAoC;CACzC,CAAC;AAGX,MAAM,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aalis/api-llm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,17 +19,18 @@
|
|
|
19
19
|
"dist"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@aalis/schema-message": ">=0.
|
|
23
|
-
"@aalis/api-tools": ">=0.
|
|
24
|
-
"@aalis/schema-config": ">=0.
|
|
22
|
+
"@aalis/schema-message": ">=0.11.0 <1.0.0",
|
|
23
|
+
"@aalis/api-tools": ">=0.12.0 <1.0.0",
|
|
24
|
+
"@aalis/schema-config": ">=0.16.0 <1.0.0",
|
|
25
|
+
"@aalis/schema-i18n": ">=0.1.0 <1.0.0"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
27
28
|
"@types/node": "^22.0.0",
|
|
28
29
|
"typescript": "^5.7.0",
|
|
29
|
-
"@aalis/core": "0.
|
|
30
|
+
"@aalis/core": "0.21.0"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {
|
|
32
|
-
"@aalis/core": ">=0.
|
|
33
|
+
"@aalis/core": ">=0.21.0 <1.0.0"
|
|
33
34
|
},
|
|
34
35
|
"keywords": [
|
|
35
36
|
"aalis",
|