fix(opencode): accept answer_commit list inputs sent as JSON strings

EK
17h ago
+154-10

Issue for this PR

Closes #1700

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

In Analyst mode with Altimate Base, the model sometimes sends answer_commit's fields (and asked) as a JSON-encoded string instead of an array. Validation then fails with fields: Invalid input: expected array, received string. The analysis finishes, but the user never gets the answer. The trace is in #1700.

The tool's z.preprocess already accepts "true"/"false" strings for answer_only. This PR makes it also decode fields, asked, rows, unresolved and readings when one arrives as a string that starts with [ or { and parses as JSON. A string is never a valid value for those keys, so nothing that passes validation today behaves differently. The decoded value still goes through the full schema, and invalid JSON is left as it is, so it still fails with the normal error.

How did you verify your code works?

  • Added 8 tests to test/altimate/tools/answer-commit.test.ts. They include the exact shape from the #1700 trace, readings and asked decoded into metadata, invalid JSON and plain strings (still rejected), and decoded values that are still validated. 5 of them fail without the fix, with the same error as the trace.
  • The existing answer_commit suites pass (tool, conjunction, checks and agent: 367 tests). tsgo --noEmit is clean, and the pre-push typecheck passes.
  • Ran it from source on macOS against jaffle_shop_duckdb with Altimate Base in Analyst mode. Before the fix the session ended with the expected array error (twice). After it, answer_commit succeeded and the answer was rendered.

Cost side effects

None. It only parses tool-call arguments locally, and adds no model calls, queries or cloud resources.

Screenshots / recordings

N/A (not a UI change).

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR
  • I checked for cost side effects (model calls, queries or cloud resources that grow with user data) and described them, or wrote "none"

I diagnosed and patched this with help from Claude, and verified the behavior myself as described above.

Summary by CodeRabbit

  • New Features
    • Structured inputs can now be provided as valid JSON-encoded strings, including fields, rows, questions, unresolved items, and readings. They’re handled like equivalent arrays or objects, while ordinary text values remain unchanged.
    • Boolean-like answer_only values are recognized, and JSON-encoded inputs are supported when formatting final answers and clarifying readings.
  • Bug Fixes
    • Invalid JSON strings and decoded values that fail validation continue to receive the usual validation checks and errors.