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)getPromptPartsputFileMessagePart.datastraight into the OpenCode file part'surl. OpenCode forwards that into an AI SDK file part (sst/opencode,session/message-v2.ts), whoseurlreaches an unguardednew 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 adata:<mime>;base64,envelope; data URLs and http sources are forwarded untouched, and asourceType: "id"reference is left alone so it fails loudly instead of shipping a corrupt payload.The predicate behind that decision moves to
isParsableUrlin@assistant-ui/core/internal, next to thehttpUrlPatternandparseDataUrlit 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)getPromptPartsemitted{ 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 anImageMessagePartnever reached the model. Images now go out asFilePartInput, with the media type read from the attachment'scontentType, then a data URL envelope, thenimage/pngas 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 declaredmimeTypewas previously overridden by a mismatched envelope, and an emptymimeTypefloors toapplication/octet-streamrather than producing a malformeddata:;base64,url.The attachment's own
nameandcontentTypenow 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 pendingcontentTextof 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)detectImageMediaTypeanddataUrlMediaTypejoinparseDataUrlandisParsableUrlin@assistant-ui/core/internal. AnImageMessagePartcarries 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, thenimage/png. Previously react-opencode had no byte rung at all, and react-ai-sdk's was skipped for anydata:payload, so a JPEG inside a genericapplication/octet-streamenvelope 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 anapplication/octet-streamenvelope was announced as pdf and delivered as octet-stream. File parts also gain the same three rungs, so an emptymimeTypefalls to the envelope and then toapplication/octet-streamrather than producing a malformeddata:;base64,url;vercelAttachmentAdapteremits 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,resolveFileMediaTypeandtoMediaWireUrljoin 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