Skip to content

Commit 9f59927

Browse files
committed
Add supportsImages option to read_file tool and update docs
Introduces a supportsImages option to the read_file tool, updating its description to document image file support when enabled. Updates related tests and propagates the option through getNativeTools and buildNativeToolsArray to allow dynamic configuration based on model capabilities.
1 parent 1a7738e commit 9f59927

4 files changed

Lines changed: 110 additions & 4 deletions

File tree

extensions/roopik-roo/src/core/prompts/tools/native-tools/__tests__/read_file.spec.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,48 @@ describe("createReadFileTool", () => {
9696
})
9797
})
9898

99+
describe("supportsImages option", () => {
100+
it("should include image format documentation when supportsImages is true", () => {
101+
const tool = createReadFileTool({ supportsImages: true })
102+
const description = getFunctionDef(tool).description
103+
104+
expect(description).toContain(
105+
"Automatically processes and returns image files (PNG, JPG, JPEG, GIF, BMP, SVG, WEBP, ICO, AVIF) for visual analysis",
106+
)
107+
})
108+
109+
it("should not include image format documentation when supportsImages is false", () => {
110+
const tool = createReadFileTool({ supportsImages: false })
111+
const description = getFunctionDef(tool).description
112+
113+
expect(description).not.toContain(
114+
"Automatically processes and returns image files (PNG, JPG, JPEG, GIF, BMP, SVG, WEBP, ICO, AVIF) for visual analysis",
115+
)
116+
expect(description).toContain("may not handle other binary files properly")
117+
})
118+
119+
it("should default supportsImages to false", () => {
120+
const tool = createReadFileTool({})
121+
const description = getFunctionDef(tool).description
122+
123+
expect(description).not.toContain(
124+
"Automatically processes and returns image files (PNG, JPG, JPEG, GIF, BMP, SVG, WEBP, ICO, AVIF) for visual analysis",
125+
)
126+
})
127+
128+
it("should always include PDF and DOCX support in description", () => {
129+
const toolWithImages = createReadFileTool({ supportsImages: true })
130+
const toolWithoutImages = createReadFileTool({ supportsImages: false })
131+
132+
expect(getFunctionDef(toolWithImages).description).toContain(
133+
"Supports text extraction from PDF and DOCX files",
134+
)
135+
expect(getFunctionDef(toolWithoutImages).description).toContain(
136+
"Supports text extraction from PDF and DOCX files",
137+
)
138+
})
139+
})
140+
99141
describe("combined options", () => {
100142
it("should correctly combine low maxConcurrentFileReads with partialReadsEnabled", () => {
101143
const tool = createReadFileTool({
@@ -120,6 +162,49 @@ describe("createReadFileTool", () => {
120162
expect(description).not.toContain("line_ranges")
121163
expect(description).not.toContain("Example multiple files")
122164
})
165+
166+
it("should correctly combine partialReadsEnabled and supportsImages", () => {
167+
const tool = createReadFileTool({
168+
partialReadsEnabled: true,
169+
supportsImages: true,
170+
})
171+
const description = getFunctionDef(tool).description
172+
173+
// Should have both line_ranges and image support
174+
expect(description).toContain("line_ranges")
175+
expect(description).toContain(
176+
"Automatically processes and returns image files (PNG, JPG, JPEG, GIF, BMP, SVG, WEBP, ICO, AVIF) for visual analysis",
177+
)
178+
})
179+
180+
it("should work with partialReadsEnabled=false and supportsImages=true", () => {
181+
const tool = createReadFileTool({
182+
partialReadsEnabled: false,
183+
supportsImages: true,
184+
})
185+
const description = getFunctionDef(tool).description
186+
187+
// Should have image support but no line_ranges
188+
expect(description).not.toContain("line_ranges")
189+
expect(description).toContain(
190+
"Automatically processes and returns image files (PNG, JPG, JPEG, GIF, BMP, SVG, WEBP, ICO, AVIF) for visual analysis",
191+
)
192+
})
193+
194+
it("should correctly combine all three options", () => {
195+
const tool = createReadFileTool({
196+
maxConcurrentFileReads: 3,
197+
partialReadsEnabled: true,
198+
supportsImages: true,
199+
})
200+
const description = getFunctionDef(tool).description
201+
202+
expect(description).toContain("maximum of 3 files")
203+
expect(description).toContain("line_ranges")
204+
expect(description).toContain(
205+
"Automatically processes and returns image files (PNG, JPG, JPEG, GIF, BMP, SVG, WEBP, ICO, AVIF) for visual analysis",
206+
)
207+
})
123208
})
124209

125210
describe("tool structure", () => {

extensions/roopik-roo/src/core/prompts/tools/native-tools/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export interface NativeToolsOptions {
3434
partialReadsEnabled?: boolean
3535
/** Maximum number of files that can be read in a single read_file request (default: 5) */
3636
maxConcurrentFileReads?: number
37+
/** Whether the model supports image processing (default: false) */
38+
supportsImages?: boolean
3739
}
3840

3941
/**
@@ -43,11 +45,12 @@ export interface NativeToolsOptions {
4345
* @returns Array of native tool definitions
4446
*/
4547
export function getNativeTools(options: NativeToolsOptions = {}): OpenAI.Chat.ChatCompletionTool[] {
46-
const { partialReadsEnabled = true, maxConcurrentFileReads = 5 } = options
48+
const { partialReadsEnabled = true, maxConcurrentFileReads = 5, supportsImages = false } = options
4749

4850
const readFileOptions: ReadFileToolOptions = {
4951
partialReadsEnabled,
5052
maxConcurrentFileReads,
53+
supportsImages,
5154
}
5255

5356
return [

extensions/roopik-roo/src/core/prompts/tools/native-tools/read_file.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
import type OpenAI from "openai"
22

3-
const READ_FILE_SUPPORTS_NOTE = `Supports text extraction from PDF and DOCX files, but may not handle other binary files properly.`
3+
/**
4+
* Generates the file support note, optionally including image format support.
5+
*
6+
* @param supportsImages - Whether the model supports image processing
7+
* @returns Support note string
8+
*/
9+
function getReadFileSupportsNote(supportsImages: boolean): string {
10+
if (supportsImages) {
11+
return `Supports text extraction from PDF and DOCX files. Automatically processes and returns image files (PNG, JPG, JPEG, GIF, BMP, SVG, WEBP, ICO, AVIF) for visual analysis. May not handle other binary files properly.`
12+
}
13+
return `Supports text extraction from PDF and DOCX files, but may not handle other binary files properly.`
14+
}
415

516
/**
617
* Options for creating the read_file tool definition.
@@ -10,6 +21,8 @@ export interface ReadFileToolOptions {
1021
partialReadsEnabled?: boolean
1122
/** Maximum number of files that can be read in a single request (default: 5) */
1223
maxConcurrentFileReads?: number
24+
/** Whether the model supports image processing (default: false) */
25+
supportsImages?: boolean
1326
}
1427

1528
/**
@@ -20,7 +33,7 @@ export interface ReadFileToolOptions {
2033
* @returns Native tool definition for read_file
2134
*/
2235
export function createReadFileTool(options: ReadFileToolOptions = {}): OpenAI.Chat.ChatCompletionTool {
23-
const { partialReadsEnabled = true, maxConcurrentFileReads = 5 } = options
36+
const { partialReadsEnabled = true, maxConcurrentFileReads = 5, supportsImages = false } = options
2437
const isMultipleReadsEnabled = maxConcurrentFileReads > 1
2538

2639
// Build description intro with concurrent reads limit message
@@ -50,7 +63,8 @@ export function createReadFileTool(options: ReadFileToolOptions = {}): OpenAI.Ch
5063
? `Example multiple files (within ${maxConcurrentFileReads}-file limit): { files: [{ path: 'file1.ts' }, { path: 'file2.ts' }] }`
5164
: "")
5265

53-
const description = baseDescription + optionalRangesDescription + READ_FILE_SUPPORTS_NOTE + " " + examples
66+
const description =
67+
baseDescription + optionalRangesDescription + getReadFileSupportsNote(supportsImages) + " " + examples
5468

5569
// Build the properties object conditionally
5670
const fileProperties: Record<string, any> = {

extensions/roopik-roo/src/core/task/build-tools.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,14 @@ export async function buildNativeToolsArray(options: BuildToolsOptions): Promise
6464
// Determine if partial reads are enabled based on maxReadFileLine setting.
6565
const partialReadsEnabled = maxReadFileLine !== -1
6666

67+
// Check if the model supports images for read_file tool description.
68+
const supportsImages = modelInfo?.supportsImages ?? false
69+
6770
// Build native tools with dynamic read_file tool based on settings.
6871
const nativeTools = getNativeTools({
6972
partialReadsEnabled,
7073
maxConcurrentFileReads,
74+
supportsImages,
7175
})
7276

7377
// Filter native tools based on mode restrictions.

0 commit comments

Comments
 (0)