@astack-tech/integrations
Version:
Integrations for the Astack AI Framework.
349 lines (346 loc) • 11.3 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ModelProvider: () => model_provider_exports
});
module.exports = __toCommonJS(src_exports);
// src/model-provider/index.ts
var model_provider_exports = {};
__export(model_provider_exports, {
Deepseek: () => deepseek_default
});
// src/model-provider/deepseek/index.ts
var import_core = require("@astack-tech/core");
var import_openai = __toESM(require("openai"), 1);
var Deepseek = class extends import_core.Component {
constructor(config) {
super({});
this.client = new import_openai.default({
apiKey: config.apiKey,
baseURL: config.baseURL || "https://api.deepseek.com/v1",
dangerouslyAllowBrowser: config.dangerouslyAllowBrowser ?? false
});
this.model = config.model || "deepseek-chat";
this.temperature = config.temperature ?? 0.7;
this.maxTokens = config.maxTokens;
this.topP = config.topP;
this.systemPrompt = config.systemPrompt;
if (config.rawTools && config.rawTools.length > 0) {
this.tools = config.rawTools.map((tool) => ({
type: "function",
function: {
name: tool.name,
description: tool.description,
parameters: tool.parameters || {}
}
}));
} else {
this.tools = config.tools;
}
import_core.Component.Port.I("prompt").attach(this);
import_core.Component.Port.I("messages").attach(this);
import_core.Component.Port.O("completion").attach(this);
import_core.Component.Port.O("message").attach(this);
}
/**
* 生成文本完成
* @param prompt 提示文本
* @returns 生成的文本
*/
async generateCompletion(prompt) {
const messages = [];
if (this.systemPrompt) {
messages.push({
role: "system",
content: this.systemPrompt
});
}
messages.push({
role: "user",
content: prompt
});
const requestParams = {
model: this.model,
messages,
temperature: this.temperature,
max_tokens: this.maxTokens,
top_p: this.topP
};
if (this.tools && this.tools.length > 0) {
requestParams.tools = this.tools;
}
const response = await this.client.chat.completions.create(requestParams);
if (response.choices[0].message.tool_calls && response.choices[0].message.tool_calls.length > 0) {
return JSON.stringify(response.choices[0].message);
}
return response.choices[0].message.content || "";
}
/**
* 流式处理对话消息
* @param messages 对话消息数组
* @param options 可选的调用选项,包含临时工具列表
* @returns 生成的流式响应消息异步生成器
*/
async *streamChatCompletion(messages, options) {
const formattedMessages = [];
if (this.systemPrompt) {
formattedMessages.push({
role: "system",
content: this.systemPrompt
});
}
formattedMessages.push(
...messages.map((msg) => {
const formattedMsg = {
role: msg.role,
content: msg.content
};
if (msg.role === "tool" && msg.tool_call_id) {
formattedMsg.tool_call_id = msg.tool_call_id;
}
return formattedMsg;
})
);
const requestParams = {
model: this.model,
messages: formattedMessages,
temperature: this.temperature,
max_tokens: this.maxTokens,
top_p: this.topP,
stream: true
// 开启流式模式
};
const toolsToUse = options?.temporaryTools || this.tools;
if (toolsToUse && toolsToUse.length > 0) {
const formattedTools = toolsToUse.map((tool) => {
const typedTool = tool;
if (typedTool.type === "function") {
return tool;
}
return {
type: "function",
function: {
name: typedTool.name,
description: typedTool.description,
parameters: typedTool.parameters || {}
}
};
});
requestParams.tools = formattedTools;
}
const stream = await this.client.chat.completions.create(requestParams);
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta;
if (delta?.content) {
yield {
role: "assistant",
content: delta.content
};
}
if (delta?.tool_calls) {
yield {
role: "assistant",
content: "",
// eslint-disable-next-line @typescript-eslint/no-explicit-any
tool_calls: delta.tool_calls.map((toolCall) => ({
id: toolCall.id || "",
function: {
name: toolCall.function?.name || "",
arguments: toolCall.function?.arguments || ""
},
type: "function",
tool_name: toolCall.function?.name || "",
arguments: toolCall.function?.arguments || ""
}))
};
}
if (chunk.usage) {
yield {
role: "assistant",
content: "",
usage: {
completion_tokens: chunk.usage.completion_tokens || 0,
prompt_tokens: chunk.usage.prompt_tokens || 0,
prompt_cache_hit_tokens: chunk.usage.prompt_cache_hit_tokens,
prompt_cache_miss_tokens: chunk.usage.prompt_cache_miss_tokens,
total_tokens: chunk.usage.total_tokens || 0
}
};
}
}
}
/**
* 处理对话消息
* @param messages 对话消息数组
* @param options 可选的调用选项,包含临时工具列表
* @returns 生成的响应消息
*/
async chatCompletion(messages, options) {
const formattedMessages = [];
if (this.systemPrompt) {
formattedMessages.push({
role: "system",
content: this.systemPrompt
});
}
formattedMessages.push(
...messages.map((msg) => {
const formattedMsg = {
role: msg.role,
content: msg.content
};
if (msg.role === "tool" && msg.tool_call_id) {
formattedMsg.tool_call_id = msg.tool_call_id;
}
return formattedMsg;
})
);
const requestParams = {
model: this.model,
messages: formattedMessages,
temperature: this.temperature,
max_tokens: this.maxTokens,
top_p: this.topP
};
const toolsToUse = options?.temporaryTools || this.tools;
if (toolsToUse && toolsToUse.length > 0) {
const formattedTools = toolsToUse.map((tool) => {
const typedTool = tool;
if (typedTool.type === "function") {
return tool;
}
return {
type: "function",
function: {
name: typedTool.name,
description: typedTool.description,
parameters: typedTool.parameters || {}
}
};
});
requestParams.tools = formattedTools;
}
const response = await this.client.chat.completions.create(requestParams);
const responseMessage = response.choices[0].message;
const result = {
role: "assistant",
content: responseMessage.content || ""
};
if (response.usage) {
const usage = response.usage;
result.usage = {
completion_tokens: usage.completion_tokens || 0,
prompt_tokens: usage.prompt_tokens || 0,
prompt_cache_hit_tokens: usage.prompt_cache_hit_tokens,
prompt_cache_miss_tokens: usage.prompt_cache_miss_tokens,
total_tokens: usage.total_tokens || 0
};
}
if (responseMessage.tool_calls && responseMessage.tool_calls.length > 0) {
result.tool_calls = responseMessage.tool_calls.map((toolCall) => {
let args;
const rawArgs = toolCall.function.arguments;
if (typeof rawArgs === "string") {
const raw = rawArgs;
try {
args = raw && raw.trim().length > 0 ? JSON.parse(raw) : {};
} catch {
args = {};
}
} else if (rawArgs && typeof rawArgs === "object") {
args = rawArgs;
} else {
args = {};
}
return {
id: toolCall.id,
// 满足 Agent 组件期望的格式
function: {
name: toolCall.function.name,
arguments: toolCall.function.arguments || "{}"
},
type: "function",
// 满足内部 ToolCall 接口
tool_name: toolCall.function.name,
arguments: args
};
});
}
return result;
}
/**
* 在独立模式下运行组件
* @param input 输入参数,可以是提示文本或对话消息数组
* @returns 生成的文本或响应消息
*/
async run(input) {
if (typeof input === "string") {
return this.generateCompletion(input);
} else {
return this.chatCompletion(input);
}
}
/**
* 在流水线中运行组件
* @param $i 输入端口
* @param $o 输出端口
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_transform($i, $o) {
$i("prompt").receive(async (prompt) => {
try {
const completion = await this.generateCompletion(prompt);
$o("completion").send(completion);
} catch (error) {
console.error("Deepseek API \u8C03\u7528\u9519\u8BEF:", error);
$o("completion").send("API \u8C03\u7528\u9519\u8BEF");
}
});
$i("messages").receive(async (messages) => {
try {
const responseMessage = await this.chatCompletion(messages);
$o("message").send(responseMessage);
} catch (error) {
console.error("Deepseek API \u8C03\u7528\u9519\u8BEF:", error);
$o("message").send({
role: "assistant",
content: "API \u8C03\u7528\u9519\u8BEF"
});
}
});
}
};
var deepseek_default = Deepseek;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ModelProvider
});
//# sourceMappingURL=index.cjs.map