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
4 changes: 4 additions & 0 deletions .github/workflows/release-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,13 +288,17 @@ jobs:
EOF

# DNF/YUM repo file
# metadata_expire=300 ensures dnf checks for new packages every 5 minutes
# (GitHub Pages CDN caches for max 10 minutes, so 5 min is a safe middle ground)
cat > repo/xnoto.repo << 'EOF'
[xnoto]
name=xnoto packages
baseurl=https://xnoto.github.io/opencode-agent-hub/rpm
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://xnoto.github.io/opencode-agent-hub/KEY.gpg
metadata_expire=300
EOF

- name: Create index page
Expand Down
29 changes: 22 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,16 @@ This project uses [Conventional Commits](https://www.conventionalcommits.org/) (
| `perf` | Performance improvement | Patch |
| `ci` | CI/CD changes | None |

### Scope (required)
### Scope (recommended)

Use a scope to indicate what area is affected:
- `daemon` - Main daemon code
- `watch` - Dashboard script
- `config` - Configuration/env vars
- `config` - Configuration/env vars/config file
- `docs` - Documentation
- `ci` - GitHub Actions
- `deps` - Dependencies
- `tests` - Test files

### Examples

Expand Down Expand Up @@ -95,18 +96,32 @@ Releases are automated via [release-please](https://github.com/google-github-act

```
~/.agent-hub/
├── agents/ # Agent registration files
├── messages/ # Message queue (JSON files)
│ └── archive/ # Processed messages
└── threads/ # Conversation tracking
├── agents/ # Agent registration files
├── messages/ # Message queue (JSON files)
│ └── archive/ # Processed messages
├── threads/ # Conversation tracking
├── session_agents.json # Session-to-agent identity mapping
└── oriented_sessions.json # Session orientation cache

~/.config/agent-hub-daemon/
├── config.json # Optional config file (env vars override)
├── AGENTS.md # Optional coordinator instructions override
└── COORDINATOR.md # Alias for AGENTS.md

Daemon watches these directories and:
1. Detects new messages via watchdog
2. Looks up target agent's OpenCode session
2. Looks up target agent's OpenCode session (by session ID, not directory)
3. Injects message via OpenCode HTTP API
4. Marks message as delivered
```

### Session-Based Agent Identity

Multiple OpenCode sessions in the same directory each get a unique agent identity:
- Agent ID derived from session slug (e.g., "cosmic-panda") or session ID
- Enables parallel agents working on the same codebase without conflicts
- Session-agent mapping persisted in `~/.agent-hub/session_agents.json`

## Testing

Tests use pytest:
Expand Down
107 changes: 98 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ Enables multiple AI agents running in separate OpenCode sessions to communicate,
- **Message Bus**: Filesystem-based message passing between agents via `~/.agent-hub/messages/`
- **Session Integration**: Automatically discovers and injects messages into OpenCode sessions
- **Thread Management**: Conversations tracked with auto-created thread IDs and resolution
- **Agent Auto-Registration**: Sessions automatically registered as agents by project path
- **Session-Based Agent Identity**: Each OpenCode session gets a unique agent ID (even in the same directory)
- **Agent Auto-Registration**: Sessions automatically registered as agents with unique identities
- **Garbage Collection**: Stale messages, agents, and threads cleaned up (1hr TTL)
- **Prometheus Metrics**: Exportable metrics at `~/.agent-hub/metrics.prom`
- **Dashboard**: Real-time terminal UI showing agents, threads, and messages
- **Config File Support**: Optional JSON config file at `~/.config/agent-hub-daemon/config.json`

## How It Works

Expand All @@ -66,10 +68,12 @@ The daemon operates as a **message broker** between OpenCode sessions, using a l

1. **Daemon starts** an OpenCode relay server on port 4096 (if not already running)
2. **Polls the relay API** (`GET /session`) every 5 seconds to discover active sessions
3. **Auto-registers agents** based on each session's working directory (project path)
3. **Auto-registers agents** with unique identities derived from session slug or ID
4. **Injects an orientation message** into newly discovered sessions, informing the agent of its registered identity
5. **Notifies the coordinator** to capture the agent's task and introduce related agents

**Note**: Multiple sessions in the same directory each get unique agent IDs (e.g., "cosmic-panda", "brave-tiger"), enabling parallel agents working on the same codebase.

### Message Flow

When Agent A sends a message to Agent B:
Expand Down Expand Up @@ -440,12 +444,67 @@ uv run src/opencode_agent_hub/watch.py

## Configuration

Configuration via environment variables:
The daemon supports configuration via a JSON config file and/or environment variables.

**Precedence**: Environment variables > Config file > Defaults

### Config File

Create `~/.config/agent-hub-daemon/config.json`:

```json
{
"opencode_port": 4096,
"log_level": "INFO",
"rate_limit": {
"enabled": false,
"max_messages": 10,
"window_seconds": 300,
"cooldown_seconds": 0
},
"coordinator": {
"enabled": true,
"model": "opencode/claude-opus-4-5",
"directory": "~/.agent-hub/coordinator",
"agents_md": ""
},
"gc": {
"message_ttl_seconds": 3600,
"agent_stale_seconds": 3600,
"interval_seconds": 60
},
"session": {
"poll_seconds": 5,
"cache_ttl": 10
},
"injection": {
"workers": 4,
"retries": 3,
"timeout": 5
},
"metrics_interval": 30
}
```

All fields are optional - only specify what you want to override.

### Environment Variables

Environment variables take precedence over config file values:

| Variable | Default | Description |
|----------|---------|-------------|
| `OPENCODE_PORT` | `4096` | Port for OpenCode relay server |
| `AGENT_HUB_DAEMON_LOG_LEVEL` | `INFO` | Logging level (DEBUG, INFO, WARNING, ERROR) |
| `AGENT_HUB_MESSAGE_TTL` | `3600` | Message TTL in seconds |
| `AGENT_HUB_AGENT_STALE` | `3600` | Agent stale threshold in seconds |
| `AGENT_HUB_GC_INTERVAL` | `60` | Garbage collection interval in seconds |
| `AGENT_HUB_SESSION_POLL` | `5` | Session poll interval in seconds |
| `AGENT_HUB_SESSION_CACHE_TTL` | `10` | Session cache TTL in seconds |
| `AGENT_HUB_INJECTION_WORKERS` | `4` | Number of injection worker threads |
| `AGENT_HUB_INJECTION_RETRIES` | `3` | Injection retry attempts |
| `AGENT_HUB_INJECTION_TIMEOUT` | `5` | Injection timeout in seconds |
| `AGENT_HUB_METRICS_INTERVAL` | `30` | Metrics write interval in seconds |

### Rate Limiting (Optional)

Expand Down Expand Up @@ -480,23 +539,53 @@ Configuration via environment variables:
| `AGENT_HUB_COORDINATOR` | `true` | Enable the coordinator agent (`true`, `1`, or `yes`) |
| `AGENT_HUB_COORDINATOR_MODEL` | `opencode/claude-opus-4-5` | OpenCode model for the coordinator session |
| `AGENT_HUB_COORDINATOR_DIR` | `~/.agent-hub/coordinator` | Directory used for the coordinator session |
| `AGENT_HUB_COORDINATOR_AGENTS_MD` | (auto-detect) | Custom path to coordinator AGENTS.md |

Example - run coordinator on a different model:

```bash
export AGENT_HUB_COORDINATOR_MODEL=opencode/claude-sonnet-4-5
```

#### Custom Coordinator Instructions

You can customize the coordinator's behavior by providing your own AGENTS.md file. The daemon searches for the template in this order:

1. **Explicit config**: `AGENT_HUB_COORDINATOR_AGENTS_MD` env var or `coordinator.agents_md` in config file
2. **User config**: `~/.config/agent-hub-daemon/AGENTS.md`
3. **User config alias**: `~/.config/agent-hub-daemon/COORDINATOR.md`
4. **Package template**: `contrib/coordinator/AGENTS.md` (from installation)
5. **System locations**: `/usr/local/share/opencode-agent-hub/coordinator/AGENTS.md`

If no template is found, a minimal default is created. To customize:

```bash
# Copy the default template and edit
mkdir -p ~/.config/agent-hub-daemon
cp /path/to/opencode-agent-hub/contrib/coordinator/AGENTS.md ~/.config/agent-hub-daemon/
# Edit to your liking
```

Or specify an explicit path:

```bash
export AGENT_HUB_COORDINATOR_AGENTS_MD=~/my-coordinator-instructions.md
```

## Directory Structure

```
~/.agent-hub/
├── agents/ # Registered agent JSON files
├── messages/ # Pending messages (JSON files)
│ └── archive/ # Processed/expired messages
├── threads/ # Conversation thread tracking
├── metrics.prom # Prometheus metrics export
└── oriented_sessions.json # Session orientation cache
├── agents/ # Registered agent JSON files
├── messages/ # Pending messages (JSON files)
│ └── archive/ # Processed/expired messages
├── threads/ # Conversation thread tracking
├── metrics.prom # Prometheus metrics export
├── oriented_sessions.json # Session orientation cache
└── session_agents.json # Session-to-agent identity mapping

~/.config/agent-hub-daemon/
└── config.json # Optional config file
```

## Message Format
Expand Down
Loading
Loading