Direct models now use bundled ripgrep for workspace discovery, read files through resumable pages, and edit multiple files with apply_patch. Ask can search and read while Execute retains write access, and fixed total input limits no longer constrain these tools. Release note: 直连模型现可使用随包 ripgrep 搜索项目、分页读取任意大小的文本,并通过多文件补丁修改代码;设置中的相关能力统一显示为工作区文件和开发工具。
64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import { LocalWorkspaceAccess } from '../workspace'
|
|
import { readWorkspaceLines } from './workspace-read-lines'
|
|
|
|
const temporaryDirectories: string[] = []
|
|
|
|
afterEach(async () => {
|
|
await Promise.all(
|
|
temporaryDirectories.splice(0).map((path) =>
|
|
rm(path, { recursive: true, force: true })
|
|
)
|
|
)
|
|
})
|
|
|
|
describe('workspace line reader', () => {
|
|
it('reads a selected line page without adding a line after the final newline', async () => {
|
|
const root = await mkdtemp(join(tmpdir(), 'goodbuddy-read-lines-'))
|
|
temporaryDirectories.push(root)
|
|
await writeFile(join(root, 'sample.txt'), 'one\ntwo\nthree\nfour\n', 'utf8')
|
|
|
|
const result = await readWorkspaceLines(
|
|
new LocalWorkspaceAccess(root),
|
|
{ path: 'sample.txt', offset: 2, limit: 2 },
|
|
new AbortController().signal
|
|
)
|
|
|
|
expect(result).toBe('2: two\n3: three\n[lines 2-3; more available]')
|
|
const last = await readWorkspaceLines(
|
|
new LocalWorkspaceAccess(root),
|
|
{ path: 'sample.txt', offset: 4, limit: 10 },
|
|
new AbortController().signal
|
|
)
|
|
expect(last).toContain('4: four')
|
|
expect(last).not.toContain('5:')
|
|
})
|
|
|
|
it('bounds a line that spans multiple byte pages', async () => {
|
|
const root = await mkdtemp(join(tmpdir(), 'goodbuddy-read-lines-'))
|
|
temporaryDirectories.push(root)
|
|
await writeFile(join(root, 'long.txt'), `${'x'.repeat(300_000)}\nnext`, 'utf8')
|
|
|
|
const result = await readWorkspaceLines(
|
|
new LocalWorkspaceAccess(root),
|
|
{ path: 'long.txt', offset: 1, limit: 2 },
|
|
new AbortController().signal
|
|
)
|
|
|
|
expect(result).toContain('1: ')
|
|
expect(result).toContain('...[line truncated]')
|
|
expect(result).toContain('2: next')
|
|
expect(Buffer.byteLength(result)).toBeLessThan(20_000)
|
|
|
|
const rawPage = await readWorkspaceLines(
|
|
new LocalWorkspaceAccess(root),
|
|
{ path: 'long.txt', offset: 1, limit: 1, offsetBytes: 0 },
|
|
new AbortController().signal
|
|
)
|
|
expect(rawPage).toContain('continue with offsetBytes=')
|
|
})
|
|
})
|