@astack-tech/integrations 0.1.1-beta.6 → 0.2.0-beta.11
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/CHANGELOG.md +71 -0
- package/README.md +98 -1
- package/dist/index.cjs +252 -245
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +252 -245
- package/dist/index.js.map +1 -1
- package/dist/model-provider/index.cjs +254 -246
- package/dist/model-provider/index.cjs.map +1 -1
- package/dist/model-provider/index.d.cts +226 -146
- package/dist/model-provider/index.d.ts +226 -146
- package/dist/model-provider/index.js +252 -245
- package/dist/model-provider/index.js.map +1 -1
- package/package.json +47 -26
- package/src/index.ts +5 -3
- package/src/model-provider/deepseek/index.ts +35 -596
- package/src/model-provider/index.ts +23 -2
- package/src/model-provider/openai-compatible/index.ts +573 -0
|
@@ -30,317 +30,325 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/model-provider/index.ts
|
|
31
31
|
var model_provider_exports = {};
|
|
32
32
|
__export(model_provider_exports, {
|
|
33
|
-
Deepseek: () => deepseek_default
|
|
33
|
+
Deepseek: () => deepseek_default,
|
|
34
|
+
OpenAICompatible: () => openai_compatible_default
|
|
34
35
|
});
|
|
35
36
|
module.exports = __toCommonJS(model_provider_exports);
|
|
36
37
|
|
|
37
|
-
// src/model-provider/
|
|
38
|
+
// src/model-provider/openai-compatible/index.ts
|
|
38
39
|
var import_core = require("@astack-tech/core");
|
|
39
40
|
var import_openai = __toESM(require("openai"), 1);
|
|
40
|
-
var
|
|
41
|
+
var DEFAULT_BASE_URL = "https://api.openai.com/v1";
|
|
42
|
+
var DEFAULT_NAME = "The model API";
|
|
43
|
+
var DEFAULT_TEMPERATURE = 0.7;
|
|
44
|
+
var FALLBACK_TEXT = "API call failed";
|
|
45
|
+
function isRecord(value) {
|
|
46
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
47
|
+
}
|
|
48
|
+
function isOptionalString(value) {
|
|
49
|
+
return value === void 0 || typeof value === "string";
|
|
50
|
+
}
|
|
51
|
+
function isCount(value) {
|
|
52
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
53
|
+
}
|
|
54
|
+
function isTokenUsage(value) {
|
|
55
|
+
return isRecord(value) && isCount(value["completion_tokens"]) && isCount(value["prompt_tokens"]) && isCount(value["total_tokens"]) && (value["prompt_cache_hit_tokens"] === void 0 || isCount(value["prompt_cache_hit_tokens"])) && (value["prompt_cache_miss_tokens"] === void 0 || isCount(value["prompt_cache_miss_tokens"]));
|
|
56
|
+
}
|
|
57
|
+
function isMessage(value) {
|
|
58
|
+
return isRecord(value) && typeof value["role"] === "string" && isOptionalString(value["content"]) && (value["tool_calls"] === void 0 || Array.isArray(value["tool_calls"])) && isOptionalString(value["tool_call_id"]) && (value["usage"] === void 0 || isTokenUsage(value["usage"]));
|
|
59
|
+
}
|
|
60
|
+
function isMessageList(value) {
|
|
61
|
+
return Array.isArray(value) && value.every((item) => isMessage(item));
|
|
62
|
+
}
|
|
63
|
+
function toApiTool(tool) {
|
|
64
|
+
const raw = isRecord(tool) ? tool : {};
|
|
65
|
+
const definition = raw["function"];
|
|
66
|
+
if (raw["type"] === "function" && isRecord(definition)) {
|
|
67
|
+
const { name: name2, description: description2, parameters: parameters2, strict } = definition;
|
|
68
|
+
return {
|
|
69
|
+
type: "function",
|
|
70
|
+
function: {
|
|
71
|
+
name: typeof name2 === "string" ? name2 : "",
|
|
72
|
+
...typeof description2 === "string" ? { description: description2 } : {},
|
|
73
|
+
...isRecord(parameters2) ? { parameters: parameters2 } : {},
|
|
74
|
+
...typeof strict === "boolean" ? { strict } : {}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const { name, description, parameters } = raw;
|
|
79
|
+
return {
|
|
80
|
+
type: "function",
|
|
81
|
+
function: {
|
|
82
|
+
name: typeof name === "string" ? name : "",
|
|
83
|
+
description: typeof description === "string" ? description : "",
|
|
84
|
+
parameters: isRecord(parameters) ? parameters : {}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function parseArguments(raw) {
|
|
89
|
+
if (raw.trim().length === 0) {
|
|
90
|
+
return {};
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const parsed = JSON.parse(raw);
|
|
94
|
+
return isRecord(parsed) ? parsed : {};
|
|
95
|
+
} catch {
|
|
96
|
+
return {};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function mapUsage(usage) {
|
|
100
|
+
return {
|
|
101
|
+
completion_tokens: usage.completion_tokens ?? 0,
|
|
102
|
+
prompt_tokens: usage.prompt_tokens ?? 0,
|
|
103
|
+
total_tokens: usage.total_tokens ?? 0,
|
|
104
|
+
...usage.prompt_cache_hit_tokens === void 0 ? {} : { prompt_cache_hit_tokens: usage.prompt_cache_hit_tokens },
|
|
105
|
+
...usage.prompt_cache_miss_tokens === void 0 ? {} : { prompt_cache_miss_tokens: usage.prompt_cache_miss_tokens }
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
var OpenAICompatible = class extends import_core.Component {
|
|
109
|
+
client;
|
|
110
|
+
model;
|
|
111
|
+
temperature;
|
|
112
|
+
maxTokens;
|
|
113
|
+
topP;
|
|
114
|
+
systemPrompt;
|
|
115
|
+
tools;
|
|
116
|
+
verbose;
|
|
117
|
+
name;
|
|
41
118
|
constructor(config) {
|
|
42
119
|
super({});
|
|
43
120
|
this.client = new import_openai.default({
|
|
44
121
|
apiKey: config.apiKey,
|
|
45
|
-
baseURL: config.baseURL
|
|
122
|
+
baseURL: config.baseURL ?? DEFAULT_BASE_URL,
|
|
46
123
|
dangerouslyAllowBrowser: config.dangerouslyAllowBrowser ?? false
|
|
47
124
|
});
|
|
48
|
-
this.model = config.model
|
|
49
|
-
this.
|
|
125
|
+
this.model = config.model;
|
|
126
|
+
this.name = config.name ?? DEFAULT_NAME;
|
|
127
|
+
this.temperature = config.temperature ?? DEFAULT_TEMPERATURE;
|
|
50
128
|
this.maxTokens = config.maxTokens;
|
|
51
129
|
this.topP = config.topP;
|
|
52
130
|
this.systemPrompt = config.systemPrompt;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
type: "function",
|
|
56
|
-
function: {
|
|
57
|
-
name: tool.name,
|
|
58
|
-
description: tool.description,
|
|
59
|
-
parameters: tool.parameters || {}
|
|
60
|
-
}
|
|
61
|
-
}));
|
|
62
|
-
} else {
|
|
63
|
-
this.tools = config.tools;
|
|
64
|
-
}
|
|
131
|
+
this.verbose = config.verbose ?? false;
|
|
132
|
+
this.tools = config.rawTools !== void 0 && config.rawTools.length > 0 ? config.rawTools.map(toApiTool) : config.tools;
|
|
65
133
|
import_core.Component.Port.I("prompt").attach(this);
|
|
66
134
|
import_core.Component.Port.I("messages").attach(this);
|
|
67
135
|
import_core.Component.Port.O("completion").attach(this);
|
|
68
136
|
import_core.Component.Port.O("message").attach(this);
|
|
69
137
|
}
|
|
70
138
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* @returns
|
|
139
|
+
* Generates a completion for a single prompt.
|
|
140
|
+
*
|
|
141
|
+
* @returns The text answer, or the JSON-encoded assistant message when it contains tool calls.
|
|
74
142
|
*/
|
|
75
143
|
async generateCompletion(prompt) {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
messages.
|
|
79
|
-
|
|
80
|
-
content: this.systemPrompt
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
messages.push({
|
|
84
|
-
role: "user",
|
|
85
|
-
content: prompt
|
|
144
|
+
const response = await this.client.chat.completions.create({
|
|
145
|
+
...this.baseRequest(),
|
|
146
|
+
messages: [...this.systemMessages(), { role: "user", content: prompt }],
|
|
147
|
+
...this.toolsParam(this.tools)
|
|
86
148
|
});
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
temperature: this.temperature,
|
|
91
|
-
max_tokens: this.maxTokens,
|
|
92
|
-
top_p: this.topP
|
|
93
|
-
};
|
|
94
|
-
if (this.tools && this.tools.length > 0) {
|
|
95
|
-
requestParams.tools = this.tools;
|
|
96
|
-
}
|
|
97
|
-
const response = await this.client.chat.completions.create(requestParams);
|
|
98
|
-
if (response.choices[0].message.tool_calls && response.choices[0].message.tool_calls.length > 0) {
|
|
99
|
-
return JSON.stringify(response.choices[0].message);
|
|
149
|
+
const message = this.firstMessage(response);
|
|
150
|
+
if (message.tool_calls !== void 0 && message.tool_calls.length > 0) {
|
|
151
|
+
return JSON.stringify(message);
|
|
100
152
|
}
|
|
101
|
-
return
|
|
153
|
+
return message.content ?? "";
|
|
102
154
|
}
|
|
103
155
|
/**
|
|
104
|
-
*
|
|
105
|
-
* @param messages 对话消息数组
|
|
106
|
-
* @param options 可选的调用选项,包含临时工具列表
|
|
107
|
-
* @returns 生成的流式响应消息异步生成器
|
|
156
|
+
* Sends a conversation and returns the assistant reply.
|
|
108
157
|
*/
|
|
109
|
-
async
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
158
|
+
async chatCompletion(messages, options) {
|
|
159
|
+
const response = await this.client.chat.completions.create({
|
|
160
|
+
...this.baseRequest(),
|
|
161
|
+
messages: this.formatMessages(messages),
|
|
162
|
+
...this.toolsParam(options?.temporaryTools ?? this.tools)
|
|
163
|
+
});
|
|
164
|
+
const message = this.firstMessage(response);
|
|
165
|
+
const result = { role: "assistant", content: message.content ?? "" };
|
|
166
|
+
if (response.usage !== void 0) {
|
|
167
|
+
result.usage = mapUsage(response.usage);
|
|
116
168
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
content: msg.content
|
|
122
|
-
};
|
|
123
|
-
if (msg.role === "tool" && msg.tool_call_id) {
|
|
124
|
-
formattedMsg.tool_call_id = msg.tool_call_id;
|
|
125
|
-
}
|
|
126
|
-
return formattedMsg;
|
|
127
|
-
})
|
|
128
|
-
);
|
|
129
|
-
const requestParams = {
|
|
130
|
-
model: this.model,
|
|
131
|
-
messages: formattedMessages,
|
|
132
|
-
temperature: this.temperature,
|
|
133
|
-
max_tokens: this.maxTokens,
|
|
134
|
-
top_p: this.topP,
|
|
135
|
-
stream: true
|
|
136
|
-
// 开启流式模式
|
|
137
|
-
};
|
|
138
|
-
const toolsToUse = options?.temporaryTools || this.tools;
|
|
139
|
-
if (toolsToUse && toolsToUse.length > 0) {
|
|
140
|
-
const formattedTools = toolsToUse.map((tool) => {
|
|
141
|
-
const typedTool = tool;
|
|
142
|
-
if (typedTool.type === "function") {
|
|
143
|
-
return tool;
|
|
169
|
+
if (message.tool_calls !== void 0 && message.tool_calls.length > 0) {
|
|
170
|
+
result.tool_calls = message.tool_calls.map((toolCall) => {
|
|
171
|
+
if (toolCall.type !== "function") {
|
|
172
|
+
throw new Error(`Unsupported tool call type: ${toolCall.type}`);
|
|
144
173
|
}
|
|
174
|
+
const rawArguments = toolCall.function.arguments;
|
|
145
175
|
return {
|
|
176
|
+
id: toolCall.id,
|
|
146
177
|
type: "function",
|
|
147
178
|
function: {
|
|
148
|
-
name:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
179
|
+
name: toolCall.function.name,
|
|
180
|
+
arguments: rawArguments.length > 0 ? rawArguments : "{}"
|
|
181
|
+
},
|
|
182
|
+
tool_name: toolCall.function.name,
|
|
183
|
+
arguments: parseArguments(rawArguments)
|
|
152
184
|
};
|
|
153
185
|
});
|
|
154
|
-
requestParams.tools = formattedTools;
|
|
155
186
|
}
|
|
156
|
-
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Streams the assistant reply. Each chunk holds a text delta, tool-call deltas, or usage.
|
|
191
|
+
*/
|
|
192
|
+
async *streamChatCompletion(messages, options) {
|
|
193
|
+
const stream = await this.client.chat.completions.create({
|
|
194
|
+
...this.baseRequest(),
|
|
195
|
+
messages: this.formatMessages(messages),
|
|
196
|
+
...this.toolsParam(options?.temporaryTools ?? this.tools),
|
|
197
|
+
stream: true
|
|
198
|
+
});
|
|
157
199
|
for await (const chunk of stream) {
|
|
158
200
|
const delta = chunk.choices[0]?.delta;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
content: delta.content
|
|
163
|
-
};
|
|
201
|
+
const text = delta?.content ?? "";
|
|
202
|
+
if (text !== "") {
|
|
203
|
+
yield { role: "assistant", content: text };
|
|
164
204
|
}
|
|
165
205
|
if (delta?.tool_calls) {
|
|
166
206
|
yield {
|
|
167
207
|
role: "assistant",
|
|
168
208
|
content: "",
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
})
|
|
209
|
+
tool_calls: delta.tool_calls.map((toolCall) => {
|
|
210
|
+
const name = toolCall.function?.name ?? "";
|
|
211
|
+
const args = toolCall.function?.arguments ?? "";
|
|
212
|
+
return {
|
|
213
|
+
id: toolCall.id ?? "",
|
|
214
|
+
type: "function",
|
|
215
|
+
function: { name, arguments: args },
|
|
216
|
+
tool_name: name,
|
|
217
|
+
arguments: args
|
|
218
|
+
};
|
|
219
|
+
})
|
|
180
220
|
};
|
|
181
221
|
}
|
|
182
222
|
if (chunk.usage) {
|
|
183
|
-
yield {
|
|
184
|
-
role: "assistant",
|
|
185
|
-
content: "",
|
|
186
|
-
usage: {
|
|
187
|
-
completion_tokens: chunk.usage.completion_tokens || 0,
|
|
188
|
-
prompt_tokens: chunk.usage.prompt_tokens || 0,
|
|
189
|
-
prompt_cache_hit_tokens: chunk.usage.prompt_cache_hit_tokens,
|
|
190
|
-
prompt_cache_miss_tokens: chunk.usage.prompt_cache_miss_tokens,
|
|
191
|
-
total_tokens: chunk.usage.total_tokens || 0
|
|
192
|
-
}
|
|
193
|
-
};
|
|
223
|
+
yield { role: "assistant", content: "", usage: mapUsage(chunk.usage) };
|
|
194
224
|
}
|
|
195
225
|
}
|
|
196
226
|
}
|
|
197
227
|
/**
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* @param
|
|
201
|
-
* @returns 生成的响应消息
|
|
228
|
+
* Runs the model outside a pipeline.
|
|
229
|
+
*
|
|
230
|
+
* @param input - A prompt string or a list of messages.
|
|
202
231
|
*/
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
232
|
+
run(input) {
|
|
233
|
+
return typeof input === "string" ? this.generateCompletion(input) : this.chatCompletion(input);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Connects the `prompt` and `messages` input ports to the model.
|
|
237
|
+
* API errors produce a fallback value so the pipeline keeps flowing. Input of the wrong
|
|
238
|
+
* type fails the pipeline run with a `TypeError` before the API is called.
|
|
239
|
+
*/
|
|
240
|
+
_transform($i, $o) {
|
|
241
|
+
$i("prompt").receive((prompt) => {
|
|
242
|
+
if (typeof prompt !== "string") {
|
|
243
|
+
throw new TypeError(`${this.name}: the prompt port expects a string.`);
|
|
244
|
+
}
|
|
245
|
+
return this.generateCompletion(prompt).then(
|
|
246
|
+
(completion) => {
|
|
247
|
+
$o("completion").send(completion);
|
|
248
|
+
},
|
|
249
|
+
(error) => {
|
|
250
|
+
this.logError(error);
|
|
251
|
+
$o("completion").send(FALLBACK_TEXT);
|
|
219
252
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
)
|
|
223
|
-
|
|
253
|
+
);
|
|
254
|
+
});
|
|
255
|
+
$i("messages").receive((messages) => {
|
|
256
|
+
if (!isMessageList(messages)) {
|
|
257
|
+
throw new TypeError(`${this.name}: the messages port expects an array of messages.`);
|
|
258
|
+
}
|
|
259
|
+
return this.chatCompletion(messages).then(
|
|
260
|
+
(message) => {
|
|
261
|
+
$o("message").send(message);
|
|
262
|
+
},
|
|
263
|
+
(error) => {
|
|
264
|
+
this.logError(error);
|
|
265
|
+
$o("message").send({ role: "assistant", content: FALLBACK_TEXT });
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
baseRequest() {
|
|
271
|
+
return {
|
|
224
272
|
model: this.model,
|
|
225
|
-
messages: formattedMessages,
|
|
226
273
|
temperature: this.temperature,
|
|
227
|
-
max_tokens: this.maxTokens,
|
|
228
|
-
top_p: this.topP
|
|
274
|
+
...this.maxTokens === void 0 ? {} : { max_tokens: this.maxTokens },
|
|
275
|
+
...this.topP === void 0 ? {} : { top_p: this.topP }
|
|
229
276
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
return {
|
|
238
|
-
type: "function",
|
|
239
|
-
function: {
|
|
240
|
-
name: typedTool.name,
|
|
241
|
-
description: typedTool.description,
|
|
242
|
-
parameters: typedTool.parameters || {}
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
});
|
|
246
|
-
requestParams.tools = formattedTools;
|
|
247
|
-
}
|
|
248
|
-
const response = await this.client.chat.completions.create(requestParams);
|
|
249
|
-
const responseMessage = response.choices[0].message;
|
|
250
|
-
const result = {
|
|
251
|
-
role: "assistant",
|
|
252
|
-
content: responseMessage.content || ""
|
|
253
|
-
};
|
|
254
|
-
if (response.usage) {
|
|
255
|
-
const usage = response.usage;
|
|
256
|
-
result.usage = {
|
|
257
|
-
completion_tokens: usage.completion_tokens || 0,
|
|
258
|
-
prompt_tokens: usage.prompt_tokens || 0,
|
|
259
|
-
prompt_cache_hit_tokens: usage.prompt_cache_hit_tokens,
|
|
260
|
-
prompt_cache_miss_tokens: usage.prompt_cache_miss_tokens,
|
|
261
|
-
total_tokens: usage.total_tokens || 0
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
if (responseMessage.tool_calls && responseMessage.tool_calls.length > 0) {
|
|
265
|
-
result.tool_calls = responseMessage.tool_calls.map((toolCall) => {
|
|
266
|
-
if (toolCall.type !== "function" || !("function" in toolCall)) {
|
|
267
|
-
throw new Error(`Unsupported tool call type: ${toolCall.type}`);
|
|
268
|
-
}
|
|
269
|
-
let args;
|
|
270
|
-
const rawArgs = toolCall.function.arguments;
|
|
271
|
-
if (typeof rawArgs === "string") {
|
|
272
|
-
const raw = rawArgs;
|
|
273
|
-
try {
|
|
274
|
-
args = raw && raw.trim().length > 0 ? JSON.parse(raw) : {};
|
|
275
|
-
} catch {
|
|
276
|
-
args = {};
|
|
277
|
-
}
|
|
278
|
-
} else if (rawArgs && typeof rawArgs === "object") {
|
|
279
|
-
args = rawArgs;
|
|
280
|
-
} else {
|
|
281
|
-
args = {};
|
|
282
|
-
}
|
|
283
|
-
return {
|
|
284
|
-
id: toolCall.id,
|
|
285
|
-
// 满足 Agent 组件期望的格式
|
|
286
|
-
function: {
|
|
287
|
-
name: toolCall.function.name,
|
|
288
|
-
arguments: toolCall.function.arguments || "{}"
|
|
289
|
-
},
|
|
290
|
-
type: "function",
|
|
291
|
-
// 满足内部 ToolCall 接口
|
|
292
|
-
tool_name: toolCall.function.name,
|
|
293
|
-
arguments: args
|
|
294
|
-
};
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
return result;
|
|
277
|
+
}
|
|
278
|
+
toolsParam(tools) {
|
|
279
|
+
return tools !== void 0 && tools.length > 0 ? { tools: tools.map(toApiTool) } : {};
|
|
280
|
+
}
|
|
281
|
+
systemMessages() {
|
|
282
|
+
return this.systemPrompt === void 0 || this.systemPrompt === "" ? [] : [{ role: "system", content: this.systemPrompt }];
|
|
298
283
|
}
|
|
299
284
|
/**
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
285
|
+
* Converts input messages to API messages. Assistant `tool_calls` are not forwarded:
|
|
286
|
+
* agents send tool results back as user messages, and the API rejects assistant tool
|
|
287
|
+
* calls that are not followed by tool messages.
|
|
303
288
|
*/
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
return this.generateCompletion(input);
|
|
307
|
-
} else {
|
|
308
|
-
return this.chatCompletion(input);
|
|
309
|
-
}
|
|
289
|
+
formatMessages(messages) {
|
|
290
|
+
return [...this.systemMessages(), ...messages.map((message) => this.toApiMessage(message))];
|
|
310
291
|
}
|
|
311
292
|
/**
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
* @
|
|
293
|
+
* Converts one input message to its API shape.
|
|
294
|
+
*
|
|
295
|
+
* @throws Error when the role is not one of `MessageRole`, or a `tool` message has no
|
|
296
|
+
* `tool_call_id`. The API would reject both.
|
|
315
297
|
*/
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
298
|
+
toApiMessage(message) {
|
|
299
|
+
const content = message.content ?? "";
|
|
300
|
+
switch (message.role) {
|
|
301
|
+
case "system":
|
|
302
|
+
return { role: "system", content };
|
|
303
|
+
case "user":
|
|
304
|
+
return { role: "user", content };
|
|
305
|
+
case "assistant":
|
|
306
|
+
return message.content === void 0 ? { role: "assistant" } : { role: "assistant", content: message.content };
|
|
307
|
+
case "tool":
|
|
308
|
+
if (message.tool_call_id === void 0 || message.tool_call_id === "") {
|
|
309
|
+
throw new Error(
|
|
310
|
+
`${this.name}: a tool message needs the tool_call_id of the call it answers.`
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
return { role: "tool", content, tool_call_id: message.tool_call_id };
|
|
314
|
+
default:
|
|
315
|
+
throw new Error(
|
|
316
|
+
`${this.name}: unsupported message role '${message.role}'. Use system, user, assistant or tool.`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
firstMessage(response) {
|
|
321
|
+
const choice = response.choices[0];
|
|
322
|
+
if (choice === void 0) {
|
|
323
|
+
throw new Error(`${this.name} returned no choices.`);
|
|
324
|
+
}
|
|
325
|
+
return choice.message;
|
|
326
|
+
}
|
|
327
|
+
logError(error) {
|
|
328
|
+
if (this.verbose) {
|
|
329
|
+
console.error(`[${this.name}] API call failed:`, error);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
var openai_compatible_default = OpenAICompatible;
|
|
334
|
+
|
|
335
|
+
// src/model-provider/deepseek/index.ts
|
|
336
|
+
var DEFAULT_BASE_URL2 = "https://api.deepseek.com/v1";
|
|
337
|
+
var DEFAULT_MODEL = "deepseek-chat";
|
|
338
|
+
var Deepseek = class extends openai_compatible_default {
|
|
339
|
+
constructor(config) {
|
|
340
|
+
super({
|
|
341
|
+
...config,
|
|
342
|
+
model: config.model ?? DEFAULT_MODEL,
|
|
343
|
+
baseURL: config.baseURL ?? DEFAULT_BASE_URL2,
|
|
344
|
+
name: "DeepSeek"
|
|
338
345
|
});
|
|
339
346
|
}
|
|
340
347
|
};
|
|
341
348
|
var deepseek_default = Deepseek;
|
|
342
349
|
// Annotate the CommonJS export names for ESM import in node:
|
|
343
350
|
0 && (module.exports = {
|
|
344
|
-
Deepseek
|
|
351
|
+
Deepseek,
|
|
352
|
+
OpenAICompatible
|
|
345
353
|
});
|
|
346
354
|
//# sourceMappingURL=index.cjs.map
|