pass @-mention notes by reference, not by inlined content

Mentions now route through the structured-attachment path, sending
only path/filename/mimeType. The agent fetches content on demand via
workspace-readFile (line-prefixed, paginated). Avoids freezing a stale
snapshot of the note into the conversation and saves tokens on long
notes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ramnique Singh 2026-04-13 14:59:36 +05:30
parent f4dc5e7db4
commit 4a2dfbf16f

View file

@ -2144,8 +2144,9 @@ function App() {
} }
let titleSource = userMessage let titleSource = userMessage
const hasMentions = (mentions?.length ?? 0) > 0
if (hasAttachments) { if (hasAttachments || hasMentions) {
type ContentPart = type ContentPart =
| { type: 'text'; text: string } | { type: 'text'; text: string }
| { | {
@ -2182,7 +2183,7 @@ function App() {
if (userMessage) { if (userMessage) {
contentParts.push({ type: 'text', text: userMessage }) contentParts.push({ type: 'text', text: userMessage })
} else { } else {
titleSource = stagedAttachments[0]?.filename ?? '' titleSource = stagedAttachments[0]?.filename ?? mentions?.[0]?.displayName ?? mentions?.[0]?.path ?? ''
} }
// Shared IPC payload types can lag until package rebuilds; runtime validation still enforces schema. // Shared IPC payload types can lag until package rebuilds; runtime validation still enforces schema.
@ -2200,32 +2201,9 @@ function App() {
searchEnabled: searchEnabled || undefined, searchEnabled: searchEnabled || undefined,
}) })
} else { } else {
// Legacy path: plain string with optional XML-formatted @mentions.
let formattedMessage = userMessage
if (mentions && mentions.length > 0) {
const attachedFiles = await Promise.all(
mentions.map(async (mention) => {
try {
const result = await window.ipc.invoke('workspace:readFile', { path: mention.path })
return { path: mention.path, content: result.data as string }
} catch (err) {
console.error('Failed to read mentioned file:', mention.path, err)
return { path: mention.path, content: `[Error reading file: ${mention.path}]` }
}
})
)
if (attachedFiles.length > 0) {
const filesXml = attachedFiles
.map((file) => `<file path="${file.path}">\n${file.content}\n</file>`)
.join('\n')
formattedMessage = `<attached-files>\n${filesXml}\n</attached-files>\n\n${userMessage}`
}
}
await window.ipc.invoke('runs:createMessage', { await window.ipc.invoke('runs:createMessage', {
runId: currentRunId, runId: currentRunId,
message: formattedMessage, message: userMessage,
voiceInput: pendingVoiceInputRef.current || undefined, voiceInput: pendingVoiceInputRef.current || undefined,
voiceOutput: ttsEnabledRef.current ? ttsModeRef.current : undefined, voiceOutput: ttsEnabledRef.current ? ttsModeRef.current : undefined,
searchEnabled: searchEnabled || undefined, searchEnabled: searchEnabled || undefined,
@ -2235,8 +2213,6 @@ function App() {
voiceOutput: ttsEnabledRef.current ? ttsModeRef.current : undefined, voiceOutput: ttsEnabledRef.current ? ttsModeRef.current : undefined,
searchEnabled: searchEnabled || undefined, searchEnabled: searchEnabled || undefined,
}) })
titleSource = formattedMessage
} }
pendingVoiceInputRef.current = false pendingVoiceInputRef.current = false