107 lines
3.2 KiB
TypeScript
107 lines
3.2 KiB
TypeScript
import { z } from "zod";
|
|
import { OPENAI_OUTPUT_MAX } from "./openai";
|
|
|
|
/**
|
|
* Helper function to check if a model is from Moonshot
|
|
*/
|
|
export function isMoonshotModel(model: string): boolean {
|
|
return model.includes("moonshot");
|
|
}
|
|
|
|
/**
|
|
* Helper function to check if a model is a Moonshot vision model
|
|
*/
|
|
export function isMoonshotVisionModel(model: string): boolean {
|
|
return model.includes("moonshot") && model.includes("vision");
|
|
}
|
|
|
|
// Content schema for vision models
|
|
const MoonshotVisionContentSchema = z.union([
|
|
z.string(),
|
|
z.array(
|
|
z.union([
|
|
z.object({
|
|
type: z.literal("text"),
|
|
text: z.string(),
|
|
}),
|
|
z.object({
|
|
type: z.literal("image_url"),
|
|
image_url: z.object({
|
|
url: z.string(),
|
|
detail: z.enum(["low", "high", "auto"]).optional(),
|
|
}),
|
|
}),
|
|
])
|
|
),
|
|
]);
|
|
|
|
// Basic chat message schema
|
|
const MoonshotChatMessageSchema = z.object({
|
|
role: z.enum(["user", "assistant", "system"]),
|
|
content: z.union([z.string(), MoonshotVisionContentSchema]).nullable(),
|
|
name: z.string().optional(),
|
|
// Support for partial mode
|
|
partial: z.boolean().optional(),
|
|
});
|
|
|
|
const MoonshotMessagesSchema = z.array(MoonshotChatMessageSchema);
|
|
|
|
// Schema for Moonshot chat completions
|
|
export const MoonshotV1ChatCompletionsSchema = z.object({
|
|
model: z.string(),
|
|
messages: MoonshotMessagesSchema,
|
|
temperature: z.number().optional().default(0.3),
|
|
top_p: z.number().optional().default(1),
|
|
max_tokens: z.coerce
|
|
.number()
|
|
.int()
|
|
.nullish()
|
|
.transform((v) => Math.min(v ?? OPENAI_OUTPUT_MAX, OPENAI_OUTPUT_MAX)),
|
|
stream: z.boolean().optional().default(false),
|
|
stop: z
|
|
.union([z.string(), z.array(z.string()).max(5)])
|
|
.optional()
|
|
.default([])
|
|
.transform((v) => (Array.isArray(v) ? v : [v])),
|
|
seed: z.number().int().min(0).optional(),
|
|
response_format: z
|
|
.object({
|
|
type: z.enum(["text", "json_object"])
|
|
})
|
|
.optional(),
|
|
tools: z.array(z.any()).optional(),
|
|
tool_choice: z.any().optional(),
|
|
frequency_penalty: z.number().min(-2).max(2).optional().default(0),
|
|
presence_penalty: z.number().min(-2).max(2).optional().default(0),
|
|
n: z.number().int().min(1).max(5).optional().default(1),
|
|
});
|
|
|
|
// Schema for Moonshot embeddings
|
|
export const MoonshotV1EmbeddingsSchema = z.object({
|
|
model: z.string(),
|
|
input: z.union([z.string(), z.array(z.string())]),
|
|
encoding_format: z.enum(["float", "base64"]).optional()
|
|
});
|
|
|
|
// Helper function to enable partial mode for Moonshot (similar to Deepseek's prefill)
|
|
export function enableMoonshotPartial(messages: any[]): any[] {
|
|
// If the last message is from assistant and doesn't have partial flag, add it
|
|
if (messages.length > 0 && messages[messages.length - 1].role === 'assistant') {
|
|
const lastMessage = messages[messages.length - 1];
|
|
if (!lastMessage.partial) {
|
|
return [
|
|
...messages.slice(0, -1),
|
|
{ ...lastMessage, partial: true }
|
|
];
|
|
}
|
|
}
|
|
return messages;
|
|
}
|
|
|
|
// Helper function to check if request uses partial mode
|
|
export function hasMoonshotPartialMode(messages: any[]): boolean {
|
|
return messages.length > 0 &&
|
|
messages[messages.length - 1].role === 'assistant' &&
|
|
messages[messages.length - 1].partial === true;
|
|
}
|