github assistant-ui/assistant-ui @assistant-ui/react-opencode@0.2.17

latest releases: @assistant-ui/react@0.15.4, assistant-stream@0.3.33, @assistant-ui/cloud-ai-sdk@0.1.29...
3 hours ago

Patch Changes

  • #5431 6a0f087 - fix: avoid repeated child session scans during streaming (@Kinfe123)

  • #5492 5003325 - feat: add OpenCodeAttachmentAdapter, converting browser files into attachments that preserve OpenCode's native file semantics (@okisdev)

  • #5490 e60694f - fix: project user file parts as message attachments instead of inline content, for server, pending, and shadow copies alike (@okisdev)

  • #5459 22b05a4 - fix: wrap a file part payload that is not a parsable url (@okisdev)

    getPromptParts put FileMessagePart.data straight into the OpenCode file part's url. OpenCode forwards that into an AI SDK file part (sst/opencode, session/message-v2.ts), whose url reaches an unguarded new URL(), so a payload that is raw base64 rather than a data URL or an http source failed there. A non-parsable payload is now wrapped in a data:<mime>;base64, envelope; data URLs and http sources are forwarded untouched, and a sourceType: "id" reference is left alone so it fails loudly instead of shipping a corrupt payload.

    The predicate behind that decision moves to isParsableUrl in @assistant-ui/core/internal, next to the httpUrlPattern and parseDataUrl it belongs with, and react-ai-sdk now imports it instead of keeping its own copy. No behavior change there.

  • #5468 3a7d091 - fix: send image parts as file parts so they reach the model (@okisdev)

    getPromptParts emitted { type: "image", image }, a part type OpenCode does not define: its input union is text, file, agent and subtask, and upstream's converter has no image branch, so an ImageMessagePart never reached the model. Images now go out as FilePartInput, with the media type read from the attachment's contentType, then a data URL envelope, then image/png as the floor, matching the ladder react-ai-sdk uses for the same input. An inline payload is re-enveloped with the resolved media type rather than forwarded, because the AI SDK lets a data URL's own type win over the declared one; the same now applies to file parts, whose declared mimeType was previously overridden by a mismatched envelope, and an empty mimeType floors to application/octet-stream rather than producing a malformed data:;base64, url.

    The attachment's own name and contentType now ride onto its flattened parts instead of being dropped, so an image attachment keeps its filename and its real media type. Both the outbound prompt and the pending optimistic copy share one flatten, so their reconciliation fingerprints agree; previously a named image attachment produced a pending contentText of the raw base64 payload.

  • #5491 9231e07 - fix: stop fingerprinting audio and data parts the outbound path never sends, so their pending copies reconcile with the server echo (@okisdev)

  • #5480 63f81ba - fix: reconcile pending file messages after OpenCode normalizes their wire URLs (@Kinfe123)

  • #5520 ff12cf2 - fix: isolate thread controller subscriber errors (@Kinfe123)

  • #5479 011e275 - fix: read an image's media type from its leading bytes in both adapters (@okisdev)

    detectImageMediaType and dataUrlMediaType join parseDataUrl and isParsableUrl in @assistant-ui/core/internal. An ImageMessagePart carries no media type, so an adapter that must declare one on the wire now reads it from the payload rather than assuming a format. It never throws, whatever a caller put on the part.

    react-ai-sdk and react-opencode run the same ladder rung for rung: the attachment's contentType, then a data URL's declared type when that is itself an image type (read whether or not the payload is base64, so an SVG data URL keeps its type), then the leading bytes, then image/png. Previously react-opencode had no byte rung at all, and react-ai-sdk's was skipped for any data: payload, so a JPEG inside a generic application/octet-stream envelope resolved to png on both.

    Resolving the label alone was not enough, because a data URL's own media type wins over the declared one downstream. Both adapters now rebuild the envelope when it disagrees with the resolved type and forward it untouched when it agrees. That applies to file parts too, where a mimeType: "application/pdf" part carrying an application/octet-stream envelope was announced as pdf and delivered as octet-stream. File parts also gain the same three rungs, so an empty mimeType falls to the envelope and then to application/octet-stream rather than producing a malformed data:;base64, url; vercelAttachmentAdapter emits exactly that shape for a file the OS cannot type.

  • #5485 da32fe0 - refactor: share the media type ladder and wire url between adapters (@okisdev)

    resolveImageMediaType, resolveFileMediaType and toMediaWireUrl join the data URL helpers in @assistant-ui/core/internal. react-ai-sdk and react-opencode had arrived at identical ladders and an identical wire url builder by construction rather than by sharing code, and they had already drifted apart twice while getting there. Both now call the shared functions and keep only their own part-shape plumbing.

    No behavior change: both adapters' existing suites pass untouched.

  • Updated dependencies [b19c2f5, 8c99934, ece5a54, 2fdff87, 90b3003, 55b2824, 22b05a4, f913c21, c868710, 011e275, da32fe0, f913c21, 5bb2573]:

    • @assistant-ui/core@0.3.4
    • @assistant-ui/store@0.3.3

Don't miss a new assistant-ui release

NewReleases is sending notifications on new releases.