Files
OllaHub/repomix-output.xml
T
Evandro Fonseca Junior 8834ef2b4f feat: update dependencies and enhance chat functionality
- Added new Radix UI components including checkbox, label, popover, slider, switch, and tooltip to improve UI interactions.
- Integrated react-syntax-highlighter for better code rendering in chat messages.
- Updated package.json and pnpm-lock.yaml to include new dependencies and ensure compatibility.
- Enhanced chat input to support web search toggling, improving user experience during message composition.
- Implemented auto-saving of chat sessions and improved session management features.
- Refactored chat message rendering to clean up metadata and improve display quality.
2025-11-20 04:26:35 -03:00

10169 lines
261 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file is a merged representation of the entire codebase, combined into a single document by Repomix.
<file_summary>
This section contains a summary of this file.
<purpose>
This file contains a packed representation of the entire repository's contents.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.
</purpose>
<file_format>
The content is organized as follows:
1. This summary section
2. Repository information
3. Directory structure
4. Repository files (if enabled)
5. Multiple file entries, each consisting of:
- File path as an attribute
- Full contents of the file
</file_format>
<usage_guidelines>
- This file should be treated as read-only. Any changes should be made to the
original repository files, not this packed version.
- When processing this file, use the file path to distinguish
between different files in the repository.
- Be aware that this file may contain sensitive information. Handle it with
the same level of security as you would the original repository.
</usage_guidelines>
<notes>
- Some files may have been excluded based on .gitignore rules and Repomix's configuration
- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
- Files matching patterns in .gitignore are excluded
- Files matching default ignore patterns are excluded
- Files are sorted by Git change count (files with more changes are at the bottom)
</notes>
</file_summary>
<directory_structure>
.gitignore
app/chat/page.tsx
app/favicon.ico
app/globals.css
app/layout.tsx
app/page.tsx
app/setup/page.tsx
components.json
components/chat/chat-input.tsx
components/chat/chat-message.tsx
components/chat/code-block.tsx
components/chat/markdown-renderers.tsx
components/chat/message-actions.tsx
components/chat/prompt-generator.tsx
components/chat/system-panel.tsx
components/landing/hero.tsx
components/landing/stopped-card.tsx
components/modals/install-modal.tsx
components/setup/hardware-scan.tsx
components/setup/model-selector.tsx
components/theme-provider.tsx
components/ui/badge.tsx
components/ui/button.tsx
components/ui/card.tsx
components/ui/dialog.tsx
components/ui/dropdown-menu.tsx
components/ui/progress.tsx
components/ui/resizable.tsx
components/ui/select.tsx
components/ui/separator.tsx
components/ui/tabs.tsx
components/ui/textarea.tsx
data/models/alfred.json
data/models/all-minilm.json
data/models/athene-v2.json
data/models/aya-expanse.json
data/models/aya.json
data/models/bakllava.json
data/models/bespoke-minicheck.json
data/models/bge-large.json
data/models/bge-m3.json
data/models/codebooga.json
data/models/codegeex4.json
data/models/codegemma.json
data/models/codellama.json
data/models/codeqwen.json
data/models/codestral.json
data/models/codeup.json
data/models/cogito.json
data/models/command-a.json
data/models/command-r-plus.json
data/models/command-r.json
data/models/command-r7b-arabic.json
data/models/command-r7b.json
data/models/dbrx.json
data/models/deepcoder.json
data/models/deepscaler.json
data/models/deepseek-coder-v2.json
data/models/deepseek-coder.json
data/models/deepseek-llm.json
data/models/deepseek-r1.json
data/models/deepseek-v2.5.json
data/models/deepseek-v2.json
data/models/deepseek-v3.1.json
data/models/deepseek-v3.json
data/models/devstral.json
data/models/dolphin-llama3.json
data/models/dolphin-mistral.json
data/models/dolphin-mixtral.json
data/models/dolphin-phi.json
data/models/dolphin3.json
data/models/dolphincoder.json
data/models/duckdb-nsql.json
data/models/embeddinggemma.json
data/models/everythinglm.json
data/models/exaone-deep.json
data/models/exaone3.5.json
data/models/falcon.json
data/models/falcon2.json
data/models/falcon3.json
data/models/firefunction-v2.json
data/models/gemini-3-pro-preview.json
data/models/gemma.json
data/models/gemma2.json
data/models/gemma3.json
data/models/gemma3n.json
data/models/glm-4.6.json
data/models/glm4.json
data/models/goliath.json
data/models/gpt-oss-safeguard.json
data/models/gpt-oss.json
data/models/granite-code.json
data/models/granite-embedding.json
data/models/granite3-dense.json
data/models/granite3-guardian.json
data/models/granite3-moe.json
data/models/granite3.1-dense.json
data/models/granite3.1-moe.json
data/models/granite3.2-vision.json
data/models/granite3.2.json
data/models/granite3.3.json
data/models/granite4.json
data/models/hermes3.json
data/models/internlm2.json
data/models/kimi-k2-thinking.json
data/models/kimi-k2.json
data/models/llama-guard3.json
data/models/llama-pro.json
data/models/llama2-chinese.json
data/models/llama2-uncensored.json
data/models/llama2.json
data/models/llama3-chatqa.json
data/models/llama3-gradient.json
data/models/llama3-groq-tool-use.json
data/models/llama3.1.json
data/models/llama3.2-vision.json
data/models/llama3.2.json
data/models/llama3.3.json
data/models/llama3.json
data/models/llama4.json
data/models/llava-llama3.json
data/models/llava-phi3.json
data/models/llava.json
data/models/magicoder.json
data/models/magistral.json
data/models/marco-o1.json
data/models/mathstral.json
data/models/meditron.json
data/models/medllama2.json
data/models/megadolphin.json
data/models/minicpm-v.json
data/models/minimax-m2.json
data/models/mistral-large.json
data/models/mistral-nemo.json
data/models/mistral-openorca.json
data/models/mistral-small.json
data/models/mistral-small3.1.json
data/models/mistral-small3.2.json
data/models/mistral.json
data/models/mistrallite.json
data/models/mixtral.json
data/models/moondream.json
data/models/mxbai-embed-large.json
data/models/nemotron-mini.json
data/models/nemotron.json
data/models/neural-chat.json
data/models/nexusraven.json
data/models/nomic-embed-text.json
data/models/notus.json
data/models/notux.json
data/models/nous-hermes.json
data/models/nous-hermes2-mixtral.json
data/models/nous-hermes2.json
data/models/nuextract.json
data/models/olmo2.json
data/models/open-orca-platypus2.json
data/models/openchat.json
data/models/opencoder.json
data/models/openhermes.json
data/models/openthinker.json
data/models/orca-mini.json
data/models/orca2.json
data/models/paraphrase-multilingual.json
data/models/phi.json
data/models/phi3.5.json
data/models/phi3.json
data/models/phi4-mini-reasoning.json
data/models/phi4-mini.json
data/models/phi4-reasoning.json
data/models/phi4.json
data/models/phind-codellama.json
data/models/qwen.json
data/models/qwen2-math.json
data/models/qwen2.5-coder.json
data/models/qwen2.5.json
data/models/qwen2.5vl.json
data/models/qwen2.json
data/models/qwen3-coder.json
data/models/qwen3-embedding.json
data/models/qwen3-vl.json
data/models/qwen3.json
data/models/qwq.json
data/models/r1-1776.json
data/models/reader-lm.json
data/models/reflection.json
data/models/sailor2.json
data/models/samantha-mistral.json
data/models/shieldgemma.json
data/models/smallthinker.json
data/models/smollm.json
data/models/smollm2.json
data/models/snowflake-arctic-embed.json
data/models/snowflake-arctic-embed2.json
data/models/solar-pro.json
data/models/solar.json
data/models/sqlcoder.json
data/models/stable-beluga.json
data/models/stable-code.json
data/models/stablelm-zephyr.json
data/models/stablelm2.json
data/models/starcoder.json
data/models/starcoder2.json
data/models/starling-lm.json
data/models/tinydolphin.json
data/models/tinyllama.json
data/models/tulu3.json
data/models/vicuna.json
data/models/wizard-math.json
data/models/wizard-vicuna-uncensored.json
data/models/wizard-vicuna.json
data/models/wizardcoder.json
data/models/wizardlm-uncensored.json
data/models/wizardlm.json
data/models/wizardlm2.json
data/models/xwinlm.json
data/models/yarn-llama2.json
data/models/yarn-mistral.json
data/models/yi-coder.json
data/models/yi.json
data/models/zephyr.json
data/prompts/default-format.md
data/prompts/prompt-gen.md
eslint.config.mjs
hooks/use-chat.ts
hooks/use-hardware.ts
hooks/use-local-models.ts
hooks/use-ollama-check.ts
hooks/use-prompt-generator.ts
hooks/use-system-monitor.ts
lib/recommendation.ts
lib/utils.ts
next.config.ts
package.json
postcss.config.mjs
public/file.svg
public/globe.svg
public/next.svg
public/vercel.svg
public/window.svg
README.md
src-tauri/.gitignore
src-tauri/build.rs
src-tauri/capabilities/default.json
src-tauri/Cargo.toml
src-tauri/icons/128x128.png
src-tauri/icons/[email protected]
src-tauri/icons/32x32.png
src-tauri/icons/icon.icns
src-tauri/icons/icon.ico
src-tauri/icons/icon.png
src-tauri/icons/Square107x107Logo.png
src-tauri/icons/Square142x142Logo.png
src-tauri/icons/Square150x150Logo.png
src-tauri/icons/Square284x284Logo.png
src-tauri/icons/Square30x30Logo.png
src-tauri/icons/Square310x310Logo.png
src-tauri/icons/Square44x44Logo.png
src-tauri/icons/Square71x71Logo.png
src-tauri/icons/Square89x89Logo.png
src-tauri/icons/StoreLogo.png
src-tauri/src/lib.rs
src-tauri/src/main.rs
src-tauri/tauri.conf.json
tsconfig.json
</directory_structure>
<files>
This section contains the contents of the repository's files.
<file path=".gitignore">
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
</file>
<file path="app/chat/page.tsx">
'use client';
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { MessageSquare, Settings, Server, Moon, Sun, PanelLeftClose, PanelLeftOpen } from "lucide-react";
import { ChatInput } from "@/components/chat/chat-input";
import { ChatMessage } from "@/components/chat/chat-message";
import { SystemPanel } from "@/components/chat/system-panel";
import { PromptGeneratorDialog } from "@/components/chat/prompt-generator";
import { useChat } from "@/hooks/use-chat";
import { useLocalModels } from "@/hooks/use-local-models";
import { useState, useEffect, useRef } from "react";
import { useTheme } from "next-themes";
import { ImperativePanelHandle } from "react-resizable-panels";
// @ts-ignore
import defaultFormatPrompt from "@/data/prompts/default-format.md";
export default function ChatPage() {
const { messages, sendMessage, isLoading, stop } = useChat();
const { models } = useLocalModels();
const { theme, setTheme } = useTheme();
const [selectedModel, setSelectedModel] = useState("");
// Initialize with default format prompt
const [systemPrompt, setSystemPrompt] = useState(defaultFormatPrompt || "Você é um assistente útil e prestativo.");
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
const sidebarRef = useRef<ImperativePanelHandle>(null);
// Auto-select first model
useEffect(() => {
if (models.length > 0 && !selectedModel) {
setSelectedModel(models[0].name);
}
}, [models, selectedModel]);
const handleSend = (content: string) => {
if (!selectedModel) return;
sendMessage(content, selectedModel, systemPrompt);
};
const toggleSidebar = () => {
const panel = sidebarRef.current;
if (panel) {
if (isSidebarCollapsed) {
panel.expand();
} else {
panel.collapse();
}
}
};
return (
<div className="h-screen w-full bg-background overflow-hidden flex">
{/* Left Sidebar (Nav) */}
<ResizablePanelGroup direction="horizontal" className="flex-1">
<ResizablePanel
ref={sidebarRef}
defaultSize={4}
minSize={4}
maxSize={15}
collapsible={true}
collapsedSize={0}
onCollapse={() => setIsSidebarCollapsed(true)}
onExpand={() => setIsSidebarCollapsed(false)}
className="border-r flex flex-col items-center py-4 gap-4 bg-muted/20 min-w-[60px]"
>
<Button variant="ghost" size="icon" className="rounded-lg bg-primary/10 text-primary">
<MessageSquare className="w-5 h-5" />
</Button>
<Button variant="ghost" size="icon" className="rounded-lg text-muted-foreground hover:text-foreground">
<Server className="w-5 h-5" />
</Button>
<div className="flex-1" />
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
className="rounded-lg text-muted-foreground hover:text-foreground"
>
{theme === "dark" ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
</Button>
<Button variant="ghost" size="icon" className="rounded-lg text-muted-foreground hover:text-foreground">
<Settings className="w-5 h-5" />
</Button>
</ResizablePanel>
<ResizableHandle />
{/* Main Chat Area */}
<ResizablePanel defaultSize={75} minSize={50}>
<div className="h-full flex flex-col">
{/* Header */}
<div className="h-14 border-b flex items-center px-4 justify-between bg-background/50 backdrop-blur gap-4">
<div className="flex items-center gap-2">
{isSidebarCollapsed && (
<Button variant="ghost" size="icon" onClick={toggleSidebar} className="h-8 w-8">
<PanelLeftOpen className="w-4 h-4" />
</Button>
)}
{!isSidebarCollapsed && (
<Button variant="ghost" size="icon" onClick={toggleSidebar} className="h-8 w-8 text-muted-foreground">
<PanelLeftClose className="w-4 h-4" />
</Button>
)}
<div className="font-semibold">Chat</div>
</div>
<div className="flex-1 max-w-[300px]">
<Select value={selectedModel} onValueChange={setSelectedModel}>
<SelectTrigger className="h-9">
<SelectValue placeholder="Selecione um modelo..." />
</SelectTrigger>
<SelectContent>
{models.map(m => (
<SelectItem key={m.name} value={m.name}>{m.name}</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
{/* Messages */}
<div className="flex-1 overflow-y-auto scroll-smooth">
{messages.length === 0 ? (
<div className="h-full flex flex-col items-center justify-center text-muted-foreground space-y-4">
<div className="p-4 rounded-full bg-muted/50">
<MessageSquare className="w-8 h-8" />
</div>
<p>Inicie uma conversa com {selectedModel}</p>
</div>
) : (
<div className="flex flex-col pb-4">
{messages.map((msg, i) => (
<ChatMessage key={i} message={msg} />
))}
{isLoading && (
<div className="px-6 py-4 text-xs text-muted-foreground animate-pulse">
Gerando resposta...
</div>
)}
</div>
)}
</div>
{/* Input */}
<ChatInput
onSend={handleSend}
onStop={stop}
isLoading={isLoading}
/>
</div>
</ResizablePanel>
<ResizableHandle withHandle />
{/* Right Sidebar (Settings & Monitor) */}
<ResizablePanel defaultSize={25} minSize={20} maxSize={40} className="bg-muted/10">
<Tabs defaultValue="params" className="h-full flex flex-col">
<div className="border-b px-4">
<TabsList className="w-full justify-start h-12 bg-transparent p-0 gap-4">
<TabsTrigger
value="params"
className="data-[state=active]:bg-transparent data-[state=active]:shadow-none data-[state=active]:border-b-2 data-[state=active]:border-primary rounded-none px-0"
>
Parâmetros
</TabsTrigger>
<TabsTrigger
value="system"
className="data-[state=active]:bg-transparent data-[state=active]:shadow-none data-[state=active]:border-b-2 data-[state=active]:border-primary rounded-none px-0"
>
Sistema
</TabsTrigger>
</TabsList>
</div>
<TabsContent value="params" className="flex-1 p-4 space-y-6 overflow-y-auto m-0">
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium">System Prompt</label>
<PromptGeneratorDialog
defaultModel={selectedModel}
onPromptGenerated={setSystemPrompt}
/>
</div>
<Textarea
value={systemPrompt}
onChange={(e) => setSystemPrompt(e.target.value)}
className="min-h-[300px] resize-none font-mono text-sm"
placeholder="Defina como a IA deve se comportar..."
/>
<p className="text-xs text-muted-foreground">
Instruções globais para o comportamento do modelo.
</p>
</div>
</TabsContent>
<TabsContent value="system" className="flex-1 m-0 overflow-hidden">
<SystemPanel />
</TabsContent>
</Tabs>
</ResizablePanel>
</ResizablePanelGroup>
</div>
);
}
</file>
<file path="app/globals.css">
@import "tailwindcss";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.141 0.005 285.823);
--card: oklch(1 0 0);
--card-foreground: oklch(0.141 0.005 285.823);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.141 0.005 285.823);
--primary: oklch(0.21 0.006 285.885);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.967 0.001 286.375);
--secondary-foreground: oklch(0.21 0.006 285.885);
--muted: oklch(0.967 0.001 286.375);
--muted-foreground: oklch(0.552 0.016 285.938);
--accent: oklch(0.967 0.001 286.375);
--accent-foreground: oklch(0.21 0.006 285.885);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.92 0.004 286.32);
--input: oklch(0.92 0.004 286.32);
--ring: oklch(0.705 0.015 286.067);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.141 0.005 285.823);
--sidebar-primary: oklch(0.21 0.006 285.885);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.967 0.001 286.375);
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
--sidebar-border: oklch(0.92 0.004 286.32);
--sidebar-ring: oklch(0.705 0.015 286.067);
}
.dark {
--background: oklch(0.141 0.005 285.823);
--foreground: oklch(0.985 0 0);
--card: oklch(0.21 0.006 285.885);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.21 0.006 285.885);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.92 0.004 286.32);
--primary-foreground: oklch(0.21 0.006 285.885);
--secondary: oklch(0.274 0.006 286.033);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.274 0.006 286.033);
--muted-foreground: oklch(0.705 0.015 286.067);
--accent: oklch(0.274 0.006 286.033);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.552 0.016 285.938);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.21 0.006 285.885);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.274 0.006 286.033);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.552 0.016 285.938);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}
</file>
<file path="app/layout.tsx">
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { ThemeProvider } from "@/components/theme-provider";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "OllaHub",
description: "Interface moderna para Ollama",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="pt-BR" suppressHydrationWarning>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);
}
</file>
<file path="app/page.tsx">
'use client';
import { useOllamaCheck } from "@/hooks/use-ollama-check";
import { Hero } from "@/components/landing/hero";
import { InstallModal } from "@/components/modals/install-modal";
import { StoppedCard } from "@/components/landing/stopped-card";
import { Loader2 } from "lucide-react";
import { useRouter } from "next/navigation";
export default function Home() {
const { status, check } = useOllamaCheck();
const router = useRouter();
const handleStart = () => {
const setupComplete = localStorage.getItem("ollahub_setup_complete");
if (setupComplete) {
router.push("/chat");
} else {
router.push("/setup");
}
};
if (status === 'checking') {
return (
<div className="flex h-screen w-full items-center justify-center bg-background">
<Loader2 className="h-8 w-8 animate-spin text-primary" />
<span className="ml-2 text-muted-foreground">Verificando sistema...</span>
</div>
);
}
return (
<main className="flex min-h-screen flex-col items-center justify-center p-4 bg-background text-foreground transition-colors duration-300">
{/* Layout for Running State */}
{status === 'running' && (
<Hero onStart={handleStart} />
)}
{/* Layout for Stopped State */}
{status === 'installed_stopped' && (
<div className="flex flex-col items-center gap-8 animate-in fade-in slide-in-from-bottom-4 duration-500">
<div className="text-center space-y-2">
<h1 className="text-3xl font-bold tracking-tighter">OllaHub</h1>
<p className="text-muted-foreground">Detectamos o Ollama, mas ele não está rodando.</p>
</div>
<StoppedCard onCheckAgain={check} />
</div>
)}
{/* Layout for Not Installed State (Background + Modal) */}
{status === 'not_installed' && (
<>
<div className="opacity-20 pointer-events-none blur-sm">
<Hero onStart={() => {}} />
</div>
{/* Hero is shown in background, modal is open */}
<InstallModal
open={true}
onCheckAgain={check}
/>
</>
)}
</main>
);
}
</file>
<file path="app/setup/page.tsx">
'use client';
import { useHardware } from "@/hooks/use-hardware";
import { HardwareScan } from "@/components/setup/hardware-scan";
import { ModelSelector } from "@/components/setup/model-selector";
import { getRecommendation } from "@/lib/recommendation";
import { useRouter } from "next/navigation";
export default function SetupPage() {
const { specs, loading } = useHardware();
const router = useRouter();
const handleComplete = () => {
// Save setup state if needed
localStorage.setItem("ollahub_setup_complete", "true");
router.push("/chat");
};
return (
<main className="flex min-h-screen flex-col items-center justify-center p-4 bg-background text-foreground">
<div className="w-full max-w-2xl space-y-8 animate-in fade-in duration-700">
<div className="text-center space-y-2">
<h1 className="text-3xl font-bold tracking-tighter">Configuração Inicial</h1>
<p className="text-muted-foreground">Vamos preparar o ambiente ideal para você.</p>
</div>
<HardwareScan specs={specs} loading={loading} />
{!loading && specs && (
<div className="animate-in slide-in-from-bottom-8 duration-700 delay-300 fill-mode-backwards">
<ModelSelector
recommendation={getRecommendation(specs)}
onComplete={handleComplete}
/>
</div>
)}
</div>
</main>
);
}
</file>
<file path="components.json">
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
</file>
<file path="components/chat/chat-input.tsx">
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Send, Square } from "lucide-react";
import { useState, useRef, useEffect } from "react";
interface ChatInputProps {
onSend: (message: string) => void;
onStop: () => void;
isLoading: boolean;
}
export function ChatInput({ onSend, onStop, isLoading }: ChatInputProps) {
const [input, setInput] = useState("");
const textareaRef = useRef<HTMLTextAreaElement>(null);
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSend();
}
};
const handleSend = () => {
if (input.trim() && !isLoading) {
onSend(input);
setInput("");
}
};
useEffect(() => {
if (textareaRef.current) {
textareaRef.current.style.height = "auto";
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
}
}, [input]);
return (
<div className="p-4 border-t bg-background">
<div className="relative flex items-end gap-2 max-w-3xl mx-auto">
<Textarea
ref={textareaRef}
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Digite sua mensagem..."
className="min-h-[50px] max-h-[200px] resize-none pr-12 py-3"
rows={1}
/>
<div className="absolute right-2 bottom-2">
{isLoading ? (
<Button size="icon" variant="destructive" onClick={onStop} className="h-8 w-8">
<Square className="h-4 w-4 fill-current" />
</Button>
) : (
<Button
size="icon"
onClick={handleSend}
disabled={!input.trim()}
className="h-8 w-8"
>
<Send className="h-4 w-4" />
</Button>
)}
</div>
</div>
<div className="text-xs text-center text-muted-foreground mt-2">
OllaHub pode cometer erros. Verifique informações importantes.
</div>
</div>
);
}
</file>
<file path="components/chat/chat-message.tsx">
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import { cn } from "@/lib/utils";
import { Message } from "@/hooks/use-chat";
import { Bot, User } from "lucide-react";
import { markdownRenderers } from "./markdown-renderers";
import { MessageActions } from "./message-actions";
export function ChatMessage({ message }: { message: Message }) {
const isUser = message.role === 'user';
return (
<div className={cn(
"group flex w-full gap-4 p-6 relative",
isUser ? "bg-background" : "bg-muted/30"
)}>
<div className="flex-shrink-0 mt-1">
<div className={cn(
"w-8 h-8 rounded-sm flex items-center justify-center",
isUser ? "bg-primary text-primary-foreground" : "bg-secondary text-secondary-foreground"
)}>
{isUser ? <User className="w-5 h-5" /> : <Bot className="w-5 h-5" />}
</div>
</div>
<div className="flex-1 overflow-hidden min-w-0">
<div className="prose dark:prose-invert max-w-none break-words">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={markdownRenderers}
>
{message.content}
</ReactMarkdown>
</div>
</div>
{/* Actions Toolbar - Absolute positioned or flex end */}
{!isUser && (
<div className="absolute top-4 right-4">
<MessageActions content={message.content} role={message.role} />
</div>
)}
</div>
);
}
</file>
<file path="components/chat/code-block.tsx">
import { Check, Copy } from "lucide-react";
import { useState } from "react";
import { Button } from "@/components/ui/button";
interface CodeBlockProps {
language: string;
children: string;
}
export function CodeBlock({ language, children }: CodeBlockProps) {
const [copied, setCopied] = useState(false);
const handleCopy = () => {
navigator.clipboard.writeText(children);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
<div className="my-4 rounded-lg border bg-muted/50 overflow-hidden">
<div className="flex items-center justify-between px-4 py-2 bg-muted/80 border-b">
<span className="text-xs font-medium text-muted-foreground uppercase">
{language || "text"}
</span>
<Button
variant="ghost"
size="icon"
className="h-6 w-6 hover:bg-background/50"
onClick={handleCopy}
title="Copiar código"
>
{copied ? (
<Check className="h-3.5 w-3.5 text-green-500" />
) : (
<Copy className="h-3.5 w-3.5 text-muted-foreground" />
)}
</Button>
</div>
<div className="p-4 overflow-x-auto">
<code className="text-sm font-mono whitespace-pre">{children}</code>
</div>
</div>
);
}
</file>
<file path="components/chat/markdown-renderers.tsx">
import { Components } from "react-markdown";
import { CodeBlock } from "./code-block";
import { cn } from "@/lib/utils";
export const markdownRenderers: Components = {
h1: ({ className, ...props }) => (
<h1
className={cn(
"mt-2 scroll-m-20 text-2xl font-bold tracking-tight first:mt-0",
className
)}
{...props}
/>
),
h2: ({ className, ...props }) => (
<h2
className={cn(
"mt-6 scroll-m-20 border-b pb-2 text-xl font-semibold tracking-tight first:mt-0",
className
)}
{...props}
/>
),
h3: ({ className, ...props }) => (
<h3
className={cn(
"mt-4 scroll-m-20 text-lg font-semibold tracking-tight",
className
)}
{...props}
/>
),
h4: ({ className, ...props }) => (
<h4
className={cn(
"mt-4 scroll-m-20 text-base font-semibold tracking-tight",
className
)}
{...props}
/>
),
p: ({ className, ...props }) => (
<p
className={cn("leading-7 [&:not(:first-child)]:mt-4", className)}
{...props}
/>
),
ul: ({ className, ...props }) => (
<ul className={cn("my-4 ml-6 list-disc [&>li]:mt-2", className)} {...props} />
),
ol: ({ className, ...props }) => (
<ol className={cn("my-4 ml-6 list-decimal [&>li]:mt-2", className)} {...props} />
),
li: ({ className, ...props }) => (
<li className={cn("mt-2", className)} {...props} />
),
blockquote: ({ className, ...props }) => (
<blockquote
className={cn(
"mt-4 border-l-2 border-primary pl-6 italic text-muted-foreground",
className
)}
{...props}
/>
),
img: ({ className, alt, ...props }) => (
// eslint-disable-next-line @next/next/no-img-element
<img
className={cn("rounded-md border bg-muted", className)}
alt={alt}
{...props}
/>
),
hr: ({ ...props }) => <hr className="my-4 md:my-6" {...props} />,
table: ({ className, ...props }) => (
<div className="my-4 w-full overflow-y-auto">
<table className={cn("w-full", className)} {...props} />
</div>
),
tr: ({ className, ...props }) => (
<tr
className={cn("m-0 border-t p-0 even:bg-muted", className)}
{...props}
/>
),
th: ({ className, ...props }) => (
<th
className={cn(
"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right",
className
)}
{...props}
/>
),
td: ({ className, ...props }) => (
<td
className={cn(
"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right",
className
)}
{...props}
/>
),
pre: ({ children }) => <>{children}</>,
code: ({ className, children, ...props }) => {
const match = /language-(\w+)/.exec(className || "");
const isInline = !match;
if (isInline) {
return (
<code
className={cn(
"relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold",
className
)}
{...props}
>
{children}
</code>
);
}
return (
<CodeBlock language={match[1]}>
{String(children).replace(/\n$/, "")}
</CodeBlock>
);
},
a: ({ className, ...props }) => (
<a
className={cn("font-medium underline underline-offset-4 text-primary hover:text-primary/80", className)}
target="_blank"
rel="noopener noreferrer"
{...props}
/>
),
};
</file>
<file path="components/chat/message-actions.tsx">
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Copy, FileJson, FileText, MoreHorizontal } from "lucide-react";
import { useState } from "react";
interface MessageActionsProps {
content: string;
role: string;
}
export function MessageActions({ content, role }: MessageActionsProps) {
const [copied, setCopied] = useState(false);
const handleCopy = (text: string) => {
navigator.clipboard.writeText(text);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
const copyMarkdown = () => handleCopy(content);
const copyText = () => {
// Simple strip markdown (can be improved with a library if needed)
const text = content
.replace(/#{1,6}\s/g, '') // Headers
.replace(/(\*\*|__)(.*?)\1/g, '$2') // Bold
.replace(/(\*|_)(.*?)\1/g, '$2') // Italic
.replace(/`{3}[\s\S]*?`{3}/g, '$&') // Keep code blocks but maybe strip fences? For now keep raw
.replace(/`(.+?)`/g, '$1') // Inline code
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1 ($2)') // Links
.replace(/>\s/g, ''); // Blockquotes
handleCopy(text);
};
const copyJson = () => {
const json = JSON.stringify({ role, content }, null, 2);
handleCopy(json);
};
return (
<div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
<Button
variant="ghost"
size="icon"
className="h-6 w-6"
onClick={copyMarkdown}
title="Copiar Markdown"
>
{copied ? (
<span className="text-green-500 text-xs font-bold">✓</span>
) : (
<Copy className="h-3.5 w-3.5 text-muted-foreground" />
)}
</Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon" className="h-6 w-6">
<MoreHorizontal className="h-3.5 w-3.5 text-muted-foreground" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={copyText}>
<FileText className="mr-2 h-4 w-4" />
<span>Copiar Texto Puro</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={copyJson}>
<FileJson className="mr-2 h-4 w-4" />
<span>Copiar JSON</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
);
}
</file>
<file path="components/chat/prompt-generator.tsx">
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Sparkles, Loader2 } from "lucide-react";
import { useState, useEffect } from "react";
import { usePromptGenerator } from "@/hooks/use-prompt-generator";
import { useLocalModels } from "@/hooks/use-local-models";
interface PromptGeneratorDialogProps {
defaultModel: string;
onPromptGenerated: (prompt: string) => void;
}
export function PromptGeneratorDialog({ defaultModel, onPromptGenerated }: PromptGeneratorDialogProps) {
const [open, setOpen] = useState(false);
const [goal, setGoal] = useState("");
const [selectedModel, setSelectedModel] = useState(defaultModel || "");
const { generatePrompt, isGenerating } = usePromptGenerator();
const { models, loading } = useLocalModels();
// Set default model when dialog opens or defaultModel changes
useEffect(() => {
if (defaultModel && defaultModel.trim()) {
setSelectedModel(defaultModel);
}
}, [defaultModel]);
// Try to set specific default if available and no model is selected
useEffect(() => {
if (loading || models.length === 0) return;
// Se já tem um modelo selecionado e válido, não alterar
if (selectedModel && models.some(m => m.name === selectedModel)) return;
// Primeiro, tenta usar o defaultModel se for válido
if (defaultModel && defaultModel.trim() && models.some(m => m.name === defaultModel)) {
setSelectedModel(defaultModel);
return;
}
// Fallback para modelo preferido
const preferredModel = "llama3.2-abliterate:3b";
const hasPreferred = models.some(m => m.name === preferredModel);
if (hasPreferred && !selectedModel.trim()) {
setSelectedModel(preferredModel);
return;
}
// Se nenhum modelo está selecionado, seleciona o primeiro disponível
if (!selectedModel.trim() && models.length > 0) {
setSelectedModel(models[0].name);
}
}, [models, loading, defaultModel, selectedModel]);
const handleGenerate = async () => {
if (!goal.trim() || !selectedModel.trim()) return;
try {
const prompt = await generatePrompt(goal, selectedModel);
onPromptGenerated(prompt);
setOpen(false);
setGoal("");
} catch (error) {
console.error("Erro ao gerar prompt:", error);
// TODO: Implementar toast de erro quando disponível
}
};
const handleCancel = () => {
setOpen(false);
setGoal("");
};
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="ghost" size="icon" className="h-6 w-6 text-yellow-500 hover:text-yellow-600 hover:bg-yellow-100 dark:hover:bg-yellow-900/20" title="Gerar com IA">
<Sparkles className="w-4 h-4" />
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle>Gerador de Prompts</DialogTitle>
<DialogDescription>
Descreva o que você quer que a IA faça, e nós criaremos um System Prompt otimizado para você.
</DialogDescription>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="space-y-2">
<label htmlFor="model-select" className="text-sm font-medium">
Modelo para Geração
</label>
<Select
value={selectedModel || undefined}
onValueChange={setSelectedModel}
disabled={loading || models.length === 0}
>
<SelectTrigger id="model-select">
<SelectValue placeholder={
loading
? "Carregando modelos..."
: models.length === 0
? "Nenhum modelo disponível"
: "Selecione um modelo..."
} />
</SelectTrigger>
<SelectContent>
{models.length === 0 ? (
<SelectItem value="" disabled>Nenhum modelo disponível</SelectItem>
) : (
models.map(m => (
<SelectItem key={m.name} value={m.name}>{m.name}</SelectItem>
))
)}
</SelectContent>
</Select>
<p className="text-xs text-muted-foreground">
Recomendado: Modelos com boa capacidade de instrução (ex: Llama 3, Mistral).
</p>
</div>
<div className="space-y-2">
<label htmlFor="goal-textarea" className="text-sm font-medium">
Seu Objetivo
</label>
<Textarea
id="goal-textarea"
value={goal}
onChange={(e) => setGoal(e.target.value)}
placeholder="Ex: Quero um assistente especialista em Python que explique conceitos complexos de forma simples..."
className="min-h-[150px]"
disabled={isGenerating}
/>
</div>
</div>
<DialogFooter>
<Button variant="ghost" onClick={handleCancel} disabled={isGenerating}>
Cancelar
</Button>
<Button
onClick={handleGenerate}
disabled={isGenerating || !goal.trim() || !selectedModel.trim() || models.length === 0}
>
{isGenerating ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Gerando...
</>
) : (
<>
<Sparkles className="mr-2 h-4 w-4" />
Gerar Prompt
</>
)}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
</file>
<file path="components/chat/system-panel.tsx">
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Progress } from "@/components/ui/progress";
import { Button } from "@/components/ui/button";
import { Trash2, HardDrive, Cpu, Database } from "lucide-react";
import { useSystemMonitor } from "@/hooks/use-system-monitor";
import { useLocalModels } from "@/hooks/use-local-models";
export function SystemPanel() {
const stats = useSystemMonitor();
const { models, deleteModel, refresh } = useLocalModels();
const ramUsagePercent = stats
? (stats.memory_used / stats.memory_total) * 100
: 0;
const formatBytes = (bytes: number) => {
const gb = bytes / (1024 * 1024 * 1024);
return `${gb.toFixed(1)} GB`;
};
return (
<div className="h-full overflow-y-auto p-4 space-y-6">
{/* Hardware Stats */}
<div className="space-y-4">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Monitoramento
</h3>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium flex items-center gap-2">
<Cpu className="w-4 h-4" /> Processador
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex justify-between text-xs mb-1">
<span>Uso</span>
<span>{stats?.cpu_usage.toFixed(1)}%</span>
</div>
<Progress value={stats?.cpu_usage || 0} className="h-2" />
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium flex items-center gap-2">
<HardDrive className="w-4 h-4" /> Memória RAM
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex justify-between text-xs mb-1">
<span>{stats ? formatBytes(stats.memory_used) : '-'}</span>
<span>{stats ? formatBytes(stats.memory_total) : '-'}</span>
</div>
<Progress value={ramUsagePercent} className="h-2" />
</CardContent>
</Card>
</div>
{/* Models List */}
<div className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Modelos Instalados
</h3>
<Button variant="ghost" size="sm" onClick={refresh} className="h-6 text-xs">
Atualizar
</Button>
</div>
<div className="space-y-2">
{models.map((model) => (
<Card key={model.id} className="overflow-hidden">
<CardContent className="p-3 flex items-center justify-between">
<div className="min-w-0">
<div className="font-medium text-sm truncate" title={model.name}>
{model.name}
</div>
<div className="text-xs text-muted-foreground flex items-center gap-2">
<Database className="w-3 h-3" />
{model.size}
</div>
</div>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-destructive hover:text-destructive hover:bg-destructive/10"
onClick={() => deleteModel(model.name)}
>
<Trash2 className="w-4 h-4" />
</Button>
</CardContent>
</Card>
))}
{models.length === 0 && (
<div className="text-center text-sm text-muted-foreground py-4">
Nenhum modelo encontrado.
</div>
)}
</div>
</div>
</div>
);
}
</file>
<file path="components/landing/hero.tsx">
import { Button } from "@/components/ui/button";
import { ArrowRight, Cpu } from "lucide-react";
export function Hero({ onStart }: { onStart: () => void }) {
return (
<div className="flex flex-col items-center justify-center min-h-[60vh] text-center px-4 space-y-6 animate-in fade-in zoom-in duration-500">
<div className="p-4 rounded-full bg-primary/10 animate-pulse">
<Cpu className="w-12 h-12 text-primary" />
</div>
<h1 className="text-4xl md:text-6xl font-bold tracking-tighter bg-clip-text text-transparent bg-gradient-to-r from-primary to-primary/60">
OllaHub
</h1>
<p className="text-lg md:text-xl text-muted-foreground max-w-[600px]">
Sua interface moderna e poderosa para interagir com Ollama e Modelos de Linguagem Locais.
</p>
<div className="flex gap-4 pt-4">
<Button size="lg" onClick={onStart} className="group text-lg px-8 h-12">
Iniciar Chat
<ArrowRight className="ml-2 w-5 h-5 transition-transform group-hover:translate-x-1" />
</Button>
</div>
</div>
);
}
</file>
<file path="components/landing/stopped-card.tsx">
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { RefreshCw, Copy, Check, Play, Loader2 } from "lucide-react"
import { useState } from "react"
import { invoke } from "@tauri-apps/api/core"
export function StoppedCard({ onCheckAgain }: { onCheckAgain: () => void }) {
const [copied, setCopied] = useState(false);
const [starting, setStarting] = useState(false);
const command = "ollama serve";
const handleCopy = () => {
navigator.clipboard.writeText(command);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
const handleStart = async () => {
setStarting(true);
try {
await invoke('start_ollama_server');
// Wait a bit for the server to start before checking again
setTimeout(() => {
onCheckAgain();
setStarting(false);
}, 3000);
} catch (error) {
console.error("Failed to start ollama:", error);
setStarting(false);
}
};
return (
<Card className="w-full max-w-md mx-auto border-yellow-500/50 bg-yellow-50/10 dark:bg-yellow-900/10">
<CardHeader>
<CardTitle className="text-yellow-600 dark:text-yellow-500">Ollama está parado</CardTitle>
<CardDescription>
O Ollama está instalado mas não está rodando. Você pode iniciá-lo automaticamente ou executar o comando manualmente.
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<Button
onClick={handleStart}
className="w-full bg-yellow-600 hover:bg-yellow-700 text-white"
disabled={starting}
>
{starting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Iniciando...
</>
) : (
<>
<Play className="mr-2 h-4 w-4" />
Iniciar Ollama Automaticamente
</>
)}
</Button>
<div className="relative">
<div className="absolute inset-0 flex items-center">
<span className="w-full border-t border-yellow-500/20" />
</div>
<div className="relative flex justify-center text-xs uppercase">
<span className="bg-background px-2 text-muted-foreground">Ou manualmente</span>
</div>
</div>
<div className="flex items-center space-x-2">
<div className="bg-muted p-3 rounded-md font-mono text-sm flex-1 border">
{command}
</div>
<Button size="icon" variant="outline" onClick={handleCopy}>
{copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
</Button>
</div>
<Button onClick={onCheckAgain} className="w-full" variant="secondary">
<RefreshCw className="mr-2 h-4 w-4" />
Verificar Novamente
</Button>
</CardContent>
</Card>
)
}
</file>
<file path="components/modals/install-modal.tsx">
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Button } from "@/components/ui/button"
import { Download } from "lucide-react"
interface InstallModalProps {
open: boolean;
onCheckAgain: () => void;
}
export function InstallModal({ open, onCheckAgain }: InstallModalProps) {
return (
<Dialog open={open}>
<DialogContent className="sm:max-w-[600px]">
<DialogHeader>
<DialogTitle>Ollama não encontrado</DialogTitle>
<DialogDescription>
Para usar o OllaHub, você precisa ter o Ollama instalado no seu sistema.
Siga os passos abaixo para o seu sistema operacional.
</DialogDescription>
</DialogHeader>
<Tabs defaultValue="mac" className="w-full">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="mac">macOS</TabsTrigger>
<TabsTrigger value="linux">Linux</TabsTrigger>
<TabsTrigger value="windows">Windows</TabsTrigger>
</TabsList>
<TabsContent value="mac" className="space-y-4 py-4">
<div className="space-y-2">
<h3 className="font-medium">1. Download e Instalação</h3>
<Button variant="outline" className="w-full" asChild>
<a href="https://ollama.com/download/Ollama-darwin.zip" target="_blank" rel="noopener noreferrer">
<Download className="mr-2 h-4 w-4" />
Baixar para macOS
</a>
</Button>
</div>
<div className="text-sm text-muted-foreground">
Após instalar, abra o terminal e digite <code>ollama serve</code> se necessário.
</div>
</TabsContent>
<TabsContent value="linux" className="space-y-4 py-4">
<div className="space-y-2">
<h3 className="font-medium">Instalação via Terminal</h3>
<div className="bg-muted p-4 rounded-md relative group">
<code className="text-sm break-all">curl -fsSL https://ollama.com/install.sh | sh</code>
</div>
</div>
<div className="space-y-2">
<h3 className="font-medium">Comando Manual</h3>
<div className="text-sm text-muted-foreground">
Ou consulte <a href="https://ollama.com/download/linux" className="underline text-primary" target="_blank" rel="noopener noreferrer">ollama.com/download/linux</a> para instruções manuais.
</div>
</div>
</TabsContent>
<TabsContent value="windows" className="space-y-4 py-4">
<div className="space-y-2">
<h3 className="font-medium">1. Download do Instalador</h3>
<Button variant="outline" className="w-full" asChild>
<a href="https://ollama.com/download/OllamaSetup.exe" target="_blank" rel="noopener noreferrer">
<Download className="mr-2 h-4 w-4" />
Baixar para Windows
</a>
</Button>
</div>
<div className="text-sm text-muted-foreground">
Execute o instalador baixado e siga as instruções na tela.
</div>
</TabsContent>
</Tabs>
<div className="flex justify-end gap-2 mt-4">
<Button onClick={onCheckAgain}>
Verificar Novamente
</Button>
</div>
</DialogContent>
</Dialog>
)
}
</file>
<file path="components/setup/hardware-scan.tsx">
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Progress } from "@/components/ui/progress";
import { Cpu, HardDrive, Laptop } from "lucide-react";
import { SystemSpecs } from "@/lib/recommendation";
import { useEffect, useState } from "react";
interface HardwareScanProps {
specs: SystemSpecs | null;
loading: boolean;
}
export function HardwareScan({ specs, loading }: HardwareScanProps) {
const [progress, setProgress] = useState(0);
useEffect(() => {
if (loading) {
const interval = setInterval(() => {
setProgress((prev) => (prev >= 90 ? 90 : prev + 10));
}, 150);
return () => clearInterval(interval);
} else {
setProgress(100);
}
}, [loading]);
if (loading) {
return (
<Card className="w-full max-w-md mx-auto border-primary/20">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Cpu className="animate-pulse text-primary" />
Analisando Hardware...
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<Progress value={progress} className="h-2" />
<p className="text-sm text-muted-foreground text-center">
Verificando memória e processador para recomendação ideal.
</p>
</CardContent>
</Card>
);
}
if (!specs) return null;
const ramGB = (specs.total_memory / (1024 * 1024 * 1024)).toFixed(1);
return (
<Card className="w-full max-w-md mx-auto bg-muted/30 animate-in fade-in slide-in-from-bottom-4">
<CardHeader>
<CardTitle className="flex items-center gap-2 text-lg">
<Laptop className="text-primary" />
Sistema Detectado
</CardTitle>
</CardHeader>
<CardContent className="grid grid-cols-2 gap-4">
<div className="flex flex-col items-center p-3 bg-background rounded-lg border">
<HardDrive className="w-6 h-6 mb-2 text-muted-foreground" />
<span className="text-xl font-bold">{ramGB} GB</span>
<span className="text-xs text-muted-foreground">RAM Total</span>
</div>
<div className="flex flex-col items-center p-3 bg-background rounded-lg border">
<Cpu className="w-6 h-6 mb-2 text-muted-foreground" />
<span className="text-xl font-bold">{specs.cpu_count}</span>
<span className="text-xs text-muted-foreground">Núcleos CPU</span>
</div>
</CardContent>
</Card>
);
}
</file>
<file path="components/setup/model-selector.tsx">
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Progress } from "@/components/ui/progress";
import { Badge } from "@/components/ui/badge";
import { Check, Download, Loader2, Play } from "lucide-react";
import { RECOMMENDED_MODELS, ModelRecommendation } from "@/lib/recommendation";
import { useState, useEffect } from "react";
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
interface ModelSelectorProps {
recommendation: ModelRecommendation;
onComplete: () => void;
}
export function ModelSelector({ recommendation, onComplete }: ModelSelectorProps) {
const [selectedModelId, setSelectedModelId] = useState(recommendation.modelId);
const [isInstalled, setIsInstalled] = useState(false);
const [isDownloading, setIsDownloading] = useState(false);
const [downloadProgress, setDownloadProgress] = useState(0);
const [downloadStatus, setDownloadStatus] = useState("");
const selectedModel = RECOMMENDED_MODELS.find(m => m.id === selectedModelId) || RECOMMENDED_MODELS[0];
useEffect(() => {
checkInstallation(selectedModelId);
}, [selectedModelId]);
useEffect(() => {
const unlisten = listen<string>('download-progress', (event) => {
const line = event.payload;
setDownloadStatus(line);
// Simple heuristic parsing for progress
// Ollama output example: "pulling manifest", "downloading 10%", "verifying sha256 digest"
if (line.includes('%')) {
const match = line.match(/(\d+)%/);
if (match) {
setDownloadProgress(parseInt(match[1], 10));
}
} else if (line.includes('success')) {
setDownloadProgress(100);
}
});
return () => {
unlisten.then(f => f());
};
}, []);
const checkInstallation = async (modelId: string) => {
try {
const installed = await invoke<boolean>('check_if_model_installed', { name: modelId });
setIsInstalled(installed);
} catch (e) {
console.error("Check failed", e);
}
};
const handleDownload = async () => {
setIsDownloading(true);
setDownloadProgress(0);
try {
await invoke('pull_model', { name: selectedModelId });
setIsInstalled(true);
setIsDownloading(false);
} catch (error) {
console.error("Download failed", error);
setDownloadStatus("Falha no download. Tente novamente.");
setIsDownloading(false);
}
};
return (
<Card className="w-full max-w-md mx-auto mt-6 border-primary shadow-lg">
<CardHeader>
<div className="flex justify-between items-start">
<div>
<CardTitle>Escolha seu Modelo</CardTitle>
<CardDescription>
{selectedModelId === recommendation.modelId
? "Baseado no seu hardware, recomendamos:"
: "Você selecionou um modelo personalizado:"}
</CardDescription>
</div>
{selectedModelId === recommendation.modelId && (
<Badge variant="secondary" className="bg-green-100 text-green-800 hover:bg-green-100 dark:bg-green-900 dark:text-green-100">
Recomendado
</Badge>
)}
</div>
</CardHeader>
<CardContent className="space-y-4">
<Select
value={selectedModelId}
onValueChange={setSelectedModelId}
disabled={isDownloading}
>
<SelectTrigger className="w-full h-14 text-lg">
<SelectValue placeholder="Selecione um modelo" />
</SelectTrigger>
<SelectContent>
{RECOMMENDED_MODELS.map((model) => (
<SelectItem key={model.id} value={model.id}>
<div className="flex flex-col items-start">
<span className="font-medium">{model.name}</span>
<span className="text-xs text-muted-foreground">{model.size} • Min RAM: {model.minRam}GB</span>
</div>
</SelectItem>
))}
</SelectContent>
</Select>
<div className="bg-muted/50 p-4 rounded-md text-sm">
<p className="font-medium mb-1">Sobre este modelo:</p>
<p className="text-muted-foreground">
{selectedModelId === recommendation.modelId
? recommendation.reason
: "Modelo alternativo selecionado. Certifique-se de ter memória suficiente."}
</p>
</div>
{isDownloading && (
<div className="space-y-2">
<div className="flex justify-between text-xs text-muted-foreground">
<span>{downloadStatus || "Iniciando..."}</span>
<span>{downloadProgress}%</span>
</div>
<Progress value={downloadProgress} className="h-2" />
</div>
)}
</CardContent>
<CardFooter>
{isInstalled ? (
<Button className="w-full h-12 text-lg" onClick={onComplete}>
Ir para o Chat
<Play className="ml-2 w-5 h-5" />
</Button>
) : (
<Button
className="w-full h-12 text-lg"
onClick={handleDownload}
disabled={isDownloading}
>
{isDownloading ? (
<>
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
Baixando...
</>
) : (
<>
<Download className="mr-2 h-5 w-5" />
Baixar e Instalar ({selectedModel.size})
</>
)}
</Button>
)}
</CardFooter>
</Card>
);
}
</file>
<file path="components/theme-provider.tsx">
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
export function ThemeProvider({
children,
...props
}: React.ComponentProps<typeof NextThemesProvider>) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
</file>
<file path="components/ui/badge.tsx">
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const badgeVariants = cva(
"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
{
variants: {
variant: {
default:
"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
secondary:
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
destructive:
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
},
},
defaultVariants: {
variant: "default",
},
}
)
function Badge({
className,
variant,
asChild = false,
...props
}: React.ComponentProps<"span"> &
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
const Comp = asChild ? Slot : "span"
return (
<Comp
data-slot="badge"
className={cn(badgeVariants({ variant }), className)}
{...props}
/>
)
}
export { Badge, badgeVariants }
</file>
<file path="components/ui/button.tsx">
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
icon: "size-9",
"icon-sm": "size-8",
"icon-lg": "size-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
function Button({
className,
variant,
size,
asChild = false,
...props
}: React.ComponentProps<"button"> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean
}) {
const Comp = asChild ? Slot : "button"
return (
<Comp
data-slot="button"
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
)
}
export { Button, buttonVariants }
</file>
<file path="components/ui/card.tsx">
import * as React from "react"
import { cn } from "@/lib/utils"
function Card({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card"
className={cn(
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
className
)}
{...props}
/>
)
}
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-header"
className={cn(
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
className
)}
{...props}
/>
)
}
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-title"
className={cn("leading-none font-semibold", className)}
{...props}
/>
)
}
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-description"
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
}
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-action"
className={cn(
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
className
)}
{...props}
/>
)
}
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-content"
className={cn("px-6", className)}
{...props}
/>
)
}
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-footer"
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
{...props}
/>
)
}
export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardAction,
CardDescription,
CardContent,
}
</file>
<file path="components/ui/dialog.tsx">
"use client"
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { XIcon } from "lucide-react"
import { cn } from "@/lib/utils"
function Dialog({
...props
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
return <DialogPrimitive.Root data-slot="dialog" {...props} />
}
function DialogTrigger({
...props
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
}
function DialogPortal({
...props
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
}
function DialogClose({
...props
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
}
function DialogOverlay({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
return (
<DialogPrimitive.Overlay
data-slot="dialog-overlay"
className={cn(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
className
)}
{...props}
/>
)
}
function DialogContent({
className,
children,
showCloseButton = true,
...props
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
showCloseButton?: boolean
}) {
return (
<DialogPortal data-slot="dialog-portal">
<DialogOverlay />
<DialogPrimitive.Content
data-slot="dialog-content"
className={cn(
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
className
)}
{...props}
>
{children}
{showCloseButton && (
<DialogPrimitive.Close
data-slot="dialog-close"
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
>
<XIcon />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
)}
</DialogPrimitive.Content>
</DialogPortal>
)
}
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="dialog-header"
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
{...props}
/>
)
}
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="dialog-footer"
className={cn(
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
className
)}
{...props}
/>
)
}
function DialogTitle({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn("text-lg leading-none font-semibold", className)}
{...props}
/>
)
}
function DialogDescription({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
return (
<DialogPrimitive.Description
data-slot="dialog-description"
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
}
export {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogOverlay,
DialogPortal,
DialogTitle,
DialogTrigger,
}
</file>
<file path="components/ui/dropdown-menu.tsx">
import * as React from "react"
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
import { Check, ChevronRight, Circle } from "lucide-react"
import { cn } from "@/lib/utils"
const DropdownMenu = DropdownMenuPrimitive.Root
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
const DropdownMenuGroup = DropdownMenuPrimitive.Group
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
const DropdownMenuSub = DropdownMenuPrimitive.Sub
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
const DropdownMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean
}
>(({ className, inset, children, ...props }, ref) => (
<DropdownMenuPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
inset && "pl-8",
className
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</DropdownMenuPrimitive.SubTrigger>
))
DropdownMenuSubTrigger.displayName =
DropdownMenuPrimitive.SubTrigger.displayName
const DropdownMenuSubContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
))
DropdownMenuSubContent.displayName =
DropdownMenuPrimitive.SubContent.displayName
const DropdownMenuContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
</DropdownMenuPrimitive.Portal>
))
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
const DropdownMenuItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className
)}
{...props}
/>
))
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
const DropdownMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
<DropdownMenuPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
checked={checked}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.CheckboxItem>
))
DropdownMenuCheckboxItem.displayName =
DropdownMenuPrimitive.CheckboxItem.displayName
const DropdownMenuRadioItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
<DropdownMenuPrimitive.RadioItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Circle className="h-2 w-2 fill-current" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.RadioItem>
))
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
const DropdownMenuLabel = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Label
ref={ref}
className={cn(
"px-2 py-1.5 text-sm font-semibold",
inset && "pl-8",
className
)}
{...props}
/>
))
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
const DropdownMenuSeparator = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
))
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
const DropdownMenuShortcut = ({
className,
...props
}: React.HTMLAttributes<HTMLSpanElement>) => {
return (
<span
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
{...props}
/>
)
}
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
export {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuCheckboxItem,
DropdownMenuRadioItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuGroup,
DropdownMenuPortal,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuRadioGroup,
}
</file>
<file path="components/ui/progress.tsx">
import * as React from "react"
import * as ProgressPrimitive from "@radix-ui/react-progress"
import { cn } from "@/lib/utils"
const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={cn(
"relative h-4 w-full overflow-hidden rounded-full bg-secondary",
className
)}
{...props}
>
<ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
))
Progress.displayName = ProgressPrimitive.Root.displayName
export { Progress }
</file>
<file path="components/ui/resizable.tsx">
import * as React from "react"
import { GripVertical } from "lucide-react"
import * as ResizablePrimitive from "react-resizable-panels"
import { cn } from "@/lib/utils"
const ResizablePanelGroup = ({
className,
...props
}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
<ResizablePrimitive.PanelGroup
className={cn(
"flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
className
)}
{...props}
/>
)
const ResizablePanel = ResizablePrimitive.Panel
const ResizableHandle = ({
withHandle,
className,
...props
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
withHandle?: boolean
}) => (
<ResizablePrimitive.PanelResizeHandle
className={cn(
"relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
className
)}
{...props}
>
{withHandle && (
<div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
<GripVertical className="h-2.5 w-2.5" />
</div>
)}
</ResizablePrimitive.PanelResizeHandle>
)
export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
</file>
<file path="components/ui/select.tsx">
import * as React from "react"
import * as SelectPrimitive from "@radix-ui/react-select"
import { Check, ChevronDown, ChevronUp } from "lucide-react"
import { cn } from "@/lib/utils"
const Select = SelectPrimitive.Root
const SelectGroup = SelectPrimitive.Group
const SelectValue = SelectPrimitive.Value
const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
))
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
))
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
))
SelectScrollDownButton.displayName =
SelectPrimitive.ScrollDownButton.displayName
const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
))
SelectContent.displayName = SelectPrimitive.Content.displayName
const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
{...props}
/>
))
SelectLabel.displayName = SelectPrimitive.Label.displayName
const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
))
SelectItem.displayName = SelectPrimitive.Item.displayName
const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
))
SelectSeparator.displayName = SelectPrimitive.Separator.displayName
export {
Select,
SelectGroup,
SelectValue,
SelectTrigger,
SelectContent,
SelectLabel,
SelectItem,
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
}
</file>
<file path="components/ui/separator.tsx">
"use client"
import * as React from "react"
import * as SeparatorPrimitive from "@radix-ui/react-separator"
import { cn } from "@/lib/utils"
function Separator({
className,
orientation = "horizontal",
decorative = true,
...props
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
return (
<SeparatorPrimitive.Root
data-slot="separator"
decorative={decorative}
orientation={orientation}
className={cn(
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
className
)}
{...props}
/>
)
}
export { Separator }
</file>
<file path="components/ui/tabs.tsx">
"use client"
import * as React from "react"
import * as TabsPrimitive from "@radix-ui/react-tabs"
import { cn } from "@/lib/utils"
function Tabs({
className,
...props
}: React.ComponentProps<typeof TabsPrimitive.Root>) {
return (
<TabsPrimitive.Root
data-slot="tabs"
className={cn("flex flex-col gap-2", className)}
{...props}
/>
)
}
function TabsList({
className,
...props
}: React.ComponentProps<typeof TabsPrimitive.List>) {
return (
<TabsPrimitive.List
data-slot="tabs-list"
className={cn(
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
className
)}
{...props}
/>
)
}
function TabsTrigger({
className,
...props
}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
return (
<TabsPrimitive.Trigger
data-slot="tabs-trigger"
className={cn(
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}
/>
)
}
function TabsContent({
className,
...props
}: React.ComponentProps<typeof TabsPrimitive.Content>) {
return (
<TabsPrimitive.Content
data-slot="tabs-content"
className={cn("flex-1 outline-none", className)}
{...props}
/>
)
}
export { Tabs, TabsList, TabsTrigger, TabsContent }
</file>
<file path="components/ui/textarea.tsx">
import * as React from "react"
import { cn } from "@/lib/utils"
const Textarea = React.forwardRef<
HTMLTextAreaElement,
React.ComponentProps<"textarea">
>(({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className
)}
ref={ref}
{...props}
/>
)
})
Textarea.displayName = "Textarea"
export { Textarea }
</file>
<file path="data/models/alfred.json">
{
"model": "alfred",
"url": "https://ollama.com/library/alfred",
"description": "A robust conversational model designed to be used for both chat and instruct use cases.",
"variantsCount": 2,
"variants": [
{
"name": "alfred:latest",
"size": "24GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "alfred:40b",
"size": "24GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/all-minilm.json">
{
"model": "all-minilm",
"url": "https://ollama.com/library/all-minilm",
"description": "Embedding models on very large sentence level datasets.",
"variantsCount": 3,
"variants": [
{
"name": "all-minilm:latest",
"size": "46MB",
"context": "512",
"inputType": "Text"
},
{
"name": "all-minilm:22m",
"size": "46MB",
"context": "512",
"inputType": "Text"
},
{
"name": "all-minilm:33m",
"size": "67MB",
"context": "512",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/athene-v2.json">
{
"model": "athene-v2",
"url": "https://ollama.com/library/athene-v2",
"description": "Athene-V2 is a 72B parameter model which excels at code completion, mathematics, and log extraction tasks.",
"variantsCount": 2,
"variants": [
{
"name": "athene-v2:latest",
"size": "47GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "athene-v2:72b",
"size": "47GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/aya-expanse.json">
{
"model": "aya-expanse",
"url": "https://ollama.com/library/aya-expanse",
"description": "Cohere For AI's language models trained to perform well across 23 different languages.",
"variantsCount": 3,
"variants": [
{
"name": "aya-expanse:latest",
"size": "5.1GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "aya-expanse:8b",
"size": "5.1GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "aya-expanse:32b",
"size": "20GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/aya.json">
{
"model": "aya",
"url": "https://ollama.com/library/aya",
"description": "Aya 23, released by Cohere, is a new family of state-of-the-art, multilingual models that support 23 languages. ",
"variantsCount": 3,
"variants": [
{
"name": "aya:latest",
"size": "4.8GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "aya:8b",
"size": "4.8GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "aya:35b",
"size": "20GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/bakllava.json">
{
"model": "bakllava",
"url": "https://ollama.com/library/bakllava",
"description": "BakLLaVA is a multimodal model consisting of the Mistral 7B base model augmented with the LLaVA architecture.",
"variantsCount": 2,
"variants": [
{
"name": "bakllava:latest",
"size": "4.7GB",
"context": "32K",
"inputType": "Text, Image"
},
{
"name": "bakllava:7b",
"size": "4.7GB",
"context": "32K",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/bespoke-minicheck.json">
{
"model": "bespoke-minicheck",
"url": "https://ollama.com/library/bespoke-minicheck",
"description": "A state-of-the-art fact-checking model developed by Bespoke Labs.",
"variantsCount": 2,
"variants": [
{
"name": "bespoke-minicheck:latest",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "bespoke-minicheck:7b",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/bge-large.json">
{
"model": "bge-large",
"url": "https://ollama.com/library/bge-large",
"description": "Embedding model from BAAI mapping texts to vectors.",
"variantsCount": 2,
"variants": [
{
"name": "bge-large:latest",
"size": "671MB",
"context": "512",
"inputType": "Text"
},
{
"name": "bge-large:335m",
"size": "671MB",
"context": "512",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/bge-m3.json">
{
"model": "bge-m3",
"url": "https://ollama.com/library/bge-m3",
"description": "BGE-M3 is a new model from BAAI distinguished for its versatility in Multi-Functionality, Multi-Linguality, and Multi-Granularity.",
"variantsCount": 2,
"variants": [
{
"name": "bge-m3:latest",
"size": "1.2GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "bge-m3:567m",
"size": "1.2GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/codebooga.json">
{
"model": "codebooga",
"url": "https://ollama.com/library/codebooga",
"description": "A high-performing code instruct model created by merging two existing code models.",
"variantsCount": 2,
"variants": [
{
"name": "codebooga:latest",
"size": "19GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "codebooga:34b",
"size": "19GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/codegeex4.json">
{
"model": "codegeex4",
"url": "https://ollama.com/library/codegeex4",
"description": "A versatile model for AI software development scenarios, including code completion.",
"variantsCount": 2,
"variants": [
{
"name": "codegeex4:latest",
"size": "5.5GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "codegeex4:9b",
"size": "5.5GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/codegemma.json">
{
"model": "codegemma",
"url": "https://ollama.com/library/codegemma",
"description": "CodeGemma is a collection of powerful, lightweight models that can perform a variety of coding tasks like fill-in-the-middle code completion, code generation, natural language understanding, mathematical reasoning, and instruction following.",
"variantsCount": 3,
"variants": [
{
"name": "codegemma:latest",
"size": "5.0GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "codegemma:2b",
"size": "1.6GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "codegemma:7b",
"size": "5.0GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/codellama.json">
{
"model": "codellama",
"url": "https://ollama.com/library/codellama",
"description": "A large language model that can use text prompts to generate and discuss code.",
"variantsCount": 5,
"variants": [
{
"name": "codellama:latest",
"size": "3.8GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "codellama:7b",
"size": "3.8GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "codellama:13b",
"size": "7.4GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "codellama:34b",
"size": "19GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "codellama:70b",
"size": "39GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/codeqwen.json">
{
"model": "codeqwen",
"url": "https://ollama.com/library/codeqwen",
"description": "CodeQwen1.5 is a large language model pretrained on a large amount of code data.",
"variantsCount": 2,
"variants": [
{
"name": "codeqwen:latest",
"size": "4.2GB",
"context": "64K",
"inputType": "Text"
},
{
"name": "codeqwen:7b",
"size": "4.2GB",
"context": "64K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/codestral.json">
{
"model": "codestral",
"url": "https://ollama.com/library/codestral",
"description": "Codestral is Mistral AI’s first-ever code model designed for code generation tasks.",
"variantsCount": 2,
"variants": [
{
"name": "codestral:latest",
"size": "13GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "codestral:22b",
"size": "13GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/codeup.json">
{
"model": "codeup",
"url": "https://ollama.com/library/codeup",
"description": "Great code generation model based on Llama2.",
"variantsCount": 2,
"variants": [
{
"name": "codeup:latest",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "codeup:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/cogito.json">
{
"model": "cogito",
"url": "https://ollama.com/library/cogito",
"description": "Cogito v1 Preview is a family of hybrid reasoning models by Deep Cogito that outperform the best available open models of the same size, including counterparts from LLaMA, DeepSeek, and Qwen across most standard benchmarks.",
"variantsCount": 6,
"variants": [
{
"name": "cogito:latest",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "cogito:3b",
"size": "2.2GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "cogito:8b",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "cogito:14b",
"size": "9.0GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "cogito:32b",
"size": "20GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "cogito:70b",
"size": "43GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/command-a.json">
{
"model": "command-a",
"url": "https://ollama.com/library/command-a",
"description": "111 billion parameter model optimized for demanding enterprises that require fast, secure, and high-quality AI",
"variantsCount": 2,
"variants": [
{
"name": "command-a:latest",
"size": "67GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "command-a:111b",
"size": "67GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/command-r-plus.json">
{
"model": "command-r-plus",
"url": "https://ollama.com/library/command-r-plus",
"description": "Command R+ is a powerful, scalable large language model purpose-built to excel at real-world enterprise use cases.",
"variantsCount": 2,
"variants": [
{
"name": "command-r-plus:latest",
"size": "59GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "command-r-plus:104b",
"size": "59GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/command-r.json">
{
"model": "command-r",
"url": "https://ollama.com/library/command-r",
"description": "Command R is a Large Language Model optimized for conversational interaction and long context tasks.",
"variantsCount": 2,
"variants": [
{
"name": "command-r:latest",
"size": "19GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "command-r:35b",
"size": "19GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/command-r7b-arabic.json">
{
"model": "command-r7b-arabic",
"url": "https://ollama.com/library/command-r7b-arabic",
"description": "A new state-of-the-art version of the lightweight Command R7B model that excels in advanced Arabic language capabilities for enterprises in the Middle East and Northern Africa.",
"variantsCount": 2,
"variants": [
{
"name": "command-r7b-arabic:latest",
"size": "5.1GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "command-r7b-arabic:7b",
"size": "5.1GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/command-r7b.json">
{
"model": "command-r7b",
"url": "https://ollama.com/library/command-r7b",
"description": "The smallest model in Cohere's R series delivers top-tier speed, efficiency, and quality to build powerful AI applications on commodity GPUs and edge devices.",
"variantsCount": 2,
"variants": [
{
"name": "command-r7b:latest",
"size": "5.1GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "command-r7b:7b",
"size": "5.1GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/dbrx.json">
{
"model": "dbrx",
"url": "https://ollama.com/library/dbrx",
"description": "DBRX is an open, general-purpose LLM created by Databricks.",
"variantsCount": 2,
"variants": [
{
"name": "dbrx:latest",
"size": "74GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "dbrx:132b",
"size": "74GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepcoder.json">
{
"model": "deepcoder",
"url": "https://ollama.com/library/deepcoder",
"description": "DeepCoder is a fully open-Source 14B coder model at O3-mini level, with a 1.5B version also available.",
"variantsCount": 3,
"variants": [
{
"name": "deepcoder:latest",
"size": "9.0GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepcoder:1.5b",
"size": "1.1GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepcoder:14b",
"size": "9.0GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepscaler.json">
{
"model": "deepscaler",
"url": "https://ollama.com/library/deepscaler",
"description": "A fine-tuned version of Deepseek-R1-Distilled-Qwen-1.5B that surpasses the performance of OpenAI’s o1-preview with just 1.5B parameters on popular math evaluations.",
"variantsCount": 2,
"variants": [
{
"name": "deepscaler:latest",
"size": "3.6GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepscaler:1.5b",
"size": "3.6GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepseek-coder-v2.json">
{
"model": "deepseek-coder-v2",
"url": "https://ollama.com/library/deepseek-coder-v2",
"description": "An open-source Mixture-of-Experts code language model that achieves performance comparable to GPT4-Turbo in code-specific tasks.",
"variantsCount": 3,
"variants": [
{
"name": "deepseek-coder-v2:latest",
"size": "8.9GB",
"context": "160K",
"inputType": "Text"
},
{
"name": "deepseek-coder-v2:16b",
"size": "8.9GB",
"context": "160K",
"inputType": "Text"
},
{
"name": "deepseek-coder-v2:236b",
"size": "133GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepseek-coder.json">
{
"model": "deepseek-coder",
"url": "https://ollama.com/library/deepseek-coder",
"description": "DeepSeek Coder is a capable coding model trained on two trillion code and natural language tokens.",
"variantsCount": 4,
"variants": [
{
"name": "deepseek-coder:latest",
"size": "776MB",
"context": "16K",
"inputType": "Text"
},
{
"name": "deepseek-coder:1.3b",
"size": "776MB",
"context": "16K",
"inputType": "Text"
},
{
"name": "deepseek-coder:6.7b",
"size": "3.8GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "deepseek-coder:33b",
"size": "19GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepseek-llm.json">
{
"model": "deepseek-llm",
"url": "https://ollama.com/library/deepseek-llm",
"description": "An advanced language model crafted with 2 trillion bilingual tokens.",
"variantsCount": 3,
"variants": [
{
"name": "deepseek-llm:latest",
"size": "4.0GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "deepseek-llm:7b",
"size": "4.0GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "deepseek-llm:67b",
"size": "38GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepseek-r1.json">
{
"model": "deepseek-r1",
"url": "https://ollama.com/library/deepseek-r1",
"description": "DeepSeek-R1 is a family of open reasoning models with performance approaching that of leading models, such as O3 and Gemini 2.5 Pro.",
"variantsCount": 8,
"variants": [
{
"name": "deepseek-r1:latest",
"size": "5.2GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepseek-r1:1.5b",
"size": "1.1GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepseek-r1:7b",
"size": "4.7GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepseek-r1:8b",
"size": "5.2GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepseek-r1:14b",
"size": "9.0GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepseek-r1:32b",
"size": "20GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepseek-r1:70b",
"size": "43GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "deepseek-r1:671b",
"size": "404GB",
"context": "160K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepseek-v2.5.json">
{
"model": "deepseek-v2.5",
"url": "https://ollama.com/library/deepseek-v2.5",
"description": "An upgraded version of DeekSeek-V2 that integrates the general and coding abilities of both DeepSeek-V2-Chat and DeepSeek-Coder-V2-Instruct.",
"variantsCount": 2,
"variants": [
{
"name": "deepseek-v2.5:latest",
"size": "133GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "deepseek-v2.5:236b",
"size": "133GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepseek-v2.json">
{
"model": "deepseek-v2",
"url": "https://ollama.com/library/deepseek-v2",
"description": "A strong, economical, and efficient Mixture-of-Experts language model.",
"variantsCount": 3,
"variants": [
{
"name": "deepseek-v2:latest",
"size": "8.9GB",
"context": "160K",
"inputType": "Text"
},
{
"name": "deepseek-v2:16b",
"size": "8.9GB",
"context": "160K",
"inputType": "Text"
},
{
"name": "deepseek-v2:236b",
"size": "133GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepseek-v3.1.json">
{
"model": "deepseek-v3.1",
"url": "https://ollama.com/library/deepseek-v3.1",
"description": "DeepSeek-V3.1-Terminus is a hybrid model that supports both thinking mode and non-thinking mode.",
"variantsCount": 3,
"variants": [
{
"name": "deepseek-v3.1:latest",
"size": "404GB",
"context": "160K",
"inputType": "Text"
},
{
"name": "deepseek-v3.1:671b",
"size": "404GB",
"context": "160K",
"inputType": "Text"
},
{
"name": "deepseek-v3.1:671b-cloud",
"size": "-",
"context": "160K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/deepseek-v3.json">
{
"model": "deepseek-v3",
"url": "https://ollama.com/library/deepseek-v3",
"description": "A strong Mixture-of-Experts (MoE) language model with 671B total parameters with 37B activated for each token.",
"variantsCount": 2,
"variants": [
{
"name": "deepseek-v3:latest",
"size": "404GB",
"context": "160K",
"inputType": "Text"
},
{
"name": "deepseek-v3:671b",
"size": "404GB",
"context": "160K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/devstral.json">
{
"model": "devstral",
"url": "https://ollama.com/library/devstral",
"description": "Devstral: the best open source model for coding agents",
"variantsCount": 2,
"variants": [
{
"name": "devstral:latest",
"size": "14GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "devstral:24b",
"size": "14GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/dolphin-llama3.json">
{
"model": "dolphin-llama3",
"url": "https://ollama.com/library/dolphin-llama3",
"description": "Dolphin 2.9 is a new model with 8B and 70B sizes by Eric Hartford based on Llama 3 that has a variety of instruction, conversational, and coding skills.",
"variantsCount": 3,
"variants": [
{
"name": "dolphin-llama3:latest",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "dolphin-llama3:8b",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "dolphin-llama3:70b",
"size": "40GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/dolphin-mistral.json">
{
"model": "dolphin-mistral",
"url": "https://ollama.com/library/dolphin-mistral",
"description": "The uncensored Dolphin model based on Mistral that excels at coding tasks. Updated to version 2.8.",
"variantsCount": 2,
"variants": [
{
"name": "dolphin-mistral:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "dolphin-mistral:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/dolphin-mixtral.json">
{
"model": "dolphin-mixtral",
"url": "https://ollama.com/library/dolphin-mixtral",
"description": "Uncensored, 8x7b and 8x22b fine-tuned models based on the Mixtral mixture of experts models that excels at coding tasks. Created by Eric Hartford.",
"variantsCount": 3,
"variants": [
{
"name": "dolphin-mixtral:latest",
"size": "26GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "dolphin-mixtral:8x7b",
"size": "26GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "dolphin-mixtral:8x22b",
"size": "80GB",
"context": "64K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/dolphin-phi.json">
{
"model": "dolphin-phi",
"url": "https://ollama.com/library/dolphin-phi",
"description": "2.7B uncensored Dolphin model by Eric Hartford, based on the Phi language model by Microsoft Research.",
"variantsCount": 2,
"variants": [
{
"name": "dolphin-phi:latest",
"size": "1.6GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "dolphin-phi:2.7b",
"size": "1.6GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/dolphin3.json">
{
"model": "dolphin3",
"url": "https://ollama.com/library/dolphin3",
"description": "Dolphin 3.0 Llama 3.1 8B 🐬 is the next generation of the Dolphin series of instruct-tuned models designed to be the ultimate general purpose local model, enabling coding, math, agentic, function calling, and general use cases.",
"variantsCount": 2,
"variants": [
{
"name": "dolphin3:latest",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "dolphin3:8b",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/dolphincoder.json">
{
"model": "dolphincoder",
"url": "https://ollama.com/library/dolphincoder",
"description": "A 7B and 15B uncensored variant of the Dolphin model family that excels at coding, based on StarCoder2.",
"variantsCount": 3,
"variants": [
{
"name": "dolphincoder:latest",
"size": "4.2GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "dolphincoder:7b",
"size": "4.2GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "dolphincoder:15b",
"size": "9.1GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/duckdb-nsql.json">
{
"model": "duckdb-nsql",
"url": "https://ollama.com/library/duckdb-nsql",
"description": "7B parameter text-to-SQL model made by MotherDuck and Numbers Station.",
"variantsCount": 2,
"variants": [
{
"name": "duckdb-nsql:latest",
"size": "3.8GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "duckdb-nsql:7b",
"size": "3.8GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/embeddinggemma.json">
{
"model": "embeddinggemma",
"url": "https://ollama.com/library/embeddinggemma",
"description": "EmbeddingGemma is a 300M parameter embedding model from Google.",
"variantsCount": 2,
"variants": [
{
"name": "embeddinggemma:latest",
"size": "622MB",
"context": "2K",
"inputType": "Text"
},
{
"name": "embeddinggemma:300m",
"size": "622MB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/everythinglm.json">
{
"model": "everythinglm",
"url": "https://ollama.com/library/everythinglm",
"description": "Uncensored Llama2 based model with support for a 16K context window.",
"variantsCount": 2,
"variants": [
{
"name": "everythinglm:latest",
"size": "7.4GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "everythinglm:13b",
"size": "7.4GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/exaone-deep.json">
{
"model": "exaone-deep",
"url": "https://ollama.com/library/exaone-deep",
"description": "EXAONE Deep exhibits superior capabilities in various reasoning tasks including math and coding benchmarks, ranging from 2.4B to 32B parameters developed and released by LG AI Research.",
"variantsCount": 4,
"variants": [
{
"name": "exaone-deep:latest",
"size": "4.8GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "exaone-deep:2.4b",
"size": "1.6GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "exaone-deep:7.8b",
"size": "4.8GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "exaone-deep:32b",
"size": "19GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/exaone3.5.json">
{
"model": "exaone3.5",
"url": "https://ollama.com/library/exaone3.5",
"description": "EXAONE 3.5 is a collection of instruction-tuned bilingual (English and Korean) generative models ranging from 2.4B to 32B parameters, developed and released by LG AI Research. ",
"variantsCount": 4,
"variants": [
{
"name": "exaone3.5:latest",
"size": "4.8GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "exaone3.5:2.4b",
"size": "1.6GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "exaone3.5:7.8b",
"size": "4.8GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "exaone3.5:32b",
"size": "19GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/falcon.json">
{
"model": "falcon",
"url": "https://ollama.com/library/falcon",
"description": "A large language model built by the Technology Innovation Institute (TII) for use in summarization, text generation, and chat bots.",
"variantsCount": 4,
"variants": [
{
"name": "falcon:latest",
"size": "4.2GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "falcon:7b",
"size": "4.2GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "falcon:40b",
"size": "24GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "falcon:180b",
"size": "101GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/falcon2.json">
{
"model": "falcon2",
"url": "https://ollama.com/library/falcon2",
"description": "Falcon2 is an 11B parameters causal decoder-only model built by TII and trained over 5T tokens.",
"variantsCount": 2,
"variants": [
{
"name": "falcon2:latest",
"size": "6.4GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "falcon2:11b",
"size": "6.4GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/falcon3.json">
{
"model": "falcon3",
"url": "https://ollama.com/library/falcon3",
"description": "A family of efficient AI models under 10B parameters performant in science, math, and coding through innovative training techniques.",
"variantsCount": 5,
"variants": [
{
"name": "falcon3:latest",
"size": "4.6GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "falcon3:1b",
"size": "1.8GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "falcon3:3b",
"size": "2.0GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "falcon3:7b",
"size": "4.6GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "falcon3:10b",
"size": "6.3GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/firefunction-v2.json">
{
"model": "firefunction-v2",
"url": "https://ollama.com/library/firefunction-v2",
"description": "An open weights function calling model based on Llama 3, competitive with GPT-4o function calling capabilities.",
"variantsCount": 2,
"variants": [
{
"name": "firefunction-v2:latest",
"size": "40GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "firefunction-v2:70b",
"size": "40GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/gemini-3-pro-preview.json">
{
"model": "gemini-3-pro-preview",
"url": "https://ollama.com/library/gemini-3-pro-preview",
"description": "Google's most intelligent model with SOTA reasoning and multimodal understanding, and powerful agentic and vibe coding capabilities.",
"variantsCount": 1,
"variants": [
{
"name": "gemini-3-pro-preview:latest",
"size": "-",
"context": "1M",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/gemma.json">
{
"model": "gemma",
"url": "https://ollama.com/library/gemma",
"description": "Gemma is a family of lightweight, state-of-the-art open models built by Google DeepMind. Updated to version 1.1",
"variantsCount": 3,
"variants": [
{
"name": "gemma:latest",
"size": "5.0GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "gemma:2b",
"size": "1.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "gemma:7b",
"size": "5.0GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/gemma2.json">
{
"model": "gemma2",
"url": "https://ollama.com/library/gemma2",
"description": "Google Gemma 2 is a high-performing and efficient model available in three sizes: 2B, 9B, and 27B.",
"variantsCount": 4,
"variants": [
{
"name": "gemma2:latest",
"size": "5.4GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "gemma2:2b",
"size": "1.6GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "gemma2:9b",
"size": "5.4GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "gemma2:27b",
"size": "16GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/gemma3.json">
{
"model": "gemma3",
"url": "https://ollama.com/library/gemma3",
"description": "The current, most capable model that runs on a single GPU.",
"variantsCount": 6,
"variants": [
{
"name": "gemma3:latest",
"size": "3.3GB",
"context": "128K",
"inputType": "Text, Image"
},
{
"name": "gemma3:270m",
"size": "292MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "gemma3:1b",
"size": "815MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "gemma3:4b",
"size": "3.3GB",
"context": "128K",
"inputType": "Text, Image"
},
{
"name": "gemma3:12b",
"size": "8.1GB",
"context": "128K",
"inputType": "Text, Image"
},
{
"name": "gemma3:27b",
"size": "17GB",
"context": "128K",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/gemma3n.json">
{
"model": "gemma3n",
"url": "https://ollama.com/library/gemma3n",
"description": "Gemma 3n models are designed for efficient execution on everyday devices such as laptops, tablets or phones. ",
"variantsCount": 3,
"variants": [
{
"name": "gemma3n:latest",
"size": "7.5GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "gemma3n:e2b",
"size": "5.6GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "gemma3n:e4b",
"size": "7.5GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/glm-4.6.json">
{
"model": "glm-4.6",
"url": "https://ollama.com/library/glm-4.6",
"description": "Advanced agentic, reasoning and coding capabilities.",
"variantsCount": 1,
"variants": [
{
"name": "glm-4.6:cloud",
"size": "-",
"context": "198K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/glm4.json">
{
"model": "glm4",
"url": "https://ollama.com/library/glm4",
"description": "A strong multi-lingual general language model with competitive performance to Llama 3.",
"variantsCount": 2,
"variants": [
{
"name": "glm4:latest",
"size": "5.5GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "glm4:9b",
"size": "5.5GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/goliath.json">
{
"model": "goliath",
"url": "https://ollama.com/library/goliath",
"description": "A language model created by combining two fine-tuned Llama 2 70B models into one.",
"variantsCount": 16,
"variants": [
{
"name": "goliath:latest",
"size": "66GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q2_K",
"size": "50GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q3_K_S",
"size": "51GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q3_K_M",
"size": "56GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q3_K_L",
"size": "62GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q4_0",
"size": "66GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q4_1",
"size": "74GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q4_K_S",
"size": "66GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q4_K_M",
"size": "71GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q5_0",
"size": "81GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q5_1",
"size": "88GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q5_K_S",
"size": "81GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q5_K_M",
"size": "83GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q6_K",
"size": "97GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-q8_0",
"size": "125GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "goliath:120b-fp16",
"size": "236GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/gpt-oss-safeguard.json">
{
"model": "gpt-oss-safeguard",
"url": "https://ollama.com/library/gpt-oss-safeguard",
"description": "gpt-oss-safeguard-20b and gpt-oss-safeguard-120b are safety reasoning models built-upon gpt-oss",
"variantsCount": 3,
"variants": [
{
"name": "gpt-oss-safeguard:latest",
"size": "14GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "gpt-oss-safeguard:20b",
"size": "14GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "gpt-oss-safeguard:120b",
"size": "65GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/gpt-oss.json">
{
"model": "gpt-oss",
"url": "https://ollama.com/library/gpt-oss",
"description": "OpenAI’s open-weight models designed for powerful reasoning, agentic tasks, and versatile developer use cases.",
"variantsCount": 5,
"variants": [
{
"name": "gpt-oss:latest",
"size": "14GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "gpt-oss:20b",
"size": "14GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "gpt-oss:120b",
"size": "65GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "gpt-oss:20b-cloud",
"size": "-",
"context": "128K",
"inputType": "Text"
},
{
"name": "gpt-oss:120b-cloud",
"size": "-",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite-code.json">
{
"model": "granite-code",
"url": "https://ollama.com/library/granite-code",
"description": "A family of open foundation models by IBM for Code Intelligence",
"variantsCount": 5,
"variants": [
{
"name": "granite-code:latest",
"size": "2.0GB",
"context": "125K",
"inputType": "Text"
},
{
"name": "granite-code:3b",
"size": "2.0GB",
"context": "125K",
"inputType": "Text"
},
{
"name": "granite-code:8b",
"size": "4.6GB",
"context": "125K",
"inputType": "Text"
},
{
"name": "granite-code:20b",
"size": "12GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "granite-code:34b",
"size": "19GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite-embedding.json">
{
"model": "granite-embedding",
"url": "https://ollama.com/library/granite-embedding",
"description": "The IBM Granite Embedding 30M and 278M models models are text-only dense biencoder embedding models, with 30M available in English only and 278M serving multilingual use cases.",
"variantsCount": 3,
"variants": [
{
"name": "granite-embedding:latest",
"size": "63MB",
"context": "512",
"inputType": "Text"
},
{
"name": "granite-embedding:30m",
"size": "63MB",
"context": "512",
"inputType": "Text"
},
{
"name": "granite-embedding:278m",
"size": "563MB",
"context": "512",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite3-dense.json">
{
"model": "granite3-dense",
"url": "https://ollama.com/library/granite3-dense",
"description": "The IBM Granite 2B and 8B models are designed to support tool-based use cases and support for retrieval augmented generation (RAG), streamlining code generation, translation and bug fixing.",
"variantsCount": 3,
"variants": [
{
"name": "granite3-dense:latest",
"size": "1.6GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "granite3-dense:2b",
"size": "1.6GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "granite3-dense:8b",
"size": "4.9GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite3-guardian.json">
{
"model": "granite3-guardian",
"url": "https://ollama.com/library/granite3-guardian",
"description": "The IBM Granite Guardian 3.0 2B and 8B models are designed to detect risks in prompts and/or responses.",
"variantsCount": 3,
"variants": [
{
"name": "granite3-guardian:latest",
"size": "2.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "granite3-guardian:2b",
"size": "2.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "granite3-guardian:8b",
"size": "5.8GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite3-moe.json">
{
"model": "granite3-moe",
"url": "https://ollama.com/library/granite3-moe",
"description": "The IBM Granite 1B and 3B models are the first mixture of experts (MoE) Granite models from IBM designed for low latency usage.",
"variantsCount": 3,
"variants": [
{
"name": "granite3-moe:latest",
"size": "822MB",
"context": "4K",
"inputType": "Text"
},
{
"name": "granite3-moe:1b",
"size": "822MB",
"context": "4K",
"inputType": "Text"
},
{
"name": "granite3-moe:3b",
"size": "2.1GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite3.1-dense.json">
{
"model": "granite3.1-dense",
"url": "https://ollama.com/library/granite3.1-dense",
"description": "The IBM Granite 2B and 8B models are text-only dense LLMs trained on over 12 trillion tokens of data, demonstrated significant improvements over their predecessors in performance and speed in IBM’s initial testing.",
"variantsCount": 3,
"variants": [
{
"name": "granite3.1-dense:latest",
"size": "5.0GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite3.1-dense:2b",
"size": "1.6GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite3.1-dense:8b",
"size": "5.0GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite3.1-moe.json">
{
"model": "granite3.1-moe",
"url": "https://ollama.com/library/granite3.1-moe",
"description": "The IBM Granite 1B and 3B models are long-context mixture of experts (MoE) Granite models from IBM designed for low latency usage.",
"variantsCount": 3,
"variants": [
{
"name": "granite3.1-moe:latest",
"size": "2.0GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite3.1-moe:1b",
"size": "1.4GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite3.1-moe:3b",
"size": "2.0GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite3.2-vision.json">
{
"model": "granite3.2-vision",
"url": "https://ollama.com/library/granite3.2-vision",
"description": "A compact and efficient vision-language model, specifically designed for visual document understanding, enabling automated content extraction from tables, charts, infographics, plots, diagrams, and more.",
"variantsCount": 2,
"variants": [
{
"name": "granite3.2-vision:latest",
"size": "2.4GB",
"context": "16K",
"inputType": "Text, Image"
},
{
"name": "granite3.2-vision:2b",
"size": "2.4GB",
"context": "16K",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/granite3.2.json">
{
"model": "granite3.2",
"url": "https://ollama.com/library/granite3.2",
"description": "Granite-3.2 is a family of long-context AI models from IBM Granite fine-tuned for thinking capabilities.",
"variantsCount": 3,
"variants": [
{
"name": "granite3.2:latest",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite3.2:2b",
"size": "1.5GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite3.2:8b",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite3.3.json">
{
"model": "granite3.3",
"url": "https://ollama.com/library/granite3.3",
"description": "IBM Granite 2B and 8B models are 128K context length language models that have been fine-tuned for improved reasoning and instruction-following capabilities.",
"variantsCount": 3,
"variants": [
{
"name": "granite3.3:latest",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite3.3:2b",
"size": "1.5GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite3.3:8b",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/granite4.json">
{
"model": "granite4",
"url": "https://ollama.com/library/granite4",
"description": "Granite 4 features improved instruction following (IF) and tool-calling capabilities, making them more effective in enterprise applications.",
"variantsCount": 4,
"variants": [
{
"name": "granite4:latest",
"size": "2.1GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite4:350m",
"size": "708MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "granite4:1b",
"size": "3.3GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "granite4:3b",
"size": "2.1GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/hermes3.json">
{
"model": "hermes3",
"url": "https://ollama.com/library/hermes3",
"description": "Hermes 3 is the latest version of the flagship Hermes series of LLMs by Nous Research",
"variantsCount": 5,
"variants": [
{
"name": "hermes3:latest",
"size": "4.7GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "hermes3:3b",
"size": "2.0GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "hermes3:8b",
"size": "4.7GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "hermes3:70b",
"size": "40GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "hermes3:405b",
"size": "229GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/internlm2.json">
{
"model": "internlm2",
"url": "https://ollama.com/library/internlm2",
"description": "InternLM2.5 is a 7B parameter model tailored for practical scenarios with outstanding reasoning capability.",
"variantsCount": 5,
"variants": [
{
"name": "internlm2:latest",
"size": "4.5GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "internlm2:1m",
"size": "4.5GB",
"context": "256K",
"inputType": "Text"
},
{
"name": "internlm2:1.8b",
"size": "1.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "internlm2:7b",
"size": "4.5GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "internlm2:20b",
"size": "11GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/kimi-k2-thinking.json">
{
"model": "kimi-k2-thinking",
"url": "https://ollama.com/library/kimi-k2-thinking",
"description": "Kimi K2 Thinking, Moonshot AI's best open-source thinking model.",
"variantsCount": 1,
"variants": [
{
"name": "kimi-k2-thinking:cloud",
"size": "-",
"context": "256K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/kimi-k2.json">
{
"model": "kimi-k2",
"url": "https://ollama.com/library/kimi-k2",
"description": "A state-of-the-art mixture-of-experts (MoE) language model. Kimi K2-Instruct-0905 demonstrates significant improvements in performance on public benchmarks and real-world coding agent tasks.",
"variantsCount": 1,
"variants": [
{
"name": "kimi-k2:1t-cloud",
"size": "-",
"context": "256K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama-guard3.json">
{
"model": "llama-guard3",
"url": "https://ollama.com/library/llama-guard3",
"description": "Llama Guard 3 is a series of models fine-tuned for content safety classification of LLM inputs and responses.",
"variantsCount": 3,
"variants": [
{
"name": "llama-guard3:latest",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "llama-guard3:1b",
"size": "1.6GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "llama-guard3:8b",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama-pro.json">
{
"model": "llama-pro",
"url": "https://ollama.com/library/llama-pro",
"description": "An expansion of Llama 2 that specializes in integrating both general language understanding and domain-specific knowledge, particularly in programming and mathematics.",
"variantsCount": 33,
"variants": [
{
"name": "llama-pro:latest",
"size": "4.7GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:instruct",
"size": "4.7GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:text",
"size": "4.7GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q2_K",
"size": "3.5GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q3_K_S",
"size": "3.6GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q3_K_M",
"size": "4.1GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q3_K_L",
"size": "4.5GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q4_0",
"size": "4.7GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q4_1",
"size": "5.3GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q4_K_S",
"size": "4.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q4_K_M",
"size": "5.1GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q5_0",
"size": "5.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q5_1",
"size": "6.3GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q5_K_S",
"size": "5.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q5_K_M",
"size": "5.9GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q6_K",
"size": "6.9GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-q8_0",
"size": "8.9GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-instruct-fp16",
"size": "17GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q2_K",
"size": "3.5GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q3_K_S",
"size": "3.6GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q3_K_M",
"size": "4.1GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q3_K_L",
"size": "4.5GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q4_0",
"size": "4.7GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q4_1",
"size": "5.3GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q4_K_S",
"size": "4.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q4_K_M",
"size": "5.1GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q5_0",
"size": "5.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q5_1",
"size": "6.3GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q5_K_S",
"size": "5.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q5_K_M",
"size": "5.9GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q6_K",
"size": "6.9GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-q8_0",
"size": "8.9GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama-pro:8b-text-fp16",
"size": "17GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama2-chinese.json">
{
"model": "llama2-chinese",
"url": "https://ollama.com/library/llama2-chinese",
"description": "Llama 2 based model fine tuned to improve Chinese dialogue ability.",
"variantsCount": 3,
"variants": [
{
"name": "llama2-chinese:latest",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama2-chinese:7b",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama2-chinese:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama2-uncensored.json">
{
"model": "llama2-uncensored",
"url": "https://ollama.com/library/llama2-uncensored",
"description": "Uncensored Llama 2 model by George Sung and Jarrad Hope.",
"variantsCount": 3,
"variants": [
{
"name": "llama2-uncensored:latest",
"size": "3.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "llama2-uncensored:7b",
"size": "3.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "llama2-uncensored:70b",
"size": "39GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama2.json">
{
"model": "llama2",
"url": "https://ollama.com/library/llama2",
"description": "Llama 2 is a collection of foundation language models ranging from 7B to 70B parameters.",
"variantsCount": 4,
"variants": [
{
"name": "llama2:latest",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama2:7b",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama2:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llama2:70b",
"size": "39GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama3-chatqa.json">
{
"model": "llama3-chatqa",
"url": "https://ollama.com/library/llama3-chatqa",
"description": "A model from NVIDIA based on Llama 3 that excels at conversational question answering (QA) and retrieval-augmented generation (RAG).",
"variantsCount": 3,
"variants": [
{
"name": "llama3-chatqa:latest",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "llama3-chatqa:8b",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "llama3-chatqa:70b",
"size": "40GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama3-gradient.json">
{
"model": "llama3-gradient",
"url": "https://ollama.com/library/llama3-gradient",
"description": "This model extends LLama-3 8B's context length from 8k to over 1m tokens.",
"variantsCount": 3,
"variants": [
{
"name": "llama3-gradient:latest",
"size": "4.7GB",
"context": "1M",
"inputType": "Text"
},
{
"name": "llama3-gradient:8b",
"size": "4.7GB",
"context": "1M",
"inputType": "Text"
},
{
"name": "llama3-gradient:70b",
"size": "40GB",
"context": "1M",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama3-groq-tool-use.json">
{
"model": "llama3-groq-tool-use",
"url": "https://ollama.com/library/llama3-groq-tool-use",
"description": "A series of models from Groq that represent a significant advancement in open-source AI capabilities for tool use/function calling.",
"variantsCount": 3,
"variants": [
{
"name": "llama3-groq-tool-use:latest",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "llama3-groq-tool-use:8b",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "llama3-groq-tool-use:70b",
"size": "40GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama3.1.json">
{
"model": "llama3.1",
"url": "https://ollama.com/library/llama3.1",
"description": "Llama 3.1 is a new state-of-the-art model from Meta available in 8B, 70B and 405B parameter sizes.",
"variantsCount": 4,
"variants": [
{
"name": "llama3.1:latest",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "llama3.1:8b",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "llama3.1:70b",
"size": "43GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "llama3.1:405b",
"size": "243GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama3.2-vision.json">
{
"model": "llama3.2-vision",
"url": "https://ollama.com/library/llama3.2-vision",
"description": "Llama 3.2 Vision is a collection of instruction-tuned image reasoning generative models in 11B and 90B sizes.",
"variantsCount": 3,
"variants": [
{
"name": "llama3.2-vision:latest",
"size": "7.8GB",
"context": "128K",
"inputType": "Text, Image"
},
{
"name": "llama3.2-vision:11b",
"size": "7.8GB",
"context": "128K",
"inputType": "Text, Image"
},
{
"name": "llama3.2-vision:90b",
"size": "55GB",
"context": "128K",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/llama3.2.json">
{
"model": "llama3.2",
"url": "https://ollama.com/library/llama3.2",
"description": "Meta's Llama 3.2 goes small with 1B and 3B models. ",
"variantsCount": 3,
"variants": [
{
"name": "llama3.2:latest",
"size": "2.0GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "llama3.2:1b",
"size": "1.3GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "llama3.2:3b",
"size": "2.0GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama3.3.json">
{
"model": "llama3.3",
"url": "https://ollama.com/library/llama3.3",
"description": "New state of the art 70B model. Llama 3.3 70B offers similar performance compared to the Llama 3.1 405B model.",
"variantsCount": 2,
"variants": [
{
"name": "llama3.3:latest",
"size": "43GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "llama3.3:70b",
"size": "43GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama3.json">
{
"model": "llama3",
"url": "https://ollama.com/library/llama3",
"description": "Meta Llama 3: The most capable openly available LLM to date",
"variantsCount": 3,
"variants": [
{
"name": "llama3:latest",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "llama3:8b",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "llama3:70b",
"size": "40GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llama4.json">
{
"model": "llama4",
"url": "https://ollama.com/library/llama4",
"description": "Meta's latest collection of multimodal models.",
"variantsCount": 3,
"variants": [
{
"name": "llama4:latest",
"size": "67GB",
"context": "10M",
"inputType": "Text, Image"
},
{
"name": "llama4:16x17b",
"size": "67GB",
"context": "10M",
"inputType": "Text, Image"
},
{
"name": "llama4:128x17b",
"size": "245GB",
"context": "1M",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/llava-llama3.json">
{
"model": "llava-llama3",
"url": "https://ollama.com/library/llava-llama3",
"description": "A LLaVA model fine-tuned from Llama 3 Instruct with better scores in several benchmarks.",
"variantsCount": 2,
"variants": [
{
"name": "llava-llama3:latest",
"size": "5.5GB",
"context": "8K",
"inputType": "Text, Image"
},
{
"name": "llava-llama3:8b",
"size": "5.5GB",
"context": "8K",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/llava-phi3.json">
{
"model": "llava-phi3",
"url": "https://ollama.com/library/llava-phi3",
"description": "A new small LLaVA model fine-tuned from Phi 3 Mini.",
"variantsCount": 2,
"variants": [
{
"name": "llava-phi3:latest",
"size": "2.9GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "llava-phi3:3.8b",
"size": "2.9GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/llava.json">
{
"model": "llava",
"url": "https://ollama.com/library/llava",
"description": "🌋 LLaVA is a novel end-to-end trained large multimodal model that combines a vision encoder and Vicuna for general-purpose visual and language understanding. Updated to version 1.6.",
"variantsCount": 4,
"variants": [
{
"name": "llava:latest",
"size": "4.7GB",
"context": "32K",
"inputType": "Text, Image"
},
{
"name": "llava:7b",
"size": "4.7GB",
"context": "32K",
"inputType": "Text, Image"
},
{
"name": "llava:13b",
"size": "8.0GB",
"context": "4K",
"inputType": "Text, Image"
},
{
"name": "llava:34b",
"size": "20GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/magicoder.json">
{
"model": "magicoder",
"url": "https://ollama.com/library/magicoder",
"description": "🎩 Magicoder is a family of 7B parameter models trained on 75K synthetic instruction data using OSS-Instruct, a novel approach to enlightening LLMs with open-source code snippets.",
"variantsCount": 2,
"variants": [
{
"name": "magicoder:latest",
"size": "3.8GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "magicoder:7b",
"size": "3.8GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/magistral.json">
{
"model": "magistral",
"url": "https://ollama.com/library/magistral",
"description": "Magistral is a small, efficient reasoning model with 24B parameters.",
"variantsCount": 2,
"variants": [
{
"name": "magistral:latest",
"size": "14GB",
"context": "39K",
"inputType": "Text"
},
{
"name": "magistral:24b",
"size": "14GB",
"context": "39K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/marco-o1.json">
{
"model": "marco-o1",
"url": "https://ollama.com/library/marco-o1",
"description": "An open large reasoning model for real-world solutions by the Alibaba International Digital Commerce Group (AIDC-AI).",
"variantsCount": 2,
"variants": [
{
"name": "marco-o1:latest",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "marco-o1:7b",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/mathstral.json">
{
"model": "mathstral",
"url": "https://ollama.com/library/mathstral",
"description": "MathΣtral: a 7B model designed for math reasoning and scientific discovery by Mistral AI.",
"variantsCount": 2,
"variants": [
{
"name": "mathstral:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "mathstral:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/meditron.json">
{
"model": "meditron",
"url": "https://ollama.com/library/meditron",
"description": "Open-source medical large language model adapted from Llama 2 to the medical domain.",
"variantsCount": 3,
"variants": [
{
"name": "meditron:latest",
"size": "3.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "meditron:7b",
"size": "3.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "meditron:70b",
"size": "39GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/medllama2.json">
{
"model": "medllama2",
"url": "https://ollama.com/library/medllama2",
"description": "Fine-tuned Llama 2 model to answer medical questions based on an open source medical dataset. ",
"variantsCount": 2,
"variants": [
{
"name": "medllama2:latest",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "medllama2:7b",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/megadolphin.json">
{
"model": "megadolphin",
"url": "https://ollama.com/library/megadolphin",
"description": "MegaDolphin-2.2-120b is a transformation of Dolphin-2.2-70b created by interleaving the model with itself.",
"variantsCount": 2,
"variants": [
{
"name": "megadolphin:latest",
"size": "68GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "megadolphin:120b",
"size": "68GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/minicpm-v.json">
{
"model": "minicpm-v",
"url": "https://ollama.com/library/minicpm-v",
"description": "A series of multimodal LLMs (MLLMs) designed for vision-language understanding.",
"variantsCount": 2,
"variants": [
{
"name": "minicpm-v:latest",
"size": "5.5GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "minicpm-v:8b",
"size": "5.5GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/minimax-m2.json">
{
"model": "minimax-m2",
"url": "https://ollama.com/library/minimax-m2",
"description": "MiniMax M2 is a high-efficiency large language model built for coding and agentic workflows.",
"variantsCount": 1,
"variants": [
{
"name": "minimax-m2:cloud",
"size": "-",
"context": "200K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/mistral-large.json">
{
"model": "mistral-large",
"url": "https://ollama.com/library/mistral-large",
"description": "Mistral Large 2 is Mistral's new flagship model that is significantly more capable in code generation, mathematics, and reasoning with 128k context window and support for dozens of languages.",
"variantsCount": 2,
"variants": [
{
"name": "mistral-large:latest",
"size": "73GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "mistral-large:123b",
"size": "73GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/mistral-nemo.json">
{
"model": "mistral-nemo",
"url": "https://ollama.com/library/mistral-nemo",
"description": "A state-of-the-art 12B model with 128k context length, built by Mistral AI in collaboration with NVIDIA.",
"variantsCount": 2,
"variants": [
{
"name": "mistral-nemo:latest",
"size": "7.1GB",
"context": "1000K",
"inputType": "Text"
},
{
"name": "mistral-nemo:12b",
"size": "7.1GB",
"context": "1000K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/mistral-openorca.json">
{
"model": "mistral-openorca",
"url": "https://ollama.com/library/mistral-openorca",
"description": "Mistral OpenOrca is a 7 billion parameter model, fine-tuned on top of the Mistral 7B model using the OpenOrca dataset.",
"variantsCount": 2,
"variants": [
{
"name": "mistral-openorca:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "mistral-openorca:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/mistral-small.json">
{
"model": "mistral-small",
"url": "https://ollama.com/library/mistral-small",
"description": "Mistral Small 3 sets a new benchmark in the “small” Large Language Models category below 70B.",
"variantsCount": 3,
"variants": [
{
"name": "mistral-small:latest",
"size": "14GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "mistral-small:22b",
"size": "13GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "mistral-small:24b",
"size": "14GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/mistral-small3.1.json">
{
"model": "mistral-small3.1",
"url": "https://ollama.com/library/mistral-small3.1",
"description": "Building upon Mistral Small 3, Mistral Small 3.1 (2503) adds state-of-the-art vision understanding and enhances long context capabilities up to 128k tokens without compromising text performance.",
"variantsCount": 2,
"variants": [
{
"name": "mistral-small3.1:latest",
"size": "15GB",
"context": "128K",
"inputType": "Text, Image"
},
{
"name": "mistral-small3.1:24b",
"size": "15GB",
"context": "128K",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/mistral-small3.2.json">
{
"model": "mistral-small3.2",
"url": "https://ollama.com/library/mistral-small3.2",
"description": "An update to Mistral Small that improves on function calling, instruction following, and less repetition errors.",
"variantsCount": 2,
"variants": [
{
"name": "mistral-small3.2:latest",
"size": "15GB",
"context": "128K",
"inputType": "Text, Image"
},
{
"name": "mistral-small3.2:24b",
"size": "15GB",
"context": "128K",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/mistral.json">
{
"model": "mistral",
"url": "https://ollama.com/library/mistral",
"description": "The 7B model released by Mistral AI, updated to version 0.3.",
"variantsCount": 2,
"variants": [
{
"name": "mistral:latest",
"size": "4.4GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "mistral:7b",
"size": "4.4GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/mistrallite.json">
{
"model": "mistrallite",
"url": "https://ollama.com/library/mistrallite",
"description": "MistralLite is a fine-tuned model based on Mistral with enhanced capabilities of processing long contexts.",
"variantsCount": 2,
"variants": [
{
"name": "mistrallite:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "mistrallite:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/mixtral.json">
{
"model": "mixtral",
"url": "https://ollama.com/library/mixtral",
"description": "A set of Mixture of Experts (MoE) model with open weights by Mistral AI in 8x7b and 8x22b parameter sizes.",
"variantsCount": 3,
"variants": [
{
"name": "mixtral:latest",
"size": "26GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "mixtral:8x7b",
"size": "26GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "mixtral:8x22b",
"size": "80GB",
"context": "64K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/moondream.json">
{
"model": "moondream",
"url": "https://ollama.com/library/moondream",
"description": "moondream2 is a small vision language model designed to run efficiently on edge devices.",
"variantsCount": 2,
"variants": [
{
"name": "moondream:latest",
"size": "1.7GB",
"context": "2K",
"inputType": "Text, Image"
},
{
"name": "moondream:1.8b",
"size": "1.7GB",
"context": "2K",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/mxbai-embed-large.json">
{
"model": "mxbai-embed-large",
"url": "https://ollama.com/library/mxbai-embed-large",
"description": "State-of-the-art large embedding model from mixedbread.ai",
"variantsCount": 2,
"variants": [
{
"name": "mxbai-embed-large:latest",
"size": "670MB",
"context": "512",
"inputType": "Text"
},
{
"name": "mxbai-embed-large:335m",
"size": "670MB",
"context": "512",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/nemotron-mini.json">
{
"model": "nemotron-mini",
"url": "https://ollama.com/library/nemotron-mini",
"description": "A commercial-friendly small language model by NVIDIA optimized for roleplay, RAG QA, and function calling.",
"variantsCount": 2,
"variants": [
{
"name": "nemotron-mini:latest",
"size": "2.7GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "nemotron-mini:4b",
"size": "2.7GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/nemotron.json">
{
"model": "nemotron",
"url": "https://ollama.com/library/nemotron",
"description": "Llama-3.1-Nemotron-70B-Instruct is a large language model customized by NVIDIA to improve the helpfulness of LLM generated responses to user queries.",
"variantsCount": 2,
"variants": [
{
"name": "nemotron:latest",
"size": "43GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "nemotron:70b",
"size": "43GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/neural-chat.json">
{
"model": "neural-chat",
"url": "https://ollama.com/library/neural-chat",
"description": "A fine-tuned model based on Mistral with good coverage of domain and language.",
"variantsCount": 2,
"variants": [
{
"name": "neural-chat:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "neural-chat:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/nexusraven.json">
{
"model": "nexusraven",
"url": "https://ollama.com/library/nexusraven",
"description": "Nexus Raven is a 13B instruction tuned model for function calling tasks. ",
"variantsCount": 2,
"variants": [
{
"name": "nexusraven:latest",
"size": "7.4GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "nexusraven:13b",
"size": "7.4GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/nomic-embed-text.json">
{
"model": "nomic-embed-text",
"url": "https://ollama.com/library/nomic-embed-text",
"description": "A high-performing open embedding model with a large token context window.",
"variantsCount": 3,
"variants": [
{
"name": "nomic-embed-text:latest",
"size": "274MB",
"context": "2K",
"inputType": "Text"
},
{
"name": "nomic-embed-text:v1.5",
"size": "274MB",
"context": "2K",
"inputType": "Text"
},
{
"name": "nomic-embed-text:137m-v1.5-fp16",
"size": "274MB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/notus.json">
{
"model": "notus",
"url": "https://ollama.com/library/notus",
"description": "A 7B chat model fine-tuned with high-quality data and based on Zephyr.",
"variantsCount": 2,
"variants": [
{
"name": "notus:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "notus:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/notux.json">
{
"model": "notux",
"url": "https://ollama.com/library/notux",
"description": "A top-performing mixture of experts model, fine-tuned with high-quality data.",
"variantsCount": 2,
"variants": [
{
"name": "notux:latest",
"size": "26GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "notux:8x7b",
"size": "26GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/nous-hermes.json">
{
"model": "nous-hermes",
"url": "https://ollama.com/library/nous-hermes",
"description": "General use models based on Llama and Llama 2 from Nous Research.",
"variantsCount": 3,
"variants": [
{
"name": "nous-hermes:latest",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "nous-hermes:7b",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "nous-hermes:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/nous-hermes2-mixtral.json">
{
"model": "nous-hermes2-mixtral",
"url": "https://ollama.com/library/nous-hermes2-mixtral",
"description": "The Nous Hermes 2 model from Nous Research, now trained over Mixtral.",
"variantsCount": 2,
"variants": [
{
"name": "nous-hermes2-mixtral:latest",
"size": "26GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "nous-hermes2-mixtral:8x7b",
"size": "26GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/nous-hermes2.json">
{
"model": "nous-hermes2",
"url": "https://ollama.com/library/nous-hermes2",
"description": "The powerful family of models by Nous Research that excels at scientific discussion and coding tasks.",
"variantsCount": 3,
"variants": [
{
"name": "nous-hermes2:latest",
"size": "6.1GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "nous-hermes2:10.7b",
"size": "6.1GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "nous-hermes2:34b",
"size": "19GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/nuextract.json">
{
"model": "nuextract",
"url": "https://ollama.com/library/nuextract",
"description": "A 3.8B model fine-tuned on a private high-quality synthetic dataset for information extraction, based on Phi-3.",
"variantsCount": 2,
"variants": [
{
"name": "nuextract:latest",
"size": "2.2GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "nuextract:3.8b",
"size": "2.2GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/olmo2.json">
{
"model": "olmo2",
"url": "https://ollama.com/library/olmo2",
"description": "OLMo 2 is a new family of 7B and 13B models trained on up to 5T tokens. These models are on par with or better than equivalently sized fully open models, and competitive with open-weight models such as Llama 3.1 on English academic benchmarks.",
"variantsCount": 3,
"variants": [
{
"name": "olmo2:latest",
"size": "4.5GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "olmo2:7b",
"size": "4.5GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "olmo2:13b",
"size": "8.4GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/open-orca-platypus2.json">
{
"model": "open-orca-platypus2",
"url": "https://ollama.com/library/open-orca-platypus2",
"description": "Merge of the Open Orca OpenChat model and the Garage-bAInd Platypus 2 model. Designed for chat and code generation.",
"variantsCount": 2,
"variants": [
{
"name": "open-orca-platypus2:latest",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "open-orca-platypus2:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/openchat.json">
{
"model": "openchat",
"url": "https://ollama.com/library/openchat",
"description": "A family of open-source models trained on a wide variety of data, surpassing ChatGPT on various benchmarks. Updated to version 3.5-0106.",
"variantsCount": 2,
"variants": [
{
"name": "openchat:latest",
"size": "4.1GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "openchat:7b",
"size": "4.1GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/opencoder.json">
{
"model": "opencoder",
"url": "https://ollama.com/library/opencoder",
"description": "OpenCoder is an open and reproducible code LLM family which includes 1.5B and 8B models, supporting chat in English and Chinese languages.",
"variantsCount": 3,
"variants": [
{
"name": "opencoder:latest",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "opencoder:1.5b",
"size": "1.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "opencoder:8b",
"size": "4.7GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/openhermes.json">
{
"model": "openhermes",
"url": "https://ollama.com/library/openhermes",
"description": "OpenHermes 2.5 is a 7B model fine-tuned by Teknium on Mistral with fully open datasets.",
"variantsCount": 35,
"variants": [
{
"name": "openhermes:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:v2",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:v2.5",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q2_K",
"size": "3.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q3_K_S",
"size": "3.2GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q3_K_M",
"size": "3.5GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q3_K_L",
"size": "3.8GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q4_0",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q4_1",
"size": "4.6GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q4_K_S",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q4_K_M",
"size": "4.4GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q5_0",
"size": "5.0GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q5_1",
"size": "5.4GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q5_K_S",
"size": "5.0GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q5_K_M",
"size": "5.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q6_K",
"size": "5.9GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-q8_0",
"size": "7.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2-fp16",
"size": "14GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q2_K",
"size": "3.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q3_K_S",
"size": "3.2GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q3_K_M",
"size": "3.5GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q3_K_L",
"size": "3.8GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q4_0",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q4_1",
"size": "4.6GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q4_K_S",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q4_K_M",
"size": "4.4GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q5_0",
"size": "5.0GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q5_1",
"size": "5.4GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q5_K_S",
"size": "5.0GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q5_K_M",
"size": "5.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q6_K",
"size": "5.9GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-q8_0",
"size": "7.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-mistral-v2.5-fp16",
"size": "14GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-v2",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openhermes:7b-v2.5",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/openthinker.json">
{
"model": "openthinker",
"url": "https://ollama.com/library/openthinker",
"description": "A fully open-source family of reasoning models built using a dataset derived by distilling DeepSeek-R1.",
"variantsCount": 3,
"variants": [
{
"name": "openthinker:latest",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openthinker:7b",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "openthinker:32b",
"size": "20GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/orca-mini.json">
{
"model": "orca-mini",
"url": "https://ollama.com/library/orca-mini",
"description": "A general-purpose model ranging from 3 billion parameters to 70 billion, suitable for entry-level hardware.",
"variantsCount": 5,
"variants": [
{
"name": "orca-mini:latest",
"size": "2.0GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "orca-mini:3b",
"size": "2.0GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "orca-mini:7b",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "orca-mini:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "orca-mini:70b",
"size": "39GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/orca2.json">
{
"model": "orca2",
"url": "https://ollama.com/library/orca2",
"description": "Orca 2 is built by Microsoft research, and are a fine-tuned version of Meta's Llama 2 models. The model is designed to excel particularly in reasoning.",
"variantsCount": 3,
"variants": [
{
"name": "orca2:latest",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "orca2:7b",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "orca2:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/paraphrase-multilingual.json">
{
"model": "paraphrase-multilingual",
"url": "https://ollama.com/library/paraphrase-multilingual",
"description": "Sentence-transformers model that can be used for tasks like clustering or semantic search.",
"variantsCount": 2,
"variants": [
{
"name": "paraphrase-multilingual:latest",
"size": "563MB",
"context": "512",
"inputType": "Text"
},
{
"name": "paraphrase-multilingual:278m",
"size": "563MB",
"context": "512",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/phi.json">
{
"model": "phi",
"url": "https://ollama.com/library/phi",
"description": "Phi-2: a 2.7B language model by Microsoft Research that demonstrates outstanding reasoning and language understanding capabilities.",
"variantsCount": 2,
"variants": [
{
"name": "phi:latest",
"size": "1.6GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "phi:2.7b",
"size": "1.6GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/phi3.5.json">
{
"model": "phi3.5",
"url": "https://ollama.com/library/phi3.5",
"description": "A lightweight AI model with 3.8 billion parameters with performance overtaking similarly and larger sized models.",
"variantsCount": 2,
"variants": [
{
"name": "phi3.5:latest",
"size": "2.2GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "phi3.5:3.8b",
"size": "2.2GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/phi3.json">
{
"model": "phi3",
"url": "https://ollama.com/library/phi3",
"description": "Phi-3 is a family of lightweight 3B (Mini) and 14B (Medium) state-of-the-art open models by Microsoft.",
"variantsCount": 3,
"variants": [
{
"name": "phi3:latest",
"size": "2.2GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "phi3:3.8b",
"size": "2.2GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "phi3:14b",
"size": "7.9GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/phi4-mini-reasoning.json">
{
"model": "phi4-mini-reasoning",
"url": "https://ollama.com/library/phi4-mini-reasoning",
"description": "Phi 4 mini reasoning is a lightweight open model that balances efficiency with advanced reasoning ability.",
"variantsCount": 2,
"variants": [
{
"name": "phi4-mini-reasoning:latest",
"size": "3.2GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "phi4-mini-reasoning:3.8b",
"size": "3.2GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/phi4-mini.json">
{
"model": "phi4-mini",
"url": "https://ollama.com/library/phi4-mini",
"description": "Phi-4-mini brings significant enhancements in multilingual support, reasoning, and mathematics, and now, the long-awaited function calling feature is finally supported.",
"variantsCount": 2,
"variants": [
{
"name": "phi4-mini:latest",
"size": "2.5GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "phi4-mini:3.8b",
"size": "2.5GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/phi4-reasoning.json">
{
"model": "phi4-reasoning",
"url": "https://ollama.com/library/phi4-reasoning",
"description": "Phi 4 reasoning and reasoning plus are 14-billion parameter open-weight reasoning models that rival much larger models on complex reasoning tasks. ",
"variantsCount": 2,
"variants": [
{
"name": "phi4-reasoning:latest",
"size": "11GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "phi4-reasoning:14b",
"size": "11GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/phi4.json">
{
"model": "phi4",
"url": "https://ollama.com/library/phi4",
"description": "Phi-4 is a 14B parameter, state-of-the-art open model from Microsoft.",
"variantsCount": 2,
"variants": [
{
"name": "phi4:latest",
"size": "9.1GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "phi4:14b",
"size": "9.1GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/phind-codellama.json">
{
"model": "phind-codellama",
"url": "https://ollama.com/library/phind-codellama",
"description": "Code generation model based on Code Llama.",
"variantsCount": 2,
"variants": [
{
"name": "phind-codellama:latest",
"size": "19GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "phind-codellama:34b",
"size": "19GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwen.json">
{
"model": "qwen",
"url": "https://ollama.com/library/qwen",
"description": "Qwen 1.5 is a series of large language models by Alibaba Cloud spanning from 0.5B to 110B parameters",
"variantsCount": 9,
"variants": [
{
"name": "qwen:latest",
"size": "2.3GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen:0.5b",
"size": "395MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen:1.8b",
"size": "1.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen:4b",
"size": "2.3GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen:7b",
"size": "4.5GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen:14b",
"size": "8.2GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen:32b",
"size": "18GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen:72b",
"size": "41GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen:110b",
"size": "63GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwen2-math.json">
{
"model": "qwen2-math",
"url": "https://ollama.com/library/qwen2-math",
"description": "Qwen2 Math is a series of specialized math language models built upon the Qwen2 LLMs, which significantly outperforms the mathematical capabilities of open-source models and even closed-source models (e.g., GPT4o).",
"variantsCount": 4,
"variants": [
{
"name": "qwen2-math:latest",
"size": "4.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "qwen2-math:1.5b",
"size": "935MB",
"context": "4K",
"inputType": "Text"
},
{
"name": "qwen2-math:7b",
"size": "4.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "qwen2-math:72b",
"size": "41GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwen2.5-coder.json">
{
"model": "qwen2.5-coder",
"url": "https://ollama.com/library/qwen2.5-coder",
"description": "The latest series of Code-Specific Qwen models, with significant improvements in code generation, code reasoning, and code fixing.",
"variantsCount": 7,
"variants": [
{
"name": "qwen2.5-coder:latest",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5-coder:0.5b",
"size": "398MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5-coder:1.5b",
"size": "986MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5-coder:3b",
"size": "1.9GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5-coder:7b",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5-coder:14b",
"size": "9.0GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5-coder:32b",
"size": "20GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwen2.5.json">
{
"model": "qwen2.5",
"url": "https://ollama.com/library/qwen2.5",
"description": "Qwen2.5 models are pretrained on Alibaba's latest large-scale dataset, encompassing up to 18 trillion tokens. The model supports up to 128K tokens and has multilingual support. ",
"variantsCount": 8,
"variants": [
{
"name": "qwen2.5:latest",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5:0.5b",
"size": "398MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5:1.5b",
"size": "986MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5:3b",
"size": "1.9GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5:7b",
"size": "4.7GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5:14b",
"size": "9.0GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5:32b",
"size": "20GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2.5:72b",
"size": "47GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwen2.5vl.json">
{
"model": "qwen2.5vl",
"url": "https://ollama.com/library/qwen2.5vl",
"description": "Flagship vision-language model of Qwen and also a significant leap from the previous Qwen2-VL.",
"variantsCount": 5,
"variants": [
{
"name": "qwen2.5vl:latest",
"size": "6.0GB",
"context": "125K",
"inputType": "Text, Image"
},
{
"name": "qwen2.5vl:3b",
"size": "3.2GB",
"context": "125K",
"inputType": "Text, Image"
},
{
"name": "qwen2.5vl:7b",
"size": "6.0GB",
"context": "125K",
"inputType": "Text, Image"
},
{
"name": "qwen2.5vl:32b",
"size": "21GB",
"context": "125K",
"inputType": "Text, Image"
},
{
"name": "qwen2.5vl:72b",
"size": "49GB",
"context": "125K",
"inputType": "Text, Image"
}
]
}
</file>
<file path="data/models/qwen2.json">
{
"model": "qwen2",
"url": "https://ollama.com/library/qwen2",
"description": "Qwen2 is a new series of large language models from Alibaba group",
"variantsCount": 5,
"variants": [
{
"name": "qwen2:latest",
"size": "4.4GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2:0.5b",
"size": "352MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2:1.5b",
"size": "935MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2:7b",
"size": "4.4GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen2:72b",
"size": "41GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwen3-coder.json">
{
"model": "qwen3-coder",
"url": "https://ollama.com/library/qwen3-coder",
"description": "Alibaba's performant long context models for agentic and coding tasks.",
"variantsCount": 4,
"variants": [
{
"name": "qwen3-coder:latest",
"size": "19GB",
"context": "256K",
"inputType": "Text"
},
{
"name": "qwen3-coder:30b",
"size": "19GB",
"context": "256K",
"inputType": "Text"
},
{
"name": "qwen3-coder:480b",
"size": "290GB",
"context": "256K",
"inputType": "Text"
},
{
"name": "qwen3-coder:480b-cloud",
"size": "-",
"context": "256K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwen3-embedding.json">
{
"model": "qwen3-embedding",
"url": "https://ollama.com/library/qwen3-embedding",
"description": "Building upon the foundational models of the Qwen3 series, Qwen3 Embedding provides a comprehensive range of text embeddings models in various sizes",
"variantsCount": 4,
"variants": [
{
"name": "qwen3-embedding:latest",
"size": "4.7GB",
"context": "40K",
"inputType": "Text"
},
{
"name": "qwen3-embedding:0.6b",
"size": "639MB",
"context": "32K",
"inputType": "Text"
},
{
"name": "qwen3-embedding:4b",
"size": "2.5GB",
"context": "40K",
"inputType": "Text"
},
{
"name": "qwen3-embedding:8b",
"size": "4.7GB",
"context": "40K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwen3-vl.json">
{
"model": "qwen3-vl",
"url": "https://ollama.com/library/qwen3-vl",
"description": "The most powerful vision-language model in the Qwen model family to date. ",
"variantsCount": 9,
"variants": [
{
"name": "qwen3-vl:latest",
"size": "6.1GB",
"context": "256K",
"inputType": "Text, Image"
},
{
"name": "qwen3-vl:2b",
"size": "1.9GB",
"context": "256K",
"inputType": "Text, Image"
},
{
"name": "qwen3-vl:4b",
"size": "3.3GB",
"context": "256K",
"inputType": "Text, Image"
},
{
"name": "qwen3-vl:8b",
"size": "6.1GB",
"context": "256K",
"inputType": "Text, Image"
},
{
"name": "qwen3-vl:30b",
"size": "20GB",
"context": "256K",
"inputType": "Text, Image"
},
{
"name": "qwen3-vl:32b",
"size": "21GB",
"context": "256K",
"inputType": "Text, Image"
},
{
"name": "qwen3-vl:235b",
"size": "143GB",
"context": "256K",
"inputType": "Text, Image"
},
{
"name": "qwen3-vl:235b-cloud",
"size": "-",
"context": "256K",
"inputType": "Text"
},
{
"name": "qwen3-vl:235b-instruct-cloud",
"size": "-",
"context": "256K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwen3.json">
{
"model": "qwen3",
"url": "https://ollama.com/library/qwen3",
"description": "Qwen3 is the latest generation of large language models in Qwen series, offering a comprehensive suite of dense and mixture-of-experts (MoE) models.",
"variantsCount": 9,
"variants": [
{
"name": "qwen3:latest",
"size": "5.2GB",
"context": "40K",
"inputType": "Text"
},
{
"name": "qwen3:0.6b",
"size": "523MB",
"context": "40K",
"inputType": "Text"
},
{
"name": "qwen3:1.7b",
"size": "1.4GB",
"context": "40K",
"inputType": "Text"
},
{
"name": "qwen3:4b",
"size": "2.5GB",
"context": "256K",
"inputType": "Text"
},
{
"name": "qwen3:8b",
"size": "5.2GB",
"context": "40K",
"inputType": "Text"
},
{
"name": "qwen3:14b",
"size": "9.3GB",
"context": "40K",
"inputType": "Text"
},
{
"name": "qwen3:30b",
"size": "19GB",
"context": "256K",
"inputType": "Text"
},
{
"name": "qwen3:32b",
"size": "20GB",
"context": "40K",
"inputType": "Text"
},
{
"name": "qwen3:235b",
"size": "142GB",
"context": "256K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/qwq.json">
{
"model": "qwq",
"url": "https://ollama.com/library/qwq",
"description": "QwQ is the reasoning model of the Qwen series.",
"variantsCount": 2,
"variants": [
{
"name": "qwq:latest",
"size": "20GB",
"context": "40K",
"inputType": "Text"
},
{
"name": "qwq:32b",
"size": "20GB",
"context": "40K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/r1-1776.json">
{
"model": "r1-1776",
"url": "https://ollama.com/library/r1-1776",
"description": "A version of the DeepSeek-R1 model that has been post trained to provide unbiased, accurate, and factual information by Perplexity. ",
"variantsCount": 3,
"variants": [
{
"name": "r1-1776:latest",
"size": "43GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "r1-1776:70b",
"size": "43GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "r1-1776:671b",
"size": "404GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/reader-lm.json">
{
"model": "reader-lm",
"url": "https://ollama.com/library/reader-lm",
"description": "A series of models that convert HTML content to Markdown content, which is useful for content conversion tasks.",
"variantsCount": 3,
"variants": [
{
"name": "reader-lm:latest",
"size": "935MB",
"context": "250K",
"inputType": "Text"
},
{
"name": "reader-lm:0.5b",
"size": "352MB",
"context": "250K",
"inputType": "Text"
},
{
"name": "reader-lm:1.5b",
"size": "935MB",
"context": "250K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/reflection.json">
{
"model": "reflection",
"url": "https://ollama.com/library/reflection",
"description": "A high-performing model trained with a new technique called Reflection-tuning that teaches a LLM to detect mistakes in its reasoning and correct course.",
"variantsCount": 2,
"variants": [
{
"name": "reflection:latest",
"size": "40GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "reflection:70b",
"size": "40GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/sailor2.json">
{
"model": "sailor2",
"url": "https://ollama.com/library/sailor2",
"description": "Sailor2 are multilingual language models made for South-East Asia. Available in 1B, 8B, and 20B parameter sizes.",
"variantsCount": 4,
"variants": [
{
"name": "sailor2:latest",
"size": "5.2GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "sailor2:1b",
"size": "1.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "sailor2:8b",
"size": "5.2GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "sailor2:20b",
"size": "12GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/samantha-mistral.json">
{
"model": "samantha-mistral",
"url": "https://ollama.com/library/samantha-mistral",
"description": "A companion assistant trained in philosophy, psychology, and personal relationships. Based on Mistral.",
"variantsCount": 2,
"variants": [
{
"name": "samantha-mistral:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "samantha-mistral:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/shieldgemma.json">
{
"model": "shieldgemma",
"url": "https://ollama.com/library/shieldgemma",
"description": "ShieldGemma is set of instruction tuned models for evaluating the safety of text prompt input and text output responses against a set of defined safety policies.",
"variantsCount": 4,
"variants": [
{
"name": "shieldgemma:latest",
"size": "5.8GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "shieldgemma:2b",
"size": "1.7GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "shieldgemma:9b",
"size": "5.8GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "shieldgemma:27b",
"size": "17GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/smallthinker.json">
{
"model": "smallthinker",
"url": "https://ollama.com/library/smallthinker",
"description": "A new small reasoning model fine-tuned from the Qwen 2.5 3B Instruct model.",
"variantsCount": 2,
"variants": [
{
"name": "smallthinker:latest",
"size": "3.6GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "smallthinker:3b",
"size": "3.6GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/smollm.json">
{
"model": "smollm",
"url": "https://ollama.com/library/smollm",
"description": "🪐 A family of small models with 135M, 360M, and 1.7B parameters, trained on a new high-quality dataset.",
"variantsCount": 4,
"variants": [
{
"name": "smollm:latest",
"size": "991MB",
"context": "2K",
"inputType": "Text"
},
{
"name": "smollm:135m",
"size": "92MB",
"context": "2K",
"inputType": "Text"
},
{
"name": "smollm:360m",
"size": "229MB",
"context": "2K",
"inputType": "Text"
},
{
"name": "smollm:1.7b",
"size": "991MB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/smollm2.json">
{
"model": "smollm2",
"url": "https://ollama.com/library/smollm2",
"description": "SmolLM2 is a family of compact language models available in three size: 135M, 360M, and 1.7B parameters.",
"variantsCount": 4,
"variants": [
{
"name": "smollm2:latest",
"size": "1.8GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "smollm2:135m",
"size": "271MB",
"context": "8K",
"inputType": "Text"
},
{
"name": "smollm2:360m",
"size": "726MB",
"context": "8K",
"inputType": "Text"
},
{
"name": "smollm2:1.7b",
"size": "1.8GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/snowflake-arctic-embed.json">
{
"model": "snowflake-arctic-embed",
"url": "https://ollama.com/library/snowflake-arctic-embed",
"description": "A suite of text embedding models by Snowflake, optimized for performance.",
"variantsCount": 6,
"variants": [
{
"name": "snowflake-arctic-embed:latest",
"size": "669MB",
"context": "512",
"inputType": "Text"
},
{
"name": "snowflake-arctic-embed:22m",
"size": "46MB",
"context": "512",
"inputType": "Text"
},
{
"name": "snowflake-arctic-embed:33m",
"size": "67MB",
"context": "512",
"inputType": "Text"
},
{
"name": "snowflake-arctic-embed:110m",
"size": "219MB",
"context": "512",
"inputType": "Text"
},
{
"name": "snowflake-arctic-embed:137m",
"size": "274MB",
"context": "2K",
"inputType": "Text"
},
{
"name": "snowflake-arctic-embed:335m",
"size": "669MB",
"context": "512",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/snowflake-arctic-embed2.json">
{
"model": "snowflake-arctic-embed2",
"url": "https://ollama.com/library/snowflake-arctic-embed2",
"description": "Snowflake's frontier embedding model. Arctic Embed 2.0 adds multilingual support without sacrificing English performance or scalability.",
"variantsCount": 2,
"variants": [
{
"name": "snowflake-arctic-embed2:latest",
"size": "1.2GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "snowflake-arctic-embed2:568m",
"size": "1.2GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/solar-pro.json">
{
"model": "solar-pro",
"url": "https://ollama.com/library/solar-pro",
"description": "Solar Pro Preview: an advanced large language model (LLM) with 22 billion parameters designed to fit into a single GPU",
"variantsCount": 2,
"variants": [
{
"name": "solar-pro:latest",
"size": "13GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "solar-pro:22b",
"size": "13GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/solar.json">
{
"model": "solar",
"url": "https://ollama.com/library/solar",
"description": "A compact, yet powerful 10.7B large language model designed for single-turn conversation.",
"variantsCount": 2,
"variants": [
{
"name": "solar:latest",
"size": "6.1GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "solar:10.7b",
"size": "6.1GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/sqlcoder.json">
{
"model": "sqlcoder",
"url": "https://ollama.com/library/sqlcoder",
"description": "SQLCoder is a code completion model fined-tuned on StarCoder for SQL generation tasks",
"variantsCount": 3,
"variants": [
{
"name": "sqlcoder:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "sqlcoder:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "sqlcoder:15b",
"size": "9.0GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/stable-beluga.json">
{
"model": "stable-beluga",
"url": "https://ollama.com/library/stable-beluga",
"description": "Llama 2 based model fine tuned on an Orca-style dataset. Originally called Free Willy.",
"variantsCount": 4,
"variants": [
{
"name": "stable-beluga:latest",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "stable-beluga:7b",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "stable-beluga:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "stable-beluga:70b",
"size": "39GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/stable-code.json">
{
"model": "stable-code",
"url": "https://ollama.com/library/stable-code",
"description": "Stable Code 3B is a coding model with instruct and code completion variants on par with models such as Code Llama 7B that are 2.5x larger.",
"variantsCount": 2,
"variants": [
{
"name": "stable-code:latest",
"size": "1.6GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "stable-code:3b",
"size": "1.6GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/stablelm-zephyr.json">
{
"model": "stablelm-zephyr",
"url": "https://ollama.com/library/stablelm-zephyr",
"description": "A lightweight chat model allowing accurate, and responsive output without requiring high-end hardware.",
"variantsCount": 2,
"variants": [
{
"name": "stablelm-zephyr:latest",
"size": "1.6GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "stablelm-zephyr:3b",
"size": "1.6GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/stablelm2.json">
{
"model": "stablelm2",
"url": "https://ollama.com/library/stablelm2",
"description": "Stable LM 2 is a state-of-the-art 1.6B and 12B parameter language model trained on multilingual data in English, Spanish, German, Italian, French, Portuguese, and Dutch.",
"variantsCount": 3,
"variants": [
{
"name": "stablelm2:latest",
"size": "983MB",
"context": "4K",
"inputType": "Text"
},
{
"name": "stablelm2:1.6b",
"size": "983MB",
"context": "4K",
"inputType": "Text"
},
{
"name": "stablelm2:12b",
"size": "7.0GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/starcoder.json">
{
"model": "starcoder",
"url": "https://ollama.com/library/starcoder",
"description": "StarCoder is a code generation model trained on 80+ programming languages.",
"variantsCount": 5,
"variants": [
{
"name": "starcoder:latest",
"size": "1.8GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "starcoder:1b",
"size": "726MB",
"context": "8K",
"inputType": "Text"
},
{
"name": "starcoder:3b",
"size": "1.8GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "starcoder:7b",
"size": "4.3GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "starcoder:15b",
"size": "9.0GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/starcoder2.json">
{
"model": "starcoder2",
"url": "https://ollama.com/library/starcoder2",
"description": "StarCoder2 is the next generation of transparently trained open code LLMs that comes in three sizes: 3B, 7B and 15B parameters. ",
"variantsCount": 4,
"variants": [
{
"name": "starcoder2:latest",
"size": "1.7GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "starcoder2:3b",
"size": "1.7GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "starcoder2:7b",
"size": "4.0GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "starcoder2:15b",
"size": "9.1GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/starling-lm.json">
{
"model": "starling-lm",
"url": "https://ollama.com/library/starling-lm",
"description": "Starling is a large language model trained by reinforcement learning from AI feedback focused on improving chatbot helpfulness.",
"variantsCount": 2,
"variants": [
{
"name": "starling-lm:latest",
"size": "4.1GB",
"context": "8K",
"inputType": "Text"
},
{
"name": "starling-lm:7b",
"size": "4.1GB",
"context": "8K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/tinydolphin.json">
{
"model": "tinydolphin",
"url": "https://ollama.com/library/tinydolphin",
"description": "An experimental 1.1B parameter model trained on the new Dolphin 2.8 dataset by Eric Hartford and based on TinyLlama.",
"variantsCount": 2,
"variants": [
{
"name": "tinydolphin:latest",
"size": "637MB",
"context": "4K",
"inputType": "Text"
},
{
"name": "tinydolphin:1.1b",
"size": "637MB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/tinyllama.json">
{
"model": "tinyllama",
"url": "https://ollama.com/library/tinyllama",
"description": "The TinyLlama project is an open endeavor to train a compact 1.1B Llama model on 3 trillion tokens.",
"variantsCount": 2,
"variants": [
{
"name": "tinyllama:latest",
"size": "638MB",
"context": "2K",
"inputType": "Text"
},
{
"name": "tinyllama:1.1b",
"size": "638MB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/tulu3.json">
{
"model": "tulu3",
"url": "https://ollama.com/library/tulu3",
"description": "Tülu 3 is a leading instruction following model family, offering fully open-source data, code, and recipes by the The Allen Institute for AI.",
"variantsCount": 3,
"variants": [
{
"name": "tulu3:latest",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "tulu3:8b",
"size": "4.9GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "tulu3:70b",
"size": "43GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/vicuna.json">
{
"model": "vicuna",
"url": "https://ollama.com/library/vicuna",
"description": "General use chat model based on Llama and Llama 2 with 2K to 16K context sizes.",
"variantsCount": 4,
"variants": [
{
"name": "vicuna:latest",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "vicuna:7b",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "vicuna:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "vicuna:33b",
"size": "18GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/wizard-math.json">
{
"model": "wizard-math",
"url": "https://ollama.com/library/wizard-math",
"description": "Model focused on math and logic problems",
"variantsCount": 4,
"variants": [
{
"name": "wizard-math:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "wizard-math:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "wizard-math:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizard-math:70b",
"size": "39GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/wizard-vicuna-uncensored.json">
{
"model": "wizard-vicuna-uncensored",
"url": "https://ollama.com/library/wizard-vicuna-uncensored",
"description": "Wizard Vicuna Uncensored is a 7B, 13B, and 30B parameter model based on Llama 2 uncensored by Eric Hartford.",
"variantsCount": 4,
"variants": [
{
"name": "wizard-vicuna-uncensored:latest",
"size": "3.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizard-vicuna-uncensored:7b",
"size": "3.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizard-vicuna-uncensored:13b",
"size": "7.4GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizard-vicuna-uncensored:30b",
"size": "18GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/wizard-vicuna.json">
{
"model": "wizard-vicuna",
"url": "https://ollama.com/library/wizard-vicuna",
"description": "Wizard Vicuna is a 13B parameter model based on Llama 2 trained by MelodysDreamj.",
"variantsCount": 2,
"variants": [
{
"name": "wizard-vicuna:latest",
"size": "7.4GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizard-vicuna:13b",
"size": "7.4GB",
"context": "2K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/wizardcoder.json">
{
"model": "wizardcoder",
"url": "https://ollama.com/library/wizardcoder",
"description": "State-of-the-art code generation model",
"variantsCount": 2,
"variants": [
{
"name": "wizardcoder:latest",
"size": "3.8GB",
"context": "16K",
"inputType": "Text"
},
{
"name": "wizardcoder:33b",
"size": "19GB",
"context": "16K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/wizardlm-uncensored.json">
{
"model": "wizardlm-uncensored",
"url": "https://ollama.com/library/wizardlm-uncensored",
"description": "Uncensored version of Wizard LM model ",
"variantsCount": 2,
"variants": [
{
"name": "wizardlm-uncensored:latest",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm-uncensored:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/wizardlm.json">
{
"model": "wizardlm",
"url": "https://ollama.com/library/wizardlm",
"description": "General use model based on Llama 2.",
"variantsCount": 73,
"variants": [
{
"name": "wizardlm:7b-q2_K",
"size": "2.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q3_K_S",
"size": "2.9GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q3_K_M",
"size": "3.3GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q3_K_L",
"size": "3.6GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q4_0",
"size": "3.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q4_1",
"size": "4.2GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q4_K_S",
"size": "3.9GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q4_K_M",
"size": "4.1GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q5_0",
"size": "4.7GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q5_1",
"size": "5.1GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q5_K_S",
"size": "4.7GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q5_K_M",
"size": "4.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q6_K",
"size": "5.5GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-q8_0",
"size": "7.2GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:7b-fp16",
"size": "13GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q2_K",
"size": "5.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q3_K_S",
"size": "5.7GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q3_K_M",
"size": "6.3GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q3_K_L",
"size": "6.9GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q4_0",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q4_1",
"size": "8.2GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q4_K_S",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q4_K_M",
"size": "7.9GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q5_0",
"size": "9.0GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q5_1",
"size": "9.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q5_K_S",
"size": "9.0GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q5_K_M",
"size": "9.2GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q6_K",
"size": "11GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-q8_0",
"size": "14GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-llama2-fp16",
"size": "26GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q2_K",
"size": "5.4GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q3_K_S",
"size": "5.7GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q3_K_M",
"size": "6.3GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q3_K_L",
"size": "6.9GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q4_0",
"size": "7.4GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q4_1",
"size": "8.2GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q4_K_S",
"size": "7.4GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q4_K_M",
"size": "7.9GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q5_0",
"size": "9.0GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q5_1",
"size": "9.8GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q5_K_S",
"size": "9.0GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q5_K_M",
"size": "9.2GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q6_K",
"size": "11GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-q8_0",
"size": "14GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:13b-fp16",
"size": "26GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q2_K",
"size": "14GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q3_K_S",
"size": "14GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q3_K_M",
"size": "16GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q3_K_L",
"size": "17GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q4_0",
"size": "18GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q4_1",
"size": "20GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q4_K_S",
"size": "18GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q4_K_M",
"size": "20GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q5_0",
"size": "22GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q5_1",
"size": "24GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q5_K_S",
"size": "22GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q5_K_M",
"size": "23GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q6_K",
"size": "27GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-q8_0",
"size": "35GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:30b-fp16",
"size": "65GB",
"context": "2K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q2_K",
"size": "29GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q3_K_S",
"size": "30GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q3_K_M",
"size": "33GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q3_K_L",
"size": "36GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q4_0",
"size": "39GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q4_1",
"size": "43GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q4_K_S",
"size": "39GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q4_K_M",
"size": "41GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q5_0",
"size": "47GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q5_K_S",
"size": "47GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q5_K_M",
"size": "49GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q6_K",
"size": "57GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "wizardlm:70b-llama2-q8_0",
"size": "73GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/wizardlm2.json">
{
"model": "wizardlm2",
"url": "https://ollama.com/library/wizardlm2",
"description": "State of the art large language model from Microsoft AI with improved performance on complex chat, multilingual, reasoning and agent use cases.",
"variantsCount": 3,
"variants": [
{
"name": "wizardlm2:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "wizardlm2:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "wizardlm2:8x22b",
"size": "80GB",
"context": "64K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/xwinlm.json">
{
"model": "xwinlm",
"url": "https://ollama.com/library/xwinlm",
"description": "Conversational model based on Llama 2 that performs competitively on various benchmarks.",
"variantsCount": 3,
"variants": [
{
"name": "xwinlm:latest",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "xwinlm:7b",
"size": "3.8GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "xwinlm:13b",
"size": "7.4GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/yarn-llama2.json">
{
"model": "yarn-llama2",
"url": "https://ollama.com/library/yarn-llama2",
"description": "An extension of Llama 2 that supports a context of up to 128k tokens.",
"variantsCount": 3,
"variants": [
{
"name": "yarn-llama2:latest",
"size": "3.8GB",
"context": "64K",
"inputType": "Text"
},
{
"name": "yarn-llama2:7b",
"size": "3.8GB",
"context": "64K",
"inputType": "Text"
},
{
"name": "yarn-llama2:13b",
"size": "7.4GB",
"context": "64K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/yarn-mistral.json">
{
"model": "yarn-mistral",
"url": "https://ollama.com/library/yarn-mistral",
"description": "An extension of Mistral to support context windows of 64K or 128K.",
"variantsCount": 2,
"variants": [
{
"name": "yarn-mistral:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "yarn-mistral:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/yi-coder.json">
{
"model": "yi-coder",
"url": "https://ollama.com/library/yi-coder",
"description": "Yi-Coder is a series of open-source code language models that delivers state-of-the-art coding performance with fewer than 10 billion parameters.",
"variantsCount": 3,
"variants": [
{
"name": "yi-coder:latest",
"size": "5.0GB",
"context": "128K",
"inputType": "Text"
},
{
"name": "yi-coder:1.5b",
"size": "866MB",
"context": "128K",
"inputType": "Text"
},
{
"name": "yi-coder:9b",
"size": "5.0GB",
"context": "128K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/yi.json">
{
"model": "yi",
"url": "https://ollama.com/library/yi",
"description": "Yi 1.5 is a high-performing, bilingual language model.",
"variantsCount": 4,
"variants": [
{
"name": "yi:latest",
"size": "3.5GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "yi:6b",
"size": "3.5GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "yi:9b",
"size": "5.0GB",
"context": "4K",
"inputType": "Text"
},
{
"name": "yi:34b",
"size": "19GB",
"context": "4K",
"inputType": "Text"
}
]
}
</file>
<file path="data/models/zephyr.json">
{
"model": "zephyr",
"url": "https://ollama.com/library/zephyr",
"description": "Zephyr is a series of fine-tuned versions of the Mistral and Mixtral models that are trained to act as helpful assistants.",
"variantsCount": 3,
"variants": [
{
"name": "zephyr:latest",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "zephyr:7b",
"size": "4.1GB",
"context": "32K",
"inputType": "Text"
},
{
"name": "zephyr:141b",
"size": "80GB",
"context": "64K",
"inputType": "Text"
}
]
}
</file>
<file path="data/prompts/default-format.md">
Você é um assistente de IA avançado integrado ao OllaHub. Sua principal função é fornecer respostas úteis, precisas e bem formatadas.
## DIRETRIZES DE FORMATAÇÃO (MUITO IMPORTANTE)
Para garantir a melhor experiência de leitura, siga rigorosamente estas regras de Markdown:
### 1. Estrutura e Hierarquia
- Use **Títulos (H1, H2, H3)** para organizar seções. Nunca use apenas negrito para títulos.
- Use **Listas (Bulleted ou Numbered)** para passos, itens ou características.
- Use **Separadores (---)** para dividir grandes blocos de conteúdo.
### 2. Blocos de Código
- SEMPRE use blocos de código triplos (\`\`\`) para qualquer trecho de código, comando de terminal ou configuração.
- SEMPRE especifique a linguagem após os acentos graves (ex: \`\`\`python, \`\`\`bash, \`\`\`json).
- Para menções curtas de código no meio do texto, use `código inline`.
### 3. Ênfase e Destaque
- Use **Negrito** para conceitos chave ou avisos importantes.
- Use *Itálico* para termos estrangeiros ou ênfase sutil.
- Use > Blockquotes para citações ou notas laterais.
### 4. Links
- Formate links corretamente: `[Texto do Link](URL)`.
## ESTILO DE RESPOSTA
- Seja direto e objetivo. Evite preâmbulos desnecessários ("Claro, aqui está...").
- Se a resposta for longa, comece com um resumo executivo.
- Ao explicar código, comente o que cada parte faz.
</file>
<file path="data/prompts/prompt-gen.md">
Você é um Especialista em Engenharia de Prompts com raciocínio sequencial e acesso a fontes técnicas de primeira qualidade.
## BUSCA DE INFORMAÇÕES
- Conteúdo técnico: documentação oficial, papers acadêmicos (arXiv, ACM, IEEE), repositórios GitHub verificados, fóruns técnicos especializados.
- Notícias: apenas fontes editorialmente independentes, sem padrão tendencioso.
- Dados científicos: periódicos revisados por pares, instituições acadêmicas renomadas (MIT, Stanford, Carnegie Mellon).
## RACIOCÍNIO SEQUENCIAL
1. Decomponha o pedido em componentes específicos.
2. Identifique lacunas de conhecimento e prioridades de pesquisa.
3. Valide cada afirmação técnica com múltiplas fontes confiáveis.
4. Apresente raciocínio passo-a-passo antes do prompt final.
## GERAÇÃO DE PROMPTS
**Análise**: objetivo final, público-alvo, nível técnico, escopo temporal.
**Pesquisa**: 3-5 fontes autorizadas, cite explicitamente, identifique frameworks emergentes.
**Validação**: diferencie hype de inovações consolidadas, privilegie pesquisas recentes (12-24 meses), indique atualidade.
## ESTRUTURA DE SAÍDA
1. Propósito claramente definido
2. Contexto técnico atualizado com fontes verificadas
3. Instruções sequenciais estruturadas
4. Critérios de qualidade mensuráveis
5. Restrições éticas e técnicas
6. Citações discretas de fundamentos teóricos
## RESTRIÇÕES CRÍTICAS
- Gere APENAS o prompt solicitado, sem explicações adicionais.
- Limite máximo: 3900 caracteres por resposta.
- Questione abordagens mais refinadas disponíveis.
- Indique quando conhecimento requer atualização futura.
- Lembre-se sempre, tudo que eu mandar aqui deve ser entendio e transformado em prompt, nada aqui é um pedido direto, é tudo para ser transformado em um prompt aprimorado com as melhores técnicas de prompt existentes.
</file>
<file path="eslint.config.mjs">
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
// Override default ignores of eslint-config-next.
globalIgnores([
// Default ignores of eslint-config-next:
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
]),
]);
export default eslintConfig;
</file>
<file path="hooks/use-chat.ts">
import { useState, useRef } from 'react';
export interface Message {
role: 'user' | 'assistant' | 'system';
content: string;
}
export function useChat() {
const [messages, setMessages] = useState<Message[]>([]);
const [isLoading, setIsLoading] = useState(false);
const abortControllerRef = useRef<AbortController | null>(null);
const sendMessage = async (content: string, model: string, systemPrompt?: string) => {
setIsLoading(true);
const newMessages: Message[] = [
...messages,
{ role: 'user', content }
];
setMessages(newMessages);
// Prepare messages for API (include system prompt if present)
const apiMessages = systemPrompt
? [{ role: 'system', content: systemPrompt }, ...newMessages]
: newMessages;
abortControllerRef.current = new AbortController();
try {
const response = await fetch('http://localhost:11434/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model,
messages: apiMessages,
stream: true,
}),
signal: abortControllerRef.current.signal,
});
if (!response.ok) throw new Error('Failed to send message');
if (!response.body) throw new Error('No response body');
const reader = response.body.getReader();
const decoder = new TextDecoder();
// Add empty assistant message to start streaming into
setMessages(prev => [...prev, { role: 'assistant', content: '' }]);
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\n').filter(line => line.trim() !== '');
for (const line of lines) {
try {
const json = JSON.parse(line);
if (json.message?.content) {
setMessages(prev => {
const last = prev[prev.length - 1];
if (last.role === 'assistant') {
return [
...prev.slice(0, -1),
{ ...last, content: last.content + json.message.content }
];
}
return prev;
});
}
if (json.done) {
setIsLoading(false);
}
} catch (e) {
console.error('Error parsing chunk', e);
}
}
}
} catch (error: any) {
if (error.name === 'AbortError') {
console.log('Request aborted');
} else {
console.error('Chat error:', error);
setMessages(prev => [...prev, { role: 'assistant', content: 'Error: Failed to get response from Ollama.' }]);
}
} finally {
setIsLoading(false);
abortControllerRef.current = null;
}
};
const stop = () => {
if (abortControllerRef.current) {
abortControllerRef.current.abort();
setIsLoading(false);
}
};
const clearChat = () => {
setMessages([]);
};
return { messages, sendMessage, isLoading, stop, clearChat };
}
</file>
<file path="hooks/use-hardware.ts">
import { useState, useEffect } from 'react';
import { invoke } from '@tauri-apps/api/core';
import { SystemSpecs } from '@/lib/recommendation';
export function useHardware() {
const [specs, setSpecs] = useState<SystemSpecs | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchSpecs() {
try {
const data = await invoke<SystemSpecs>('get_system_specs');
// Simulate a small delay for the "scanning" effect
setTimeout(() => {
setSpecs(data);
setLoading(false);
}, 1500);
} catch (error) {
console.error("Failed to get system specs:", error);
setLoading(false);
}
}
fetchSpecs();
}, []);
return { specs, loading };
}
</file>
<file path="hooks/use-local-models.ts">
import { useState, useEffect, useCallback } from 'react';
import { invoke } from '@tauri-apps/api/core';
export interface LocalModel {
name: string;
size: string;
id: string;
modified_at: string;
}
export function useLocalModels() {
const [models, setModels] = useState<LocalModel[]>([]);
const [loading, setLoading] = useState(true);
const fetchModels = useCallback(async () => {
setLoading(true);
try {
const list = await invoke<LocalModel[]>('list_local_models');
setModels(list);
} catch (error) {
console.error("Failed to list models:", error);
} finally {
setLoading(false);
}
}, []);
const deleteModel = async (name: string) => {
try {
await invoke('delete_model', { name });
await fetchModels(); // Refresh list
} catch (error) {
console.error("Failed to delete model:", error);
throw error;
}
};
useEffect(() => {
fetchModels();
}, [fetchModels]);
return { models, loading, refresh: fetchModels, deleteModel };
}
</file>
<file path="hooks/use-ollama-check.ts">
import { useState, useEffect } from 'react';
import { invoke } from '@tauri-apps/api/core';
export type OllamaStatus = 'checking' | 'not_installed' | 'installed_stopped' | 'running';
export function useOllamaCheck() {
const [status, setStatus] = useState<OllamaStatus>('checking');
const check = async () => {
// Don't set checking here if we want to silently revalidate,
// but for initial load or explicit re-check it is fine.
// Only set checking if it's not already in a known state to avoid flicker?
// For now simple is better.
try {
const installed = await invoke<boolean>('check_ollama_installed');
if (!installed) {
setStatus('not_installed');
return;
}
const running = await invoke<boolean>('check_ollama_running');
if (!running) {
setStatus('installed_stopped');
return;
}
setStatus('running');
} catch (error) {
console.error('Failed to check ollama:', error);
// If invoke fails (e.g. backend not ready), we might want to handle gracefully
setStatus('not_installed');
}
};
useEffect(() => {
check();
}, []);
return { status, check };
}
</file>
<file path="hooks/use-prompt-generator.ts">
import { useState } from 'react';
// Hardcoded for now to avoid FS complexity in v1, but ideally read from file
const PROMPT_GEN_SYSTEM = `Você é um Especialista em Engenharia de Prompts com raciocínio sequencial e acesso a fontes técnicas de primeira qualidade.
## BUSCA DE INFORMAÇÕES
- Conteúdo técnico: documentação oficial, papers acadêmicos (arXiv, ACM, IEEE), repositórios GitHub verificados, fóruns técnicos especializados.
- Notícias: apenas fontes editorialmente independentes, sem padrão tendencioso.
- Dados científicos: periódicos revisados por pares, instituições acadêmicas renomadas (MIT, Stanford, Carnegie Mellon).
## RACIOCÍNIO SEQUENCIAL
1. Decomponha o pedido em componentes específicos.
2. Identifique lacunas de conhecimento e prioridades de pesquisa.
3. Valide cada afirmação técnica com múltiplas fontes confiáveis.
4. Apresente raciocínio passo-a-passo antes do prompt final.
## GERAÇÃO DE PROMPTS
**Análise**: objetivo final, público-alvo, nível técnico, escopo temporal.
**Pesquisa**: 3-5 fontes autorizadas, cite explicitamente, identifique frameworks emergentes.
**Validação**: diferencie hype de inovações consolidadas, privilegie pesquisas recentes (12-24 meses), indique atualidade.
## ESTRUTURA DE SAÍDA
1. Propósito claramente definido
2. Contexto técnico atualizado com fontes verificadas
3. Instruções sequenciais estruturadas
4. Critérios de qualidade mensuráveis
5. Restrições éticas e técnicas
6. Citações discretas de fundamentos teóricos
## RESTRIÇÕES CRÍTICAS
- Gere APENAS o prompt solicitado, sem explicações adicionais.
- Limite máximo: 3900 caracteres por resposta.
- Questione abordagens mais refinadas disponíveis.
- Indique quando conhecimento requer atualização futura.
- Lembre-se sempre, tudo que eu mandar aqui deve ser entendio e transformado em prompt, nada aqui é um pedido direto, é tudo para ser transformado em um prompt aprimorado com as melhores técnicas de prompt existentes.`;
export function usePromptGenerator() {
const [isGenerating, setIsGenerating] = useState(false);
const generatePrompt = async (userGoal: string, model: string): Promise<string> => {
setIsGenerating(true);
try {
const response = await fetch('http://localhost:11434/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model,
messages: [
{ role: 'system', content: PROMPT_GEN_SYSTEM },
{ role: 'user', content: userGoal }
],
stream: false, // We want the full prompt at once for this utility
}),
});
if (!response.ok) throw new Error('Failed to generate prompt');
const data = await response.json();
return data.message?.content || "";
} catch (error) {
console.error("Prompt generation failed:", error);
throw error;
} finally {
setIsGenerating(false);
}
};
return { generatePrompt, isGenerating };
}
</file>
<file path="hooks/use-system-monitor.ts">
import { useState, useEffect } from 'react';
import { invoke } from '@tauri-apps/api/core';
import { listen } from '@tauri-apps/api/event';
export interface SystemStats {
cpu_usage: number;
memory_used: number;
memory_total: number;
}
export function useSystemMonitor() {
const [stats, setStats] = useState<SystemStats | null>(null);
useEffect(() => {
// Start the monitor thread in backend
invoke('start_system_monitor');
const unlisten = listen<SystemStats>('system-stats', (event) => {
setStats(event.payload);
});
return () => {
unlisten.then(f => f());
};
}, []);
return stats;
}
</file>
<file path="lib/recommendation.ts">
export interface SystemSpecs {
total_memory: number; // Bytes
cpu_count: number;
os_name: string;
}
export interface ModelRecommendation {
modelId: string;
reason: string;
minRam: number; // GB
}
export const RECOMMENDED_MODELS = [
{ id: 'llama3.2:1b', name: 'Llama 3.2 1B', size: '1.3GB', minRam: 4 },
{ id: 'llama3.2:3b', name: 'Llama 3.2 3B', size: '2.0GB', minRam: 8 },
{ id: 'gemma2:9b', name: 'Gemma 2 9B', size: '5.4GB', minRam: 12 },
{ id: 'llama3.1:8b', name: 'Llama 3.1 8B', size: '4.7GB', minRam: 16 },
{ id: 'mistral:latest', name: 'Mistral 7B', size: '4.1GB', minRam: 16 },
];
export function getRecommendation(specs: SystemSpecs): ModelRecommendation {
const ramGB = specs.total_memory / (1024 * 1024 * 1024);
if (ramGB < 8) {
return {
modelId: 'llama3.2:1b',
reason: 'Ideal para sistemas com pouca memória (< 8GB). Rápido e leve.',
minRam: 4
};
}
if (ramGB < 12) {
return {
modelId: 'llama3.2:3b',
reason: 'Equilíbrio perfeito entre velocidade e inteligência para seu sistema.',
minRam: 8
};
}
if (ramGB < 16) {
return {
modelId: 'gemma2:9b',
reason: 'Modelo avançado do Google, ótimo para raciocínio.',
minRam: 12
};
}
return {
modelId: 'llama3.1:8b',
reason: 'Padrão da indústria. Alta capacidade de raciocínio e conhecimento geral.',
minRam: 16
};
}
</file>
<file path="lib/utils.ts">
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
</file>
<file path="next.config.ts">
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: 'export',
images: {
unoptimized: true,
},
webpack: (config) => {
config.module.rules.push({
test: /\.md$/,
use: 'raw-loader',
});
return config;
},
// Configuração Turbopack: objeto vazio silencia o erro
// Turbopack ainda não suporta raw-loader, então usaremos webpack para builds
turbopack: {},
};
export default nextConfig;
</file>
<file path="package.json">
{
"name": "temp_app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --webpack",
"build": "next build",
"start": "next start",
"lint": "eslint"
},
"dependencies": {
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-progress": "^1.1.8",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.13",
"@tauri-apps/api": "^2.9.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"framer-motion": "^12.23.24",
"lucide-react": "^0.554.0",
"next": "16.0.3",
"next-themes": "^0.4.6",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-markdown": "^10.1.0",
"react-resizable-panels": "^3.0.6",
"remark-gfm": "^4.0.1",
"tailwind-merge": "^3.4.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@tauri-apps/cli": "^2.9.4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.0.3",
"raw-loader": "^4.0.2",
"tailwindcss": "^4",
"tw-animate-css": "^1.4.0",
"typescript": "^5"
}
}
</file>
<file path="postcss.config.mjs">
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
};
export default config;
</file>
<file path="public/file.svg">
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
</file>
<file path="public/globe.svg">
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
</file>
<file path="public/next.svg">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
</file>
<file path="public/vercel.svg">
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
</file>
<file path="public/window.svg">
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
</file>
<file path="README.md">
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
</file>
<file path="src-tauri/.gitignore">
# Generated by Cargo
# will have compiled files and executables
/target/
/gen/schemas
</file>
<file path="src-tauri/build.rs">
fn main() {
tauri_build::build()
}
</file>
<file path="src-tauri/capabilities/default.json">
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "enables the default permissions",
"windows": [
"main"
],
"permissions": [
"core:default"
]
}
</file>
<file path="src-tauri/Cargo.toml">
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"
rust-version = "1.77.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2.5.1", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri = { version = "2.9.2", features = [] }
tauri-plugin-log = "2"
reqwest = { version = "0.12", features = ["json"] }
sysinfo = "0.36.1"
</file>
<file path="src-tauri/src/lib.rs">
use std::process::{Command, Stdio};
use std::io::{BufRead, BufReader};
use std::time::Duration;
use tauri::{command, Window, Emitter};
use sysinfo::System;
#[cfg(target_os = "windows")]
use std::os::windows::process::CommandExt;
#[derive(serde::Serialize)]
struct SystemSpecs {
total_memory: u64,
cpu_count: usize,
os_name: String,
}
#[derive(serde::Serialize, Clone)]
struct SystemStats {
cpu_usage: f32,
memory_used: u64,
memory_total: u64,
}
#[derive(serde::Serialize)]
struct LocalModel {
name: String,
size: String,
id: String,
modified_at: String,
}
#[command]
fn get_system_specs() -> SystemSpecs {
let mut sys = System::new_all();
sys.refresh_all();
SystemSpecs {
total_memory: sys.total_memory(),
cpu_count: sys.cpus().len(),
os_name: System::name().unwrap_or("Unknown".to_string()),
}
}
#[command]
fn start_system_monitor(window: Window) {
std::thread::spawn(move || {
let mut sys = System::new_all();
loop {
sys.refresh_cpu_all();
sys.refresh_memory();
let cpu_usage = sys.global_cpu_usage();
let memory_used = sys.used_memory();
let memory_total = sys.total_memory();
let stats = SystemStats {
cpu_usage,
memory_used,
memory_total,
};
if window.emit("system-stats", stats).is_err() {
break; // Stop if window is closed
}
std::thread::sleep(Duration::from_secs(2));
}
});
}
#[command]
fn list_local_models() -> Vec<LocalModel> {
let output = Command::new("ollama")
.arg("list")
.output();
match output {
Ok(output) => {
let stdout = String::from_utf8_lossy(&output.stdout);
let mut models = Vec::new();
// Skip header line
for line in stdout.lines().skip(1) {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() >= 4 {
// NAME ID SIZE MODIFIED
// Note: Modified can be "2 days ago" (multiple parts)
// We'll take the first part as name, second as ID, third as size
// and the rest as modified
let name = parts[0].to_string();
let id = parts[1].to_string();
let size = parts[2].to_string();
let modified_at = parts[3..].join(" ");
models.push(LocalModel {
name,
id,
size,
modified_at,
});
}
}
models
}
Err(_) => Vec::new(),
}
}
#[command]
async fn delete_model(name: String) -> Result<(), String> {
let output = Command::new("ollama")
.arg("rm")
.arg(&name)
.output()
.map_err(|e| e.to_string())?;
if output.status.success() {
Ok(())
} else {
Err(String::from_utf8_lossy(&output.stderr).to_string())
}
}
#[command]
fn check_if_model_installed(name: String) -> bool {
let output = Command::new("ollama")
.arg("list")
.output();
match output {
Ok(output) => {
let stdout = String::from_utf8_lossy(&output.stdout);
stdout.contains(&name)
}
Err(_) => false,
}
}
#[command]
async fn pull_model(window: Window, name: String) -> Result<(), String> {
let mut child = Command::new("ollama")
.arg("pull")
.arg(&name)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.map_err(|e| e.to_string())?;
let stdout = child.stdout.take().ok_or("Failed to open stdout")?;
let reader = BufReader::new(stdout);
for line in reader.lines() {
match line {
Ok(l) => {
window.emit("download-progress", l).unwrap_or(());
}
Err(_) => break,
}
}
let status = child.wait().map_err(|e| e.to_string())?;
if status.success() {
Ok(())
} else {
Err("Failed to pull model".to_string())
}
}
#[command]
fn check_ollama_installed() -> bool {
match Command::new("ollama").arg("--version").output() {
Ok(output) => output.status.success(),
Err(_) => false,
}
}
#[command]
async fn check_ollama_running() -> bool {
match reqwest::get("http://localhost:11434").await {
Ok(resp) => resp.status().is_success(),
Err(_) => false,
}
}
#[command]
fn start_ollama_server() -> Result<(), String> {
let mut cmd = Command::new("ollama");
cmd.arg("serve");
#[cfg(target_os = "windows")]
{
const CREATE_NO_WINDOW: u32 = 0x08000000;
cmd.creation_flags(CREATE_NO_WINDOW);
}
// Spawn detached
cmd.spawn()
.map_err(|e| format!("Failed to start ollama: {}", e))?;
Ok(())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
if cfg!(debug_assertions) {
app.handle().plugin(
tauri_plugin_log::Builder::default()
.level(log::LevelFilter::Info)
.build(),
)?;
}
Ok(())
})
.invoke_handler(tauri::generate_handler![
check_ollama_installed,
check_ollama_running,
get_system_specs,
check_if_model_installed,
pull_model,
start_ollama_server,
start_system_monitor,
list_local_models,
delete_model
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
</file>
<file path="src-tauri/src/main.rs">
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
app_lib::run();
}
</file>
<file path="src-tauri/tauri.conf.json">
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "ollahub",
"version": "0.1.0",
"identifier": "com.tauri.dev",
"build": {
"frontendDist": "../out",
"devUrl": "http://localhost:3000",
"beforeDevCommand": "pnpm dev",
"beforeBuildCommand": "pnpm build"
},
"app": {
"windows": [
{
"title": "OllaHub",
"width": 800,
"height": 600,
"resizable": true,
"fullscreen": false
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/[email protected]",
"icons/icon.icns",
"icons/icon.ico"
]
}
}
</file>
<file path="tsconfig.json">
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts",
"**/*.mts"
],
"exclude": ["node_modules"]
}
</file>
</files>