Skip to content

Polish tool results for chat hosts and fix compressed-body truncation - #12

Merged
markmnl merged 2 commits into
mainfrom
connector-polish
Oct 9, 2026
Merged

markmnl merged 2 commits into
mainfrom
connector-polish

Conversation

@markmnl

@markmnl markmnl commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Rebased onto main after #11 merged.

Fixes from a user-agent session in a chat host against a hosted deployment.

Bug fix

  • Compressed bodies were truncated. For a deflate-compressed message, size is the compressed wire size, while short_text previews the decoded body. shortTextIsComplete took the preview as the whole body whenever the body compressed to less than the preview cap. For example, an 807-byte body that compressed to 474 bytes came back as its first 768 bytes with body_truncated: false. Previews of deflate messages are now never treated as complete. get_message.body_bytes and the new per-message get_thread body_bytes report the decoded length. Thread truncation notes use the decoded length too. This affects get_message, the thread pid walk, wait_for_message bodies and the message resource.

Results in chat hosts

  • untrusted_content_notice is added to structured results that carry other parties' words, since hosts may show structuredContent instead of the text. wait_for_message and get_thread get a next step, and get_attachment_download_url gets a fallback.
  • wait_for_message:
    • Skipped entries add from, and reactions also add emoji and reaction_to. Skipped reactions are listed in the text.
    • Adds thread_topic, taken from the thread lookup it already makes.
    • The description now says that a timeout's after_id is the inbox high-water mark ("0" only for an empty inbox), and that each wait is a model turn.
  • get_thread adds thread_topic. list_messages and list_sent make no extra round trips because the API returns no root topic there.
  • add_recipients takes recipients. add_to remains as a deprecated alias: pass exactly one of the two.
  • Attachment types are now consistent. The Web API stores application/octet-stream on upload, but its download route infers the type from the extension. A missing or generic type is now inferred from the filename. type is added to list items, get_message, send results and download links.
  • delivery_status now describes response codes correctly: 200 means accepted, other fmsg codes are rejections, and null means not recorded. It adds code_meaning. Negative host-local codes now count as pending.
  • whoami:
    • transport is now stdio or streamable-http (was http).
    • The text no longer states the token expiry; token_expires_at stays in the structured result, described as internal.
    • directory_names is omitted when empty.
  • resolve_address describes only the resolution steps the operator configured.
  • List items add reaction. Hidden reactions are never counted as unread, and mark_read accepts listed reactions.
  • Descriptions and errors mention save_attachment and get_attachment_download_url only where those tools are registered.
  • The server instructions now state neutrally that other fmsg tools or local credentials may act as a different address, instead of telling the model not to use them.

Graceful shutdown

  • On SIGINT/SIGTERM or HttpServerHandle.close(), an in-flight wait_for_message returns at once with status interrupted. The result carries the caller's after_id and the next step: call again with the same after_id; no messages are lost. Previously the wait hung through a restart until the client's own timeout.
  • New requests get 503 with Retry-After. Other in-flight requests get a 5-second grace period, then a 503.
  • The process exits within a bounded time, and a second signal exits immediately.
  • Tests cover: the wait engine, close() over HTTP (the interrupted result arrives promptly), a stalled request getting 503 after the grace period, and a real child process on SIGTERM (interrupted result, exit 0 in under 3 s).

Compatibility

  • Tool names are unchanged and new fields are additive.
  • whoami.transport changes from http to streamable-http.
  • add_recipients input is now recipients; add_to is still accepted.

Tests

  • New vitest coverage for: compressed messages whose short_text is the 768-byte prefix (client and tools), the structured notice and next fields, skipped reaction details, the add_to alias, attachment types, thread_topic, the timeout high-water mark, whoami text and directory, hidden-reaction unread counts, delivery codes, and titles/annotations for every tool.
  • typecheck, build and 180 tests pass.

🤖 Generated with Claude Code

markmnl and others added 2 commits October 9, 2026 18:02
- Never treat short_text as the whole body of a deflate-compressed
  message (size is the compressed wire size); report decoded body_bytes.
- Repeat the untrusted-content framing and next steps in structured
  results for hosts that show structuredContent instead of the text.
- wait_for_message: richer skipped entries (from, emoji, reaction_to),
  thread_topic, explicit after_id/turn guidance in the description.
- add_recipients takes recipients; add_to stays as a deprecated alias.
- Consistent attachment types (inferred from the filename when the host
  records none), including list items and send results.
- Accurate delivery code semantics with code_meaning.
- get_thread thread_topic; reactions labelled in lists and never counted
  as unread while hidden.
- whoami: stdio / streamable-http, no expiry in text, omit empty
  directory_names; resolve_address describes only configured steps.
- Mention save_attachment / download URLs only where registered; neutral
  wording in the server instructions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On SIGINT/SIGTERM or HttpServerHandle.close(), wait_for_message returns
at once with status "interrupted", the caller's after_id and a next step,
instead of hanging until the client's timeout. New requests get 503 with
Retry-After; other in-flight requests get a 5 s grace, then 503. The
process exits within a bounded time; a second signal exits immediately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@markmnl
markmnl merged commit a730d5c into main Oct 9, 2026
4 checks passed
@markmnl
markmnl deleted the connector-polish branch October 9, 2026 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant