@zimtsui/brainswitch 0.0.1
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/LICENSE +165 -0
- package/README.md +164 -0
- package/build/adaptor.d.ts +12 -0
- package/build/adaptor.js +62 -0
- package/build/adaptor.js.map +1 -0
- package/build/agentloop.d.ts +12 -0
- package/build/agentloop.js +47 -0
- package/build/agentloop.js.map +1 -0
- package/build/api-types/base.d.ts +21 -0
- package/build/api-types/base.js +37 -0
- package/build/api-types/base.js.map +1 -0
- package/build/api-types/google-base.d.ts +22 -0
- package/build/api-types/google-base.js +142 -0
- package/build/api-types/google-base.js.map +1 -0
- package/build/api-types/google-rest.d.ts +20 -0
- package/build/api-types/google-rest.js +113 -0
- package/build/api-types/google-rest.js.map +1 -0
- package/build/api-types/huggingface-cerebras-qwen3-thinking.d.ts +13 -0
- package/build/api-types/huggingface-cerebras-qwen3-thinking.js +52 -0
- package/build/api-types/huggingface-cerebras-qwen3-thinking.js.map +1 -0
- package/build/api-types/openai-chatcompletions-base.d.ts +28 -0
- package/build/api-types/openai-chatcompletions-base.js +150 -0
- package/build/api-types/openai-chatcompletions-base.js.map +1 -0
- package/build/api-types/openai-chatcompletions-monolith-base.d.ts +10 -0
- package/build/api-types/openai-chatcompletions-monolith-base.js +85 -0
- package/build/api-types/openai-chatcompletions-monolith-base.js.map +1 -0
- package/build/api-types/openai-chatcompletions-stream-base.d.ts +11 -0
- package/build/api-types/openai-chatcompletions-stream-base.js +110 -0
- package/build/api-types/openai-chatcompletions-stream-base.js.map +1 -0
- package/build/api-types/openai-chatcompletions.d.ts +6 -0
- package/build/api-types/openai-chatcompletions.js +10 -0
- package/build/api-types/openai-chatcompletions.js.map +1 -0
- package/build/api-types/openai-responses.d.ts +30 -0
- package/build/api-types/openai-responses.js +216 -0
- package/build/api-types/openai-responses.js.map +1 -0
- package/build/api-types/openrouter-monolith.d.ts +21 -0
- package/build/api-types/openrouter-monolith.js +57 -0
- package/build/api-types/openrouter-monolith.js.map +1 -0
- package/build/api-types/openrouter-stream.d.ts +27 -0
- package/build/api-types/openrouter-stream.js +68 -0
- package/build/api-types/openrouter-stream.js.map +1 -0
- package/build/api-types/qwen.d.ts +11 -0
- package/build/api-types/qwen.js +13 -0
- package/build/api-types/qwen.js.map +1 -0
- package/build/config.d.ts +23 -0
- package/build/config.js +12 -0
- package/build/config.js.map +1 -0
- package/build/endpoint-spec.d.ts +19 -0
- package/build/endpoint-spec.js +28 -0
- package/build/endpoint-spec.js.map +1 -0
- package/build/engine.d.ts +23 -0
- package/build/engine.js +18 -0
- package/build/engine.js.map +1 -0
- package/build/exports.d.ts +9 -0
- package/build/exports.js +10 -0
- package/build/exports.js.map +1 -0
- package/build/function.d.ts +68 -0
- package/build/function.js +41 -0
- package/build/function.js.map +1 -0
- package/build/inference-context.d.ts +15 -0
- package/build/inference-context.js +4 -0
- package/build/inference-context.js.map +1 -0
- package/build/session.d.ts +55 -0
- package/build/session.js +78 -0
- package/build/session.js.map +1 -0
- package/build/test.d.ts +1 -0
- package/build/test.js +23 -0
- package/build/test.js.map +1 -0
- package/build/throttle.d.ts +14 -0
- package/build/throttle.js +50 -0
- package/build/throttle.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/package.json +38 -0
- package/typedoc.json +8 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { RoleMessage } from "../session.js";
|
|
2
|
+
import { Function } from "../function.js";
|
|
3
|
+
import OpenAI from 'openai';
|
|
4
|
+
import assert from 'node:assert';
|
|
5
|
+
import { TransientError, RetryLimitError } from "./base.js";
|
|
6
|
+
import { InvalidFinishReason } from "./openai-chatcompletions-base.js";
|
|
7
|
+
import { OpenAIChatCompletionsAPIBase } from "./openai-chatcompletions-base.js";
|
|
8
|
+
import {} from "../inference-context.js";
|
|
9
|
+
export class OpenAIChatCompletionsMonolithAPIBase extends OpenAIChatCompletionsAPIBase {
|
|
10
|
+
convertToAIMessage(message) {
|
|
11
|
+
const parts = [];
|
|
12
|
+
if (message.content)
|
|
13
|
+
parts.push(new RoleMessage.Text(this.extractContent(message.content)));
|
|
14
|
+
if (message.tool_calls)
|
|
15
|
+
parts.push(...message.tool_calls.map(apifc => {
|
|
16
|
+
assert(apifc.type === 'function');
|
|
17
|
+
return this.convertToFunctionCall(apifc);
|
|
18
|
+
}));
|
|
19
|
+
return new RoleMessage.AI(parts);
|
|
20
|
+
}
|
|
21
|
+
makeMonolithParams(session) {
|
|
22
|
+
return {
|
|
23
|
+
model: this.model,
|
|
24
|
+
messages: [
|
|
25
|
+
...(session.developerMessage ? this.convertFromRoleMessage(session.developerMessage) : []),
|
|
26
|
+
...session.chatMessages.flatMap(chatMessage => this.convertFromRoleMessage(chatMessage)),
|
|
27
|
+
],
|
|
28
|
+
tools: Object.keys(this.functionDeclarationMap).length
|
|
29
|
+
? Object.entries(this.functionDeclarationMap).map(fdentry => this.convertFromFunctionDeclarationEntry(fdentry))
|
|
30
|
+
: undefined,
|
|
31
|
+
tool_choice: Object.keys(this.functionDeclarationMap).length && this.toolChoice ? this.convertFromFunctionCallMode(this.toolChoice) : undefined,
|
|
32
|
+
parallel_tool_calls: Object.keys(this.functionDeclarationMap).length ? false : undefined,
|
|
33
|
+
...this.customOptions,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async monolith(ctx, session, retry = 0) {
|
|
37
|
+
if (retry > 2)
|
|
38
|
+
throw new RetryLimitError();
|
|
39
|
+
const signalTimeout = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
|
|
40
|
+
const signal = ctx.signal && signalTimeout ? AbortSignal.any([
|
|
41
|
+
ctx.signal,
|
|
42
|
+
signalTimeout,
|
|
43
|
+
]) : ctx.signal || signalTimeout;
|
|
44
|
+
const params = this.makeMonolithParams(session);
|
|
45
|
+
ctx.logger.message?.trace(params);
|
|
46
|
+
await this.throttle.requests(ctx);
|
|
47
|
+
await this.throttle.inputTokens(this.tokenize(params), ctx);
|
|
48
|
+
try {
|
|
49
|
+
const completion = await this.client.chat.completions.create(params, { signal });
|
|
50
|
+
ctx.logger.message?.trace(completion);
|
|
51
|
+
assert(completion.choices[0], new TransientError('No choices', { cause: completion }));
|
|
52
|
+
assert(completion.choices[0].finish_reason && ['stop', 'tool_calls'].includes(completion.choices[0].finish_reason), new InvalidFinishReason(completion.choices[0].finish_reason));
|
|
53
|
+
assert(completion.usage);
|
|
54
|
+
this.throttle.outputTokens(completion.usage.completion_tokens);
|
|
55
|
+
const cost = this.calcCost(completion.usage);
|
|
56
|
+
ctx.logger.cost?.(cost);
|
|
57
|
+
const aiMessage = this.convertToAIMessage(completion.choices[0].message);
|
|
58
|
+
const text = aiMessage.getText();
|
|
59
|
+
if (text)
|
|
60
|
+
ctx.logger.inference?.debug(text + '\n');
|
|
61
|
+
const apifcs = completion.choices[0].message.tool_calls || [];
|
|
62
|
+
if (apifcs.length)
|
|
63
|
+
ctx.logger.message?.debug(apifcs);
|
|
64
|
+
ctx.logger.message?.debug(completion.usage);
|
|
65
|
+
this.validateFunctionCallByToolChoice(aiMessage.getFunctionCalls());
|
|
66
|
+
return aiMessage;
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
if (ctx.signal?.aborted)
|
|
70
|
+
throw new DOMException(undefined, 'AbortError');
|
|
71
|
+
if (e instanceof TransientError) { } // 模型抽风
|
|
72
|
+
else if (e instanceof InvalidFinishReason) { } // 服务器中道崩殂
|
|
73
|
+
else if (e instanceof OpenAI.APIUserAbortError) { } // 推理超时
|
|
74
|
+
else if (e instanceof OpenAI.BadRequestError) {
|
|
75
|
+
ctx.logger.message?.warn(params);
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
throw e;
|
|
79
|
+
ctx.logger.message?.warn(e);
|
|
80
|
+
return await this.monolith(ctx, session, retry + 1)
|
|
81
|
+
.catch(nexte => Promise.reject(nexte instanceof RetryLimitError ? e : nexte));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=openai-chatcompletions-monolith-base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-chatcompletions-monolith-base.js","sourceRoot":"","sources":["../../src/api-types/openai-chatcompletions-monolith-base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RoleMessage, type Session } from '../session.ts';
|
|
2
|
+
import { Function } from '../function.ts';
|
|
3
|
+
import OpenAI from 'openai';
|
|
4
|
+
import { OpenAIChatCompletionsAPIBase } from './openai-chatcompletions-base.ts';
|
|
5
|
+
import { type InferenceContext } from '../inference-context.ts';
|
|
6
|
+
export declare abstract class OpenAIChatCompletionsStreamAPIBase<in out fdm extends Function.Declaration.Map = {}> extends OpenAIChatCompletionsAPIBase<fdm> {
|
|
7
|
+
protected makeStreamParams(session: Session<Function.Declaration.From<fdm>>): OpenAI.ChatCompletionCreateParamsStreaming;
|
|
8
|
+
protected convertToFunctionCallFromDelta(apifc: OpenAI.ChatCompletionChunk.Choice.Delta.ToolCall): Function.Call.Distributive<Function.Declaration.From<fdm>>;
|
|
9
|
+
protected abstract getDeltaThoughts(delta: OpenAI.ChatCompletionChunk.Choice.Delta): string;
|
|
10
|
+
protected stream(ctx: InferenceContext, session: Session<Function.Declaration.From<fdm>>, retry?: number): Promise<RoleMessage.AI<Function.Declaration.From<fdm>>>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { RoleMessage } from "../session.js";
|
|
2
|
+
import { Function } from "../function.js";
|
|
3
|
+
import OpenAI from 'openai';
|
|
4
|
+
import assert from 'node:assert';
|
|
5
|
+
import { OpenAIChatCompletionsAPIBase, InvalidFinishReason } from "./openai-chatcompletions-base.js";
|
|
6
|
+
import {} from "../inference-context.js";
|
|
7
|
+
import { RetryLimitError, TransientError } from "./base.js";
|
|
8
|
+
export class OpenAIChatCompletionsStreamAPIBase extends OpenAIChatCompletionsAPIBase {
|
|
9
|
+
makeStreamParams(session) {
|
|
10
|
+
return {
|
|
11
|
+
model: this.model,
|
|
12
|
+
messages: [
|
|
13
|
+
...(session.developerMessage ? this.convertFromRoleMessage(session.developerMessage) : []),
|
|
14
|
+
...session.chatMessages.flatMap(chatMessage => this.convertFromRoleMessage(chatMessage)),
|
|
15
|
+
],
|
|
16
|
+
tools: Object.keys(this.functionDeclarationMap).length
|
|
17
|
+
? Object.entries(this.functionDeclarationMap).map(fdentry => this.convertFromFunctionDeclarationEntry(fdentry)) : undefined,
|
|
18
|
+
tool_choice: Object.keys(this.functionDeclarationMap).length && this.toolChoice ? this.convertFromFunctionCallMode(this.toolChoice) : undefined,
|
|
19
|
+
stream: true,
|
|
20
|
+
stream_options: {
|
|
21
|
+
include_usage: true
|
|
22
|
+
},
|
|
23
|
+
...this.customOptions,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
convertToFunctionCallFromDelta(apifc) {
|
|
27
|
+
assert(apifc.id);
|
|
28
|
+
assert(apifc.function?.name);
|
|
29
|
+
assert(apifc.function?.arguments);
|
|
30
|
+
return this.convertToFunctionCall(apifc);
|
|
31
|
+
}
|
|
32
|
+
async stream(ctx, session, retry = 0) {
|
|
33
|
+
if (retry > 2)
|
|
34
|
+
throw new RetryLimitError();
|
|
35
|
+
const signalTimeout = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
|
|
36
|
+
const signal = ctx.signal && signalTimeout ? AbortSignal.any([
|
|
37
|
+
ctx.signal,
|
|
38
|
+
signalTimeout,
|
|
39
|
+
]) : ctx.signal || signalTimeout;
|
|
40
|
+
const params = this.makeStreamParams(session);
|
|
41
|
+
ctx.logger.message?.trace(params);
|
|
42
|
+
await this.throttle.requests(ctx);
|
|
43
|
+
await this.throttle.inputTokens(this.tokenize(params), ctx);
|
|
44
|
+
try {
|
|
45
|
+
const stream = await this.client.chat.completions.create(params, { signal });
|
|
46
|
+
let chunk = null;
|
|
47
|
+
let usage = { completion_tokens: 0, prompt_tokens: 0, total_tokens: 0 };
|
|
48
|
+
let finishReason = null;
|
|
49
|
+
const toolCalls = [];
|
|
50
|
+
let thoughts = '', text = '', cost = 0, thinking = true;
|
|
51
|
+
ctx.logger.inference?.trace('<think>\n');
|
|
52
|
+
for await (chunk of stream) {
|
|
53
|
+
const deltaThoughts = chunk.choices[0] ? this.getDeltaThoughts(chunk.choices[0].delta) : '';
|
|
54
|
+
thoughts += deltaThoughts;
|
|
55
|
+
const deltaText = chunk.choices[0]?.delta.content ?? '';
|
|
56
|
+
text += deltaText;
|
|
57
|
+
const deltaToolCalls = chunk.choices[0]?.delta.tool_calls ?? [];
|
|
58
|
+
for (const deltaToolCall of deltaToolCalls) {
|
|
59
|
+
toolCalls[deltaToolCall.index] ||= { index: deltaToolCall.index };
|
|
60
|
+
toolCalls[deltaToolCall.index].id ||= deltaToolCall.id;
|
|
61
|
+
toolCalls[deltaToolCall.index].function ||= {};
|
|
62
|
+
toolCalls[deltaToolCall.index].function.name ||= deltaToolCall.function?.name;
|
|
63
|
+
toolCalls[deltaToolCall.index].function.arguments ||= '';
|
|
64
|
+
toolCalls[deltaToolCall.index].function.arguments += deltaToolCall.function?.arguments || '';
|
|
65
|
+
}
|
|
66
|
+
if (chunk.usage)
|
|
67
|
+
cost = this.calcCost(chunk.usage);
|
|
68
|
+
const newUsage = chunk.usage || usage;
|
|
69
|
+
this.throttle.outputTokens(newUsage.completion_tokens - usage.completion_tokens);
|
|
70
|
+
finishReason = chunk.choices[0]?.finish_reason ?? finishReason;
|
|
71
|
+
ctx.logger.inference?.trace(deltaThoughts);
|
|
72
|
+
if (thinking && (deltaText || deltaToolCalls.length)) {
|
|
73
|
+
thinking = false;
|
|
74
|
+
ctx.logger.inference?.trace('\n</think>\n');
|
|
75
|
+
}
|
|
76
|
+
ctx.logger.inference?.debug(deltaText);
|
|
77
|
+
usage = newUsage;
|
|
78
|
+
}
|
|
79
|
+
assert(finishReason && ['stop', 'tool_calls'].includes(finishReason), new InvalidFinishReason(finishReason));
|
|
80
|
+
ctx.logger.inference?.debug('\n');
|
|
81
|
+
assert(usage);
|
|
82
|
+
if (toolCalls.length)
|
|
83
|
+
ctx.logger.message?.debug(toolCalls);
|
|
84
|
+
ctx.logger.message?.debug(usage);
|
|
85
|
+
ctx.logger.cost?.(cost);
|
|
86
|
+
const fcs = toolCalls.map(apifc => this.convertToFunctionCallFromDelta(apifc));
|
|
87
|
+
this.validateFunctionCallByToolChoice(fcs);
|
|
88
|
+
return new RoleMessage.AI([
|
|
89
|
+
new RoleMessage.Text(this.extractContent(text)),
|
|
90
|
+
...fcs,
|
|
91
|
+
]);
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
if (ctx.signal?.aborted)
|
|
95
|
+
throw new DOMException(undefined, 'AbortError');
|
|
96
|
+
if (e instanceof TransientError) { } // 模型抽风
|
|
97
|
+
else if (e instanceof InvalidFinishReason) { } // 服务器中道崩殂
|
|
98
|
+
else if (e instanceof OpenAI.APIUserAbortError) { } // 推理超时
|
|
99
|
+
else if (e instanceof OpenAI.BadRequestError) {
|
|
100
|
+
ctx.logger.message?.warn(params);
|
|
101
|
+
}
|
|
102
|
+
else
|
|
103
|
+
throw e;
|
|
104
|
+
ctx.logger.message?.warn(e);
|
|
105
|
+
return this.stream(ctx, session, retry + 1)
|
|
106
|
+
.catch(nexte => Promise.reject(nexte instanceof RetryLimitError ? e : nexte));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=openai-chatcompletions-stream-base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-chatcompletions-stream-base.js","sourceRoot":"","sources":["../../src/api-types/openai-chatcompletions-stream-base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Engine } from '../engine.ts';
|
|
2
|
+
import { Function } from '../function.ts';
|
|
3
|
+
import { OpenAIChatCompletionsMonolithAPIBase } from './openai-chatcompletions-monolith-base.ts';
|
|
4
|
+
export declare class OpenAIChatCompletionsAPI<in out fdm extends Function.Declaration.Map = {}> extends OpenAIChatCompletionsMonolithAPIBase<fdm> {
|
|
5
|
+
static create<fdm extends Function.Declaration.Map = {}>(options: Engine.Options<fdm>): Engine<Function.Declaration.From<fdm>>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Engine } from "../engine.js";
|
|
2
|
+
import { Function } from "../function.js";
|
|
3
|
+
import { OpenAIChatCompletionsMonolithAPIBase } from "./openai-chatcompletions-monolith-base.js";
|
|
4
|
+
export class OpenAIChatCompletionsAPI extends OpenAIChatCompletionsMonolithAPIBase {
|
|
5
|
+
static create(options) {
|
|
6
|
+
const api = new OpenAIChatCompletionsAPI(options);
|
|
7
|
+
return api.monolith.bind(api);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=openai-chatcompletions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-chatcompletions.js","sourceRoot":"","sources":["../../src/api-types/openai-chatcompletions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,oCAAoC,EAAE,MAAM,2CAA2C,CAAC;AAGjG,MAAM,OAAO,wBAA2E,SAAQ,oCAAyC;IACjI,MAAM,CAAC,MAAM,CAA4C,OAA4B;QAC3F,MAAM,GAAG,GAAG,IAAI,wBAAwB,CAAM,OAAO,CAAC,CAAC;QACvD,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;CACD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { APIBase } from './base.ts';
|
|
2
|
+
import { Function } from '../function.ts';
|
|
3
|
+
import { RoleMessage, type ChatMessage, type Session } from '../session.ts';
|
|
4
|
+
import { Engine } from '../engine.ts';
|
|
5
|
+
import { type InferenceContext } from '../inference-context.ts';
|
|
6
|
+
import OpenAI from 'openai';
|
|
7
|
+
import { ProxyAgent } from 'undici';
|
|
8
|
+
export declare class OpenAIResponsesAPI<in out fdm extends Function.Declaration.Map = {}> extends APIBase<fdm> {
|
|
9
|
+
protected client: OpenAI;
|
|
10
|
+
protected proxyAgent?: ProxyAgent;
|
|
11
|
+
static create<fdm extends Function.Declaration.Map = {}>(options: Engine.Options<fdm>): Engine<Function.Declaration.From<fdm>>;
|
|
12
|
+
constructor(options: Engine.Options<fdm>);
|
|
13
|
+
protected convertFromFunctionCall(fc: Function.Call.Distributive<Function.Declaration.From<fdm>>): OpenAI.Responses.ResponseFunctionToolCall;
|
|
14
|
+
protected convertToFunctionCall(apifc: OpenAI.Responses.ResponseFunctionToolCall): Function.Call.Distributive<Function.Declaration.From<fdm>>;
|
|
15
|
+
protected convertFromFunctionResponse(fr: Function.Response.Distributive<Function.Declaration.From<fdm>>): OpenAI.Responses.ResponseInputItem.FunctionCallOutput;
|
|
16
|
+
protected convertFromUserMessage(userMessage: RoleMessage.User<Function.Declaration.From<fdm>>): OpenAI.Responses.ResponseInput;
|
|
17
|
+
protected convertFromAIMessage(aiMessage: RoleMessage.AI<Function.Declaration.From<fdm>>): OpenAI.Responses.ResponseInput;
|
|
18
|
+
protected convertFromChatMessage(chatMessage: ChatMessage<Function.Declaration.From<fdm>>): OpenAI.Responses.ResponseInput;
|
|
19
|
+
protected convertFromFunctionDeclarationEntry(fdentry: Function.Declaration.Entry.From<fdm>): OpenAI.Responses.FunctionTool;
|
|
20
|
+
protected makeMonolithParams(session: Session<Function.Declaration.From<fdm>>): OpenAI.Responses.ResponseCreateParamsNonStreaming;
|
|
21
|
+
protected convertToAIMessage(output: OpenAI.Responses.ResponseOutputItem[]): OpenAIResponsesAIMessage<Function.Declaration.From<fdm>>;
|
|
22
|
+
protected validateFunctionCallByToolChoice(functionCalls: Function.Call.Distributive<Function.Declaration.From<fdm>>[]): void;
|
|
23
|
+
protected calcCost(usage: OpenAI.Responses.ResponseUsage): number;
|
|
24
|
+
protected tokenize(params: OpenAI.Responses.ResponseCreateParams): number;
|
|
25
|
+
protected monolith(ctx: InferenceContext, session: Session<Function.Declaration.From<fdm>>, retry?: number): Promise<RoleMessage.AI<Function.Declaration.From<fdm>>>;
|
|
26
|
+
}
|
|
27
|
+
export declare class OpenAIResponsesAIMessage<out fd extends Function.Declaration> extends RoleMessage.AI<fd> {
|
|
28
|
+
raw: OpenAI.Responses.ResponseOutputItem[];
|
|
29
|
+
constructor(parts: RoleMessage.AI.Part<fd>[], raw: OpenAI.Responses.ResponseOutputItem[]);
|
|
30
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { APIBase } from "./base.js";
|
|
2
|
+
import { Function } from "../function.js";
|
|
3
|
+
import { RoleMessage } from "../session.js";
|
|
4
|
+
import { Engine } from "../engine.js";
|
|
5
|
+
import {} from "../inference-context.js";
|
|
6
|
+
import OpenAI from 'openai';
|
|
7
|
+
import assert from 'node:assert';
|
|
8
|
+
import { TransientError, RetryLimitError } from "./base.js";
|
|
9
|
+
import { ProxyAgent } from 'undici';
|
|
10
|
+
import Ajv from 'ajv';
|
|
11
|
+
const ajv = new Ajv();
|
|
12
|
+
export class OpenAIResponsesAPI extends APIBase {
|
|
13
|
+
client;
|
|
14
|
+
proxyAgent;
|
|
15
|
+
static create(options) {
|
|
16
|
+
const api = new OpenAIResponsesAPI(options);
|
|
17
|
+
return api.monolith.bind(api);
|
|
18
|
+
}
|
|
19
|
+
constructor(options) {
|
|
20
|
+
super(options);
|
|
21
|
+
this.proxyAgent = options.proxy ? new ProxyAgent(options.proxy) : undefined;
|
|
22
|
+
this.client = new OpenAI({
|
|
23
|
+
baseURL: this.baseUrl,
|
|
24
|
+
apiKey: this.apiKey,
|
|
25
|
+
fetchOptions: {
|
|
26
|
+
dispatcher: this.proxyAgent,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
convertFromFunctionCall(fc) {
|
|
31
|
+
assert(fc.id);
|
|
32
|
+
return {
|
|
33
|
+
type: 'function_call',
|
|
34
|
+
call_id: fc.id,
|
|
35
|
+
name: fc.name,
|
|
36
|
+
arguments: JSON.stringify(fc.args),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
convertToFunctionCall(apifc) {
|
|
40
|
+
const fditem = this.functionDeclarationMap[apifc.name];
|
|
41
|
+
assert(fditem, new TransientError('Invalid function call', { cause: apifc }));
|
|
42
|
+
const args = (() => {
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(apifc.arguments);
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
return new TransientError('Invalid function call', { cause: apifc });
|
|
48
|
+
}
|
|
49
|
+
})();
|
|
50
|
+
assert(ajv.validate(fditem.paraschema, args), new TransientError('Invalid function call', { cause: apifc }));
|
|
51
|
+
return Function.Call.create({
|
|
52
|
+
id: apifc.call_id,
|
|
53
|
+
name: apifc.name,
|
|
54
|
+
args,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
convertFromFunctionResponse(fr) {
|
|
58
|
+
assert(fr.id);
|
|
59
|
+
return {
|
|
60
|
+
type: 'function_call_output',
|
|
61
|
+
call_id: fr.id,
|
|
62
|
+
output: fr.text,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
convertFromUserMessage(userMessage) {
|
|
66
|
+
return userMessage.parts.map(part => {
|
|
67
|
+
if (part instanceof RoleMessage.Text)
|
|
68
|
+
return {
|
|
69
|
+
type: 'message',
|
|
70
|
+
role: 'user',
|
|
71
|
+
content: part.text,
|
|
72
|
+
};
|
|
73
|
+
else if (part instanceof Function.Response)
|
|
74
|
+
return this.convertFromFunctionResponse(part);
|
|
75
|
+
else
|
|
76
|
+
throw new Error();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
convertFromAIMessage(aiMessage) {
|
|
80
|
+
if (aiMessage instanceof OpenAIResponsesAIMessage)
|
|
81
|
+
return aiMessage.raw;
|
|
82
|
+
else {
|
|
83
|
+
return aiMessage.parts.map(part => {
|
|
84
|
+
if (part instanceof RoleMessage.Text)
|
|
85
|
+
return {
|
|
86
|
+
role: 'assistant',
|
|
87
|
+
content: part.text,
|
|
88
|
+
};
|
|
89
|
+
else if (part instanceof Function.Call)
|
|
90
|
+
return this.convertFromFunctionCall(part);
|
|
91
|
+
else
|
|
92
|
+
throw new Error();
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
convertFromChatMessage(chatMessage) {
|
|
97
|
+
if (chatMessage instanceof RoleMessage.User)
|
|
98
|
+
return this.convertFromUserMessage(chatMessage);
|
|
99
|
+
else if (chatMessage instanceof RoleMessage.AI)
|
|
100
|
+
return this.convertFromAIMessage(chatMessage);
|
|
101
|
+
else
|
|
102
|
+
throw new Error();
|
|
103
|
+
}
|
|
104
|
+
convertFromFunctionDeclarationEntry(fdentry) {
|
|
105
|
+
return {
|
|
106
|
+
name: fdentry[0],
|
|
107
|
+
description: fdentry[1].description,
|
|
108
|
+
parameters: fdentry[1].paraschema,
|
|
109
|
+
strict: true,
|
|
110
|
+
type: 'function',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
makeMonolithParams(session) {
|
|
114
|
+
return {
|
|
115
|
+
model: this.model,
|
|
116
|
+
include: ['reasoning.encrypted_content'],
|
|
117
|
+
store: false,
|
|
118
|
+
input: session.chatMessages.flatMap(chatMessage => this.convertFromChatMessage(chatMessage)),
|
|
119
|
+
instructions: session.developerMessage?.getOnlyText(),
|
|
120
|
+
tools: Object.keys(this.functionDeclarationMap).length
|
|
121
|
+
? Object.entries(this.functionDeclarationMap).map(fdentry => this.convertFromFunctionDeclarationEntry(fdentry)) : undefined,
|
|
122
|
+
tool_choice: Object.keys(this.functionDeclarationMap).length ? 'required' : undefined,
|
|
123
|
+
parallel_tool_calls: Object.keys(this.functionDeclarationMap).length ? false : undefined,
|
|
124
|
+
...this.customOptions,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
convertToAIMessage(output) {
|
|
128
|
+
const parts = output.flatMap((item) => {
|
|
129
|
+
if (item.type === 'message') {
|
|
130
|
+
assert(item.content.every(part => part.type === 'output_text'));
|
|
131
|
+
return [new RoleMessage.Text(item.content.map(part => part.text).join(''))];
|
|
132
|
+
}
|
|
133
|
+
else if (item.type === 'function_call')
|
|
134
|
+
return [this.convertToFunctionCall(item)];
|
|
135
|
+
else if (item.type === 'reasoning')
|
|
136
|
+
return [];
|
|
137
|
+
else
|
|
138
|
+
throw new Error();
|
|
139
|
+
});
|
|
140
|
+
return new OpenAIResponsesAIMessage(parts, output);
|
|
141
|
+
}
|
|
142
|
+
validateFunctionCallByToolChoice(functionCalls) {
|
|
143
|
+
// https://community.openai.com/t/function-call-with-finish-reason-of-stop/437226/7
|
|
144
|
+
if (this.toolChoice === Function.ToolChoice.REQUIRED)
|
|
145
|
+
assert(functionCalls.length, new TransientError());
|
|
146
|
+
else if (this.toolChoice instanceof Array)
|
|
147
|
+
for (const fc of functionCalls)
|
|
148
|
+
assert(this.toolChoice.includes(fc.name), new TransientError());
|
|
149
|
+
else if (this.toolChoice === Function.ToolChoice.NONE)
|
|
150
|
+
assert(!functionCalls.length, new TransientError());
|
|
151
|
+
}
|
|
152
|
+
calcCost(usage) {
|
|
153
|
+
const cacheHitTokenCount = usage.input_tokens_details.cached_tokens;
|
|
154
|
+
const cacheMissTokenCount = usage.input_tokens - cacheHitTokenCount;
|
|
155
|
+
return this.inputPrice * cacheMissTokenCount / 1e6 +
|
|
156
|
+
this.cachedPrice * cacheHitTokenCount / 1e6 +
|
|
157
|
+
this.outputPrice * usage.output_tokens / 1e6;
|
|
158
|
+
}
|
|
159
|
+
tokenize(params) {
|
|
160
|
+
return JSON.stringify(params).length;
|
|
161
|
+
}
|
|
162
|
+
async monolith(ctx, session, retry = 0) {
|
|
163
|
+
if (retry > 2)
|
|
164
|
+
throw new RetryLimitError();
|
|
165
|
+
const signalTimeout = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
|
|
166
|
+
const signal = ctx.signal && signalTimeout ? AbortSignal.any([
|
|
167
|
+
ctx.signal,
|
|
168
|
+
signalTimeout,
|
|
169
|
+
]) : ctx.signal || signalTimeout;
|
|
170
|
+
const params = this.makeMonolithParams(session);
|
|
171
|
+
ctx.logger.message?.trace(params);
|
|
172
|
+
await this.throttle.requests(ctx);
|
|
173
|
+
await this.throttle.inputTokens(this.tokenize(params), ctx);
|
|
174
|
+
try {
|
|
175
|
+
const response = await this.client.responses.create(params, { signal });
|
|
176
|
+
ctx.logger.message?.trace(response);
|
|
177
|
+
const aiMessage = this.convertToAIMessage(response.output);
|
|
178
|
+
const text = aiMessage.getText();
|
|
179
|
+
if (text)
|
|
180
|
+
ctx.logger.inference?.debug(text + '\n');
|
|
181
|
+
const apifcs = response.output.filter(item => item.type === 'function_call');
|
|
182
|
+
for (const apifc of apifcs)
|
|
183
|
+
ctx.logger.message?.debug(apifc);
|
|
184
|
+
assert(response.usage);
|
|
185
|
+
const cost = this.calcCost(response.usage);
|
|
186
|
+
ctx.logger.cost?.(cost);
|
|
187
|
+
ctx.logger.message?.debug(response.usage);
|
|
188
|
+
this.throttle.outputTokens(response.usage.output_tokens);
|
|
189
|
+
const functionCalls = aiMessage.getFunctionCalls();
|
|
190
|
+
this.validateFunctionCallByToolChoice(functionCalls);
|
|
191
|
+
return aiMessage;
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
if (ctx.signal?.aborted)
|
|
195
|
+
throw new DOMException(undefined, 'AbortError');
|
|
196
|
+
if (e instanceof TransientError) { } // 模型抽风
|
|
197
|
+
else if (e instanceof OpenAI.APIUserAbortError) { } // 推理超时
|
|
198
|
+
else if (e instanceof OpenAI.BadRequestError) {
|
|
199
|
+
ctx.logger.message?.warn(params);
|
|
200
|
+
}
|
|
201
|
+
else
|
|
202
|
+
throw e;
|
|
203
|
+
ctx.logger.message?.warn(e);
|
|
204
|
+
return await this.monolith(ctx, session, retry + 1)
|
|
205
|
+
.catch(nexte => Promise.reject(nexte instanceof RetryLimitError ? e : nexte));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
export class OpenAIResponsesAIMessage extends RoleMessage.AI {
|
|
210
|
+
raw;
|
|
211
|
+
constructor(parts, raw) {
|
|
212
|
+
super(parts);
|
|
213
|
+
this.raw = raw;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=openai-responses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-responses.js","sourceRoot":"","sources":["../../src/api-types/openai-responses.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Engine } from '../engine.ts';
|
|
2
|
+
import { Function } from '../function.ts';
|
|
3
|
+
import OpenAI from 'openai';
|
|
4
|
+
import type { RoleMessage, Session } from '../session.ts';
|
|
5
|
+
import type { InferenceContext } from '../inference-context.ts';
|
|
6
|
+
import { OpenAIChatCompletionsMonolithAPIBase } from './openai-chatcompletions-monolith-base.ts';
|
|
7
|
+
export interface OpenRouterUsage extends OpenAI.CompletionUsage {
|
|
8
|
+
cost: number;
|
|
9
|
+
}
|
|
10
|
+
export interface OpenRouterMonolithParams extends OpenAI.ChatCompletionCreateParamsNonStreaming {
|
|
11
|
+
usage?: {
|
|
12
|
+
include: boolean;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export declare class OpenRouterMonolithAPI<in out fdm extends Function.Declaration.Map = {}> extends OpenAIChatCompletionsMonolithAPIBase<fdm> {
|
|
16
|
+
static create<fdm extends Function.Declaration.Map = {}>(options: Engine.Options<fdm>): Engine<Function.Declaration.From<fdm>>;
|
|
17
|
+
protected calcCost(usage: OpenAI.CompletionUsage): number;
|
|
18
|
+
protected makeMonolithParams(session: Session<Function.Declaration.From<fdm>>): OpenAI.ChatCompletionCreateParamsNonStreaming;
|
|
19
|
+
protected convertToFunctionCall(apifc: OpenAI.ChatCompletionMessageFunctionToolCall): Function.Call.Distributive<Function.Declaration.From<fdm>>;
|
|
20
|
+
monolith(ctx: InferenceContext, session: Session<Function.Declaration.From<fdm>>, retry?: number): Promise<RoleMessage.AI<Function.Declaration.From<fdm>>>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Engine } from "../engine.js";
|
|
2
|
+
import { Function } from "../function.js";
|
|
3
|
+
import OpenAI from 'openai';
|
|
4
|
+
import { OpenAIChatCompletionsMonolithAPIBase } from "./openai-chatcompletions-monolith-base.js";
|
|
5
|
+
const EXCHANGE_RATE_USD_CNY = 8;
|
|
6
|
+
export class OpenRouterMonolithAPI extends OpenAIChatCompletionsMonolithAPIBase {
|
|
7
|
+
static create(options) {
|
|
8
|
+
const api = new OpenRouterMonolithAPI(options);
|
|
9
|
+
return api.monolith.bind(api);
|
|
10
|
+
}
|
|
11
|
+
calcCost(usage) {
|
|
12
|
+
return usage.cost * EXCHANGE_RATE_USD_CNY;
|
|
13
|
+
}
|
|
14
|
+
makeMonolithParams(session) {
|
|
15
|
+
const params = {
|
|
16
|
+
model: this.model,
|
|
17
|
+
messages: [
|
|
18
|
+
...(session.developerMessage ? this.convertFromRoleMessage(session.developerMessage) : []),
|
|
19
|
+
...session.chatMessages.flatMap(chatMessage => this.convertFromRoleMessage(chatMessage)),
|
|
20
|
+
],
|
|
21
|
+
tools: Object.keys(this.functionDeclarationMap).length
|
|
22
|
+
? Object.entries(this.functionDeclarationMap).map(fdentry => this.convertFromFunctionDeclarationEntry(fdentry))
|
|
23
|
+
: undefined,
|
|
24
|
+
tool_choice: Object.keys(this.functionDeclarationMap).length && this.toolChoice ? this.convertFromFunctionCallMode(this.toolChoice) : undefined,
|
|
25
|
+
stream: false,
|
|
26
|
+
usage: {
|
|
27
|
+
include: true,
|
|
28
|
+
},
|
|
29
|
+
...this.customOptions,
|
|
30
|
+
};
|
|
31
|
+
return params;
|
|
32
|
+
}
|
|
33
|
+
convertToFunctionCall(apifc) {
|
|
34
|
+
if (apifc.function.arguments)
|
|
35
|
+
return super.convertToFunctionCall(apifc);
|
|
36
|
+
else
|
|
37
|
+
return super.convertToFunctionCall({
|
|
38
|
+
...apifc,
|
|
39
|
+
function: {
|
|
40
|
+
...apifc.function,
|
|
41
|
+
arguments: '{}',
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async monolith(ctx, session, retry = 0) {
|
|
46
|
+
try {
|
|
47
|
+
return await super.monolith(ctx, session, retry);
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
if (e instanceof TypeError && e.message === 'terminated')
|
|
51
|
+
return await this.monolith(ctx, session, retry + 1);
|
|
52
|
+
else
|
|
53
|
+
throw e;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=openrouter-monolith.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter-monolith.js","sourceRoot":"","sources":["../../src/api-types/openrouter-monolith.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,OAAO,EAAE,oCAAoC,EAAE,MAAM,2CAA2C,CAAC;AAEjG,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAWhC,MAAM,OAAO,qBAAwE,SAAQ,oCAAyC;IAC9H,MAAM,CAAC,MAAM,CAA4C,OAA4B;QAC3F,MAAM,GAAG,GAAG,IAAI,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC/C,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAEkB,QAAQ,CAAC,KAA6B;QACxD,OAAQ,KAAyB,CAAC,IAAI,GAAG,qBAAqB,CAAC;IAChE,CAAC;IAEkB,kBAAkB,CAAC,OAAgD;QACrF,MAAM,MAAM,GAA6B;YACxC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE;gBACT,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1F,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;aACxF;YACD,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,MAAM;gBACrD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAChD,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,mCAAmC,CAAC,OAA+C,CAAC,CACpG;gBACD,CAAC,CAAC,SAAS;YACZ,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;YAC/I,MAAM,EAAE,KAAK;YACb,KAAK,EAAE;gBACN,OAAO,EAAE,IAAI;aACb;YACD,GAAG,IAAI,CAAC,aAAa;SACrB,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IAEkB,qBAAqB,CAAC,KAAmD;QAC3F,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS;YAC3B,OAAO,KAAK,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;;YAE1C,OAAO,KAAK,CAAC,qBAAqB,CAAC;gBAClC,GAAG,KAAK;gBACR,QAAQ,EAAE;oBACT,GAAG,KAAK,CAAC,QAAQ;oBACjB,SAAS,EAAE,IAAI;iBACf;aACD,CAAC,CAAC;IACL,CAAC;IAEe,KAAK,CAAC,QAAQ,CAC7B,GAAqB,EAAE,OAAgD,EAAE,KAAK,GAAG,CAAC;QAElF,IAAI,CAAC;YACJ,OAAO,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,YAAY,SAAS,IAAI,CAAC,CAAC,OAAO,KAAK,YAAY;gBACvD,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,GAAC,CAAC,CAAC,CAAC;;gBAC9C,MAAM,CAAC,CAAC;QACd,CAAC;IACF,CAAC;CACD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Engine } from '../engine.ts';
|
|
2
|
+
import { Function } from '../function.ts';
|
|
3
|
+
import OpenAI from 'openai';
|
|
4
|
+
import type { RoleMessage, Session } from '../session.ts';
|
|
5
|
+
import type { InferenceContext } from '../inference-context.ts';
|
|
6
|
+
import { OpenAIChatCompletionsStreamAPIBase } from './openai-chatcompletions-stream-base.ts';
|
|
7
|
+
export interface OpenRouterUsage extends OpenAI.CompletionUsage {
|
|
8
|
+
cost: number;
|
|
9
|
+
}
|
|
10
|
+
export interface OpenRouterStreamParams extends OpenAI.ChatCompletionCreateParamsStreaming {
|
|
11
|
+
usage?: {
|
|
12
|
+
include: boolean;
|
|
13
|
+
};
|
|
14
|
+
reasoning?: {};
|
|
15
|
+
}
|
|
16
|
+
export interface OpenRouterChatCompletionChunkChoiceDelta extends OpenAI.ChatCompletionChunk.Choice.Delta {
|
|
17
|
+
reasoning?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class OpenRouterStreamAPI<in out fdm extends Function.Declaration.Map = {}> extends OpenAIChatCompletionsStreamAPIBase<fdm> {
|
|
20
|
+
static create<fdm extends Function.Declaration.Map = {}>(options: Engine.Options<fdm>): Engine<Function.Declaration.From<fdm>>;
|
|
21
|
+
protected calcCost(usage: OpenAI.CompletionUsage): number;
|
|
22
|
+
protected getDeltaThoughts(delta: OpenAI.ChatCompletionChunk.Choice.Delta): string;
|
|
23
|
+
protected makeStreamParams(session: Session<Function.Declaration.From<fdm>>): OpenAI.ChatCompletionCreateParamsStreaming;
|
|
24
|
+
protected convertToFunctionCallFromDelta(apifc: OpenAI.ChatCompletionChunk.Choice.Delta.ToolCall): Function.Call.Distributive<Function.Declaration.From<fdm>>;
|
|
25
|
+
protected convertToFunctionCall(apifc: OpenAI.ChatCompletionMessageFunctionToolCall): Function.Call.Distributive<Function.Declaration.From<fdm>>;
|
|
26
|
+
stream(ctx: InferenceContext, session: Session<Function.Declaration.From<fdm>>, retry?: number): Promise<RoleMessage.AI<Function.Declaration.From<fdm>>>;
|
|
27
|
+
}
|