@jeffusion/bungee-llms 3.2.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.
Files changed (42) hide show
  1. package/README.md +38 -0
  2. package/dist/adapter.d.ts +1 -0
  3. package/dist/core/adapter.d.ts +10 -0
  4. package/dist/core/conversion-service.d.ts +14 -0
  5. package/dist/core/index.d.ts +4 -0
  6. package/dist/core/registry.d.ts +10 -0
  7. package/dist/core/types.d.ts +40 -0
  8. package/dist/index.d.ts +10 -0
  9. package/dist/index.js +6597 -0
  10. package/dist/openai/index.d.ts +1 -0
  11. package/dist/openai/openai-protocol-conversion.d.ts +1 -0
  12. package/dist/openai-anthropic/index.d.ts +1 -0
  13. package/dist/openai-anthropic/openai-to-anthropic-request-conversion.d.ts +1 -0
  14. package/dist/plugin-api.d.ts +4 -0
  15. package/dist/plugin-api.js +6596 -0
  16. package/dist/protocol-converters/anthropic-to-gemini.converter.d.ts +62 -0
  17. package/dist/protocol-converters/anthropic-to-openai.converter.d.ts +105 -0
  18. package/dist/protocol-converters/base.d.ts +27 -0
  19. package/dist/protocol-converters/default-registry.d.ts +1 -0
  20. package/dist/protocol-converters/gemini-to-anthropic.converter.d.ts +57 -0
  21. package/dist/protocol-converters/gemini-to-openai.converter.d.ts +31 -0
  22. package/dist/protocol-converters/index.d.ts +10 -0
  23. package/dist/protocol-converters/openai-to-anthropic.converter.d.ts +27 -0
  24. package/dist/protocol-converters/openai-to-gemini.converter.d.ts +32 -0
  25. package/dist/protocol-converters/registry.d.ts +9 -0
  26. package/dist/protocol-converters/utils.d.ts +71 -0
  27. package/dist/providers/anthropic/anthropic-adapter.d.ts +16 -0
  28. package/dist/providers/anthropic/index.d.ts +1 -0
  29. package/dist/providers/index.d.ts +4 -0
  30. package/dist/providers/openai/index.d.ts +3 -0
  31. package/dist/providers/openai/messages-compat-normalization.d.ts +42 -0
  32. package/dist/providers/openai/openai-adapter.d.ts +16 -0
  33. package/dist/providers/openai/protocol-conversion.d.ts +27 -0
  34. package/dist/providers/openai-anthropic/index.d.ts +1 -0
  35. package/dist/providers/openai-anthropic/request-conversion.d.ts +20 -0
  36. package/dist/providers/provider-catalog.d.ts +26 -0
  37. package/dist/registry.d.ts +1 -0
  38. package/dist/runtime/index.d.ts +1 -0
  39. package/dist/runtime/llms-runtime.d.ts +30 -0
  40. package/dist/service.d.ts +1 -0
  41. package/dist/types.d.ts +1 -0
  42. package/package.json +76 -0
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Anthropic to Gemini Converter
3
+ *
4
+ * 将 Anthropic Messages API 格式转换为 Google Gemini API 格式
5
+ *
6
+ * 主要转换:
7
+ * - 请求:/v1/messages → /v1beta/models/{model}:generateContent
8
+ * - 请求:messages → contents (role: assistant → model)
9
+ * - 请求:system → systemInstruction
10
+ * - 请求:tools → functionDeclarations
11
+ * - 响应:Gemini 累积文本 → Anthropic 增量文本(SSE)
12
+ */
13
+ import type { AIConverter, MutableRequestContext, ResponseContext, StreamChunkContext } from './base';
14
+ export declare class AnthropicToGeminiConverter implements AIConverter {
15
+ readonly from = "anthropic";
16
+ readonly to = "gemini";
17
+ private toolIdToNameMap;
18
+ private readonly ALLOWED_QUERY_PARAMS;
19
+ /**
20
+ * 过滤 query 参数,只保留白名单中的参数
21
+ */
22
+ private filterSearchParams;
23
+ /**
24
+ * 修改请求 URL 和 body,转换为 Gemini 格式
25
+ */
26
+ onBeforeRequest(ctx: MutableRequestContext): Promise<void>;
27
+ /**
28
+ * 构建 Gemini generateContent 请求
29
+ */
30
+ private buildGenerateContentRequest;
31
+ /**
32
+ * 转换 Anthropic messages 为 Gemini contents
33
+ */
34
+ private convertMessages;
35
+ /**
36
+ * 清理 JSON Schema(移除 Gemini 不支持的字段)
37
+ * 按文档 3.4 Line 144: 深度清洗,去除不被 Gemini 接受的关键词
38
+ * 参考 llms 项目的 cleanupParameters 和 processJsonSchema 实现
39
+ */
40
+ private cleanSchema;
41
+ /**
42
+ * 处理非流式响应
43
+ * 将 Gemini 响应转换为 Anthropic 格式
44
+ */
45
+ onResponse(ctx: ResponseContext): Promise<Response | void>;
46
+ private isJsonLikeContentType;
47
+ private isLikelyGeminiErrorBody;
48
+ private isLikelyGeminiSuccessBody;
49
+ /**
50
+ * 转换 Gemini 响应为 Anthropic 格式
51
+ */
52
+ private convertGeminiResponseToAnthropic;
53
+ /**
54
+ * 处理流式响应 chunk
55
+ * Gemini 返回累积文本,需要转换为 Anthropic 的增量文本
56
+ */
57
+ processStreamChunk(chunk: any, ctx: StreamChunkContext): Promise<any[] | null>;
58
+ /**
59
+ * 流结束时发送最终事件
60
+ */
61
+ flushStream(_ctx: StreamChunkContext): Promise<any[]>;
62
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Anthropic to OpenAI Converter
3
+ *
4
+ * 将 Anthropic Messages API 格式转换为 OpenAI Chat Completions API 格式
5
+ *
6
+ * 转换规则:
7
+ * - 请求:/v1/messages → /v1/chat/completions
8
+ * - 请求:system → messages[0] (role=system)
9
+ * - 请求:tool_result → tool role, tool_use → tool_calls
10
+ * - 请求:thinking.effort / output_config.effort → reasoning_effort 映射
11
+ * - 响应:OpenAI → Anthropic (tool_calls, thinking 标签)
12
+ * - 响应:OpenAI SSE → Anthropic SSE 事件序列
13
+ */
14
+ import type { AIConverter, MutableRequestContext, ResponseContext, StreamChunkContext } from './base';
15
+ export declare class AnthropicToOpenAIConverter implements AIConverter {
16
+ readonly from = "anthropic";
17
+ readonly to = "openai";
18
+ private configuredApiMode?;
19
+ private readonly protocolConversion;
20
+ private readonly runtime;
21
+ constructor();
22
+ setApiMode(mode: unknown): void;
23
+ setRuntimeOptions(options: unknown): void;
24
+ private parseIntegerOption;
25
+ private resolveReasoningMaxCompletionTokens;
26
+ private resolveTargetApiMode;
27
+ /**
28
+ * 修改请求:转换为 OpenAI Chat Completions 格式
29
+ */
30
+ onBeforeRequest(ctx: MutableRequestContext): Promise<void>;
31
+ private canUseRuntimeRequestConversion;
32
+ private isAnthropicCountTokensPath;
33
+ private buildOpenAICountTokensRequest;
34
+ /**
35
+ * 构建 OpenAI 请求
36
+ */
37
+ private buildOpenAIRequest;
38
+ private isAnthropicThinkingEnabled;
39
+ private resolveAnthropicThinkingEffort;
40
+ private resolveOutputConfigEffort;
41
+ private normalizeOpenAIReasoningEffort;
42
+ private supportsXHighReasoningEffort;
43
+ private buildOpenAIResponsesRequest;
44
+ private convertSystemMessages;
45
+ private validateAndCleanToolCalls;
46
+ /**
47
+ * 转换 User 消息
48
+ */
49
+ private normalizeToolResultContent;
50
+ private convertUserMessage;
51
+ private convertUserContentBlock;
52
+ /**
53
+ * 转换 Assistant 消息
54
+ */
55
+ private convertAssistantMessage;
56
+ private normalizeToolCallId;
57
+ private mapAnthropicToolChoiceToOpenAI;
58
+ private parseOpenAIImageUrlSource;
59
+ private normalizeToolParametersSchema;
60
+ private normalizeJsonSchema;
61
+ /**
62
+ * 处理非流式响应:OpenAI → Anthropic
63
+ */
64
+ onResponse(ctx: ResponseContext): Promise<Response | void>;
65
+ private extractCountTokensInput;
66
+ private convertOpenAIErrorToAnthropic;
67
+ private isJsonLikeContentType;
68
+ private isLikelyOpenAIErrorBody;
69
+ private isLikelyOpenAICountTokensBody;
70
+ private isLikelyOpenAISuccessBody;
71
+ private isResponsesApiBody;
72
+ private extractReasoningSummaryTexts;
73
+ private appendUniqueThinkingBlocks;
74
+ private appendParsedContent;
75
+ private extractChatCompletionReasoningTexts;
76
+ private extractReasoningTextFromDeltaContentPart;
77
+ private extractChatThinkingDelta;
78
+ private getChatUsedIndices;
79
+ private allocateChatContentBlockIndex;
80
+ private ensureChatTextBlockStarted;
81
+ private ensureChatThinkingBlockStarted;
82
+ private resolveChatToolIndex;
83
+ private resolveResponsesReasoningIndex;
84
+ private ensureResponsesThinkingBlockStarted;
85
+ private emitResponsesThinkingDelta;
86
+ private extractResponsesReasoningDeltaText;
87
+ private convertOpenAIResponsesToAnthropic;
88
+ /**
89
+ * 转换 OpenAI 响应为 Anthropic 格式
90
+ */
91
+ private convertOpenAIResponseToAnthropic;
92
+ /**
93
+ * 处理流式响应:OpenAI chunk → Anthropic SSE
94
+ */
95
+ processStreamChunk(chunk: any, ctx: StreamChunkContext): Promise<any[] | null>;
96
+ /**
97
+ * 刷新流 - 确保流结束
98
+ */
99
+ flushStream(ctx: StreamChunkContext): Promise<any[]>;
100
+ private isResponsesStreamChunk;
101
+ private processResponsesStreamChunk;
102
+ private finalizeResponsesStreamEvents;
103
+ private extractOpenAIStreamUsage;
104
+ private extractDeltaText;
105
+ }
@@ -0,0 +1,27 @@
1
+ export interface MutableRequestContext {
2
+ url: URL;
3
+ headers: Record<string, string>;
4
+ body: any;
5
+ [key: string]: any;
6
+ }
7
+ export interface ResponseContext {
8
+ response: Response;
9
+ [key: string]: any;
10
+ }
11
+ export interface StreamChunkContext {
12
+ streamState: Map<string, any>;
13
+ chunkIndex?: number;
14
+ isFirstChunk?: boolean;
15
+ isLastChunk?: boolean;
16
+ [key: string]: any;
17
+ }
18
+ export interface AIConverter {
19
+ readonly from: string;
20
+ readonly to: string;
21
+ setRuntimeOptions?(options: unknown): void;
22
+ onBeforeRequest?(ctx: MutableRequestContext): Promise<void>;
23
+ onResponse?(ctx: ResponseContext): Promise<Response | void>;
24
+ processStreamChunk?(chunk: any, ctx: StreamChunkContext): Promise<any[] | null>;
25
+ flushStream?(ctx: StreamChunkContext): Promise<any[]>;
26
+ }
27
+ export type TransformDirection = `${string}-${string}`;
@@ -0,0 +1 @@
1
+ export declare function registerDefaultProtocolConverters(): void;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Gemini to Anthropic Plugin
3
+ *
4
+ * 将 Google Gemini API 格式转换为 Anthropic Messages API 格式
5
+ *
6
+ * 主要转换:
7
+ * - 请求:/v1beta/models/{model}:generateContent → /v1/messages
8
+ * - 请求:contents → messages (role: model → assistant, tool → user)
9
+ * - 请求:systemInstruction → system
10
+ * - 请求:functionDeclarations → tools
11
+ * - 响应:Anthropic 格式 → Gemini candidates 格式
12
+ * - 响应:Anthropic 增量 SSE → Gemini 累积 SSE
13
+ */
14
+ import type { AIConverter, MutableRequestContext, ResponseContext, StreamChunkContext } from './base';
15
+ export declare class GeminiToAnthropicConverter implements AIConverter {
16
+ readonly from = "gemini";
17
+ readonly to = "anthropic";
18
+ private parseGeminiEndpoint;
19
+ /**
20
+ * 修改请求 URL 和 body,转换为 Anthropic 格式
21
+ */
22
+ onBeforeRequest(ctx: MutableRequestContext): Promise<void>;
23
+ /**
24
+ * 转换 Gemini contents 为 Anthropic messages
25
+ */
26
+ private convertContentsToMessages;
27
+ /**
28
+ * 转换 Gemini tools 为 Anthropic tools
29
+ */
30
+ private convertTools;
31
+ /**
32
+ * 转换 Gemini schema 类型为 JSON Schema
33
+ */
34
+ private convertSchema;
35
+ /**
36
+ * 处理非流式响应
37
+ * 将 Anthropic 响应转换为 Gemini 格式
38
+ */
39
+ onResponse(ctx: ResponseContext): Promise<Response | void>;
40
+ /**
41
+ * 转换 Anthropic 错误响应为 Gemini 格式
42
+ */
43
+ private mapAnthropicErrorToGeminiStatus;
44
+ private transformErrorResponse;
45
+ private isJsonLikeContentType;
46
+ private isLikelyAnthropicErrorBody;
47
+ private isLikelyAnthropicSuccessBody;
48
+ /**
49
+ * 转换 Anthropic 响应为 Gemini candidates 格式
50
+ */
51
+ private convertAnthropicResponseToGemini;
52
+ /**
53
+ * 处理流式响应 chunk
54
+ * Anthropic 返回增量文本,需要累积为 Gemini 的累积格式
55
+ */
56
+ processStreamChunk(chunk: any, ctx: StreamChunkContext): Promise<any[] | null>;
57
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Gemini to OpenAI Plugin
3
+ *
4
+ * 将 Google Gemini API 格式转换为 OpenAI Chat Completions API 格式
5
+ *
6
+ * 主要转换:
7
+ * - 请求:/v1beta/models/{model}:generateContent → /v1/chat/completions
8
+ * - 请求:contents → messages
9
+ * - 响应:OpenAI chat.completion → Gemini candidates 格式
10
+ */
11
+ import type { AIConverter, MutableRequestContext, ResponseContext, StreamChunkContext } from './base';
12
+ export declare class GeminiToOpenAIConverter implements AIConverter {
13
+ readonly from = "gemini";
14
+ readonly to = "openai";
15
+ private parseGeminiEndpoint;
16
+ onBeforeRequest(ctx: MutableRequestContext): Promise<void>;
17
+ private parseToolArgumentsToObject;
18
+ private buildOpenAIRequest;
19
+ onResponse(ctx: ResponseContext): Promise<Response | void>;
20
+ private mapOpenAIErrorToGeminiStatus;
21
+ private transformErrorResponse;
22
+ private isJsonLikeContentType;
23
+ private isLikelyOpenAIErrorBody;
24
+ private isLikelyOpenAISuccessBody;
25
+ private convertOpenAIResponseToGemini;
26
+ processStreamChunk(chunk: any, ctx: StreamChunkContext): Promise<any[] | null>;
27
+ /**
28
+ * flushStream - 此 transformer 不需要缓冲,返回空数组
29
+ */
30
+ flushStream(ctx: StreamChunkContext): Promise<any[]>;
31
+ }
@@ -0,0 +1,10 @@
1
+ export * from './base';
2
+ export * from './utils';
3
+ export * from './registry';
4
+ export * from './default-registry';
5
+ export * from './openai-to-anthropic.converter';
6
+ export * from './anthropic-to-openai.converter';
7
+ export * from './openai-to-gemini.converter';
8
+ export * from './gemini-to-openai.converter';
9
+ export * from './anthropic-to-gemini.converter';
10
+ export * from './gemini-to-anthropic.converter';
@@ -0,0 +1,27 @@
1
+ /**
2
+ * OpenAI to Anthropic Converter
3
+ *
4
+ * 将 OpenAI Chat Completions API 格式转换为 Anthropic Messages API 格式
5
+ *
6
+ * 转换规则:
7
+ * - 请求:/v1/chat/completions → /v1/messages
8
+ * - 请求:messages、tools、reasoning_effort
9
+ * - 响应:Anthropic message → OpenAI chat.completion
10
+ * - 响应:Anthropic SSE → OpenAI SSE
11
+ */
12
+ import type { AIConverter, MutableRequestContext, ResponseContext, StreamChunkContext } from './base';
13
+ export declare class OpenAIToAnthropicConverter implements AIConverter {
14
+ readonly from = "openai";
15
+ readonly to = "anthropic";
16
+ private readonly runtime;
17
+ constructor();
18
+ onBeforeRequest(ctx: MutableRequestContext): Promise<void>;
19
+ onResponse(ctx: ResponseContext): Promise<Response | void>;
20
+ private mapAnthropicErrorToOpenAIType;
21
+ private transformErrorResponse;
22
+ private isJsonLikeContentType;
23
+ private isLikelyAnthropicErrorBody;
24
+ private convertAnthropicResponseToOpenAI;
25
+ processStreamChunk(chunk: any, ctx: StreamChunkContext): Promise<any[] | null>;
26
+ flushStream(ctx: StreamChunkContext): Promise<any[]>;
27
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * OpenAI to Gemini Plugin
3
+ *
4
+ * 将 OpenAI Chat Completions API 格式转换为 Google Gemini API 格式
5
+ *
6
+ * 主要转换:
7
+ * - 请求:/v1/chat/completions → /v1beta/models/{model}:generateContent
8
+ * - 请求:messages → contents
9
+ * - 响应:Gemini → OpenAI chat.completion
10
+ */
11
+ import type { AIConverter, MutableRequestContext, ResponseContext, StreamChunkContext } from './base';
12
+ export declare class OpenAIToGeminiConverter implements AIConverter {
13
+ readonly from = "openai";
14
+ readonly to = "gemini";
15
+ private extractInstructionText;
16
+ private parseToolArgumentsToObject;
17
+ private buildToolCallIdToNameMap;
18
+ onBeforeRequest(ctx: MutableRequestContext): Promise<void>;
19
+ private buildGeminiRequest;
20
+ private cleanSchema;
21
+ onResponse(ctx: ResponseContext): Promise<Response | void>;
22
+ private mapGeminiErrorToOpenAIType;
23
+ private transformErrorResponse;
24
+ private isJsonLikeContentType;
25
+ private isLikelyGeminiErrorBody;
26
+ private convertGeminiResponseToOpenAI;
27
+ processStreamChunk(chunk: any, ctx: StreamChunkContext): Promise<any[] | null>;
28
+ /**
29
+ * flushStream - 此 transformer 不需要缓冲,返回空数组
30
+ */
31
+ flushStream(ctx: StreamChunkContext): Promise<any[]>;
32
+ }
@@ -0,0 +1,9 @@
1
+ import type { AIConverter, TransformDirection } from './base';
2
+ export declare class ProtocolTransformerRegistry {
3
+ private static converters;
4
+ static register(from: string, to: string, ConverterClass: new () => AIConverter): void;
5
+ static get(from: string, to: string): AIConverter;
6
+ static has(from: string, to: string): boolean;
7
+ static getAllDirections(): TransformDirection[];
8
+ static clear(): void;
9
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Converter Utility Functions
3
+ *
4
+ * 提供转换器使用的通用工具函数
5
+ */
6
+ /**
7
+ * 生成 Anthropic 风格的消息 ID
8
+ *
9
+ * @returns 格式为 msg_xxxxxxxxxxxxxxxxxxxxxxxx 的 ID(24位十六进制)
10
+ */
11
+ export declare function generateAnthropicMessageId(): string;
12
+ /**
13
+ * 生成 OpenAI 风格的聊天完成 ID
14
+ *
15
+ * @returns 格式为 chatcmpl-xxxxxxxxxxxxxxxxxxxxxxxx 的 ID
16
+ */
17
+ export declare function generateOpenAIChatCompletionId(): string;
18
+ /**
19
+ * 生成 Gemini 风格的候选 ID
20
+ *
21
+ * @returns 格式为 candidate-xxxxxxxx 的 ID
22
+ */
23
+ export declare function generateGeminiCandidateId(): string;
24
+ /**
25
+ * 解析文本中的 <thinking> 标签
26
+ *
27
+ * @param text - 包含 <thinking> 标签的文本
28
+ * @returns 解析后的内容块数组
29
+ */
30
+ export declare function parseThinkingTags(text: string): Array<{
31
+ type: string;
32
+ text?: string;
33
+ thinking?: string;
34
+ }>;
35
+ /**
36
+ * 将 thinking 块转换为 <thinking> 标签文本
37
+ *
38
+ * @param blocks - 内容块数组
39
+ * @returns 包含 <thinking> 标签的文本
40
+ */
41
+ export declare function convertThinkingBlocksToTags(blocks: any[]): string;
42
+ /**
43
+ * 映射 Anthropic stop_reason 到 OpenAI finish_reason
44
+ *
45
+ * @param stopReason - Anthropic stop_reason
46
+ * @returns OpenAI finish_reason
47
+ */
48
+ export declare function mapAnthropicStopReasonToOpenAI(stopReason: string): string;
49
+ /**
50
+ * 映射 OpenAI finish_reason 到 Anthropic stop_reason
51
+ *
52
+ * @param finishReason - OpenAI finish_reason
53
+ * @returns Anthropic stop_reason
54
+ */
55
+ export declare function mapOpenAIFinishReasonToAnthropic(finishReason: string): string;
56
+ /**
57
+ * 安全解析 JSON 字符串
58
+ *
59
+ * @param jsonString - JSON 字符串
60
+ * @param defaultValue - 解析失败时的默认值
61
+ * @returns 解析结果或默认值
62
+ */
63
+ export declare function safeJsonParse<T = any>(jsonString: string, defaultValue?: T): T;
64
+ /**
65
+ * 安全 JSON 字符串化
66
+ *
67
+ * @param obj - 要字符串化的对象
68
+ * @param defaultValue - 字符串化失败时的默认值
69
+ * @returns JSON 字符串或默认值
70
+ */
71
+ export declare function safeJsonStringify(obj: any, defaultValue?: string): string;
@@ -0,0 +1,16 @@
1
+ import type { LLMProtocolAdapter } from '../../core/adapter';
2
+ import type { CanonicalRequest, CanonicalResponse, CanonicalStreamEvent, ConversionContext } from '../../core/types';
3
+ import { OpenAIToAnthropicRequestConversion } from '../openai-anthropic/request-conversion';
4
+ type JsonRecord = Record<string, unknown>;
5
+ export declare class AnthropicAdapter implements LLMProtocolAdapter<JsonRecord, JsonRecord, unknown> {
6
+ private readonly openAIToAnthropic;
7
+ readonly provider: "anthropic";
8
+ constructor(openAIToAnthropic?: OpenAIToAnthropicRequestConversion);
9
+ toCanonicalRequest(request: JsonRecord, context: ConversionContext): CanonicalRequest;
10
+ fromCanonicalRequest(request: CanonicalRequest, context: ConversionContext): JsonRecord;
11
+ toCanonicalResponse(response: JsonRecord, context: ConversionContext): CanonicalResponse;
12
+ fromCanonicalResponse(response: CanonicalResponse): JsonRecord;
13
+ toCanonicalStreamEvent(event: unknown): CanonicalStreamEvent;
14
+ fromCanonicalStreamEvent(event: CanonicalStreamEvent): unknown;
15
+ }
16
+ export {};
@@ -0,0 +1 @@
1
+ export * from './anthropic-adapter';
@@ -0,0 +1,4 @@
1
+ export * from './provider-catalog';
2
+ export * from './anthropic';
3
+ export * from './openai';
4
+ export * from './openai-anthropic';
@@ -0,0 +1,3 @@
1
+ export * from './protocol-conversion';
2
+ export * from './messages-compat-normalization';
3
+ export * from './openai-adapter';
@@ -0,0 +1,42 @@
1
+ export interface OpenAIMessagesCompatibilityNormalizerOptions {
2
+ strictValidation?: boolean;
3
+ allowShortPathAlias?: boolean;
4
+ }
5
+ export interface OpenAIMessagesCompatibilityRequestLike {
6
+ method: string;
7
+ url: {
8
+ pathname: string;
9
+ };
10
+ }
11
+ export type OpenAIMessagesCompatibilityJsonObject = Record<string, unknown>;
12
+ export type OpenAIMessagesCompatibilityBodyValidationResult = {
13
+ ok: true;
14
+ body: OpenAIMessagesCompatibilityJsonObject;
15
+ } | {
16
+ ok: false;
17
+ message: string;
18
+ };
19
+ export declare class OpenAIMessagesCompatibilityNormalizer {
20
+ private readonly strictValidation;
21
+ private readonly allowShortPathAlias;
22
+ constructor(options?: OpenAIMessagesCompatibilityNormalizerOptions);
23
+ shouldHandleRequest(ctx: OpenAIMessagesCompatibilityRequestLike): boolean;
24
+ validateAndNormalizeBody(rawBody: unknown): OpenAIMessagesCompatibilityBodyValidationResult;
25
+ isOpenAIResponsePayload(payload: unknown): boolean;
26
+ isOpenAIStreamChunk(chunk: unknown): boolean;
27
+ buildBadRequest(message: string): Response;
28
+ private normalizePathname;
29
+ private collectConflictingFields;
30
+ private parseToolsInput;
31
+ private normalizeSingleTool;
32
+ private normalizeTools;
33
+ private normalizeToolChoice;
34
+ private ensureAssistantToolCallReasoningContent;
35
+ private normalizeMessage;
36
+ private normalizeToolCallId;
37
+ private normalizeToolResultContent;
38
+ private extractThinkingText;
39
+ private normalizeUserMessageWithToolResults;
40
+ private normalizeAssistantMessageWithToolUse;
41
+ private normalizeContentPart;
42
+ }
@@ -0,0 +1,16 @@
1
+ import type { LLMProtocolAdapter } from '../../core/adapter';
2
+ import type { CanonicalRequest, CanonicalResponse, CanonicalStreamEvent, ConversionContext } from '../../core/types';
3
+ import { OpenAIProtocolConversion } from './protocol-conversion';
4
+ type JsonRecord = Record<string, unknown>;
5
+ export declare class OpenAIAdapter implements LLMProtocolAdapter<JsonRecord, JsonRecord, unknown> {
6
+ private readonly protocolConversion;
7
+ readonly provider: "openai";
8
+ constructor(protocolConversion?: OpenAIProtocolConversion);
9
+ toCanonicalRequest(request: JsonRecord, context: ConversionContext): CanonicalRequest;
10
+ fromCanonicalRequest(request: CanonicalRequest): JsonRecord;
11
+ toCanonicalResponse(response: JsonRecord, context: ConversionContext): CanonicalResponse;
12
+ fromCanonicalResponse(response: CanonicalResponse): JsonRecord;
13
+ toCanonicalStreamEvent(event: unknown): CanonicalStreamEvent;
14
+ fromCanonicalStreamEvent(event: CanonicalStreamEvent): unknown;
15
+ }
16
+ export {};
@@ -0,0 +1,27 @@
1
+ export type JsonRecord = Record<string, unknown>;
2
+ export interface OpenAIProtocolConversionOptions {
3
+ trimWhitespace?: boolean;
4
+ }
5
+ export declare class OpenAIProtocolConversion {
6
+ private readonly trimWhitespace;
7
+ constructor(options?: OpenAIProtocolConversionOptions);
8
+ isResponsesPath(pathname: string): boolean;
9
+ isReasoningContext(body: JsonRecord): boolean;
10
+ normalizeResponsesReasoningBody(body: JsonRecord): JsonRecord;
11
+ ensureAssistantToolUseReasoningContent(response: Response): Promise<Response>;
12
+ ensureMessagesStreamCompatibility(events: unknown[], ctx: {
13
+ streamState: Map<string, unknown>;
14
+ }): unknown[];
15
+ convertChatMessagesToResponsesInput(messages: unknown): {
16
+ input: JsonRecord[];
17
+ instructions?: string;
18
+ };
19
+ mapChatToolsToResponsesTools(chatTools: unknown): JsonRecord[];
20
+ convertResponsesInputToMessages(input: unknown): JsonRecord[];
21
+ normalizeResponsesMessageContent(content: unknown): unknown;
22
+ private normalizeMessageCollection;
23
+ private normalizeAssistantToolCallCandidate;
24
+ private extractThinkingTextFromAnthropicContent;
25
+ private ensureMessageStartReasoningContent;
26
+ private ensureMessageDeltaUsage;
27
+ }
@@ -0,0 +1 @@
1
+ export * from './request-conversion';
@@ -0,0 +1,20 @@
1
+ import { OpenAIProtocolConversion } from '../openai/protocol-conversion';
2
+ export interface OpenAIToAnthropicRequestConversionResult {
3
+ pathname: '/v1/messages';
4
+ body: Record<string, unknown>;
5
+ }
6
+ export declare class OpenAIToAnthropicRequestConversion {
7
+ private readonly protocolConversion;
8
+ constructor(protocolConversion?: OpenAIProtocolConversion);
9
+ convert(pathname: string, body: unknown): OpenAIToAnthropicRequestConversionResult | null;
10
+ private normalizeOpenAIRequestBody;
11
+ private convertTools;
12
+ private mapOpenAIToolChoiceToAnthropic;
13
+ private extractInstructionText;
14
+ private validateAndCleanToolCalls;
15
+ private parseImageSource;
16
+ private normalizeToolResultContent;
17
+ private convertToolResultPart;
18
+ private convertToolMessageToResultBlock;
19
+ private convertMessages;
20
+ }
@@ -0,0 +1,26 @@
1
+ import type { LLMProvider } from '../core/types';
2
+ export interface ProviderCapabilities {
3
+ supportsChatCompletions?: boolean;
4
+ supportsResponsesApi?: boolean;
5
+ supportsToolCalls?: boolean;
6
+ supportsReasoning?: boolean;
7
+ supportsStreaming?: boolean;
8
+ supportsVision?: boolean;
9
+ [key: string]: unknown;
10
+ }
11
+ export interface ProviderDescriptor {
12
+ provider: LLMProvider;
13
+ displayName?: string;
14
+ aliases?: string[];
15
+ capabilities?: ProviderCapabilities;
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ export declare class LLMProviderCatalog {
19
+ private readonly descriptors;
20
+ private readonly aliasToProvider;
21
+ register(descriptor: ProviderDescriptor): void;
22
+ unregister(provider: LLMProvider): void;
23
+ get(provider: LLMProvider | string): ProviderDescriptor | undefined;
24
+ has(provider: LLMProvider | string): boolean;
25
+ list(): ProviderDescriptor[];
26
+ }
@@ -0,0 +1 @@
1
+ export * from './core/registry';
@@ -0,0 +1 @@
1
+ export * from './llms-runtime';
@@ -0,0 +1,30 @@
1
+ import type { LLMProtocolAdapter } from '../core/adapter';
2
+ import { LLMProtocolAdapterRegistry } from '../core/registry';
3
+ import { LLMProtocolConversionService } from '../core/conversion-service';
4
+ import type { LLMProvider } from '../core/types';
5
+ import { LLMProviderCatalog, type ProviderDescriptor } from '../providers/provider-catalog';
6
+ export interface LLMSRuntimeOptions {
7
+ adapterRegistry?: LLMProtocolAdapterRegistry;
8
+ conversionService?: LLMProtocolConversionService;
9
+ providerCatalog?: LLMProviderCatalog;
10
+ }
11
+ export interface RuntimeAdapterRegistration {
12
+ adapter: LLMProtocolAdapter;
13
+ descriptor?: ProviderDescriptor;
14
+ }
15
+ export declare class LLMSRuntime {
16
+ private readonly adapterRegistry;
17
+ private readonly conversionService;
18
+ private readonly providerCatalog;
19
+ constructor(options?: LLMSRuntimeOptions);
20
+ registerAdapter(adapter: LLMProtocolAdapter, descriptor?: ProviderDescriptor): void;
21
+ registerAdapters(registrations: RuntimeAdapterRegistration[]): void;
22
+ unregisterProvider(provider: LLMProvider): void;
23
+ convertRequest<T = unknown>(from: LLMProvider, to: LLMProvider, request: unknown, metadata?: Record<string, unknown>): T;
24
+ convertResponse<T = unknown>(from: LLMProvider, to: LLMProvider, response: unknown, metadata?: Record<string, unknown>): T;
25
+ convertStreamEvent<T = unknown>(from: LLMProvider, to: LLMProvider, event: unknown, metadata?: Record<string, unknown>): T | null;
26
+ getProviderCatalog(): LLMProviderCatalog;
27
+ getAdapterRegistry(): LLMProtocolAdapterRegistry;
28
+ getConversionService(): LLMProtocolConversionService;
29
+ listProviders(): ProviderDescriptor[];
30
+ }
@@ -0,0 +1 @@
1
+ export * from './core/conversion-service';
@@ -0,0 +1 @@
1
+ export * from './core/types';