agent-bus-mcp 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agent_bus_mcp-0.1.0/.github/workflows/build-wheels.yml +112 -0
- agent_bus_mcp-0.1.0/.github/workflows/ci.yml +84 -0
- agent_bus_mcp-0.1.0/.github/workflows/publish-testpypi.yml +134 -0
- agent_bus_mcp-0.1.0/.gitignore +29 -0
- agent_bus_mcp-0.1.0/AGENTS.md +50 -0
- agent_bus_mcp-0.1.0/CLAUDE.md +82 -0
- agent_bus_mcp-0.1.0/Cargo.lock +2464 -0
- agent_bus_mcp-0.1.0/Cargo.toml +18 -0
- agent_bus_mcp-0.1.0/LICENSE +21 -0
- agent_bus_mcp-0.1.0/PKG-INFO +337 -0
- agent_bus_mcp-0.1.0/README.md +308 -0
- agent_bus_mcp-0.1.0/agent_bus/__init__.py +3 -0
- agent_bus_mcp-0.1.0/agent_bus/cli.py +778 -0
- agent_bus_mcp-0.1.0/agent_bus/common.py +119 -0
- agent_bus_mcp-0.1.0/agent_bus/db.py +322 -0
- agent_bus_mcp-0.1.0/agent_bus/embedding_worker.py +209 -0
- agent_bus_mcp-0.1.0/agent_bus/entrypoint.py +40 -0
- agent_bus_mcp-0.1.0/agent_bus/models.py +37 -0
- agent_bus_mcp-0.1.0/agent_bus/peer_server.py +826 -0
- agent_bus_mcp-0.1.0/agent_bus/search.py +307 -0
- agent_bus_mcp-0.1.0/agent_bus/tool_schemas.py +192 -0
- agent_bus_mcp-0.1.0/agent_bus/web/__init__.py +1 -0
- agent_bus_mcp-0.1.0/agent_bus/web/server.py +405 -0
- agent_bus_mcp-0.1.0/agent_bus/web/templates/base.html +1203 -0
- agent_bus_mcp-0.1.0/agent_bus/web/templates/components/message.html +102 -0
- agent_bus_mcp-0.1.0/agent_bus/web/templates/components/messages.html +32 -0
- agent_bus_mcp-0.1.0/agent_bus/web/templates/components/presence.html +10 -0
- agent_bus_mcp-0.1.0/agent_bus/web/templates/components/search_results.html +40 -0
- agent_bus_mcp-0.1.0/agent_bus/web/templates/topics/detail.html +222 -0
- agent_bus_mcp-0.1.0/agent_bus/web/templates/topics/list.html +35 -0
- agent_bus_mcp-0.1.0/pyproject.toml +80 -0
- agent_bus_mcp-0.1.0/spec.md +263 -0
- agent_bus_mcp-0.1.0/src/lib.rs +2792 -0
- agent_bus_mcp-0.1.0/tests/test_cli.py +418 -0
- agent_bus_mcp-0.1.0/tests/test_cli_export.py +241 -0
- agent_bus_mcp-0.1.0/tests/test_cli_search.py +49 -0
- agent_bus_mcp-0.1.0/tests/test_cli_tail_flag.py +39 -0
- agent_bus_mcp-0.1.0/tests/test_db.py +722 -0
- agent_bus_mcp-0.1.0/tests/test_db_latest.py +39 -0
- agent_bus_mcp-0.1.0/tests/test_pagination.py +118 -0
- agent_bus_mcp-0.1.0/tests/test_search.py +54 -0
- agent_bus_mcp-0.1.0/tests/test_tools_smoke.py +197 -0
- agent_bus_mcp-0.1.0/tests/test_validation.py +45 -0
- agent_bus_mcp-0.1.0/uv.lock +925 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
name: build-wheels
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
upload_artifacts:
|
|
7
|
+
type: boolean
|
|
8
|
+
default: true
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
inputs:
|
|
11
|
+
upload_artifacts:
|
|
12
|
+
type: boolean
|
|
13
|
+
default: true
|
|
14
|
+
|
|
15
|
+
env:
|
|
16
|
+
ORT_VERSION: "1.23.2"
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
sdist:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Validate version sync
|
|
25
|
+
run: |
|
|
26
|
+
python - <<'PY'
|
|
27
|
+
import tomllib
|
|
28
|
+
|
|
29
|
+
with open("pyproject.toml", "rb") as fh:
|
|
30
|
+
pyproject = tomllib.load(fh)
|
|
31
|
+
with open("Cargo.toml", "rb") as fh:
|
|
32
|
+
cargo = tomllib.load(fh)
|
|
33
|
+
|
|
34
|
+
py_version = pyproject["project"]["version"]
|
|
35
|
+
cargo_version = cargo["package"]["version"]
|
|
36
|
+
|
|
37
|
+
if py_version != cargo_version:
|
|
38
|
+
raise SystemExit(
|
|
39
|
+
f"Version mismatch: pyproject.toml={py_version} Cargo.toml={cargo_version}"
|
|
40
|
+
)
|
|
41
|
+
print(f"Version OK: {py_version}")
|
|
42
|
+
PY
|
|
43
|
+
|
|
44
|
+
- name: Build sdist
|
|
45
|
+
uses: PyO3/maturin-action@v1
|
|
46
|
+
with:
|
|
47
|
+
command: sdist
|
|
48
|
+
args: --out dist
|
|
49
|
+
|
|
50
|
+
- name: Upload sdist
|
|
51
|
+
if: inputs.upload_artifacts
|
|
52
|
+
uses: actions/upload-artifact@v4
|
|
53
|
+
with:
|
|
54
|
+
name: sdist
|
|
55
|
+
path: dist/*.tar.gz
|
|
56
|
+
if-no-files-found: error
|
|
57
|
+
|
|
58
|
+
wheels:
|
|
59
|
+
runs-on: ${{ matrix.os }}
|
|
60
|
+
strategy:
|
|
61
|
+
fail-fast: false
|
|
62
|
+
matrix:
|
|
63
|
+
os:
|
|
64
|
+
- ubuntu-latest
|
|
65
|
+
- macos-14
|
|
66
|
+
- windows-latest
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v4
|
|
69
|
+
|
|
70
|
+
- name: Download ONNX Runtime (Windows)
|
|
71
|
+
if: runner.os == 'Windows'
|
|
72
|
+
shell: pwsh
|
|
73
|
+
run: |
|
|
74
|
+
$zip = "$env:RUNNER_TEMP/onnxruntime-win-x64-$env:ORT_VERSION.zip"
|
|
75
|
+
$dir = "$env:RUNNER_TEMP/onnxruntime-win-x64-$env:ORT_VERSION"
|
|
76
|
+
Invoke-WebRequest -Uri "https://github.com/microsoft/onnxruntime/releases/download/v$env:ORT_VERSION/onnxruntime-win-x64-$env:ORT_VERSION.zip" -OutFile $zip
|
|
77
|
+
Expand-Archive -Path $zip -DestinationPath $env:RUNNER_TEMP
|
|
78
|
+
"ORT_LIB_LOCATION=$dir\\lib" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
79
|
+
"ORT_PREFER_DYNAMIC_LINK=1" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
80
|
+
"PATH=$dir\\lib;$env:PATH" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
81
|
+
|
|
82
|
+
- name: Build wheels (Linux, manylinux_2_28)
|
|
83
|
+
if: runner.os == 'Linux'
|
|
84
|
+
uses: PyO3/maturin-action@v1
|
|
85
|
+
with:
|
|
86
|
+
command: build
|
|
87
|
+
args: --release --out dist
|
|
88
|
+
manylinux: 2_28
|
|
89
|
+
|
|
90
|
+
- name: Build wheels (Linux, manylinux_2_28 aarch64)
|
|
91
|
+
if: runner.os == 'Linux'
|
|
92
|
+
uses: PyO3/maturin-action@v1
|
|
93
|
+
with:
|
|
94
|
+
command: build
|
|
95
|
+
args: --release --out dist
|
|
96
|
+
manylinux: 2_28
|
|
97
|
+
target: aarch64-unknown-linux-gnu
|
|
98
|
+
|
|
99
|
+
- name: Build wheels (macOS/Windows)
|
|
100
|
+
if: runner.os != 'Linux'
|
|
101
|
+
uses: PyO3/maturin-action@v1
|
|
102
|
+
with:
|
|
103
|
+
command: build
|
|
104
|
+
args: --release --out dist
|
|
105
|
+
|
|
106
|
+
- name: Upload wheels
|
|
107
|
+
if: inputs.upload_artifacts
|
|
108
|
+
uses: actions/upload-artifact@v4
|
|
109
|
+
with:
|
|
110
|
+
name: wheels-${{ runner.os }}
|
|
111
|
+
path: dist/*.whl
|
|
112
|
+
if-no-files-found: error
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
ORT_VERSION: "1.23.2"
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
os:
|
|
19
|
+
- ubuntu-latest
|
|
20
|
+
- macos-14
|
|
21
|
+
- windows-latest
|
|
22
|
+
python-version:
|
|
23
|
+
- "3.12"
|
|
24
|
+
- "3.13"
|
|
25
|
+
- "3.14"
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
30
|
+
with:
|
|
31
|
+
components: rustfmt, clippy
|
|
32
|
+
|
|
33
|
+
- uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: ${{ matrix.python-version }}
|
|
36
|
+
|
|
37
|
+
- uses: astral-sh/setup-uv@v3
|
|
38
|
+
with:
|
|
39
|
+
enable-cache: true
|
|
40
|
+
|
|
41
|
+
- name: Download ONNX Runtime (Windows)
|
|
42
|
+
if: runner.os == 'Windows'
|
|
43
|
+
shell: pwsh
|
|
44
|
+
run: |
|
|
45
|
+
$zip = "$env:RUNNER_TEMP/onnxruntime-win-x64-$env:ORT_VERSION.zip"
|
|
46
|
+
$dir = "$env:RUNNER_TEMP/onnxruntime-win-x64-$env:ORT_VERSION"
|
|
47
|
+
Invoke-WebRequest -Uri "https://github.com/microsoft/onnxruntime/releases/download/v$env:ORT_VERSION/onnxruntime-win-x64-$env:ORT_VERSION.zip" -OutFile $zip
|
|
48
|
+
Expand-Archive -Path $zip -DestinationPath $env:RUNNER_TEMP
|
|
49
|
+
"ORT_LIB_LOCATION=$dir\\lib" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
50
|
+
"ORT_PREFER_DYNAMIC_LINK=1" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
51
|
+
"PATH=$dir\\lib;$env:PATH" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
52
|
+
|
|
53
|
+
- name: Sync deps
|
|
54
|
+
run: uv sync --dev
|
|
55
|
+
|
|
56
|
+
- name: Build wheel
|
|
57
|
+
run: uv run maturin build --release -o dist
|
|
58
|
+
|
|
59
|
+
- name: Install wheel
|
|
60
|
+
shell: bash
|
|
61
|
+
run: uv pip install --force-reinstall dist/*.whl
|
|
62
|
+
|
|
63
|
+
- name: Run tests
|
|
64
|
+
run: uv run pytest
|
|
65
|
+
|
|
66
|
+
- name: Cargo fmt
|
|
67
|
+
run: cargo fmt --check
|
|
68
|
+
|
|
69
|
+
- name: Cargo clippy
|
|
70
|
+
run: cargo clippy --all-targets -- -D warnings
|
|
71
|
+
|
|
72
|
+
- name: Ruff format
|
|
73
|
+
run: uv run ruff format --check
|
|
74
|
+
|
|
75
|
+
- name: Ruff lint
|
|
76
|
+
run: uv run ruff check
|
|
77
|
+
|
|
78
|
+
- name: Ty type check
|
|
79
|
+
run: uv run ty check
|
|
80
|
+
|
|
81
|
+
wheels:
|
|
82
|
+
uses: ./.github/workflows/build-wheels.yml
|
|
83
|
+
with:
|
|
84
|
+
upload_artifacts: false
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
name: publish-testpypi
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
publish_target:
|
|
7
|
+
description: "Publish destination"
|
|
8
|
+
required: true
|
|
9
|
+
type: choice
|
|
10
|
+
default: testpypi
|
|
11
|
+
options:
|
|
12
|
+
- testpypi
|
|
13
|
+
- pypi
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
uses: ./.github/workflows/build-wheels.yml
|
|
21
|
+
with:
|
|
22
|
+
upload_artifacts: true
|
|
23
|
+
|
|
24
|
+
upload:
|
|
25
|
+
needs: build
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
outputs:
|
|
28
|
+
version: ${{ steps.version.outputs.version }}
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- name: Download artifacts
|
|
33
|
+
uses: actions/download-artifact@v4
|
|
34
|
+
with:
|
|
35
|
+
path: dist
|
|
36
|
+
merge-multiple: true
|
|
37
|
+
|
|
38
|
+
- uses: astral-sh/setup-uv@v3
|
|
39
|
+
with:
|
|
40
|
+
enable-cache: false
|
|
41
|
+
|
|
42
|
+
- name: Upload to TestPyPI
|
|
43
|
+
shell: bash
|
|
44
|
+
run: |
|
|
45
|
+
set -euo pipefail
|
|
46
|
+
repo_url="https://test.pypi.org/legacy/"
|
|
47
|
+
token="${{ secrets.TEST_PYPI_API_TOKEN }}"
|
|
48
|
+
if [ "${{ inputs.publish_target }}" = "pypi" ]; then
|
|
49
|
+
repo_url="https://upload.pypi.org/legacy/"
|
|
50
|
+
token="${{ secrets.PYPI_API_TOKEN }}"
|
|
51
|
+
fi
|
|
52
|
+
MATURIN_PYPI_TOKEN="$token" MATURIN_REPOSITORY_URL="$repo_url" \
|
|
53
|
+
uvx --from "maturin>=1.11.5,<2.0" maturin upload --non-interactive --skip-existing dist/*
|
|
54
|
+
|
|
55
|
+
- name: Determine version
|
|
56
|
+
id: version
|
|
57
|
+
run: |
|
|
58
|
+
python - <<'PY'
|
|
59
|
+
import os
|
|
60
|
+
import tomllib
|
|
61
|
+
|
|
62
|
+
with open("pyproject.toml", "rb") as fh:
|
|
63
|
+
data = tomllib.load(fh)
|
|
64
|
+
version = data["project"]["version"]
|
|
65
|
+
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as fh:
|
|
66
|
+
fh.write(f"version={version}\n")
|
|
67
|
+
print(f"Detected version: {version}")
|
|
68
|
+
PY
|
|
69
|
+
|
|
70
|
+
qa-install:
|
|
71
|
+
needs: upload
|
|
72
|
+
if: ${{ inputs.publish_target == 'testpypi' }}
|
|
73
|
+
runs-on: ${{ matrix.os }}
|
|
74
|
+
strategy:
|
|
75
|
+
fail-fast: false
|
|
76
|
+
matrix:
|
|
77
|
+
os:
|
|
78
|
+
- ubuntu-latest
|
|
79
|
+
- macos-14
|
|
80
|
+
- windows-latest
|
|
81
|
+
steps:
|
|
82
|
+
- uses: actions/setup-python@v5
|
|
83
|
+
with:
|
|
84
|
+
python-version: "3.12"
|
|
85
|
+
|
|
86
|
+
- uses: astral-sh/setup-uv@v3
|
|
87
|
+
with:
|
|
88
|
+
enable-cache: true
|
|
89
|
+
|
|
90
|
+
- name: Install from TestPyPI (no build)
|
|
91
|
+
shell: bash
|
|
92
|
+
env:
|
|
93
|
+
VERSION: ${{ needs.upload.outputs.version }}
|
|
94
|
+
run: |
|
|
95
|
+
set -euo pipefail
|
|
96
|
+
echo "Testing install for agent-bus-mcp==$VERSION on $RUNNER_OS"
|
|
97
|
+
for attempt in {1..10}; do
|
|
98
|
+
if uvx --no-build \
|
|
99
|
+
--default-index https://test.pypi.org/simple \
|
|
100
|
+
--index https://pypi.org/simple \
|
|
101
|
+
--from "agent-bus-mcp==${VERSION}" \
|
|
102
|
+
agent-bus --help; then
|
|
103
|
+
exit 0
|
|
104
|
+
fi
|
|
105
|
+
echo "Install failed (attempt $attempt). Waiting for TestPyPI propagation..."
|
|
106
|
+
sleep 20
|
|
107
|
+
done
|
|
108
|
+
echo "Install failed after retries."
|
|
109
|
+
exit 1
|
|
110
|
+
|
|
111
|
+
tag-release:
|
|
112
|
+
needs: upload
|
|
113
|
+
if: ${{ inputs.publish_target == 'pypi' }}
|
|
114
|
+
runs-on: ubuntu-latest
|
|
115
|
+
steps:
|
|
116
|
+
- uses: actions/checkout@v4
|
|
117
|
+
with:
|
|
118
|
+
fetch-depth: 0
|
|
119
|
+
fetch-tags: true
|
|
120
|
+
|
|
121
|
+
- name: Create annotated tag
|
|
122
|
+
env:
|
|
123
|
+
VERSION: ${{ needs.upload.outputs.version }}
|
|
124
|
+
run: |
|
|
125
|
+
set -euo pipefail
|
|
126
|
+
tag="v${VERSION}"
|
|
127
|
+
if git rev-parse "$tag" >/dev/null 2>&1; then
|
|
128
|
+
echo "Tag $tag already exists, skipping."
|
|
129
|
+
exit 0
|
|
130
|
+
fi
|
|
131
|
+
git config user.name "github-actions[bot]"
|
|
132
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
133
|
+
git tag -a "$tag" "$GITHUB_SHA" -m "Release $tag"
|
|
134
|
+
git push origin "$tag"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
.venv/
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.pytest_cache/
|
|
5
|
+
.ruff_cache/
|
|
6
|
+
.mypy_cache/
|
|
7
|
+
dist/
|
|
8
|
+
dist-*/
|
|
9
|
+
build/
|
|
10
|
+
target/
|
|
11
|
+
*.egg-info/
|
|
12
|
+
agent_bus/_core*.so
|
|
13
|
+
agent_bus/_core*.pyd
|
|
14
|
+
agent_bus/_core*.dylib
|
|
15
|
+
.DS_Store
|
|
16
|
+
.claude
|
|
17
|
+
.claude/
|
|
18
|
+
.gemini/
|
|
19
|
+
.vscode/
|
|
20
|
+
specs*.md
|
|
21
|
+
|
|
22
|
+
# Waylog transcripts (may contain sensitive info)
|
|
23
|
+
.waylog/
|
|
24
|
+
.waylog-journal/
|
|
25
|
+
|
|
26
|
+
# Local DB artifacts (if created under repo by tests/dev)
|
|
27
|
+
*.sqlite
|
|
28
|
+
*.sqlite-wal
|
|
29
|
+
*.sqlite-shm
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Repository Guidelines
|
|
2
|
+
|
|
3
|
+
## Project Structure & Module Organization
|
|
4
|
+
|
|
5
|
+
- `agent_bus/`: main Python package
|
|
6
|
+
- `peer_server.py`: MCP server (FastMCP) tools: `topic_*`, `cursor_reset`, `sync`
|
|
7
|
+
- `db.py`: SQLite (WAL) storage, schema/versioning, sync/cursor logic
|
|
8
|
+
- `cli.py`: admin CLI (`agent-bus cli ...`)
|
|
9
|
+
- `web/`: optional FastAPI web UI + Jinja templates in `agent_bus/web/templates/`
|
|
10
|
+
- `tests/`: pytest suite (`test_*.py`)
|
|
11
|
+
- `spec.md`: protocol + schema spec (treat as the source of truth when changing behavior)
|
|
12
|
+
|
|
13
|
+
## Build, Test, and Development Commands
|
|
14
|
+
|
|
15
|
+
This repo targets Python 3.12+ and uses `uv` for local development:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
uv sync # install runtime deps
|
|
19
|
+
uv sync --dev # install dev deps (pytest, ruff, web extra)
|
|
20
|
+
uv run agent-bus # run MCP server over stdio
|
|
21
|
+
uv sync --extra web # install Web UI deps
|
|
22
|
+
uv run agent-bus serve # run Web UI (default http://127.0.0.1:8080)
|
|
23
|
+
uv run ruff format # format
|
|
24
|
+
uv run ruff check # lint
|
|
25
|
+
uv run pytest # tests
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Coding Style & Naming Conventions
|
|
29
|
+
|
|
30
|
+
- Format/lint with Ruff (`ruff format`, `ruff check`). Line length is 100.
|
|
31
|
+
- Prefer type hints and small, focused modules.
|
|
32
|
+
- Naming: `snake_case` (functions/vars), `PascalCase` (types), `SCREAMING_SNAKE_CASE` (constants).
|
|
33
|
+
|
|
34
|
+
## Testing Guidelines
|
|
35
|
+
|
|
36
|
+
- Framework: pytest (some tests use `anyio` to exercise the stdio MCP server).
|
|
37
|
+
- Keep tests hermetic: use `tmp_path` and point `AGENT_BUS_DB` at a temp SQLite file.
|
|
38
|
+
- Name tests `tests/test_*.py` and prefer unit tests for `AgentBusDB` plus a small number of end-to-end smoke tests.
|
|
39
|
+
|
|
40
|
+
## Commit & Pull Request Guidelines
|
|
41
|
+
|
|
42
|
+
Commit history uses lightweight Conventional-ish prefixes (e.g. `feat(web): ...`, `fix(web): ...`, `docs: ...`, `chore: ...`) and component prefixes like `web: ...` / `peer: ...` / `cli: ...`. Follow one of those patterns.
|
|
43
|
+
|
|
44
|
+
PRs should include: a short description, how to test, and screenshots for Web UI changes. Run `uv run ruff check` and `uv run pytest` before requesting review.
|
|
45
|
+
|
|
46
|
+
## Security & Configuration Tips
|
|
47
|
+
|
|
48
|
+
- Web UI has no auth; keep it bound to localhost unless you add protections.
|
|
49
|
+
- DB schema is versioned; a mismatch requires wiping the DB (see `agent-bus cli db wipe --yes`).
|
|
50
|
+
- Key env vars: `AGENT_BUS_DB`, `AGENT_BUS_MAX_*`, `AGENT_BUS_POLL_*`.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
Agent Bus is a local SQLite-backed MCP (Model Context Protocol) server for peer-to-peer agent communication. It enables multiple AI agents to communicate through a shared message bus with delta-based sync via server-side cursors.
|
|
8
|
+
|
|
9
|
+
## Common Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install dependencies
|
|
13
|
+
uv sync # Core dependencies only
|
|
14
|
+
uv sync --dev # With dev dependencies (pytest, ruff)
|
|
15
|
+
uv sync --extra web # With web UI dependencies
|
|
16
|
+
|
|
17
|
+
# Run the MCP server (stdio transport)
|
|
18
|
+
uv run agent-bus
|
|
19
|
+
|
|
20
|
+
# Run the web UI
|
|
21
|
+
uv run agent-bus serve
|
|
22
|
+
|
|
23
|
+
# Linting and formatting
|
|
24
|
+
uv run ruff format
|
|
25
|
+
uv run ruff check
|
|
26
|
+
|
|
27
|
+
# Run all tests
|
|
28
|
+
uv run pytest
|
|
29
|
+
|
|
30
|
+
# Run a single test file
|
|
31
|
+
uv run pytest tests/test_db.py
|
|
32
|
+
|
|
33
|
+
# Run a specific test
|
|
34
|
+
uv run pytest tests/test_db.py::test_topic_create_reuse_newest_open
|
|
35
|
+
|
|
36
|
+
# CLI administrative commands
|
|
37
|
+
uv run agent-bus cli topics list --status all
|
|
38
|
+
uv run agent-bus cli topics watch <topic_id> --follow
|
|
39
|
+
uv run agent-bus cli db wipe --yes
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Architecture
|
|
43
|
+
|
|
44
|
+
### Core Components
|
|
45
|
+
|
|
46
|
+
- **`agent_bus/peer_server.py`**: MCP server implementation using FastMCP. Defines all MCP tools (`ping`, `topic_create`, `topic_join`, `sync`, etc.). The `sync()` tool is the primary read/write interface with delta-based polling and server-side cursors.
|
|
47
|
+
|
|
48
|
+
- **`agent_bus/db.py`**: SQLite database layer (`AgentBusDB` class). Handles all persistence: topics, messages, cursors, and sequences. Uses WAL mode for concurrent access. Key method is `sync_once()` which handles message sending and receiving in a single transaction.
|
|
49
|
+
|
|
50
|
+
- **`agent_bus/models.py`**: Frozen dataclasses for `Topic`, `Message`, and `Cursor`.
|
|
51
|
+
|
|
52
|
+
- **`agent_bus/common.py`**: Shared utilities including `tool_ok()`/`tool_error()` for MCP response formatting, error codes, and environment variable helpers.
|
|
53
|
+
|
|
54
|
+
- **`agent_bus/cli.py`**: Click-based CLI for administrative operations (list topics, watch messages, export, delete).
|
|
55
|
+
|
|
56
|
+
- **`agent_bus/entrypoint.py`**: Main entry point. Runs MCP server by default; `serve` subcommand starts web UI; `cli` subcommand runs admin commands.
|
|
57
|
+
|
|
58
|
+
- **`agent_bus/web/server.py`**: Optional FastAPI web server with HTMX-powered UI for browsing topics and messages.
|
|
59
|
+
|
|
60
|
+
### Key Patterns
|
|
61
|
+
|
|
62
|
+
- **Server-side cursors**: Each agent has a cursor per topic tracking `last_seq`. The `sync()` tool advances this cursor, enabling delta-based message retrieval without re-fetching history.
|
|
63
|
+
|
|
64
|
+
- **Idempotent sends**: Use `client_message_id` to make message sends idempotent for retry safety.
|
|
65
|
+
|
|
66
|
+
- **Per-session join**: Agents must call `topic_join()` before `sync()`. Join state is in-memory (`_joined_agent_names` dict in peer_server.py).
|
|
67
|
+
|
|
68
|
+
- **Presence tracking**: Derived from cursor `updated_at` timestamps - calling `sync()` updates presence.
|
|
69
|
+
|
|
70
|
+
### Database Schema (v6)
|
|
71
|
+
|
|
72
|
+
Tables: `meta`, `topics`, `topic_seq`, `messages`, `cursors`
|
|
73
|
+
|
|
74
|
+
- Topics can be "open" or "closed"
|
|
75
|
+
- Messages have sequential `seq` numbers per topic
|
|
76
|
+
- Cursors track `(topic_id, agent_name, last_seq)`
|
|
77
|
+
|
|
78
|
+
### Environment Variables
|
|
79
|
+
|
|
80
|
+
- `AGENT_BUS_DB`: SQLite path (default: `~/.agent_bus/agent_bus.sqlite`)
|
|
81
|
+
- `AGENT_BUS_MAX_SYNC_ITEMS`: Max messages per sync (default: 20)
|
|
82
|
+
- `AGENT_BUS_MAX_MESSAGE_CHARS`: Max message length (default: 65536)
|