Tool display intetns

This commit is contained in:
Siddharth Ganesan
2026-04-09 13:44:57 -07:00
parent e610df6843
commit fe5baf7569
5 changed files with 36 additions and 25 deletions

View File

@@ -838,6 +838,15 @@ function PptxPreview({
const [rendering, setRendering] = useState(false)
const [renderError, setRenderError] = useState<string | null>(null)
const shouldSuppressStreamingPptxError = (message: string): boolean => {
return (
message.includes('SyntaxError: Invalid or unexpected token') ||
message.includes('PPTX generation cancelled') ||
message.includes('Preview failed') ||
message.includes('AbortError')
)
}
// Streaming preview: only re-triggers when the streaming source code or
// workspace changes. Isolated from fileData/dataUpdatedAt so that file-list
// refreshes don't abort the in-flight compilation request.
@@ -879,8 +888,12 @@ function PptxPreview({
} catch (err) {
if (!cancelled && !(err instanceof DOMException && err.name === 'AbortError')) {
const msg = err instanceof Error ? err.message : 'Failed to render presentation'
logger.error('PPTX render failed', { error: msg })
setRenderError(msg)
if (shouldSuppressStreamingPptxError(msg)) {
logger.info('Suppressing transient PPTX streaming preview error', { error: msg })
} else {
logger.error('PPTX render failed', { error: msg })
setRenderError(msg)
}
}
} finally {
if (!cancelled) setRendering(false)

View File

@@ -269,12 +269,12 @@ export const TOOL_UI_METADATA: Record<string, ToolUIMetadata> = {
phase: 'resource',
},
[WorkspaceFile.id]: {
title: 'Managing file',
title: 'Declaring file intent',
phaseLabel: 'Resource',
phase: 'resource',
},
[EditContent.id]: {
title: 'Writing content',
title: 'Applying file content',
phaseLabel: 'Resource',
phase: 'resource',
},

View File

@@ -2587,7 +2587,7 @@ export const WorkspaceFile: ToolCatalogEntry = {
operation: {
type: 'string',
description: 'The file operation to perform.',
enum: ['append', 'update', 'patch', 'rename', 'delete'],
enum: ['append', 'update', 'patch'],
},
target: {
type: 'object',
@@ -2613,7 +2613,7 @@ export const WorkspaceFile: ToolCatalogEntry = {
title: {
type: 'string',
description:
'Optional short UI label for create/append chunks, e.g. "Chapter 1" or "Slide 3".',
'Required short UI label for this content unit, e.g. "Chapter 1", "Slide 3", or "Fix footer spacing".',
},
contentType: {
type: 'string',
@@ -2684,12 +2684,8 @@ export const WorkspaceFile: ToolCatalogEntry = {
},
},
},
newName: {
type: 'string',
description: 'New file name for rename. Must be a plain workspace filename like "main.py".',
},
},
required: ['operation', 'target'],
required: ['operation', 'target', 'title'],
},
resultSchema: {
type: 'object',

View File

@@ -2355,7 +2355,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
operation: {
type: 'string',
description: 'The file operation to perform.',
enum: ['append', 'update', 'patch', 'rename', 'delete'],
enum: ['append', 'update', 'patch'],
},
target: {
type: 'object',
@@ -2382,7 +2382,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
title: {
type: 'string',
description:
'Optional short UI label for create/append chunks, e.g. "Chapter 1" or "Slide 3".',
'Required short UI label for this content unit, e.g. "Chapter 1", "Slide 3", or "Fix footer spacing".',
},
contentType: {
type: 'string',
@@ -2453,13 +2453,8 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
},
},
newName: {
type: 'string',
description:
'New file name for rename. Must be a plain workspace filename like "main.py".',
},
},
required: ['operation', 'target'],
required: ['operation', 'target', 'title'],
},
resultSchema: {
type: 'object',

View File

@@ -21,6 +21,10 @@ function isOversizedReadPlaceholder(content: string): boolean {
)
}
function hasImageAttachment(result: { attachment?: { type?: string } }): boolean {
return result.attachment?.type === 'image'
}
export async function executeVfsGrep(
params: Record<string, unknown>,
context: ExecutionContext
@@ -153,8 +157,9 @@ export async function executeVfsRead(
const uploadResult = await readChatUpload(filename, context.chatId)
if (uploadResult) {
if (
isOversizedReadPlaceholder(uploadResult.content) ||
serializedResultSize(uploadResult) > TOOL_RESULT_MAX_INLINE_CHARS
!hasImageAttachment(uploadResult) &&
(isOversizedReadPlaceholder(uploadResult.content) ||
serializedResultSize(uploadResult) > TOOL_RESULT_MAX_INLINE_CHARS)
) {
return {
success: false,
@@ -183,8 +188,9 @@ export async function executeVfsRead(
const fileContent = await vfs.readFileContent(path)
if (fileContent) {
if (
isOversizedReadPlaceholder(fileContent.content) ||
serializedResultSize(fileContent) > TOOL_RESULT_MAX_INLINE_CHARS
!hasImageAttachment(fileContent) &&
(isOversizedReadPlaceholder(fileContent.content) ||
serializedResultSize(fileContent) > TOOL_RESULT_MAX_INLINE_CHARS)
) {
return {
success: false,
@@ -214,8 +220,9 @@ export async function executeVfsRead(
return { success: false, error: `File not found: ${path}.${hint}` }
}
if (
isOversizedReadPlaceholder(result.content) ||
serializedResultSize(result) > TOOL_RESULT_MAX_INLINE_CHARS
!hasImageAttachment(result) &&
(isOversizedReadPlaceholder(result.content) ||
serializedResultSize(result) > TOOL_RESULT_MAX_INLINE_CHARS)
) {
return {
success: false,