graphlit-client
Version:
Graphlit API Client for TypeScript
119 lines (118 loc) • 4.12 kB
JavaScript
export class RequiredToolChoiceError extends Error {
code = "required_tool_choice_violation";
requiredToolName;
actualToolNames;
constructor(args) {
super(args.message);
this.name = "RequiredToolChoiceError";
this.requiredToolName = args.requiredToolName;
this.actualToolNames = args.actualToolNames ?? [];
}
}
export function normalizeToolVisibilityResult(fallbackTools, result) {
if (!result)
return { tools: fallbackTools };
if (Array.isArray(result))
return { tools: result };
return {
tools: result.tools ?? fallbackTools,
requireTool: result.requireTool,
requiredToolName: result.requiredToolName,
};
}
export function deriveProviderToolChoicePolicy(visibility) {
if (!visibility.requireTool && !visibility.requiredToolName)
return undefined;
return {
requireTool: visibility.requireTool === true || !!visibility.requiredToolName,
requiredToolName: visibility.requiredToolName,
};
}
export function assertRequiredToolChoiceConfig(visibility) {
const policy = deriveProviderToolChoicePolicy(visibility);
if (!policy?.requireTool)
return;
const visibleToolNames = new Set((visibility.tools ?? []).map((tool) => tool.name));
if (visibleToolNames.size === 0) {
throw new RequiredToolChoiceError({
message: "Tool visibility required a tool call, but no tools were visible.",
requiredToolName: policy.requiredToolName,
});
}
if (policy.requiredToolName && !visibleToolNames.has(policy.requiredToolName)) {
throw new RequiredToolChoiceError({
message: `Tool visibility required ${policy.requiredToolName}, but that tool was not visible.`,
requiredToolName: policy.requiredToolName,
});
}
}
export function validateRequiredToolChoice(visibility, toolCalls) {
const policy = deriveProviderToolChoicePolicy(visibility);
if (!policy?.requireTool)
return;
const actualToolNames = (toolCalls ?? [])
.map((toolCall) => toolCall.name)
.filter((name) => !!name);
if (actualToolNames.length === 0) {
throw new RequiredToolChoiceError({
message: policy.requiredToolName
? `Expected tool call ${policy.requiredToolName}, but the provider returned no tool calls.`
: "Expected a tool call, but the provider returned no tool calls.",
requiredToolName: policy.requiredToolName,
actualToolNames,
});
}
if (policy.requiredToolName &&
actualToolNames.some((name) => name !== policy.requiredToolName)) {
throw new RequiredToolChoiceError({
message: `Expected tool call ${policy.requiredToolName}, but the provider returned ${actualToolNames.join(", ")}.`,
requiredToolName: policy.requiredToolName,
actualToolNames,
});
}
}
export function toOpenAIChatToolChoice(policy) {
if (!policy?.requireTool)
return undefined;
if (policy.requiredToolName) {
return {
type: "function",
function: { name: policy.requiredToolName },
};
}
return "required";
}
export function toOpenAIResponsesToolChoice(policy) {
if (!policy?.requireTool)
return undefined;
if (policy.requiredToolName) {
return {
type: "function",
name: policy.requiredToolName,
};
}
return "required";
}
export function toAnthropicToolChoice(policy) {
if (!policy?.requireTool)
return undefined;
if (policy.requiredToolName) {
return {
type: "tool",
name: policy.requiredToolName,
};
}
return { type: "any" };
}
export function toGoogleToolConfig(policy) {
if (!policy?.requireTool)
return undefined;
return {
functionCallingConfig: {
mode: "ANY",
...(policy.requiredToolName
? { allowedFunctionNames: [policy.requiredToolName] }
: {}),
},
};
}