Download Game! Currently 99 players. Last logged in:HeidelGlauriMangyCelebrimber

Blitzer's Blog >> 72902

Back to blogs index
Posted: 02 Oct 2026 22:17 [ permalink ]
Feeding a massive text like Dracula into a 9B model requires a sliding window
approach. Gemma 2 9B has an 8k context window, meaning if you dump the whole
book in at once, it will either truncate the prompt or crash with an
out-of-memory error.
Testing one page (or about 500-800 words) at a time from the browser is the
perfect way to calibrate the pipeline before writing an automated ingestion
loop.
Because you are calling a local cluster over a mesh network IP
(100.111.184.107), you will hit Cross-Origin Resource Sharing (CORS) blocks if
you fire requests directly from a browser dashboard. To make the browser
script work, you must start your Ollama node with the environment variable
OLLAMA_ORIGINS="*".
Here is a browser-ready JavaScript function utilizing the OpenAI-compatible
/v1/chat/completions endpoint provided by Ollama. It wraps the Pass 1 prompt
we designed and enforces JSON output.
const OLLAMA_BASE_URL = "http://100.111.184.107:8080/v1";
const MODEL_NAME = "gemma-2-9b-it";
const API_KEY = "sk-local-no-key";

 * Sends a single chunk of text to the local Gemma cluster to extract spatial
data.
 * @param {string} pageText - The current page/chunk of the book.
 * @param {string} previousContext - A summary of the last room to maintain
map continuity.
 */
async function extractTopologyPass(pageText, previousContext = "None") {
    const systemPrompt = `You are a world-building spatial engine. Your task
is to read a chunk of narrative text and extract a topological map of the
locations described.
    
    Rules:
    1. Identify distinct rooms, areas, or zones mentioned in the text.
    2. Create an uppercase ID for each (e.g., CH1_LIVING_ROOM).
    3. Determine a logical grid size (w and h) for the 2D map.
    4. Identify obvious physical connections (exits) and the cardinal
direction.
    5. Output strict JSON with a root 'zones' array. Do NOT include characters
or events.`;

    const userPrompt = `Previous Location Context: ${previousContext}

Current Text to Scan:
${pageText}`;

    try {
        console.log(`Sending page to ${MODEL_NAME}...`);
        
        const response = await fetch(`${OLLAMA_BASE_URL}/chat/completions`, {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer ${API_KEY}`
            },
            body: JSON.stringify({
                model: MODEL_NAME,
                // Setting a low temperature forces the model to be
deterministic and stick to extraction
                temperature: 0.1, 
                // If your Ollama/Gemma version supports strict JSON mode:
                response_format: { type: "json_object" }, 
                messages: [
                    { role: "system", content: systemPrompt },
                    { role: "user", content: userPrompt }
                ]
            })
        });

        if (!response.ok) {
            throw new Error(`Cluster Error: ${response.status}
${response.statusText}`);
        }

        const data = await response.json();
        const extractedJson = JSON.parse(data.choices[0].message.content);
        
        console.log("Extraction Complete:", extractedJson);
        return extractedJson;

    } catch (error) {
        console.error("Pipeline failure:", error);
    }
}

/ Example usage to hook into your prototype UI:
const testPage = `He walked out of the dusty living room and moved north into
a dark hallway. 
The hallway was narrow and reeked of damp earth, eventually terminating into a
ruined kitchen.`;

/ extractTopologyPass(testPage, "Currently in: The Dusty Living Room");

The "Overlap" Strategy for the Full Book
When you move past testing a single page and start iterating through a text
file of Dracula, you cannot chop the text blindly by character count. If a cut
happens in the middle of a sentence describing a door, Gemma will miss the
exit.
You will need an iterator that chunks the book by paragraphs (splitting by 

) until it hits a target word count (e.g., 600 words). Furthermore, you must
feed the model a previousContext variable. If page 14 describes a hallway, and
page 15 describes opening the door at the end of it, injecting Previous
Location Context: Hallway ensures Gemma links the new room to the existing
exit graph rather than hallucinating an isolated map fragment.