@jeffusion/bungee-llms 5.20.0 → 5.22.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/README.md +8 -31
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2158 -5530
- package/dist/plugin-api.d.ts +1 -4
- package/dist/plugin-api.js +4069 -8408
- package/dist/protocol-session/index.d.ts +14 -0
- package/dist/protocol-session/request.d.ts +5 -0
- package/dist/protocol-session/response.d.ts +23 -0
- package/dist/protocol-session/schema.d.ts +5 -0
- package/dist/protocol-session/stream.d.ts +35 -0
- package/dist/protocol-session/types.d.ts +48 -0
- package/dist/protocol-session/validation.d.ts +5 -0
- package/dist/providers/openai/index.d.ts +0 -1
- package/dist/responses-codec/common.d.ts +17 -2
- package/dist/responses-codec/events.d.ts +7 -1
- package/dist/responses-codec/index.d.ts +1 -1
- package/dist/responses-codec/request-preferences.d.ts +3 -0
- package/dist/responses-codec/request.d.ts +3 -1
- package/dist/responses-codec/web-search.d.ts +3 -0
- package/package.json +3 -3
- package/dist/protocol-converters/anthropic-to-gemini.converter.d.ts +0 -62
- package/dist/protocol-converters/anthropic-to-openai.converter.d.ts +0 -110
- package/dist/protocol-converters/base.d.ts +0 -38
- package/dist/protocol-converters/default-registry.d.ts +0 -1
- package/dist/protocol-converters/gemini-to-anthropic.converter.d.ts +0 -57
- package/dist/protocol-converters/gemini-to-openai.converter.d.ts +0 -31
- package/dist/protocol-converters/index.d.ts +0 -10
- package/dist/protocol-converters/openai-to-anthropic.converter.d.ts +0 -27
- package/dist/protocol-converters/openai-to-gemini.converter.d.ts +0 -32
- package/dist/protocol-converters/registry.d.ts +0 -9
- package/dist/protocol-converters/utils.d.ts +0 -71
- package/dist/providers/openai/messages-compat-normalization.d.ts +0 -42
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ProtocolSession, type ProtocolSessionContext } from './types';
|
|
2
|
+
export * from './types';
|
|
3
|
+
export declare const PROTOCOL_CONVERSION_RULES_VERSION = "1.0.1";
|
|
4
|
+
export declare function describeProtocolConversion(): {
|
|
5
|
+
rulesVersion: string;
|
|
6
|
+
protocols: ("chat_completions" | "anthropic_messages" | "responses" | "gemini_generate_content")[];
|
|
7
|
+
matrix: {
|
|
8
|
+
readonly sourceProtocol: "chat_completions" | "anthropic_messages" | "responses" | "gemini_generate_content";
|
|
9
|
+
readonly targetProtocol: "chat_completions" | "anthropic_messages" | "responses" | "gemini_generate_content";
|
|
10
|
+
readonly mode: "passthrough" | "unsupported" | "convert";
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
/** One request/attempt, bounded retained state, plain own-property functions for local service facades. */
|
|
14
|
+
export declare function createProtocolSession(context: ProtocolSessionContext): ProtocolSession;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type JsonRecord } from '../responses-codec/common';
|
|
2
|
+
import type { LLMProtocol, ProtocolSessionContext, ProtocolRequestConversion } from './types';
|
|
3
|
+
/** The normative history is Responses items, not a provider plugin conversion chain. */
|
|
4
|
+
export declare function canonicalRequest(raw: unknown, protocol: LLMProtocol, model: string): JsonRecord;
|
|
5
|
+
export declare function convertProtocolRequest(raw: unknown, context: ProtocolSessionContext): ProtocolRequestConversion;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type JsonRecord, type ResponsesToolNames } from '../responses-codec/common';
|
|
2
|
+
import type { LLMProtocol, ProtocolSessionContext } from './types';
|
|
3
|
+
export declare function safeProtocolError(): JsonRecord;
|
|
4
|
+
export declare function validateUsage(raw: unknown, protocol: LLMProtocol): void;
|
|
5
|
+
export declare function validateProviderResponse(raw: unknown, protocol: LLMProtocol): JsonRecord;
|
|
6
|
+
export declare function validateAnthropicBlock(b: JsonRecord, path: string): void;
|
|
7
|
+
export declare function validateCanonicalResponse(raw: unknown, context: ProtocolSessionContext, itemOnly?: boolean): JsonRecord;
|
|
8
|
+
export declare function canonicalUsage(raw: unknown): JsonRecord;
|
|
9
|
+
export declare function wireUsage(raw: unknown, protocol: LLMProtocol): JsonRecord;
|
|
10
|
+
export declare function responseFromCanonical(raw: unknown, protocol: LLMProtocol, context: ProtocolSessionContext): JsonRecord;
|
|
11
|
+
/** Gemini chunks carry complete function-call objects, never JSON argument deltas. */
|
|
12
|
+
export declare class GeminiCanonicalDecoder {
|
|
13
|
+
private context;
|
|
14
|
+
private encoder;
|
|
15
|
+
private serial;
|
|
16
|
+
private ended;
|
|
17
|
+
private tools;
|
|
18
|
+
private ids;
|
|
19
|
+
constructor(context: ProtocolSessionContext, names: ResponsesToolNames);
|
|
20
|
+
push(raw: unknown): JsonRecord[];
|
|
21
|
+
finish(): JsonRecord[];
|
|
22
|
+
}
|
|
23
|
+
export declare function canonicalResponse(raw: unknown, context: ProtocolSessionContext, names: ResponsesToolNames): JsonRecord;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type JsonRecord } from '../responses-codec/common';
|
|
2
|
+
/** Gemini's Schema is an OpenAPI dialect, not JSON Schema. Preserve supported
|
|
3
|
+
* constraints exactly and reject provider-specific ordering or unknown extensions.
|
|
4
|
+
*/
|
|
5
|
+
export declare function geminiSchemaToJson(raw: unknown, path: string, code?: string, depth?: number): JsonRecord;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type JsonRecord } from '../responses-codec/common';
|
|
2
|
+
import type { LLMProtocol, ProtocolSessionContext } from './types';
|
|
3
|
+
/** Validate Responses event ordering and final snapshots before rendering another wire protocol. */
|
|
4
|
+
export declare class CanonicalStreamValidator {
|
|
5
|
+
private context;
|
|
6
|
+
private items;
|
|
7
|
+
private started;
|
|
8
|
+
private ended;
|
|
9
|
+
private sequence;
|
|
10
|
+
private retained;
|
|
11
|
+
private partCount;
|
|
12
|
+
private responseId?;
|
|
13
|
+
constructor(context: ProtocolSessionContext);
|
|
14
|
+
push(raw: unknown): JsonRecord[];
|
|
15
|
+
private retain;
|
|
16
|
+
finish(): JsonRecord[];
|
|
17
|
+
}
|
|
18
|
+
export declare class CanonicalStreamRenderer {
|
|
19
|
+
private protocol;
|
|
20
|
+
private context;
|
|
21
|
+
private id;
|
|
22
|
+
private created;
|
|
23
|
+
private toolCount;
|
|
24
|
+
private started;
|
|
25
|
+
private items;
|
|
26
|
+
private blocks;
|
|
27
|
+
private nextBlock;
|
|
28
|
+
private toolIndexes;
|
|
29
|
+
constructor(protocol: LLMProtocol, context: ProtocolSessionContext);
|
|
30
|
+
push(events: JsonRecord[]): JsonRecord[];
|
|
31
|
+
private chat;
|
|
32
|
+
private gemini;
|
|
33
|
+
private blockKey;
|
|
34
|
+
private render;
|
|
35
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ResponsesCodecCapabilities, ResponsesConversionDiagnostic, ResponsesToolNames } from '../responses-codec';
|
|
2
|
+
export declare const LLM_PROTOCOLS: readonly ["responses", "chat_completions", "anthropic_messages", "gemini_generate_content"];
|
|
3
|
+
export type LLMProtocol = typeof LLM_PROTOCOLS[number];
|
|
4
|
+
export type ProtocolJsonObject = Record<string, unknown>;
|
|
5
|
+
/** Every mapping is supplied by the capability owner, never inferred from a reasoning flag. */
|
|
6
|
+
export interface ProtocolReasoningPolicy {
|
|
7
|
+
effortMap?: Readonly<Record<string, string>>;
|
|
8
|
+
/** Verified target effort for source budget/mode policies that have no effort label. */
|
|
9
|
+
targetEffort?: string;
|
|
10
|
+
anthropicThinkingBudget?: number;
|
|
11
|
+
anthropicThinkingMode?: 'adaptive' | 'enabled' | 'disabled';
|
|
12
|
+
geminiThinkingBudget?: number;
|
|
13
|
+
geminiThinkingLevel?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ProtocolSessionCapabilities extends ResponsesCodecCapabilities {
|
|
16
|
+
anthropicStructuredOutput?: boolean;
|
|
17
|
+
anthropicStrictTools?: boolean;
|
|
18
|
+
anthropicEffort?: boolean;
|
|
19
|
+
geminiJsonSchema?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface ProtocolSessionContext {
|
|
22
|
+
sourceProtocol: LLMProtocol;
|
|
23
|
+
targetProtocol: LLMProtocol;
|
|
24
|
+
/** Target model; caller owns routing and source URL validation. */
|
|
25
|
+
model: string;
|
|
26
|
+
/** Transport-derived mode for protocols such as Gemini whose stream flag is in the URL. */
|
|
27
|
+
streaming?: boolean;
|
|
28
|
+
responseModel?: string;
|
|
29
|
+
capabilities?: ProtocolSessionCapabilities;
|
|
30
|
+
reasoningPolicy?: ProtocolReasoningPolicy;
|
|
31
|
+
}
|
|
32
|
+
export interface ProtocolRequestConversion {
|
|
33
|
+
body: ProtocolJsonObject;
|
|
34
|
+
canonicalHistory: ProtocolJsonObject[];
|
|
35
|
+
diagnostics: ResponsesConversionDiagnostic[];
|
|
36
|
+
toolNames: ResponsesToolNames;
|
|
37
|
+
streaming: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** Requests flow source→target; responses and JSON stream events flow target→source.
|
|
40
|
+
* Transport framing, [DONE], HTTP errors, readers and cancellation are caller-owned.
|
|
41
|
+
*/
|
|
42
|
+
export interface ProtocolSession {
|
|
43
|
+
convertRequest(raw: unknown): ProtocolRequestConversion;
|
|
44
|
+
convertResponse(raw: unknown): ProtocolJsonObject;
|
|
45
|
+
push(event: unknown): ProtocolJsonObject[];
|
|
46
|
+
finish(): ProtocolJsonObject[];
|
|
47
|
+
dispose(): void;
|
|
48
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type JsonRecord } from '../responses-codec/common';
|
|
2
|
+
export declare function fields(value: JsonRecord, allowed: readonly string[], path: string, code?: string): void;
|
|
3
|
+
export declare function bool(value: unknown, path: string): boolean;
|
|
4
|
+
export declare function integer(value: unknown, path: string, min?: number): number;
|
|
5
|
+
export declare function textParts(raw: unknown, path: string, style: 'chat' | 'anthropic' | 'gemini', role: string): JsonRecord[];
|
|
@@ -16,16 +16,31 @@ export interface ResponsesCodecLimits {
|
|
|
16
16
|
export declare const DEFAULT_RESPONSES_CODEC_LIMITS: Readonly<ResponsesCodecLimits>;
|
|
17
17
|
export interface ResponsesCodecCapabilities {
|
|
18
18
|
reasoningEffort?: boolean;
|
|
19
|
+
/** Plain reasoning history support is independent of effort parameter mapping. */
|
|
20
|
+
reasoningHistory?: boolean;
|
|
21
|
+
anthropicStrictTools?: boolean;
|
|
22
|
+
/** Include original names in alias descriptions so model-facing identity is retained. */
|
|
23
|
+
preserveToolIdentityDescription?: boolean;
|
|
24
|
+
preserveRefusalContent?: boolean;
|
|
25
|
+
/** Codex declares optional hosted search even when the selected model has no search backend. */
|
|
26
|
+
omitOptionalWebSearch?: boolean;
|
|
19
27
|
/** Explicit provider-approved thinking budget; do not guess budgets from effort labels. */
|
|
20
28
|
anthropicThinkingBudget?: number;
|
|
21
29
|
maxOutputTokens?: number;
|
|
22
30
|
limits?: Partial<ResponsesCodecLimits>;
|
|
23
31
|
}
|
|
32
|
+
export interface ResponsesConversionDiagnostic {
|
|
33
|
+
param: string;
|
|
34
|
+
action: 'mapped' | 'omitted';
|
|
35
|
+
reason: string;
|
|
36
|
+
}
|
|
24
37
|
export declare class ResponsesCodecError extends Error {
|
|
25
38
|
readonly code: string;
|
|
26
|
-
|
|
39
|
+
readonly param?: string | undefined;
|
|
40
|
+
constructor(code: string, message: string, param?: string | undefined);
|
|
27
41
|
}
|
|
28
|
-
export declare function fail(code: string, message: string): never;
|
|
42
|
+
export declare function fail(code: string, message: string, param?: string): never;
|
|
43
|
+
export declare function atParam<T>(param: string, run: () => T): T;
|
|
29
44
|
export declare function record(value: unknown, where: string): JsonRecord;
|
|
30
45
|
export declare function string(value: unknown, where: string, nonempty?: boolean): string;
|
|
31
46
|
export declare function list(value: unknown, where: string): unknown[];
|
|
@@ -7,6 +7,7 @@ export declare class ResponsesEventEncoder {
|
|
|
7
7
|
readonly protocol: ResponsesProtocol;
|
|
8
8
|
readonly model: string;
|
|
9
9
|
readonly toolNames: ResponsesToolNames;
|
|
10
|
+
private readonly options;
|
|
10
11
|
private readonly budget;
|
|
11
12
|
private readonly id;
|
|
12
13
|
private readonly createdAt;
|
|
@@ -23,7 +24,12 @@ export declare class ResponsesEventEncoder {
|
|
|
23
24
|
private poisoned;
|
|
24
25
|
private sequence;
|
|
25
26
|
private retained;
|
|
26
|
-
|
|
27
|
+
private lastKind?;
|
|
28
|
+
private contentSerial;
|
|
29
|
+
constructor(protocol: ResponsesProtocol, model: string, toolNames?: ResponsesToolNames, configuredLimits?: Partial<ResponsesCodecLimits>, options?: {
|
|
30
|
+
preserveContentOrder?: boolean;
|
|
31
|
+
});
|
|
32
|
+
private contentState;
|
|
27
33
|
private event;
|
|
28
34
|
private start;
|
|
29
35
|
private retain;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { decodeResponsesRequest, type DecodedResponsesRequest } from './request';
|
|
2
2
|
export { encodeResponsesResult } from './result';
|
|
3
3
|
export { ResponsesEventEncoder } from './events';
|
|
4
|
-
export { ResponsesCodecError, DEFAULT_RESPONSES_CODEC_LIMITS, type ResponsesProtocol, type ResponsesToolName, type ResponsesToolNames, type ResponsesCodecCapabilities, type ResponsesCodecLimits } from './common';
|
|
4
|
+
export { ResponsesCodecError, DEFAULT_RESPONSES_CODEC_LIMITS, type ResponsesProtocol, type ResponsesToolName, type ResponsesToolNames, type ResponsesCodecCapabilities, type ResponsesCodecLimits, type ResponsesConversionDiagnostic } from './common';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type JsonRecord, type ResponsesCodecCapabilities, type ResponsesConversionDiagnostic, type ResponsesProtocol } from './common';
|
|
2
|
+
/** Known preferences may be omitted; output constraints are handled by the request renderer. */
|
|
3
|
+
export declare function applyResponsesPreferences(body: JsonRecord, result: JsonRecord, protocol: ResponsesProtocol, capabilities: ResponsesCodecCapabilities, maxTokens: unknown, diagnostics: ResponsesConversionDiagnostic[]): void;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { type JsonRecord, type ResponsesCodecCapabilities, type ResponsesProtocol, type ResponsesToolNames } from './common';
|
|
1
|
+
import { type JsonRecord, type ResponsesCodecCapabilities, type ResponsesConversionDiagnostic, type ResponsesProtocol, type ResponsesToolNames } from './common';
|
|
2
2
|
export interface DecodedResponsesRequest {
|
|
3
3
|
body: JsonRecord;
|
|
4
4
|
toolNames: ResponsesToolNames;
|
|
5
|
+
canonicalInput: JsonRecord[];
|
|
6
|
+
diagnostics: ResponsesConversionDiagnostic[];
|
|
5
7
|
}
|
|
6
8
|
/** Converts only self-contained history. Reference resolution belongs to the caller. */
|
|
7
9
|
export declare function decodeResponsesRequest(raw: unknown, protocol: ResponsesProtocol, capabilities?: ResponsesCodecCapabilities): DecodedResponsesRequest;
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jeffusion/bungee-llms",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.22.0",
|
|
4
4
|
"description": "Extensible LLM adapters and protocol conversion package for Bungee",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"dev": "bun --watch src/index.ts",
|
|
9
9
|
"build": "bun build src/index.ts src/plugin-api.ts --outdir dist --target bun && tsc -p tsconfig.build.json",
|
|
10
|
-
"test": "
|
|
10
|
+
"test": "bun test tests/",
|
|
11
11
|
"prepublishOnly": "bun run build"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@jeffusion/bungee-types": "^5.
|
|
14
|
+
"@jeffusion/bungee-types": "^5.22.0"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"bun-types": "^1.3.2",
|
|
@@ -1,62 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
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 readonly protocolConversion;
|
|
19
|
-
private configuredApiMode?;
|
|
20
|
-
setApiMode(mode: unknown): void;
|
|
21
|
-
setRuntimeOptions(options: unknown): void;
|
|
22
|
-
private resolveTargetApiMode;
|
|
23
|
-
/**
|
|
24
|
-
* 修改请求:转换为 OpenAI Chat Completions 格式
|
|
25
|
-
*/
|
|
26
|
-
onBeforeRequest(ctx: MutableRequestContext): Promise<void>;
|
|
27
|
-
private isAnthropicCountTokensPath;
|
|
28
|
-
private buildOpenAICountTokensRequest;
|
|
29
|
-
/**
|
|
30
|
-
* 构建 OpenAI 请求
|
|
31
|
-
*/
|
|
32
|
-
private buildOpenAIRequest;
|
|
33
|
-
private isOpenAINumericOSeriesModel;
|
|
34
|
-
private buildOpenAIResponsesRequest;
|
|
35
|
-
private convertAnthropicSystemToInstructions;
|
|
36
|
-
private convertAnthropicMessagesToResponsesInput;
|
|
37
|
-
private convertAnthropicImageSourceToUrl;
|
|
38
|
-
private mapAnthropicToolChoiceToResponses;
|
|
39
|
-
private resolveAnthropicReasoningEffort;
|
|
40
|
-
private supportsReasoningEffort;
|
|
41
|
-
private convertSystemMessages;
|
|
42
|
-
private sanitizeSystemText;
|
|
43
|
-
private extractTextFromOpenAIContent;
|
|
44
|
-
private normalizeOpenAISystemMessages;
|
|
45
|
-
/**
|
|
46
|
-
* 转换 User 消息
|
|
47
|
-
*/
|
|
48
|
-
private normalizeToolResultContent;
|
|
49
|
-
private convertUserMessage;
|
|
50
|
-
private convertUserContentBlock;
|
|
51
|
-
/**
|
|
52
|
-
* 转换 Assistant 消息
|
|
53
|
-
*/
|
|
54
|
-
private convertAssistantMessage;
|
|
55
|
-
private normalizeOpenAIMessageContent;
|
|
56
|
-
private normalizeToolParametersSchema;
|
|
57
|
-
private cleanOpenAIToolSchema;
|
|
58
|
-
private resolvePromptCacheKey;
|
|
59
|
-
private normalizeJsonSchema;
|
|
60
|
-
/**
|
|
61
|
-
* 处理非流式响应:OpenAI → Anthropic
|
|
62
|
-
*/
|
|
63
|
-
onResponse(ctx: ResponseContext): Promise<Response | void>;
|
|
64
|
-
private extractCountTokensInput;
|
|
65
|
-
private convertOpenAIErrorToAnthropic;
|
|
66
|
-
private isJsonLikeContentType;
|
|
67
|
-
private isLikelyOpenAIErrorBody;
|
|
68
|
-
private isLikelyOpenAICountTokensBody;
|
|
69
|
-
private isLikelyOpenAISuccessBody;
|
|
70
|
-
private isResponsesApiBody;
|
|
71
|
-
private extractReasoningSummaryTexts;
|
|
72
|
-
private extractStrictResponsesReasoningText;
|
|
73
|
-
private extractReasoningTextFromDeltaContentPart;
|
|
74
|
-
private extractChatThinkingDelta;
|
|
75
|
-
private getChatUsedIndices;
|
|
76
|
-
private allocateChatContentBlockIndex;
|
|
77
|
-
private ensureChatTextBlockStarted;
|
|
78
|
-
private ensureChatThinkingBlockStarted;
|
|
79
|
-
private closeChatNonToolBlock;
|
|
80
|
-
private resolveChatToolIndex;
|
|
81
|
-
private resolveResponsesReasoningIndex;
|
|
82
|
-
private nextResponsesContentIndex;
|
|
83
|
-
private resolveResponsesContentIndex;
|
|
84
|
-
private ensureResponsesTextBlockStarted;
|
|
85
|
-
private resolveResponsesToolIndex;
|
|
86
|
-
private ensureResponsesThinkingBlockStarted;
|
|
87
|
-
private emitResponsesThinkingDelta;
|
|
88
|
-
private extractResponsesReasoningDeltaText;
|
|
89
|
-
private convertOpenAIResponsesToAnthropic;
|
|
90
|
-
private mapResponsesStopReason;
|
|
91
|
-
private buildAnthropicUsageFromResponses;
|
|
92
|
-
/**
|
|
93
|
-
* 转换 OpenAI 响应为 Anthropic 格式
|
|
94
|
-
*/
|
|
95
|
-
private convertOpenAIResponseToAnthropic;
|
|
96
|
-
private parseToolArguments;
|
|
97
|
-
/**
|
|
98
|
-
* 处理流式响应:OpenAI chunk → Anthropic SSE
|
|
99
|
-
*/
|
|
100
|
-
processStreamChunk(chunk: any, ctx: StreamChunkContext): Promise<any[] | null>;
|
|
101
|
-
/**
|
|
102
|
-
* 刷新流 - 确保流结束
|
|
103
|
-
*/
|
|
104
|
-
flushStream(ctx: StreamChunkContext): Promise<any[]>;
|
|
105
|
-
private isResponsesStreamChunk;
|
|
106
|
-
private processResponsesStreamChunk;
|
|
107
|
-
private finalizeResponsesStreamEvents;
|
|
108
|
-
private extractOpenAIStreamUsage;
|
|
109
|
-
private extractDeltaText;
|
|
110
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
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
|
-
/** Shared immutable JSON view owned by the gateway. */
|
|
10
|
-
bodyHandle: {
|
|
11
|
-
json(): Promise<unknown>;
|
|
12
|
-
};
|
|
13
|
-
[key: string]: any;
|
|
14
|
-
}
|
|
15
|
-
export interface StreamChunkContext {
|
|
16
|
-
/** SSE metadata belongs to the transport envelope, not the JSON object. */
|
|
17
|
-
sseEvent?: {
|
|
18
|
-
event?: string;
|
|
19
|
-
id?: string;
|
|
20
|
-
retry?: string;
|
|
21
|
-
comments?: string[];
|
|
22
|
-
};
|
|
23
|
-
streamState: Map<string, any>;
|
|
24
|
-
chunkIndex?: number;
|
|
25
|
-
isFirstChunk?: boolean;
|
|
26
|
-
isLastChunk?: boolean;
|
|
27
|
-
[key: string]: any;
|
|
28
|
-
}
|
|
29
|
-
export interface AIConverter {
|
|
30
|
-
readonly from: string;
|
|
31
|
-
readonly to: string;
|
|
32
|
-
setRuntimeOptions?(options: unknown): void;
|
|
33
|
-
onBeforeRequest?(ctx: MutableRequestContext): Promise<void>;
|
|
34
|
-
onResponse?(ctx: ResponseContext): Promise<Response | void>;
|
|
35
|
-
processStreamChunk?(chunk: any, ctx: StreamChunkContext): Promise<any[] | null>;
|
|
36
|
-
flushStream?(ctx: StreamChunkContext): Promise<any[]>;
|
|
37
|
-
}
|
|
38
|
-
export type TransformDirection = `${string}-${string}`;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function registerDefaultProtocolConverters(): void;
|
|
@@ -1,57 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
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';
|
|
@@ -1,27 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
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
|
-
}
|