Skip to content

Commit 521ab75

Browse files
committed
Keep file tool prompts relative-first
1 parent 2f89dd9 commit 521ab75

8 files changed

Lines changed: 48 additions & 18 deletions

File tree

common/src/templates/initial-agents-dir/types/tools.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ export interface SpawnAgentsParams {
353353
* Replace strings in a file with new strings.
354354
*/
355355
export interface StrReplaceParams {
356-
/** The path to the file to edit, either relative to the project root or an absolute path inside the project. */
356+
/** The path to the file to edit. */
357357
path: string
358358
/** Array of replacements to make. */
359359
replacements: {
@@ -411,7 +411,7 @@ export interface WebSearchParams {
411411
* Create or edit a file with the given content.
412412
*/
413413
export interface WriteFileParams {
414-
/** Path to the file, either relative to the project root or an absolute path inside the project. */
414+
/** Path to the file relative to the **project root** */
415415
path: string
416416
/** What the change is intended to do in only one sentence. */
417417
instructions: string

common/src/tools/params/tool/str-replace.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ const inputSchema = z
2828
path: z
2929
.string()
3030
.min(1, 'Path cannot be empty')
31-
.describe(
32-
`The path to the file to edit, either relative to the project root or an absolute path inside the project.`,
33-
),
31+
.describe(`The path to the file to edit.`),
3432
replacements: z
3533
.preprocess(
3634
coerceToArray,

common/src/tools/params/tool/write-file.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ const inputSchema = z
1212
path: z
1313
.string()
1414
.min(1, 'Path cannot be empty')
15-
.describe(
16-
`Path to the file, either relative to the project root or an absolute path inside the project.`,
17-
),
15+
.describe(`Path to the file relative to the **project root**`),
1816
instructions: z
1917
.string()
2018
.describe('What the change is intended to do in only one sentence.'),

sdk/src/__tests__/change-file.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('changeFile', () => {
3636
)
3737
})
3838

39-
test('accepts absolute paths inside the project for string replacements', async () => {
39+
test('tolerates absolute paths inside the project for string replacements', async () => {
4040
const fs = createMockFs({
4141
files: {
4242
'/repo/src/file.ts': 'const value = 1\n',
@@ -94,7 +94,7 @@ describe('changeFile', () => {
9494
)
9595
})
9696

97-
test('accepts absolute paths inside the project for file writes', async () => {
97+
test('tolerates absolute paths inside the project for file writes', async () => {
9898
const fs = createMockFs()
9999

100100
const result = await changeFile({

sdk/src/__tests__/path-utils.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { describe, expect, test } from 'bun:test'
22

3-
import { resolveFilePathWithinProject } from '../tools/path-utils'
3+
import {
4+
getProjectPathLookupKeys,
5+
resolveFilePathWithinProject,
6+
} from '../tools/path-utils'
47

58
describe('resolveFilePathWithinProject', () => {
69
test('normalizes relative paths to full and project-relative paths', () => {
@@ -32,3 +35,24 @@ describe('resolveFilePathWithinProject', () => {
3235
).toBeNull()
3336
})
3437
})
38+
39+
describe('getProjectPathLookupKeys', () => {
40+
test('returns the normalized relative key before the original absolute key', () => {
41+
expect(getProjectPathLookupKeys('/repo', '/repo/src/file.ts')).toEqual([
42+
'src/file.ts',
43+
'/repo/src/file.ts',
44+
])
45+
})
46+
47+
test('dedupes relative paths that are already normalized', () => {
48+
expect(getProjectPathLookupKeys('/repo', 'src/file.ts')).toEqual([
49+
'src/file.ts',
50+
])
51+
})
52+
53+
test('returns only the original key for paths outside the project', () => {
54+
expect(getProjectPathLookupKeys('/repo', '/outside.ts')).toEqual([
55+
'/outside.ts',
56+
])
57+
})
58+
})

sdk/src/__tests__/run-file-filter.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ describe('CodebuffClientOptions fileFilter', () => {
312312
expect(optionalFileResult).toBeNull()
313313
})
314314

315-
it('should resolve absolute requestOptionalFile paths inside cwd', async () => {
315+
it('should tolerate absolute requestOptionalFile paths inside cwd', async () => {
316316
spyOn(databaseModule, 'getUserInfoFromApiKey').mockResolvedValue({
317317
id: 'user-123',
318318
email: 'test@example.com',

sdk/src/run.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { applyPatchTool } from './tools/apply-patch'
2727
import { codeSearch } from './tools/code-search'
2828
import { glob } from './tools/glob'
2929
import { listDirectory } from './tools/list-directory'
30-
import { resolveFilePathWithinProject } from './tools/path-utils'
30+
import { getProjectPathLookupKeys } from './tools/path-utils'
3131
import { getFiles } from './tools/read-files'
3232
import { runTerminalCommand } from './tools/run-terminal-command'
3333

@@ -435,11 +435,11 @@ async function runOnce({
435435
cwd,
436436
fs,
437437
})
438-
const lookupPath = cwd
439-
? (resolveFilePathWithinProject(cwd, filePath)?.relativePath ??
440-
filePath)
441-
: filePath
442-
return toOptionalFile(files[lookupPath] ?? files[filePath] ?? null)
438+
const lookupKeys = cwd
439+
? getProjectPathLookupKeys(cwd, filePath)
440+
: [filePath]
441+
const fileKey = lookupKeys.find((key) => key in files)
442+
return toOptionalFile(fileKey === undefined ? null : files[fileKey]!)
443443
},
444444
sendAction: ({ action }) => {
445445
if (action.type === 'action-error') {

sdk/src/tools/path-utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,13 @@ export function resolveFilePathWithinProject(
2929

3030
return { fullPath, relativePath }
3131
}
32+
33+
export function getProjectPathLookupKeys(
34+
projectRoot: string,
35+
filePath: string,
36+
): string[] {
37+
const resolvedPath = resolveFilePathWithinProject(projectRoot, filePath)
38+
const keys = resolvedPath ? [resolvedPath.relativePath, filePath] : [filePath]
39+
40+
return [...new Set(keys)]
41+
}

0 commit comments

Comments
 (0)