@vybestack/llxprt-code-core 0.5.0-nightly.251105.e148f3d8 → 0.5.0-nightly.251106.c2b44a77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/prompt-config/defaults/default-prompts.json +3 -0
- package/dist/src/auth/precedence.js +1 -1
- package/dist/src/auth/precedence.js.map +1 -1
- package/dist/src/config/config.js +6 -0
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/prompt-config/defaults/tool-defaults.js +3 -0
- package/dist/src/prompt-config/defaults/tool-defaults.js.map +1 -1
- package/dist/src/prompt-config/defaults/tools/delete_line_range.md +3 -0
- package/dist/src/prompt-config/defaults/tools/insert_at_line.md +3 -0
- package/dist/src/prompt-config/defaults/tools/read_line_range.md +2 -0
- package/dist/src/providers/BaseProvider.d.ts +5 -0
- package/dist/src/providers/BaseProvider.js +38 -2
- package/dist/src/providers/BaseProvider.js.map +1 -1
- package/dist/src/providers/anthropic/AnthropicProvider.d.ts +4 -0
- package/dist/src/providers/anthropic/AnthropicProvider.js +34 -2
- package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -1
- package/dist/src/providers/gemini/GeminiProvider.d.ts +0 -4
- package/dist/src/providers/gemini/GeminiProvider.js +35 -66
- package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
- package/dist/src/providers/openai/OpenAIProvider.d.ts +0 -5
- package/dist/src/providers/openai/OpenAIProvider.js +21 -31
- package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
- package/dist/src/tools/delete_line_range.d.ts +34 -0
- package/dist/src/tools/delete_line_range.js +147 -0
- package/dist/src/tools/delete_line_range.js.map +1 -0
- package/dist/src/tools/insert_at_line.d.ts +34 -0
- package/dist/src/tools/insert_at_line.js +164 -0
- package/dist/src/tools/insert_at_line.js.map +1 -0
- package/dist/src/tools/read_line_range.d.ts +34 -0
- package/dist/src/tools/read_line_range.js +119 -0
- package/dist/src/tools/read_line_range.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { makeRelative, shortenPath } from '../utils/paths.js';
|
|
8
|
+
import { BaseDeclarativeTool, BaseToolInvocation, Kind, } from './tools.js';
|
|
9
|
+
import { ToolErrorType } from './tool-error.js';
|
|
10
|
+
import { recordFileOperationMetric, FileOperation, } from '../telemetry/metrics.js';
|
|
11
|
+
import { getSpecificMimeType } from '../utils/fileUtils.js';
|
|
12
|
+
import { isNodeError } from '../utils/errors.js';
|
|
13
|
+
class InsertAtLineToolInvocation extends BaseToolInvocation {
|
|
14
|
+
config;
|
|
15
|
+
constructor(config, params) {
|
|
16
|
+
super(params);
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
19
|
+
getDescription() {
|
|
20
|
+
const relativePath = makeRelative(this.params.absolute_path, this.config.getTargetDir());
|
|
21
|
+
return `Insert content at line ${this.params.line_number} in ${shortenPath(relativePath)}`;
|
|
22
|
+
}
|
|
23
|
+
toolLocations() {
|
|
24
|
+
return [{ path: this.params.absolute_path, line: this.params.line_number }];
|
|
25
|
+
}
|
|
26
|
+
async execute() {
|
|
27
|
+
const fileService = this.config.getFileSystemService();
|
|
28
|
+
// Read the file content
|
|
29
|
+
let content;
|
|
30
|
+
let fileExists = true;
|
|
31
|
+
try {
|
|
32
|
+
content = await fileService.readTextFile(this.params.absolute_path);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (isNodeError(error) && error.code === 'ENOENT') {
|
|
36
|
+
// File doesn't exist - only allow insertion at line 1
|
|
37
|
+
if (this.params.line_number !== 1) {
|
|
38
|
+
return {
|
|
39
|
+
llmContent: `Cannot insert at line ${this.params.line_number}: file does not exist. For new files, you can only insert at line_number: 1`,
|
|
40
|
+
returnDisplay: `Cannot insert at line ${this.params.line_number}: file does not exist`,
|
|
41
|
+
error: {
|
|
42
|
+
message: `File does not exist, can only insert at line 1`,
|
|
43
|
+
type: ToolErrorType.INVALID_TOOL_PARAMS,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
content = '';
|
|
48
|
+
fileExists = false;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return {
|
|
52
|
+
llmContent: `Error reading file: ${error instanceof Error ? error.message : String(error)}`,
|
|
53
|
+
returnDisplay: `Error reading file: ${error instanceof Error ? error.message : String(error)}`,
|
|
54
|
+
error: {
|
|
55
|
+
message: error instanceof Error ? error.message : String(error),
|
|
56
|
+
type: ToolErrorType.FILE_NOT_FOUND,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Split into lines
|
|
62
|
+
const lines = content.split('\n');
|
|
63
|
+
// Validate line number
|
|
64
|
+
const totalLines = lines.length;
|
|
65
|
+
if (fileExists && this.params.line_number > totalLines + 1) {
|
|
66
|
+
return {
|
|
67
|
+
llmContent: `Cannot insert at line ${this.params.line_number}: exceeds file length (${totalLines}). Use line_number <= ${totalLines + 1} to append.`,
|
|
68
|
+
returnDisplay: `Cannot insert at line ${this.params.line_number}: exceeds file length (${totalLines})`,
|
|
69
|
+
error: {
|
|
70
|
+
message: `line_number ${this.params.line_number} exceeds file length (${totalLines})`,
|
|
71
|
+
type: ToolErrorType.INVALID_TOOL_PARAMS,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// Calculate 0-based insertion index
|
|
76
|
+
const insertIndex = this.params.line_number - 1;
|
|
77
|
+
// Split new content into lines
|
|
78
|
+
const newLines = this.params.content.split('\n');
|
|
79
|
+
// Insert the lines
|
|
80
|
+
lines.splice(insertIndex, 0, ...newLines);
|
|
81
|
+
// Join back
|
|
82
|
+
const newContent = lines.join('\n');
|
|
83
|
+
// Write back
|
|
84
|
+
try {
|
|
85
|
+
await fileService.writeTextFile(this.params.absolute_path, newContent);
|
|
86
|
+
// Record metrics
|
|
87
|
+
const linesInserted = newLines.length;
|
|
88
|
+
const mimetype = getSpecificMimeType(this.params.absolute_path);
|
|
89
|
+
recordFileOperationMetric(this.config, fileExists ? FileOperation.UPDATE : FileOperation.CREATE, linesInserted, mimetype, path.extname(this.params.absolute_path));
|
|
90
|
+
const action = fileExists ? 'inserted' : 'created and inserted';
|
|
91
|
+
return {
|
|
92
|
+
llmContent: `Successfully ${action} content at line ${this.params.line_number} in ${this.params.absolute_path}`,
|
|
93
|
+
returnDisplay: `${action.charAt(0).toUpperCase() + action.slice(1)} ${linesInserted} lines at line ${this.params.line_number}`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
llmContent: `Error writing file: ${error instanceof Error ? error.message : String(error)}`,
|
|
99
|
+
returnDisplay: `Error writing file: ${error instanceof Error ? error.message : String(error)}`,
|
|
100
|
+
error: {
|
|
101
|
+
message: error instanceof Error ? error.message : String(error),
|
|
102
|
+
type: ToolErrorType.FILE_WRITE_FAILURE,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Implementation of the InsertAtLine tool logic
|
|
110
|
+
*/
|
|
111
|
+
export class InsertAtLineTool extends BaseDeclarativeTool {
|
|
112
|
+
config;
|
|
113
|
+
static Name = 'insert_at_line';
|
|
114
|
+
constructor(config) {
|
|
115
|
+
super(InsertAtLineTool.Name, 'InsertAtLine', `Inserts new content at a specific line in a file. This is the "paste" operation for refactoring. The 'line_number' is 1-based. The new content will be inserted *before* this line number. To prepend to the top of a file, use 'line_number: 1'. If 'line_number' is greater than the total lines, the content will be appended to the end of the file.`, Kind.Edit, {
|
|
116
|
+
properties: {
|
|
117
|
+
absolute_path: {
|
|
118
|
+
description: "The absolute path to the file to modify. Must start with '/' and be within the workspace.",
|
|
119
|
+
type: 'string',
|
|
120
|
+
},
|
|
121
|
+
line_number: {
|
|
122
|
+
description: 'The 1-based line number to insert before. Content will be inserted before this line.',
|
|
123
|
+
type: 'number',
|
|
124
|
+
minimum: 1,
|
|
125
|
+
},
|
|
126
|
+
content: {
|
|
127
|
+
description: 'The content to insert at the specified line.',
|
|
128
|
+
type: 'string',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
required: ['absolute_path', 'line_number', 'content'],
|
|
132
|
+
type: 'object',
|
|
133
|
+
});
|
|
134
|
+
this.config = config;
|
|
135
|
+
}
|
|
136
|
+
validateToolParamValues(params) {
|
|
137
|
+
if (!params.absolute_path || params.absolute_path.trim() === '') {
|
|
138
|
+
return "The 'absolute_path' parameter must be non-empty.";
|
|
139
|
+
}
|
|
140
|
+
if (!path.isAbsolute(params.absolute_path)) {
|
|
141
|
+
return `File path must be absolute: ${params.absolute_path}`;
|
|
142
|
+
}
|
|
143
|
+
const workspaceContext = this.config.getWorkspaceContext();
|
|
144
|
+
if (!workspaceContext.isPathWithinWorkspace(params.absolute_path)) {
|
|
145
|
+
const directories = workspaceContext.getDirectories();
|
|
146
|
+
return `File path must be within one of the workspace directories: ${directories.join(', ')}`;
|
|
147
|
+
}
|
|
148
|
+
if (params.line_number < 1) {
|
|
149
|
+
return 'line_number must be a positive integer (>= 1)';
|
|
150
|
+
}
|
|
151
|
+
if (!params.content) {
|
|
152
|
+
return 'content parameter must be provided and non-empty';
|
|
153
|
+
}
|
|
154
|
+
const fileService = this.config.getFileService();
|
|
155
|
+
if (fileService.shouldLlxprtIgnoreFile(params.absolute_path)) {
|
|
156
|
+
return `File path '${params.absolute_path}' is ignored by .llxprtignore pattern(s).`;
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
createInvocation(params) {
|
|
161
|
+
return new InsertAtLineToolInvocation(this.config, params);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=insert_at_line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insert_at_line.js","sourceRoot":"","sources":["../../../src/tools/insert_at_line.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { BaseDeclarativeTool, ToolInvocation, ToolResult } from './tools.js';
|
|
7
|
+
import { Config } from '../config/config.js';
|
|
8
|
+
/**
|
|
9
|
+
* Parameters for the ReadLineRange tool
|
|
10
|
+
*/
|
|
11
|
+
export interface ReadLineRangeToolParams {
|
|
12
|
+
/**
|
|
13
|
+
* The absolute path to the file to read
|
|
14
|
+
*/
|
|
15
|
+
absolute_path: string;
|
|
16
|
+
/**
|
|
17
|
+
* The 1-based line number to start reading from (inclusive)
|
|
18
|
+
*/
|
|
19
|
+
start_line: number;
|
|
20
|
+
/**
|
|
21
|
+
* The 1-based line number to end reading at (inclusive)
|
|
22
|
+
*/
|
|
23
|
+
end_line: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Implementation of the ReadLineRange tool logic
|
|
27
|
+
*/
|
|
28
|
+
export declare class ReadLineRangeTool extends BaseDeclarativeTool<ReadLineRangeToolParams, ToolResult> {
|
|
29
|
+
private config;
|
|
30
|
+
static readonly Name: string;
|
|
31
|
+
constructor(config: Config);
|
|
32
|
+
protected validateToolParamValues(params: ReadLineRangeToolParams): string | null;
|
|
33
|
+
protected createInvocation(params: ReadLineRangeToolParams): ToolInvocation<ReadLineRangeToolParams, ToolResult>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { makeRelative, shortenPath } from '../utils/paths.js';
|
|
8
|
+
import { BaseDeclarativeTool, BaseToolInvocation, Kind, } from './tools.js';
|
|
9
|
+
import { processSingleFileContent, getSpecificMimeType, } from '../utils/fileUtils.js';
|
|
10
|
+
import { recordFileOperationMetric, FileOperation, } from '../telemetry/metrics.js';
|
|
11
|
+
class ReadLineRangeToolInvocation extends BaseToolInvocation {
|
|
12
|
+
config;
|
|
13
|
+
constructor(config, params) {
|
|
14
|
+
super(params);
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
getDescription() {
|
|
18
|
+
const relativePath = makeRelative(this.params.absolute_path, this.config.getTargetDir());
|
|
19
|
+
return shortenPath(relativePath);
|
|
20
|
+
}
|
|
21
|
+
toolLocations() {
|
|
22
|
+
return [{ path: this.params.absolute_path, line: this.params.start_line }];
|
|
23
|
+
}
|
|
24
|
+
async execute() {
|
|
25
|
+
// Convert 1-based line numbers to 0-based offset and limit
|
|
26
|
+
const offset = this.params.start_line - 1;
|
|
27
|
+
const limit = this.params.end_line - this.params.start_line + 1;
|
|
28
|
+
const result = await processSingleFileContent(this.params.absolute_path, this.config.getTargetDir(), this.config.getFileSystemService(), offset, limit);
|
|
29
|
+
if (result.error) {
|
|
30
|
+
return {
|
|
31
|
+
llmContent: result.llmContent,
|
|
32
|
+
returnDisplay: result.returnDisplay || 'Error reading file',
|
|
33
|
+
error: {
|
|
34
|
+
message: result.error,
|
|
35
|
+
type: result.errorType,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
let llmContent;
|
|
40
|
+
if (result.isTruncated) {
|
|
41
|
+
const [start, end] = result.linesShown;
|
|
42
|
+
const total = result.originalLineCount;
|
|
43
|
+
llmContent = `\nIMPORTANT: The file content has been truncated.\nStatus: Showing lines ${start}-${end} of ${total} total lines.\nAction: To read more of the file, you can use the 'read_file' tool with 'offset' and 'limit' parameters.\n\n--- FILE CONTENT (truncated) ---\n${result.llmContent}`;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
llmContent = result.llmContent || '';
|
|
47
|
+
}
|
|
48
|
+
const lines = typeof result.llmContent === 'string'
|
|
49
|
+
? result.llmContent.split('\n').length
|
|
50
|
+
: undefined;
|
|
51
|
+
const mimetype = getSpecificMimeType(this.params.absolute_path);
|
|
52
|
+
recordFileOperationMetric(this.config, FileOperation.READ, lines, mimetype, path.extname(this.params.absolute_path));
|
|
53
|
+
return {
|
|
54
|
+
llmContent,
|
|
55
|
+
returnDisplay: result.returnDisplay || '',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Implementation of the ReadLineRange tool logic
|
|
61
|
+
*/
|
|
62
|
+
export class ReadLineRangeTool extends BaseDeclarativeTool {
|
|
63
|
+
config;
|
|
64
|
+
static Name = 'read_line_range';
|
|
65
|
+
constructor(config) {
|
|
66
|
+
super(ReadLineRangeTool.Name, 'ReadLineRange', `Reads a specific range of lines from a file. This is very useful for "copying" a function or class after finding its definition. The 'start_line' and 'end_line' parameters are 1-based and inclusive.`, Kind.Read, {
|
|
67
|
+
properties: {
|
|
68
|
+
absolute_path: {
|
|
69
|
+
description: "The absolute path to the file to read (e.g., '/home/user/project/file.txt'). Relative paths are not supported. You must provide an absolute path.",
|
|
70
|
+
type: 'string',
|
|
71
|
+
},
|
|
72
|
+
start_line: {
|
|
73
|
+
description: 'The 1-based line number to start reading from (inclusive).',
|
|
74
|
+
type: 'number',
|
|
75
|
+
minimum: 1,
|
|
76
|
+
},
|
|
77
|
+
end_line: {
|
|
78
|
+
description: 'The 1-based line number to end reading at (inclusive). Must be >= start_line.',
|
|
79
|
+
type: 'number',
|
|
80
|
+
minimum: 1,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
required: ['absolute_path', 'start_line', 'end_line'],
|
|
84
|
+
type: 'object',
|
|
85
|
+
});
|
|
86
|
+
this.config = config;
|
|
87
|
+
}
|
|
88
|
+
validateToolParamValues(params) {
|
|
89
|
+
if (!params.absolute_path || params.absolute_path.trim() === '') {
|
|
90
|
+
return "The 'absolute_path' parameter must be non-empty.";
|
|
91
|
+
}
|
|
92
|
+
if (!path.isAbsolute(params.absolute_path)) {
|
|
93
|
+
return `File path must be absolute: ${params.absolute_path}`;
|
|
94
|
+
}
|
|
95
|
+
const workspaceContext = this.config.getWorkspaceContext();
|
|
96
|
+
if (!workspaceContext.isPathWithinWorkspace(params.absolute_path)) {
|
|
97
|
+
const directories = workspaceContext.getDirectories();
|
|
98
|
+
return `File path must be within one of the workspace directories: ${directories.join(', ')}`;
|
|
99
|
+
}
|
|
100
|
+
if (params.start_line < 1) {
|
|
101
|
+
return 'start_line must be a positive integer (>= 1)';
|
|
102
|
+
}
|
|
103
|
+
if (params.end_line < 1) {
|
|
104
|
+
return 'end_line must be a positive integer (>= 1)';
|
|
105
|
+
}
|
|
106
|
+
if (params.end_line < params.start_line) {
|
|
107
|
+
return 'end_line must be greater than or equal to start_line';
|
|
108
|
+
}
|
|
109
|
+
const fileService = this.config.getFileService();
|
|
110
|
+
if (fileService.shouldLlxprtIgnoreFile(params.absolute_path)) {
|
|
111
|
+
return `File path '${params.absolute_path}' is ignored by .llxprtignore pattern(s).`;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
createInvocation(params) {
|
|
116
|
+
return new ReadLineRangeToolInvocation(this.config, params);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=read_line_range.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read_line_range.js","sourceRoot":"","sources":["../../../src/tools/read_line_range.ts"],"names":[],"mappings":"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"}
|