mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
Rename server->core (#638)
This commit is contained in:
committed by
GitHub
parent
c81148a0cc
commit
21fba832d1
131
packages/core/src/tools/read-file.ts
Normal file
131
packages/core/src/tools/read-file.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import { SchemaValidator } from '../utils/schemaValidator.js';
|
||||
import { makeRelative, shortenPath } from '../utils/paths.js';
|
||||
import { BaseTool, ToolResult } from './tools.js';
|
||||
import { isWithinRoot, processSingleFileContent } from '../utils/fileUtils.js';
|
||||
|
||||
/**
|
||||
* Parameters for the ReadFile tool
|
||||
*/
|
||||
export interface ReadFileToolParams {
|
||||
/**
|
||||
* The absolute path to the file to read
|
||||
*/
|
||||
path: string;
|
||||
|
||||
/**
|
||||
* The line number to start reading from (optional)
|
||||
*/
|
||||
offset?: number;
|
||||
|
||||
/**
|
||||
* The number of lines to read (optional)
|
||||
*/
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the ReadFile tool logic
|
||||
*/
|
||||
export class ReadFileTool extends BaseTool<ReadFileToolParams, ToolResult> {
|
||||
static readonly Name: string = 'read_file';
|
||||
|
||||
constructor(private rootDirectory: string) {
|
||||
super(
|
||||
ReadFileTool.Name,
|
||||
'ReadFile',
|
||||
'Reads and returns the content of a specified file from the local filesystem. Handles text, images (PNG, JPG, GIF, WEBP, SVG, BMP), and PDF files. For text files, it can read specific line ranges.',
|
||||
{
|
||||
properties: {
|
||||
path: {
|
||||
description:
|
||||
"The absolute path to the file to read (e.g., '/home/user/project/file.txt'). Relative paths are not supported.",
|
||||
type: 'string',
|
||||
},
|
||||
offset: {
|
||||
description:
|
||||
"Optional: For text files, the 0-based line number to start reading from. Requires 'limit' to be set. Use for paginating through large files.",
|
||||
type: 'number',
|
||||
},
|
||||
limit: {
|
||||
description:
|
||||
"Optional: For text files, maximum number of lines to read. Use with 'offset' to paginate through large files. If omitted, reads the entire file (if feasible, up to a default limit).",
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
required: ['path'],
|
||||
type: 'object',
|
||||
},
|
||||
);
|
||||
this.rootDirectory = path.resolve(rootDirectory);
|
||||
}
|
||||
|
||||
validateToolParams(params: ReadFileToolParams): string | null {
|
||||
if (
|
||||
this.schema.parameters &&
|
||||
!SchemaValidator.validate(
|
||||
this.schema.parameters as Record<string, unknown>,
|
||||
params,
|
||||
)
|
||||
) {
|
||||
return 'Parameters failed schema validation.';
|
||||
}
|
||||
const filePath = params.path;
|
||||
if (!path.isAbsolute(filePath)) {
|
||||
return `File path must be absolute: ${filePath}`;
|
||||
}
|
||||
if (!isWithinRoot(filePath, this.rootDirectory)) {
|
||||
return `File path must be within the root directory (${this.rootDirectory}): ${filePath}`;
|
||||
}
|
||||
if (params.offset !== undefined && params.offset < 0) {
|
||||
return 'Offset must be a non-negative number';
|
||||
}
|
||||
if (params.limit !== undefined && params.limit <= 0) {
|
||||
return 'Limit must be a positive number';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getDescription(params: ReadFileToolParams): string {
|
||||
const relativePath = makeRelative(params.path, this.rootDirectory);
|
||||
return shortenPath(relativePath);
|
||||
}
|
||||
|
||||
async execute(
|
||||
params: ReadFileToolParams,
|
||||
_signal: AbortSignal,
|
||||
): Promise<ToolResult> {
|
||||
const validationError = this.validateToolParams(params);
|
||||
if (validationError) {
|
||||
return {
|
||||
llmContent: `Error: Invalid parameters provided. Reason: ${validationError}`,
|
||||
returnDisplay: validationError,
|
||||
};
|
||||
}
|
||||
|
||||
const result = await processSingleFileContent(
|
||||
params.path,
|
||||
this.rootDirectory,
|
||||
params.offset,
|
||||
params.limit,
|
||||
);
|
||||
|
||||
if (result.error) {
|
||||
return {
|
||||
llmContent: result.error, // The detailed error for LLM
|
||||
returnDisplay: result.returnDisplay, // User-friendly error
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
llmContent: result.llmContent,
|
||||
returnDisplay: result.returnDisplay,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user