Skip to content

Commit d9391d6

Browse files
authored
Merge pull request Azgaar#1211 from Azgaar/ollama
Ollama: local AI text generation
2 parents 004097e + c891689 commit d9391d6

File tree

3 files changed

+57
-16
lines changed

3 files changed

+57
-16
lines changed

index.html

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4980,11 +4980,16 @@
49804980
</label>
49814981
<label for="aiGeneratorKey"
49824982
>Key:
4983-
<input id="aiGeneratorKey" placeholder="Enter API key" class="icon-key" />
4983+
<input
4984+
id="aiGeneratorKey"
4985+
placeholder="Enter API key"
4986+
class="icon-key"
4987+
data-tip="Enter API key. Note: the Generator doesn't store the key or any generated data"
4988+
/>
49844989
<button
49854990
id="aiGeneratorKeyHelp"
49864991
class="icon-help-circled"
4987-
data-tip="Open provider's website to get the API key there. Note: the Map Genenerator doesn't store the key or any generated data"
4992+
data-tip="Click to see the usage instructions"
49884993
/>
49894994
</label>
49904995
</div>
@@ -8138,7 +8143,7 @@
81388143
<script defer src="modules/ui/burg-editor.js?v=1.106.6"></script>
81398144
<script defer src="modules/ui/units-editor.js?v=1.104.0"></script>
81408145
<script defer src="modules/ui/notes-editor.js?v=1.107.3"></script>
8141-
<script defer src="modules/ui/ai-generator.js?v=1.105.22"></script>
8146+
<script defer src="modules/ui/ai-generator.js?v=1.108.8"></script>
81428147
<script defer src="modules/ui/diplomacy-editor.js?v=1.99.00"></script>
81438148
<script defer src="modules/ui/zones-editor.js?v=1.105.20"></script>
81448149
<script defer src="modules/ui/burgs-overview.js?v=1.105.15"></script>

modules/ui/ai-generator.js

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ const PROVIDERS = {
88
anthropic: {
99
keyLink: "https://console.anthropic.com/account/keys",
1010
generate: generateWithAnthropic
11+
},
12+
ollama: {
13+
keyLink: "https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Ollama-text-generation",
14+
generate: generateWithOllama
1115
}
1216
};
1317

@@ -18,11 +22,16 @@ const MODELS = {
1822
"chatgpt-4o-latest": "openai",
1923
"gpt-4o": "openai",
2024
"gpt-4-turbo": "openai",
21-
"o1-preview": "openai",
22-
"o1-mini": "openai",
25+
o3: "openai",
26+
"o3-mini": "openai",
27+
"o3-pro": "openai",
28+
"o4-mini": "openai",
29+
"claude-opus-4-20250514": "anthropic",
30+
"claude-sonnet-4-20250514": "anthropic",
2331
"claude-3-5-haiku-latest": "anthropic",
2432
"claude-3-5-sonnet-latest": "anthropic",
25-
"claude-3-opus-latest": "anthropic"
33+
"claude-3-opus-latest": "anthropic",
34+
"ollama (local models)": "ollama"
2635
};
2736

2837
const SYSTEM_MESSAGE = "I'm working on my fantasy map.";
@@ -76,10 +85,36 @@ async function generateWithAnthropic({key, model, prompt, temperature, onContent
7685
await handleStream(response, getContent);
7786
}
7887

88+
async function generateWithOllama({key, model, prompt, temperature, onContent}) {
89+
const ollamaModelName = key; // for Ollama, 'key' is the actual model name entered by the user
90+
91+
const response = await fetch("http://localhost:11434/api/generate", {
92+
method: "POST",
93+
headers: {"Content-Type": "application/json"},
94+
body: JSON.stringify({
95+
model: ollamaModelName,
96+
prompt,
97+
system: SYSTEM_MESSAGE,
98+
options: {temperature},
99+
stream: true
100+
})
101+
});
102+
103+
const getContent = json => {
104+
if (json.response) onContent(json.response);
105+
};
106+
107+
await handleStream(response, getContent);
108+
}
109+
79110
async function handleStream(response, getContent) {
80111
if (!response.ok) {
81-
const json = await response.json();
82-
throw new Error(json?.error?.message || "Failed to generate");
112+
let errorMessage = `Failed to generate (${response.status} ${response.statusText})`;
113+
try {
114+
const json = await response.json();
115+
errorMessage = json.error?.message || json.error || errorMessage;
116+
} catch {}
117+
throw new Error(errorMessage);
83118
}
84119

85120
const reader = response.body.getReader();
@@ -95,13 +130,14 @@ async function handleStream(response, getContent) {
95130

96131
for (let i = 0; i < lines.length - 1; i++) {
97132
const line = lines[i].trim();
98-
if (line.startsWith("data: ") && line !== "data: [DONE]") {
99-
try {
100-
const json = JSON.parse(line.slice(6));
101-
getContent(json);
102-
} catch (jsonError) {
103-
ERROR && console.error(`Failed to parse JSON:`, jsonError, `Line: ${line}`);
104-
}
133+
if (!line) continue;
134+
if (line === "data: [DONE]") break;
135+
136+
try {
137+
const parsed = line.startsWith("data: ") ? JSON.parse(line.slice(6)) : JSON.parse(line);
138+
getContent(parsed);
139+
} catch (error) {
140+
ERROR && console.error("Failed to parse line:", line, error);
105141
}
106142
}
107143

versioning.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Example: 1.102.2 -> Major version 1, Minor version 102, Patch version 2
1414
*/
1515

16-
const VERSION = "1.108.7";
16+
const VERSION = "1.108.8";
1717
if (parseMapVersion(VERSION) !== VERSION) alert("versioning.js: Invalid format or parsing function");
1818

1919
{

0 commit comments

Comments
 (0)