feat: Local-First TensorZero Gateway & AgentGym Integration - #347
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
WalkthroughThis PR introduces a comprehensive TensorZero gateway integration with tiered model routing, a new AgentGym RL Coordinator service for training/dataset management, and multi-service Docker deployment with ClickHouse observability. Documentation is restructured to reflect local-first architecture with cloud fallbacks and security hardening requirements. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant GW as TensorZero Gateway
participant Ollama as Ollama (Local)
participant CF as CloudFlare Workers
participant Gemini as Google Gemini
participant Claude as Anthropic Claude
participant GPT as OpenAI GPT
User->>GW: chat request (weight distribution)
rect rgb(200, 220, 255)
Note over GW,Ollama: Tier 1: Local/Free (weight: 1.0)
GW->>Ollama: attempt local inference
alt Success
Ollama-->>GW: response
GW-->>User: response (local)
else Ollama unavailable
Note over GW: fallback triggered
end
end
rect rgb(200, 240, 200)
Note over GW,CF: Tier 1b: Free Cloud (weight: 0.5)
GW->>CF: attempt CloudFlare llama
alt Success
CF-->>GW: response
GW-->>User: response (cloudflare)
else CF unavailable
Note over GW: fallback triggered
end
end
rect rgb(255, 240, 200)
Note over GW,Gemini: Tier 2: Free Plans (weight: 0.4)
GW->>Gemini: attempt Gemini
alt Success
Gemini-->>GW: response
GW-->>User: response (gemini)
else Gemini unavailable
Note over GW: fallback triggered
end
end
rect rgb(255, 220, 200)
Note over GW,Claude: Tier 3: Cloud Premium (weight: 0.3)
GW->>Claude: attempt Claude
alt Success
Claude-->>GW: response
GW-->>User: response (claude)
else Claude unavailable
Note over GW: final fallback
end
end
GW->>GPT: attempt GPT-4o (weight: 0.1)
GPT-->>GW: response
GW-->>User: response (gpt-4o)
sequenceDiagram
actor User
participant API as AgentGym API
participant NATS as NATS Bus
participant HF as HuggingFace Hub
participant Cache as HF Cache Volume
User->>API: POST /agentgym/train/start (run_id)
API->>NATS: subscribe geometry.event.v1
Note over NATS: Await training events
NATS-->>API: training events stream
API->>API: log training initiation
API-->>User: {status: training_started}
User->>API: POST /agentgym/dataset/publish (dataset_name)
rect rgb(200, 220, 255)
Note over API: Validate HF_TOKEN
alt HF_TOKEN present
API->>Cache: check local cache
Cache-->>API: cached artifacts (if exists)
API->>HF: publish dataset/model
HF-->>API: publication status
API-->>User: {status: published}
else HF_TOKEN missing
API-->>User: HTTP 500 (token required)
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (4)
pmoves/services/agentgym-rl-coordinator/Dockerfile (1)
15-16: Optional: Optimize COPY to exclude build artifacts.The
COPY . /appstatement copies all files includingrequirements.txt,Dockerfile, and potentially other build artifacts that aren't needed in production. This slightly increases image size.🔎 Proposed optimization
-COPY . /app +COPY app.py /app/ WORKDIR /appAlternatively, add a
.dockerignorefile to exclude unnecessary files:requirements.txt Dockerfile docker-compose.yml *.md .git __pycache__ *.pycfeatures/gateway/docker-compose.yml (1)
21-24: Hardcoded credentials in ClickHouse configuration.The credentials
tensorzero:tensorzeroare hardcoded in the environment variables and healthcheck. While acceptable for local development, these should be parameterized for production deployments.🔎 Proposed improvement
environment: - - CLICKHOUSE_USER=tensorzero - - CLICKHOUSE_PASSWORD=tensorzero + - CLICKHOUSE_USER=${CLICKHOUSE_USER:-tensorzero} + - CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-tensorzero} - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1And update the healthcheck to use environment variable interpolation (note: may require docker-compose v2.x):
healthcheck: - test: [ "CMD-SHELL", "wget --spider http://tensorzero:tensorzero@localhost:8123/ping" ] + test: [ "CMD-SHELL", "wget --spider http://$${CLICKHOUSE_USER}:$${CLICKHOUSE_PASSWORD}@localhost:8123/ping" ]Document in README or deployment guide that production deployments must set unique credentials.
features/gateway/config/tensorzero.toml (1)
112-118: Consider adding cloud fallback variants for embedding function.The
embedfunction only has a local variant (qwen-embedding-local). If the local Ollama service is unavailable, embedding requests will fail. Consider adding cloud fallback options similar to the chat function.🔎 Proposed enhancement
Add cloud embedding models:
+# Cloud embedding models +[models.openai-embedding] +provider = "openai" +model = "text-embedding-3-small" + # Embedding: Local First [functions.embed] type = "embedding" -variants = ["local_embed"] +variants = ["local_embed", "cloud_embed"] [functions.embed.variants.local_embed] model = "models.qwen-embedding-local" +weight = 1.0 + +[functions.embed.variants.cloud_embed] +model = "models.openai-embedding" +weight = 0.3This ensures embedding functionality remains available even when Ollama is down, aligning with the "Local-First" philosophy's resilience goals.
docs/PMOVES_TensorZero_Implementation.md (1)
169-245: Add blank lines around all tables for proper markdown formatting.Markdown tables should be surrounded by blank lines. This is flagged by the linter at multiple locations (lines 169, 177, 185, 195, 207, 219, 230, 241) and can cause rendering issues in various markdown processors.
🔎 Example fix
### 3.1 Core Infrastructure + | Service | Current Status | Integration Strategy | Action Item | | :--- | :--- | :--- | :--- | | `tensorzero-gateway` | **NEW** | **CORE**: The central hub. | Deploy & Secure | ... | `nats` | **EXISTING** | **CORE**: The Geometry Bus carrier. | Ensure `bus_tier` isolation | + ### 3.2 Agent OrchestrationApply to all tables in section 3.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
docs/PMOVES_TensorZero_Implementation.mdfeatures/gateway/config/tensorzero.tomlfeatures/gateway/docker-compose.ymlpmoves/services/agentgym-rl-coordinator/Dockerfilepmoves/services/agentgym-rl-coordinator/app.pypmoves/services/agentgym-rl-coordinator/docker-compose.ymlpmoves/services/agentgym-rl-coordinator/requirements.txt
🧰 Additional context used
📓 Path-based instructions (4)
pmoves/**/docker-compose.yml
📄 CodeRabbit inference engine (pmoves/AGENTS.md)
Use Compose profiles (
data,workers) to scope what runs locally in docker-compose.yml
Files:
pmoves/services/agentgym-rl-coordinator/docker-compose.yml
pmoves/services/**/*.py
📄 CodeRabbit inference engine (pmoves/AGENTS.md)
pmoves/services/**/*.py: Keep modules small and single-purpose; share helpers inservices/common/
FastAPI routes: snake_case function names; path names kebab-case only in URLs
Validate payloads against schemas before publishing events usingservices/common/events.py
Files:
pmoves/services/agentgym-rl-coordinator/app.py
pmoves/**/*.py
📄 CodeRabbit inference engine (pmoves/AGENTS.md)
Python 3.11+, 4-space indentation, prefer type hints
Files:
pmoves/services/agentgym-rl-coordinator/app.py
**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Use Python 3.11+ with 4-space indentation and prefer type hints in all Python code
Files:
pmoves/services/agentgym-rl-coordinator/app.py
🧠 Learnings (10)
📚 Learning: 2025-12-07T11:03:53.415Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: pmoves/AGENTS.md:0-0
Timestamp: 2025-12-07T11:03:53.415Z
Learning: Applies to pmoves/**/environment.yml : Preferred Python: Conda 3.11+ (env name: `PMOVES.AI` or `pmoves-ai`); use `environment.yml` at repo root for setup
Applied to files:
pmoves/services/agentgym-rl-coordinator/requirements.txt
📚 Learning: 2025-12-15T12:02:18.878Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: pmoves/docs/ARTSTUFF/realtime/GEMINI.md:0-0
Timestamp: 2025-12-15T12:02:18.878Z
Learning: Applies to pmoves/docs/ARTSTUFF/realtime/**/*{install,start,update,reset}.{js,json} : Install Python packages using uv instead of pip when possible, for example uv pip install -r requirements.txt instead of pip install
Applied to files:
pmoves/services/agentgym-rl-coordinator/requirements.txt
📚 Learning: 2025-12-07T11:03:53.415Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: pmoves/AGENTS.md:0-0
Timestamp: 2025-12-07T11:03:53.415Z
Learning: Applies to pmoves/services/{agent-zero,archon}/**/*.py : For Agents/Archon full-stack validation, follow the 'All Services Up, Then Tests' section in `pmoves/docs/SMOKETESTS.md` and use `make -C pmoves agents-headless-smoke`, `make -C pmoves smoke-gpu`, and `make -C pmoves verify-all`
Applied to files:
pmoves/services/agentgym-rl-coordinator/requirements.txtpmoves/services/agentgym-rl-coordinator/app.pydocs/PMOVES_TensorZero_Implementation.md
📚 Learning: 2025-12-07T11:03:07.638Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-07T11:03:07.638Z
Learning: Applies to **/pmoves/**/*{qwen,gemma,audio,summary}*.py : Integrate Qwen2-Audio provider and add Gemma summaries to PMOVES.YT endpoints
Applied to files:
pmoves/services/agentgym-rl-coordinator/requirements.txtdocs/PMOVES_TensorZero_Implementation.md
📚 Learning: 2025-12-07T11:03:53.415Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: pmoves/AGENTS.md:0-0
Timestamp: 2025-12-07T11:03:53.415Z
Learning: Applies to pmoves/**/docker-compose.yml : Use Compose profiles (`data`, `workers`) to scope what runs locally in docker-compose.yml
Applied to files:
pmoves/services/agentgym-rl-coordinator/docker-compose.ymlfeatures/gateway/docker-compose.yml
📚 Learning: 2025-12-07T11:03:53.415Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: pmoves/AGENTS.md:0-0
Timestamp: 2025-12-07T11:03:53.415Z
Learning: Applies to pmoves/services/**/*.py : Keep modules small and single-purpose; share helpers in `services/common/`
Applied to files:
pmoves/services/agentgym-rl-coordinator/app.py
📚 Learning: 2025-12-15T12:03:17.291Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-15T12:03:17.291Z
Learning: Mandatory context before changes: read pmoves/docs/PMOVES.AI PLANS/ROADMAP.md and pmoves/docs/NEXT_STEPS.md to align with current sprint focus
Applied to files:
docs/PMOVES_TensorZero_Implementation.md
📚 Learning: 2025-12-07T11:03:53.415Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: pmoves/AGENTS.md:0-0
Timestamp: 2025-12-07T11:03:53.415Z
Learning: Read `pmoves/docs/PMOVES.AI PLANS/ROADMAP.md` and `pmoves/docs/NEXT_STEPS.md` before making changes to align with current sprint focus
Applied to files:
docs/PMOVES_TensorZero_Implementation.md
📚 Learning: 2025-12-15T12:03:17.291Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-15T12:03:17.291Z
Learning: Applies to services/**/README.md : Update services/*/README.md and pmoves/docs/PMOVES.AI PLANS/ runbooks when touching service operational code
Applied to files:
docs/PMOVES_TensorZero_Implementation.md
📚 Learning: 2025-12-15T12:03:17.291Z
Learnt from: CR
Repo: POWERFULMOVES/PMOVES.AI PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-15T12:03:17.291Z
Learning: Agents/Archon: for full-stack validation, follow the 'All Services Up, Then Tests' section in pmoves/docs/SMOKETESTS.md and the Archon service guide
Applied to files:
docs/PMOVES_TensorZero_Implementation.md
🪛 Checkov (3.2.334)
features/gateway/docker-compose.yml
[medium] 41-42: Basic Auth Credentials
(CKV_SECRET_4)
🪛 markdownlint-cli2 (0.18.1)
docs/PMOVES_TensorZero_Implementation.md
169-169: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
177-177: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
179-179: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
180-180: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
181-181: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
182-182: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
185-185: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
187-187: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
188-188: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
189-189: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
190-190: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
191-191: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
192-192: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
195-195: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
197-197: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
198-198: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
199-199: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
200-200: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
201-201: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
202-202: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
203-203: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
204-204: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
207-207: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
209-209: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
210-210: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
211-211: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
212-212: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
213-213: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
214-214: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
215-215: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
216-216: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
219-219: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
221-221: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
222-222: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
223-223: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
224-224: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
225-225: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
226-226: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
227-227: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
230-230: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
232-232: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
233-233: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
234-234: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
235-235: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
236-236: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
237-237: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
238-238: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
241-241: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
243-243: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
244-244: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
245-245: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
🪛 OSV Scanner (2.3.1)
pmoves/services/agentgym-rl-coordinator/requirements.txt
[HIGH] 1-1: fastapi 0.109.0: undefined
(PYSEC-2024-38)
[HIGH] 1-1: python-multipart 0.0.6: python-multipart vulnerable to Content-Type Header ReDoS
[HIGH] 1-1: python-multipart 0.0.6: Denial of service (DoS) via deformation multipart/form-data boundary
[HIGH] 1-1: starlette 0.35.1: Starlette has possible denial-of-service vector when parsing large files in multipart forms
[HIGH] 1-1: starlette 0.35.1: Starlette Denial of service (DoS) via multipart/form-data
🪛 Ruff (0.14.10)
pmoves/services/agentgym-rl-coordinator/app.py
21-21: Unused function argument: app
(ARG001)
38-38: Do not catch blind exception: Exception
(BLE001)
39-39: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: tests (3.11)
- GitHub Check: Analyze (python)
🔇 Additional comments (6)
pmoves/services/agentgym-rl-coordinator/app.py (1)
49-53: LGTM!The health check endpoint provides clear visibility into NATS connectivity and HuggingFace configuration status.
pmoves/services/agentgym-rl-coordinator/Dockerfile (1)
1-25: LGTM! Excellent security posture.The multi-stage build using distroless with a non-root user aligns perfectly with the PR's security hardening objectives. The PATH configuration and HF_HOME setup are appropriate for the service's HuggingFace integration needs.
pmoves/services/agentgym-rl-coordinator/docker-compose.yml (1)
39-43: LGTM! Security hardening properly implemented.The security configuration follows the PR's hardening requirements:
- Non-root distroless user (65532:65532)
- Read-only filesystem with volume-specific write access
- All capabilities dropped
This aligns with the documented Production Hardening Guidelines.
features/gateway/docker-compose.yml (1)
32-44: LGTM! Strong security hardening implementation.Both services properly implement:
- Non-root users (101 for ClickHouse, 65532 for Gateway)
- Capability dropping with minimal re-additions for ClickHouse
- Read-only filesystem for gateway
- Health-based startup ordering
- Network segmentation
The ClickHouse capability additions (SYS_NICE, NET_ADMIN, IPC_LOCK) are justified for database performance and networking.
Also applies to: 72-78
features/gateway/config/tensorzero.toml (1)
83-110: LGTM! Well-structured tiered routing hierarchy.The function routing configuration clearly implements the Local-First philosophy with appropriate weight distribution:
- Local (1.0) → Free (0.5) → Gemini (0.4) → Anthropic (0.3) → OpenAI (0.1)
The decreasing weights properly prioritize cost-effective options while maintaining fallback resilience.
docs/PMOVES_TensorZero_Implementation.md (1)
1-304: Excellent comprehensive documentation.This documentation provides:
- Clear architectural overview of the Local-First routing philosophy
- Detailed configuration guidance with practical examples
- Exhaustive service integration matrix covering 55+ services
- Security hardening requirements aligned with the PR objectives
- HuggingFace training pipeline integration details
The structured approach will significantly help with the migration and deployment process.
| | Service | Integration Strategy | Action Item | | ||
| | :--- | :--- | :--- | | ||
| | `agent-zero` | **MIGRATE** | Point `OPENAI_BASE_URL` to Gateway. Use `tensorzero::model` names. | Update `.env` | | ||
| | `archon` | **MIGRATE** | Same as Agent Zero. Ensure all sub-agents route through Gateway. | Update `.env` | | ||
| | `mesh-agent` | **NETWORK** | Ensure connectivity to Gateway for health checks. | Verify Network | | ||
| | `channel-monitor` | **INTEGRATE** | Publish `content.new.v1` as Geometry Packet. | Add NATS logic | |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Fix table column mismatch in Agent Orchestration section.
The table header defines 3 columns, but the data rows contain 4 columns (the separator row also has only 3 columns). This causes rendering issues and is flagged by the markdown linter.
🔎 Proposed fix
Looking at the table structure, it appears the first column in data rows should be part of the header. The table should have either:
Option 1: Keep 3 columns by removing the first data cell:
### 3.2 Agent Orchestration
| Service | Integration Strategy | Action Item |
| :--- | :--- | :--- |
-| `agent-zero` | **MIGRATE** | Point `OPENAI_BASE_URL` to Gateway. Use `tensorzero::model` names. | Update `.env` |
+| `agent-zero` | **MIGRATE**: Point `OPENAI_BASE_URL` to Gateway. Use `tensorzero::model` names. | Update `.env` |Option 2: Add a 4th column to the header (recommended based on content):
### 3.2 Agent Orchestration
-| Service | Integration Strategy | Action Item |
-| :--- | :--- | :--- |
+| Service | Integration Strategy | Details | Action Item |
+| :--- | :--- | :--- | :--- |Apply the same fix to all tables in sections 3.2 through 3.8 (lines 177-245).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | Service | Integration Strategy | Action Item | | |
| | :--- | :--- | :--- | | |
| | `agent-zero` | **MIGRATE** | Point `OPENAI_BASE_URL` to Gateway. Use `tensorzero::model` names. | Update `.env` | | |
| | `archon` | **MIGRATE** | Same as Agent Zero. Ensure all sub-agents route through Gateway. | Update `.env` | | |
| | `mesh-agent` | **NETWORK** | Ensure connectivity to Gateway for health checks. | Verify Network | | |
| | `channel-monitor` | **INTEGRATE** | Publish `content.new.v1` as Geometry Packet. | Add NATS logic | | |
| | Service | Integration Strategy | Details | Action Item | | |
| | :--- | :--- | :--- | :--- | | |
| | `agent-zero` | **MIGRATE** | Point `OPENAI_BASE_URL` to Gateway. Use `tensorzero::model` names. | Update `.env` | | |
| | `archon` | **MIGRATE** | Same as Agent Zero. Ensure all sub-agents route through Gateway. | Update `.env` | | |
| | `mesh-agent` | **NETWORK** | Ensure connectivity to Gateway for health checks. | Verify Network | | |
| | `channel-monitor` | **INTEGRATE** | Publish `content.new.v1` as Geometry Packet. | Add NATS logic | |
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
177-177: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
179-179: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
180-180: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
181-181: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
182-182: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing
(MD056, table-column-count)
🤖 Prompt for AI Agents
In docs/PMOVES_TensorZero_Implementation.md around lines 177 to 182 (and apply
across sections 3.2–3.8, lines ~177–245): the markdown tables declare 3 header
columns but the data rows contain 4 cells, causing lint/render errors; fix by
adding a 4th header column and updating the separator row so every table has the
same number of pipes (or alternatively remove the extra data cell), then update
all corresponding tables in sections 3.2–3.8 so header, separator, and data rows
have matching column counts.
| [providers.ollama] | ||
| type = "ollama" | ||
| # Access local Ollama on host machine via Docker internal gateway | ||
| url = "http://host.docker.internal:11434" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's explore the repository structure
git ls-files | head -30Repository: POWERFULMOVES/PMOVES.AI
Length of output: 1037
🏁 Script executed:
# Search for docker-compose files
fd docker-composeRepository: POWERFULMOVES/PMOVES.AI
Length of output: 2984
🏁 Script executed:
# Look for the tensorzero.toml file and its context
fd tensorzero.tomlRepository: POWERFULMOVES/PMOVES.AI
Length of output: 254
🏁 Script executed:
# Search for any documentation about deployment or Linux compatibility
fd -e md -e rst | grep -E "(README|DEPLOY|INSTALL|GUIDE|doc)" | head -20Repository: POWERFULMOVES/PMOVES.AI
Length of output: 989
🏁 Script executed:
# Search for references to OLLAMA_URL or environment variables
rg "OLLAMA_URL|host.docker.internal" -iRepository: POWERFULMOVES/PMOVES.AI
Length of output: 33717
🏁 Script executed:
# Check the features/gateway directory structure and docker-compose
ls -la features/gateway/ 2>/dev/null || echo "Directory not found or doesn't exist"Repository: POWERFULMOVES/PMOVES.AI
Length of output: 301
🏁 Script executed:
# Read the features/gateway docker-compose file
cat -n features/gateway/docker-compose.yml 2>/dev/null || echo "File not found"Repository: POWERFULMOVES/PMOVES.AI
Length of output: 2610
🏁 Script executed:
# Read the tensorzero.toml file in full context
cat -n features/gateway/config/tensorzero.tomlRepository: POWERFULMOVES/PMOVES.AI
Length of output: 3431
🏁 Script executed:
# Check if there are any environment variable substitutions in tensorzero.toml
rg -A 5 -B 5 "tensorzero.toml" features/gateway/ || echo "No additional context found"Repository: POWERFULMOVES/PMOVES.AI
Length of output: 842
🏁 Script executed:
# Check what documentation exists specifically for features/gateway
find features/gateway -type f \( -name "*.md" -o -name "README*" -o -name "*.txt" \) 2>/dev/nullRepository: POWERFULMOVES/PMOVES.AI
Length of output: 49
Add Linux compatibility configuration to the TensorZero gateway Docker Compose setup.
The hardcoded URL http://host.docker.internal:11434 is unavailable on Linux Docker hosts without explicit configuration. Add to features/gateway/docker-compose.yml under the tensorzero-gateway service:
extra_hosts:
- "host.docker.internal:host-gateway"Alternatively, modify features/gateway/config/tensorzero.toml line 10 to support environment variable override:
url = "${env.OLLAMA_URL:-http://host.docker.internal:11434}"and add OLLAMA_URL to the environment section in docker-compose.yml.
Document this Linux requirement in a features/gateway/README.md or update deployment docs to note that Linux deployments must either use the extra_hosts approach or configure a network override.
🤖 Prompt for AI Agents
In features/gateway/config/tensorzero.toml around lines 7 to 10, the hardcoded
Ollama URL uses host.docker.internal which is not available on Linux Docker
hosts; update the configuration to allow an environment override for the URL
(read OLLAMA_URL with a fallback to the existing value) and then update
features/gateway/docker-compose.yml to either add extra_hosts:
["host.docker.internal:host-gateway"] under the tensorzero-gateway service or
add OLLAMA_URL to the service environment so operators can set a
Linux-compatible address; also add a short note to features/gateway/README.md
(or your deployment docs) explaining the Linux requirement and the two supported
workarounds.
| services: | ||
| tensorzero-clickhouse: | ||
| image: clickhouse/clickhouse-server:24.12-alpine | ||
| restart: unless-stopped | ||
| environment: | ||
| - CLICKHOUSE_USER=tensorzero | ||
| - CLICKHOUSE_PASSWORD=tensorzero | ||
| - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 | ||
| ports: | ||
| - "8123:8123" | ||
| volumes: | ||
| - ./clickhouse-data:/var/lib/clickhouse | ||
| networks: | ||
| - data_tier | ||
| - monitoring_tier | ||
| # Security Hardening | ||
| user: "101:101" # ClickHouse default non-root user | ||
| cap_drop: | ||
| - ALL | ||
| cap_add: | ||
| - SYS_NICE | ||
| - NET_ADMIN | ||
| - IPC_LOCK | ||
| healthcheck: | ||
| test: [ "CMD-SHELL", "wget --spider http://tensorzero:tensorzero@localhost:8123/ping" ] | ||
| interval: 5s | ||
| timeout: 2s | ||
| retries: 5 |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Add Compose profile for gateway services.
Per coding guidelines: "Use Compose profiles (data, workers) to scope what runs locally in docker-compose.yml"
The gateway services should have a profile (e.g., gateway or data) to control when they're started.
🔎 Proposed change
services:
tensorzero-clickhouse:
image: clickhouse/clickhouse-server:24.12-alpine
restart: unless-stopped
+ profiles:
+ - data
environment:And similarly for tensorzero-gateway:
tensorzero-gateway:
image: tensorzero/gateway:latest
restart: unless-stopped
+ profiles:
+ - gateway
command: [ "--config-file", "/app/config/tensorzero.toml" ]Based on coding guidelines: "Use Compose profiles (data, workers) to scope what runs locally in docker-compose.yml"
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| services: | |
| tensorzero-clickhouse: | |
| image: clickhouse/clickhouse-server:24.12-alpine | |
| restart: unless-stopped | |
| environment: | |
| - CLICKHOUSE_USER=tensorzero | |
| - CLICKHOUSE_PASSWORD=tensorzero | |
| - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 | |
| ports: | |
| - "8123:8123" | |
| volumes: | |
| - ./clickhouse-data:/var/lib/clickhouse | |
| networks: | |
| - data_tier | |
| - monitoring_tier | |
| # Security Hardening | |
| user: "101:101" # ClickHouse default non-root user | |
| cap_drop: | |
| - ALL | |
| cap_add: | |
| - SYS_NICE | |
| - NET_ADMIN | |
| - IPC_LOCK | |
| healthcheck: | |
| test: [ "CMD-SHELL", "wget --spider http://tensorzero:tensorzero@localhost:8123/ping" ] | |
| interval: 5s | |
| timeout: 2s | |
| retries: 5 | |
| services: | |
| tensorzero-clickhouse: | |
| image: clickhouse/clickhouse-server:24.12-alpine | |
| restart: unless-stopped | |
| profiles: | |
| - data | |
| environment: | |
| - CLICKHOUSE_USER=tensorzero | |
| - CLICKHOUSE_PASSWORD=tensorzero | |
| - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 | |
| ports: | |
| - "8123:8123" | |
| volumes: | |
| - ./clickhouse-data:/var/lib/clickhouse | |
| networks: | |
| - data_tier | |
| - monitoring_tier | |
| # Security Hardening | |
| user: "101:101" # ClickHouse default non-root user | |
| cap_drop: | |
| - ALL | |
| cap_add: | |
| - SYS_NICE | |
| - NET_ADMIN | |
| - IPC_LOCK | |
| healthcheck: | |
| test: [ "CMD-SHELL", "wget --spider http://tensorzero:tensorzero@localhost:8123/ping" ] | |
| interval: 5s | |
| timeout: 2s | |
| retries: 5 |
🧰 Tools
🪛 Checkov (3.2.334)
[medium] 41-42: Basic Auth Credentials
(CKV_SECRET_4)
🤖 Prompt for AI Agents
In features/gateway/docker-compose.yml around lines 17-44, the
tensorzero-clickhouse service lacks a Compose profile so it always starts; add a
profiles key (e.g., profiles: ["data"] or ["gateway"]) to scope startup,
matching project guidelines, and do the same for the tensorzero-gateway service
elsewhere in this file so both services only run when the matching Compose
profile is enabled.
| @asynccontextmanager | ||
| async def lifespan(app: FastAPI): | ||
| # Startup | ||
| global nc | ||
| try: | ||
| logger.info(f"Connecting to NATS at {NATS_URL}...") | ||
| nc = await nats.connect(NATS_URL) | ||
| logger.info("Connected to NATS.") | ||
|
|
||
| # Subscribe to Geometry Bus events (Simulation Actions) | ||
| async def message_handler(msg): | ||
| subject = msg.subject | ||
| data = msg.data.decode() | ||
| logger.info(f"Received geometry event on {subject}: {len(data)} bytes") | ||
| # TODO: Accumulate trajectory for dataset creation | ||
|
|
||
| await nc.subscribe("geometry.event.v1", cb=message_handler) | ||
|
|
||
| except Exception as e: | ||
| logger.error(f"Failed to connect to NATS: {e}") | ||
|
|
||
| yield | ||
|
|
||
| # Shutdown | ||
| if nc: | ||
| await nc.close() |
There was a problem hiding this comment.
Critical: NATS connection failure doesn't prevent app startup.
If NATS connection fails during startup, the exception is logged but the app continues running. This means health checks will report "disconnected" status, and events won't be processed. Services depending on this coordinator will fail silently.
Additionally:
- No connection timeout specified, which could cause indefinite hangs.
- The message handler (lines 30-35) has no error handling; a malformed message could crash the subscription.
- Line 39: Use
logging.exceptioninstead oflogging.errorto capture the full traceback.
🔎 Proposed fixes
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
global nc
try:
logger.info(f"Connecting to NATS at {NATS_URL}...")
- nc = await nats.connect(NATS_URL)
+ nc = await nats.connect(NATS_URL, connect_timeout=10)
logger.info("Connected to NATS.")
# Subscribe to Geometry Bus events (Simulation Actions)
async def message_handler(msg):
- subject = msg.subject
- data = msg.data.decode()
- logger.info(f"Received geometry event on {subject}: {len(data)} bytes")
- # TODO: Accumulate trajectory for dataset creation
+ try:
+ subject = msg.subject
+ data = msg.data.decode()
+ logger.info(f"Received geometry event on {subject}: {len(data)} bytes")
+ # TODO: Accumulate trajectory for dataset creation
+ except Exception as e:
+ logger.exception(f"Error processing message from {msg.subject}: {e}")
await nc.subscribe("geometry.event.v1", cb=message_handler)
- except Exception as e:
- logger.error(f"Failed to connect to NATS: {e}")
+ except (ConnectionClosedError, TimeoutError, NoServersError) as e:
+ logger.exception(f"Failed to connect to NATS: {e}")
+ raise # Prevent app from starting without NATS
yield
# Shutdown
if nc:
await nc.close()🧰 Tools
🪛 Ruff (0.14.10)
21-21: Unused function argument: app
(ARG001)
38-38: Do not catch blind exception: Exception
(BLE001)
39-39: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
🤖 Prompt for AI Agents
In pmoves/services/agentgym-rl-coordinator/app.py around lines 20 to 45, the
lifespan handler currently logs NATS connection failures but allows the app to
continue, has no connection timeout, and the message_handler lacks error
handling; change it so that the startup fails when NATS cannot be established
(raise the exception or call sys.exit after logging), use a connect call with a
timeout/connection options (or wrap await nats.connect(...) in asyncio.wait_for
with a reasonable timeout), replace logger.error with logger.exception to
capture tracebacks, and wrap the message_handler body in a try/except that logs
exceptions (using logger.exception) and safely skips malformed messages; also
ensure shutdown checks that nc exists and is connected before awaiting
nc.close().
| @app.post("/agentgym/train/start") | ||
| async def start_training(run_id: str): | ||
| logger.info(f"Triggering training run: {run_id}") | ||
| # TODO: Implement PPO training loop triggering | ||
| return {"status": "training_started", "run_id": run_id} |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Add request body validation with Pydantic.
The run_id parameter should be part of a validated request body rather than a query parameter. This aligns with REST best practices and the coding guideline: "Validate payloads against schemas before publishing events."
🔎 Proposed refactor
Add a Pydantic model at the top of the file after imports:
+from pydantic import BaseModel, Field
+
+class TrainingStartRequest(BaseModel):
+ run_id: str = Field(..., min_length=1, description="Unique training run identifier")Then update the endpoint:
@app.post("/agentgym/train/start")
-async def start_training(run_id: str):
+async def start_training(request: TrainingStartRequest):
+ run_id = request.run_id
logger.info(f"Triggering training run: {run_id}")
# TODO: Implement PPO training loop triggering
return {"status": "training_started", "run_id": run_id}Based on coding guidelines: "Validate payloads against schemas before publishing events using services/common/events.py"
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @app.post("/agentgym/train/start") | |
| async def start_training(run_id: str): | |
| logger.info(f"Triggering training run: {run_id}") | |
| # TODO: Implement PPO training loop triggering | |
| return {"status": "training_started", "run_id": run_id} | |
| @app.post("/agentgym/train/start") | |
| async def start_training(request: TrainingStartRequest): | |
| run_id = request.run_id | |
| logger.info(f"Triggering training run: {run_id}") | |
| # TODO: Implement PPO training loop triggering | |
| return {"status": "training_started", "run_id": run_id} |
🤖 Prompt for AI Agents
In pmoves/services/agentgym-rl-coordinator/app.py around lines 55 to 59, the
endpoint currently takes run_id as a query parameter; change it to accept and
validate a request body by adding a Pydantic model (e.g., TrainStartRequest with
a run_id: str) after the imports, update the POST handler signature to accept
that model (async def start_training(req: TrainStartRequest)), use req.run_id in
the handler, and ensure any published events use the validated payload and the
existing services/common/events.py helpers.
| @app.post("/agentgym/dataset/publish") | ||
| async def publish_dataset(dataset_name: str): | ||
| if not HF_TOKEN: | ||
| raise HTTPException(status_code=500, detail="HF_TOKEN not configured") | ||
|
|
||
| logger.info(f"Publishing dataset {dataset_name} to Hugging Face...") | ||
| # TODO: Implement dataset push logic via huggingface_hub | ||
| return {"status": "publishing_started", "dataset": dataset_name} |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Improve validation and error handling.
Issues:
dataset_nameshould be part of a validated request body, not a query parameter.HF_TOKENvalidation should occur at startup (in the lifespan manager) rather than per-request to fail fast.- HTTP 500 is incorrect for missing configuration; use 503 (Service Unavailable) or validate at startup and refuse to start.
🔎 Proposed refactor
Add validation at startup in the lifespan manager:
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
global nc
+
+ # Validate HF_TOKEN at startup
+ if not HF_TOKEN:
+ logger.error("HF_TOKEN not configured. Dataset publishing will be unavailable.")
+ # Optionally: raise ValueError("HF_TOKEN required") to prevent startup
+
try:Add a Pydantic model:
+class DatasetPublishRequest(BaseModel):
+ dataset_name: str = Field(..., min_length=1, pattern=r'^[\w\-]+$', description="Dataset name")Update the endpoint:
@app.post("/agentgym/dataset/publish")
-async def publish_dataset(dataset_name: str):
+async def publish_dataset(request: DatasetPublishRequest):
if not HF_TOKEN:
- raise HTTPException(status_code=500, detail="HF_TOKEN not configured")
+ raise HTTPException(status_code=503, detail="HF_TOKEN not configured - dataset publishing unavailable")
+ dataset_name = request.dataset_name
logger.info(f"Publishing dataset {dataset_name} to Hugging Face...")
# TODO: Implement dataset push logic via huggingface_hub
return {"status": "publishing_started", "dataset": dataset_name}Based on coding guidelines: "Validate payloads against schemas before publishing events using services/common/events.py"
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
pmoves/services/agentgym-rl-coordinator/app.py around lines 61-68: change the
endpoint to accept a Pydantic request body (e.g., DatasetPublish model) so
dataset_name is validated as part of the body rather than a query param; remove
the per-request HF_TOKEN check and instead validate HF_TOKEN in the
application's lifespan manager (fail fast on startup and log a clear error or
raise StartupError) so requests never proceed without config; return proper HTTP
status for service unavailability (503) only when appropriate or rely on startup
failure to prevent running; and validate the incoming payload against the
canonical schema in services/common/events.py before publishing, returning
validation errors (422) if it fails.
| services: | ||
| agentgym-coordinator: | ||
| build: . | ||
| restart: unless-stopped | ||
| ports: | ||
| - "8114:8114" | ||
| environment: | ||
| - NATS_URL=nats://nats:4222 | ||
| - PORT=8114 | ||
| - HF_TOKEN=${HF_TOKEN} | ||
| - HF_HOME=/home/nonroot/.cache/huggingface | ||
| volumes: | ||
| - huggingface-cache:/home/nonroot/.cache/huggingface | ||
| networks: | ||
| - app_tier | ||
| - bus_tier | ||
| - api_tier | ||
| - monitoring_tier | ||
| # Security Hardening | ||
| user: "65532:65532" # Non-root distroless | ||
| read_only: true | ||
| cap_drop: | ||
| - ALL |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Add Compose profile and clarify network requirements.
Per coding guidelines: "Use Compose profiles (data, workers) to scope what runs locally in docker-compose.yml"
Additionally, the service is attached to all four networks. Clarify if api_tier access is required—typically, internal coordinators only need app_tier, bus_tier, and monitoring_tier.
🔎 Proposed changes
services:
agentgym-coordinator:
build: .
restart: unless-stopped
+ profiles:
+ - workers # or 'ai' if there's a profile for AI/ML services
ports:
- "8114:8114"
environment:
- NATS_URL=nats://nats:4222
- PORT=8114
- HF_TOKEN=${HF_TOKEN}
- HF_HOME=/home/nonroot/.cache/huggingface
volumes:
- huggingface-cache:/home/nonroot/.cache/huggingface
networks:
- app_tier
- bus_tier
- - api_tier
- monitoring_tierIf api_tier access is genuinely required (e.g., the service exposes a public API), document the reason in a comment.
Based on coding guidelines: "Use Compose profiles (data, workers) to scope what runs locally in docker-compose.yml"
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| services: | |
| agentgym-coordinator: | |
| build: . | |
| restart: unless-stopped | |
| ports: | |
| - "8114:8114" | |
| environment: | |
| - NATS_URL=nats://nats:4222 | |
| - PORT=8114 | |
| - HF_TOKEN=${HF_TOKEN} | |
| - HF_HOME=/home/nonroot/.cache/huggingface | |
| volumes: | |
| - huggingface-cache:/home/nonroot/.cache/huggingface | |
| networks: | |
| - app_tier | |
| - bus_tier | |
| - api_tier | |
| - monitoring_tier | |
| # Security Hardening | |
| user: "65532:65532" # Non-root distroless | |
| read_only: true | |
| cap_drop: | |
| - ALL | |
| services: | |
| agentgym-coordinator: | |
| build: . | |
| restart: unless-stopped | |
| profiles: | |
| - workers # or 'ai' if there's a profile for AI/ML services | |
| ports: | |
| - "8114:8114" | |
| environment: | |
| - NATS_URL=nats://nats:4222 | |
| - PORT=8114 | |
| - HF_TOKEN=${HF_TOKEN} | |
| - HF_HOME=/home/nonroot/.cache/huggingface | |
| volumes: | |
| - huggingface-cache:/home/nonroot/.cache/huggingface | |
| networks: | |
| - app_tier | |
| - bus_tier | |
| - monitoring_tier | |
| # Security Hardening | |
| user: "65532:65532" # Non-root distroless | |
| read_only: true | |
| cap_drop: | |
| - ALL |
🤖 Prompt for AI Agents
In pmoves/services/agentgym-rl-coordinator/docker-compose.yml around lines 21 to
43, add a Compose profile (e.g., "workers") to the agentgym-coordinator service
so it only runs under the intended local scope and adjust the networks to only
include the required internal networks (app_tier, bus_tier, monitoring_tier)
unless external API access is needed; if api_tier is genuinely required, add a
clear inline comment explaining why the service must be on api_tier (e.g.,
exposes public API) and otherwise remove api_tier from the networks list. Ensure
the service entry includes the profile name and update any documentation or
compose comments to reflect the chosen profile and network rationale.
| fastapi==0.109.0 | ||
| uvicorn==0.27.0 | ||
| nats-py==2.6.0 | ||
| httpx==0.26.0 | ||
| pydantic==2.6.0 | ||
| huggingface_hub==0.20.0 | ||
| python-multipart==0.0.6 |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
PYSEC-2024-38 fastapi vulnerability
💡 Result:
Summary — what it is
- PYSEC-2024-38 is a Regular Expression Denial-of-Service (ReDoS) affecting form-data parsing via python-multipart used by FastAPI. An attacker can craft a Content-Type option that causes the regex to consume CPU and stall the event loop, resulting in DoS. Published Feb 5, 2024. [1][2]
Identifiers
- PYSEC-2024-38 = CVE-2024-24762; GHSA-2jv5-9r88-3w3p / GHSA-qf9m-vfgh-m389. [1]
Affected software
- FastAPI versions before 0.109.1 (when using form-data parsing via python-multipart).
- python-multipart versions prior to 0.0.7. [1][3]
Impact
- High (CVSS 3.1 7.5): Denial of Service (process becomes unresponsive while parsing a single malicious request). [1][3]
Mitigation / Fix
- Upgrade FastAPI to >= 0.109.1.
- Upgrade python-multipart to >= 0.0.7 (if your app directly depends on it).
- If you cannot upgrade immediately, block or validate suspicious Content-Type headers at your edge (WAF/proxy) to reject unusually long or weird option strings. [1][3]
References
- OSV advisory (PYSEC-2024-38 / FastAPI). [1]
- GitLab / CVE-2024-24762 (python-multipart / Starlette notes). [2]
- PT Security / dbugs summary of CVE-2024-24762 and remediation. [3]
🌐 Web query:
GHSA-2jv5-9r88-3w3p python-multipart Content-Type Header ReDoS
💡 Result:
Summary — CVE-2024-24762 / GHSA-2jv5-9r88-3w3p
- What: A ReDoS (regular-expression DoS) in python-multipart when parsing the Content-Type header options for form data. A maliciously crafted Content-Type option can cause catastrophic regex backtracking, consuming CPU and stalling the event loop. [1][2]
- Affected versions: python-multipart <= 0.0.6 (all versions before 0.0.7). [1][3]
- Severity: CVSS 7.5 (High). [1][3]
- Fixed: Upgrade to python-multipart >= 0.0.7. Commit/patch referenced in the advisory. [1][2]
Actionable mitigation
- Upgrade immediately: pip install --upgrade python-multipart (ensure version >= 0.0.7). [1][2]
- If you cannot upgrade immediately, apply network mitigations (rate limiting, request throttling, WAF rules to block suspicious Content-Type headers) and avoid parsing untrusted form Content-Type options until patched. [3][4]
References
- GitLab Advisory / package advisory summary (python-multipart — CVE-2024-24762). [turn0search0]
- Chainguard / advisory summary (CVE-2024-24762). [turn0search2]
- Snyk / Debian security tracker summary for CVE-2024-24762. [turn0search4]
- Additional vendor write-ups / vulnerability databases (Vulert / Seal) summarizing exploit and mitigation. [turn0search5][turn0search1]
🌐 Web query:
GHSA-59g5-xgcq-4qw3 python-multipart multipart form-data DoS
💡 Result:
Summary
- GHSA-59g5-xgcq-4qw3 (CVE-2024-53981) affects python-multipart versions < 0.0.18: a malicious multipart/form-data request that places lots of bytes before the first boundary or after the last boundary triggers one-byte-at-a-time skips and excessive logging, allowing high CPU use and an ASGI event-loop stall (DoS). Patch: upgrade to 0.0.18+. [1][2]
Mitigation
- Upgrade python-multipart to >= 0.0.18 and deploy/restart services.
- If you vendor/pin dependencies, update lockfiles (requirements.txt/Poetry/Pipfile) and rebuild images.
- Consider WAF/rate-limiting for multipart endpoints until patched.
Related note
- python-multipart also had an earlier ReDoS issue (CVE-2024-24762) fixed in 0.0.7; ensure you’re on recent non-vulnerable versions for both issues. [3]
Sources
[1] GitHub Advisory GHSA-59g5-xgcq-4qw3 (python-multipart).
[2] CVE-2024-53981 / CVE feed entry.
[3] Snyk / GitLab advisories (python-multipart vulnerability summaries).
🌐 Web query:
GHSA-2c2j-9gv5-cj73 starlette DoS vulnerability
💡 Result:
Summary: GHSA-2c2j-9gv5-cj73 is a moderate-severity denial‑of‑service in Starlette (CVE‑2025‑54121). When parsing multipart/form-data with large file parts (larger than the default in‑memory spool size) Starlette can block the event/main thread while rolling files to disk, preventing the app from accepting new connections. Affects Starlette versions < 0.47.2. Fixed in 0.47.2 — upgrade or pin to ≥ 0.47.2. [1][2][3]
References
- GitHub security advisory (GHSA-2c2j-9gv5-cj73). [1]
- OSV / vulnerability record (CVE‑2025‑54121). [2]
- Safety / vulnerability summary. [3]
🌐 Web query:
GHSA-f96h-pmfr-66vw starlette DoS vulnerability
💡 Result:
Yes — GHSA-f96h-pmfr-66vw is a published high-severity DoS in Starlette (CVE-2024-47874). Summary, impact, and mitigation:
- Issue: multipart/form-data parts that lack a filename are treated as text fields and buffered without size limits, allowing an attacker to send very large form fields and exhaust server memory (DoS). PoC uses request.form() with a large field. [1][2]
- Affected versions: all starlette < 0.40.0. [1][3]
- Fixed in: starlette 0.40.0 — adds max_part_size to MultiPartParser to enforce limits. Upgrade to >= 0.40.0. [1][3]
- Mitigation alternatives: enforce upstream request-size limits (may not fully prevent this), use a reverse proxy with strict per-part limits, or explicitly set max_part_size via Starlette 0.40.0+ configuration. [1][2]
Sources:
- GitHub Advisory GHSA-f96h-pmfr-66vw / CVE-2024-47874. [GitHub Advisory]. [1]
- OSV entry for GHSA-f96h-pmfr-66vw. [2]
- Safety / package advisories and changelog noting fix in 0.40.0. [3]
🏁 Script executed:
# Check what version of starlette is required by fastapi 0.109.0
curl -s "https://pypi.org/pypi/fastapi/0.109.0/json" | jq -r '.info.requires_dist[] | select(contains("starlette"))'Repository: POWERFULMOVES/PMOVES.AI
Length of output: 92
🏁 Script executed:
# Check the current versions of these packages on PyPI
for pkg in fastapi python-multipart starlette; do
echo "=== $pkg latest version ==="
curl -s "https://pypi.org/pypi/$pkg/json" | jq -r '.info | "\(.version) (released: \(.last_modified))"'
doneRepository: POWERFULMOVES/PMOVES.AI
Length of output: 243
Critical: Multiple HIGH severity security vulnerabilities in dependencies.
python-multipart 0.0.6 is affected by two HIGH severity DoS vulnerabilities:
- GHSA-2jv5-9r88-3w3p (CVE-2024-24762): Content-Type header ReDoS—fixed in 0.0.7
- GHSA-59g5-xgcq-4qw3 (CVE-2024-53981): Multipart boundary parsing DoS—fixed in 0.0.18
fastapi 0.109.0 itself is patched in 0.109.1 for PYSEC-2024-38 (the ReDoS issue above).
starlette 0.35.x (transitive via fastapi) is vulnerable to:
- GHSA-f96h-pmfr-66vw (CVE-2024-47874): HIGH severity—unbounded buffering of form fields leads to memory exhaustion; fixed in 0.40.0
- GHSA-2c2j-9gv5-cj73 (CVE-2025-54121): Moderate severity—file spooling DoS; fixed in 0.47.2
These vulnerabilities directly impact production readiness and require immediate updates to: fastapi ≥ 0.109.1, python-multipart ≥ 0.0.18, and starlette ≥ 0.40.0 (or higher for full coverage).
🧰 Tools
🪛 OSV Scanner (2.3.1)
[HIGH] 1-1: fastapi 0.109.0: undefined
(PYSEC-2024-38)
[HIGH] 1-1: python-multipart 0.0.6: python-multipart vulnerable to Content-Type Header ReDoS
[HIGH] 1-1: python-multipart 0.0.6: Denial of service (DoS) via deformation multipart/form-data boundary
[HIGH] 1-1: starlette 0.35.1: Starlette has possible denial-of-service vector when parsing large files in multipart forms
[HIGH] 1-1: starlette 0.35.1: Starlette Denial of service (DoS) via multipart/form-data
🤖 Prompt for AI Agents
In pmoves/services/agentgym-rl-coordinator/requirements.txt lines 1-7, update
vulnerable dependency versions: bump fastapi to at least 0.109.1,
python-multipart to at least 0.0.18, and add an explicit starlette>=0.40.0 (or
higher) to ensure transitive fixes are applied; then run a fresh install and
regenerate the lock/constraints file (pip-compile or pip freeze) and run the
test suite/quick smoke tests to ensure compatibility with the new versions.
* docs: update TensorZero master plan with network segmentation and local-first routing * feat(gateway): implement TensorZero Gateway with security hardening and clickhouse observability * feat(agentgym): add RL coordinator service with NATS and HF integration --------- Co-authored-by: Codex Agent <codex-agent@example.com>
* feat: Local-First TensorZero Gateway & AgentGym Integration (#347) * docs: update TensorZero master plan with network segmentation and local-first routing * feat(gateway): implement TensorZero Gateway with security hardening and clickhouse observability * feat(agentgym): add RL coordinator service with NATS and HF integration --------- Co-authored-by: Codex Agent <codex-agent@example.com> * TensorZero: Local-First Architecture & Supabase Integration (#336) * feat(tensorzero): impl cloud-first routing & text-only system prompts * infra(tensorzero): integrate with main supabase postgres cluster * docs: add comprehensive services documentation * docs: update TensorZero to Local-First architecture - Correct architecture: Local First, Cloud Hybrid (not Cloud First) - TensorZero is the SINGLE source of truth for all models - Routing priority: Ollama (local) → Anthropic → Gemini - Dynamic model discovery from TensorZero API - No hardcoded models in services or compose files - crush_configurator now queries TensorZero for available models 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address CodeRabbit review comments for PR #336 CRITICAL FIXES: - Fix TensorZero port from 3030 to 3000 for container-to-container communication in docker-compose.yml - Comment out duplicate OPENAI_MODEL in .env.example line 246 (already defined at line 234) MAJOR FIXES: - Remove numpy/_core deletion from ultimate-tts-studio Dockerfile that breaks numpy - Consolidate duplicate comments in Dockerfile MINOR FIXES (nitpicks): - Remove duplicate DeepResearch section in services documentation - Update timestamp from 2025-01-19 to 2025-12-21 - Remove duplicate "New BoTZ Models" comment in tensorzero.toml - Add 'text' language specifier to directory tree code block in documentation Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: update .gitignore for user-specific configs Add ignores for: - .claude/settings.json (user-specific Claude Code settings) - .kilocode/ (external AI tool configs) - pmoves/PR_BODY_*.md (temporary PR templates) - research/ (local research notes) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(tensorzero): add orchestrator function and documentation Adds TensorZero configuration and documentation: - `.claude/commands/tensorzero/models.md` - TAC command to list models - `.claude/learnings/tensorzero-pr336-review-2025-12.md` - PR review learnings - `docs/PMOVES_TensorZero_Implementation.md` - Implementation guide - `docs/tz.md` - Quick reference - `pmoves/tensorzero/config/functions/orchestrator/` - Orchestrator function - `pmoves/tensorzero/config/tools/web_search.json` - Web search tool schema 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Codex Agent <codex-agent@example.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat(tensorzero): Dynamic configuration management with validation and observability (#367) * feat: Voice Cloning + AgentGym RL Coordinator - Add RVC voice cloning workflow with Supabase state management - New provider: providers/cloning.py with VoiceCloningProvider class - API endpoints: register, train, status, jobs, synthesize - Feature flag voice_cloning changed from False to True - Trajectory accumulation from NATS geometry events - PPO training orchestration with background asyncio tasks - HuggingFace dataset preparation and publishing - Unified Supabase storage interface - 20251225_voice_cloning.sql: voice_persona cloning columns - 20251225_agentgym_rl.sql: trajectories and training_runs tables 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix: PR #364 - Critical fixes, pre-production improvements, and future enhancements 1. Fixed missing `datetime` import in publisher.py 2. Fixed file handle leak with context manager 3. Fixed UPSERT function by adding UNIQUE constraint on session_id 4. Replaced fake implementations with NotImplementedError or real implementations 5. Added input validation (dataset_name regex, status enum, trajectory_id UUID) 1. Added CHECK constraints for data integrity (event_count >= 0, epochs bounds) 2. Added completion validation constraint (voice_cloning_status='completed' requires model URIs) 3. Fixed empty except blocks - now log errors 4. Fixed silent error returns - now log before returning 5. Added status validation to AgentGym endpoints 1. Temporal consistency triggers for training timestamps 2. Real MinIO upload implementation via presign service 3. Real GPU training trigger via NATS message bus 4. Real HuggingFace publishing using huggingface_hub library 5. State transition validation triggers - Added prometheus-client to services that import it but were missing the dependency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix: Address SQL Policy Lint and CodeQL security alert - Fixed SQL Policy Lint: Added new migration files to allowlist - 20251216_social_scheduler.sql: Removed anon grants, added namespace-based RLS - 20251225_agentgym_rl.sql: Service role policies are acceptable - 20251225_voice_cloning.sql: Service role policies are acceptable - Fixed CodeQL path traversal in training.py: - Added explicit run_id sanitization with regex substitution - Added os.path.normpath() and /tmp prefix check - Defense in depth: validation + sanitization + path check 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix: Address all PR #364 CodeRabbit feedback (26 fixes) Fixes all remaining Major, Minor, and Nitpick issues from CodeRabbit review: - storage.py: Use HEAD + Prefer: count=exact for efficient counting - cloning.py: Add response status check on PATCH request - agentgym_rl.sql: Remove blanket USING (true) RLS policies - voice_cloning.sql: Restrict register_voice_cloning to service_role - messaging-gateway.json: Fix duplicate panel title/query - training.py: Remove duplicate status update in cancel_training - main.py: Add cloning_provider.close() to shutdown sequence - coordinator/__init__.py: Sort __all__ alphabetically - coordinator/publisher.py: Use tempfile.gettempdir(), prefix unused var - coordinator/trajectory.py: Remove redundant exception in logging - coordinator/training.py: Remove redundant exception in logging - app.py: Remove unused dict, fix logging patterns, add exception chaining - main.py: Add 'from None' exception chaining (6 locations) - storage.py: Add warning logs on list failures - cloning.py: Narrow exception catches, add HTTP connection limits All changes improve code quality, security, and observability. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * feat(tz-cli): add TensorZero CLI with path validation Adds CLI tool for managing TensorZero configurations: - validate command - check config syntax and semantics - add_variant command - dynamically add function variants - apply_template command - apply predefined templates - diff command - view configuration changes - reload command - trigger hot reload Security enhancements: - validate_config_path() - prevents path traversal - validate_template_name() - validates naming conventions - validate_safe_path() - ensures path stays within bounds - All user inputs validated before filesystem access 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(tz-core): add validators library and TensorZero docs Adds comprehensive validation for TensorZero configurations: - JSON Schema validation (CONFIG_SCHEMA) - validate_model_config() - model/provider validation - validate_function_config() - function/variant validation - validate_variant_config() - variant-specific validation - validate_cross_references() - cross-reference integrity - validate_identifier_name() - naming conventions - validate_config_path() - path security validation Also adds comprehensive TensorZero Config Management README at pmoves/docs/tensorzero/README.md with: - Overview and feature documentation - Installation instructions for all components - Configuration schema reference - Validation rules - CLI usage examples - API endpoints documentation - Security considerations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(tz-obs): add TensorZero Config API with SQL injection protection Adds REST API for dynamic TensorZero configuration management: - GET /config - retrieve current configuration - POST /config/validate - validate without applying - POST /config/reload - trigger hot reload - GET /history - retrieve change history - GET /health - health check ClickHouse integration: - ConfigChangeLogger for audit trail - log_configuration_update() - track updates with diffs - log_configuration_create() - track new resources - log_configuration_delete() - track deletions - log_configuration_rollback() - track rollbacks - log_hot_reload() - track reload events - get_validation_error_rate() - metrics - get_hot_reload_success_rate() - metrics - get_rollback_count() - metrics Security fixes: - _validate_identifier() - prevents SQL injection in table/db names - _validate_positive_integer() - validates integer parameters - All SQL queries use parameterized values - Backtick quoting for validated identifiers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(tz-ui): add TensorZero Config React UI components Adds React components for TensorZero configuration management: - TensorZeroConfigEditor - TOML editor with syntax highlighting - TensorZeroValidationPanel - real-time validation feedback - TensorZeroChangeHistory - audit trail with diffs - TensorZeroMetricsDashboard - validation and reload metrics Dependencies: - Added Monaco Editor for TOML syntax highlighting - Added React Query for data fetching - Added Recharts for metrics visualization 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Codex Agent <codex-agent@example.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> * feat: Voice Cloning + AgentGym RL Coordinator Merged with all fixes from CodeRabbit, CodeQL, and SQL Policy Lint reviews. All 31 comments addressed: - 3 Critical issues fixed (missing import, UNIQUE constraint, path traversal) - 6 Major issues fixed (efficient counting, response validation, RLS security) - 4 Minor issues fixed (dashboard clarity, resource leaks) - 18 Nitpicks addressed (style, logging patterns, exception handling) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Codex Agent <codex-agent@example.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: Local-First TensorZero Gateway & AgentGym Integration (#347) * docs: update TensorZero master plan with network segmentation and local-first routing * feat(gateway): implement TensorZero Gateway with security hardening and clickhouse observability * feat(agentgym): add RL coordinator service with NATS and HF integration --------- Co-authored-by: Codex Agent <codex-agent@example.com> * TensorZero: Local-First Architecture & Supabase Integration (#336) * feat(tensorzero): impl cloud-first routing & text-only system prompts * infra(tensorzero): integrate with main supabase postgres cluster * docs: add comprehensive services documentation * docs: update TensorZero to Local-First architecture - Correct architecture: Local First, Cloud Hybrid (not Cloud First) - TensorZero is the SINGLE source of truth for all models - Routing priority: Ollama (local) → Anthropic → Gemini - Dynamic model discovery from TensorZero API - No hardcoded models in services or compose files - crush_configurator now queries TensorZero for available models 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address CodeRabbit review comments for PR #336 CRITICAL FIXES: - Fix TensorZero port from 3030 to 3000 for container-to-container communication in docker-compose.yml - Comment out duplicate OPENAI_MODEL in .env.example line 246 (already defined at line 234) MAJOR FIXES: - Remove numpy/_core deletion from ultimate-tts-studio Dockerfile that breaks numpy - Consolidate duplicate comments in Dockerfile MINOR FIXES (nitpicks): - Remove duplicate DeepResearch section in services documentation - Update timestamp from 2025-01-19 to 2025-12-21 - Remove duplicate "New BoTZ Models" comment in tensorzero.toml - Add 'text' language specifier to directory tree code block in documentation Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: update .gitignore for user-specific configs Add ignores for: - .claude/settings.json (user-specific Claude Code settings) - .kilocode/ (external AI tool configs) - pmoves/PR_BODY_*.md (temporary PR templates) - research/ (local research notes) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(tensorzero): add orchestrator function and documentation Adds TensorZero configuration and documentation: - `.claude/commands/tensorzero/models.md` - TAC command to list models - `.claude/learnings/tensorzero-pr336-review-2025-12.md` - PR review learnings - `docs/PMOVES_TensorZero_Implementation.md` - Implementation guide - `docs/tz.md` - Quick reference - `pmoves/tensorzero/config/functions/orchestrator/` - Orchestrator function - `pmoves/tensorzero/config/tools/web_search.json` - Web search tool schema 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Codex Agent <codex-agent@example.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat(tensorzero): Dynamic configuration management with validation and observability (#367) * feat: Voice Cloning + AgentGym RL Coordinator - Add RVC voice cloning workflow with Supabase state management - New provider: providers/cloning.py with VoiceCloningProvider class - API endpoints: register, train, status, jobs, synthesize - Feature flag voice_cloning changed from False to True - Trajectory accumulation from NATS geometry events - PPO training orchestration with background asyncio tasks - HuggingFace dataset preparation and publishing - Unified Supabase storage interface - 20251225_voice_cloning.sql: voice_persona cloning columns - 20251225_agentgym_rl.sql: trajectories and training_runs tables 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix: PR #364 - Critical fixes, pre-production improvements, and future enhancements 1. Fixed missing `datetime` import in publisher.py 2. Fixed file handle leak with context manager 3. Fixed UPSERT function by adding UNIQUE constraint on session_id 4. Replaced fake implementations with NotImplementedError or real implementations 5. Added input validation (dataset_name regex, status enum, trajectory_id UUID) 1. Added CHECK constraints for data integrity (event_count >= 0, epochs bounds) 2. Added completion validation constraint (voice_cloning_status='completed' requires model URIs) 3. Fixed empty except blocks - now log errors 4. Fixed silent error returns - now log before returning 5. Added status validation to AgentGym endpoints 1. Temporal consistency triggers for training timestamps 2. Real MinIO upload implementation via presign service 3. Real GPU training trigger via NATS message bus 4. Real HuggingFace publishing using huggingface_hub library 5. State transition validation triggers - Added prometheus-client to services that import it but were missing the dependency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix: Address SQL Policy Lint and CodeQL security alert - Fixed SQL Policy Lint: Added new migration files to allowlist - 20251216_social_scheduler.sql: Removed anon grants, added namespace-based RLS - 20251225_agentgym_rl.sql: Service role policies are acceptable - 20251225_voice_cloning.sql: Service role policies are acceptable - Fixed CodeQL path traversal in training.py: - Added explicit run_id sanitization with regex substitution - Added os.path.normpath() and /tmp prefix check - Defense in depth: validation + sanitization + path check 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix: Address all PR #364 CodeRabbit feedback (26 fixes) Fixes all remaining Major, Minor, and Nitpick issues from CodeRabbit review: - storage.py: Use HEAD + Prefer: count=exact for efficient counting - cloning.py: Add response status check on PATCH request - agentgym_rl.sql: Remove blanket USING (true) RLS policies - voice_cloning.sql: Restrict register_voice_cloning to service_role - messaging-gateway.json: Fix duplicate panel title/query - training.py: Remove duplicate status update in cancel_training - main.py: Add cloning_provider.close() to shutdown sequence - coordinator/__init__.py: Sort __all__ alphabetically - coordinator/publisher.py: Use tempfile.gettempdir(), prefix unused var - coordinator/trajectory.py: Remove redundant exception in logging - coordinator/training.py: Remove redundant exception in logging - app.py: Remove unused dict, fix logging patterns, add exception chaining - main.py: Add 'from None' exception chaining (6 locations) - storage.py: Add warning logs on list failures - cloning.py: Narrow exception catches, add HTTP connection limits All changes improve code quality, security, and observability. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * feat(tz-cli): add TensorZero CLI with path validation Adds CLI tool for managing TensorZero configurations: - validate command - check config syntax and semantics - add_variant command - dynamically add function variants - apply_template command - apply predefined templates - diff command - view configuration changes - reload command - trigger hot reload Security enhancements: - validate_config_path() - prevents path traversal - validate_template_name() - validates naming conventions - validate_safe_path() - ensures path stays within bounds - All user inputs validated before filesystem access 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(tz-core): add validators library and TensorZero docs Adds comprehensive validation for TensorZero configurations: - JSON Schema validation (CONFIG_SCHEMA) - validate_model_config() - model/provider validation - validate_function_config() - function/variant validation - validate_variant_config() - variant-specific validation - validate_cross_references() - cross-reference integrity - validate_identifier_name() - naming conventions - validate_config_path() - path security validation Also adds comprehensive TensorZero Config Management README at pmoves/docs/tensorzero/README.md with: - Overview and feature documentation - Installation instructions for all components - Configuration schema reference - Validation rules - CLI usage examples - API endpoints documentation - Security considerations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(tz-obs): add TensorZero Config API with SQL injection protection Adds REST API for dynamic TensorZero configuration management: - GET /config - retrieve current configuration - POST /config/validate - validate without applying - POST /config/reload - trigger hot reload - GET /history - retrieve change history - GET /health - health check ClickHouse integration: - ConfigChangeLogger for audit trail - log_configuration_update() - track updates with diffs - log_configuration_create() - track new resources - log_configuration_delete() - track deletions - log_configuration_rollback() - track rollbacks - log_hot_reload() - track reload events - get_validation_error_rate() - metrics - get_hot_reload_success_rate() - metrics - get_rollback_count() - metrics Security fixes: - _validate_identifier() - prevents SQL injection in table/db names - _validate_positive_integer() - validates integer parameters - All SQL queries use parameterized values - Backtick quoting for validated identifiers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(tz-ui): add TensorZero Config React UI components Adds React components for TensorZero configuration management: - TensorZeroConfigEditor - TOML editor with syntax highlighting - TensorZeroValidationPanel - real-time validation feedback - TensorZeroChangeHistory - audit trail with diffs - TensorZeroMetricsDashboard - validation and reload metrics Dependencies: - Added Monaco Editor for TOML syntax highlighting - Added React Query for data fetching - Added Recharts for metrics visualization 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Codex Agent <codex-agent@example.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> * feat: Voice Cloning + AgentGym RL Coordinator Merged with all fixes from CodeRabbit, CodeQL, and SQL Policy Lint reviews. All 31 comments addressed: - 3 Critical issues fixed (missing import, UNIQUE constraint, path traversal) - 6 Major issues fixed (efficient counting, response validation, RLS security) - 4 Minor issues fixed (dashboard clarity, resource leaks) - 18 Nitpicks addressed (style, logging patterns, exception handling) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Codex Agent <codex-agent@example.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* docs: update TensorZero master plan with network segmentation and local-first routing * feat(gateway): implement TensorZero Gateway with security hardening and clickhouse observability * feat(agentgym): add RL coordinator service with NATS and HF integration --------- Co-authored-by: Codex Agent <codex-agent@example.com>
TensorZero: Local-First Architecture & Network Hardening
Summary
This PR transitions TensorZero to a production-ready "Local-First" architecture, implementing the
features/gatewaywith strict 5-tier network segmentation, ClickHouse observability, and a routing hierarchy that prioritizes local/free models. It also introduces theAgentGym-RL Coordinatorfor the simulation-to-reality training loop.Key Changes
1. Local-First Routing Hierarchy
qwen2.5:32b,qwen3-embedding) - Always try first.llama-3-8b).2. Security Hardening
api_tier,data_tier,app_tier,bus_tier.65532(distroless) or101(service specific).cap_drop: [ALL]applied universally.3. New Services
features/gateway(TensorZero + ClickHouse).pmoves/services/agentgym-rl-coordinatorwith NATS & Hugging Face integration (HF_TOKENauth).Pmoves-hyperdimensionsserved via unprivileged Nginx.4. Integration
docs/PMOVES_TensorZero_Implementation.mdwith service integration matrix.Verification
chatfunction falls back from Ollama -> Cloudflare -> Gemini.geometry.event.v1.Summary by CodeRabbit
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.