https://github.com/stephenyeargin/hubot-ollama
π¦π€ Ollama for Hubot
https://github.com/stephenyeargin/hubot-ollama
hacktoberfest hubot hubot-scripts llm ollama
Last synced: about 2 months ago
JSON representation
π¦π€ Ollama for Hubot
- Host: GitHub
- URL: https://github.com/stephenyeargin/hubot-ollama
- Owner: stephenyeargin
- License: mit
- Created: 2025-11-13T00:00:40.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2026-05-16T13:37:03.000Z (about 2 months ago)
- Last Synced: 2026-05-16T15:24:14.531Z (about 2 months ago)
- Topics: hacktoberfest, hubot, hubot-scripts, llm, ollama
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/hubot-ollama
- Size: 1.24 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# hubot-ollama
[](https://github.com/stephenyeargin/hubot-ollama/actions/workflows/nodejs.yml)
> Hubot script for integrating with [Ollama](https://ollama.ai/) - run local or cloud LLMs in your chat.

## Quick Start
1. Install Ollama and pull a model:
```bash
# Install Ollama from https://ollama.com
ollama pull llama3.2
# Ollama server starts automatically on macOS/Windows.
# On Linux, start manually (or enable the systemd service):
# ollama serve
# sudo systemctl enable --now ollama
```
2. Add this package to your Hubot:
```bash
npm install hubot-ollama --save
```
Then add to `external-scripts.json`:
```json
["hubot-ollama"]
```
3. Start chatting:
```text
hubot ask what is an LLM?
hubot ollama explain async/await
hubot llm write a haiku about databases
```
## Commands
| Pattern | Example | Notes |
|---------|---------|-------|
| `hubot ask ` | `hubot ask what is caching?` | Primary documented command |
| `hubot ollama ` | `hubot ollama summarize HTTP` | Alias |
| `hubot llm ` | `hubot llm list json benefits` | Alias |
Prompts are sanitized and truncated if they exceed the configured limit.
## Configuration
| Variable | Required | Default | Purpose |
|----------|----------|---------|---------|
| `HUBOT_OLLAMA_MODEL` | Optional | `llama3.2` | Model name (validated: `[A-Za-z0-9._:-]+`) |
| `HUBOT_OLLAMA_HOST` | Optional | `http://127.0.0.1:11434` | Ollama server URL |
| `HUBOT_OLLAMA_API_KEY` | Optional | (unset) | API key for [Ollama cloud](https://ollama.com/settings/keys) access |
| `HUBOT_OLLAMA_SYSTEM_PROMPT` | Optional | Builtβin concise chat prompt | Override system instructions |
| `HUBOT_OLLAMA_MAX_PROMPT_CHARS` | Optional | `2000` | Truncate overly long user prompts |
| `HUBOT_OLLAMA_TIMEOUT_MS` | Optional | `60000` (60 sec) | Abort request after this duration |
| `HUBOT_OLLAMA_CONTEXT_TTL_MS` | Optional | `600000` (10 min) | Time to maintain conversation history; `0` to disable |
| `HUBOT_OLLAMA_CONTEXT_TURNS` | Optional | `5` | Maximum number of conversation turns to remember |
| `HUBOT_OLLAMA_CONTEXT_SCOPE` | Optional | `room-user` | Context isolation: `room-user`, `room`, or `thread` |
| `HUBOT_OLLAMA_RESPOND_TO_ADDRESSED_FALLBACK` | Optional | `false` | Enable fallback replies for addressed messages when no other listener matched |
| `HUBOT_OLLAMA_WEB_ENABLED` | Optional | `false` | Enable web-assisted workflow that can search/fetch context |
| `HUBOT_OLLAMA_WEB_MAX_RESULTS` | Optional | `5` | Max search results to use (capped at 10) |
| `HUBOT_OLLAMA_WEB_FETCH_CONCURRENCY` | Optional | `3` | Parallel fetch concurrency |
| `HUBOT_OLLAMA_WEB_MAX_BYTES` | Optional | `120000` | Max bytes per fetched page used in context |
| `HUBOT_OLLAMA_WEB_TIMEOUT_MS` | Optional | `45000` | Timeout for the web phase per fetch |
Change model:
```bash
export HUBOT_OLLAMA_MODEL=mistral
```
Connect to remote Ollama server:
```bash
export HUBOT_OLLAMA_HOST=http://my-ollama-server:11434
```
Use Ollama cloud (requires [API key](https://ollama.com/settings/keys)):
```bash
export HUBOT_OLLAMA_HOST=https://ollama.com
export HUBOT_OLLAMA_API_KEY=your_api_key
export HUBOT_OLLAMA_MODEL=gpt-oss:120b # Use a cloud model
# Note: The host should match what `ollama signin` configures.
# Some environments may use a region-specific or API-prefixed host.
# Check `ollama signin --verbose` if unsure.
```
Custom system prompt:
```bash
export HUBOT_OLLAMA_SYSTEM_PROMPT="You are terse; answer in <=200 chars."
```
Adjust conversation memory:
```bash
# Keep 10 turns for 30 minutes, shared across the room
export HUBOT_OLLAMA_CONTEXT_TURNS=10
export HUBOT_OLLAMA_CONTEXT_TTL_MS=1800000
export HUBOT_OLLAMA_CONTEXT_SCOPE=room
```
Enable addressed fallback mode:
```bash
export HUBOT_OLLAMA_RESPOND_TO_ADDRESSED_FALLBACK=true
```
### Addressed Fallback Mode
When `HUBOT_OLLAMA_RESPOND_TO_ADDRESSED_FALLBACK=true`, hubot-ollama can answer without `ask`/`ollama`/`llm` prefixes, but only as a fallback.
- It runs through Hubot `catchAll`, so it only triggers when no other listener matched first.
- 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).
- In Slack, `@mentions` are normalized to the alias character by the adapter, so alias-prefix messages are treated as bot-addressed.
- Single-token alias-prefix messages (for example: `! ping`) are treated as command misses and ignored.
- In direct messages/private chats, plain text is treated as addressed.
- Explicit commands still work exactly as before (`hubot ask ...`, `hubot ollama ...`, `hubot llm ...`).
## Examples
```text
hubot ask explain vector embeddings
hubot llm generate a short motivational quote
hubot ollama compare sql vs nosql
```
### Web-Enabled Workflow
When `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:
- Phase 1: The model chooses whether to call `hubot_ollama_web_search`.
- Phase 2: The tool performs `webSearch`, fetches top results in parallel, builds a compact context block, and returns it.
- Phase 3: The model incorporates the returned context into its final reply.
- The bot sends a status message when the search is running and skips duplicate web searches in the same interaction.
### Slack Reactions And Status
When running with the Slack adapter, hubot-ollama uses reactions/status indicators on the triggering message:
- `π` (`thought_balloon`) while the main prompt is being processed.
- `π οΈ` (`hammer_and_wrench`) while a tool call is actively executing.
- `β³` status text is posted during web search (`_Searching web for relevant sources..._`).
Reactions require Slack reaction scopes (for example, `reactions:write`).
If reaction permissions are missing, the bot continues normally and keeps the existing web-search status message behavior.
Enable:
```bash
export HUBOT_OLLAMA_WEB_ENABLED=true
export HUBOT_OLLAMA_WEB_MAX_RESULTS=5
export HUBOT_OLLAMA_WEB_FETCH_CONCURRENCY=3
export HUBOT_OLLAMA_WEB_MAX_BYTES=120000
export HUBOT_OLLAMA_WEB_TIMEOUT_MS=45000
```
### Tool Integration
The bot uses a **two-call LLM workflow** to enable tools when supported by the model:
1. **Phase 1**: Model decides if a tool is needed to answer the question
2. **Phase 2**: Tool is executed (if selected) and results are captured
3. **Phase 3**: Model incorporates tool results into a natural conversational response
**Built-in Tools:**
- `hubot_ollama_get_current_time` - Returns the current UTC timestamp (always available)
**Configuration:**
| Variable | Required | Default | Purpose |
|----------|----------|---------|---------|
| `HUBOT_OLLAMA_TOOLS_ENABLED` | Optional | `true` | Enable tool support (`true`/`1` or `false`/`0`) |
Enable tool support (default):
```bash
export HUBOT_OLLAMA_TOOLS_ENABLED=true
```
Disable tool support (useful for models without tool capability):
```bash
export HUBOT_OLLAMA_TOOLS_ENABLED=false
```
**How It Works:**
- The bot automatically detects whether your selected model supports tools via `ollama show`.
- If tools are enabled AND the model supports them, the two-call workflow activates.
- If the model doesn't support tools or tools are disabled, the bot falls back to a single-call workflow.
- When a tool is invoked, the model can request data (like current time) to enhance its response.
**Example Tool Interaction:**
```text
user> hubot ask what time is it in UTC?
hubot> (Phase 1: Model decides current time is needed)
(Phase 2: Tool returns: 2025-12-05T14:30:45.123Z)
(Phase 3: Model incorporates and responds)
The current UTC time is 2:30:45 PM on December 5, 2025.
```
**Registering Custom Tools:**
Use the tool registry to add your own tools:
```javascript
const registry = require('hubot-ollama/src/tool-registry');
registry.registerTool('my_tool', {
name: 'my_tool',
description: 'A brief description of what this tool does',
parameters: {
type: 'object',
properties: {
param1: { type: 'string', description: 'The first parameter' }
}
},
handler: async (args, robot, msg) => {
// args: parsed arguments from the LLM
// robot: Hubot robot instance
// msg: Current message object, use msg.send() to output results while tool in use
return { result: 'Tool output here' };
}
});
```
### Conversation Context
Hubot remembers recent exchanges within the configured scope, allowing natural follow-up questions:
```text
alice> hubot ask what are the planets in our solar system?
hubot> Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune.
alice> hubot ask which is the largest?
hubot> Jupiter is the largest planet in our solar system.
```
**Context Scopes:**
- `room-user` (default): Each user has separate conversation history per room
- `room`: All users in a room share the same conversation history
- `thread`: Separate history per thread (for Slack-style threading)
Context automatically expires after the configured TTL (default 10 minutes). Set `HUBOT_OLLAMA_CONTEXT_TTL_MS=0` to disable conversation memory entirely.
**Automatic Token Optimization:**
For 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.
## Ollama Cloud
This 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.
### Setup
1. Create an account at [ollama.com](https://ollama.com/signup)
2. Generate an [API key](https://ollama.com/settings/keys)
3. Run `ollama signin` to register the host with Ollama.com
4. Configure your environment:
```bash
export HUBOT_OLLAMA_HOST=https://ollama.com
export HUBOT_OLLAMA_API_KEY=your_api_key
export HUBOT_OLLAMA_MODEL=gpt-oss:120b-cloud
```
### Available Models
Hubot-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.
> Cloud model availability changes over time. Check the model catalog at [Ollama.com](https://ollama.com/search?c=cloud) for the latest list.
Both local and cloud models share the same API, making the integration seamless regardless of where your model runs.
**Note:** Cloud models require network connectivity and count against your cloud usage. Local models remain free and private.
## Error Handling
| Situation | User Message |
|-----------|------------|
| Ollama server unreachable | Cannot connect to Ollama server message |
| Model missing | Suggest `ollama pull ` |
| Empty response | Specific empty response notice |
| Timeout | Indicates the configured timeout elapsed |
| API error | Surfaces error message |
## Security & Safety
- Uses official Ollama JavaScript library with proper API communication.
- Model name validation & prompt sanitization (strip control chars).
- 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.
## Troubleshooting
| Symptom | Check |
|---------|-------|
| No response | Check Hubot logs for errors; verify Ollama server is accessible |
| Connection refused | Ensure Ollama server is running (`ollama serve` or daemon) |
| Model not found | Run `ollama list` to see available models, then `ollama pull ` |
| Wrong server | Set `HUBOT_OLLAMA_HOST=http://your-server:11434` |
| Long delays | Try increasing `HUBOT_OLLAMA_TIMEOUT_MS` or use a faster model |
| Web tools not running | The connected Ollama host must support `webSearch`/`webFetch`; feature auto-skips when unavailable |
| No search performed | The model decided a web search was unnecessary; disable web workflow or ask explicitly |
| `Error: unauthorized` | If using a cloud model, you must run `ollama signin` to register the host |
| Other cloud auth issues | Verify your `HUBOT_OLLAMA_API_KEY` is valid at [ollama.com/settings/keys](https://ollama.com/settings/keys) |
## Development
Run tests & lint:
```bash
npm test
npm run lint
```
## License
MIT