Added automatic image resizing

This commit is contained in:
Armin Ronacher 2026-01-02 11:55:44 +01:00
parent fd35d9188c
commit 4a32af2532
10 changed files with 247 additions and 29 deletions

View file

@ -522,7 +522,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
const contextFiles = options.contextFiles ?? discoverContextFiles(cwd, agentDir);
time("discoverContextFiles");
const builtInTools = options.tools ?? createCodingTools(cwd);
const autoResizeImages = settingsManager.getImageAutoResize();
const builtInTools = options.tools ?? createCodingTools(cwd, { read: { autoResizeImages } });
time("createCodingTools");
let customToolsResult: CustomToolsLoadResult;

View file

@ -34,6 +34,10 @@ export interface TerminalSettings {
showImages?: boolean; // default: true (only relevant if terminal supports images)
}
export interface ImageSettings {
autoResize?: boolean; // default: true (resize images to 2000x2000 max for better model compatibility)
}
export interface Settings {
lastChangelogVersion?: string;
defaultProvider?: string;
@ -51,6 +55,7 @@ export interface Settings {
customTools?: string[]; // Array of custom tool file paths
skills?: SkillsSettings;
terminal?: TerminalSettings;
images?: ImageSettings;
enabledModels?: string[]; // Model patterns for cycling (same format as --models CLI flag)
}
@ -368,6 +373,18 @@ export class SettingsManager {
this.save();
}
getImageAutoResize(): boolean {
return this.settings.images?.autoResize ?? true;
}
setImageAutoResize(enabled: boolean): void {
if (!this.globalSettings.images) {
this.globalSettings.images = {};
}
this.globalSettings.images.autoResize = enabled;
this.save();
}
getEnabledModels(): string[] | undefined {
return this.settings.enabledModels;
}

View file

@ -3,7 +3,7 @@ export { createEditTool, editTool } from "./edit.js";
export { createFindTool, type FindToolDetails, findTool } from "./find.js";
export { createGrepTool, type GrepToolDetails, grepTool } from "./grep.js";
export { createLsTool, type LsToolDetails, lsTool } from "./ls.js";
export { createReadTool, type ReadToolDetails, readTool } from "./read.js";
export { createReadTool, type ReadToolDetails, type ReadToolOptions, readTool } from "./read.js";
export type { TruncationResult } from "./truncate.js";
export { createWriteTool, writeTool } from "./write.js";
@ -13,7 +13,7 @@ import { createEditTool, editTool } from "./edit.js";
import { createFindTool, findTool } from "./find.js";
import { createGrepTool, grepTool } from "./grep.js";
import { createLsTool, lsTool } from "./ls.js";
import { createReadTool, readTool } from "./read.js";
import { createReadTool, type ReadToolOptions, readTool } from "./read.js";
import { createWriteTool, writeTool } from "./write.js";
/** Tool type (AgentTool from pi-ai) */
@ -38,26 +38,31 @@ export const allTools = {
export type ToolName = keyof typeof allTools;
export interface ToolsOptions {
/** Options for the read tool */
read?: ReadToolOptions;
}
/**
* Create coding tools configured for a specific working directory.
*/
export function createCodingTools(cwd: string): Tool[] {
return [createReadTool(cwd), createBashTool(cwd), createEditTool(cwd), createWriteTool(cwd)];
export function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {
return [createReadTool(cwd, options?.read), createBashTool(cwd), createEditTool(cwd), createWriteTool(cwd)];
}
/**
* Create read-only tools configured for a specific working directory.
*/
export function createReadOnlyTools(cwd: string): Tool[] {
return [createReadTool(cwd), createGrepTool(cwd), createFindTool(cwd), createLsTool(cwd)];
export function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {
return [createReadTool(cwd, options?.read), createGrepTool(cwd), createFindTool(cwd), createLsTool(cwd)];
}
/**
* Create all tools configured for a specific working directory.
*/
export function createAllTools(cwd: string): Record<ToolName, Tool> {
export function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {
return {
read: createReadTool(cwd),
read: createReadTool(cwd, options?.read),
bash: createBashTool(cwd),
edit: createEditTool(cwd),
write: createWriteTool(cwd),

View file

@ -3,6 +3,7 @@ import type { ImageContent, TextContent } from "@mariozechner/pi-ai";
import { Type } from "@sinclair/typebox";
import { constants } from "fs";
import { access, readFile } from "fs/promises";
import { formatDimensionNote, resizeImage } from "../../utils/image-resize.js";
import { detectSupportedImageMimeTypeFromFile } from "../../utils/mime.js";
import { resolveReadPath } from "./path-utils.js";
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationResult, truncateHead } from "./truncate.js";
@ -17,7 +18,13 @@ export interface ReadToolDetails {
truncation?: TruncationResult;
}
export function createReadTool(cwd: string): AgentTool<typeof readSchema> {
export interface ReadToolOptions {
/** Whether to auto-resize images to 2000x2000 max. Default: true */
autoResizeImages?: boolean;
}
export function createReadTool(cwd: string, options?: ReadToolOptions): AgentTool<typeof readSchema> {
const autoResizeImages = options?.autoResizeImages ?? true;
return {
name: "read",
label: "read",
@ -72,10 +79,26 @@ export function createReadTool(cwd: string): AgentTool<typeof readSchema> {
const buffer = await readFile(absolutePath);
const base64 = buffer.toString("base64");
content = [
{ type: "text", text: `Read image file [${mimeType}]` },
{ type: "image", data: base64, mimeType },
];
if (autoResizeImages) {
// Resize image if needed
const resized = await resizeImage({ type: "image", data: base64, mimeType });
const dimensionNote = formatDimensionNote(resized);
let textNote = `Read image file [${resized.mimeType}]`;
if (dimensionNote) {
textNote += `\n${dimensionNote}`;
}
content = [
{ type: "text", text: textNote },
{ type: "image", data: resized.data, mimeType: resized.mimeType },
];
} else {
content = [
{ type: "text", text: `Read image file [${mimeType}]` },
{ type: "image", data: base64, mimeType },
];
}
} else {
// Read as text
const textContent = await readFile(absolutePath, "utf-8");