* feat: merge http/web_fetch tools, add tool output stash for large responses
Merge `web_fetch` into `http` tool with smart approval: plain GETs (no
headers, no body) run without approval and follow redirects with SSRF
re-validation per hop; all other requests require approval as before.
Add `tool_output_stash` on JobContext so full tool outputs are preserved
before safety-layer truncation. The `json` tool gains a
`source_tool_call_id` parameter to reference stashed outputs, enabling
reliable parsing of large API responses that exceed the 100KB context
limit.
Other improvements:
- Descriptive User-Agent header using CARGO_PKG_VERSION
- Truncation now keeps partial data + hint about source_tool_call_id
- System prompt reinforces tool_calls over narration
- json tool query/stringify handle pre-parsed (non-string) data
[skip-regression-check]
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* chore: delete dead web_fetch.rs (merged into http tool)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* style: fix rustfmt formatting
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* style: rename shadowed data binding for clarity in json tool
Address PR review: rename owned `data` to `data_value` before
re-binding as `let data = &data_value` to make ownership explicit.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix(ci): mark network-dependent trace tests as #[ignore]
The weather_sf and baseball_stats tests hit live external APIs (wttr.in,
ESPN) which are unreliable in CI. Mark them #[ignore] so they don't
block the pipeline. Run locally with `--ignored` to include them.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: replay recorded HTTP exchanges in trace tests instead of hitting live APIs
Wire ReplayingHttpInterceptor into TestRig when the trace fixture
contains http_exchanges. This replays recorded responses instead of
making live network calls, making tests deterministic and CI-stable.
Add captured HTTP responses to weather_sf.json (wttr.in) and
baseball_stats.json (ESPN API) fixtures.
Revert #[ignore] on both tests — they now run offline.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: recover inline bracket-format tool calls from LLM text responses
When flatten_tool_messages converts tool calls to text like
`[Called tool `http` with arguments: {...}]` for NEAR AI compatibility,
the LLM sometimes echoes this format back in its text responses instead
of using proper tool_calls. Add recovery for this bracket format in
recover_tool_calls_from_content and strip it in clean_response so
users don't see raw tool call syntax.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
* fix: remove union type arrays from tool schemas for OpenAI compatibility
OpenAI rejects JSON Schema union types containing "array" without an
"items" subschema. The http tool's "body" and json tool's "data" params
used union types to accept any value. Replace with freeform (untyped)
schemas which OpenAI treats as accepting any JSON value.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: update schema tests to assert type is absent, fix missed json.rs test
- http.rs test: assert body has no "type" (not just has description)
- json.rs test: update to match the freeform schema change (was still
asserting type is present)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
Fixes#184 — updates model selection, priority sort, and cost table to
match current OpenAI and Anthropic model catalogs.
OpenAI: GPT-5.3 Codex, GPT-5.2 Codex/Pro, GPT-5.1 Codex/Mini/Max,
GPT-5/Mini/Nano, GPT-4.1/Mini/Nano, o4-mini, o3/Pro
Anthropic: Claude Opus 4.6/4.5/4.1/4.0, Claude Sonnet 4.6/4.5/4.0,
Claude Haiku 4.5, Claude 3.7 Sonnet, Claude 3.5 Haiku
Also resolves stale merge-conflict markers in http.rs and json.rs.
* fix: persist OpenAI-compatible provider and respect embeddings disable (#129)
Three interrelated bugs caused the agent to ignore user choices made
during onboarding when using an OpenAI-compatible LLM provider:
1. Session auth ran before DB config reload, so Config::from_env()
defaulted to NearAi and attempted Clerk auth before the real
backend was known. Moved session auth to after final config
resolution.
2. EmbeddingsConfig::resolve() force-enabled embeddings whenever
OPENAI_API_KEY was present, ignoring the user's explicit disable.
Changed to respect the stored setting as source of truth.
3. LLM_BACKEND was not saved to the bootstrap .env file, so
Config::from_env() always defaulted to NearAi before the DB
was connected. Now saves LLM_BACKEND, LLM_BASE_URL, and
OLLAMA_BASE_URL alongside the database bootstrap vars.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: add SAFETY comments and sanitize .env value escaping
Address PR review feedback:
- Add SAFETY comments to all unsafe env var manipulation in config
tests (gemini-code-assist).
- Escape backslashes and double quotes in save_bootstrap_env() to
prevent env var injection via malicious URLs (gemini-code-assist).
- Add test verifying injection attempt is neutralized.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: incorporate PR #138 changes (chat completions, model sorting, tool schemas)
Includes all changes from bigguybobby's PR #138:
- Use Chat Completions API for OpenAI-compatible providers (avoids
Responses API assumptions like required tool call IDs)
- Fall back to settings.selected_model when LLM_MODEL env var is unset
- Update OpenAI model list (add gpt-5 family) with priority-based sorting
- Add is_openai_chat_model() filter with broader exclusion patterns
- Fix http tool: headers schema → array of {name,value}, body → string type,
parse_headers_param() accepts both legacy object and array formats
- Fix json tool: data schema → string type, parse_json_input() normalizer,
validate uses strict string-only check
- Add mutex-serialized config tests for env var manipulation
- Update NEAR AI config comment for accuracy
Co-Authored-By: Bobby (bigguybobby) <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Illia Polosukhin <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Bobby (bigguybobby) <[email protected]>
* refactor: deduplicate tool parameter extraction and remove dead stub tools
Delete 4 never-registered stub tools (marketplace, restaurant, ecommerce,
taskrabbit) removing ~625 lines of dead code. Add require_str/require_param
helpers to tool.rs and refactor ~30 call sites across 10 tool files from
4-6 line inline extractions to single-line calls. Consolidate worker HTTP
client with get_json/post_json helpers, reducing boilerplate in 4 methods.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: return JSON from orchestrator /complete endpoint
The report_complete handler returned bare StatusCode::OK (no body),
which broke the post_json helper that expects a JSON response.
Return {"status": "ok"} for consistency with other worker endpoints.
Addresses review feedback on PR #98.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>