feat(client): typed shapes for the remaining agent tools; error.data at the boundary - #413
Merged
Merged
Conversation
…ors/write_instance + session trio; error.data at the boundary
Contract-parity fixes, part 2: the advertised agent-scope tools that
had no typed request/response structs or client methods (tests used
call_raw), and the error.data envelope the transport dropped.
- New escurel-types shapes matching the wire exactly: FetchBlob*
(blob: Option<BlobInfo> — null = absent/hidden/non-document, one
indistinguishable answer), ListSnapshots* (taken_at strings, oldest
first), ListOpAuthors* (OpAuthor{op_id, hlc, applied_at?, principal?}),
WriteInstance* (wire key `ref`; {ok, source, fields}), and the HTTP
session trio OpenSession*/ApplyOp*/CloseSession* (apply_op carries the
base64 Loro blob as the wire does; CloseSessionRequest::default() has
commit: true, the wire default — a defaulted close commits, never a
silent discard).
- escurel-client methods for all seven tools. ExpandResponse also
decodes backend_projection (the sql_view/remote live overlay), so a
typed write_instance caller can do a read-after-write.
- Error::JsonRpc gains data_code/retryable, parsed from the gateway's
error.data {code, retryable} — the STABLE app-level refusal code docs
tell callers to branch on (several refusals share -32000). None when
the envelope has no data; existing `{ code, .. }` matches unaffected.
Skill sync (same PR): references/05-consume-from-rust.md documents the
new typed methods + error fields (replacing the stale "the live-CRDT
trio ... as the types catch up" deferral); skill CHANGELOG 0.6.28 +
VERSION.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Contract-parity fixes (2/2, stacked on #409): the advertised agent-scope tools that had no typed request/response structs or client methods, and the
error.dataenvelope the transport dropped.fetch_blob,list_snapshots,list_op_authors,write_instance(wire keyref), and the HTTP session trioopen_session/apply_op/close_session. Each struct matches the server handler's wire keys exactly;apply_op.opis the base64 Loro blob as the wire carries it;CloseSessionRequest::default()carries the wire defaultcommit: true(a defaulted close commits, never a silent discard).ExpandResponsealso decodesbackend_projectionso awrite_instancecaller can do a typed read-after-write.error.dataat the client boundary:Error::JsonRpcgainsdata_code: Option<String>/retryable: Option<bool>, parsed from the gateway'serror.data = {code, retryable}— the STABLE app-level refusal code the docs tell callers to branch on (several refusals share-32000). BothNonewhen the envelope carries nodata; existing{ code, .. }matches are unaffected. (Note: perdocs/spec/dx.mdthe error enum is a breaking-change surface — downstream struct-literal constructions ofJsonRpcneed the two new fields; the one in-workspace site,escurel-runner-core's reconciler test, is updated here.)Skill sync in the same PR:
references/05-consume-from-rust.mddocuments the new typed methods + error fields (replacing the stale "the live-CRDT trio and admin methods are added as … the types catch up" deferral); skill CHANGELOG0.6.28+ VERSION.Test plan
Real boundary, no mocks (
crates/escurel-client/tests/typed_tools.rs, new):session_trio_round_trips_typed— real DuckDB CRDT backend sharing the indexer's DuckDB instance viatry_clone(the production single-file wiring): open → apply (real Loro op) →list_op_authorsshows the verified principal → close(commit) →expandobserves the write-through body.list_snapshots_round_trips_typed— a whole-page write's snapshot is listed through the typed method.fetch_blob_round_trips_typed— real/ingest/uploadof a born-digital text document into adocument-backend skill, bytes fetched back verbatim (base64, declared content type); a non-document page decodesblob: None.write_instance_round_trips_typed— a real stateful loopback axum CRM as the openapi upstream; endpoint registered + overlay materialised viacall_raw(admin plumbing), typedwrite_instancePATCHes it, livebackend_projectionread-after-write proves the upstream mutated.error_data_code_and_retryable_surface_typed— areader_modegateway refusesupdate_pageand the typed error carriesdata_code: Some("read_only_replica"),retryable: Some(true).error_without_data_decodes_none— plain protocol error keeps both additionsNone.crates/escurel-types/tests/wire_contract.rs:write_instance_request_ref_rename,fetch_blob_response_wire_shape,list_op_authors_response_wire_shape,roundtrip_session_tools,close_session_commit_defaults_true.Gate (un-piped exit codes):
cargo fmt --check= 0,cargo clippy --workspace --all-targets -- -D warnings= 0,cargo test --workspace --all-targets= 0 (102 suites ok),cargo build --workspace --release= 0.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.