Repository navigation
fix(tools): restore external tool calling across OpenCode, OpenClaw, and Codex - #27
Conversation
Verdict matrix
Sensitive paths
Deterministic pre-checks
gateway_safetyVERDICT: APPROVE Summary RationaleThe PR rigorously hardens the configuration matrix, external tool calling contracts, error categorization, and container port validation across OpenCode2API without violating any [provider] safety invariants.
Findings
api_compatAPI Compatibility ReviewThis is a very large PR touching the config merge layer, tool policy, stream handling, error surfaces, and multiple route files. I'll focus on the wire-shape compatibility checklist. VERDICT: NEEDS_CHANGESBLOCKING
SHOULD_FIX
NITS
Test gaps
docs_configVERDICT: COMMENT BLOCKING:
SHOULD_FIX:
NITS:
Matrix-close file list for new/changed envs (
FINAL_VERDICT: COMMENT Session: response_id=resp_xzC6aoCLMKOB1e8PtfqoiAw,resp_req_vrtx_011CfVar2E6wPdcw6jPj4zY5,chatcmpl-0a023414-f782-4fd5-8675-8727e2bdba54 (chain via previous_response_id, 30min TTL). model=[model] provider=[provider]. |
- Dockerfile: add empty OPENCODE_PROXY_BIND_HOST + 5 legacy EXTERNAL_TOOL_* (empty==unset, value-identical) - tests/env-alias: fix stale unit-default-false comment (both defaults true) - CHANGELOG: Phase 3A merge unification + Stage1 symmetry
- chat stream fail-closed tool errors now return 502 server_error+code (JSON/SSE) like non-stream, not 500 internal_error - collector ID-less active-tool flag becomes a counter to avoid early idle/stop truncation on concurrent tools - CHANGELOG: Stage2 policy/stream/collector notes with breaking migration
…ntent - interactions: comment that omitted toolCalls is intentional (text+grounding only) - CHANGELOG: Stage3 upstream 503/Anthropic/empty-result/empty-stream/cooldown notes
- messages stream fail-closed now 502 JSON / SSE error api_error+code like non-stream - responses stream fail-closed now response.failed server_error+code + [DONE] like non-stream - tests lock stream code/type; CHANGELOG notes prompt breaking
…atch fallback Terminal snapshots redeliver settled tool parts; a replayed completed part must not fall through to the mismatch path and delete a still-running tool bucket (early idle/stop truncation). Add settledNoidKeys so replays are ignored; restrict fuzzy clearing to the single-bucket case and ignore multi-bucket ambiguity (waiting beats truncating). Pending re-arms a re-run of the same tool. Locks behavior with 6 regression tests in tests/stream-hardening.test.js (repeat, distinct-parallel, replay, mismatch both directions, same-name limitation).
…document collector settled-set
…partial-error semantics
Re-review summary (HEAD
|
CHANGELOG recommended EXTERNAL_TOOL_REQUIRE_CONFIRMATION_FOR=delete_*,write_* but policy uses exact Set.has(), so wildcards silently ALLOW destructive tools. Document exact-match only with exact-name examples.
- docs/README: drop dangling API Reference tracker, update status cells - docs/api-reference: specify 128-cap eviction/TTL/scope - entrypoint: printf for port return values
Restores reliable external tool calling across OpenCode, OpenClaw/Codex-style Responses clients, and Anthropic clients.\n\nPhase 1A: explicit external-tool policy/choice semantics, OMIT preserves tool schema, Anthropic metadata, empty tool results.\nPhase 1B: stream-safe tool validation, cross-channel parsing, merged tool artifacts, collector finish/error handling.\nPhase 2A: Responses SSE output assembler, argument accumulation, response identity, hosted-search ordering.\nPhase 2B: Codex additional_tools/namespace/custom declarations, continuation metadata, explicit unsupported-tool errors.\nPhase 3A: unified env/file/default config merge and deployment sources.\nPhase 3B: native tool discovery fail-closed plus readiness/metrics.\nPhase 4: Anthropic tool-loop and Interactions contract regression coverage.\nFinal: unified non-stream errors and parallel semantics.\n\nVerification: npm run typecheck, npm run build, npm test -- --runInBand, randomized Jest, and phased multi-subagent reviews.