Skip to content

Commit a9bc7e3

Browse files
droidnoobclaude
andcommitted
build,ci: rename PyPI dist to murmur-runtime, scope js-client to @Murmur, scope release to PyPI only
PyPI rejected ``murmur-ai`` as too similar to existing projects (``murmur`` the hash library, ``murmurai`` the transcription API). Rename: - PyPI distribution: ``murmur-ai`` → ``murmur-runtime``. The Python import name stays ``murmur`` (distribution name and import name are independent); only ``pip install`` changes. - npm scope: ``@murmur-ai`` → ``@murmur`` (the package becomes ``@murmur/client``). Aligns the brand on npm without depending on PyPI's exact name. Sweep every reference in README, docs, CLAUDE.md, examples, RELEASING, and the JS client package metadata. The repo (``droidnoob/murmur-ai``) and the Pages URL (``droidnoob.github.io/murmur-ai/``) keep their existing names — they're tied to the GitHub repo, not the package. Trim ``release.yml`` to publish only ``murmur-runtime`` on the first release. ``murmur-client`` (PyPI) and ``@murmur/client`` (npm) need their pending-publisher / npm-token + scope set up before the workflow can publish them; add those jobs back once that's in place. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c80a673 commit a9bc7e3

51 files changed

Lines changed: 186 additions & 240 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 15 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
name: release
22

33
# Tag-triggered release. Push ``vX.Y.Z`` and this workflow:
4-
# 1. Builds + publishes ``murmur-ai`` and ``murmur-client`` to PyPI
5-
# (Trusted Publishing via OIDC — no tokens).
6-
# 2. Builds + publishes ``@murmur-ai/client`` to npm (uses NPM_TOKEN).
7-
# 3. Creates a GitHub Release with auto-generated notes from commits
4+
# 1. Builds + publishes ``murmur-runtime`` to PyPI (Trusted Publishing
5+
# via OIDC — no tokens).
6+
# 2. Creates a GitHub Release with auto-generated notes from commits
87
# since the previous tag.
98
#
10-
# All three packages must already report the same ``X.Y.Z`` as the tag —
11-
# the verification step below fails fast otherwise so you don't ship a
12-
# version mismatch.
9+
# ``murmur-client`` (PyPI) and ``@murmur/client`` (npm) ship from this
10+
# repo too, but are not yet wired into the release pipeline. Add their
11+
# build + publish steps once their first publish is unblocked
12+
# (PyPI pending publisher entry / npm token + scope).
1313

1414
on:
1515
push:
@@ -27,7 +27,7 @@ concurrency:
2727
jobs:
2828
# --------------------------------------------------------------- verify
2929
# Fail fast if the tag and the in-tree versions disagree. Cheaper to
30-
# catch here than mid-publish.
30+
# catch here than mid-publish. Only checks files we publish from.
3131
verify:
3232
runs-on: ubuntu-latest
3333
outputs:
@@ -44,20 +44,11 @@ jobs:
4444
echo "version=${version}" >> "$GITHUB_OUTPUT"
4545
echo "Tag → ${tag}, version → ${version}"
4646
47-
- name: Verify pyproject.toml versions match
47+
- name: Verify pyproject.toml version matches
4848
run: |
4949
v="${{ steps.parse.outputs.version }}"
50-
for f in pyproject.toml packages/murmur-client/pyproject.toml; do
51-
grep -E "^version = \"${v}\"" "$f" \
52-
|| { echo "::error::${f} does not declare version ${v}"; exit 1; }
53-
done
54-
55-
- name: Verify package.json version matches
56-
run: |
57-
v="${{ steps.parse.outputs.version }}"
58-
jq -e --arg v "$v" '.version == $v' \
59-
packages/js-client/package.json \
60-
|| { echo "::error::js-client/package.json does not declare ${v}"; exit 1; }
50+
grep -E "^version = \"${v}\"" pyproject.toml \
51+
|| { echo "::error::pyproject.toml does not declare version ${v}"; exit 1; }
6152
6253
- name: Verify __version__ matches
6354
run: |
@@ -77,60 +68,15 @@ jobs:
7768
with:
7869
enable-cache: true
7970

80-
- name: Build murmur-ai
81-
run: uv build --out-dir dist-murmur-ai
71+
- name: Build murmur-runtime
72+
run: uv build --out-dir dist
8273

83-
- name: Build murmur-client
84-
run: uv build --out-dir dist-murmur-client packages/murmur-client
85-
86-
- name: Publish murmur-ai
74+
- name: Publish murmur-runtime
8775
uses: pypa/gh-action-pypi-publish@release/v1
88-
with:
89-
packages-dir: dist-murmur-ai
90-
91-
- name: Publish murmur-client
92-
uses: pypa/gh-action-pypi-publish@release/v1
93-
with:
94-
packages-dir: dist-murmur-client
95-
96-
# ----------------------------------------------------------------- npm
97-
npm:
98-
needs: verify
99-
runs-on: ubuntu-latest
100-
defaults:
101-
run:
102-
working-directory: packages/js-client
103-
steps:
104-
- uses: actions/checkout@v4
105-
106-
- uses: actions/setup-node@v4
107-
with:
108-
node-version: '20'
109-
registry-url: 'https://registry.npmjs.org'
110-
111-
- name: Install
112-
run: npm ci || npm install
113-
114-
- name: Typecheck
115-
run: npm run typecheck
116-
117-
- name: Test
118-
run: npm test
119-
120-
- name: Build
121-
run: npm run build
122-
123-
- name: Publish
124-
# ``--access public`` is required for the first publish of a
125-
# scoped package (``@murmur-ai/...``) — scoped packages default
126-
# to private otherwise. Idempotent on subsequent publishes.
127-
run: npm publish --access public --provenance
128-
env:
129-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
13076

13177
# -------------------------------------------------------- github release
13278
github-release:
133-
needs: [pypi, npm]
79+
needs: pypi
13480
runs-on: ubuntu-latest
13581
steps:
13682
- uses: actions/checkout@v4

AGENTS.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ It is **not** a framework for defining agent behavior. It is **infrastructure**
1414

1515
PydanticAI handles single-agent execution (LLM calls, tools, structured output, validation). FastStream handles broker-backed distribution. Murmur owns the orchestration layer between them — and **hides both behind its own public API.**
1616

17-
Repository: `murmur-ai` · PyPI distribution: `murmur-ai` · Import package: `murmur`.
17+
Repository: `murmur-runtime` · PyPI distribution: `murmur-runtime` · Import package: `murmur`.
1818

1919
---
2020

@@ -443,14 +443,14 @@ structlog ← logging
443443
### Broker extras
444444

445445
```
446-
murmur-ai[kafka] → faststream[kafka]
447-
murmur-ai[nats] → faststream[nats]
448-
murmur-ai[rabbitmq] → faststream[rabbit]
449-
murmur-ai[redis] → faststream[redis]
450-
murmur-ai[all] → all brokers
446+
murmur-runtime[kafka] → faststream[kafka]
447+
murmur-runtime[nats] → faststream[nats]
448+
murmur-runtime[rabbitmq] → faststream[rabbit]
449+
murmur-runtime[redis] → faststream[redis]
450+
murmur-runtime[all] → all brokers
451451
```
452452

453-
ThreadBackend has no broker dep — `pip install murmur-ai` works out of the box.
453+
ThreadBackend has no broker dep — `pip install murmur-runtime` works out of the box.
454454

455455
---
456456

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ shipped yet (`0.0.0` placeholder). Highlights since project inception:
108108

109109
### Added — packaging
110110

111-
- Workspace layout: `murmur-ai` (this) + `murmur-client` (separate wheel).
111+
- Workspace layout: `murmur-runtime` (this) + `murmur-client` (separate wheel).
112112
- Optional extras: `[kafka]`, `[nats]`, `[rabbitmq]`, `[redis]`, `[all]`,
113113
`[server]`, `[sqlite]`, `[rocksdb]`, `[redis-runstore]`, `[container]`,
114114
`[docs]`.
@@ -121,4 +121,4 @@ shipped yet (`0.0.0` placeholder). Highlights since project inception:
121121
- GitHub Pages workflow at `.github/workflows/docs.yml` using
122122
`actions/upload-pages-artifact@v3` + `actions/deploy-pages@v4`.
123123

124-
[Unreleased]: https://github.com/murmur-ai/murmur/commits/main
124+
[Unreleased]: https://github.com/murmur-runtime/murmur/commits/main

CLAUDE.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ It is **not** a framework for defining agent behavior. It is **infrastructure**
1414

1515
PydanticAI handles single-agent execution (LLM calls, tools, structured output, validation). FastStream handles broker-backed distribution. Murmur owns the orchestration layer between them — and **hides both behind its own public API.**
1616

17-
Repository: `murmur-ai` · PyPI distribution: `murmur-ai` · Import package: `murmur`.
17+
Repository: `murmur-runtime` · PyPI distribution: `murmur-runtime` · Import package: `murmur`.
1818

1919
---
2020

@@ -443,14 +443,14 @@ structlog ← logging
443443
### Broker extras
444444

445445
```
446-
murmur-ai[kafka] → faststream[kafka]
447-
murmur-ai[nats] → faststream[nats]
448-
murmur-ai[rabbitmq] → faststream[rabbit]
449-
murmur-ai[redis] → faststream[redis]
450-
murmur-ai[all] → all brokers
446+
murmur-runtime[kafka] → faststream[kafka]
447+
murmur-runtime[nats] → faststream[nats]
448+
murmur-runtime[rabbitmq] → faststream[rabbit]
449+
murmur-runtime[redis] → faststream[redis]
450+
murmur-runtime[all] → all brokers
451451
```
452452

453-
ThreadBackend has no broker dep — `pip install murmur-ai` works out of the box.
453+
ThreadBackend has no broker dep — `pip install murmur-runtime` works out of the box.
454454

455455
---
456456

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ opening a PR.
1212
## Local setup
1313

1414
```bash
15-
git clone https://github.com/murmur-ai/murmur && cd murmur
15+
git clone https://github.com/murmur-runtime/murmur && cd murmur
1616
uv sync --group dev # core deps + dev tools
1717
uv run pre-commit install # one-time per clone
1818
uv run pytest -m "not integration" -q # 556 unit tests

README.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
[![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue)](https://www.python.org/downloads/)
1010
[![pydantic-ai](https://img.shields.io/badge/pydantic--ai-1.87-purple)](https://ai.pydantic.dev/)
1111
[![FastStream](https://img.shields.io/badge/faststream-0.6-orange)](https://faststream.ag2.ai/latest/)
12-
[![PyPI](https://img.shields.io/badge/pypi-murmur--ai-blueviolet)](https://pypi.org/project/murmur-ai/)
12+
[![PyPI](https://img.shields.io/badge/pypi-murmur--ai-blueviolet)](https://pypi.org/project/murmur-runtime/)
1313
[![Docs](https://img.shields.io/badge/docs-droidnoob.github.io-blue)](https://droidnoob.github.io/murmur-ai/)
1414
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
1515

@@ -45,7 +45,7 @@ The same code runs locally on `asyncio` or distributed across a worker fleet on
4545

4646
- **Observable by default.** Every spawn, completion, tool call, group start/end, worker lifecycle, and budget hit emits a typed `RuntimeEvent`. Composable emitters: `LogEventEmitter` (structlog), `SSEEventEmitter` (HTTP streaming), `MultiEventEmitter` (fan-out), `BrokerEventBridge` (worker → publisher relay). Every event carries `agent_name`, `task_id`, `trace_id`, `parent_trace_id`, `timestamp`.
4747

48-
- **OpenTelemetry metrics export.** Drop-in `OTelMetricsEmitter` records `gen_ai.client.token.usage` and `gen_ai.client.operation.duration` histograms per the OTel GenAI semantic conventions, plus Murmur's own tool-call and rejection counters. Cardinality-safe attributes; your `MeterProvider` decides where the data lands (Datadog, Grafana, Logfire, Phoenix). Opt-in via `murmur-ai[otel]`.
48+
- **OpenTelemetry metrics export.** Drop-in `OTelMetricsEmitter` records `gen_ai.client.token.usage` and `gen_ai.client.operation.duration` histograms per the OTel GenAI semantic conventions, plus Murmur's own tool-call and rejection counters. Cardinality-safe attributes; your `MeterProvider` decides where the data lands (Datadog, Grafana, Logfire, Phoenix). Opt-in via `murmur-runtime[otel]`.
4949

5050
- **Cost-aware orchestration.** `TokenBudget` enforces per-task and per-runtime token ceilings with pre-check + post-charge semantics. Budgets propagate through cascading spawns; over-budget runs raise the typed `BudgetExceededError`. Best-effort USD costs computed from per-model rate cards.
5151

@@ -95,33 +95,33 @@ Null → Full → Summary → Selective (Summary / Selective planned)
9595
## Install
9696

9797
```bash
98-
pip install murmur-ai # AsyncBackend, no broker — works immediately
98+
pip install murmur-runtime # AsyncBackend, no broker — works immediately
9999
```
100100

101101
Or with [`uv`](https://github.com/astral-sh/uv):
102102

103103
```bash
104-
uv add murmur-ai
104+
uv add murmur-runtime
105105
```
106106

107107
Optional extras:
108108

109109
| Extra | Pulls in | When |
110110
|---|---|---|
111-
| `murmur-ai[redis]` | `faststream[redis]` | Redis Streams broker |
112-
| `murmur-ai[kafka]` | `faststream[kafka]` | Kafka broker |
113-
| `murmur-ai[nats]` | `faststream[nats]` | NATS broker |
114-
| `murmur-ai[rabbitmq]` | `faststream[rabbit]` | RabbitMQ broker |
115-
| `murmur-ai[all-brokers]` | All four brokers | Multi-broker fleet |
116-
| `murmur-ai[server]` | `fastapi`, `uvicorn`, `sse-starlette` | `murmur serve` HTTP API |
117-
| `murmur-ai[otel]` | `opentelemetry-api`, `opentelemetry-sdk` | OTel metrics export |
118-
| `murmur-ai[mcp-server]` | `mcp` | Expose as an MCP server |
119-
| `murmur-ai[sqlite]` | `aiosqlite` | Persistent `RunStore` / `EventStore` |
120-
| `murmur-ai[redis-runstore]` | `redis` | Cluster-wide `RunStore` |
121-
| `murmur-ai[rocksdb]` | `rocksdict` | High-throughput single-host store |
122-
| `murmur-ai[uvloop]` | `uvloop` | Faster async event loop (POSIX only) |
123-
| `murmur-ai[reload]` | `watchfiles` | `--reload` for serve / worker |
124-
| `murmur-ai[all]` | Every optional extra | Kitchen-sink install |
111+
| `murmur-runtime[redis]` | `faststream[redis]` | Redis Streams broker |
112+
| `murmur-runtime[kafka]` | `faststream[kafka]` | Kafka broker |
113+
| `murmur-runtime[nats]` | `faststream[nats]` | NATS broker |
114+
| `murmur-runtime[rabbitmq]` | `faststream[rabbit]` | RabbitMQ broker |
115+
| `murmur-runtime[all-brokers]` | All four brokers | Multi-broker fleet |
116+
| `murmur-runtime[server]` | `fastapi`, `uvicorn`, `sse-starlette` | `murmur serve` HTTP API |
117+
| `murmur-runtime[otel]` | `opentelemetry-api`, `opentelemetry-sdk` | OTel metrics export |
118+
| `murmur-runtime[mcp-server]` | `mcp` | Expose as an MCP server |
119+
| `murmur-runtime[sqlite]` | `aiosqlite` | Persistent `RunStore` / `EventStore` |
120+
| `murmur-runtime[redis-runstore]` | `redis` | Cluster-wide `RunStore` |
121+
| `murmur-runtime[rocksdb]` | `rocksdict` | High-throughput single-host store |
122+
| `murmur-runtime[uvloop]` | `uvloop` | Faster async event loop (POSIX only) |
123+
| `murmur-runtime[reload]` | `watchfiles` | `--reload` for serve / worker |
124+
| `murmur-runtime[all]` | Every optional extra | Kitchen-sink install |
125125

126126
## Example
127127

@@ -329,7 +329,7 @@ docs/ # mkdocs site (concepts, guides, API ref)
329329
tests/
330330
```
331331

332-
PyPI distribution: `murmur-ai`. Import: `murmur` (`pip install murmur-ai``import murmur`).
332+
PyPI distribution: `murmur-runtime`. Import: `murmur` (`pip install murmur-runtime``import murmur`).
333333

334334
The dependency arrow points inward to `core/` and `types.py`. Only `murmur.interop` may import `pydantic_ai` or `faststream`.
335335

RELEASING.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Releases ship three artifacts off one git tag:
44

55
| Artifact | Registry |
66
|---|---|
7-
| `murmur-ai` | [PyPI](https://pypi.org/project/murmur-ai/) |
7+
| `murmur-runtime` | [PyPI](https://pypi.org/project/murmur-runtime/) |
88
| `murmur-client` | [PyPI](https://pypi.org/project/murmur-client/) |
9-
| `@murmur-ai/client` | [npm](https://www.npmjs.com/package/@murmur-ai/client) |
9+
| `@murmur/client` | [npm](https://www.npmjs.com/package/@murmur/client) |
1010

1111
The whole pipeline runs from `.github/workflows/release.yml` on a `v*` tag push.
1212

@@ -21,18 +21,18 @@ Add a Trusted Publisher entry on PyPI for each project. PyPI
2121
verifies the GitHub OIDC token at publish time — no long-lived
2222
credentials live in the repo.
2323

24-
For both `murmur-ai` and `murmur-client`, register a publisher at:
24+
For both `murmur-runtime` and `murmur-client`, register a publisher at:
2525

26-
- `https://pypi.org/manage/project/murmur-ai/settings/publishing/`
26+
- `https://pypi.org/manage/project/murmur-runtime/settings/publishing/`
2727
- `https://pypi.org/manage/project/murmur-client/settings/publishing/`
2828

2929
Use these values:
3030

3131
| Field | Value |
3232
|---|---|
33-
| PyPI Project Name | `murmur-ai` / `murmur-client` |
33+
| PyPI Project Name | `murmur-runtime` / `murmur-client` |
3434
| Owner | `droidnoob` |
35-
| Repository name | `murmur-ai` |
35+
| Repository name | `murmur-runtime` |
3636
| Workflow name | `release.yml` |
3737
| Environment name | `pypi` |
3838

@@ -62,7 +62,7 @@ trusted publishing).
6262
- Value: the token
6363

6464
The first publish needs `--access public` (the workflow passes it
65-
automatically; required because `@murmur-ai/...` is a scoped package
65+
automatically; required because `@murmur/...` is a scoped package
6666
and scoped packages default to private).
6767

6868
## Cutting a release
@@ -93,10 +93,10 @@ mismatched release.
9393
After the tag push, the workflow:
9494

9595
1. **`verify`** — confirms tag and in-tree versions agree.
96-
2. **`pypi`** — builds + publishes `murmur-ai` and `murmur-client`
96+
2. **`pypi`** — builds + publishes `murmur-runtime` and `murmur-client`
9797
(Trusted Publishing OIDC).
9898
3. **`npm`** — typechecks, tests, builds, publishes
99-
`@murmur-ai/client` with provenance.
99+
`@murmur/client` with provenance.
100100
4. **`github-release`** — creates a GitHub Release with auto-generated
101101
notes pulled from commit subjects since the previous tag.
102102

0 commit comments

Comments
 (0)