Skip to content

Commit 9c76c24

Browse files
committed
Appends
1 parent 94c2d7a commit 9c76c24

16 files changed

Lines changed: 978 additions & 541 deletions

File tree

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,35 @@ function TextEditor({
240240

241241
useEffect(() => {
242242
if (streamingContent !== undefined) {
243-
setContent(streamingContent)
244-
contentRef.current = streamingContent
243+
// #region agent log
244+
fetch('http://127.0.0.1:7774/ingest/b056eec6-a1ee-457f-8556-85f94314ca06', {
245+
method: 'POST',
246+
headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': '6f10b0' },
247+
body: JSON.stringify({
248+
sessionId: '6f10b0',
249+
location: 'file-viewer.tsx:streaming-merge',
250+
message: 'TextEditor streaming merge',
251+
data: {
252+
fileId: file.id,
253+
fileName: file.name,
254+
fetchedLen: fetchedContent?.length ?? 0,
255+
streamingLen: streamingContent.length,
256+
mode: fetchedContent !== undefined ? 'append_to_fetched' : 'stream_only',
257+
},
258+
timestamp: Date.now(),
259+
hypothesisId: 'H9',
260+
}),
261+
}).catch(() => {})
262+
// #endregion
263+
const nextContent =
264+
fetchedContent === undefined
265+
? streamingContent
266+
: fetchedContent.endsWith(streamingContent) ||
267+
fetchedContent.endsWith(`\n${streamingContent}`)
268+
? fetchedContent
269+
: `${fetchedContent}\n${streamingContent}`
270+
setContent(nextContent)
271+
contentRef.current = nextContent
245272
initializedRef.current = true
246273
return
247274
}

apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useMemo } from 'react'
22
import { PillsRing } from '@/components/emcn'
3-
import { FunctionExecute } from '@/lib/copilot/generated/tool-catalog-v1'
3+
import { FunctionExecute, WorkspaceFile } from '@/lib/copilot/generated/tool-catalog-v1'
44
import type { ToolCallStatus } from '../../../../types'
55
import { getToolIcon } from '../../utils'
66

@@ -100,6 +100,18 @@ interface ToolCallItemProps {
100100
}
101101

102102
export function ToolCallItem({ toolName, displayTitle, status, streamingArgs }: ToolCallItemProps) {
103+
const liveWorkspaceFileTitle = useMemo(() => {
104+
if (toolName !== WorkspaceFile.id || !streamingArgs) return null
105+
const titleMatch = streamingArgs.match(/"title"\s*:\s*"([^"]+)"/)
106+
if (!titleMatch?.[1]) return null
107+
const unescaped = titleMatch[1]
108+
.replace(/\\u([0-9a-fA-F]{4})/g, (_, hex: string) =>
109+
String.fromCharCode(Number.parseInt(hex, 16))
110+
)
111+
.replace(/\\"/g, '"')
112+
.replace(/\\\\/g, '\\')
113+
return `Writing ${unescaped}`
114+
}, [toolName, streamingArgs])
103115
const extracted = useMemo(() => {
104116
if (toolName !== FunctionExecute.id || !streamingArgs) return null
105117
return extractFunctionExecutePreview(streamingArgs)
@@ -114,7 +126,9 @@ export function ToolCallItem({ toolName, displayTitle, status, streamingArgs }:
114126
<div className='flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center'>
115127
<StatusIcon status={status} toolName={toolName} />
116128
</div>
117-
<span className='font-base text-[13px] text-[var(--text-secondary)]'>{displayTitle}</span>
129+
<span className='font-base text-[13px] text-[var(--text-secondary)]'>
130+
{liveWorkspaceFileTitle || displayTitle}
131+
</span>
118132
</div>
119133
)
120134
}

apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ function parseBlocks(blocks: ContentBlock[]): MessageSegment[] {
210210
if (block.type === 'tool_call') {
211211
if (!block.toolCall) continue
212212
const tc = block.toolCall
213-
if (tc.name === ToolSearchToolRegex.id) continue
213+
if (tc.name === ToolSearchToolRegex.id || tc.name === 'set_file_context') continue
214214
if (tc.name === ReadTool.id && isToolResultRead(tc.params)) continue
215215
const isDispatch = SUBAGENT_KEYS.has(tc.name) && !tc.calledBy
216216

apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ interface ResourceContentProps {
5757
workspaceId: string
5858
resource: MothershipResource
5959
previewMode?: PreviewMode
60-
streamingFile?: { fileName: string; content: string } | null
60+
streamingFile?: { fileName: string; fileId?: string; content: string } | null
6161
genericResourceData?: GenericResourceData
6262
}
6363

@@ -102,6 +102,30 @@ export const ResourceContent = memo(function ResourceContent({
102102
}
103103
}, [workspaceId, streamFileName])
104104

105+
// #region agent log
106+
if (streamingFile) {
107+
fetch('http://127.0.0.1:7774/ingest/b056eec6-a1ee-457f-8556-85f94314ca06', {
108+
method: 'POST',
109+
headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': '6f10b0' },
110+
body: JSON.stringify({
111+
sessionId: '6f10b0',
112+
location: 'resource-content.tsx:render',
113+
message: 'ResourceContent render with streamingFile',
114+
data: {
115+
resourceId: resource.id,
116+
resourceType: resource.type,
117+
streamFileName: streamFileName,
118+
hasExtractedContent: streamingExtractedContent !== undefined,
119+
extractedLen: streamingExtractedContent?.length ?? 0,
120+
rawContentLen: streamingFile.content.length,
121+
},
122+
timestamp: Date.now(),
123+
hypothesisId: 'H3',
124+
}),
125+
}).catch(() => {})
126+
}
127+
// #endregion
128+
105129
if (streamingFile && resource.id === 'streaming-file') {
106130
return (
107131
<div className='flex h-full flex-col overflow-hidden'>
@@ -483,5 +507,6 @@ function extractFileContent(raw: string): string {
483507
.replace(/\\t/g, '\t')
484508
.replace(/\\r/g, '\r')
485509
.replace(/\\"/g, '"')
510+
.replace(/\\u([0-9a-fA-F]{4})/g, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)))
486511
.replace(/\\\\/g, '\\')
487512
}

apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/mothership-view.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,16 @@ function fileTitlesEquivalent(streamFileName: string, resourceTitle: string): bo
3434
* The synthetic `streaming-file` tab always shows it; a real file tab shows it when
3535
* the streamed `fileName` matches that resource (so users who stay on the open file see live text).
3636
*/
37-
function streamReferencesFileId(raw: string, fileId: string): boolean {
38-
if (!fileId) return false
39-
const escaped = fileId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
40-
return new RegExp(`"fileId"\\s*:\\s*"${escaped}"`).test(raw)
41-
}
42-
4337
function shouldShowStreamingFilePanel(
44-
streamingFile: { fileName: string; content: string } | null | undefined,
38+
streamingFile: { fileName: string; fileId?: string; content: string } | null | undefined,
4539
active: MothershipResource | null
4640
): boolean {
4741
if (!streamingFile || !active) return false
4842
if (active.id === 'streaming-file') return true
4943
if (active.type !== 'file') return false
5044
const fn = streamingFile.fileName.trim()
5145
if (fn && fileTitlesEquivalent(fn, active.title)) return true
52-
if (active.id && streamReferencesFileId(streamingFile.content, active.id)) return true
46+
if (active.id && streamingFile.fileId === active.id) return true
5347
return false
5448
}
5549

@@ -65,7 +59,7 @@ interface MothershipViewProps {
6559
onCollapse: () => void
6660
isCollapsed: boolean
6761
className?: string
68-
streamingFile?: { fileName: string; content: string } | null
62+
streamingFile?: { fileName: string; fileId?: string; content: string } | null
6963
genericResourceData?: GenericResourceData
7064
}
7165

0 commit comments

Comments
 (0)