@spacex110/core 0.1.15 → 0.1.17
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 +337 -0
- package/dist/index.js +2553 -1893
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +19 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +1 -1
- package/src/channel-manager.ts +190 -2
- package/src/index.ts +18 -0
- package/src/multimodal-normalize.ts +170 -0
- package/src/providers.ts +2 -2
- package/src/strategies.ts +735 -1
- package/src/types.ts +177 -0
- package/dist/channel-manager.d.ts +0 -276
package/dist/index.d.ts
CHANGED
|
@@ -168,6 +168,55 @@ export declare class AIChannelManager {
|
|
|
168
168
|
onDelta: (full: string) => void;
|
|
169
169
|
signal?: AbortSignal;
|
|
170
170
|
}): Promise<ChatResult>;
|
|
171
|
+
/**
|
|
172
|
+
* 私有:根据聊天结果更新通道状态。复用 chatWith / chatWithStream 的逻辑。
|
|
173
|
+
*/
|
|
174
|
+
private updateChannelStatusAfterChat;
|
|
175
|
+
/**
|
|
176
|
+
* 使用当前激活通道发送多模态聊天。
|
|
177
|
+
* messages 支持 string(纯文本)或 ContentPart[](多模态)。
|
|
178
|
+
*/
|
|
179
|
+
chatMultimodal(message: ChatMessage | ChatMessage[], options?: {
|
|
180
|
+
messages?: ChatMessage[];
|
|
181
|
+
maxTokens?: number;
|
|
182
|
+
outputModalities?: Array<'text' | 'image'>;
|
|
183
|
+
temperature?: number;
|
|
184
|
+
timeoutMs?: number;
|
|
185
|
+
}): Promise<MultimodalChatManagerResult>;
|
|
186
|
+
/**
|
|
187
|
+
* 使用指定通道发送多模态聊天。
|
|
188
|
+
* 与 chatMultimodal 区别:可显式指定 channelId。
|
|
189
|
+
*/
|
|
190
|
+
chatMultimodalWith(channelId: string, message: ChatMessage | ChatMessage[], options?: {
|
|
191
|
+
messages?: ChatMessage[];
|
|
192
|
+
maxTokens?: number;
|
|
193
|
+
outputModalities?: Array<'text' | 'image'>;
|
|
194
|
+
temperature?: number;
|
|
195
|
+
timeoutMs?: number;
|
|
196
|
+
}): Promise<MultimodalChatManagerResult>;
|
|
197
|
+
/**
|
|
198
|
+
* 使用当前激活通道发送多模态流式聊天。
|
|
199
|
+
* onDelta 每次收到「累计完整状态」({ text, images })。
|
|
200
|
+
*/
|
|
201
|
+
chatMultimodalStream(message: ChatMessage | ChatMessage[], options: {
|
|
202
|
+
messages?: ChatMessage[];
|
|
203
|
+
maxTokens?: number;
|
|
204
|
+
outputModalities?: Array<'text' | 'image'>;
|
|
205
|
+
temperature?: number;
|
|
206
|
+
timeoutMs?: number;
|
|
207
|
+
onDelta: (state: MultimodalStreamDelta) => void;
|
|
208
|
+
}): Promise<MultimodalChatManagerResult>;
|
|
209
|
+
/**
|
|
210
|
+
* 使用指定通道发送多模态流式聊天。
|
|
211
|
+
*/
|
|
212
|
+
chatMultimodalStreamWith(channelId: string, message: ChatMessage | ChatMessage[], options: {
|
|
213
|
+
messages?: ChatMessage[];
|
|
214
|
+
maxTokens?: number;
|
|
215
|
+
outputModalities?: Array<'text' | 'image'>;
|
|
216
|
+
temperature?: number;
|
|
217
|
+
timeoutMs?: number;
|
|
218
|
+
onDelta: (state: MultimodalStreamDelta) => void;
|
|
219
|
+
}): Promise<MultimodalChatManagerResult>;
|
|
171
220
|
/** 测试指定通道的连接 */
|
|
172
221
|
testChannel(id: string): Promise<{
|
|
173
222
|
success: boolean;
|
|
@@ -305,6 +354,20 @@ export declare interface ChannelManagerOptions {
|
|
|
305
354
|
proxyUrl?: string;
|
|
306
355
|
}
|
|
307
356
|
|
|
357
|
+
/**
|
|
358
|
+
* 多模态聊天消息。
|
|
359
|
+
* content 可以是纯文本字符串(兼容 sendDirectChat)或多模态内容块数组。
|
|
360
|
+
*/
|
|
361
|
+
export declare interface ChatMessage {
|
|
362
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
363
|
+
/**
|
|
364
|
+
* 消息内容:字符串走纯文本路径,多模态块数组走多模态路径。
|
|
365
|
+
*/
|
|
366
|
+
content: string | ContentPart[];
|
|
367
|
+
/** 可选的消息名(部分协议支持) */
|
|
368
|
+
name?: string;
|
|
369
|
+
}
|
|
370
|
+
|
|
308
371
|
/** 聊天结果 */
|
|
309
372
|
export declare interface ChatResult {
|
|
310
373
|
success: boolean;
|
|
@@ -315,6 +378,62 @@ export declare interface ChatResult {
|
|
|
315
378
|
model?: string;
|
|
316
379
|
}
|
|
317
380
|
|
|
381
|
+
/**
|
|
382
|
+
* 多模态内容块(输入侧调用方传入格式)。
|
|
383
|
+
* 不同协议的 ContentPart 形态不同,这里提供统一的 OpenAI 风格接口作为上层标准。
|
|
384
|
+
*/
|
|
385
|
+
export declare type ContentPart = {
|
|
386
|
+
type: 'text';
|
|
387
|
+
text: string;
|
|
388
|
+
} | {
|
|
389
|
+
type: 'image_url';
|
|
390
|
+
image_url: {
|
|
391
|
+
url: string;
|
|
392
|
+
detail?: 'low' | 'high' | 'auto';
|
|
393
|
+
};
|
|
394
|
+
} | {
|
|
395
|
+
type: 'image';
|
|
396
|
+
source: {
|
|
397
|
+
type: 'base64';
|
|
398
|
+
media_type: string;
|
|
399
|
+
data: string;
|
|
400
|
+
} | {
|
|
401
|
+
type: 'url';
|
|
402
|
+
url: string;
|
|
403
|
+
};
|
|
404
|
+
} | {
|
|
405
|
+
type: 'inline_data';
|
|
406
|
+
inline_data: {
|
|
407
|
+
mime_type: string;
|
|
408
|
+
data: string;
|
|
409
|
+
};
|
|
410
|
+
} | {
|
|
411
|
+
type: 'audio';
|
|
412
|
+
input_audio: {
|
|
413
|
+
data: string;
|
|
414
|
+
format: 'wav' | 'mp3';
|
|
415
|
+
};
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* 响应侧的内容块。
|
|
420
|
+
* 文本部分用 string;多模态用数组,每个元素描述一种产出(文本/图片/音频)。
|
|
421
|
+
*/
|
|
422
|
+
export declare type ContentResponsePart = {
|
|
423
|
+
type: 'text';
|
|
424
|
+
text: string;
|
|
425
|
+
} | {
|
|
426
|
+
type: 'image';
|
|
427
|
+
url?: string;
|
|
428
|
+
b64_json?: string;
|
|
429
|
+
mimeType?: string;
|
|
430
|
+
} | {
|
|
431
|
+
type: 'audio';
|
|
432
|
+
url?: string;
|
|
433
|
+
b64_json?: string;
|
|
434
|
+
mimeType?: string;
|
|
435
|
+
};
|
|
436
|
+
|
|
318
437
|
export declare function createConfigStorage(adapter?: StorageAdapter, options?: StorageOptions): {
|
|
319
438
|
/**
|
|
320
439
|
* Save AI config
|
|
@@ -400,6 +519,16 @@ export declare interface FetchModelsOptions {
|
|
|
400
519
|
fallbackToStatic?: boolean;
|
|
401
520
|
}
|
|
402
521
|
|
|
522
|
+
/**
|
|
523
|
+
* 远程图片 → data URI。
|
|
524
|
+
* 拉取失败时返回原始 URL(标记 fallback=true),让协议策略自行决定是否接受 URL。
|
|
525
|
+
*/
|
|
526
|
+
export declare function fetchRemoteToDataUri(url: string): Promise<{
|
|
527
|
+
dataUri: string;
|
|
528
|
+
mimeType?: string;
|
|
529
|
+
fallback: boolean;
|
|
530
|
+
}>;
|
|
531
|
+
|
|
403
532
|
/**
|
|
404
533
|
* Get all providers as an array
|
|
405
534
|
*/
|
|
@@ -427,6 +556,17 @@ export declare function getStaticModels(providerId: string): Model[];
|
|
|
427
556
|
|
|
428
557
|
export declare function getStrategy(format: string): ProviderStrategy;
|
|
429
558
|
|
|
559
|
+
/**
|
|
560
|
+
* 从 data URI 字符串中猜测 MIME 类型。
|
|
561
|
+
* 用于图片/音频响应在缺少 mimeType 字段时的回退解析。
|
|
562
|
+
*
|
|
563
|
+
* @example
|
|
564
|
+
* guessMimeFromDataUri('data:image/png;base64,xxx') // => 'image/png'
|
|
565
|
+
* guessMimeFromDataUri('data:audio/mp3;base64,xxx') // => 'audio/mp3'
|
|
566
|
+
* guessMimeFromDataUri('https://example.com/a.jpg') // => null
|
|
567
|
+
*/
|
|
568
|
+
export declare function guessMimeFromDataUri(uri: string): string | null;
|
|
569
|
+
|
|
430
570
|
export declare const I18N: {
|
|
431
571
|
readonly zh: {
|
|
432
572
|
readonly save: "保存配置";
|
|
@@ -502,6 +642,13 @@ export declare interface Model {
|
|
|
502
642
|
name: string;
|
|
503
643
|
/** 模型能力列表(如 text, vision, audio) */
|
|
504
644
|
capabilities?: ModelCapability[];
|
|
645
|
+
/**
|
|
646
|
+
* 模型输出能力(如 image, audio)。
|
|
647
|
+
* 与 capabilities 区分:capabilities 指模型能理解/处理哪些输入;
|
|
648
|
+
* outputCapabilities 指模型能生成哪些类型的输出。
|
|
649
|
+
* 当前仅在多模态输出场景(如 OpenRouter 文生图、Gemini 生图)使用。
|
|
650
|
+
*/
|
|
651
|
+
outputCapabilities?: Array<'image' | 'audio'>;
|
|
505
652
|
/** 上下文窗口大小 */
|
|
506
653
|
contextLength?: number;
|
|
507
654
|
}
|
|
@@ -528,6 +675,153 @@ declare interface ModelCapabilityMeta {
|
|
|
528
675
|
*/
|
|
529
676
|
export declare type ModelFetcher = (params: FetcherParams) => Promise<any>;
|
|
530
677
|
|
|
678
|
+
/**
|
|
679
|
+
* 多模态聊天结果(通道管理器层)。
|
|
680
|
+
* 在底层 MultimodalChatResult 上附加 channelId 与 model,便于上层定位调用方。
|
|
681
|
+
*/
|
|
682
|
+
export declare interface MultimodalChatManagerResult extends MultimodalChatResult {
|
|
683
|
+
/** 调用方通道 ID */
|
|
684
|
+
channelId: string;
|
|
685
|
+
/** 实际请求的模型 ID */
|
|
686
|
+
model: string;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* 调用 sendMultimodalChat / sendMultimodalChatStream 的输入参数。
|
|
691
|
+
* 与 sendDirectChat 不同:messages 字段是 ChatMessage[](支持 content: string | ContentPart[])。
|
|
692
|
+
*/
|
|
693
|
+
export declare interface MultimodalChatOptions {
|
|
694
|
+
/** 协议类型 */
|
|
695
|
+
apiFormat: ApiFormat;
|
|
696
|
+
/** API Key */
|
|
697
|
+
apiKey: string;
|
|
698
|
+
/** 模型 ID */
|
|
699
|
+
model: string;
|
|
700
|
+
/** 厂商 Base URL */
|
|
701
|
+
baseUrl: string;
|
|
702
|
+
/** 聊天消息列表(支持多模态) */
|
|
703
|
+
messages: ChatMessage[];
|
|
704
|
+
/** 最大输出 token */
|
|
705
|
+
maxTokens?: number;
|
|
706
|
+
/** 温度 */
|
|
707
|
+
temperature?: number;
|
|
708
|
+
/** 请求超时(毫秒) */
|
|
709
|
+
timeoutMs?: number;
|
|
710
|
+
/**
|
|
711
|
+
* 期望的输出模态。
|
|
712
|
+
* - 仅在 OpenRouter(OpenAI 协议)或 Gemini 协议下生效;其他协议传入 image 会直接报错
|
|
713
|
+
* - 示例:['text']、['text', 'image']
|
|
714
|
+
*/
|
|
715
|
+
outputModalities?: Array<'text' | 'image'>;
|
|
716
|
+
/** 透传给 fetch 的额外 headers(用于透传 Authorization 代理等) */
|
|
717
|
+
extraHeaders?: Record<string, string>;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/** 非流式多模态聊天结果 */
|
|
721
|
+
export declare interface MultimodalChatResult {
|
|
722
|
+
success: boolean;
|
|
723
|
+
/** 纯文本内容(仅当响应只有文本时填充) */
|
|
724
|
+
text?: string;
|
|
725
|
+
/** 多模态产出(文本/图片/音频混排;与 text 二选一) */
|
|
726
|
+
images?: Array<{
|
|
727
|
+
type: 'image';
|
|
728
|
+
url?: string;
|
|
729
|
+
b64_json?: string;
|
|
730
|
+
mimeType?: string;
|
|
731
|
+
}>;
|
|
732
|
+
/** token 用量 */
|
|
733
|
+
usage?: {
|
|
734
|
+
inputTokens?: number;
|
|
735
|
+
outputTokens?: number;
|
|
736
|
+
totalTokens?: number;
|
|
737
|
+
};
|
|
738
|
+
/** 耗时(毫秒) */
|
|
739
|
+
latencyMs?: number;
|
|
740
|
+
/** 错误信息(success=false 时填充) */
|
|
741
|
+
message?: string;
|
|
742
|
+
/** 结束原因 */
|
|
743
|
+
finishReason?: string;
|
|
744
|
+
/** 协议原始响应 */
|
|
745
|
+
raw?: unknown;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/** 流式多模态聊天入参 */
|
|
749
|
+
export declare interface MultimodalChatStreamOptions extends Omit<MultimodalChatOptions, 'timeoutMs'> {
|
|
750
|
+
/**
|
|
751
|
+
* 增量回调,每次收到协议 chunk 时触发。
|
|
752
|
+
* state.text 是累计完整文本(同 sendDirectChatStream 约定);
|
|
753
|
+
* state.images 是累计完整图片数组(图片一般整块出现,浅拷贝给上层)。
|
|
754
|
+
*/
|
|
755
|
+
onDelta: (state: MultimodalStreamDelta) => void;
|
|
756
|
+
/** 可选超时(毫秒) */
|
|
757
|
+
timeoutMs?: number;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/** 流式多模态聊天的增量回调状态 */
|
|
761
|
+
export declare interface MultimodalStreamDelta {
|
|
762
|
+
/** 累计的完整文本 */
|
|
763
|
+
text?: string;
|
|
764
|
+
/** 累计的图片数组(每次浅拷贝替换,不要 append) */
|
|
765
|
+
images?: Array<{
|
|
766
|
+
type: 'image';
|
|
767
|
+
url?: string;
|
|
768
|
+
b64_json?: string;
|
|
769
|
+
mimeType?: string;
|
|
770
|
+
}>;
|
|
771
|
+
/** 结束原因(最后一片 chunk 时填充) */
|
|
772
|
+
finishReason?: string;
|
|
773
|
+
/** token 用量(最后一片 chunk 时填充) */
|
|
774
|
+
usage?: {
|
|
775
|
+
inputTokens?: number;
|
|
776
|
+
outputTokens?: number;
|
|
777
|
+
totalTokens?: number;
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/** 内部统一的消息结构 */
|
|
782
|
+
export declare interface NormalizedMessage {
|
|
783
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
784
|
+
parts: NormalizedPart[];
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* 内部统一的多模态内容块。
|
|
789
|
+
* 各协议策略都接收 NormalizedMessage[] 作为输入,避免重复处理不同协议字段差异。
|
|
790
|
+
*/
|
|
791
|
+
export declare type NormalizedPart = {
|
|
792
|
+
type: 'text';
|
|
793
|
+
data: string;
|
|
794
|
+
meta?: Record<string, unknown>;
|
|
795
|
+
} | {
|
|
796
|
+
type: 'image';
|
|
797
|
+
data: string;
|
|
798
|
+
mimeType?: string;
|
|
799
|
+
meta?: Record<string, unknown>;
|
|
800
|
+
} | {
|
|
801
|
+
type: 'audio';
|
|
802
|
+
data: string;
|
|
803
|
+
mimeType?: string;
|
|
804
|
+
meta?: Record<string, unknown>;
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* 把 ChatMessage[] 转为 NormalizedMessage[]。
|
|
809
|
+
*
|
|
810
|
+
* 规则:
|
|
811
|
+
* - content: string → 一个 text part
|
|
812
|
+
* - content: ContentPart[] → 逐个 normalizePart
|
|
813
|
+
* - role: 'tool' → 在统一层视为 'user'(避免各策略重复处理 tool role)
|
|
814
|
+
*/
|
|
815
|
+
export declare function normalizeMessages(messages: ChatMessage[]): Promise<NormalizedMessage[]>;
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* 把一个 ContentPart 转成 NormalizedPart。
|
|
819
|
+
* - text:透传
|
|
820
|
+
* - image_url / image / inline_data:归一化为 image + data URI
|
|
821
|
+
* - audio:归一化为 audio + data URI
|
|
822
|
+
*/
|
|
823
|
+
export declare function normalizePart(p: ContentPart): Promise<NormalizedPart>;
|
|
824
|
+
|
|
531
825
|
/**
|
|
532
826
|
* 明文存储适配器(不推荐)
|
|
533
827
|
*/
|
|
@@ -597,6 +891,16 @@ export declare interface ProviderStrategy {
|
|
|
597
891
|
/** 从一个 SSE data 块中提取增量文本(流式)。返回空字符串表示无内容。 */
|
|
598
892
|
parseStreamChunk?: (data: any) => string;
|
|
599
893
|
buildHeaders: (apiKey: string, baseUrl?: string) => Record<string, string>;
|
|
894
|
+
/** 是否支持图片/音频等多模态输入。不支持时调用方传入多模态消息应直接报错。 */
|
|
895
|
+
supportsMultimodalInput?: boolean;
|
|
896
|
+
/** 是否支持多模态输出(如文生图)。不支持时调用方传入 outputModalities 含 image 应直接报错。 */
|
|
897
|
+
supportsMultimodalOutput?: boolean;
|
|
898
|
+
/** 构造多模态聊天请求体 */
|
|
899
|
+
buildMultimodalChatPayload?: (model: string, messages: NormalizedMessage[], options: MultimodalChatOptions) => Record<string, unknown>;
|
|
900
|
+
/** 解析多模态聊天响应为统一的 ResponseMessage */
|
|
901
|
+
parseMultimodalChatResponse?: (data: any) => ResponseMessage;
|
|
902
|
+
/** 解析 SSE 流式 chunk 为增量状态 */
|
|
903
|
+
parseMultimodalStreamChunk?: (data: any) => MultimodalStreamDelta;
|
|
600
904
|
}
|
|
601
905
|
|
|
602
906
|
export declare interface ResolvedConfig {
|
|
@@ -609,6 +913,25 @@ export declare interface ResolvedConfig {
|
|
|
609
913
|
*/
|
|
610
914
|
export declare function resolveProviderConfig(config?: ProviderConfig): ResolvedConfig;
|
|
611
915
|
|
|
916
|
+
/** 各协议策略解析后的统一响应结构 */
|
|
917
|
+
export declare interface ResponseMessage {
|
|
918
|
+
role: 'assistant';
|
|
919
|
+
/**
|
|
920
|
+
* 响应内容:纯文本时用 string,包含图片/音频时用 ContentResponsePart 数组。
|
|
921
|
+
*/
|
|
922
|
+
content: string | ContentResponsePart[];
|
|
923
|
+
/** token 用量(如协议提供) */
|
|
924
|
+
usage?: {
|
|
925
|
+
inputTokens?: number;
|
|
926
|
+
outputTokens?: number;
|
|
927
|
+
totalTokens?: number;
|
|
928
|
+
};
|
|
929
|
+
/** 原始协议响应(调试/透传用) */
|
|
930
|
+
raw?: unknown;
|
|
931
|
+
/** 结束原因(如 'stop'、'length'、'tool_calls') */
|
|
932
|
+
finishReason?: string;
|
|
933
|
+
}
|
|
934
|
+
|
|
612
935
|
/**
|
|
613
936
|
* 纯前端直连 AI 厂商进行聊天
|
|
614
937
|
* 注意: 这会将 API Key 暴露在浏览器中,仅适用于 Demo/测试场景
|
|
@@ -621,6 +944,20 @@ export declare function sendDirectChat(options: DirectChatOptions): Promise<Dire
|
|
|
621
944
|
*/
|
|
622
945
|
export declare function sendDirectChatStream(options: DirectChatStreamOptions): Promise<DirectChatResult>;
|
|
623
946
|
|
|
947
|
+
/**
|
|
948
|
+
* 发送多模态聊天请求(输入支持文本/图片/音频;输出可选图片)。
|
|
949
|
+
* 与 sendDirectChat 并存,是独立 API,不影响纯文本路径。
|
|
950
|
+
*/
|
|
951
|
+
export declare function sendMultimodalChat(options: MultimodalChatOptions): Promise<MultimodalChatResult>;
|
|
952
|
+
|
|
953
|
+
/**
|
|
954
|
+
* 发送多模态聊天请求(SSE 流式)。
|
|
955
|
+
* 每次收到协议 chunk 都会触发 onDelta 回调:
|
|
956
|
+
* - state.text 累计完整文本
|
|
957
|
+
* - state.images 累计完整图片数组(浅拷贝)
|
|
958
|
+
*/
|
|
959
|
+
export declare function sendMultimodalChatStream(options: MultimodalChatStreamOptions): Promise<MultimodalChatResult>;
|
|
960
|
+
|
|
624
961
|
export declare const STATIC_MODELS: Record<string, Model[]>;
|
|
625
962
|
|
|
626
963
|
export declare interface StorageAdapter {
|