Skip to content

Commit

Permalink
use Ollama instead of Gemini
Browse files Browse the repository at this point in the history
  • Loading branch information
luongnv89 committed Jan 8, 2025
1 parent fb05465 commit 22145b1
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 59 deletions.
22 changes: 6 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,18 @@
<div style="display: flex; align-items: center; justify-content: center;">
<img alt="Gemini Coder" src="./public/logo.svg" style="height: 50px;">
<h1 style="margin-left: 10px;">Gemini Coder</h1>
</div>
Generate small apps with one prompt. Powered by the Ollama API.

<p align="center">
Generate small apps with one prompt. Powered by the Gemini API.
</p>
Try it in https://huggingface.co/spaces/luongnv89/ollama-coder

Try it in https://huggingface.co/spaces/osanseviero/gemini-coder

This project is fully based on [llamacoder](https://github.com/Nutlope/llamacoder). Please follow [Nutlope](https://github.com/Nutlope) and give them a star..
This project is fully based on [geminicoder](https://github.com/osanseviero/geminicoder).

## Tech stack

- [Gemini API](https://ai.google.dev/gemini-api/docs) to use Gemini 1.5 Pro, Gemini 1.5 Flash, and Gemini 2.0 Flash Experimental
- [Ollama](https://ollama.com) - Recommend pull the following models: `qwen2.5-coder:14b`, `phi3:14b`. Add your models in `./app/(main)/page.tsx`
- [Sandpack](https://sandpack.codesandbox.io/) for the code sandbox
- Next.js app router with Tailwind

You can also experiment with Gemini in [Google AI Studio](https://aistudio.google.com/).

## Cloning & running

1. Clone the repo: `git clone https://github.com/osanseviero/geminicoder`
2. Create a `.env` file and add your [Google AI Studio API key](https://aistudio.google.com/app/apikey): `GOOGLE_AI_API_KEY=`
1. Clone the repo: `git clone https://github.com/luongnv89/ollama-coder`
3. Run `npm install` and `npm run dev` to install dependencies and run locally

**This is a personal project and not a Google official project**
**This is a personal project and not a Ollama official project**
16 changes: 6 additions & 10 deletions app/(main)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,13 @@ export default function Home() {
let [prompt, setPrompt] = useState("");
let models = [
{
label: "gemini-2.0-flash-exp",
value: "gemini-2.0-flash-exp",
label: "qwen2.5-coder:14b",
value: "qwen2.5-coder:14b",
},
{
label: "gemini-1.5-pro",
value: "gemini-1.5-pro",
label: "phi3:14b",
value: "phi3:14b",
},
{
label: "gemini-1.5-flash",
value: "gemini-1.5-flash",
}
];
let [model, setModel] = useState(models[0].value);
let [modification, setModification] = useState("");
Expand Down Expand Up @@ -106,11 +102,11 @@ export default function Home() {
<main className="mt-12 flex w-full flex-1 flex-col items-center px-4 text-center sm:mt-1">
<a
className="mb-4 inline-flex h-7 shrink-0 items-center gap-[9px] rounded-[50px] border-[0.5px] border-solid border-[#E6E6E6] bg-[rgba(234,238,255,0.65)] dark:bg-[rgba(30,41,59,0.5)] dark:border-gray-700 px-7 py-5 shadow-[0px_1px_1px_0px_rgba(0,0,0,0.25)]"
href="https://ai.google.dev/gemini-api/docs"
href="https://ollama.com/"
target="_blank"
>
<span className="text-center">
Powered by <span className="font-medium">Gemini API</span>
Powered by <span className="font-medium">Ollama</span>
</span>
</a>
<h1 className="my-6 max-w-3xl text-4xl font-bold text-gray-800 dark:text-white sm:text-6xl">
Expand Down
47 changes: 28 additions & 19 deletions app/api/generateCode/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import dedent from "dedent";
import { z } from "zod";
import { GoogleGenerativeAI } from "@google/generative-ai";

const apiKey = process.env.GOOGLE_AI_API_KEY || "";
const genAI = new GoogleGenerativeAI(apiKey);
const ollamaApiUrl = "http://localhost:11434/api/generate"; // Ollama API endpoint

export async function POST(req: Request) {
let json = await req.json();
Expand All @@ -26,30 +24,41 @@ export async function POST(req: Request) {
let { model, messages } = result.data;
let systemPrompt = getSystemPrompt();

const geminiModel = genAI.getGenerativeModel({model: model});
const prompt =
messages[0].content +
systemPrompt +
"\nPlease ONLY return code, NO backticks or language names. Don't start with ```typescript or ```javascript or ```tsx or ```.";

const geminiStream = await geminiModel.generateContentStream(
messages[0].content + systemPrompt + "\nPlease ONLY return code, NO backticks or language names. Don't start with \`\`\`typescript or \`\`\`javascript or \`\`\`tsx or \`\`\`."
);
console.log(prompt);

console.log(messages[0].content + systemPrompt + "\nPlease ONLY return code, NO backticks or language names. Don't start with \`\`\`typescript or \`\`\`javascript or \`\`\`tsx or \`\`\`.")

const readableStream = new ReadableStream({
async start(controller) {
for await (const chunk of geminiStream.stream) {
const chunkText = chunk.text();
controller.enqueue(new TextEncoder().encode(chunkText));
}
controller.close();
const ollamaResponse = await fetch(ollamaApiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
model: model,
prompt: prompt,
stream: false, // Disable streaming
}),
});

return new Response(readableStream);
if (!ollamaResponse.ok) {
return new Response("Failed to fetch response from Ollama API", {
status: 500,
});
}

const responseData = await ollamaResponse.json();
const responseText = responseData.response; // Extract the response text from Ollama

return new Response(responseText, {
headers: { "Content-Type": "text/plain" },
});
}

function getSystemPrompt() {
let systemPrompt =
`You are an expert frontend React engineer who is also a great UI/UX designer. Follow the instructions carefully, I will tip you $1 million if you do a good job:
let systemPrompt = `You are an expert frontend React engineer who is also a great UI/UX designer. Follow the instructions carefully, I will tip you $1 million if you do a good job:
- Think carefully step by step.
- Create a React component for whatever the user asked you to create and make sure it can run by itself by using a default export
Expand Down
12 changes: 6 additions & 6 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ import type { Metadata } from "next";
import "./globals.css";
import { ThemeProvider } from "@/components/ThemeProvider";

let title = "Gemini Coder – AI Code Generator";
let description = "Generate your next app with Gemini";
let url = "https://llamacoder.io/";
let ogimage = "https://www.gstatic.com/lamda/images/gemini_sparkle_v002_d4735304ff6292a690345.svg";
let sitename = "geminicoder.io";
let title = "Ollama Coder – AI Code Generator";
let description = "Welcome to Ollama Coder, the AI code generator that helps you build your next app.";
let url = "https://ollama-coder.ai/";
let ogimage = "ollama.svg";
let sitename = "ollama-coder.ai";

export const metadata: Metadata = {
metadataBase: new URL(url),
title,
description,
icons: {
icon: "/favicon.ico",
icon: "favicon.ico",
},
openGraph: {
images: [ogimage],
Expand Down
22 changes: 22 additions & 0 deletions app/ollama.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,26 @@ export default function Footer() {
<div className="font-medium">
Built with{" "}
<a
href="https://ai.google.dev/gemini-api/docs"
href="https://ollama.com"
className="font-semibold text-blue-600 underline-offset-4 transition hover:text-gray-700 hover:underline"
target="_blank"
>
Gemini API
Ollama
</a>{" "}
and{" "}
<a
href="https://github.com/nutlope/llamacoder"
className="font-semibold text-blue-600 underline-offset-4 transition hover:text-gray-700 hover:underline"
target="_blank"
>
Inspired on Llamacoder
Inspired on GeminiCoder
</a>
. This is not an official Google product.
. This is not an official Ollama product.
</div>
</div>
<div className="flex space-x-4 pb-4 sm:pb-0">
<Link
href="https://twitter.com/osanseviero"
href="https://twitter.com/luongnv89"
className="group"
aria-label=""
target="_blank"
Expand All @@ -39,7 +39,7 @@ export default function Footer() {
</svg>
</Link>
<Link
href="https://github.com/osanseviero/geminicoder"
href="https://github.com/luongnv89/ollama-coder"
className="group"
aria-label="TaxPal on GitHub"
target="_blank"
Expand Down
4 changes: 2 additions & 2 deletions components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ export default function Header() {
<Link href="/" className="absolute flex items-center gap-2">
<Image alt="header text" src={logo} className="h-5 w-5" />
<h1 className="text-xl tracking-tight">
<span className="text-blue-600">Gemini</span>Coder
<span className="text-blue-600">Ollama</span>Coder
</h1>
</Link>
<a
href="https://github.com/osanseviero/geminicoder"
href="https://github.com/luongnv89/ollama-coder"
target="_blank"
className="ml-auto hidden items-center gap-3 rounded-2xl bg-white dark:bg-[#1E293B] dark:text-gray-100 px-6 py-2 sm:flex border border-gray-200 dark:border-gray-700"
>
Expand Down

0 comments on commit 22145b1

Please sign in to comment.