{"id":28814918,"url":"https://github.com/earu/gm_ollama","last_synced_at":"2026-04-24T12:06:53.825Z","repository":{"id":298107916,"uuid":"998895468","full_name":"Earu/gm_ollama","owner":"Earu","description":"Providing access to LLMs through Garry's mod and Ollama.","archived":false,"fork":false,"pushed_at":"2025-12-30T12:40:36.000Z","size":40,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-03T04:32:23.365Z","etag":null,"topics":["api","binary","garrysmod","gmod","llm","ollama"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Earu.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-09T12:27:05.000Z","updated_at":"2025-12-30T12:40:39.000Z","dependencies_parsed_at":"2025-06-09T13:34:24.364Z","dependency_job_id":null,"html_url":"https://github.com/Earu/gm_ollama","commit_stats":null,"previous_names":["earu/gm_ollama"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Earu/gm_ollama","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Earu%2Fgm_ollama","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Earu%2Fgm_ollama/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Earu%2Fgm_ollama/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Earu%2Fgm_ollama/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Earu","download_url":"https://codeload.github.com/Earu/gm_ollama/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Earu%2Fgm_ollama/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32222530,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T10:26:35.452Z","status":"ssl_error","status_checked_at":"2026-04-24T10:25:27.643Z","response_time":64,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","binary","garrysmod","gmod","llm","ollama"],"created_at":"2025-06-18T16:03:16.020Z","updated_at":"2026-04-24T12:06:53.817Z","avatar_url":"https://github.com/Earu.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gm_ollama - Ollama Integration for Garry's Mod\n\nA Garry's Mod binary module that provides Lua bindings for the [Ollama](https://ollama.ai/) API, allowing you to connect to local LLMs directly in your GMod server or client.\n\n## Prerequisites\n\n- [Ollama](https://ollama.ai/) installed and running\n- Rust toolchain for building\n- Garry's Mod\n\n## Building\n\n1. Clone this repository\n2. Make sure you have Rust installed with the correct toolchain:\n   ```bash\n   rustup install stable\n   rustup default stable\n   ```\n3. Build the module:\n   ```bash\n   cargo build --release\n   ```\n4. The compiled binary will be in `target/release/`\n\n## Installation\n\n1. Place the compiled binary in your GMod's `garrysmod/lua/bin/` folder\n2. Rename it to follow GMod's naming convention:\n   - Windows (64-bit): `gmsv_ollama_win64.dll` (server) or `gmcl_ollama_win64.dll` (client)\n   - Linux (64-bit): `gmsv_ollama_linux64.dll` (server) or `gmcl_ollama_linux64.dll` (client)\n   - Windows (32-bit): `gmsv_ollama_win32.dll` (server) or `gmcl_ollama_win32.dll` (client)\n   - Linux (32-bit): `gmsv_ollama_linux.dll` (server) or `gmcl_ollama_linux.dll` (client)\n\n## API Reference\n\n**Important**: All operations are asynchronous. Callbacks use the error-first pattern: `function(err, data)`.\n\n### Configuration\n\n#### `Ollama.SetConfig(url, timeout)`\nConfigure the Ollama connection.\n- `url` (string): Ollama server URL (default: \"http://localhost:11434\")\n- `timeout` (number): Request timeout in seconds (default: 30)\n\n```lua\nOllama.SetConfig(\"http://localhost:11434\", 30)\n```\n\n#### `Ollama.IsRunning()`\nCheck if Ollama server is accessible. Returns cached result (updated every 2 seconds).\n- Returns: `boolean` - true if accessible\n\n```lua\nif Ollama.IsRunning() then\n    print(\"Ollama is running!\")\nelse\n    print(\"Ollama is not running or not accessible\")\nend\n```\n\n### Text Generation\n\n#### `Ollama.Generate(model, prompt, system, callback)`\nGenerate text using the specified model. Model names without tags automatically get \":latest\" appended.\n\n**Parameters:**\n- `model` (string): Model name (e.g., \"llama2\", \"codellama:13b\")\n- `prompt` (string): The text prompt\n- `system` (string, optional): System prompt to guide behavior (can be nil)\n- `callback` (function): Callback function `function(err, data)`\n\n**Callback data structure:**\n```lua\n{\n    response = \"Generated text response\",\n    model = \"llama2:latest\"\n}\n```\n\n**Example:**\n```lua\nOllama.Generate(\"llama2\", \"Tell me a short joke about programming\", nil, function(err, data)\n    if err then\n        print(\"Error: \" .. err)\n    else\n        print(\"Response from \" .. data.model .. \": \" .. data.response)\n    end\nend)\n\n-- With system prompt\nOllama.Generate(\"llama2\", \"Explain quantum physics\", \"You are a helpful physics teacher. Keep explanations simple.\", function(err, data)\n    if err then\n        print(\"Error: \" .. err)\n    else\n        print(\"Physics Response: \" .. data.response)\n    end\nend)\n```\n\n### Chat Conversations\n\n#### `Ollama.Chat(model, messages, callback)`\nConduct a conversation with context.\n\n**Parameters:**\n- `model` (string): Model name\n- `messages` (table): Array of message objects with `role` and `content` fields\n- `callback` (function): Callback function `function(err, data)`\n\n**Message format:**\n```lua\n{\n    {role = \"system\", content = \"You are a helpful assistant\"},\n    {role = \"user\", content = \"Hello!\"},\n    {role = \"assistant\", content = \"Hi there!\"},\n    {role = \"user\", content = \"How are you?\"}\n}\n```\n\n**Callback data structure:**\n```lua\n{\n    content = \"AI response content\",\n    role = \"assistant\",\n    model = \"llama2:latest\"\n}\n```\n\n**Example:**\n```lua\nlocal conversation = {\n    {role = \"system\", content = \"You are a helpful assistant for Garry's Mod players.\"},\n    {role = \"user\", content = \"How do I create a basic prop in GMod?\"},\n}\nOllama.Chat(\"llama2\", conversation, function(err, data)\n    if err then\n        print(\"Error: \" .. err)\n    else\n        print(\"Chat Response from \" .. data.model .. \" (\" .. data.role .. \"): \" .. data.content)\n    end\nend)\n```\n\n### Model Management\n\n#### `Ollama.ListModels(callback)`\nList all available models.\n\n**Callback data structure:**\n```lua\n{\n    {\n        name = \"llama2:latest\",\n        modified_at = \"2023-12-01T12:00:00Z\",\n        size = 3825819519,\n        digest = \"sha256:...\"\n    },\n    -- ... more models\n}\n```\n\n**Example:**\n```lua\nOllama.ListModels(function(err, models)\n    if err then\n        print(\"Error: \" .. err)\n    else\n        print(\"Available models:\")\n        for i, model in ipairs(models) do\n            local size_mb = math.floor(model.size / 1024 / 1024)\n            print(\"  \" .. i .. \". \" .. model.name .. \" (Size: \" .. size_mb .. \" MB)\")\n        end\n    end\nend)\n```\n\n#### `Ollama.GetModelInfo(model, callback)`\nGet detailed information about a specific model.\n\n**Callback data structure:**\n```lua\n{\n    license = \"Model license text\",\n    modelfile = \"Modelfile content\",\n    parameters = \"Model parameters\",\n    template = \"Prompt template\"\n}\n```\n\n**Example:**\n```lua\nOllama.GetModelInfo(\"llama2\", function(err, data)\n    if err then\n        print(\"Error: \" .. err)\n    else\n        print(\"Model Info for llama2:\")\n        print(\"  License: \" .. (data.license ~= \"\" and data.license or \"N/A\"))\n        print(\"  Parameters: \" .. (data.parameters ~= \"\" and data.parameters or \"N/A\"))\n        print(\"  Template length: \" .. string.len(data.template))\n    end\nend)\n```\n\n#### `Ollama.IsModelAvailable(model, callback)`\nCheck if a specific model is available.\n\n**Example:**\n```lua\nOllama.IsModelAvailable(\"llama2\", function(err, is_available)\n    if err then\n        print(\"Error: \" .. err)\n    else\n        print(\"llama2 is \" .. (is_available and \"available\" or \"not available\"))\n    end\nend)\n```\n\n#### `Ollama.GetRunningModels(callback)`\nList models currently loaded into memory.\n\n**Callback data structure:**\n```lua\n{\n    {\n        name = \"llama2:latest\",\n        model = \"llama2:latest\",\n        size = 3825819519,\n        digest = \"sha256:...\",\n        expires_at = \"2023-12-01T12:05:00Z\", -- optional\n        size_vram = 3825819519 -- optional\n    },\n    -- ... more running models\n}\n```\n\n**Example:**\n```lua\nOllama.GetRunningModels(function(err, models)\n    if err then\n        print(\"Error: \" .. err)\n    else\n        if #models \u003e 0 then\n            print(\"Currently running models:\")\n            for i, model in ipairs(models) do\n                local size_mb = math.floor(model.size / 1024 / 1024)\n                local vram_mb = model.size_vram and math.floor(model.size_vram / 1024 / 1024) or 0\n                print(\"  \" .. i .. \". \" .. model.name)\n                print(\"     Size: \" .. size_mb .. \" MB (VRAM: \" .. vram_mb .. \" MB)\")\n                if model.expires_at then\n                    print(\"     Expires: \" .. model.expires_at)\n                end\n            end\n        else\n            print(\"No models currently running\")\n        end\n    end\nend)\n```\n\n### Embeddings\n\n#### `Ollama.GenerateEmbeddings(model, input, callback)`\nGenerate embeddings from text input.\n\n**Parameters:**\n- `model` (string): Model name (e.g., \"all-minilm\")\n- `input` (string or table): Single string or array of strings\n- `callback` (function): Callback function `function(err, data)`\n\n**Callback data structure:**\n```lua\n{\n    model = \"all-minilm:latest\",\n    embeddings = {\n        {0.1, -0.2, 0.3, ...}, -- First embedding vector\n        {0.2, -0.1, 0.4, ...}, -- Second embedding vector (if multiple inputs)\n        -- ... more vectors\n    }\n}\n```\n\n**Single text example:**\n```lua\nOllama.GenerateEmbeddings(\"all-minilm\", \"Why is the sky blue?\", function(err, data)\n    if err then\n        print(\"Error: \" .. err)\n    else\n        print(\"Generated embeddings for model: \" .. data.model)\n        print(\"Number of embedding vectors: \" .. #data.embeddings)\n        if #data.embeddings \u003e 0 then\n            print(\"First embedding dimensions: \" .. #data.embeddings[1])\n        end\n    end\nend)\n```\n\n**Multiple texts example:**\n```lua\nlocal texts = {\n    \"Hello world\",\n    \"How are you today?\",\n    \"Garry's Mod is fun\"\n}\nOllama.GenerateEmbeddings(\"all-minilm\", texts, function(err, data)\n    if err then\n        print(\"Error: \" .. err)\n    else\n        print(\"Generated \" .. #data.embeddings .. \" embedding vectors\")\n\n        -- Calculate similarity between first two embeddings\n        if #data.embeddings \u003e= 2 then\n            local function dot_product(a, b)\n                local sum = 0\n                for i = 1, math.min(#a, #b) do\n                    sum = sum + (a[i] * b[i])\n                end\n                return sum\n            end\n\n            local function magnitude(vec)\n                local sum = 0\n                for i = 1, #vec do\n                    sum = sum + (vec[i] * vec[i])\n                end\n                return math.sqrt(sum)\n            end\n\n            local emb1, emb2 = data.embeddings[1], data.embeddings[2]\n            local similarity = dot_product(emb1, emb2) / (magnitude(emb1) * magnitude(emb2))\n            print(\"Similarity between first two texts: \" .. string.format(\"%.4f\", similarity))\n        end\n    end\nend)\n```\n\n## Chat Commands Integration\n\n```lua\nhook.Add(\"PlayerSay\", \"OllamaChat\", function(ply, text)\n    if string.StartWith(text, \"!ai \") then\n        local prompt = string.sub(text, 5)\n\n        Ollama.Generate(\"llama2\", prompt, nil, function(err, data)\n            if err then\n                ply:ChatPrint(\"AI Error: \" .. err)\n            else\n                ply:ChatPrint(\"AI: \" .. data.response)\n            end\n        end)\n\n        return \"\"\n    elseif string.StartWith(text, \"!models\") then\n        Ollama.ListModels(function(err, models)\n            if err then\n                ply:ChatPrint(\"Error: \" .. err)\n            else\n                if models and #models \u003e 0 then\n                    ply:ChatPrint(\"Available models:\")\n                    for i, model in ipairs(models) do\n                        if i \u003c= 5 then -- Limit to first 5 to avoid spam\n                            local size_mb = math.floor(model.size / 1024 / 1024)\n                            ply:ChatPrint(\"  \" .. model.name .. \" (\" .. size_mb .. \"MB)\")\n                        end\n                    end\n                    if #models \u003e 5 then\n                        ply:ChatPrint(\"  ... and \" .. (#models - 5) .. \" more\")\n                    end\n                else\n                    ply:ChatPrint(\"No models available\")\n                end\n            end\n        end)\n\n        return \"\"\n    elseif string.StartWith(text, \"!running\") then\n        Ollama.GetRunningModels(function(err, models)\n            if err then\n                ply:ChatPrint(\"Error: \" .. err)\n            else\n                if #models \u003e 0 then\n                    ply:ChatPrint(\"Currently running models:\")\n                    for i, model in ipairs(models) do\n                        local size_mb = math.floor(model.size / 1024 / 1024)\n                        local vram_mb = model.size_vram and math.floor(model.size_vram / 1024 / 1024) or 0\n                        ply:ChatPrint(\"  \" .. model.name .. \" (\" .. size_mb .. \"MB, VRAM: \" .. vram_mb .. \"MB)\")\n                    end\n                else\n                    ply:ChatPrint(\"No models currently running\")\n                end\n            end\n        end)\n\n        return \"\"\n    elseif string.StartWith(text, \"!embed \") then\n        local input_text = string.sub(text, 8)\n\n        Ollama.GenerateEmbeddings(\"all-minilm\", input_text, function(err, data)\n            if err then\n                ply:ChatPrint(\"Embedding Error: \" .. err)\n            else\n                ply:ChatPrint(\"Generated embedding with \" .. #data.embeddings[1] .. \" dimensions\")\n                ply:ChatPrint(\"Model: \" .. data.model)\n            end\n        end)\n\n        return \"\"\n    end\nend)\n```\n\n## Advanced Conversation System\n\n```lua\nlocal function startConversation()\n    local history = {\n        {role = \"system\", content = \"You are an AI assistant in Garry's Mod. Help players with game-related questions.\"}\n    }\n\n    local function addMessage(role, content)\n        table.insert(history, {role = role, content = content})\n    end\n\n    local function sendMessage(message)\n        addMessage(\"user\", message)\n\n        Ollama.Chat(\"llama2\", history, function(err, data)\n            if err then\n                print(\"Conversation Error: \" .. err)\n            else\n                addMessage(\"assistant\", data.content)\n                print(\"AI: \" .. data.content)\n            end\n        end)\n    end\n\n    -- Example conversation\n    sendMessage(\"What's the best way to build in GMod?\")\nend\n```\n\n## Error Handling\n\nAll callbacks follow the error-first pattern:\n- First parameter is the error (string or nil)\n- Second parameter is the result data (structured table)\n\n```lua\nOllama.Generate(\"model\", \"prompt\", nil, function(err, data)\n    if err then\n        -- Handle error\n        print(\"Something went wrong: \" .. err)\n    else\n        -- Handle success\n        print(\"Got response: \" .. data.response)\n        print(\"From model: \" .. data.model)\n    end\nend)\n```\n\n## Troubleshooting\n\n1. **\"Ollama request failed\"**: Check if Ollama is running and accessible\n2. **Module not loading**: Ensure correct binary name and placement\n3. **Slow responses**: Large models take time\n4. **Memory issues**: Monitor model sizes and server resources\n5. **Generation fails**: Make sure you have installed the model you're trying to use\n\n## License\n\nMIT License - see LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fearu%2Fgm_ollama","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fearu%2Fgm_ollama","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fearu%2Fgm_ollama/lists"}