Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions packages/core/script/generate-ollama-cloud.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
#!/usr/bin/env bun

/**
* Generates model files from the data in Ollama Cloud's API.
*
* Ollama Cloud does not provide some data fields, such as release date or
* knowledge cutoff. The `family` field provided by Ollama Cloud may not match
* the values in family.ts. We expect that when TOML validaton fails, the
* maintainer will manually source those data points (such as from other
* provider TOML files, or from the internet at large). This script preserves
* those fields when overwriting Ollama Cloud's TOML files.
*/

import { z } from "zod";
import path from "node:path";

const modelsDir = path.join(
import.meta.dirname,
"..",
"..",
"..",
"providers",
"ollama-cloud",
"models"
);

function modelFileName(modelName: string): string {
return modelName + ".toml";
}

const OllamaTagsResponse = z.object({
models: z.array(
z.object({
name: z.string(),
})
),
});

type OllamaTagsResponse = z.infer<typeof OllamaTagsResponse>;

const OllamaModelDetails = z.object({
modified_at: z.string(),
details: z.object({
parent_model: z.string(),
format: z.string(),
family: z.string(),
families: z.array(z.string()).nullable(),
parameter_size: z.string().transform(Number),
quantization_level: z.string(),
}),
model_info: z.record(z.union([z.string(), z.number()])),
capabilities: z.array(z.enum(["thinking", "completion", "tools", "vision"])),
});

type OllamaModelDetails = z.infer<typeof OllamaModelDetails>;

function generateToml(
modelName: string,
data: OllamaModelDetails & {
release_date?: string;
knowledge?: string;
family: string;
output: number;
}
): string {
const capabilities = data.capabilities;
const modelInfo = data.model_info;
const contextLength =
(modelInfo[`${data.details.family}.context_length`] as number) ?? 0;

const lines: string[] = [];
const attachment = capabilities.includes("vision"); // Copied from generate-venice.ts

lines.push(`name = "${modelName}"`);
lines.push(`family = "${data.family}"`);
lines.push(`attachment = ${attachment}`);
lines.push(`reasoning = ${capabilities.includes("thinking")}`);
lines.push(`tool_call = ${capabilities.includes("tools")}`);
if (data.release_date) {
lines.push(`release_date = "${data.release_date}"`);
}
if (data.knowledge) {
lines.push(`knowledge = "${data.knowledge}"`);
}
lines.push(`last_updated = "${new Date().toISOString().slice(0, 10)}"`);
lines.push(`open_weights = true`);
lines.push("");
lines.push("[limit]");
lines.push(`context = ${contextLength}`);
lines.push(`output = ${data.output}`);
lines.push("");
lines.push("[modalities]");
lines.push(`input = ${capabilities.includes("vision") ? '["text", "image"]' : '["text"]'}`);
lines.push('output = ["text"]');
return lines.join("\n") + "\n";
}

const tagsResponse = await fetch("https://ollama.com/api/tags");
if (!tagsResponse.ok) {
console.error(
`Failed to fetch tags: ${tagsResponse.status} ${tagsResponse.statusText}`
);
process.exit(1);
}

const tagsJson = await tagsResponse.json();
const tagsParsed = OllamaTagsResponse.safeParse(tagsJson);
if (!tagsParsed.success) {
console.error("Invalid tags response:", tagsParsed.error.errors);
process.exit(1);
}
const tagsData: OllamaTagsResponse = tagsParsed.data;
const modelNames = tagsData.models.map((m) => m.name);

console.log(`Fetching details for ${modelNames.length} models...`);

const modelsData: Array<{ name: string; data: OllamaModelDetails }> = [];
for (const modelName of modelNames) {
const showResponse = await fetch("https://ollama.com/api/show", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ model: modelName }),
});

if (!showResponse.ok) {
console.error(
`Failed to fetch details for ${modelName}: ${showResponse.status} ${showResponse.statusText}`
);
process.exit(1);
}

const showJson = await showResponse.json();
const showParsed = OllamaModelDetails.safeParse(showJson);
if (!showParsed.success) {
console.error(
`Invalid response for ${modelName}:`,
showParsed.error.errors
);
process.exit(1);
}

modelsData.push({ name: modelName, data: showParsed.data });
}

console.log(`Fetched all models. Writing new files...`);

type ExistingMetadata = {
release_date: string;
knowledge?: string;
family: string;
};

let created = 0;
for (const { name, data } of modelsData) {
const fileName = modelFileName(name);
const filePath = path.join(modelsDir, fileName);

let metadata: ExistingMetadata = {};
try {
const existingToml = await Bun.file(filePath).text();
const parsed = Bun.TOML.parse(existingToml);
const { release_date, knowledge, family } = parsed as ExistingMetadata;
metadata = { release_date, knowledge, family };
} catch {
// File doesn't exist
}

Object.assign(
data,
metadata,
// Not provided by Ollama API. Zero appears to be the appropriate "unknown
// value" value.
{ output: 0 }
);

data.family = data.family ?? data.details.family;

await Bun.write(filePath, generateToml(name, data));
console.log(`Created: ${fileName}`);
created++;
}

console.log(`\nDone. Created ${created}`);
18 changes: 0 additions & 18 deletions providers/ollama-cloud/models/cogito-2.1:671b-cloud.toml

This file was deleted.

16 changes: 16 additions & 0 deletions providers/ollama-cloud/models/cogito-2.1:671b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name = "cogito-2.1:671b"
family = "cogito"
attachment = false
reasoning = true
tool_call = true
release_date = "2025-11-19"
last_updated = "2026-01-18"
open_weights = true

[limit]
context = 163840
output = 0

[modalities]
input = ["text"]
output = ["text"]
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
name = "DeepSeek-V3.1 671B"
name = "deepseek-v3.1:671b"
family = "deepseek"
release_date = "2025-08-21"
last_updated = "2025-08-21"
attachment = false
reasoning = true
tool_call = true
structured_output = true
temperature = true
release_date = "2025-08-21"
last_updated = "2026-01-18"
open_weights = true

[limit]
context = 160_000
output = 8_192
context = 163840
output = 0

[modalities]
input = ["text"]
Expand Down
16 changes: 16 additions & 0 deletions providers/ollama-cloud/models/deepseek-v3.2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name = "deepseek-v3.2"
family = "deepseek"
attachment = false
reasoning = true
tool_call = true
release_date = "2025-06-15"
last_updated = "2026-01-18"
open_weights = true

[limit]
context = 163840
output = 0

[modalities]
input = ["text"]
output = ["text"]
16 changes: 16 additions & 0 deletions providers/ollama-cloud/models/devstral-2:123b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name = "devstral-2:123b"
family = "devstral"
attachment = false
reasoning = false
tool_call = true
release_date = "2025-12-09"
last_updated = "2026-01-18"
open_weights = true

[limit]
context = 262144
output = 0

[modalities]
input = ["text"]
output = ["text"]
16 changes: 16 additions & 0 deletions providers/ollama-cloud/models/devstral-small-2:24b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name = "devstral-small-2:24b"
family = "devstral"
attachment = true
reasoning = false
tool_call = true
release_date = "2025-12-09"
last_updated = "2026-01-18"
open_weights = true

[limit]
context = 262144
output = 0

[modalities]
input = ["text", "image"]
output = ["text"]
17 changes: 17 additions & 0 deletions providers/ollama-cloud/models/gemini-3-flash-preview.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name = "gemini-3-flash-preview"
family = "gemini-flash"
attachment = false
reasoning = true
tool_call = true
release_date = "2025-12-17"
knowledge = "2025-01"
last_updated = "2026-01-18"
open_weights = true

[limit]
context = 1048576
output = 0

[modalities]
input = ["text"]
output = ["text"]
16 changes: 16 additions & 0 deletions providers/ollama-cloud/models/gemini-3-pro-preview.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name = "gemini-3-pro-preview"
family = "gemini-pro"
attachment = true
reasoning = true
tool_call = true
release_date = "2025-11-18"
last_updated = "2026-01-18"
open_weights = true

[limit]
context = 1048576
output = 0

[modalities]
input = ["text", "image"]
output = ["text"]
18 changes: 0 additions & 18 deletions providers/ollama-cloud/models/gemini-3-pro-preview:latest.toml

This file was deleted.

16 changes: 16 additions & 0 deletions providers/ollama-cloud/models/gemma3:12b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name = "gemma3:12b"
family = "gemma"
attachment = true
reasoning = false
tool_call = false
release_date = "2024-12-01"
last_updated = "2026-01-18"
open_weights = true

[limit]
context = 131072
output = 0

[modalities]
input = ["text", "image"]
output = ["text"]
16 changes: 16 additions & 0 deletions providers/ollama-cloud/models/gemma3:27b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name = "gemma3:27b"
family = "gemma"
attachment = true
reasoning = false
tool_call = false
release_date = "2025-07-27"
last_updated = "2026-01-18"
open_weights = true

[limit]
context = 131072
output = 0

[modalities]
input = ["text", "image"]
output = ["text"]
Loading