Package Management: uv (mandatory)
- All Python projects use
uvfor dependency management - Commands:
uv sync,uv run,uv add <pkg> - Build backend:
uv_buildorhatchlingwithuv-dynamic-versioning
Type Annotations: Strict (mandatory)
- All code must be fully typed
- Pyright in
strictmode is the standard - Ruff
ANNrules enforce annotation completeness - Avoid
# type: ignore- fix the types or use proper stubs
Linting: Ruff
- Line length: 100-120 characters
- Auto-fix with:
uv run ruff check --fix - Format with:
uv run ruff format - Strict rule selection - see individual
pyproject.tomlfor project-specific ignores
Testing: pytest
- Default: automated e2e functional tests for new code
- Unit tests for complex logic
- Integration tests marked with
@pytest.mark.integration - Async tests:
@pytest.mark.asyncio - Fixtures for state setup (prefer fixtures over manual setup in tests)
Project Verification
- Run
uv run pytestbefore finalizing changes - Some projects have
just allormake testfor full verification
Imports
- Unconditional imports at top of files
- Sort with
isortvia Ruff (Irules) - Type-checking imports in
TYPE_CHECKINGblock when needed
Error Handling
- Typed result patterns over exceptions where practical
- Pydantic models for data validation at boundaries
- Explicit error types for domain errors
Async
- Prefer async/await for IO-bound operations
- Use
asynciopatterns; avoid threading unless necessary - See "Topics to Revisit" for asyncio/threading edge cases
Activation: Say "learning mode" or "tutorial approach" to enable guided learning.
When active, this collaborative approach applies:
- Learn by doing - Build real features rather than just reading
- Guided exploration - Balance between teaching and discovering
- Incremental complexity - Start simple, build up
- Collaboration over automation - You implement key decisions; I handle boilerplate
- Context provided - Explain what we're building and why
- You make decisions - Choose approaches for meaningful features (2-10 lines of key logic)
- I handle scaffolding - Structure, boilerplate, and routine code
- Insights shared - Patterns, architecture, and how things connect
- Multiple valid approaches exist (error handling, data structures)
- Business logic involves design decisions
- Key algorithms or interface definitions need writing
- The decision teaches an important concept
At session end (or when you say "journal this"), create an entry in ./journal/session-XX.md:
---
## Session [N] - [Date: YYYY-MM-DD]
### Goals
- [ ] Goal 1
- [ ] Goal 2
### What We Covered
- Topic 1: Brief description
- Topic 2: Brief description
### Key Concepts Learned
1. **Concept Name**: Explanation
2. **Concept Name**: Explanation
### What We Built
- Feature/file created
- Code written (file paths and key changes)
### Insights & Aha Moments
- Important realization or pattern discovered
### Challenges & Solutions
- **Challenge**: Description
- **Solution**: How we resolved it
### Next Steps
- [ ] Next task to tackle
### Questions/Blockers
- Unresolved questions for next timeSession Index: ./journal/ directory contains all entries (session-01.md through session-23.md)
Concepts that need deeper exploration:
-
Threading + Asyncio interaction (Session 12)
asyncio.get_event_loop()fails in background threadscall_soon_threadsafe()bridges threads to event loop- Pattern: capture loop reference in main thread, use from background
-
Audio feedback loop prevention (Session 12)
- Mic picks up speaker output, causing echo
- Solution: mute mic during TTS playback
-
VAD tuning (Session 12, 20)
- Current:
stop_secs=1.5, variousmin_volume/confidenceparams - Different environments need different tuning
- Smart Turn Detection (
LocalSmartTurnAnalyzerV3) may help
- Current:
-
Barge-in / interruption handling (Session 14)
- User interrupting AI mid-speech vs echo detection
- Pipecat's
allow_interruptions=Truebehavior unclear
The kx script in v2-runtime/ is the unified CLI for managing Kairix services:
cd v2-runtime
# Service management
./kx up # Start all services
./kx down # Stop all services
./kx restart # Restart all services
./kx status # Show service status
./kx logs [service] # View logs
# Development
./kx dev # Start dependencies only (postgres, redis, letta)
./kx dev:down # Stop dev dependencies
# Database
./kx migrate # Run alembic migrations
./kx psql # Connect to PostgreSQL shell
./kx db:reset # Reset database (destroys data)
# Voice management
./kx voice list # List configured TTS voices
./kx voice add # Add a new voice (interactive)
./kx voice assign # Assign voice to an agent
# KP3 (passage/knowledge management)
./kx kp3 passage search "query"
./kx kp3 passage ls
./kx kp3 sql "SELECT ..."
# Health checks
./kx wait postgres redis # Wait for specific services
./kx wait all # Wait for all servicesUse deploy.sh to deploy changes to remote hosts (e.g., salinas):
cd v2-runtime
./deploy.sh salinas
# or
./kx deploy salinasThe deploy script:
- SSHs to the target host
- Pulls latest from
origin/main - Stops existing services (
kx down) - Rebuilds images (
kx build) - Starts infrastructure (
kx dev) - Waits for postgres to be healthy
- Runs migrations (
kx migrate) - Starts app services (
kx up)
Prerequisites: SSH access configured for the target host, and the repo cloned at ~/kairix/v2-runtime on the remote.
For ad-hoc commands on salinas, SSH and use the REST API or kx CLI:
# REST API
ssh salinas 'curl -s http://localhost:8000/voices | jq'
# kx CLI
ssh salinas 'cd ~/kairix/v2-runtime && ./kx voice list'- Letta SDK: Use official docs at https://docs.letta.com/api (not Context7 - outdated)
- Other libraries: Use Context7 MCP server for current documentation