Skip to content
Open
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
42 changes: 42 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# OpenRTC environment variables
# Copy this file to .env and fill in the values for your setup.
# python-dotenv is used in the examples: `from dotenv import load_dotenv; load_dotenv()`

# ---------------------------------------------------------------------------
# LiveKit connection (required for dev / start / connect / console)
# ---------------------------------------------------------------------------
LIVEKIT_API_KEY=devkey
LIVEKIT_API_SECRET=secret
LIVEKIT_URL=ws://localhost:7880

# ---------------------------------------------------------------------------
# Provider API keys — set only the keys for providers your agents use
# ---------------------------------------------------------------------------

# OpenAI (STT: gpt-4o-mini-transcribe, LLM: gpt-4.1-mini, TTS: gpt-4o-mini-tts)
OPENAI_API_KEY=

# Deepgram (STT: deepgram/nova-3:multi)
DEEPGRAM_API_KEY=

# Cartesia (TTS: cartesia/sonic-3)
CARTESIA_API_KEY=

# ElevenLabs (TTS: elevenlabs/*)
ELEVEN_API_KEY=

# Azure OpenAI (if using azure provider strings)
AZURE_OPENAI_API_KEY=
AZURE_OPENAI_ENDPOINT=

# ---------------------------------------------------------------------------
# Optional: remote end-of-turn model (LiveKit Cloud)
# Set this to enable multilingual remote turn detection via LIVEKIT_REMOTE_EOT_URL
# ---------------------------------------------------------------------------
LIVEKIT_REMOTE_EOT_URL=

# ---------------------------------------------------------------------------
# Logging level passed through to the LiveKit worker
# One of: DEBUG, INFO, WARNING, ERROR
# ---------------------------------------------------------------------------
LIVEKIT_LOG_LEVEL=INFO
83 changes: 83 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Bug report
description: Report a reproducible bug in OpenRTC
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug. Please fill in as much detail as possible so we can reproduce and fix it quickly.

- type: input
id: version
attributes:
label: OpenRTC version
description: Output of `python -c "import openrtc; print(openrtc.__version__)"`
placeholder: "e.g. 0.0.15"
validations:
required: true

- type: input
id: python-version
attributes:
label: Python version
description: Output of `python --version`
placeholder: "e.g. 3.12.2"
validations:
required: true

- type: input
id: livekit-agents-version
attributes:
label: livekit-agents version
description: Output of `python -c "import livekit.agents; print(livekit.agents.__version__)"`
placeholder: "e.g. 1.4.3"
validations:
required: false

- type: textarea
id: description
attributes:
label: Description
description: A clear and concise description of what the bug is.
validations:
required: true

- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Minimal steps to reproduce the issue.
placeholder: |
1. Create a pool with `AgentPool(...)`
2. Call `pool.add(...)`
3. Start with `pool.run()`
4. See error
validations:
required: true

- type: textarea
id: expected
attributes:
label: Expected behaviour
description: What did you expect to happen?
validations:
required: true

- type: textarea
id: actual
attributes:
label: Actual behaviour
description: What actually happened? Include the full traceback if applicable.
render: python
validations:
required: true

- type: textarea
id: extra
attributes:
label: Additional context
description: |
Any other context, environment details, or screenshots that may help.
For example: OS, deployment environment (Docker, bare metal, cloud), provider plugins in use.
validations:
required: false
58 changes: 58 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Feature request
description: Propose an improvement or new capability for OpenRTC
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for suggesting an improvement! Please describe the problem you're solving and the solution you have in mind.

- type: textarea
id: problem
attributes:
label: Problem statement
description: |
What problem are you trying to solve? Describe the use case that is not well-served today.
placeholder: "I'm trying to do X, but OpenRTC currently doesn't support it because..."
validations:
required: true

- type: textarea
id: proposed-solution
attributes:
label: Proposed solution
description: |
Describe the feature or change you'd like. Include example code if helpful.
placeholder: |
Add a `pool.add_async()` method that accepts an async factory so providers
can be lazily initialised on first call.
validations:
required: true

- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: |
Are there workarounds you've already tried? Why aren't they sufficient?
validations:
required: false

- type: dropdown
id: breaking
attributes:
label: Does this require a breaking API change?
options:
- "No — purely additive"
- "Yes — existing callers would need to update"
- "Not sure"
validations:
required: true

- type: textarea
id: extra
attributes:
label: Additional context
description: Links, prior art, related issues, or any other context.
validations:
required: false
19 changes: 9 additions & 10 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,21 @@ jobs:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
- name: Set up uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
python-version: "3.11"

- name: Install lint dependencies
run: |
python -m pip install --upgrade pip
python -m pip install ruff "mypy>=1.19.1"
python -m pip install -e ".[cli,tui]"
- name: Install dependencies
run: uv sync --group dev

- name: Check formatting
run: ruff format --check .
run: uv run ruff format --check .

- name: Run lint checks
run: ruff check .
run: uv run ruff check .

- name: Run mypy
run: mypy src/
run: uv run mypy src/
72 changes: 62 additions & 10 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,79 @@ jobs:
contents: write

steps:
- name: Checkout code
- name: Checkout main
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
# Use a PAT so the changelog commit can trigger deploy-docs.yml.
# Falls back to GITHUB_TOKEN if the secret is absent (docs won't
# auto-deploy in that case, but the publish still succeeds).
token: ${{ secrets.CHANGELOG_PUSH_TOKEN || secrets.GITHUB_TOKEN }}

- name: Set up Python
uses: actions/setup-python@v5
- name: Set up uv
uses: astral-sh/setup-uv@v6
with:
python-version: "3.12"

- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build

- name: Build package
run: |
python -m build
run: uv build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
packages-dir: dist/

- name: Update docs/changelog.md
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
RELEASE_BODY: ${{ github.event.release.body }}
RELEASE_DATE: ${{ github.event.release.published_at }}
run: |
python3 - <<'PYEOF'
import os

raw_tag = os.environ["RELEASE_TAG"]
# Strip leading 'v' to keep headings like "## [0.0.16]" consistent
tag = raw_tag.lstrip("v")
body = os.environ["RELEASE_BODY"].strip()
# published_at is ISO-8601; keep only the date part
date = os.environ["RELEASE_DATE"][:10]

new_section = f"## [{tag}] - {date}\n\n{body}\n\n---\n\n"

path = "docs/changelog.md"
with open(path) as f:
content = f.read()

marker = "<!-- releases -->"
if marker not in content:
raise SystemExit(f"Marker '{marker}' not found in {path}")

# Skip if this release was already recorded (idempotent re-runs)
if f"## [{tag}]" in content:
print(f"Section for {tag} already present in {path}; skipping.")
else:
# Insert the new release section right after the marker line.
# Match "marker\n\n" so the replacement keeps exactly two newlines
# between the marker and the new (and subsequent) sections.
content = content.replace(
marker + "\n\n",
marker + "\n\n" + new_section,
1,
)

with open(path, "w") as f:
f.write(content)

print(f"Prepended {tag} ({date}) to {path}")
PYEOF

- name: Commit and push changelog
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add docs/changelog.md
git commit -m "docs(changelog): add ${{ github.event.release.tag_name }} release notes [skip ci]"
git push origin HEAD:main
12 changes: 6 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ jobs:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
- name: Set up uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[cli,tui]" pytest pytest-asyncio pytest-cov
run: uv sync --group dev

- name: Run tests with coverage
run: pytest --cov=openrtc --cov-report=xml --cov-fail-under=80
run: uv run pytest --cov=openrtc --cov-report=xml --cov-fail-under=80

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
Expand Down
40 changes: 40 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# OpenRTC developer convenience targets.
# All commands delegate to `uv run` so they pick up the locked dev environment.
# Run `uv sync --group dev` once to set up the environment, then use these targets.

.PHONY: help install test test-fast lint format format-check typecheck dev clean

help: ## Show this help message
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
| awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-14s\033[0m %s\n", $$1, $$2}'

install: ## Install package and dev dependencies via uv
uv sync --group dev

test: ## Run the test suite with coverage
uv run pytest --cov=openrtc --cov-report=term-missing --cov-fail-under=80

test-fast: ## Run tests without coverage (faster feedback loop)
uv run pytest -q

lint: ## Run Ruff lint checks
uv run ruff check .

format: ## Auto-format code with Ruff
uv run ruff format .

format-check: ## Check formatting without making changes (used in CI)
uv run ruff format --check .

typecheck: ## Run mypy type checks on the source tree
uv run mypy src/

dev: ## Validate agent discovery without a LiveKit server (set --agents-dir as needed)
uv run openrtc list ./examples/agents \
--default-stt "deepgram/nova-3:multi" \
--default-llm "openai/gpt-4.1-mini" \
--default-tts "cartesia/sonic-3"

clean: ## Remove build artefacts and __pycache__ directories
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
rm -rf dist build .coverage coverage.xml htmlcov .mypy_cache .ruff_cache
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export default defineConfig({
{ text: 'AgentPool API', link: '/api/pool' },
{ text: 'CLI', link: '/cli' },
{ text: 'Examples', link: '/examples' },
{ text: 'Changelog', link: '/changelog' },
{ text: 'GitHub Pages Deployment', link: '/deployment/github-pages' },
],
},
Expand Down
Loading
Loading