Commit Graph

176 Commits

Author SHA1 Message Date
Chummy
2dc9d081e4 fix(shell): recover command args from malformed tool payloads 2026-02-25 01:00:13 +08:00
Chummy
bf1d7ac928 supersede: file-replay changes from #1317
Automated conflict recovery via changed-file replay on latest dev.
2026-02-24 23:46:04 +08:00
reidliu41
56ffcd4477 feat(tool): add background process management tool (spawn/list/output/kill) 2026-02-24 21:53:23 +08:00
reidliu41
d6d32400fa feat(tool): add session-scoped task_plan tool for multi-step work tracking
- Base branch target: dev
  - Problem: ZeroClaw agents have no structured way to decompose complex tasks into trackable steps, falling behind
  every comparable agent runtime
  - Why it matters: Without task tracking, multi-step work is fragile (lost on context compression), invisible to users
   (no progress signal), and error-prone (agent loses track of what's done vs. pending)
  - What changed: Added a session-scoped task_plan tool with create/add/update/list/delete actions, integrated with
  SecurityPolicy, registered in the tool factory
  - What did not change: No config schema changes, no persistence layer, no CLI subcommand, no changes to agent loop or
   any other subsystem

  Label Snapshot

  - Risk label: risk: low
  - Size label: size: S
  - Scope labels: tool
  - Module labels: tool: task_plan
  - Contributor tier label: (auto-managed)
  - If any auto-label is incorrect: N/A

  Change Metadata

  - Change type: feature
  - Primary scope: tool

  Linked Issue

  - Closes #(issue number)
  - Related: N/A
  - Depends on: N/A
  - Supersedes: N/A

  Supersede Attribution

  N/A — no superseded PRs.

  Validation Evidence

  cargo fmt --all -- --check    # pass (no output)
  cargo clippy --all-targets -- -D warnings  # task_plan.rs: 0 warnings (pre-existing warnings in other files
  unrelated)
  cargo test --lib tools::task_plan  # 15/15 passed

  - Evidence provided: test output (15 passed, 0 failed)
  - If any command is intentionally skipped: cargo clippy reports pre-existing warnings in unrelated files
  (onboard/wizard.rs etc.); task_plan.rs itself has zero clippy warnings

  Security Impact

  - New permissions/capabilities? No — uses existing ToolOperation::Act enforcement
  - New external network calls? No
  - Secrets/tokens handling changed? No
  - File system access scope changed? No

  Privacy and Data Hygiene

  - Data-hygiene status: pass
  - Redaction/anonymization notes: No identity data in code or tests. Test fixtures use neutral strings ("step one",
  "do thing", "first")
  - Neutral wording confirmation: All naming follows ZeroClaw/project-native conventions

  Compatibility / Migration

  - Backward compatible? Yes
  - Config/env changes? No
  - Migration needed? No

  i18n Follow-Through

  - i18n follow-through triggered? No — no docs or user-facing wording changes

  Human Verification

  - Verified scenarios: Ran ./target/debug/zeroclaw agent -m "调用 task_plan 工具,action=list" — agent correctly
  identified and called task_plan, returned "No tasks."
  - Edge cases checked: read-only mode blocks mutations, empty task list, invalid action names, missing required
  parameters, create replaces existing list, ID auto-increment after add
  - What was not verified: Behavior with non-CLI channels (Telegram, Discord); behavior with XML-fallback dispatcher
  (non-native-tool providers)

  Side Effects / Blast Radius

  - Affected subsystems/workflows: src/tools/ only — tool factory gains one additional entry
  - Potential unintended effects: Marginally increases tool spec payload size sent to LLM (one more tool definition).
  Could theoretically cause tool name confusion with schedule if LLM descriptions are ambiguous — mitigated by distinct
   naming (task_plan vs schedule) and different description wording.
  - Guardrails/monitoring for early detection: Standard tool dispatch logging. Tool is session-scoped so no persistent
  side effects on failure.

  Agent Collaboration Notes

  - Agent tools used: Claude Code for implementation assistance and review
  - Workflow/plan summary: Implement Tool trait → register in factory → validate with tests → manual agent session test
  - Verification focus: Security policy enforcement, parameter validation edge cases, all 5 action paths
  - Confirmation: naming + architecture boundaries followed (CLAUDE.md §6.3, §6.4, §7.3): Yes

  Rollback Plan

  - Fast rollback command/path: git revert <commit> — removes 3 lines from mod.rs and deletes task_plan.rs
  - Feature flags or config toggles: None needed — tool is stateless and session-scoped
  - Observable failure symptoms: Tool not appearing in agent tool list, or tool returning errors on valid input

  Risks and Mitigations

  - Risk: LLM may occasionally confuse task_plan (action: list) with schedule (action: list) due to similar parameter
  structure
    - Mitigation: Distinct tool names and descriptions; task_plan description emphasizes "session checklist" while
  schedule emphasizes "cron/recurring tasks"
2026-02-24 20:52:31 +08:00
Chummy
d78a6712ef fix: stabilize UTF-8 truncation and dashboard message IDs (RMN-25 RMN-33) 2026-02-24 16:52:26 +08:00
Chummy
b3b5055080 feat: replay custom provider api mode, route max_tokens, and lark image support 2026-02-24 15:59:49 +08:00
Chummy
fb95fc61a0 fix(browser): harden rust_native interactability for click/fill/type 2026-02-24 14:12:08 +08:00
Chummy
3157867a71 test(file_read): align outside-workspace case with workspace_only=false policy 2026-02-24 13:12:03 +08:00
Chummy
f4f6f5f48a test(codex): align provider init with runtime option changes 2026-02-24 12:38:48 +08:00
Chummy
1290b73faa fix: align codex provider runtime options with current interfaces 2026-02-24 12:24:51 +08:00
Chummy
fefd0a1cc8 style: apply rustfmt normalization 2026-02-24 12:02:18 +08:00
NB😈
5386414666 fix(cron): enable delivery for crons created from external channels
Scheduled jobs created via channel conversations (Discord, Telegram, etc.)
never delivered output back to the channel because:

1. The agent had no channel context (channel name + reply_target) in its
   system prompt, so it could not populate the delivery config.
2. The schedule tool only creates shell jobs with no delivery support,
   and the cron_add tool's delivery schema was opaque.
3. OpenAiCompatibleProvider was missing the native_tool_calling field,
   causing a compile error.

Changes:
- Inject channel context (channel name + reply_target) into the system
  prompt so the agent knows how to address delivery when scheduling.
- Improve cron_add tool description and delivery parameter schema to
  guide the agent toward correct delivery config.
- Update schedule tool description to warn that output is only logged
  and redirect to cron_add for channel delivery.
- Fix missing native_tool_calling field in OpenAiCompatibleProvider.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-24 11:34:12 +08:00
Chummy
e6227d905a
[supersede #1354 v2] feat(composio): fix v3 compatibility with parameter discovery, NLP text execution, and error enrichment (#1493)
* feat(composio): fix v3 compatibility with parameter discovery, NLP text execution, and error enrichment

Three-layer fix for the Composio v3 API compatibility issue where the LLM
agent cannot discover parameter schemas, leading to repeated guessing and
execution failures.

Layer 1 – Surface parameter hints in list output:
  - Add input_parameters field to ComposioV3Tool and ComposioAction structs
  - Pass through input_parameters from v3 list response via map_v3_tools_to_actions
  - Add format_input_params_hint() to show required/optional param names in list output

Layer 2 – Support natural-language text execution:
  - Add text parameter to tool schema (mutually exclusive with params)
  - Thread text through execute handler → execute_action → execute_action_v3
  - Update build_execute_action_v3_request to send text instead of arguments
  - Skip v2 fallback when text-mode is used (v2 has no NLP support)

Layer 3 – Enrich execute errors with parameter schema:
  - Add get_tool_schema() to fetch full tool metadata from GET /api/v3/tools/{slug}
  - Add format_schema_hint() to render parameter names, types, and descriptions
  - On execute failure, auto-fetch schema and append to error message

Root cause: The v3 API returns input_parameters in list responses but
ComposioV3Tool was silently discarding them. The LLM had no way to discover
parameter schemas before calling execute, and error messages provided no
remediation guidance — creating an infinite guessing loop.

Co-Authored-By: unknown <>
(cherry picked from commit fd92cc5eb0)

* fix(composio): use floor_char_boundary for safe UTF-8 truncation in format_schema_hint

Co-Authored-By: unknown <>
(cherry picked from commit 18e72b6344)

* fix(composio): restore coherent v3 execute flow after replay

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-23 07:38:59 -05:00
reidliu41
d3f0a79fe9 Summary
- Problem: The existing http_request tool returns raw HTML/JSON, which is nearly unusable for LLMs to extract
  meaningful content from web pages.
- Why it matters: All mainstream AI agents (Claude Code, Gemini CLI, Aider) have dedicated web content extraction
  tools. ZeroClaw lacks this capability, limiting its ability to research and gather information from the web.
- What changed: Added a new web_fetch tool that fetches web pages and converts HTML to clean plain text using
  nanohtml2text. Includes domain allowlist/blocklist, SSRF protection, redirect following, and content-type aware
  processing.
- What did not change (scope boundary): http_request tool is untouched. No shared code extracted between http_request
   and web_fetch (DRY rule-of-three: only 2 callers). No changes to existing tool behavior or defaults.

Label Snapshot (required)

  - Risk label: risk: medium
  - Size label: size: M
  - Scope labels: tool, config
  - Module labels: tool: web_fetch
  - If any auto-label is incorrect, note requested correction: N/A

  Change Metadata

  - Change type: feature
  - Primary scope: tool

  Linked Issue

  - Closes #
  - Related #
  - Depends on #
  - Supersedes #

  Supersede Attribution (required when Supersedes # is used)

  N/A

  Validation Evidence (required)

  cargo fmt --all -- --check   # pass
  cargo clippy --all-targets -- -D warnings  # no new warnings (pre-existing warnings only)
  cargo test --lib -- web_fetch  # 26/26 passed
  cargo test --lib -- tools::tests  # 12/12 passed
  cargo test --lib -- config::schema::tests  # 134/134 passed

  - Evidence provided: unit test results (26 new tests), manual end-to-end test with Ollama + qwen2.5:72b
  - If any command is intentionally skipped, explain why: Full cargo clippy --all-targets has 43 pre-existing errors
  unrelated to this PR (e.g. await_holding_lock, format! appended to String). Zero errors from web_fetch code.

  Security Impact (required)

  - New permissions/capabilities? Yes — new web_fetch tool can make outbound HTTP GET requests
  - New external network calls? Yes — fetches web pages from allowed domains
  - Secrets/tokens handling changed? No
  - File system access scope changed? No
  - If any Yes, describe risk and mitigation:
    - Deny-by-default: enabled = false by default; tool is not registered unless explicitly enabled
    - Domain filtering: allowed_domains (default ["*"] = all public hosts) + blocked_domains (takes priority).
  Blocklist always wins over allowlist.
    - SSRF protection: Blocks localhost, private IPs (RFC 1918), link-local, multicast, reserved ranges, IPv4-mapped
  IPv6, .local TLD — identical coverage to http_request
    - Rate limiting: can_act() + record_action() enforce autonomy level and rate limits
    - Read-only mode: Blocked when autonomy is ReadOnly
    - Response size cap: 500KB default truncation prevents context window exhaustion
    - Proxy support: Honors [proxy] config via tool.web_fetch service key

  Privacy and Data Hygiene (required)

  - Data-hygiene status: pass
  - Redaction/anonymization notes: No personal data in code, tests, or fixtures
  - Neutral wording confirmation: All test identifiers use neutral project-scoped labels

  Compatibility / Migration

  - Backward compatible? Yes — new tool, no existing behavior changed
  - Config/env changes? Yes — new [web_fetch] section in config.toml (all fields have defaults)
  - Migration needed? No — #[serde(default)] on all fields; existing configs without [web_fetch] section work unchanged

  i18n Follow-Through (required when docs or user-facing wording changes)

  - i18n follow-through triggered? No — no docs or user-facing wording changes

  Human Verification (required)

  - Verified scenarios:
    - End-to-end test: zeroclaw agent with Ollama qwen2.5:72b successfully called web_fetch to fetch
  https://github.com/zeroclaw-labs/zeroclaw, returned clean plain text with project description, features, star count
    - Tool registration: tool_count increased from 22 to 23 when enabled = true
    - Config: enabled = false (default) → tool not registered; enabled = true → tool available
  - Edge cases checked:
    - Missing [web_fetch] section in existing config.toml → works (serde defaults)
    - Blocklist priority over allowlist
    - SSRF with localhost, private IPs, IPv6
  - What was not verified:
    - Proxy routing (no proxy configured in test environment)
    - Very large page truncation with real-world content

  Side Effects / Blast Radius (required)

  - Affected subsystems/workflows: all_tools_with_runtime() signature gained one parameter (web_fetch_config); all 5
  call sites updated
  - Potential unintended effects: None — new tool only, existing tools unchanged
  - Guardrails/monitoring for early detection: enabled = false default; tool_count in debug logs

  Agent Collaboration Notes (recommended)

  - Agent tools used: Claude Code (Opus 4.6)
  - Workflow/plan summary: Plan mode → approval → implementation → validation
  - Verification focus: Security (SSRF, domain filtering, rate limiting), config compatibility, tool registration
  - Confirmation: naming + architecture boundaries followed (CLAUDE.md + CONTRIBUTING.md): Yes — trait implementation +
   factory registration pattern, independent security helpers (DRY rule-of-three), deny-by-default config

  Rollback Plan (required)

  - Fast rollback command/path: git revert <commit>
  - Feature flags or config toggles: [web_fetch] enabled = false (default) disables completely
  - Observable failure symptoms: tool_count in debug logs drops by 1; LLM cannot call web_fetch

  Risks and Mitigations

  - Risk: SSRF bypass via DNS rebinding (attacker-controlled domain resolving to private IP)
    - Mitigation: Pre-request host validation blocks known private/local patterns. Same defense level as existing
  http_request tool. Full DNS-level protection would require async DNS resolution before connect, which is out of scope
   for this PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
(cherry picked from commit 04597352cc)
2026-02-23 20:30:21 +08:00
Ken Simpson
456b53d9d3 fix(tools): recover rust-native browser session on stale webdriver 2026-02-23 19:54:15 +08:00
Nguyen Minh Thai
87ac60c71d
feat(tools): Use system default browser instead of hard-coded Brave Browser (#1453)
* ci(homebrew): prefer HOMEBREW_UPSTREAM_PR_TOKEN with fallback

* ci(homebrew): handle existing upstream remote and main base

* feat(tools): Use system default browser instead of hard-coded Brave Browser

---------

Co-authored-by: Will Sarg <12886992+willsarg@users.noreply.github.com>
2026-02-23 05:57:21 -05:00
InuDial
a8e5606650 Add hardware feature conditional compile for hardware mods 2026-02-23 16:45:44 +08:00
Robert McGinley
7bea36532d fix(tool): treat max_response_size = 0 as unlimited
When max_response_size is set to 0, the condition `text.len() > 0` is
true for any non-empty response, causing all responses to be truncated
to empty strings. The conventional meaning of 0 for size limits is
"no limit" (matching ulimit, nginx client_max_body_size, curl, etc.).

Add an early return when max_response_size == 0 and update the doc
comment to document this behavior.
2026-02-23 14:55:27 +08:00
argenis de la rosa
10973eb075 fix(web): call doctor endpoint with authenticated POST 2026-02-22 21:32:34 -05:00
Chummy
d8eb789db4 fix(composio): harden v3 slug candidate and test coverage 2026-02-23 00:55:42 +08:00
Bogdan
0d24a54b90 fix tests 2026-02-23 00:43:54 +08:00
Bogdan
a6e53e6fcd feat(tools): stabilize composio slug resolution and drop v2 fallback
- add cache + candidate builder for Composio action/tool slugs so execute runs without manual priming @src/tools/composio.rs#285-320
- remove unused v2 execute/connect code paths and rely on HTTPS-only v3 endpoints @src/tools/composio.rs#339-502
- extend tooling tests to cover slug candidate generation variants @src/tools/composio.rs#1317-1324
2026-02-23 00:43:54 +08:00
Vernon Stinebaker
7e6491142e fix(provider): preserve reasoning_content in tool-call conversation history
Thinking/reasoning models (Kimi K2.5, GLM-4.7, DeepSeek-R1) return a
reasoning_content field in assistant messages containing tool calls.
ZeroClaw was silently dropping this field when constructing conversation
history, causing provider APIs to reject follow-up requests with 400
errors: "thinking is enabled but reasoning_content is missing in
assistant tool call message".

Add reasoning_content: Option<String> as an opaque pass-through at every
layer of the pipeline: ChatResponse, ConversationMessage, NativeMessage
structs, parse/convert/build functions, and dispatcher. The field is
skip_serializing_if = None so it is invisible for non-thinking models.

Closes #1327
2026-02-22 17:40:48 +08:00
Chummy
9735253484 fix(tool): harden content_search parsing and output safety 2026-02-21 23:26:11 +08:00
Chummy
e5bc9514a4 security: close shell path-policy bypasses 2026-02-21 22:35:52 +08:00
reidliu41
007a7e2ec6 feat(tool): add content_search tool for regex-based file content search 2026-02-21 22:24:03 +08:00
Chummy
38e27ff629 test(schedule): lock in rate-limit blocking for mutating actions 2026-02-21 21:20:53 +08:00
Chummy
a92f5c94cd test(cron): cover rate-limit policy gates across cron tools 2026-02-21 21:04:22 +08:00
Chummy
85f218eb0f feat(tools): add natural-language model routing config tool 2026-02-21 20:45:43 +08:00
Chummy
ccc3d6759f security: block plain shell variable expansion and forbidden path args 2026-02-21 20:42:48 +08:00
Chummy
628654ebe5 fix: improve allowed_roots guidance for filesystem access 2026-02-21 17:33:11 +08:00
Chummy
ccd0de36aa fix(tools): honor wildcard allowed_domains for browser and http_request 2026-02-21 17:08:08 +08:00
chumyin0912@gmail.com
179e7949c2 fix(gateway): align dashboard API client and embed built web assets 2026-02-21 16:14:01 +08:00
Zeki Kocabıyık
79337c76e8 feat(gateway): add embedded web dashboard with React frontend
Add a complete web management panel for ZeroClaw, served directly from
the binary via rust-embed. The dashboard provides real-time monitoring,
agent chat, configuration editing, and system diagnostics — all
accessible at http://localhost:5555/ after pairing.

Backend (Rust):
- Add 15+ REST API endpoints under /api/* with bearer token auth
- Add WebSocket agent chat at /ws/chat with query param auth
- Add SSE event stream at /api/events via BroadcastObserver
- Add rust-embed static file serving at /_app/* with SPA fallback
- Extend AppState with tools_registry, cost_tracker, event_tx
- Extract doctor::diagnose() for structured diagnostic results
- Add Serialize derives to IntegrationStatus, CliCategory, DiscoveredCli

Frontend (React + Vite + Tailwind CSS):
- 10 dashboard pages: Dashboard, AgentChat, Tools, Cron, Integrations,
  Memory, Config, Cost, Logs, Doctor
- WebSocket client with auto-reconnect for agent chat
- SSE client (fetch-based, supports auth headers) for live events
- Full EN/TR internationalization (~190 translation keys)
- Dark theme with responsive layouts
- Auth flow via 6-digit pairing code, token stored in localStorage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 16:14:01 +08:00
xero7689
356d60f931 fix(config): HttpRequestConfig::default() zero-initializes numeric fields
#[derive(Default)] gives 0 for numeric types, bypassing
#[serde(default = "fn")] helpers. Onboarding wizard calls
::default() directly, writing timeout_secs=0 and
max_response_size=0 to config.toml — causing every
http_request tool call to fail immediately and silently.

- Replace derive Default with manual impl calling
  default_http_timeout_secs() / default_http_max_response_size()
- Add zero-guard in execute_request with tracing::warn!
- Add regression test for correct default values
2026-02-21 16:09:22 +08:00
Chummy
580cc52a0a
Merge pull request #1127 from ecschoye/fix/non-cli-tool-exclusion
feat(security): add non_cli_excluded_tools config for channel tool filtering
2026-02-21 15:33:16 +08:00
chumyin
67942318c9 Merge origin/main into fix/non-cli-tool-exclusion 2026-02-21 15:28:53 +08:00
chumyin
782bb0b483 fix: resolve multi-issue provider/channel/tool regressions 2026-02-21 15:12:27 +08:00
chumyin
f74fd478b1 fix(telegram): harden html rendering and scope allowlist change 2026-02-21 14:32:02 +08:00
Shawn Zhang
7fed5cf56b feat(telegram): convert Markdown to Telegram HTML for proper formatting
- Add markdown_to_telegram_html() to TelegramChannel: converts **bold**,
  *italic*, `code`, ```blocks```, [text](url) links, and ## headers
  to Telegram HTML tags (<b>, <i>, <code>, <pre>, <a href>)
- Switch send_text_chunks() and finalize_draft() from parse_mode=Markdown
  to parse_mode=HTML — more reliable and supports richer formatting
- Update channel_delivery_instructions() for Telegram: guide model to use
  bold, emoji, and concise style (mirrors OpenClaw SOUL.md approach)
- Add wildcard support to http_request allowlist: allowed_domains=["*"]
  now bypasses domain filtering entirely
- Expand system prompt URL fetching guidance: jina.ai reader-mode proxy
  as fallback for paywalled/403 content
2026-02-21 14:32:02 +08:00
Alex Gorevski
959fbee782
Merge pull request #1187 from zeroclaw-labs/fix/update-tests-for-usage-and-hooks-fields
fix(tests): update test structs for new usage and hooks fields
2026-02-20 22:30:54 -08:00
agorevski
00a7510e91 fix(tests): update test structs for new usage and hooks fields
Add missing `usage: None` to ChatResponse literals in benchmarks,
agent loop tests, and file_read tests. Add missing `hooks: None` to
channel context structs in channel tests. Remove obsolete
`.map(|(m, _)| m)` calls in telegram tests to match updated
parse_update_message return type.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-20 22:30:23 -08:00
Alex Gorevski
4a1bacf960
Merge pull request #1186 from zeroclaw-labs/test/audit-07-coverage-remediation
test: add unit tests for audit-07 coverage gaps
2026-02-20 22:28:34 -08:00
agorevski
06e0632a09 test: add unit tests for audit-07 coverage gaps
Add 81 new tests addressing audit-07 findings across 4 areas:

Provider factory resolution (42 tests):
- Cover all 25+ untested providers and aliases in factory
- Test openrouter, gemini, bedrock, copilot, china region, local,
  cloud AI, and custom endpoint providers

Config schema boundaries (26 tests):
- Invalid value fail-fast (wrong types, overflow port)
- Gateway, security, autonomy config defaults and roundtrips
- Backward compatibility (unknown keys, partial sections)
- Nested optional section defaults

Gateway rate limiter boundaries (8 tests):
- Window expiry and re-allow after cooldown
- Independent key tracking
- Exact max_keys boundary eviction
- Pair vs webhook independence
- Concurrent access thread safety
- Rapid burst then cooldown pattern

Tool error paths (5 tests):
- Null byte in path rejection for file_read and file_edit
- Shell nonexistent command, stderr capture, action budget exhaustion

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-20 22:23:55 -08:00
Alex Gorevski
bd31f77e8f
Merge pull request #1182 from zeroclaw-labs/fix/cleartext-logging-alerts
fix(security): remove sensitive fields from Debug impls
2026-02-20 22:14:04 -08:00
agorevski
52f72692ba fix(security): remove sensitive fields from Debug impls
Resolve 18 CodeQL cleartext-logging/cleartext-transmission alerts by
removing sensitive data from Debug output entirely rather than redacting.

Changes:
- memory/mod.rs: omit api_key from ResolvedEmbeddingConfig Debug
- tools/browser.rs: omit api_key from ComputerUseConfig Debug
- providers/mod.rs: omit access_token/refresh_token from
  QwenOauthCredentials Debug, credential from QwenOauthProviderContext
- memory/traits.rs: custom Debug for MemoryEntry omitting session_id
- auth/profiles.rs: custom Debug for AuthProfile omitting token,
  token_set, account_id
- channels/matrix.rs: add Debug impl for MatrixChannel omitting
  access_token
- channels/qq.rs: sanitize user_id before URL interpolation
- channels/whatsapp_storage.rs: document false-positive analysis

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-20 22:06:21 -08:00
xj
69f4b95f8e fix(hooks): add JsonSchema derive to HooksConfig and BuiltinHooksConfig
Upstream main now derives schemars::JsonSchema on all config structs.
Our HooksConfig and BuiltinHooksConfig were missing it, causing CI
Build (Smoke) failure when the merge commit was compiled.
2026-02-21 13:34:09 +08:00
EC2 Default User
9ff86c372f fix(tools): reject empty old_string in file_edit 2026-02-21 13:32:59 +08:00
reidliu41
34ec788968 feat(tools): add file_edit tool for precise in-place text replacement 2026-02-21 13:32:59 +08:00
Aleksandr Prilipko
0a2609d538 fix(tools): file_read binary file support — PDF extraction + lossy fallback
Add cascading fallback to file_read tool: UTF-8 → PDF text extraction
(via pdf-extract) → lossy UTF-8 conversion. Binary files no longer
produce errors; PDFs return extracted text, other binaries get lossy
output with U+FFFD replacement characters.

Changes:
- Cargo.toml: add rag-pdf to default features
- file_read.rs: cascading fallback logic + try_extract_pdf_text helper
- file_read.rs: update tool description
- test_document.pdf: replace empty fixture with PDF containing "Hello PDF"
- Tests: remove file_read_rejects_binary_pdf, add unit + e2e tests for
  PDF extraction and lossy binary reads (including live OpenAI Codex e2e)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:03:13 +08:00