82 lines
3.8 KiB
Markdown
82 lines
3.8 KiB
Markdown
# pragent current architecture
|
|
|
|
Status: pilot implementation, September 2026.
|
|
|
|
## System shape
|
|
|
|
```text
|
|
Gitea pull_request webhook
|
|
│ signed HTTP
|
|
▼
|
|
webhook_server ── trusted base config ──► review_config
|
|
│ bounded worker
|
|
▼
|
|
review_pr facade/orchestrator
|
|
├── entrypoints/gitea fetch diff, reviews, config; publish review
|
|
├── diff_compress reduce prompt context
|
|
├── opencode review orchestration seam
|
|
│ ├── opencode_workspace archive, sanitization, brief, factory
|
|
│ ├── opencode_lens_config reviewer configuration and selection
|
|
│ └── opencode_synthesis normalization, deduplication, summaries
|
|
├── review/budget trusted limits and cumulative accounting
|
|
├── review parsing normalize findings + validate anchors
|
|
├── feedback persist reactions and derive scores
|
|
└── langfuse_trace usage, cost, evaluation telemetry
|
|
```
|
|
|
|
## Seams and responsibilities
|
|
|
|
The external seam is `ai_review.review_pr(...)`: one call represents one review
|
|
attempt and returns success/skip status. The top-level module and
|
|
`review/ai_review.py` are compatibility facades; the current implementation is
|
|
implemented by `review/pipeline.py`, with pure transforms and adapters split
|
|
into the neighboring modules.
|
|
|
|
The internal seams are deliberately narrower:
|
|
|
|
- `review_config.repo_enabled(get, ...)` owns the security-sensitive opt-in
|
|
decision. It receives a transport function, so malformed configuration and
|
|
failure behavior are deterministic in tests.
|
|
- `entrypoints/gitea.request()` and `GiteaClient` own HTTP authentication, JSON
|
|
request encoding, timeout, and Gitea URL construction.
|
|
- `model_client.complete()` owns the legacy Anthropic-compatible request shape.
|
|
`opencode` is the preferred agent adapter and keeps Gitea I/O out of the
|
|
autonomous process. Its sibling modules provide internal seams for workspace
|
|
preparation, lens policy, and synthesis without expanding the caller-facing
|
|
interface.
|
|
- `review/analysis`, `review/output`, `review/configuration`, and
|
|
`review/adapters` keep prompt construction, finding parsing, config filtering,
|
|
rendering, and publishing in focused modules.
|
|
pure transformations. Their callers do not need to know how model or Gitea
|
|
transport works.
|
|
- `langfuse_trace` is an optional sink. It is fail-open and cannot change the
|
|
review result.
|
|
- `review/budget` owns deployment and repository resource limits. The runner
|
|
streams model events and terminates the subprocess after a completed step
|
|
crosses a step, token, duration, or equivalent-cost limit. Cap status is
|
|
retained in review output and Langfuse metadata.
|
|
|
|
## Trust model
|
|
|
|
The review config is read from the PR base branch, never the PR head. The agent
|
|
checkout is treated as hostile: instruction files are removed, credentials are
|
|
not inherited, and the agent only returns text to the Python publisher. Python
|
|
validates finding paths and post-change line anchors before sending comments.
|
|
|
|
## Observability
|
|
|
|
Langfuse is the operational analytics surface. A trace groups runs by
|
|
`owner/repo#PR`; generations carry usage and cost basis; evaluation scores and
|
|
human-feedback scores are attached later. The former SQLite-backed dashboard
|
|
was removed. SQLite remains only as the feedback/evaluation ingestion store.
|
|
|
|
## Removed surface
|
|
|
|
The dashboard server, dashboard data module, dashboard tests, dashboard README,
|
|
and dashboard Kubernetes manifest are intentionally gone. Operators use the
|
|
Langfuse UI for review trends and cost analysis, and Gitea for review details
|
|
and configuration changes.
|
|
|
|
Historical design/implementation plans under `docs/plans/` describe the
|
|
earlier TypeScript framework proposal and are not the runtime architecture.
|