Skip to content
Merged
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
11 changes: 8 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4980,11 +4980,16 @@
</label>
<label for="aiGeneratorKey"
>Key:
<input id="aiGeneratorKey" placeholder="Enter API key" class="icon-key" />
<input
id="aiGeneratorKey"
placeholder="Enter API key"
class="icon-key"
data-tip="Enter API key. Note: the Generator doesn't store the key or any generated data"
/>
<button
id="aiGeneratorKeyHelp"
class="icon-help-circled"
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"
data-tip="Click to see the usage instructions"
/>
</label>
</div>
Expand Down Expand Up @@ -8138,7 +8143,7 @@
<script defer src="modules/ui/burg-editor.js?v=1.106.6"></script>
<script defer src="modules/ui/units-editor.js?v=1.104.0"></script>
<script defer src="modules/ui/notes-editor.js?v=1.107.3"></script>
<script defer src="modules/ui/ai-generator.js?v=1.105.22"></script>
<script defer src="modules/ui/ai-generator.js?v=1.108.8"></script>
<script defer src="modules/ui/diplomacy-editor.js?v=1.99.00"></script>
<script defer src="modules/ui/zones-editor.js?v=1.105.20"></script>
<script defer src="modules/ui/burgs-overview.js?v=1.105.15"></script>
Expand Down
60 changes: 48 additions & 12 deletions modules/ui/ai-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ const PROVIDERS = {
anthropic: {
keyLink: "https://console.anthropic.com/account/keys",
generate: generateWithAnthropic
},
ollama: {
keyLink: "https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Ollama-text-generation",
generate: generateWithOllama
}
};

Expand All @@ -18,11 +22,16 @@ const MODELS = {
"chatgpt-4o-latest": "openai",
"gpt-4o": "openai",
"gpt-4-turbo": "openai",
"o1-preview": "openai",
"o1-mini": "openai",
o3: "openai",
"o3-mini": "openai",
"o3-pro": "openai",
"o4-mini": "openai",
"claude-opus-4-20250514": "anthropic",
"claude-sonnet-4-20250514": "anthropic",
"claude-3-5-haiku-latest": "anthropic",
"claude-3-5-sonnet-latest": "anthropic",
"claude-3-opus-latest": "anthropic"
"claude-3-opus-latest": "anthropic",
"ollama (local models)": "ollama"
};

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

async function generateWithOllama({key, model, prompt, temperature, onContent}) {
const ollamaModelName = key; // for Ollama, 'key' is the actual model name entered by the user

const response = await fetch("http://localhost:11434/api/generate", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({
model: ollamaModelName,
prompt,
system: SYSTEM_MESSAGE,
options: {temperature},
stream: true
})
});

const getContent = json => {
if (json.response) onContent(json.response);
};

await handleStream(response, getContent);
}

async function handleStream(response, getContent) {
if (!response.ok) {
const json = await response.json();
throw new Error(json?.error?.message || "Failed to generate");
let errorMessage = `Failed to generate (${response.status} ${response.statusText})`;
try {
const json = await response.json();
errorMessage = json.error?.message || json.error || errorMessage;
} catch {}
throw new Error(errorMessage);
}

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

for (let i = 0; i < lines.length - 1; i++) {
const line = lines[i].trim();
if (line.startsWith("data: ") && line !== "data: [DONE]") {
try {
const json = JSON.parse(line.slice(6));
getContent(json);
} catch (jsonError) {
ERROR && console.error(`Failed to parse JSON:`, jsonError, `Line: ${line}`);
}
if (!line) continue;
if (line === "data: [DONE]") break;

try {
const parsed = line.startsWith("data: ") ? JSON.parse(line.slice(6)) : JSON.parse(line);
getContent(parsed);
Comment thread
Azgaar marked this conversation as resolved.
} catch (error) {
ERROR && console.error("Failed to parse line:", line, error);
}
}

Expand Down
2 changes: 1 addition & 1 deletion versioning.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Example: 1.102.2 -> Major version 1, Minor version 102, Patch version 2
*/

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

{
Expand Down