@@ -77,11 +77,16 @@ export const ResourceContent = memo(function ResourceContent({
7777} : ResourceContentProps ) {
7878 const streamFileName = streamingFile ?. fileName || 'file.md'
7979
80- const isPatchStream = useMemo ( ( ) => {
81- if ( ! streamingFile ) return false
82- return / " o p e r a t i o n " \s * : \s * " p a t c h " / . test ( streamingFile . content )
80+ const streamOperation = useMemo ( ( ) => {
81+ if ( ! streamingFile ) return undefined
82+ const m = streamingFile . content . match ( / " o p e r a t i o n " \s * : \s * " ( \w + ) " / )
83+ return m ?. [ 1 ]
8384 } , [ streamingFile ] )
8485
86+ const isWriteStream = streamOperation === 'write'
87+ const isPatchStream = streamOperation === 'patch'
88+ const isUpdateStream = streamOperation === 'update'
89+
8590 const { data : allFiles = [ ] } = useWorkspaceFiles ( workspaceId )
8691 const activeFileRecord = useMemo ( ( ) => {
8792 if ( ! isPatchStream || resource . type !== 'file' ) return undefined
@@ -104,13 +109,25 @@ export const ResourceContent = memo(function ResourceContent({
104109 if ( ! streamingFile ) return undefined
105110 const raw = streamingFile . content
106111
107- if ( isPatchStream && fetchedFileContent ) {
112+ // Do not guess. Until the operation key has streamed in, we don't know
113+ // whether the payload should append, replace, or splice into the file.
114+ // Rendering early here can show content at the end of the file and then
115+ // "snap" to the right place once the operation/mode becomes known.
116+ if ( ! streamOperation ) return undefined
117+
118+ if ( isPatchStream ) {
119+ if ( ! fetchedFileContent ) return undefined
108120 return extractPatchPreview ( raw , fetchedFileContent )
109121 }
110122
111123 const extracted = extractFileContent ( raw )
112- return extracted . length > 0 ? extracted : undefined
113- } , [ streamingFile , isPatchStream , fetchedFileContent ] )
124+ if ( extracted . length === 0 ) return undefined
125+
126+ if ( isUpdateStream ) return extracted
127+ if ( isWriteStream ) return extracted
128+
129+ return undefined
130+ } , [ streamingFile , streamOperation , isWriteStream , isPatchStream , isUpdateStream , fetchedFileContent ] )
114131 const syntheticFile = useMemo ( ( ) => {
115132 const ext = getFileExtension ( streamFileName )
116133 const SOURCE_MIME_MAP : Record < string , string > = {
@@ -132,6 +149,9 @@ export const ResourceContent = memo(function ResourceContent({
132149 }
133150 } , [ workspaceId , streamFileName ] )
134151
152+ const streamingFileMode : 'append' | 'replace' =
153+ isWriteStream ? 'append' : 'replace'
154+
135155 if ( streamingFile && resource . id === 'streaming-file' ) {
136156 return (
137157 < div className = 'flex h-full flex-col overflow-hidden' >
@@ -142,6 +162,7 @@ export const ResourceContent = memo(function ResourceContent({
142162 canEdit = { false }
143163 previewMode = { previewMode ?? 'preview' }
144164 streamingContent = { streamingExtractedContent }
165+ streamingMode = { streamingFileMode }
145166 />
146167 ) : (
147168 < div className = 'flex h-full items-center justify-center' >
@@ -164,6 +185,7 @@ export const ResourceContent = memo(function ResourceContent({
164185 fileId = { resource . id }
165186 previewMode = { previewMode }
166187 streamingContent = { streamingExtractedContent }
188+ streamingMode = { streamingFileMode }
167189 />
168190 )
169191
@@ -448,9 +470,10 @@ interface EmbeddedFileProps {
448470 fileId : string
449471 previewMode ?: PreviewMode
450472 streamingContent ?: string
473+ streamingMode ?: 'append' | 'replace'
451474}
452475
453- function EmbeddedFile ( { workspaceId, fileId, previewMode, streamingContent } : EmbeddedFileProps ) {
476+ function EmbeddedFile ( { workspaceId, fileId, previewMode, streamingContent, streamingMode } : EmbeddedFileProps ) {
454477 const { canEdit } = useUserPermissionsContext ( )
455478 const { data : files = [ ] , isLoading, isFetching } = useWorkspaceFiles ( workspaceId )
456479 const file = useMemo ( ( ) => files . find ( ( f ) => f . id === fileId ) , [ files , fileId ] )
@@ -478,6 +501,7 @@ function EmbeddedFile({ workspaceId, fileId, previewMode, streamingContent }: Em
478501 file = { file }
479502 workspaceId = { workspaceId }
480503 canEdit = { canEdit }
504+ streamingMode = { streamingMode }
481505 previewMode = { previewMode }
482506 streamingContent = { streamingContent }
483507 />
0 commit comments