@mdfriday/foundry 26.5.1 → 26.5.2
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/cjs/index.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/types/internal/application/wiki-service.d.ts +38 -1
- package/dist/types/internal/domain/wiki/entity/knowledge-base.d.ts +18 -0
- package/dist/types/internal/domain/wiki/index.d.ts +2 -0
- package/dist/types/internal/domain/wiki/repository/embedding-provider.d.ts +9 -1
- package/dist/types/internal/domain/wiki/repository/llm-provider.d.ts +7 -1
- package/dist/types/internal/domain/wiki/value-object/pricing.d.ts +64 -0
- package/dist/types/internal/domain/wiki/value-object/token-usage.d.ts +26 -0
- package/dist/types/internal/infrastructure/embedding/ollama-embedding-provider.d.ts +15 -3
- package/dist/types/internal/infrastructure/llm/lmstudio-provider.d.ts +19 -3
- package/dist/types/internal/infrastructure/llm/ollama-provider.d.ts +6 -1
- package/dist/types/internal/infrastructure/llm/openai-compatible-provider.d.ts +6 -1
- package/dist/types/internal/infrastructure/llm/provider.d.ts +17 -4
- package/package.json +1 -1
|
@@ -8,13 +8,22 @@
|
|
|
8
8
|
* - 协调依赖,不包含业务逻辑
|
|
9
9
|
* - 配置在创建时一次性传入,避免重复
|
|
10
10
|
*/
|
|
11
|
-
import { KnowledgeBase, WikiFactory, ConversationMetadata } from '../domain/wiki';
|
|
11
|
+
import { KnowledgeBase, WikiFactory, ConversationMetadata, TokenUsage, CostBreakdown, MODEL_PRICING, ModelPricing } from '../domain/wiki';
|
|
12
12
|
import { WikiServiceConfig } from './wiki-service-config';
|
|
13
13
|
/**
|
|
14
14
|
* Ingest 可选配置(用于覆盖默认值)
|
|
15
15
|
*/
|
|
16
16
|
export interface IngestOptions {
|
|
17
17
|
temperature?: number;
|
|
18
|
+
/** LLM token 使用量回调:实体/概念提取完成后触发精确值(isEstimate: false) */
|
|
19
|
+
onIngestTokenUsage?: (usage: TokenUsage) => void;
|
|
20
|
+
/**
|
|
21
|
+
* 实时流式进度回调:每个 LLM chunk 到达时触发,携带累计 completionTokens 估算值。
|
|
22
|
+
* 提供此回调时,ingest 改用流式模式,实现逐 chunk 实时上报(isEstimate: true)。
|
|
23
|
+
*/
|
|
24
|
+
onIngestProgress?: (estimatedCompletionTokens: number) => void;
|
|
25
|
+
/** Embedding token 使用量回调:每次 embedding 调用完成后触发(构建索引时) */
|
|
26
|
+
onEmbeddingUsage?: (usage: TokenUsage) => void;
|
|
18
27
|
}
|
|
19
28
|
/**
|
|
20
29
|
* Query 可选配置(用于覆盖默认值)
|
|
@@ -22,7 +31,13 @@ export interface IngestOptions {
|
|
|
22
31
|
export interface QueryOptions {
|
|
23
32
|
temperature?: number;
|
|
24
33
|
maxResults?: number;
|
|
34
|
+
/** LLM token 使用量回调:在 LLM stream 完成时调用 */
|
|
35
|
+
onTokenUsage?: (usage: TokenUsage) => void;
|
|
36
|
+
/** Embedding token 使用量回调:query embedding 完成后调用 */
|
|
37
|
+
onEmbeddingUsage?: (usage: TokenUsage) => void;
|
|
25
38
|
}
|
|
39
|
+
export type { TokenUsage, CostBreakdown, ModelPricing };
|
|
40
|
+
export { MODEL_PRICING };
|
|
26
41
|
/**
|
|
27
42
|
* Ingest 结果
|
|
28
43
|
*/
|
|
@@ -155,6 +170,7 @@ export declare class WikiService {
|
|
|
155
170
|
* 使用 LLM 流式生成答案
|
|
156
171
|
* 使用配置的默认值,允许可选覆盖
|
|
157
172
|
* 委托给 KB 的 queryStream 方法
|
|
173
|
+
* 通过 options.onTokenUsage 回调上报 token 使用量
|
|
158
174
|
*/
|
|
159
175
|
queryStream(question: string, options?: QueryOptions): AsyncGenerator<string, void, unknown>;
|
|
160
176
|
/**
|
|
@@ -169,6 +185,27 @@ export declare class WikiService {
|
|
|
169
185
|
* 调用聚合根的 lint 方法
|
|
170
186
|
*/
|
|
171
187
|
lint(): Promise<LintIssue[]>;
|
|
188
|
+
/**
|
|
189
|
+
* 估算 token 费用
|
|
190
|
+
*
|
|
191
|
+
* 无状态纯函数,不需要加载 KB。
|
|
192
|
+
* 根据 provider + model 在内置定价表中查找单价,计算输入/输出 token 的总成本。
|
|
193
|
+
*
|
|
194
|
+
* @param provider LLM 或 embedding 提供商名称(如 "openai", "deepseek", "ollama")
|
|
195
|
+
* @param model 模型名称(如 "gpt-4o")
|
|
196
|
+
* @param inputTokens 输入 token 数(promptTokens)
|
|
197
|
+
* @param outputTokens 输出 token 数(completionTokens)
|
|
198
|
+
* @returns 费用明细,或 undefined(找不到该 provider 的任何定价)
|
|
199
|
+
*/
|
|
200
|
+
calculateCost(provider: string, model: string, inputTokens: number, outputTokens: number): CostBreakdown | undefined;
|
|
201
|
+
/**
|
|
202
|
+
* 返回所有已知的模型定价数据(供 UI 展示定价表)
|
|
203
|
+
*/
|
|
204
|
+
getPricingTable(): ModelPricing[];
|
|
205
|
+
/**
|
|
206
|
+
* 查找单个模型的定价数据
|
|
207
|
+
*/
|
|
208
|
+
findModelPricing(provider: string, model: string): ModelPricing | undefined;
|
|
172
209
|
/**
|
|
173
210
|
* 为当前 KB 构建 Embedding Index
|
|
174
211
|
*
|
|
@@ -15,6 +15,7 @@ import { SourceRecord } from '../value-object/source-record';
|
|
|
15
15
|
import { EntityId } from '../value-object/entity-id';
|
|
16
16
|
import { ExtractionResult } from '../value-object/extraction-result';
|
|
17
17
|
import { ILLMProvider, IEmbeddingProvider, IFileSystem, IPathService, ICryptoService, IWikiPageRepository } from '../repository';
|
|
18
|
+
import type { TokenUsage } from '../value-object/token-usage';
|
|
18
19
|
export { Entity, Concept, Connection, SourceRecord, OperationLog };
|
|
19
20
|
export declare class KnowledgeBase {
|
|
20
21
|
private _entities;
|
|
@@ -139,6 +140,14 @@ export declare class KnowledgeBase {
|
|
|
139
140
|
outputLanguage?: string;
|
|
140
141
|
fileSystem: IFileSystem;
|
|
141
142
|
crypto: ICryptoService;
|
|
143
|
+
/** LLM token 使用量回调:提取完成后触发精确值(isEstimate: false) */
|
|
144
|
+
onIngestTokenUsage?: (usage: TokenUsage) => void;
|
|
145
|
+
/**
|
|
146
|
+
* 实时流式进度回调:每个 chunk 到达时触发,携带累计 completionTokens 估算值。
|
|
147
|
+
* 提供此回调时,ingestFromSource 改用流式 complete(),实现逐 chunk 实时上报。
|
|
148
|
+
* 估算方法与 queryStream 一致(约 3 字符 / token)。
|
|
149
|
+
*/
|
|
150
|
+
onIngestProgress?: (estimatedCompletionTokens: number) => void;
|
|
142
151
|
}): Promise<{
|
|
143
152
|
success: boolean;
|
|
144
153
|
extractedEntities: number;
|
|
@@ -201,6 +210,8 @@ export declare class KnowledgeBase {
|
|
|
201
210
|
embeddingModel?: string;
|
|
202
211
|
temperature?: number;
|
|
203
212
|
maxResults?: number;
|
|
213
|
+
/** Embedding token 使用量回调:query embedding 完成后调用 */
|
|
214
|
+
onEmbeddingUsage?: (usage: TokenUsage) => void;
|
|
204
215
|
}): Promise<{
|
|
205
216
|
entities: Array<{
|
|
206
217
|
id: string;
|
|
@@ -251,6 +262,8 @@ export declare class KnowledgeBase {
|
|
|
251
262
|
model: string;
|
|
252
263
|
cachePath: string;
|
|
253
264
|
fileSystem: IFileSystem;
|
|
265
|
+
/** 每次 embedding 调用完成后的 token 使用量回调(累计上报) */
|
|
266
|
+
onEmbeddingUsage?: (usage: TokenUsage) => void;
|
|
254
267
|
}): Promise<void>;
|
|
255
268
|
/**
|
|
256
269
|
* 保存 Embedding Index 缓存
|
|
@@ -280,6 +293,7 @@ export declare class KnowledgeBase {
|
|
|
280
293
|
* Query Stream - 流式返回
|
|
281
294
|
*
|
|
282
295
|
* Domain 方法:使用内部 EmbeddingIndex
|
|
296
|
+
* 通过 onTokenUsage 回调实时上报 token 使用量(属于 wiki domain 业务概念)
|
|
283
297
|
*/
|
|
284
298
|
queryStream(question: string, dependencies: {
|
|
285
299
|
llmProvider: ILLMProvider;
|
|
@@ -288,5 +302,9 @@ export declare class KnowledgeBase {
|
|
|
288
302
|
embeddingModel?: string;
|
|
289
303
|
temperature?: number;
|
|
290
304
|
maxResults?: number;
|
|
305
|
+
/** LLM token 使用量回调:在 LLM stream 完成时调用 */
|
|
306
|
+
onTokenUsage?: (usage: TokenUsage) => void;
|
|
307
|
+
/** Embedding token 使用量回调:query embedding 完成后调用 */
|
|
308
|
+
onEmbeddingUsage?: (usage: TokenUsage) => void;
|
|
291
309
|
}): AsyncGenerator<string, void, unknown>;
|
|
292
310
|
}
|
|
@@ -12,6 +12,8 @@ export * from './value-object/retrieval';
|
|
|
12
12
|
export * from './value-object/content-annotator';
|
|
13
13
|
export * from './value-object/wiki-page-renderer';
|
|
14
14
|
export * from './value-object/wiki-index-generator';
|
|
15
|
+
export * from './value-object/token-usage';
|
|
16
|
+
export * from './value-object/pricing';
|
|
15
17
|
export * from './entity/entity';
|
|
16
18
|
export * from './entity/concept';
|
|
17
19
|
export * from './entity/connection';
|
|
@@ -4,9 +4,17 @@
|
|
|
4
4
|
* Domain 层定义的 Embedding 服务接口
|
|
5
5
|
* Infrastructure 层提供具体实现
|
|
6
6
|
*/
|
|
7
|
+
import type { TokenUsage } from '../value-object/token-usage';
|
|
8
|
+
export type { TokenUsage };
|
|
7
9
|
export interface IEmbeddingProvider {
|
|
8
10
|
/**
|
|
9
11
|
* Generate embedding vector for text
|
|
12
|
+
*
|
|
13
|
+
* @param text 输入文本
|
|
14
|
+
* @param model 模型名称
|
|
15
|
+
* @param onUsage 可选回调:embedding 完成后携带 token 使用量
|
|
16
|
+
* (promptTokens = 输入 token 数,completionTokens = 0,
|
|
17
|
+
* totalTokens = promptTokens,由 infrastructure 层填充)
|
|
10
18
|
*/
|
|
11
|
-
generateEmbedding(text: string, model: string): Promise<number[]>;
|
|
19
|
+
generateEmbedding(text: string, model: string, onUsage?: (usage: TokenUsage) => void): Promise<number[]>;
|
|
12
20
|
}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Domain 层定义的 LLM 服务接口
|
|
5
5
|
* Infrastructure 层提供具体实现
|
|
6
6
|
*/
|
|
7
|
+
import type { TokenUsage } from '../value-object/token-usage';
|
|
8
|
+
export type { TokenUsage };
|
|
7
9
|
export interface LLMOptions {
|
|
8
10
|
model: string;
|
|
9
11
|
temperature?: number;
|
|
@@ -13,6 +15,8 @@ export interface LLMOptions {
|
|
|
13
15
|
export interface LLMStreamChunk {
|
|
14
16
|
text: string;
|
|
15
17
|
done: boolean;
|
|
18
|
+
/** Token 使用量统计,由 provider 在最终 chunk 中填充(若 API 支持) */
|
|
19
|
+
usage?: TokenUsage;
|
|
16
20
|
}
|
|
17
21
|
export interface ILLMProvider {
|
|
18
22
|
/**
|
|
@@ -21,8 +25,10 @@ export interface ILLMProvider {
|
|
|
21
25
|
complete(prompt: string, options: LLMOptions, signal?: AbortSignal): AsyncIterable<LLMStreamChunk>;
|
|
22
26
|
/**
|
|
23
27
|
* Synchronous completion (wait for full response)
|
|
28
|
+
*
|
|
29
|
+
* @param onUsage 可选:LLM 响应完成后,携带本次调用的 token 使用量(由 infrastructure 填充)
|
|
24
30
|
*/
|
|
25
|
-
completeSync(prompt: string, options: LLMOptions, signal?: AbortSignal): Promise<string>;
|
|
31
|
+
completeSync(prompt: string, options: LLMOptions, signal?: AbortSignal, onUsage?: (usage: TokenUsage) => void): Promise<string>;
|
|
26
32
|
/**
|
|
27
33
|
* Health check
|
|
28
34
|
*/
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Pricing Value Objects & Service
|
|
3
|
+
*
|
|
4
|
+
* Domain 层定义的模型定价数据和费用计算逻辑。
|
|
5
|
+
* 属于 wiki domain 的业务概念:用户通过消耗的 token 数量估算实际成本。
|
|
6
|
+
*
|
|
7
|
+
* 价格来源:各厂商官网公布的按量计费价格(2024-2025)。
|
|
8
|
+
* 本地模型(ollama / lmstudio)费用为 0。
|
|
9
|
+
*/
|
|
10
|
+
export interface ModelPricing {
|
|
11
|
+
provider: string;
|
|
12
|
+
model: string;
|
|
13
|
+
/** 每 1M 输入 token 的价格(USD) */
|
|
14
|
+
inputPer1M: number;
|
|
15
|
+
/** 每 1M 输出 token 的价格(USD) */
|
|
16
|
+
outputPer1M: number;
|
|
17
|
+
/** 每 1M 缓存读取 token 的价格(USD),可选 */
|
|
18
|
+
cacheReadPer1M?: number;
|
|
19
|
+
/** 每 1M 缓存写入 token 的价格(USD),可选 */
|
|
20
|
+
cacheWritePer1M?: number;
|
|
21
|
+
currency: 'USD';
|
|
22
|
+
/** 本地运行模型,费用为 0 */
|
|
23
|
+
isLocal?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface CostBreakdown {
|
|
26
|
+
provider: string;
|
|
27
|
+
model: string;
|
|
28
|
+
inputTokens: number;
|
|
29
|
+
outputTokens: number;
|
|
30
|
+
/** 输入部分费用(USD) */
|
|
31
|
+
inputCost: number;
|
|
32
|
+
/** 输出部分费用(USD) */
|
|
33
|
+
outputCost: number;
|
|
34
|
+
/** 总费用(USD) */
|
|
35
|
+
totalCost: number;
|
|
36
|
+
currency: 'USD';
|
|
37
|
+
isLocal: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* 是否使用了精确定价数据。
|
|
40
|
+
* false = 使用了通配符或没有找到精确匹配,费用为估算值。
|
|
41
|
+
*/
|
|
42
|
+
isExact: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare const MODEL_PRICING: ModelPricing[];
|
|
45
|
+
/**
|
|
46
|
+
* 根据 provider + model 查找定价数据。
|
|
47
|
+
*
|
|
48
|
+
* 匹配优先级:
|
|
49
|
+
* 1. 精确匹配 provider + model(忽略大小写)
|
|
50
|
+
* 2. provider 匹配 + model 通配符 "*"
|
|
51
|
+
* 3. 未找到返回 undefined
|
|
52
|
+
*/
|
|
53
|
+
export declare function findPricing(provider: string, model: string): ModelPricing | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* 根据定价数据计算 token 费用。
|
|
56
|
+
*/
|
|
57
|
+
export declare function calculateCost(pricing: ModelPricing, inputTokens: number, outputTokens: number): number;
|
|
58
|
+
/**
|
|
59
|
+
* 根据 provider + model 名称和 token 数量,返回完整的费用明细。
|
|
60
|
+
*
|
|
61
|
+
* 当找不到精确定价时,isExact = false;
|
|
62
|
+
* 当完全找不到该 provider(含通配符),返回 undefined。
|
|
63
|
+
*/
|
|
64
|
+
export declare function estimateCost(provider: string, model: string, inputTokens: number, outputTokens: number): CostBreakdown | undefined;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenUsage Value Object
|
|
3
|
+
*
|
|
4
|
+
* Domain 层定义的 Token 使用量值对象。
|
|
5
|
+
* 代表一次 LLM 调用中的 token 消耗统计,属于 wiki domain 的业务概念。
|
|
6
|
+
* 由 LLM infrastructure 层负责从 API 响应中提取并填充,
|
|
7
|
+
* 通过 onProgress 回调实时传递给上层(如 obsidian interface)。
|
|
8
|
+
*/
|
|
9
|
+
export interface TokenUsage {
|
|
10
|
+
/** 输入 token 数(prompt + 上下文) */
|
|
11
|
+
promptTokens: number;
|
|
12
|
+
/** 输出 token 数(模型生成的内容) */
|
|
13
|
+
completionTokens: number;
|
|
14
|
+
/** 总 token 数 = promptTokens + completionTokens */
|
|
15
|
+
totalTokens: number;
|
|
16
|
+
/** 当次调用使用的模型名称(可选,由 provider 填充) */
|
|
17
|
+
model?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 将两次 TokenUsage 累加合并(多次 LLM 调用的 session 汇总)
|
|
21
|
+
*/
|
|
22
|
+
export declare function mergeTokenUsage(a: TokenUsage, b: TokenUsage): TokenUsage;
|
|
23
|
+
/**
|
|
24
|
+
* 创建空的 TokenUsage(初始状态)
|
|
25
|
+
*/
|
|
26
|
+
export declare function emptyTokenUsage(): TokenUsage;
|
|
@@ -14,11 +14,23 @@ export declare class OllamaEmbeddingProvider implements IEmbeddingProvider {
|
|
|
14
14
|
private config;
|
|
15
15
|
constructor(config: OllamaEmbeddingConfig);
|
|
16
16
|
/**
|
|
17
|
-
* Domain IEmbeddingProvider interface: generateEmbedding(text, model)
|
|
17
|
+
* Domain IEmbeddingProvider interface: generateEmbedding(text, model, onUsage?)
|
|
18
18
|
* Bridges the domain contract to the infrastructure embed() method.
|
|
19
19
|
*/
|
|
20
|
-
generateEmbedding(text: string, model: string
|
|
21
|
-
|
|
20
|
+
generateEmbedding(text: string, model: string, onUsage?: (usage: {
|
|
21
|
+
promptTokens: number;
|
|
22
|
+
completionTokens: number;
|
|
23
|
+
totalTokens: number;
|
|
24
|
+
model?: string;
|
|
25
|
+
}) => void): Promise<number[]>;
|
|
26
|
+
embed(request: EmbedRequest & {
|
|
27
|
+
onUsage?: (usage: {
|
|
28
|
+
promptTokens: number;
|
|
29
|
+
completionTokens: number;
|
|
30
|
+
totalTokens: number;
|
|
31
|
+
model?: string;
|
|
32
|
+
}) => void;
|
|
33
|
+
}): Promise<number[]>;
|
|
22
34
|
embedBatch(texts: string[]): Promise<number[][]>;
|
|
23
35
|
healthCheck(): Promise<boolean>;
|
|
24
36
|
}
|
|
@@ -36,16 +36,32 @@ export declare class OpenAICompatibleEmbeddingProvider implements ILLMProvider,
|
|
|
36
36
|
/** Build Authorization header when an API key is configured. */
|
|
37
37
|
private buildHeaders;
|
|
38
38
|
complete(prompt: string, config: LLMConfig, signal?: AbortSignal): AsyncIterable<LLMStreamChunk>;
|
|
39
|
-
completeSync(prompt: string, config: LLMConfig, signal?: AbortSignal
|
|
39
|
+
completeSync(prompt: string, config: LLMConfig, signal?: AbortSignal, onUsage?: (usage: {
|
|
40
|
+
promptTokens: number;
|
|
41
|
+
completionTokens: number;
|
|
42
|
+
totalTokens: number;
|
|
43
|
+
model?: string;
|
|
44
|
+
}) => void): Promise<string>;
|
|
40
45
|
/**
|
|
41
|
-
* Domain IEmbeddingProvider contract: generateEmbedding(text, model).
|
|
46
|
+
* Domain IEmbeddingProvider contract: generateEmbedding(text, model, onUsage?).
|
|
42
47
|
* Bridges to the infrastructure embed() method.
|
|
43
48
|
*/
|
|
44
|
-
generateEmbedding(text: string, model: string
|
|
49
|
+
generateEmbedding(text: string, model: string, onUsage?: (usage: {
|
|
50
|
+
promptTokens: number;
|
|
51
|
+
completionTokens: number;
|
|
52
|
+
totalTokens: number;
|
|
53
|
+
model?: string;
|
|
54
|
+
}) => void): Promise<number[]>;
|
|
45
55
|
embed(request: {
|
|
46
56
|
text: string;
|
|
47
57
|
model?: string;
|
|
48
58
|
signal?: AbortSignal;
|
|
59
|
+
onUsage?: (usage: {
|
|
60
|
+
promptTokens: number;
|
|
61
|
+
completionTokens: number;
|
|
62
|
+
totalTokens: number;
|
|
63
|
+
model?: string;
|
|
64
|
+
}) => void;
|
|
49
65
|
}): Promise<number[]>;
|
|
50
66
|
embedBatch(texts: string[]): Promise<number[][]>;
|
|
51
67
|
healthCheck(): Promise<boolean>;
|
|
@@ -12,6 +12,11 @@ export declare class OllamaProvider implements ILLMProvider {
|
|
|
12
12
|
complete(prompt: string, config: LLMConfig, signal?: AbortSignal): AsyncIterable<LLMStreamChunk>;
|
|
13
13
|
private completeWithChat;
|
|
14
14
|
private completeWithGenerate;
|
|
15
|
-
completeSync(prompt: string, config: LLMConfig, signal?: AbortSignal
|
|
15
|
+
completeSync(prompt: string, config: LLMConfig, signal?: AbortSignal, onUsage?: (usage: {
|
|
16
|
+
promptTokens: number;
|
|
17
|
+
completionTokens: number;
|
|
18
|
+
totalTokens: number;
|
|
19
|
+
model?: string;
|
|
20
|
+
}) => void): Promise<string>;
|
|
16
21
|
healthCheck(): Promise<boolean>;
|
|
17
22
|
}
|
|
@@ -57,7 +57,12 @@ export declare class OpenAICompatibleProvider implements ILLMProvider {
|
|
|
57
57
|
private httpClient;
|
|
58
58
|
constructor(config: OpenAICompatibleConfig);
|
|
59
59
|
complete(prompt: string, config: LLMConfig, signal?: AbortSignal): AsyncIterable<LLMStreamChunk>;
|
|
60
|
-
completeSync(prompt: string, config: LLMConfig, signal?: AbortSignal
|
|
60
|
+
completeSync(prompt: string, config: LLMConfig, signal?: AbortSignal, onUsage?: (usage: {
|
|
61
|
+
promptTokens: number;
|
|
62
|
+
completionTokens: number;
|
|
63
|
+
totalTokens: number;
|
|
64
|
+
model?: string;
|
|
65
|
+
}) => void): Promise<string>;
|
|
61
66
|
healthCheck(): Promise<boolean>;
|
|
62
67
|
}
|
|
63
68
|
/**
|
|
@@ -9,6 +9,13 @@
|
|
|
9
9
|
export interface LLMStreamChunk {
|
|
10
10
|
text: string;
|
|
11
11
|
done: boolean;
|
|
12
|
+
/** Token 使用量统计,由 provider 在最终 chunk 中填充(若 API 支持) */
|
|
13
|
+
usage?: {
|
|
14
|
+
promptTokens: number;
|
|
15
|
+
completionTokens: number;
|
|
16
|
+
totalTokens: number;
|
|
17
|
+
model?: string;
|
|
18
|
+
};
|
|
12
19
|
}
|
|
13
20
|
/**
|
|
14
21
|
* LLM 配置
|
|
@@ -34,11 +41,17 @@ export interface ILLMProvider {
|
|
|
34
41
|
complete(prompt: string, config: LLMConfig, signal?: AbortSignal): AsyncIterable<LLMStreamChunk>;
|
|
35
42
|
/**
|
|
36
43
|
* 非流式完成(等待完整响应)
|
|
37
|
-
* @param prompt
|
|
38
|
-
* @param config
|
|
39
|
-
* @param signal
|
|
44
|
+
* @param prompt 提示词
|
|
45
|
+
* @param config LLM 配置
|
|
46
|
+
* @param signal 取消信号
|
|
47
|
+
* @param onUsage 可选:响应完成后携带 token 使用量(由 infrastructure 填充)
|
|
40
48
|
*/
|
|
41
|
-
completeSync(prompt: string, config: LLMConfig, signal?: AbortSignal
|
|
49
|
+
completeSync(prompt: string, config: LLMConfig, signal?: AbortSignal, onUsage?: (usage: {
|
|
50
|
+
promptTokens: number;
|
|
51
|
+
completionTokens: number;
|
|
52
|
+
totalTokens: number;
|
|
53
|
+
model?: string;
|
|
54
|
+
}) => void): Promise<string>;
|
|
42
55
|
/**
|
|
43
56
|
* 健康检查
|
|
44
57
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mdfriday/foundry",
|
|
3
|
-
"version": "26.5.
|
|
3
|
+
"version": "26.5.2",
|
|
4
4
|
"description": "The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|