{"id":46831221,"url":"https://github.com/stephenyeargin/hubot-ollama","last_synced_at":"2026-05-18T01:10:24.167Z","repository":{"id":325200860,"uuid":"1095353872","full_name":"stephenyeargin/hubot-ollama","owner":"stephenyeargin","description":"🦙🤖 Ollama for Hubot","archived":false,"fork":false,"pushed_at":"2026-05-16T13:37:03.000Z","size":1300,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-16T15:24:14.531Z","etag":null,"topics":["hacktoberfest","hubot","hubot-scripts","llm","ollama"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/hubot-ollama","language":"JavaScript","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/stephenyeargin.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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-11-13T00:00:40.000Z","updated_at":"2026-05-16T13:37:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/stephenyeargin/hubot-ollama","commit_stats":null,"previous_names":["stephenyeargin/hubot-ollama"],"tags_count":28,"template":false,"template_full_name":"stephenyeargin/template-hubot-script","purl":"pkg:github/stephenyeargin/hubot-ollama","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenyeargin%2Fhubot-ollama","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenyeargin%2Fhubot-ollama/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenyeargin%2Fhubot-ollama/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenyeargin%2Fhubot-ollama/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stephenyeargin","download_url":"https://codeload.github.com/stephenyeargin/hubot-ollama/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenyeargin%2Fhubot-ollama/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33161414,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T22:39:12.733Z","status":"ssl_error","status_checked_at":"2026-05-17T22:39:10.741Z","response_time":107,"last_error":"SSL_read: 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":["hacktoberfest","hubot","hubot-scripts","llm","ollama"],"created_at":"2026-03-10T10:06:58.598Z","updated_at":"2026-05-18T01:10:24.154Z","avatar_url":"https://github.com/stephenyeargin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hubot-ollama\n\n[![Node CI](https://github.com/stephenyeargin/hubot-ollama/actions/workflows/nodejs.yml/badge.svg)](https://github.com/stephenyeargin/hubot-ollama/actions/workflows/nodejs.yml)\n\n\u003e Hubot script for integrating with [Ollama](https://ollama.ai/) - run local or cloud LLMs in your chat.\n\n![screenshot](docs/screenshot.png)\n\n## Quick Start\n1. Install Ollama and pull a model:\n   ```bash\n   # Install Ollama from https://ollama.com\n   ollama pull llama3.2\n   # Ollama server starts automatically on macOS/Windows.\n   # On Linux, start manually (or enable the systemd service):\n   #   ollama serve\n   #   sudo systemctl enable --now ollama\n   ```\n2. Add this package to your Hubot:\n   ```bash\n   npm install hubot-ollama --save\n   ```\n   Then add to `external-scripts.json`:\n   ```json\n   [\"hubot-ollama\"]\n   ```\n3. Start chatting:\n   ```text\n   hubot ask what is an LLM?\n   hubot ollama explain async/await\n   hubot llm write a haiku about databases\n   ```\n\n## Commands\n| Pattern | Example | Notes |\n|---------|---------|-------|\n| `hubot ask \u003cprompt\u003e` | `hubot ask what is caching?` | Primary documented command |\n| `hubot ollama \u003cprompt\u003e` | `hubot ollama summarize HTTP` | Alias |\n| `hubot llm \u003cprompt\u003e` | `hubot llm list json benefits` | Alias |\n\nPrompts are sanitized and truncated if they exceed the configured limit.\n\n## Configuration\n| Variable | Required | Default | Purpose |\n|----------|----------|---------|---------|\n| `HUBOT_OLLAMA_MODEL` | Optional | `llama3.2` | Model name (validated: `[A-Za-z0-9._:-]+`) |\n| `HUBOT_OLLAMA_HOST` | Optional | `http://127.0.0.1:11434` | Ollama server URL |\n| `HUBOT_OLLAMA_API_KEY` | Optional | (unset) | API key for [Ollama cloud](https://ollama.com/settings/keys) access |\n| `HUBOT_OLLAMA_SYSTEM_PROMPT` | Optional | Built‑in concise chat prompt | Override system instructions |\n| `HUBOT_OLLAMA_MAX_PROMPT_CHARS` | Optional | `2000` | Truncate overly long user prompts |\n| `HUBOT_OLLAMA_TIMEOUT_MS` | Optional | `60000` (60 sec) | Abort request after this duration |\n| `HUBOT_OLLAMA_CONTEXT_TTL_MS` | Optional | `600000` (10 min) | Time to maintain conversation history; `0` to disable |\n| `HUBOT_OLLAMA_CONTEXT_TURNS` | Optional | `5` | Maximum number of conversation turns to remember |\n| `HUBOT_OLLAMA_CONTEXT_SCOPE` | Optional | `room-user` | Context isolation: `room-user`, `room`, or `thread` |\n| `HUBOT_OLLAMA_RESPOND_TO_ADDRESSED_FALLBACK` | Optional | `false` | Enable fallback replies for addressed messages when no other listener matched |\n| `HUBOT_OLLAMA_WEB_ENABLED` | Optional | `false` | Enable web-assisted workflow that can search/fetch context |\n| `HUBOT_OLLAMA_WEB_MAX_RESULTS` | Optional | `5` | Max search results to use (capped at 10) |\n| `HUBOT_OLLAMA_WEB_FETCH_CONCURRENCY` | Optional | `3` | Parallel fetch concurrency |\n| `HUBOT_OLLAMA_WEB_MAX_BYTES` | Optional | `120000` | Max bytes per fetched page used in context |\n| `HUBOT_OLLAMA_WEB_TIMEOUT_MS` | Optional | `45000` | Timeout for the web phase per fetch |\n\nChange model:\n```bash\nexport HUBOT_OLLAMA_MODEL=mistral\n```\nConnect to remote Ollama server:\n```bash\nexport HUBOT_OLLAMA_HOST=http://my-ollama-server:11434\n```\nUse Ollama cloud (requires [API key](https://ollama.com/settings/keys)):\n```bash\nexport HUBOT_OLLAMA_HOST=https://ollama.com\nexport HUBOT_OLLAMA_API_KEY=your_api_key\nexport HUBOT_OLLAMA_MODEL=gpt-oss:120b  # Use a cloud model\n\n# Note: The host should match what `ollama signin` configures.\n# Some environments may use a region-specific or API-prefixed host.\n# Check `ollama signin --verbose` if unsure.\n\n```\nCustom system prompt:\n```bash\nexport HUBOT_OLLAMA_SYSTEM_PROMPT=\"You are terse; answer in \u003c=200 chars.\"\n```\nAdjust conversation memory:\n```bash\n# Keep 10 turns for 30 minutes, shared across the room\nexport HUBOT_OLLAMA_CONTEXT_TURNS=10\nexport HUBOT_OLLAMA_CONTEXT_TTL_MS=1800000\nexport HUBOT_OLLAMA_CONTEXT_SCOPE=room\n```\n\nEnable addressed fallback mode:\n```bash\nexport HUBOT_OLLAMA_RESPOND_TO_ADDRESSED_FALLBACK=true\n```\n\n### Addressed Fallback Mode\nWhen `HUBOT_OLLAMA_RESPOND_TO_ADDRESSED_FALLBACK=true`, hubot-ollama can answer without `ask`/`ollama`/`llm` prefixes, but only as a fallback.\n\n- It runs through Hubot `catchAll`, so it only triggers when no other listener matched first.\n- In shared rooms, fallback only triggers when explicitly addressed by bot name or configured alias (for example: `hubot summarize this` or `! summarize this` when `!` is the alias).\n- In Slack, `@mentions` are normalized to the alias character by the adapter, so alias-prefix messages are treated as bot-addressed.\n- Single-token alias-prefix messages (for example: `! ping`) are treated as command misses and ignored.\n- In direct messages/private chats, plain text is treated as addressed.\n- Explicit commands still work exactly as before (`hubot ask ...`, `hubot ollama ...`, `hubot llm ...`).\n\n## Examples\n```text\nhubot ask explain vector embeddings\nhubot llm generate a short motivational quote\nhubot ollama compare sql vs nosql\n```\n\n### Web-Enabled Workflow\nWhen `HUBOT_OLLAMA_WEB_ENABLED=true` and the connected Ollama host supports web tools, the bot registers `hubot_ollama_web_search` and the LLM can invoke it directly. The flow now is:\n- Phase 1: The model chooses whether to call `hubot_ollama_web_search`.\n- Phase 2: The tool performs `webSearch`, fetches top results in parallel, builds a compact context block, and returns it.\n- Phase 3: The model incorporates the returned context into its final reply.\n- The bot sends a status message when the search is running and skips duplicate web searches in the same interaction.\n\n### Slack Reactions And Status\nWhen running with the Slack adapter, hubot-ollama uses reactions/status indicators on the triggering message:\n\n- `💭` (`thought_balloon`) while the main prompt is being processed.\n- `🛠️` (`hammer_and_wrench`) while a tool call is actively executing.\n- `⏳` status text is posted during web search (`_Searching web for relevant sources..._`).\n\nReactions require Slack reaction scopes (for example, `reactions:write`).\nIf reaction permissions are missing, the bot continues normally and keeps the existing web-search status message behavior.\n\nEnable:\n```bash\nexport HUBOT_OLLAMA_WEB_ENABLED=true\nexport HUBOT_OLLAMA_WEB_MAX_RESULTS=5\nexport HUBOT_OLLAMA_WEB_FETCH_CONCURRENCY=3\nexport HUBOT_OLLAMA_WEB_MAX_BYTES=120000\nexport HUBOT_OLLAMA_WEB_TIMEOUT_MS=45000\n```\n\n### Tool Integration\nThe bot uses a **two-call LLM workflow** to enable tools when supported by the model:\n\n1. **Phase 1**: Model decides if a tool is needed to answer the question\n2. **Phase 2**: Tool is executed (if selected) and results are captured\n3. **Phase 3**: Model incorporates tool results into a natural conversational response\n\n**Built-in Tools:**\n- `hubot_ollama_get_current_time` - Returns the current UTC timestamp (always available)\n\n**Configuration:**\n| Variable | Required | Default | Purpose |\n|----------|----------|---------|---------|\n| `HUBOT_OLLAMA_TOOLS_ENABLED` | Optional | `true` | Enable tool support (`true`/`1` or `false`/`0`) |\n\nEnable tool support (default):\n```bash\nexport HUBOT_OLLAMA_TOOLS_ENABLED=true\n```\n\nDisable tool support (useful for models without tool capability):\n```bash\nexport HUBOT_OLLAMA_TOOLS_ENABLED=false\n```\n\n**How It Works:**\n- The bot automatically detects whether your selected model supports tools via `ollama show`.\n- If tools are enabled AND the model supports them, the two-call workflow activates.\n- If the model doesn't support tools or tools are disabled, the bot falls back to a single-call workflow.\n- When a tool is invoked, the model can request data (like current time) to enhance its response.\n\n**Example Tool Interaction:**\n```text\nuser\u003e hubot ask what time is it in UTC?\nhubot\u003e (Phase 1: Model decides current time is needed)\n       (Phase 2: Tool returns: 2025-12-05T14:30:45.123Z)\n       (Phase 3: Model incorporates and responds)\n       The current UTC time is 2:30:45 PM on December 5, 2025.\n```\n\n**Registering Custom Tools:**\nUse the tool registry to add your own tools:\n\n```javascript\nconst registry = require('hubot-ollama/src/tool-registry');\n\nregistry.registerTool('my_tool', {\n  name: 'my_tool',\n  description: 'A brief description of what this tool does',\n  parameters: {\n    type: 'object',\n    properties: {\n      param1: { type: 'string', description: 'The first parameter' }\n    }\n  },\n  handler: async (args, robot, msg) =\u003e {\n    // args: parsed arguments from the LLM\n    // robot: Hubot robot instance\n    // msg: Current message object, use msg.send() to output results while tool in use\n    return { result: 'Tool output here' };\n  }\n});\n```\n\n### Conversation Context\nHubot remembers recent exchanges within the configured scope, allowing natural follow-up questions:\n\n```text\nalice\u003e hubot ask what are the planets in our solar system?\nhubot\u003e Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune.\n\nalice\u003e hubot ask which is the largest?\nhubot\u003e Jupiter is the largest planet in our solar system.\n```\n\n**Context Scopes:**\n- `room-user` (default): Each user has separate conversation history per room\n- `room`: All users in a room share the same conversation history\n- `thread`: Separate history per thread (for Slack-style threading)\n\nContext automatically expires after the configured TTL (default 10 minutes). Set `HUBOT_OLLAMA_CONTEXT_TTL_MS=0` to disable conversation memory entirely.\n\n**Automatic Token Optimization:**  \nFor longer conversations, Hubot automatically summarizes older turns while keeping recent ones verbatim. This reduces token usage without changing behavior or requiring configuration. The last 2 turns are always kept in full, while earlier turns are condensed into a compact summary. This happens transparently in the background and never blocks responses.\n\n## Ollama Cloud\n\nThis package supports [Ollama's cloud service](https://ollama.com/cloud), which allows you to run larger models that wouldn't fit on your local machine. Cloud models are accessed via the same API but run on Ollama's infrastructure.\n\n### Setup\n\n1. Create an account at [ollama.com](https://ollama.com/signup)\n2. Generate an [API key](https://ollama.com/settings/keys)\n3. Run `ollama signin` to register the host with Ollama.com\n4. Configure your environment:\n   ```bash\n   export HUBOT_OLLAMA_HOST=https://ollama.com\n   export HUBOT_OLLAMA_API_KEY=your_api_key\n   export HUBOT_OLLAMA_MODEL=gpt-oss:120b-cloud\n   ```\n\n### Available Models\n\nHubot-Ollama works with [any model supported by Ollama](https://ollama.com/search), whether running locally or in the cloud. You can switch models on the fly using `HUBOT_OLLAMA_MODEL`, making it easy to choose between speed, size, and capability.\n\n\u003e Cloud model availability changes over time. Check the model catalog at [Ollama.com](https://ollama.com/search?c=cloud) for the latest list.\n\nBoth local and cloud models share the same API, making the integration seamless regardless of where your model runs.\n\n**Note:** Cloud models require network connectivity and count against your cloud usage. Local models remain free and private.\n\n## Error Handling\n| Situation | User Message |\n|-----------|------------|\n| Ollama server unreachable | Cannot connect to Ollama server message |\n| Model missing | Suggest `ollama pull \u003cmodel\u003e` |\n| Empty response | Specific empty response notice |\n| Timeout | Indicates the configured timeout elapsed |\n| API error | Surfaces error message |\n\n## Security \u0026 Safety\n- Uses official Ollama JavaScript library with proper API communication.\n- Model name validation \u0026 prompt sanitization (strip control chars).\n- When `HUBOT_OLLAMA_WEB_ENABLED=true`, web search results are fetched from external sites. Only the fetched pages — not your private prompts — are sent over the network.\n\n## Troubleshooting\n| Symptom | Check |\n|---------|-------|\n| No response | Check Hubot logs for errors; verify Ollama server is accessible |\n| Connection refused | Ensure Ollama server is running (`ollama serve` or daemon) |\n| Model not found | Run `ollama list` to see available models, then `ollama pull \u003cmodel\u003e` |\n| Wrong server | Set `HUBOT_OLLAMA_HOST=http://your-server:11434` |\n| Long delays | Try increasing `HUBOT_OLLAMA_TIMEOUT_MS` or use a faster model |\n| Web tools not running | The connected Ollama host must support `webSearch`/`webFetch`; feature auto-skips when unavailable |\n| No search performed | The model decided a web search was unnecessary; disable web workflow or ask explicitly |\n| `Error: unauthorized` | If using a cloud model, you must run `ollama signin` to register the host |\n| Other cloud auth issues | Verify your `HUBOT_OLLAMA_API_KEY` is valid at [ollama.com/settings/keys](https://ollama.com/settings/keys) |\n\n## Development\nRun tests \u0026 lint:\n```bash\nnpm test\nnpm run lint\n```\n\n## License\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstephenyeargin%2Fhubot-ollama","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstephenyeargin%2Fhubot-ollama","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstephenyeargin%2Fhubot-ollama/lists"}