Files
OpenViking/.pr_agent.toml
T
Qin Haojie c0b0be4f4c fix(session): align async commit API docs and examples (#1188)
Update docs, tests, and example integrations to reflect accepted + task_id
session commits with task polling for completed results.

Also fix the local PR-Agent model provider prefix in .pr_agent.toml.
2026-04-02 21:09:01 +08:00

355 lines
17 KiB
TOML

# =============================================================================
# Qodo PR-Agent Configuration for OpenViking
# =============================================================================
# OpenViking: polyglot (Python/TypeScript/Rust) context database for AI agents.
# By ByteDance/Volcengine — AGPL-3.0 licensed.
#
# Rules derived from: real bug history (PRs #505, #728, #749, #740/#745),
# codebase conventions, CI pipeline (ruff, mypy, pytest), and Qodo best
# practices (Rule System blog, 2.2 PR History, raw configuration.toml).
#
# Principle: edit only what you need (Qodo Tip #1). Every override here has
# a documented reason tied to OpenViking's specific patterns.
# =============================================================================
# ---------------------------------------------------------------------------
# Global Config
# ---------------------------------------------------------------------------
[config]
output_relevant_configurations = false
# Use Ark token-billed Chat API via LiteLLM's OpenAI-compatible provider.
# Without the `openai/` prefix, PR-Agent fails with:
# "LLM Provider NOT provided" and skips review/improve generation.
model = "openai/doubao-seed-2-0-code-preview-260215"
fallback_models = []
custom_model_max_tokens = 256000
# Use high reasoning for this complex polyglot codebase with subtle async/
# concurrency bugs. Worth the extra latency for quality.
reasoning_effort = "high"
# More context around hunks helps the model understand memory pipeline flows
# that often span multiple functions.
patch_extra_lines_before = 8
patch_extra_lines_after = 3
allow_dynamic_context = true
# Auto-detect language from PR content (Chinese contributors are common)
response_language = "en-US"
# Custom labels for OpenViking-specific PR categorization
enable_custom_labels = true
# ---------------------------------------------------------------------------
# Ignore: skip generated/vendored/lock files from analysis
# Reduces noise and token waste on files humans don't review.
# ---------------------------------------------------------------------------
[ignore]
glob = [
# Lock files (auto-generated, not human-authored)
'uv.lock',
'*.lock',
'package-lock.json',
# Third-party vendored code (not our responsibility)
'third_party/**',
# Rust build artifacts
'target/**',
# Test data fixtures (binary/large JSON blobs)
'db_test_*/**',
'test_data/**',
'test_data_sync/**',
# Worktree scratch spaces
'.worktrees/**',
# Build support (C++ profiles, not core logic)
'build_support/**',
]
# ---------------------------------------------------------------------------
# Auto-triggers on PR open
# ---------------------------------------------------------------------------
[github_app]
pr_commands = [
"/describe",
"/review",
"/improve --pr_code_suggestions.commitable_code_suggestions=false",
]
push_commands = [
"/describe",
"/review --pr_reviewer.remove_previous_review_comment=true",
"/improve --pr_code_suggestions.commitable_code_suggestions=false",
]
# ---------------------------------------------------------------------------
# Custom Labels: OpenViking-specific PR categorization
# Each description is a conditional statement (Qodo best practice) so the
# model knows exactly when to apply it.
# ---------------------------------------------------------------------------
[custom_labels."memory-pipeline"]
description = "Apply when the PR modifies memory extraction, deduplication, archival, or any code in openviking/session/ that touches MemoryCategory, SessionCompressor, MemoryDeduplicator, or MemoryExtractor."
[custom_labels."async-change"]
description = "Apply when the PR modifies async/await patterns, changes commit() to commit_async(), adds asyncio.gather/TaskGroup usage, or modifies any coroutine in the session or storage layer."
[custom_labels."embedding-vectorization"]
description = "Apply when the PR modifies embedding models, vectorization logic, chunked vectorization, or VLM provider integrations in openviking/embedding/ or openviking/vlm/."
[custom_labels."plugin-bot"]
description = "Apply when the PR modifies TypeScript code in bot/ or examples/openclaw-plugin/, including hook handlers, process management, or client initialization."
[custom_labels."api-breaking"]
description = "Apply when the PR removes, renames, or changes the type of any public API parameter, REST endpoint, SDK method, or configuration key that external consumers depend on."
[custom_labels."multi-tenant"]
description = "Apply when the PR modifies authentication, authorization, account/user routing, root key handling, or RequestContext identity resolution."
[custom_labels."retrieval"]
description = "Apply when the PR modifies the retrieval pipeline: find, rerank, semantic search, or context level (L0/L1/L2) scoring logic."
[custom_labels."rust-cli"]
description = "Apply when the PR modifies Rust source files (src/*.rs) or Cargo.toml for the CLI tool."
# ---------------------------------------------------------------------------
# Review Tool
# ---------------------------------------------------------------------------
[pr_reviewer]
persistent_comment = true
final_update_message = true
# Increased from default 3 → 8 because OpenViking PRs often span multiple
# subsystems (Python core + TypeScript bot + config) with cross-cutting concerns.
num_max_findings = 8
enable_intro_text = true
enable_help_text = false
publish_output_no_suggestions = true
# --- Feature toggles (overrides from defaults) ---
require_score_review = true # Score each PR 1-100 (disabled by default, useful for quality tracking)
require_tests_review = true # Check if tests are present (default: true)
require_estimate_effort_to_review = true # Effort estimate label (default: true)
require_can_be_split_review = true # Flag large PRs that should be split (default: false → enabled)
require_security_review = true # Dedicated security audit section (default: true)
require_todo_scan = true # Surface TODO/FIXME/HACK in changed code (default: false → enabled)
require_ticket_analysis_review = true # Check ticket compliance if linked
# --- Labels ---
enable_review_labels_security = true
enable_review_labels_effort = true
extra_instructions = """\
You are reviewing OpenViking — an agent-native context database.
Stack: Python 3.10+ core (FastAPI, pydantic, httpx, loguru), TypeScript bot
(Vikingbot/OpenClaw plugin), Rust CLI, C++ extensions (AGFS).
## Severity Classification (exactly ONE per finding)
[Critical] — Blocks release. Security vulnerability, data loss/corruption, crash in
production path, resource leak without cleanup, auth bypass.
[Bug] — Must fix before merge. Logic error, behavioral regression, API contract
violation, race condition, missing await on coroutine, silent exception swallowing.
[Perf] — Performance regression. O(n²)+ algorithmic complexity, unbounded collection
growth, N+1 queries against VikingDB, redundant embedding/VLM API calls,
unnecessary large object copies in hot paths.
[Suggestion] — Recommended improvement. Missing tests, dead code, naming inconsistency,
poor observability (missing telemetry/logging), unclear intent, unrelated changes in PR.
## Rules (structured as: WHEN condition → THEN check → BECAUSE rationale)
### PYTHON CORE (openviking/, openviking_cli/)
R1. ASYNC DISCIPLINE
WHEN code is inside an async function or coroutine
THEN verify all I/O calls use async variants (commit_async not commit,
httpx.AsyncClient not requests, async for on streams)
BECAUSE blocking calls in async context starve the event loop.
Real bug: PR #728 replaced blocking commit() with commit_async().
Also check: missing `await` on coroutine calls (silent bug — returns
coroutine object instead of result).
R2. MEMORY PIPELINE COMPLETENESS
WHEN code touches MemoryCategory, MemoryExtractor, MemoryDeduplicator,
SessionCompressor, or MemoryArchiver
THEN verify all 6 categories are handled: PREFERENCES, ENTITIES, PATTERNS,
EVENTS, TOOLS, SKILLS. Check that match/if-elif chains on DedupDecision
(KEEP/MERGE/DELETE/SKIP) are exhaustive.
BECAUSE partial handling silently drops memories. The 6-category model is
a core invariant of the extraction pipeline.
R3. QUADRATIC REPROCESSING GUARD
WHEN code enqueues items (SemanticMsg, embedding tasks) inside a loop that
also processes the queue, or when a callback re-enqueues work
THEN flag as [Perf] or [Bug] — this pattern causes O(n²) reprocessing.
BECAUSE PR #505 fixed exactly this: misdirected SemanticMsg enqueue inside
a processing loop caused quadratic growth.
R4. VLM/EMBEDDING API RESILIENCE
WHEN code calls VLM providers (OpenAI, Doubao/Ark, Gemini) or embedding APIs
THEN verify: (a) timeout is set (ai_timeout or explicit), (b) retry/fallback
exists for transient failures, (c) streaming responses handle partial
failure gracefully, (d) JSON output uses json-repair not raw json.loads.
BECAUSE PR #740 was reverted (#745) due to streaming response issues, then
re-landed in #756 with proper handling. This is a repeat-risk area.
R5. TYPE SAFETY
WHEN new Python code is added or modified
THEN check: no bare `type: ignore` (must have explanation comment), consistent
Optional[X] vs X|None style within each file, proper use of
TYPE_CHECKING imports for circular dependency avoidance.
BECAUSE CI enforces ruff + mypy on changed files. Suppressions without
rationale hide real type errors.
R6. LICENSE HEADERS
WHEN a new .py file is created in openviking/ or openviking_cli/
THEN it MUST contain at the top:
# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd.
# SPDX-License-Identifier: AGPL-3.0
BECAUSE AGPL-3.0 compliance requires headers on all source files.
Every existing file in these directories follows this convention.
R7. ERROR HANDLING
WHEN code uses try/except
THEN verify: no bare `except:` or `except Exception:` without logging (loguru)
or re-raising. Narrow exceptions to specific types where possible.
BECAUSE PR #148f6e3 fixed overly broad `except Exception` to specific
(ImportError, ModuleNotFoundError, AttributeError). Broad catches hide
real bugs.
### TYPESCRIPT / BOT (bot/, examples/openclaw-plugin/)
R8. PLUGIN HOOK TIMEOUT
WHEN code registers or modifies a hook handler (before_prompt_build,
after_prompt_build, etc.) or calls getClient()
THEN verify the call has timeout protection (Promise.race with timeout,
AbortController, or equivalent).
BECAUSE PR #749 added timeout protection to getClient() after discovering
hooks could hang indefinitely, blocking the entire bot.
R9. PROCESS LIFECYCLE
WHEN code spawns child processes or manages bot lifecycle
THEN verify: SIGTERM/SIGINT handlers exist, stdio streams are properly
closed, and cleanup runs in all exit paths (including uncaught exceptions).
BECAUSE the bot uses process-manager.ts for lifecycle; leaked processes or
file descriptors degrade the host system.
### CROSS-CUTTING
R10. API BACKWARD COMPATIBILITY
WHEN a PR modifies public interfaces (FastAPI endpoints, SDK client params,
RequestContext fields, config keys in ov.conf)
THEN verify: existing params are not removed or renamed (only deprecated),
new params have defaults, multi-tenant changes preserve single-tenant
behavior as the default path.
BECAUSE PR #767 added account/user params — these must be optional to avoid
breaking existing single-tenant deployments.
R11. CONCURRENCY SAFETY
WHEN code modifies shared mutable state (dicts, lists, sets) in async
functions, or uses _pending_semantic_changes or similar shared structures
THEN verify proper synchronization (asyncio.Lock, thread-safe collections)
and that no produce-and-consume-in-same-loop pattern exists.
BECAUSE the SessionCompressor._pending_semantic_changes dict is accessed
from multiple async paths; unsynchronized access causes data races.
R12. RETRIEVAL PIPELINE INTEGRITY
WHEN code modifies find/rerank/search logic or ContextLevel scoring (L0/L1/L2)
THEN verify: rerank is optional (PR #754 fixed find-without-rerank), level-2
scores are preserved through the pipeline, and search results maintain
their ranking order.
BECAUSE PR #754 fixed a bug where find() required rerank and level-2 scores
were silently dropped.
R13. TESTING REQUIREMENTS
WHEN a PR fixes a bug → it MUST include a regression test or explicitly
explain in the PR description why one is impractical.
WHEN a PR adds a feature → it SHOULD include unit tests for the happy path
and at least one error/edge case.
WHEN a PR modifies embedding/VLM integration → verify test isolation (no
hardcoded API keys — construct test keys dynamically as in PR #148f6e3).
BECAUSE the repo uses pytest; test patterns should use fixtures, not globals.
R14. DOCUMENTATION CONSISTENCY
WHEN a PR modifies docs/ (en/ and zh/cn/ and ja/) or README files
THEN verify all language versions are updated consistently. Flag if only
one language is updated when the content change is substantive.
BECAUSE the repo maintains en/zh/ja translations (PR #755 added Japanese docs).
R15. TELEMETRY & OBSERVABILITY
WHEN code adds or modifies operations that call external services (VLM, embedding,
VikingDB) or processes memories
THEN verify telemetry integration exists (get_current_telemetry pattern) and that
timing/count metrics are recorded for the operation.
BECAUSE PR #735 added memory extract telemetry breakdown — new operations
should follow this pattern for production observability.
## Output Format
Be specific: reference exact variable names, function calls, line numbers.
When suggesting a fix, include a minimal code block.
Match PR language (Chinese PR → Chinese review, English PR → English review).
"""
# ---------------------------------------------------------------------------
# Improve Tool (code suggestions)
# ---------------------------------------------------------------------------
[pr_code_suggestions]
commitable_code_suggestions = false
persistent_comment = true
focus_only_on_problems = true
# Filter low-confidence suggestions. 0 = show all, 7+ = high quality only.
# Set to 5 to balance signal-to-noise for this codebase.
suggestions_score_threshold = 5
# Extended mode for thorough analysis of large PRs
auto_extended_mode = true
num_code_suggestions_per_chunk = 4
max_number_of_calls = 3
parallel_calls = true
extra_instructions = """\
Focus suggestions on these OpenViking-specific anti-patterns:
1. BLOCKING IN ASYNC: Replace `commit()`, `requests.get()`, `time.sleep()` with
`commit_async()`, `httpx.AsyncClient`, `asyncio.sleep()` inside async functions.
2. QUADRATIC LOOPS: Simplify nested loops over memory categories or semantic queues.
If an inner loop re-processes items already in the outer loop, suggest flattening
or using a set-based approach.
3. PROMPT CONSTRUCTION: Extract repeated LLM prompt strings into Jinja2 templates
(the dependency exists in pyproject.toml). Inline f-string prompts over 5 lines
should be templated.
4. LOGGING: Replace `print()` with `logger = get_logger(__name__)` (loguru pattern
used throughout the codebase). Include structured context in log messages.
5. VALIDATION: Prefer pydantic models for API request/response validation over raw
dicts. The codebase already depends on pydantic>=2.0.0.
6. API RESILIENCE: Flag any VLM/embedding API call missing timeout or retry logic.
Suggest wrapping with httpx timeout config or litellm retry patterns.
7. RESOURCE CLEANUP: Ensure context managers (async with) are used for DB connections,
HTTP clients, and file handles. Flag bare open() without context manager.
"""
# ---------------------------------------------------------------------------
# Describe Tool
# ---------------------------------------------------------------------------
[pr_description]
generate_ai_title = false
use_bullet_points = true
add_original_user_description = true
enable_pr_type = true
enable_pr_diagram = true
enable_semantic_files_types = true
collapsible_file_list = 'adaptive'
collapsible_file_list_threshold = 8
enable_large_pr_handling = true
include_generated_by_header = true
publish_labels = true
final_update_message = true
extra_instructions = """\
For OpenViking PRs, structure the description to include:
- **Layer affected**: core (Python), bot (TypeScript), CLI (Rust), AGFS (C++/Go), or docs.
- **Backward compatibility**: state whether existing APIs, config keys, or SDK params are affected.
- **Memory pipeline impact**: if session/ is touched, list which of the 6 memory categories
(PREFERENCES, ENTITIES, PATTERNS, EVENTS, TOOLS, SKILLS) are affected.
- **Multi-tenant impact**: if auth/identity is touched, note whether single-tenant default is preserved.
"""