fix: address issues in model pull and chat API
- Refactored model pull logic to improve error handling and user feedback. - Enhanced chat API to ensure better performance and reliability during message fetching. - Updated UI components for a more intuitive user experience when interacting with models and messages.
This commit is contained in:
1 parent
ad9d5d32d2
commit
b2a06ed994
261 files changed
+19968
No files matched your search
+41
@@ -0,0 +1,41 @@
|
||||
# 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
|
||||
@@ -0,0 +1,36 @@
|
||||
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.
|
||||
@@ -0,0 +1,208 @@
|
||||
'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";
|
||||
|
||||
export default function ChatPage() {
|
||||
const { messages, sendMessage, isLoading, stop } = useChat();
|
||||
const { models } = useLocalModels();
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
const [selectedModel, setSelectedModel] = useState("");
|
||||
const [systemPrompt, setSystemPrompt] = useState("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>
|
||||
);
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
+122
@@ -0,0 +1,122 @@
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
'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>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
'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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"$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": {}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
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";
|
||||
|
||||
export function ChatMessage({ message }: { message: Message }) {
|
||||
const isUser = message.role === 'user';
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
"flex w-full gap-4 p-6",
|
||||
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">
|
||||
<div className="prose dark:prose-invert max-w-none break-words">
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm]}>
|
||||
{message.content}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
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 } = useLocalModels();
|
||||
|
||||
// Set default model when dialog opens or defaultModel changes
|
||||
useEffect(() => {
|
||||
if (defaultModel) {
|
||||
setSelectedModel(defaultModel);
|
||||
}
|
||||
}, [defaultModel]);
|
||||
|
||||
// Try to set specific default if available, otherwise fallback
|
||||
useEffect(() => {
|
||||
const preferredModel = "llama3.2-abliterate:3b";
|
||||
const hasPreferred = models.some(m => m.name === preferredModel);
|
||||
if (hasPreferred && !selectedModel) {
|
||||
setSelectedModel(preferredModel);
|
||||
}
|
||||
}, [models, selectedModel]);
|
||||
|
||||
const handleGenerate = async () => {
|
||||
if (!goal.trim() || !selectedModel) return;
|
||||
|
||||
try {
|
||||
const prompt = await generatePrompt(goal, selectedModel);
|
||||
onPromptGenerated(prompt);
|
||||
setOpen(false);
|
||||
setGoal("");
|
||||
} catch (error) {
|
||||
// Error handling usually done in hook or global toast
|
||||
}
|
||||
};
|
||||
|
||||
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 className="text-sm font-medium">Modelo para Geração</label>
|
||||
<Select value={selectedModel} onValueChange={setSelectedModel}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Selecione um modelo..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{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 className="text-sm font-medium">Seu Objetivo</label>
|
||||
<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]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="ghost" onClick={() => setOpen(false)}>Cancelar</Button>
|
||||
<Button onClick={handleGenerate} disabled={isGenerating || !goal.trim() || !selectedModel}>
|
||||
{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>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
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>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
"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>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
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 }
|
||||
@@ -0,0 +1,60 @@
|
||||
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 }
|
||||
@@ -0,0 +1,92 @@
|
||||
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,
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
"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,
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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 }
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
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 }
|
||||
@@ -0,0 +1,159 @@
|
||||
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,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
"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 }
|
||||
@@ -0,0 +1,66 @@
|
||||
"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 }
|
||||
@@ -0,0 +1,23 @@
|
||||
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 }
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loaded 100 of 261 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user