Add LICENSE, README, and Docs tab to Mission Control
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
export type SiteMenteMessage = {
|
||||
role: "user" | "assistant" | "system";
|
||||
content: string;
|
||||
};
|
||||
|
||||
export type SiteMenteSpeechResult = {
|
||||
audioBytes: Uint8Array;
|
||||
mimeType: string;
|
||||
};
|
||||
|
||||
const TEXT_MODEL = "MiniMax-M2.5";
|
||||
const API_KEY = process.env.MINIMAX_API_KEY || "sk-cp-q8FpnlRzqa2oHVrHYVKXgCDAltN85KdsiSqAzRZeP6zvSSauupHu4ffVPKLgVWFz534az2lgM39T6ReXUvfT-8sUlQd9faush2Kr3KNmykoJNNgE8IET73Q";
|
||||
|
||||
const MINIMAX_API_BASE = "https://api.minimax.io/v1";
|
||||
|
||||
const SYSTEM_PROMPT = `You are SiteMente, an AI site strategist that helps business owners make their websites think like a smart assistant.
|
||||
You deeply understand landing pages, funnels, customer psychology, and automation.
|
||||
You recommend specific AI Minds, suggest copy and UX changes, and ask focused clarifying questions before proposing changes.
|
||||
Keep answers concise, practical, and business-oriented.`;
|
||||
|
||||
export const generateSiteMenteText = async (
|
||||
messages: SiteMenteMessage[]
|
||||
): Promise<string> => {
|
||||
try {
|
||||
// Build messages - add system prompt if not present
|
||||
const hasSystem = messages.some((m) => m.role === "system");
|
||||
|
||||
// Filter and format messages
|
||||
const contents = messages
|
||||
.filter((m) => m.role !== "system")
|
||||
.map((m) => ({
|
||||
role: m.role === "assistant" ? "assistant" : "user",
|
||||
content: m.content,
|
||||
}));
|
||||
|
||||
// Add system instruction
|
||||
if (!hasSystem) {
|
||||
contents.unshift({ role: "system", content: SYSTEM_PROMPT });
|
||||
}
|
||||
|
||||
const response = await fetch(`${MINIMAX_API_BASE}/text/chatcompletion_v2`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${API_KEY}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: TEXT_MODEL,
|
||||
messages: contents,
|
||||
max_tokens: 1024,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`MiniMax API error: ${response.status} - ${errorText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const text = data?.choices?.[0]?.message?.content;
|
||||
|
||||
if (!text) {
|
||||
throw new Error("MiniMax returned an empty response.");
|
||||
}
|
||||
|
||||
return text;
|
||||
} catch (error) {
|
||||
console.error("[SiteMente][MiniMax] Text generation failed", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const generateSiteMenteSpeech = async (
|
||||
text: string
|
||||
): Promise<SiteMenteSpeechResult> => {
|
||||
// MiniMax doesn't have built-in TTS in their text API
|
||||
// Vapi handles voice output on their end
|
||||
throw new Error("TTS not implemented - Vapi handles voice output");
|
||||
};
|
||||
@@ -1,8 +1,7 @@
|
||||
import {
|
||||
generateSiteMenteSpeech,
|
||||
generateSiteMenteText,
|
||||
type SiteMenteMessage,
|
||||
} from "./geminiClient";
|
||||
} from "./minimaxClient";
|
||||
|
||||
export type SiteMenteTextRequest = {
|
||||
messages: SiteMenteMessage[];
|
||||
@@ -49,13 +48,13 @@ export const runSiteMenteVoiceTurn = async (
|
||||
{ role: "user", content: request.transcript },
|
||||
];
|
||||
const reply = await generateSiteMenteText(withSystemPrompt(messages));
|
||||
const audio = await generateSiteMenteSpeech(reply);
|
||||
|
||||
// Return text only - Vapi handles voice output on their end
|
||||
return {
|
||||
reply,
|
||||
audio: {
|
||||
data: Buffer.from(audio.audioBytes).toString("base64"),
|
||||
mimeType: audio.mimeType,
|
||||
data: "",
|
||||
mimeType: "audio/mp3",
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user