mono项目开发模板,内置cli管理构建
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

80 lines
2.2 KiB

import { XllmError } from "../core/errors";
import type {
XChatWithToolsOptions,
XChatWithToolsResult,
XClientOptions,
XMessage,
XRequest,
XToolExecutorMap,
} from "../core/types";
import { generate } from "./generate";
import { runToolCall } from "./tool-loop-shared";
export const chatWithTools = async (
options: XClientOptions,
input: XChatWithToolsOptions,
executors: XToolExecutorMap,
): Promise<XChatWithToolsResult> => {
const maxRounds = input.maxRounds ?? 5;
const strategy = input.toolErrorStrategy ?? "throw";
if (maxRounds < 1) {
throw new XllmError({
code: "INVALID_REQUEST",
message: "maxRounds must be >= 1",
provider: input.provider ?? options.provider ?? "openai-compatible",
});
}
let rounds = 0;
let toolCallsExecuted = 0;
let currentMessages = [...input.messages];
const requestBase: Omit<XRequest, "messages"> = {
tools: input.tools,
toolChoice: input.toolChoice,
stream: false,
temperature: input.temperature,
topP: input.topP,
maxTokens: input.maxTokens,
metadata: input.metadata,
provider: input.provider,
model: input.model,
apiKey: input.apiKey,
baseURL: input.baseURL,
};
while (rounds < maxRounds) {
rounds += 1;
const response = await generate(options, {
...requestBase,
messages: currentMessages,
});
if (response.toolCalls.length === 0) {
return { response, rounds, toolCallsExecuted };
}
const assistantMessage: XMessage = {
role: "assistant",
content: [{ type: "text", text: response.text }],
toolCalls: response.toolCalls,
};
const toolMessages: XMessage[] = [];
for (const toolCall of response.toolCalls) {
const toolRunResult = await runToolCall(response.provider, toolCall, executors, strategy);
if (!toolRunResult.handled || !toolRunResult.message) {
continue;
}
toolMessages.push(toolRunResult.message);
toolCallsExecuted += 1;
}
currentMessages = [...currentMessages, assistantMessage, ...toolMessages];
}
throw new XllmError({
code: "PROVIDER_ERROR",
message: `Tool loop exceeded maxRounds=${maxRounds}`,
provider: input.provider ?? options.provider ?? "openai-compatible",
});
};