client: Honor IsError and extract JSON from tool text #16

Merged
linus merged 1 commit from client/tooljson-iserror into develop 2026-09-05 04:56:41 +00:00
Collaborator

What

Honor CallToolResult.IsError on the client and harden TextContent JSON extraction in toolJSON.

  1. When IsError is set, surface TextContent as the tool error (not non-json tool result). GetError() stays for the server/SetError path but is always nil on clients (go-sdk v1.7.0).
  2. Prefer StructuredContent when present (keep #14).
  3. Else TextContent: try each alone for valid JSON; then concat; then extract first balanced {…} / […] (string/escape-aware).
  4. On remaining failure, error includes shape summary: isError, content types, structured nil/present, textLen + ~80-rune prefix.

Why

CT113 tip 11feaad (#14) still fails: historicals: mcp get_equity_historicals: non-json tool result. StructuredContent prefer did not clear the live path → StructuredContent likely nil; TextContent non-JSON or IsError soft-fail that looked like non-json because GetError() is never set on clients.

Test

  • go test ./... green
  • New/updated: IsError+text (field, GetError nil), empty IsError → tool error, wrapped JSON in prose, one-of-many text JSON, array / brace-in-string extract, non-JSON with shape hint
  • Existing structured / text JSON / empty / nil / GetError kept

Issue: #15

Do not merge until Remy re-proves after deploy (paper only). Out of scope: live/place, knobs, lab SSH / CT113 from this PR.

## What Honor `CallToolResult.IsError` on the client and harden TextContent JSON extraction in `toolJSON`. 1. When `IsError` is set, surface TextContent as the tool error (not `non-json tool result`). `GetError()` stays for the server/SetError path but is always nil on clients (go-sdk v1.7.0). 2. Prefer `StructuredContent` when present (keep #14). 3. Else TextContent: try each alone for valid JSON; then concat; then extract first balanced `{…}` / `[…]` (string/escape-aware). 4. On remaining failure, error includes shape summary: isError, content types, structured nil/present, textLen + ~80-rune prefix. ## Why CT113 tip `11feaad` (#14) still fails: `historicals: mcp get_equity_historicals: non-json tool result`. StructuredContent prefer did not clear the live path → StructuredContent likely nil; TextContent non-JSON or IsError soft-fail that looked like non-json because `GetError()` is never set on clients. ## Test - `go test ./...` green - New/updated: IsError+text (field, GetError nil), empty IsError → `tool error`, wrapped JSON in prose, one-of-many text JSON, array / brace-in-string extract, non-JSON with shape hint - Existing structured / text JSON / empty / nil / GetError kept Issue: https://git.s1d3sw1ped.com/s1d3sw1ped/robinhood-agentic-mcp/issues/15 Do not merge until Remy re-proves after deploy (paper only). Out of scope: live/place, knobs, lab SSH / CT113 from this PR.
ash self-assigned this 2026-09-05 04:53:58 +00:00
client: Honor IsError and extract JSON from tool text
All checks were successful
CI / Test and build (pull_request) Successful in 13s
66ec6305e8
#15
ash requested review from linus 2026-09-05 04:53:58 +00:00
linus merged commit 51e1539124 into develop 2026-09-05 04:56:41 +00:00
Commenting is not possible because the repository is archived.
No reviewers
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
s1d3sw1ped/robinhood-agentic-mcp!16
No description provided.