78 Commits

Author SHA1 Message Date
zephyrq-z ab694a38ed feat: add Baidu Qianfan provider and update provider list (#188) 2026-06-23 15:22:12 +08:00
kite dc93166205 feat(rules): add dedicated review rules for GitHub Actions and GitHub config YAML
The generic YAML rule only checked spelling in keys, which is insufficient
for CI/CD workflow files. Add layered rules with security, correctness,
reliability checks for .github/workflows/ and structure validation for
other .github/ config files (issue templates, release config).
2026-06-22 17:59:16 +08:00
kite 2f3ed41009 refactor(agent): split agent.go into util.go and compression.go, fix compression bugs
Extract utility functions (stripEmptyPlanBlock, stripMarkdownFences,
buildMessageXML, copyMessages, countMessagesTokens, reviewModeString,
detectGitBranch) into util.go and all compression logic into compression.go
to improve readability (agent.go: 1489 → 1114 lines).

Fix pre-existing compression bugs from commit 14adf6f:
- Return unmodified messages on compression failure instead of truncating
  to frozen zone (which discarded all conversation context)
- Check error in async compression goroutine to avoid applying failed results
- Track snapshot length to append post-snapshot messages when applying async
  compression, preventing silent message loss
- Strip old <previous_review_summary> before appending new one to prevent
  cumulative frozen zone bloat across multiple compressions
- Guard pendingJob cleanup to only clear when it matches the completed job,
  preventing accidental clearing of a newly scheduled job
- Add context.Context and 5s timeout to detectGitBranch
- Deep copy ToolCalls in copyMessages to match session/history.go
- Reuse finalCount in addNextMessage to avoid redundant token counting
2026-06-21 21:20:40 +08:00
kite b74e5bd53f refactor(template): extract prompt strings into standalone .md files
Move all LLM prompt content from inline JSON strings in task_template.json
to individual Markdown files under prompts/, following the same embed.FS
pattern used by internal/config/rules/. This improves maintainability by
enabling native syntax highlighting, cleaner diffs, and separation of
prompt content from runtime configuration.

Also removes two dead config fields (TOOL_REQUEST_WAIT_TIME_MS,
MAX_SUBTASK_EXECUTION_TIME_MINUTES) that had no runtime consumers.
2026-06-21 21:20:40 +08:00
wxwxwxw_orange 1793de0ff2 Feat/add dashscope tokenplan provider (#155) 2026-06-19 07:47:26 +08:00
MuoDoo 75c612e973 Merge pull request #168 from PreethamNoelP/fix/session-file-permissions-cwe-732
fix(session): restrict session dir and file permissions to owner-only
2026-06-17 17:20:38 +08:00
PreethamNoelP 44c1abc8cd fix(session): restrict session dir and file permissions to owner-only
Session directories were created with 0755 (rwxr-xr-x) and session
files with 0644 (rw-r--r--), making them readable by any local user
on shared systems such as multi-user servers and CI runners.

Session JSONL files contain full LLM request and response data,
including the complete source code diff, file contents read by the
file_read tool, and the model's analysis — all sensitive material.

Change MkdirAll mode from 0755 to 0700 and OpenFile mode from 0644
to 0600, restricting access to the file owner only. This matches the
0600 permission already used for the config file (which holds the API
key) in cmd/opencodereview/provider_cmd.go.

Fixes #144
2026-06-17 12:45:31 +05:30
wxwxwxw_orange 257f9ac105 feat(llm): add glm-5.2 to z-ai provider models (#163) 2026-06-17 11:46:14 +08:00
Jiale Li c673c9475a feat:add --model flag to override LLM model per review (#122) 2026-06-16 22:38:52 +08:00
wxwxwxw_orange 16c7734af8 feat(llm): add Tencent TokenHub and Hunyuan Token Plan providers (#142) 2026-06-16 19:54:22 +08:00
kite 0a7d14e453 fix: remove duplicate kimi provider and fix test locale
Remove the duplicate kimi provider entry introduced by overlapping PRs
(#130 and #134). Keep the Kimi Moonshot API entry with MOONSHOT_API_KEY.

Set LC_ALL=C in Makefile test target to ensure git outputs English
messages regardless of system locale.
2026-06-15 15:32:53 +08:00
wxwxwxw_orange 2bde478993 feat(llm): add volcengine and kimi providers (#134)
* feat(llm): add volcengine and kimi providers
Add pay-as-you-go OpenAI-compatible presets for Volcano Engine Ark
and Kimi Moonshot API.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Apply suggestions from code review

Co-authored-by: lizhengfeng <lizhengfeng.lzf@alibaba-inc.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: lizhengfeng <lizhengfeng.lzf@alibaba-inc.com>
2026-06-15 15:23:19 +08:00
MuoDoo 86380286be fix: sort provider selection list (#135) 2026-06-15 14:55:41 +08:00
DanielWalnut 3236a610ec fix: remove sonnet 4.7&4.8 (#133) 2026-06-15 12:53:48 +08:00
kite 7c0b70b02b test(diff): add unit tests for readWorkspaceFileForDiff
Cover all key branches: regular file read, path traversal rejection,
directory rejection, parent symlink escape, external/internal symlink
target handling, and nonexistent file error.
2026-06-15 11:51:51 +08:00
不许对我狗叫丶 3b68c93013 feat: add Kimi provider (#130)
* feat: add build-in kimi provider

Co-authored-by: lizhengfeng <lizhengfeng.lzf@alibaba-inc.com>
2026-06-15 11:50:25 +08:00
不许对我狗叫丶 17c5edca8a feat: add minimax provider (#131)
* feat: add build-in minimax provider


Co-authored-by: lizhengfeng <lizhengfeng.lzf@alibaba-inc.com>
2026-06-15 11:49:14 +08:00
不许对我狗叫丶 957132e3b6 fix: change mimo token plan url to api url and add mimo flash model (#132) 2026-06-15 09:57:04 +08:00
MuoDoo 4b3f41df10 Fix workspace symlink diff containment (#125)
* Fix workspace symlink diff containment

* Share repository path containment helpers
2026-06-15 00:03:36 +08:00
不许对我狗叫丶 6b8d269c0b feat: add mimo provider (#124) 2026-06-14 22:31:30 +08:00
ZheNing Hu 283ec8558c fix(diff): detect renamed and deleted files correctly in diff parsing (#105)
When a file was renamed on the target branch, ocr review emitted
'[ocr] WARNING: cannot read file <old path> at ref <to>: exit status 128'.

Two compounding bugs:

1. The parser required 'a/'/'b/' prefixes when matching '--- /dev/null' /
   '+++ /dev/null', but git emits these lines without prefixes, so
   IsNew/IsDeleted were never set and deleted files fell through to a
   doomed 'git show ref:<old path>'.

2. 'rename from' / 'rename to' extended headers were never parsed, and
   git diff/show call sites did not force rename detection, so renames
   degraded to delete+add whenever the user had diff.renames=false.

Fixes:
- Parse 'rename from'/'rename to', 'new file mode', 'deleted file mode'
  and unprefixed /dev/null markers in ParseDiffText.
- Pass --find-renames to all git diff/show invocations so rename
  detection no longer depends on user config.
- Add IsRenamed to model.Diff (json: is_renamed) and prefer it in
  diffStatus.
- Add parser unit tests and a range-mode rename regression test.

Fixes #99
2026-06-14 22:29:02 +08:00
kite 72aad2c77c feat: add interactive provider setup with TUI and documentation 2026-06-14 10:49:33 +08:00
MuoDoo 64552aee9b fix(security): block git ref option injection (#112) 2026-06-13 11:07:59 +08:00
MuoDoo 9f81cbe486 fix(tool): constrain workspace file reads to repo (#109) 2026-06-12 17:57:28 +08:00
Daniel Grießhaber c2c7c37e0f fix(agent): user includes should have higher priority than system supported extensions (#51) 2026-06-12 14:29:47 +08:00
kite 01c9c85456 feat: add review filter to remove provably incorrect comments after subtask
- Add REVIEW_FILTER_TASK template and LLM conversation config
- Implement executeReviewFilter to post-process comments per file
- Add CommentsForPath and RemoveByPathAndIndices to CommentCollector
- Apply timeout from template config to review filter LLM call
- Await CommentWorkerPool before running filter to prevent race condition
- Include raw response preview in filter JSON parse error logs
2026-06-09 20:41:42 +08:00
kite cf32900ca1 fix: force standard diff prefixes to prevent diff.noprefix/mnemonicPrefix from breaking parsing (#82)
Add --src-prefix=a/ --dst-prefix=b/ to all git diff/show calls so that
user config (diff.noprefix, diff.mnemonicPrefix) cannot alter the prefix
format the parser depends on. Also add missing ModeCommit test coverage.
2026-06-09 18:08:11 +08:00
Eldar Shlomi c9fae8d4e9 fix: pass --no-ext-diff --no-textconv to git diff/show so external diff tools don't break parsing (#86)
When a user has configured a global external diff tool (diff.external /
GIT_EXTERNAL_DIFF) or a textconv filter, git diff/show emit the tool's
output instead of unified diff text. The provider's parser keys off
`diff --git` headers, so it parses zero diffs and the review silently
reports "No files changed".

Add --no-ext-diff --no-textconv to all four git diff/show call sites in
internal/diff/git.go (ModeRange diff, ModeCommit show, and both
workspaceTrackedDiff calls). merge-base and ls-files are left untouched
since they don't run the diff machinery.

Adds an integration test that initializes a real git repo, activates a
garbage GIT_EXTERNAL_DIFF script, and asserts the provider still parses
a non-empty diff (fails before this change, passes after).

Closes #82

AI-assisted contribution.
2026-06-09 18:02:01 +08:00
kite 48cc6a3329 feat: change default output language from Chinese to English 2026-06-09 09:57:45 +08:00
Shi Peipei 4043e9ee33 fix: handle previously swallowed json.Unmarshal errors (#78)
- Propagate json.Unmarshal error in buildAnthropicParams when parsing
  tool call arguments, preventing silent empty-map fallback on malformed JSON
- Return explicit error message in ParseComments when comments JSON
  string fails to unmarshal, instead of silently ignoring

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 21:03:00 +08:00
MuoDoo adb9ac8b4e feat(rules): add built-in Rust and Cargo.toml review rules (#74)
* Add Rust review rules

* Fix case-insensitive rule matching
2026-06-08 20:56:00 +08:00
kite fa6c7d8e04 refactor(llm): deduplicate and validate auth header normalization
Export NormalizeAuthHeader from the llm package and remove the duplicate
normalizeConfigAuthHeader in config_cmd.go. Invalid auth_header values
now return an error at configuration time instead of being silently
accepted and causing opaque 401s at runtime.
2026-06-08 20:21:28 +08:00
zhouzhihao 48dc1b37d4 fix(llm): support Anthropic auth header (#77) 2026-06-08 19:35:12 +08:00
kite 1b3c0ab19f fix(llm): handle Anthropic thinking content blocks in multi-turn conversations
Anthropic models with extended thinking return type:"thinking" content
blocks which were silently dropped, causing empty assistant content in
conversation history. Extract thinking blocks into ReasoningContent so
the existing Content() fallback works correctly.
2026-06-07 17:09:31 +08:00
kite 5fad9ce2fa fix(llm): use max_completion_tokens instead of deprecated max_tokens for OpenAI requests
Fixes #30 — newer OpenAI models (o1, o3, o4, gpt-5.x) reject the
deprecated max_tokens parameter with a 400 error.
2026-06-07 08:33:51 +08:00
kite 0d530f3b73 fix(viewer): use real API token usage in session page instead of tiktoken estimates
The session page was showing significantly lower token counts than the console
summary because it used local tiktoken estimation while the console used actual
API-reported usage data. Now SetResponse prefers resp.Usage when available
(falling back to tiktoken), persists cache token fields to JSONL, and the
viewer displays cache read/write stats alongside prompt/completion totals.
2026-06-06 21:17:47 +08:00
kite f24334deb2 perf(tool): stream file reads line-by-line to avoid full-file memory allocation
Replace os.ReadFile + strings.Split with bufio.Reader streaming in
FileReadProvider, so only the requested window (up to 500 lines) is kept
in memory instead of the entire file. Adds Runner.Stream for semaphore-
aware stdout piping, FileReader.ReadLines for line-windowed reading, and
validates invalid line ranges. Reduces per-goroutine memory from ~8MB to
~44KB for large files under concurrent workloads.
2026-06-06 20:59:05 +08:00
kite 2bebc86cfc feat(config): increase default max tool call rounds from 20 to 30
Allow more thorough analysis per file by raising MAX_TOOL_REQUEST_TIMES.
2026-06-06 20:35:32 +08:00
kite ef46dfdac9 feat(tool): add global git subprocess concurrency limiter and propagate context.Context to diff layer
Introduce gitcmd.Runner with channel-based semaphore to cap concurrent
git subprocesses (default 16, configurable via --max-git-procs). Route
all tool-layer and diff-layer git calls through the shared runner.
Also fix diff.Provider.runGit lacking context.Context — now the full
chain (GetDiff → MergeBase → ParseDiffText → finalizeDiff) propagates
the caller's context for proper cancellation and timeout support.
2026-06-06 20:20:34 +08:00
kite 363d971916 fix(tool): make Registry and DiffMap concurrency-safe via freeze semantics
Registry was a plain map alias and DiffMap a shared map[string]string,
both relying on implicit write-before-read ordering with no compile-time
safety. Refactor Registry into an encapsulated struct with Freeze() that
panics on post-freeze writes, and wrap DiffMap as an immutable value type
with defensive copy on construction. Move DiffMap injection to before
filterDiffs to preserve the original behavior of exposing all file diffs.
2026-06-06 19:41:11 +08:00
kite 08bb28ced5 feat(llm): enable Anthropic prompt caching and fix token accounting
Add cache_control ephemeral breakpoints on system prompt and tool
definitions to activate Anthropic prompt caching for multi-turn
agent loops. Fix token double-counting by removing the redundant
totalTokensUsed accumulator and computing it from sub-items. Surface
cache read/write statistics in both text and JSON summary output.
2026-06-06 19:26:34 +08:00
kite 828fc6cae7 fix(tool): propagate context.Context to all tool providers to enable subprocess cancellation
Add ctx parameter to Provider.Execute interface and propagate it through
FileReader.Read, code_search.gitGrep/runGitGrep, and file_find.listGitFiles.
This ensures parent task cancellation/timeout properly terminates running
git subprocesses (grep, show, ls-files, ls-tree). Also adds 10s timeout
to file_find and fixes context.Canceled handling in code_search.
2026-06-06 19:26:34 +08:00
kite aa86d9fa60 fix(rules): align test expectations with English rule docs and isolate global config
Rule doc files were translated from Chinese to English but tests still
expected Chinese substrings. Also added HOME isolation to prevent the
user's ~/.opencodereview/rule.json from interfering with system-default
rule assertions.
2026-06-06 19:26:34 +08:00
kite 7d75c3a9d3 refactor(llm): replace hand-rolled HTTP clients with official Anthropic and OpenAI SDKs
Migrated internal/llm from manual net/http implementation to anthropic-sdk-go v1.47.0
and openai-go/v3 v3.39.0, reducing ~400 lines of retry, request-building, and streaming
code. Simplified LLMClient interface to single CompletionsWithCtx method. Fixed Anthropic
auth to use WithAuthToken (Bearer) instead of WithAPIKey (X-Api-Key) for proxy compatibility.
Fixed OpenAI message builder to use ExtractText() for proper []ContentBlock handling.
2026-06-06 19:26:34 +08:00
kite 18e52f5555 fix(tool): add 10s timeout to code_search git grep to prevent blocking on slow I/O 2026-06-06 15:16:48 +08:00
kite 8e9772baa8 fix(llm): add context support to StreamCompletion and memory compression to prevent infinite timeouts
StreamCompletion used http.NewRequest without context and retry with
context.Background(), making streaming calls uncancellable. Memory
compression called Completions() without context, leaving async
goroutines unable to be cancelled or timed out.

- Add StreamCompletionWithCtx to LLMClient interface and both
  OpenAI/Anthropic implementations
- Propagate context through runCompression, addNextMessage, and
  triggerAsyncCompression call chain
- Add 5-minute timeout cap on async compression goroutines
- Cancel in-flight compression HTTP requests when job is superseded
2026-06-06 13:22:32 +08:00
kite 729c8647b7 fix(tool): use fixed-string matching by default in code_search to fix Linux failures
The code_search tool used -E (extended regex) by default, causing
unmatched parentheses in search patterns (e.g. "func Hello()") to
trigger "Unmatched ( or \(" fatal errors on Linux (GNU regex is strict),
while macOS (BSD regex) silently tolerated them. Since the tool
definition states the default mode is "literal text", switch to -F
(fixed string). Also capture stderr separately so real errors are
surfaced instead of being silently reported as "No matches found".
2026-06-05 23:59:01 +08:00
kite 1534085383 fix(tool): correct git grep argument order for commit/range mode (#53)
The searchText was placed after '--', causing git to interpret it as a
pathspec instead of a pattern. Use '-e' to explicitly mark the search
pattern and place the ref after it. Also replace CombinedOutput with
Output to prevent stderr from polluting result parsing.
2026-06-05 20:38:26 +08:00
kite 8c4463f657 docs(rule): Translated into English 2026-06-05 19:51:06 +08:00
Lei Zhang 95c5d5930e feat: Add HarmonyOS support for .ets files and review configurations (#48)
* feat: add .ets file extension support for HarmonyOS development

* feat: add complete HarmonyOS review support with ArkTS rules, .json5 config, and oh_modules exclusion

- Add arkts.md rule doc with ArkTS-specific and TypeScript general checks
- Add .json5 to supported file types for HarmonyOS config files
- Map .json5 to json.md rules in system_rules.json
- Exclude oh_modules/** (HarmonyOS dependency dir) from review
- Exclude *.test.ets (HarmonyOS test files) from review
- Add unit tests for all new extensions and patterns

* refactor: merge json and json5 glob patterns into single brace expansion
2026-06-05 12:22:11 +08:00