Agent-powered service for CVE analysis, patch backporting, and code upgrade — built on Deep Agents SDK and FastAPI.
| Scenario | Description | Sandbox | Task ID Prefix |
|---|---|---|---|
| Code Upgrade | Upgrade customized code from old upstream version to new | Yes | UPG- |
| CVE Analysis | Analyze whether specific versions are affected by a CVE | Optional | CVA- |
| CVE Backport | Fetch fix patches and backport to target repo | Yes | CVB- |
┌─────────────┐ ┌───────────────────┐ ┌──────────────────┐ ┌─────────────────────┐
│ HTTP Client │────▸│ Controller │────▸│ Task Queue Pool │────▸│ Agent Dispatcher │
│ (API Call) │◂────│ (FastAPI Router) │◂────│ (asyncio.Queue) │◂────│ (Deep Agents SDK) │
└─────────────┘ └───────────────────┘ └──────────────────┘ └──────────┬──────────┘
│ │ │
│ │ ┌─────────┴─────────┐
▼ ▼ │ │
┌─────────────┐ ┌───────────────┐ ┌─────────┐ ┌────────────┐
│ Pydantic │ │ Rejection │ │ Sandbox │ │ Callback │
│ Validation │ │ Policy │ │ (local │ │ channels │
│ + Sanitizer│ │ reject/drop │ │ subprocess)│ │ (registry)│
└─────────────┘ └───────────────┘ └─────────┘ └────────────┘
| Component | Module | Purpose | Docs |
|---|---|---|---|
| Controller | controller/ |
FastAPI routes, request validation, API key auth | OpenAPI |
| Task Queue | queue/ |
Bounded async worker pool with rejection policies | docs/queue.md |
| Agent Dispatcher | agents/ |
Routes tasks to the correct Deep Agent | docs/flow.md |
| Sandbox | sandbox/ |
Local subprocess sandbox (Sandbox-as-Tool pattern) | docs/sandbox.md |
| Tools | tools/ |
CVE query APIs, git command builders, patch helpers | — |
| Skills | skills/ |
SKILL.md files guiding agent behavior | — |
| Middleware | middleware/ |
Prompt injection defense, input sanitization | — |
| Callback | callback/ |
Named callback_channel → registered in-process handler functions |
— |
- Built-in queue pool with bounded async workers, configurable rejection (
reject/drop_oldest), and backpressure (HTTP 429) - Human-readable task IDs like
CVA-20260408-143052-010001instead of opaque UUIDs - Sandbox isolation — local subprocess workspace per task. API keys never enter the sandbox
- Prompt injection defense with multi-layer sanitization on all user input
- Skills-driven agents following the Deep Agents Skills specification
- Callback channels — tasks reference a channel name; handlers are registered as Python callables (e.g.
"wecom","dingtalk","slack")
# Install dependencies
uv sync --all-extras
# Set environment variables
cp .env.example .env
# Edit .env with your API keys
# Run the server
uv run uvicorn oss_agent.main:app --reload
# Run tests
uv run pytest tests/ -v --cov=oss_agent
# Lint
uv run ruff check src/ tests/| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/api/v1/tasks/code-upgrade |
API Key | Submit code upgrade task |
POST |
/api/v1/tasks/cve-analysis |
API Key | Submit CVE analysis task |
POST |
/api/v1/tasks/cve-backport |
API Key | Submit CVE backport task |
GET |
/api/v1/tasks/{task_id} |
API Key | Query individual task status |
GET |
/api/v1/queue/status |
API Key | Global queue statistics |
GET |
/api/v1/health |
None | Health check |
Tasks are assigned human-readable IDs upon submission:
UPG-20260408-143052-010001
│ │ │ │
│ │ │ └── PID suffix (2 digits) + sequence (4 digits)
│ │ └── Time: HH:MM:SS (UTC)
│ └── Date: YYYYMMDD
└── Prefix: UPG (upgrade) / CVA (analysis) / CVB (backport)
curl -X POST http://localhost:8000/api/v1/tasks/cve-analysis \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{"cve_id": "CVE-2024-1234", "versions": ["1.0.0", "2.0.0"]}'Response:
{
"task_id": "CVA-20260408-143052-010001",
"task_type": "cve_analysis",
"status": "pending",
"message": "Task submitted successfully"
}curl http://localhost:8000/api/v1/queue/status -H "X-API-Key: your-key"Response:
{
"is_running": true,
"max_workers": 4,
"queue_depth": 2,
"queue_max_size": 100,
"reject_policy": "reject",
"total_submitted": 15,
"total_completed": 12,
"total_failed": 1,
"total_pending": 1,
"total_running": 1,
"tasks_by_type": {"cve_analysis": 8, "code_upgrade": 5, "cve_backport": 2}
}When the server is running, interactive API documentation is available at:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc - OpenAPI JSON:
http://localhost:8000/openapi.json
All configuration via environment variables (see .env.example):
| Variable | Default | Description |
|---|---|---|
APP_ENV |
development |
Environment (development / production)。通过系统环境变量注入,不在 .env 文件中定义。加载顺序:如果 .env.{APP_ENV} 存在则加载它,否则加载 .env |
APP_LOG_LEVEL |
INFO |
Log level |
APP_WORKERS |
4 |
Number of async queue workers |
APP_QUEUE_MAX_SIZE |
100 |
Maximum queue depth |
APP_QUEUE_REJECT_POLICY |
reject |
Queue full policy: reject (429) or drop_oldest |
OPENAI_API_KEY |
— | LLM API 密钥 (支持 OpenAI 兼容接口;官方 DeepSeek 同样经此变量传入 ChatDeepSeek) |
OPENAI_API_BASE |
— | LLM API 地址 (可选)。官方 DeepSeek 可设为 https://api.deepseek.com/v1 或留空 + 官方模型名见 src/oss_agent/llm.py |
LLM_MODEL |
gpt-4o-mini |
模型名 (config.Settings.llm_model)。官方 DeepSeek 示例:deepseek-chat、deepseek-reasoner;经 OpenRouter 等网关时用网关要求的 id |
SANDBOX_TTL_SECONDS |
3600 |
Sandbox workspace cleanup interval |
API_KEYS |
— | Comma-separated API keys for auth |
cd docker
docker compose up --build| Document | Description |
|---|---|
| docs/sandbox.md | Local subprocess sandbox architecture and security model |
| docs/flow.md | Task lifecycle and agent execution flow |
| docs/queue.md | Queue pool internals, rejection policies, status tracking |
| docs/debug-agent.md | Local scripts/debug_agent.py transcript, subgraph updates, no LLM token stream |
| docs/dependencies.md | Dependency inventory and rationale |
| docs/commit-convention.md | Gitmoji commit message spec |
| AGENTS.md | AI-readable project guide |
src/oss_agent/
├── main.py # App entry + lifecycle
├── config.py # pydantic-settings configuration
├── llm.py # Chat model factory (ChatDeepSeek vs ChatOpenAI; see docstring)
├── controller/ # FastAPI routes + schemas + dependencies
│ ├── router.py
│ ├── schemas.py
│ └── dependencies.py
├── queue/ # Task queue pool + models
│ ├── models.py # AgentTask, TaskResult, TaskType, TaskStatus
│ └── pool.py # TaskQueuePool with rejection policies
├── agents/ # Agent factory, dispatcher, 3 scenario specs
│ ├── factory.py # AgentSpec + AgentFactory
│ ├── dispatcher.py # AgentDispatcher → Deep Agents SDK
│ ├── code_upgrade.py
│ ├── cve_analysis.py
│ └── cve_backport.py
├── tools/ # Host-side tools for agents
│ ├── cve_query.py # NVD + OSV (per-request httpx.AsyncClient, 30s timeout)
│ ├── git_ops.py # Safe git command builders
│ └── patch_ops.py # Patch URL extraction
├── skills/ # SKILL.md files for each scenario
│ ├── code-upgrade/
│ ├── cve-analysis/
│ └── cve-backport/
├── middleware/ # Prompt injection defense
│ └── sanitizer.py
├── sandbox/ # Sandbox lifecycle management
│ └── manager.py
└── callback/ # Callback channel dispatch (registered handlers)
└── notifier.py
tests/
├── conftest.py
├── unit/ # Unit tests for all modules
└── integration/ # API endpoint integration tests
scripts/
├── dev_setup.py # Hooks + local dev helpers
└── debug_agent.py # One-scenario local run; see docs/debug-agent.md
# Install git hooks (pre-commit: ruff format + ruff check --fix on staged files; commit-msg: gitmoji)
uv run python scripts/dev_setup.py
# Run tests with coverage
uv run pytest tests/ -v --cov=oss_agent --cov-report=term-missing
# Lint
uv run ruff check src/ tests/
# Auto-fix lint issues
uv run ruff check --fix src/ tests/
# Format
uv run ruff format src/ tests/
# Type checking
uv run basedpyright
# Optional: run one agent scenario locally (terminal transcript; see docs/debug-agent.md)
uv run python scripts/debug_agent.py cve_analysis
# Security / dependencies (requires dev extras: uv sync --all-extras)
uv run bandit -r src/
uv run pip-auditThis project uses Gitmoji with a Unicode emoji at the start of the subject (not :shortcode:). See docs/commit-convention.md.
✨ Add queue status endpoint
🐛 Fix callback channel validation
♻️ (queue): Refactor rejection policy