feat: port BuzzLLM from Python to Rust with v2.1 LlmClient trait + coding agent tools - #3
Conversation
rust/ - Cargo.toml with all deps (clap, reqwest, tokio, bollard, scraper, etc.) - src/types.rs: LlmOptions, RequestArgs, StreamResponse, ToolCallData - src/providers/: 4 providers (openai-chat, openai-responses, anthropic, vertexai-anthropic) - src/llm.rs: invoke_llm loop with SSE streaming, tool execution, iteration cap - src/output.rs: print_to_stdout with ANSI colors, SSE mode, brief mode - src/tools/: Tool trait, ToolRegistry with cleanup, codesearch/websearch/pythonexec - src/prompts/: 6 prompt templates via include_str!, get_prompt() + prompt_names() - src/main.rs: clap CLI matching Python interface, logging to /tmp/buzzllm.logs - .gitignore for target/ .dingllm/prds/v2/ - 10 PRDs (000-009) documenting full migration plan AGENTS.md - Repo-specific agent instructions
.dingllm/specs/v2/ - 001_context_flowchart_buzzllm.mmd: L1 system context (actors + external services) - 002_container_flowchart_buzzllm.mmd: L2 containers (binary + Docker + APIs + logs) - 003_component_flowchart_buzzllm.mmd: L3 modules (main, providers, tools, llm, output, prompts) - 004_component_sequence_chat_flow.mmd: L3 chat sequence (CLI -> invoke_llm -> SSE -> tools -> loop) - 005_component_sequence_tool_execution.mmd: L3 tool execution (concurrent dispatch, DDG fallback, Docker lifecycle) - _manifest.md: diagram index with source file cross-references - serve.py: Mermaid diagram viewer All 5 diagrams validated with Playwright (SVG renders, zero errors)
rust/Cargo.toml, rust/Cargo.lock - Add dev-dependencies: tempfile, assert_cmd, predicates, tokio-test rust/src/lib.rs - Add library target to enable integration tests rust/src/main.rs - Import from lib crate instead of declaring modules directly - Add 12 inline CLI arg parsing tests rust/tests/ - test_providers.rs: 53 tests — request builders, SSE parsers, message assemblers for all 4 providers; create_client, tool_schema_format, default_api_url - test_tools.rs: 28 tests — write_file (create, edit, not-found, multi-match, path validation), bash (simple, timeout, empty, failing), codesearch (find, ripgrep, read with pagination), tool registry - test_types_prompts.rs: 13 tests — LlmOptions, StreamResponse, ToolCallData, prompt resolution - test_output.rs: 12 tests — all StreamResponseType variants, SSE mode, brief mode - test_e2e.rs: 8 tests — help, provider validation, real API call, SSE format All 126 pass, zero warnings.
Babysit PR — StatusPR #3: feat: port BuzzLLM from Python to RustState: OPEN | Mergeable: MERGEABLE | CI: All green on CI: All passing
Resolved
Review status
Ready to mergeNo blocking reviews. CI green. Merge state CLEAN. — Bazinga PR Babysitter |
…/fmt cleanup rust/src/providers/ - Replace Provider enum with LlmClient trait + ToolSchemaFormat - 4 struct impls: OpenAIChatClient, OpenAIResponsesClient, AnthropicClient, VertexAIAnthropicClient - create_client() factory, default_api_url() per provider - --url stays as optional flag (overrides default) rust/src/tools/ - write_file: exact string replace, new file creation, CWD-safe - bash: shell command execution, timeout 1-120s rust/src/prompts/ - coding.txt: 5-tool agent system prompt rust/src/main.rs - Use create_client() instead of Provider::from_str() - tool_schema_format() replaces is_anthropic_format() - Register coding prompt tools rust/src/llm.rs - invoke_llm takes &dyn LlmClient instead of &Provider .github/workflows/ci.yml - Build (debug + release), Test (--test-threads=1), Clippy, Fmt clippy fixes: regex out of loop, manual_clamp, Default derives, writeln cargo fmt applied across all sources
Code Review (re-review 4)Decision:
Breaking Changes
Change Size
~6254 SLOC source (excl. Cargo.lock), 48 files. A full rewrite is inherently large; scope is coherent. Only v2.1 features (F4) are scope creep. Test Integrity
Spec Compliance
Action Items
DetailsPython used Spec gap.
DetailsPRD 000:92 states "No new features beyond current Python parity." Outside spec scope.
— Reviewed by Coding Agent (re-review 4, 13 commits — 5 findings resolved; F2 remains as only HIGH) |
|
[bazinga] Summary of code-review findings after automated triage: Resolved (7/13):
Not auto-fixable (6 remaining):
Acknowledged:
|
Addresses code-review items #11 (assembler tests) and #13 (stale diagrams)
- F10: +9 codesearch tests (path validation x4, pagination x4, directory filter) - F6: +15 websearch tests (schema x6, html_to_markdown x8, edge case x1) - html_to_markdown made pub for integration test access
Summary
.dingllm/specs/v2/(5 diagrams, all browser-validated)LlmClienttrait replacesProviderenum dispatch — 4 implementations (OpenAI Chat, OpenAI Responses, Anthropic, Vertex AI Anthropic)write_file(exact string replace),bash(shell commands),read_file(reuses BashRead)codingsystem prompt — 5-tool agent (read_file, write_file, bash, search_web, scrape_webpage)--urlis now optional (each provider hasdefault_api_url(); override for vLLM/proxies/region endpoints)tracingto/tmp/buzzllm.logs, controlled byLOGGING_LEVELenvTest plan
Unit tests
Note: tool tests require
--test-threads=1becauseset_current_diris a process-level global andTempDirCWD changes conflict under parallel execution.Real API smoke
Known limitations
pythonexectools not tested (Docker container required)websearchtools rely on live DuckDuckGo/Brave — flaky in CI, no mocked tests yet--test-threads=1(CWD is process-global)Specs
.dingllm/prds/v2/(000-009) +.dingllm/prds/v2.1/(010-014).dingllm/specs/v2/(C4 L1-L3 + sequence diagrams)