This commit is contained in:
reanon
2025-04-23 19:22:46 +00:00
parent 9213b7088b
commit 3beea5dcfc
+32 -25
View File
@@ -62,6 +62,13 @@ export const GoogleAIV1GenerateContentSchema = z
// except for system_instruction where it randomly uses snake case.
// google api evidently accepts either case.
system_instruction: GoogleAIV1ContentSchema.optional(),
// These fields are used by SillyTavern but aren't part of the actual API schema
// They'll be removed by the transform but used to determine thinkingBudget
enable_thinking: z.boolean().optional(),
thinking_budget: z.union([
z.literal("auto"),
z.number().int().min(0).max(24576)
]).optional(),
generationConfig: z
.object({
temperature: z.number().min(0).max(2).optional(),
@@ -76,29 +83,13 @@ export const GoogleAIV1GenerateContentSchema = z
topK: z.number().min(1).max(40).optional(),
stopSequences: z.array(z.string().max(500)).max(5).optional(),
thinkingConfig: z.object({
enable_thinking: z.boolean().optional(),
includeThoughts: z.boolean().optional(),
thinkingBudget: z.union([
z.literal("auto"),
z.number().int().min(0).max(24576)
]).optional()
}).optional()
})
.default({})
.transform((config) => {
// Auto-enable thinking when thinkingBudget is set
if (config.thinkingConfig?.thinkingBudget !== undefined &&
config.thinkingConfig.enable_thinking === undefined) {
return {
...config,
thinkingConfig: {
...config.thinkingConfig,
enable_thinking: true
}
};
}
return config;
}),
.default({}),
})
.strip();
export type GoogleAIChatMessage = z.infer<
@@ -170,18 +161,34 @@ export const transformOpenAIToGoogleAI: APIFormatTransformer<
stops.push(...Array.from(foundNames).map((name) => `\n${name}:`));
stops = [...new Set(stops)].slice(0, 5);
// Setup generation config
const generationConfig: any = {
maxOutputTokens: rest.max_tokens,
stopSequences: stops,
topP: rest.top_p,
topK: 40, // openai schema doesn't have this, google ai defaults to 40
temperature: rest.temperature,
};
// Handle thinking budget from SillyTavern's UI
if (req.body.enable_thinking !== undefined || req.body.thinking_budget !== undefined) {
const thinkingEnabled = req.body.enable_thinking !== false; // Default to true if not specified
const thinkingBudget = req.body.thinking_budget ?? 1000; // Default budget if not specified
// Only set thinkingBudget if thinking is enabled
if (thinkingEnabled && thinkingBudget !== 0) {
generationConfig.thinkingConfig = {
thinkingBudget: thinkingBudget
};
}
}
return {
model: req.body.model,
stream: rest.stream,
contents,
tools: [],
generationConfig: {
maxOutputTokens: rest.max_tokens,
stopSequences: stops,
topP: rest.top_p,
topK: 40, // openai schema doesn't have this, google ai defaults to 40
temperature: rest.temperature,
},
generationConfig,
safetySettings: [
{ category: "HARM_CATEGORY_HARASSMENT", threshold: "BLOCK_NONE" },
{ category: "HARM_CATEGORY_HATE_SPEECH", threshold: "BLOCK_NONE" },
@@ -197,4 +204,4 @@ export function containsImageContent(contents: GoogleAIChatMessage[]): boolean {
const parts = Array.isArray(content.parts) ? content.parts : [content.parts];
return parts.some(part => 'inlineData' in part);
});
}
}