@node-llm/core 1.1.0 → 1.3.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 +243 -0
- package/dist/chat/Chat.d.ts +11 -8
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +24 -14
- package/dist/chat/ChatOptions.d.ts +2 -2
- package/dist/chat/ChatOptions.d.ts.map +1 -1
- package/dist/chat/ChatStream.d.ts.map +1 -1
- package/dist/chat/ChatStream.js +85 -34
- package/dist/chat/Tool.d.ts +35 -1
- package/dist/chat/Tool.d.ts.map +1 -1
- package/dist/chat/Tool.js +38 -1
- package/dist/config.d.ts +1 -1
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.js +3 -3
- package/dist/llm.d.ts +27 -15
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +37 -5
- package/dist/models/models.js +15 -15
- package/dist/providers/BaseProvider.d.ts +2 -1
- package/dist/providers/BaseProvider.d.ts.map +1 -1
- package/dist/providers/BaseProvider.js +4 -1
- package/dist/providers/Provider.d.ts +4 -2
- package/dist/providers/Provider.d.ts.map +1 -1
- package/dist/providers/anthropic/AnthropicProvider.d.ts +1 -0
- package/dist/providers/anthropic/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/anthropic/AnthropicProvider.js +3 -0
- package/dist/providers/anthropic/Chat.d.ts.map +1 -1
- package/dist/providers/anthropic/Chat.js +5 -1
- package/dist/providers/anthropic/Streaming.d.ts.map +1 -1
- package/dist/providers/anthropic/Streaming.js +49 -2
- package/dist/providers/deepseek/Chat.d.ts.map +1 -1
- package/dist/providers/deepseek/Chat.js +5 -4
- package/dist/providers/deepseek/DeepSeekProvider.d.ts +1 -0
- package/dist/providers/deepseek/DeepSeekProvider.d.ts.map +1 -1
- package/dist/providers/deepseek/DeepSeekProvider.js +3 -0
- package/dist/providers/deepseek/Streaming.d.ts.map +1 -1
- package/dist/providers/deepseek/Streaming.js +49 -3
- package/dist/providers/gemini/Chat.d.ts.map +1 -1
- package/dist/providers/gemini/Chat.js +3 -0
- package/dist/providers/gemini/Embeddings.d.ts.map +1 -1
- package/dist/providers/gemini/Embeddings.js +3 -0
- package/dist/providers/gemini/GeminiProvider.d.ts +1 -0
- package/dist/providers/gemini/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/gemini/GeminiProvider.js +3 -0
- package/dist/providers/gemini/Image.d.ts.map +1 -1
- package/dist/providers/gemini/Image.js +3 -0
- package/dist/providers/gemini/Streaming.d.ts.map +1 -1
- package/dist/providers/gemini/Streaming.js +32 -1
- package/dist/providers/gemini/Transcription.d.ts.map +1 -1
- package/dist/providers/gemini/Transcription.js +3 -0
- package/dist/providers/ollama/OllamaProvider.d.ts +1 -0
- package/dist/providers/ollama/OllamaProvider.d.ts.map +1 -1
- package/dist/providers/ollama/OllamaProvider.js +3 -0
- package/dist/providers/openai/Chat.d.ts.map +1 -1
- package/dist/providers/openai/Chat.js +5 -4
- package/dist/providers/openai/Embedding.d.ts.map +1 -1
- package/dist/providers/openai/Embedding.js +5 -1
- package/dist/providers/openai/Image.d.ts.map +1 -1
- package/dist/providers/openai/Image.js +5 -1
- package/dist/providers/openai/Moderation.d.ts.map +1 -1
- package/dist/providers/openai/Moderation.js +12 -6
- package/dist/providers/openai/OpenAIProvider.d.ts +1 -0
- package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/openai/OpenAIProvider.js +3 -0
- package/dist/providers/openai/Streaming.d.ts.map +1 -1
- package/dist/providers/openai/Streaming.js +53 -4
- package/dist/providers/openai/Transcription.d.ts.map +1 -1
- package/dist/providers/openai/Transcription.js +9 -2
- package/dist/providers/registry.js +1 -1
- package/dist/utils/FileLoader.d.ts.map +1 -1
- package/dist/utils/FileLoader.js +2 -1
- package/dist/utils/logger.d.ts +9 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +23 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/deepseek/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/deepseek/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIxD,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEtE,OAAO,CACZ,OAAO,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,eAAe,GAC3B,cAAc,CAAC,SAAS,CAAC;CA+J7B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { APIError } from "../../errors/index.js";
|
|
2
|
+
import { logger } from "../../utils/logger.js";
|
|
2
3
|
export class DeepSeekStreaming {
|
|
3
4
|
baseUrl;
|
|
4
5
|
apiKey;
|
|
@@ -22,8 +23,12 @@ export class DeepSeekStreaming {
|
|
|
22
23
|
if (response_format)
|
|
23
24
|
body.response_format = response_format;
|
|
24
25
|
let done = false;
|
|
26
|
+
// Track tool calls being built across chunks
|
|
27
|
+
const toolCallsMap = new Map();
|
|
25
28
|
try {
|
|
26
|
-
const
|
|
29
|
+
const url = `${this.baseUrl}/chat/completions`;
|
|
30
|
+
logger.logRequest("DeepSeek", "POST", url, body);
|
|
31
|
+
const response = await fetch(url, {
|
|
27
32
|
method: "POST",
|
|
28
33
|
headers: {
|
|
29
34
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -37,6 +42,7 @@ export class DeepSeekStreaming {
|
|
|
37
42
|
const errorText = await response.text();
|
|
38
43
|
throw new Error(`DeepSeek API error: ${response.status} - ${errorText}`);
|
|
39
44
|
}
|
|
45
|
+
logger.debug("DeepSeek streaming started", { status: response.status, statusText: response.statusText });
|
|
40
46
|
if (!response.body) {
|
|
41
47
|
throw new Error("No response body for streaming");
|
|
42
48
|
}
|
|
@@ -62,6 +68,18 @@ export class DeepSeekStreaming {
|
|
|
62
68
|
const data = trimmed.replace("data: ", "").trim();
|
|
63
69
|
if (data === "[DONE]") {
|
|
64
70
|
done = true;
|
|
71
|
+
// Yield final tool calls if any were accumulated
|
|
72
|
+
if (toolCallsMap.size > 0) {
|
|
73
|
+
const toolCalls = Array.from(toolCallsMap.values()).map(tc => ({
|
|
74
|
+
id: tc.id,
|
|
75
|
+
type: "function",
|
|
76
|
+
function: {
|
|
77
|
+
name: tc.function.name,
|
|
78
|
+
arguments: tc.function.arguments
|
|
79
|
+
}
|
|
80
|
+
}));
|
|
81
|
+
yield { content: "", tool_calls: toolCalls, done: true };
|
|
82
|
+
}
|
|
65
83
|
return;
|
|
66
84
|
}
|
|
67
85
|
try {
|
|
@@ -70,14 +88,42 @@ export class DeepSeekStreaming {
|
|
|
70
88
|
if (json.error) {
|
|
71
89
|
throw new APIError("DeepSeek", response.status, json.error.message || "Stream error");
|
|
72
90
|
}
|
|
73
|
-
const
|
|
74
|
-
const
|
|
91
|
+
const delta = json.choices?.[0]?.delta;
|
|
92
|
+
const deltaContent = delta?.content;
|
|
93
|
+
const deltaReasoning = delta?.reasoning_content;
|
|
75
94
|
if (deltaContent || deltaReasoning) {
|
|
76
95
|
yield {
|
|
77
96
|
content: deltaContent || "",
|
|
78
97
|
reasoning: deltaReasoning || ""
|
|
79
98
|
};
|
|
80
99
|
}
|
|
100
|
+
// Handle tool calls delta
|
|
101
|
+
if (delta?.tool_calls) {
|
|
102
|
+
for (const toolCallDelta of delta.tool_calls) {
|
|
103
|
+
const index = toolCallDelta.index;
|
|
104
|
+
if (!toolCallsMap.has(index)) {
|
|
105
|
+
toolCallsMap.set(index, {
|
|
106
|
+
id: toolCallDelta.id || "",
|
|
107
|
+
type: "function",
|
|
108
|
+
function: {
|
|
109
|
+
name: toolCallDelta.function?.name || "",
|
|
110
|
+
arguments: toolCallDelta.function?.arguments || ""
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const existing = toolCallsMap.get(index);
|
|
116
|
+
if (toolCallDelta.id)
|
|
117
|
+
existing.id = toolCallDelta.id;
|
|
118
|
+
if (toolCallDelta.function?.name) {
|
|
119
|
+
existing.function.name += toolCallDelta.function.name;
|
|
120
|
+
}
|
|
121
|
+
if (toolCallDelta.function?.arguments) {
|
|
122
|
+
existing.function.arguments += toolCallDelta.function.arguments;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
81
127
|
}
|
|
82
128
|
catch (e) {
|
|
83
129
|
// Re-throw APIError
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAS,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAS,MAAM,gBAAgB,CAAC;AAQlE,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA4F1D,OAAO,CAAC,cAAc;CAwBvB"}
|
|
@@ -2,6 +2,7 @@ import { Capabilities } from "./Capabilities.js";
|
|
|
2
2
|
import { handleGeminiError } from "./Errors.js";
|
|
3
3
|
import { GeminiChatUtils } from "./ChatUtils.js";
|
|
4
4
|
import { ModelRegistry } from "../../models/ModelRegistry.js";
|
|
5
|
+
import { logger } from "../../utils/logger.js";
|
|
5
6
|
export class GeminiChat {
|
|
6
7
|
baseUrl;
|
|
7
8
|
apiKey;
|
|
@@ -49,6 +50,7 @@ export class GeminiChat {
|
|
|
49
50
|
},
|
|
50
51
|
];
|
|
51
52
|
}
|
|
53
|
+
logger.logRequest("Gemini", "POST", url, payload);
|
|
52
54
|
const response = await fetch(url, {
|
|
53
55
|
method: "POST",
|
|
54
56
|
headers: {
|
|
@@ -60,6 +62,7 @@ export class GeminiChat {
|
|
|
60
62
|
await handleGeminiError(response, request.model);
|
|
61
63
|
}
|
|
62
64
|
const json = (await response.json());
|
|
65
|
+
logger.logResponse("Gemini", response.status, response.statusText, json);
|
|
63
66
|
const candidate = json.candidates?.[0];
|
|
64
67
|
const content = candidate?.content?.parts
|
|
65
68
|
?.filter(p => p.text)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Embeddings.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Embeddings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Embeddings.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Embeddings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAKrE,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA2CrE"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { handleGeminiError } from "./Errors.js";
|
|
2
|
+
import { logger } from "../../utils/logger.js";
|
|
2
3
|
export class GeminiEmbeddings {
|
|
3
4
|
baseUrl;
|
|
4
5
|
apiKey;
|
|
@@ -24,6 +25,7 @@ export class GeminiEmbeddings {
|
|
|
24
25
|
return item;
|
|
25
26
|
})
|
|
26
27
|
};
|
|
28
|
+
logger.logRequest("Gemini", "POST", url, payload);
|
|
27
29
|
const response = await fetch(url, {
|
|
28
30
|
method: "POST",
|
|
29
31
|
headers: { "Content-Type": "application/json" },
|
|
@@ -33,6 +35,7 @@ export class GeminiEmbeddings {
|
|
|
33
35
|
await handleGeminiError(response, modelId);
|
|
34
36
|
}
|
|
35
37
|
const json = (await response.json());
|
|
38
|
+
logger.logResponse("Gemini", response.status, response.statusText, json);
|
|
36
39
|
const vectors = json.embeddings?.map(e => e.values) || [];
|
|
37
40
|
return {
|
|
38
41
|
model: modelId,
|
|
@@ -28,6 +28,7 @@ export declare class GeminiProvider extends BaseProvider implements Provider {
|
|
|
28
28
|
apiBase(): string;
|
|
29
29
|
headers(): Record<string, string>;
|
|
30
30
|
protected providerName(): string;
|
|
31
|
+
defaultModel(feature?: string): string;
|
|
31
32
|
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
32
33
|
stream(request: ChatRequest): AsyncGenerator<ChatChunk>;
|
|
33
34
|
listModels(): Promise<ModelInfo[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeminiProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/GeminiProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EAGrB,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASlD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,SAAQ,YAAa,YAAW,QAAQ;IAqBtD,OAAO,CAAC,QAAQ,CAAC,OAAO;IApBpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAsB;IAEpD,YAAY;gCACO,MAAM;+BACP,MAAM;0CACK,MAAM;oCACZ,MAAM;yCACD,MAAM;uCACR,MAAM;oCACT,MAAM;oCACN,MAAM;kCACR,MAAM;MAChC;gBAE2B,OAAO,EAAE,qBAAqB;IAWpD,OAAO,IAAI,MAAM;IAIjB,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMxC,SAAS,CAAC,YAAY,IAAI,MAAM;
|
|
1
|
+
{"version":3,"file":"GeminiProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/GeminiProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EAGrB,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASlD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,SAAQ,YAAa,YAAW,QAAQ;IAqBtD,OAAO,CAAC,QAAQ,CAAC,OAAO;IApBpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAsB;IAEpD,YAAY;gCACO,MAAM;+BACP,MAAM;0CACK,MAAM;oCACZ,MAAM;yCACD,MAAM;uCACR,MAAM;oCACT,MAAM;oCACN,MAAM;kCACR,MAAM;MAChC;gBAE2B,OAAO,EAAE,qBAAqB;IAWpD,OAAO,IAAI,MAAM;IAIjB,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMxC,SAAS,CAAC,YAAY,IAAI,MAAM;IAIhB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAIhD,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAIhD,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC;IAIxD,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIlC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAIpD,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAI5D,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAKhF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI7D,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAiD7D"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { handleGeminiError } from "./Errors.js";
|
|
2
|
+
import { logger } from "../../utils/logger.js";
|
|
2
3
|
export class GeminiImage {
|
|
3
4
|
baseUrl;
|
|
4
5
|
apiKey;
|
|
@@ -22,6 +23,7 @@ export class GeminiImage {
|
|
|
22
23
|
sampleCount: 1,
|
|
23
24
|
},
|
|
24
25
|
};
|
|
26
|
+
logger.logRequest("Gemini", "POST", url, body);
|
|
25
27
|
const response = await fetch(url, {
|
|
26
28
|
method: "POST",
|
|
27
29
|
headers: {
|
|
@@ -33,6 +35,7 @@ export class GeminiImage {
|
|
|
33
35
|
await handleGeminiError(response, modelId);
|
|
34
36
|
}
|
|
35
37
|
const json = await response.json();
|
|
38
|
+
logger.logResponse("Gemini", response.status, response.statusText, json);
|
|
36
39
|
const imageData = json.predictions?.[0];
|
|
37
40
|
if (!imageData || !imageData.bytesBase64Encoded) {
|
|
38
41
|
throw new Error("Unexpected response format from Gemini image generation API");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAOxD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEtE,OAAO,CACZ,OAAO,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,eAAe,GAC3B,cAAc,CAAC,SAAS,CAAC;IAyI5B,OAAO,CAAC,cAAc;CAwBvB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Capabilities } from "./Capabilities.js";
|
|
2
2
|
import { handleGeminiError } from "./Errors.js";
|
|
3
3
|
import { GeminiChatUtils } from "./ChatUtils.js";
|
|
4
|
+
import { logger } from "../../utils/logger.js";
|
|
4
5
|
export class GeminiStreaming {
|
|
5
6
|
baseUrl;
|
|
6
7
|
apiKey;
|
|
@@ -33,8 +34,21 @@ export class GeminiStreaming {
|
|
|
33
34
|
if (systemInstructionParts.length > 0) {
|
|
34
35
|
payload.systemInstruction = { parts: systemInstructionParts };
|
|
35
36
|
}
|
|
37
|
+
if (request.tools && request.tools.length > 0) {
|
|
38
|
+
payload.tools = [
|
|
39
|
+
{
|
|
40
|
+
functionDeclarations: request.tools.map((t) => ({
|
|
41
|
+
name: t.function.name,
|
|
42
|
+
description: t.function.description,
|
|
43
|
+
parameters: t.function.parameters,
|
|
44
|
+
})),
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
}
|
|
36
48
|
let done = false;
|
|
49
|
+
const toolCalls = [];
|
|
37
50
|
try {
|
|
51
|
+
logger.logRequest("Gemini", "POST", url, payload);
|
|
38
52
|
const response = await fetch(url, {
|
|
39
53
|
method: "POST",
|
|
40
54
|
headers: {
|
|
@@ -46,6 +60,7 @@ export class GeminiStreaming {
|
|
|
46
60
|
if (!response.ok) {
|
|
47
61
|
await handleGeminiError(response, request.model);
|
|
48
62
|
}
|
|
63
|
+
logger.debug("Gemini streaming started", { status: response.status, statusText: response.statusText });
|
|
49
64
|
if (!response.body) {
|
|
50
65
|
throw new Error("No response body for streaming");
|
|
51
66
|
}
|
|
@@ -54,8 +69,13 @@ export class GeminiStreaming {
|
|
|
54
69
|
let buffer = "";
|
|
55
70
|
while (true) {
|
|
56
71
|
const { value, done: readerDone } = await reader.read();
|
|
57
|
-
if (readerDone)
|
|
72
|
+
if (readerDone) {
|
|
73
|
+
// Yield tool calls if any were collected
|
|
74
|
+
if (toolCalls.length > 0) {
|
|
75
|
+
yield { content: "", tool_calls: toolCalls, done: true };
|
|
76
|
+
}
|
|
58
77
|
break;
|
|
78
|
+
}
|
|
59
79
|
buffer += decoder.decode(value, { stream: true });
|
|
60
80
|
let lineEnd;
|
|
61
81
|
while ((lineEnd = buffer.indexOf("\n")) !== -1) {
|
|
@@ -76,6 +96,17 @@ export class GeminiStreaming {
|
|
|
76
96
|
if (part.text) {
|
|
77
97
|
yield { content: part.text };
|
|
78
98
|
}
|
|
99
|
+
// Handle function calls
|
|
100
|
+
if (part.functionCall) {
|
|
101
|
+
toolCalls.push({
|
|
102
|
+
id: part.functionCall.name, // Gemini uses name as ID
|
|
103
|
+
type: "function",
|
|
104
|
+
function: {
|
|
105
|
+
name: part.functionCall.name,
|
|
106
|
+
arguments: JSON.stringify(part.functionCall.args || {})
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
79
110
|
}
|
|
80
111
|
}
|
|
81
112
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transcription.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Transcription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Transcription.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini/Transcription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAM7E,qBAAa,mBAAmB;IAGlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAA8E;gBAEvF,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CA8D7E"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { handleGeminiError } from "./Errors.js";
|
|
2
2
|
import { BinaryUtils } from "../../utils/Binary.js";
|
|
3
|
+
import { logger } from "../../utils/logger.js";
|
|
3
4
|
export class GeminiTranscription {
|
|
4
5
|
baseUrl;
|
|
5
6
|
apiKey;
|
|
@@ -42,6 +43,7 @@ export class GeminiTranscription {
|
|
|
42
43
|
responseMimeType: "text/plain",
|
|
43
44
|
},
|
|
44
45
|
};
|
|
46
|
+
logger.logRequest("Gemini", "POST", url, payload);
|
|
45
47
|
const response = await fetch(url, {
|
|
46
48
|
method: "POST",
|
|
47
49
|
headers: {
|
|
@@ -53,6 +55,7 @@ export class GeminiTranscription {
|
|
|
53
55
|
await handleGeminiError(response, model);
|
|
54
56
|
}
|
|
55
57
|
const json = (await response.json());
|
|
58
|
+
logger.logResponse("Gemini", response.status, response.statusText, json);
|
|
56
59
|
const text = json.candidates?.[0]?.content?.parts?.map(p => p.text).join("") || "";
|
|
57
60
|
return {
|
|
58
61
|
text,
|
|
@@ -5,5 +5,6 @@ export interface OllamaProviderOptions {
|
|
|
5
5
|
export declare class OllamaProvider extends OpenAIProvider {
|
|
6
6
|
constructor(options?: OllamaProviderOptions);
|
|
7
7
|
protected providerName(): string;
|
|
8
|
+
defaultModel(feature?: string): string;
|
|
8
9
|
}
|
|
9
10
|
//# sourceMappingURL=OllamaProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OllamaProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/ollama/OllamaProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAM7D,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,SAAQ,cAAc;gBACpC,OAAO,GAAE,qBAA0B;IAwB/C,SAAS,CAAC,YAAY,IAAI,MAAM;
|
|
1
|
+
{"version":3,"file":"OllamaProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/ollama/OllamaProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAM7D,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,SAAQ,cAAc;gBACpC,OAAO,GAAE,qBAA0B;IAwB/C,SAAS,CAAC,YAAY,IAAI,MAAM;IAIhB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;CAGvD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAS,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAS,MAAM,gBAAgB,CAAC;AAQlE,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAuD3D"}
|
|
@@ -2,6 +2,7 @@ import { Capabilities } from "./Capabilities.js";
|
|
|
2
2
|
import { handleOpenAIError } from "./Errors.js";
|
|
3
3
|
import { ModelRegistry } from "../../models/ModelRegistry.js";
|
|
4
4
|
import { buildUrl } from "./utils.js";
|
|
5
|
+
import { logger } from "../../utils/logger.js";
|
|
5
6
|
export class OpenAIChat {
|
|
6
7
|
baseUrl;
|
|
7
8
|
apiKey;
|
|
@@ -25,10 +26,9 @@ export class OpenAIChat {
|
|
|
25
26
|
body.tools = tools;
|
|
26
27
|
if (response_format)
|
|
27
28
|
body.response_format = response_format;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const response = await fetch(buildUrl(this.baseUrl, '/chat/completions'), {
|
|
29
|
+
const url = buildUrl(this.baseUrl, '/chat/completions');
|
|
30
|
+
logger.logRequest("OpenAI", "POST", url, body);
|
|
31
|
+
const response = await fetch(url, {
|
|
32
32
|
method: "POST",
|
|
33
33
|
headers: {
|
|
34
34
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -41,6 +41,7 @@ export class OpenAIChat {
|
|
|
41
41
|
await handleOpenAIError(response, request.model);
|
|
42
42
|
}
|
|
43
43
|
const json = (await response.json());
|
|
44
|
+
logger.logResponse("OpenAI", response.status, response.statusText, json);
|
|
44
45
|
const message = json.choices[0]?.message;
|
|
45
46
|
const content = message?.content ?? null;
|
|
46
47
|
const tool_calls = message?.tool_calls;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Embedding.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Embedding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Embedding.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Embedding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAOrE,qBAAa,eAAe;IAExB,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM;IAClC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;gBADd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM;IAGnC,SAAS,CAAC,eAAe,IAAI,MAAM;IAInC,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMtC,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA+CrE"}
|
|
@@ -2,6 +2,7 @@ import { handleOpenAIError } from "./Errors.js";
|
|
|
2
2
|
import { Capabilities } from "./Capabilities.js";
|
|
3
3
|
import { DEFAULT_MODELS } from "../../constants.js";
|
|
4
4
|
import { buildUrl } from "./utils.js";
|
|
5
|
+
import { logger } from "../../utils/logger.js";
|
|
5
6
|
export class OpenAIEmbedding {
|
|
6
7
|
baseUrl;
|
|
7
8
|
apiKey;
|
|
@@ -30,7 +31,9 @@ export class OpenAIEmbedding {
|
|
|
30
31
|
if (request.user) {
|
|
31
32
|
body.user = request.user;
|
|
32
33
|
}
|
|
33
|
-
const
|
|
34
|
+
const url = buildUrl(this.baseUrl, '/embeddings');
|
|
35
|
+
logger.logRequest("OpenAI", "POST", url, body);
|
|
36
|
+
const response = await fetch(url, {
|
|
34
37
|
method: "POST",
|
|
35
38
|
headers: {
|
|
36
39
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -42,6 +45,7 @@ export class OpenAIEmbedding {
|
|
|
42
45
|
await handleOpenAIError(response, request.model || DEFAULT_MODELS.EMBEDDING);
|
|
43
46
|
}
|
|
44
47
|
const { data, model: responseModel, usage } = await response.json();
|
|
48
|
+
logger.logResponse("OpenAI", response.status, response.statusText, { data, model: responseModel, usage });
|
|
45
49
|
// Extract vectors from the response
|
|
46
50
|
const vectors = data.map((item) => item.embedding);
|
|
47
51
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAK7D,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAuC7D"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { handleOpenAIError } from "./Errors.js";
|
|
2
2
|
import { buildUrl } from "./utils.js";
|
|
3
|
+
import { logger } from "../../utils/logger.js";
|
|
3
4
|
export class OpenAIImage {
|
|
4
5
|
baseUrl;
|
|
5
6
|
apiKey;
|
|
@@ -15,7 +16,9 @@ export class OpenAIImage {
|
|
|
15
16
|
quality: request.quality || "standard",
|
|
16
17
|
n: request.n || 1,
|
|
17
18
|
};
|
|
18
|
-
const
|
|
19
|
+
const url = buildUrl(this.baseUrl, '/images/generations');
|
|
20
|
+
logger.logRequest("OpenAI", "POST", url, body);
|
|
21
|
+
const response = await fetch(url, {
|
|
19
22
|
method: "POST",
|
|
20
23
|
headers: {
|
|
21
24
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -27,6 +30,7 @@ export class OpenAIImage {
|
|
|
27
30
|
await handleOpenAIError(response, request.model);
|
|
28
31
|
}
|
|
29
32
|
const json = await response.json();
|
|
33
|
+
logger.logResponse("OpenAI", response.status, response.statusText, json);
|
|
30
34
|
const data = json.data?.[0];
|
|
31
35
|
if (!data) {
|
|
32
36
|
throw new Error("OpenAI returned empty image response");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Moderation.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Moderation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Moderation.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Moderation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAMvE,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA0BvE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { handleOpenAIError } from "./Errors.js";
|
|
2
2
|
import { DEFAULT_MODELS } from "../../constants.js";
|
|
3
3
|
import { buildUrl } from "./utils.js";
|
|
4
|
+
import { logger } from "../../utils/logger.js";
|
|
4
5
|
export class OpenAIModeration {
|
|
5
6
|
baseUrl;
|
|
6
7
|
apiKey;
|
|
@@ -9,20 +10,25 @@ export class OpenAIModeration {
|
|
|
9
10
|
this.apiKey = apiKey;
|
|
10
11
|
}
|
|
11
12
|
async execute(request) {
|
|
12
|
-
const
|
|
13
|
+
const body = {
|
|
14
|
+
input: request.input,
|
|
15
|
+
model: request.model || DEFAULT_MODELS.MODERATION,
|
|
16
|
+
};
|
|
17
|
+
const url = buildUrl(this.baseUrl, '/moderations');
|
|
18
|
+
logger.logRequest("OpenAI", "POST", url, body);
|
|
19
|
+
const response = await fetch(url, {
|
|
13
20
|
method: "POST",
|
|
14
21
|
headers: {
|
|
15
22
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
16
23
|
"Content-Type": "application/json",
|
|
17
24
|
},
|
|
18
|
-
body: JSON.stringify(
|
|
19
|
-
input: request.input,
|
|
20
|
-
model: request.model || DEFAULT_MODELS.MODERATION,
|
|
21
|
-
}),
|
|
25
|
+
body: JSON.stringify(body),
|
|
22
26
|
});
|
|
23
27
|
if (!response.ok) {
|
|
24
28
|
await handleOpenAIError(response, request.model || DEFAULT_MODELS.MODERATION);
|
|
25
29
|
}
|
|
26
|
-
|
|
30
|
+
const json = await response.json();
|
|
31
|
+
logger.logResponse("OpenAI", response.status, response.statusText, json);
|
|
32
|
+
return json;
|
|
27
33
|
}
|
|
28
34
|
}
|
|
@@ -37,6 +37,7 @@ export declare class OpenAIProvider extends BaseProvider implements Provider {
|
|
|
37
37
|
apiBase(): string;
|
|
38
38
|
headers(): Record<string, string>;
|
|
39
39
|
protected providerName(): string;
|
|
40
|
+
defaultModel(feature?: string): string;
|
|
40
41
|
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
41
42
|
stream(request: ChatRequest): AsyncGenerator<ChatChunk>;
|
|
42
43
|
listModels(): Promise<ModelInfo[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenAIProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/OpenAIProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACpM,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,SAAQ,YAAa,YAAW,QAAQ;IAsBtD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,qBAAqB;IArB7D,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,WAAW,EAAE,UAAU,CAAC;IAClC,SAAS,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAC5C,SAAS,CAAC,aAAa,EAAE,YAAY,CAAC;IACtC,SAAS,CAAC,YAAY,EAAE,WAAW,CAAC;IACpC,SAAS,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;IACpD,SAAS,CAAC,iBAAiB,EAAE,gBAAgB,CAAC;IAC9C,SAAS,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAErC,YAAY;gCACO,MAAM;+BACP,MAAM;0CACK,MAAM;oCACZ,MAAM;yCACD,MAAM;uCACR,MAAM;oCACT,MAAM;mCACP,MAAM;kCACP,MAAM;MAChC;gBAE6B,OAAO,EAAE,qBAAqB;IAYtD,OAAO,IAAI,MAAM;IAIjB,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAOxC,SAAS,CAAC,YAAY,IAAI,MAAM;
|
|
1
|
+
{"version":3,"file":"OpenAIProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/OpenAIProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACpM,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,SAAQ,YAAa,YAAW,QAAQ;IAsBtD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,qBAAqB;IArB7D,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,WAAW,EAAE,UAAU,CAAC;IAClC,SAAS,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAC5C,SAAS,CAAC,aAAa,EAAE,YAAY,CAAC;IACtC,SAAS,CAAC,YAAY,EAAE,WAAW,CAAC;IACpC,SAAS,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;IACpD,SAAS,CAAC,iBAAiB,EAAE,gBAAgB,CAAC;IAC9C,SAAS,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAErC,YAAY;gCACO,MAAM;+BACP,MAAM;0CACK,MAAM;oCACZ,MAAM;yCACD,MAAM;uCACR,MAAM;oCACT,MAAM;mCACP,MAAM;kCACP,MAAM;MAChC;gBAE6B,OAAO,EAAE,qBAAqB;IAYtD,OAAO,IAAI,MAAM;IAIjB,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAOxC,SAAS,CAAC,YAAY,IAAI,MAAM;IAIhB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAIhD,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAIhD,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC;IAIxD,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIlC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAIpD,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAIzE,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIjE,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAGnE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAOxD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEtE,OAAO,CACZ,OAAO,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,eAAe,GAC3B,cAAc,CAAC,SAAS,CAAC;CAqK7B"}
|
|
@@ -2,6 +2,7 @@ import { Capabilities } from "./Capabilities.js";
|
|
|
2
2
|
import { handleOpenAIError } from "./Errors.js";
|
|
3
3
|
import { buildUrl } from "./utils.js";
|
|
4
4
|
import { APIError } from "../../errors/index.js";
|
|
5
|
+
import { logger } from "../../utils/logger.js";
|
|
5
6
|
export class OpenAIStreaming {
|
|
6
7
|
baseUrl;
|
|
7
8
|
apiKey;
|
|
@@ -26,9 +27,16 @@ export class OpenAIStreaming {
|
|
|
26
27
|
if (request.response_format) {
|
|
27
28
|
body.response_format = request.response_format;
|
|
28
29
|
}
|
|
30
|
+
if (request.tools && request.tools.length > 0) {
|
|
31
|
+
body.tools = request.tools;
|
|
32
|
+
}
|
|
29
33
|
let done = false;
|
|
34
|
+
// Track tool calls being built across chunks
|
|
35
|
+
const toolCallsMap = new Map();
|
|
30
36
|
try {
|
|
31
|
-
const
|
|
37
|
+
const url = buildUrl(this.baseUrl, '/chat/completions');
|
|
38
|
+
logger.logRequest("OpenAI", "POST", url, body);
|
|
39
|
+
const response = await fetch(url, {
|
|
32
40
|
method: "POST",
|
|
33
41
|
headers: {
|
|
34
42
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -41,6 +49,7 @@ export class OpenAIStreaming {
|
|
|
41
49
|
if (!response.ok) {
|
|
42
50
|
await handleOpenAIError(response, request.model);
|
|
43
51
|
}
|
|
52
|
+
logger.debug("OpenAI streaming started", { status: response.status, statusText: response.statusText });
|
|
44
53
|
if (!response.body) {
|
|
45
54
|
throw new Error("No response body for streaming");
|
|
46
55
|
}
|
|
@@ -66,6 +75,18 @@ export class OpenAIStreaming {
|
|
|
66
75
|
const data = trimmed.replace("data: ", "").trim();
|
|
67
76
|
if (data === "[DONE]") {
|
|
68
77
|
done = true;
|
|
78
|
+
// Yield final tool calls if any were accumulated
|
|
79
|
+
if (toolCallsMap.size > 0) {
|
|
80
|
+
const toolCalls = Array.from(toolCallsMap.values()).map(tc => ({
|
|
81
|
+
id: tc.id,
|
|
82
|
+
type: "function",
|
|
83
|
+
function: {
|
|
84
|
+
name: tc.function.name,
|
|
85
|
+
arguments: tc.function.arguments
|
|
86
|
+
}
|
|
87
|
+
}));
|
|
88
|
+
yield { content: "", tool_calls: toolCalls, done: true };
|
|
89
|
+
}
|
|
69
90
|
return;
|
|
70
91
|
}
|
|
71
92
|
try {
|
|
@@ -74,9 +95,37 @@ export class OpenAIStreaming {
|
|
|
74
95
|
if (json.error) {
|
|
75
96
|
throw new APIError("OpenAI", response.status, json.error.message || "Stream error");
|
|
76
97
|
}
|
|
77
|
-
const delta = json.choices?.[0]?.delta
|
|
78
|
-
|
|
79
|
-
|
|
98
|
+
const delta = json.choices?.[0]?.delta;
|
|
99
|
+
// Handle content delta
|
|
100
|
+
if (delta?.content) {
|
|
101
|
+
yield { content: delta.content };
|
|
102
|
+
}
|
|
103
|
+
// Handle tool calls delta
|
|
104
|
+
if (delta?.tool_calls) {
|
|
105
|
+
for (const toolCallDelta of delta.tool_calls) {
|
|
106
|
+
const index = toolCallDelta.index;
|
|
107
|
+
if (!toolCallsMap.has(index)) {
|
|
108
|
+
toolCallsMap.set(index, {
|
|
109
|
+
id: toolCallDelta.id || "",
|
|
110
|
+
type: "function",
|
|
111
|
+
function: {
|
|
112
|
+
name: toolCallDelta.function?.name || "",
|
|
113
|
+
arguments: toolCallDelta.function?.arguments || ""
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
const existing = toolCallsMap.get(index);
|
|
119
|
+
if (toolCallDelta.id)
|
|
120
|
+
existing.id = toolCallDelta.id;
|
|
121
|
+
if (toolCallDelta.function?.name) {
|
|
122
|
+
existing.function.name += toolCallDelta.function.name;
|
|
123
|
+
}
|
|
124
|
+
if (toolCallDelta.function?.arguments) {
|
|
125
|
+
existing.function.arguments += toolCallDelta.function.arguments;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
80
129
|
}
|
|
81
130
|
}
|
|
82
131
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transcription.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Transcription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Transcription.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Transcription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAO7E,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;YAU9D,oBAAoB;YAgDpB,iBAAiB;CA4HhC"}
|