feat: add database support, conversation sidebar, and improve chat streaming
- Update .gitignore to exclude database files, extensions, and .cursor directory - Enhance chat streaming API with safe enqueue and close functions to prevent errors - Integrate ConversationSidebar component into ClientHome for better UI - Add dependencies like better-sqlite3 and esbuild packages for database functionality This commit introduces database persistence for conversations, improves error handling in streaming responses, and adds a sidebar for managing chats, enhancing overall app robustness and user experience.
This commit is contained in:
1 parent
a3f8226fda
commit
0cc7a81319
34 files changed
+2370
-198
No files matched your search
+62
-2
@@ -29,10 +29,11 @@ export async function chatWithStream(
|
||||
const client = new Ollama({ host: OLLAMA_HOST });
|
||||
return client.chat({
|
||||
model,
|
||||
messages,
|
||||
messages: system
|
||||
? [...messages, { role: "system", content: system }]
|
||||
: messages,
|
||||
stream: true,
|
||||
options,
|
||||
system,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -40,3 +41,62 @@ export async function pullModel(model: string) {
|
||||
const client = new Ollama({ host: OLLAMA_HOST });
|
||||
return client.pull({ model, stream: true });
|
||||
}
|
||||
|
||||
export async function checkModelExists(modelName: string): Promise<boolean> {
|
||||
try {
|
||||
const models = await listModelsViaSdk();
|
||||
return models.some((model) => model.name === modelName);
|
||||
} catch (error) {
|
||||
console.error("Erro ao verificar modelos:", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureModelExists(
|
||||
modelName: string,
|
||||
description?: string
|
||||
): Promise<void> {
|
||||
const exists = await checkModelExists(modelName);
|
||||
if (!exists) {
|
||||
console.log(`📥 Baixando modelo ${modelName}...`);
|
||||
if (description) {
|
||||
console.log(`ℹ️ ${description}`);
|
||||
}
|
||||
|
||||
const stream = await pullModel(modelName);
|
||||
let downloadedBytes = 0;
|
||||
let totalBytes = 0;
|
||||
let progress = 0;
|
||||
|
||||
// Processar stream para mostrar progresso
|
||||
for await (const chunk of stream) {
|
||||
if (chunk.status === "downloading" && chunk.completed && chunk.total) {
|
||||
downloadedBytes = chunk.completed;
|
||||
totalBytes = chunk.total;
|
||||
progress = Math.round((downloadedBytes / totalBytes) * 100);
|
||||
|
||||
// Criar barra de progresso visual
|
||||
const barLength = 20;
|
||||
const filledLength = Math.round((progress / 100) * barLength);
|
||||
const bar =
|
||||
"█".repeat(filledLength) + "░".repeat(barLength - filledLength);
|
||||
|
||||
// Mostrar progresso com informações
|
||||
const downloadedMB = (downloadedBytes / 1024 / 1024).toFixed(1);
|
||||
const totalMB = (totalBytes / 1024 / 1024).toFixed(1);
|
||||
|
||||
process.stdout.write(
|
||||
`\r📥 ${modelName}: [${bar}] ${progress}% (${downloadedMB}MB/${totalMB}MB)`
|
||||
);
|
||||
} else if (chunk.status === "success") {
|
||||
console.log(`\n✅ Modelo ${modelName} baixado com sucesso!`);
|
||||
if (description) {
|
||||
console.log(`🎯 ${description.replace("será usado", "agora funciona")}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(`✅ Modelo ${modelName} já está disponível`);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user