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.
 
 
 
 

97 lines
2.5 KiB

import { XllmError } from "../core/errors";
import type {
XChatWithToolsOptions,
XClientOptions,
XMessage,
XRequest,
XToolCall,
XToolErrorStrategy,
XToolExecutorMap,
} from "../core/types";
import { resolveConfig } from "../runtime/config";
import { runToolCall } from "./tool-loop-shared";
export interface ToolLoopConfig {
provider: string;
maxRounds: number;
strategy: XToolErrorStrategy;
}
export interface ToolLoopAccumulator {
rounds: number;
toolCallsExecuted: number;
currentMessages: XMessage[];
}
export const createToolLoopConfig = (
input: XChatWithToolsOptions,
options: XClientOptions,
): ToolLoopConfig => {
const resolved = resolveConfig(input, options);
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: resolved.provider,
});
}
return { provider: resolved.provider, maxRounds, strategy };
};
export const buildRequestBase = (
input: XChatWithToolsOptions,
stream: boolean,
): Omit<XRequest, "messages"> => ({
tools: input.tools,
toolChoice: input.toolChoice,
stream,
temperature: input.temperature,
topP: input.topP,
maxTokens: input.maxTokens,
metadata: input.metadata,
provider: input.provider,
model: input.model,
apiKey: input.apiKey,
baseURL: input.baseURL,
providerExtras: input.providerExtras,
});
export const buildAssistantMessage = (
text: string,
toolCalls: XToolCall[],
reasoning?: string,
): XMessage => ({
role: "assistant",
content: text,
toolCalls,
...(reasoning ? { reasoningContent: reasoning } : {}),
});
export const executeToolCalls = async (
provider: string,
toolCalls: XToolCall[],
executors: XToolExecutorMap,
strategy: XToolErrorStrategy,
): Promise<{ toolMessages: XMessage[]; toolCallsExecuted: number }> => {
const toolMessages: XMessage[] = [];
let toolCallsExecuted = 0;
for (const toolCall of toolCalls) {
const toolRunResult = await runToolCall(provider, toolCall, executors, strategy);
if (!toolRunResult.handled || !toolRunResult.message) {
continue;
}
toolMessages.push(toolRunResult.message);
toolCallsExecuted += 1;
}
return { toolMessages, toolCallsExecuted };
};
export function throwIfMaxRoundsExceeded(config: ToolLoopConfig): never {
throw new XllmError({
code: "PROVIDER_ERROR",
message: `Tool loop exceeded maxRounds=${config.maxRounds}`,
provider: config.provider,
});
}