feat(tools): require cancellation signal on every invocation
This commit is contained in:
@@ -501,7 +501,7 @@ export async function dynamicInstructionContext(
|
||||
{
|
||||
touchedPath,
|
||||
includeBaselineScopes: baselineInstructionStates.has(agent.session),
|
||||
...exec.signal === undefined ? {} : { signal: exec.signal },
|
||||
signal: exec.signal,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ import {
|
||||
} from '../src/state.ts'
|
||||
import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts'
|
||||
|
||||
const testToolSignal = new AbortController().signal
|
||||
|
||||
async function tempRepo(): Promise<string> {
|
||||
return mkdtemp(join(tmpdir(), 'dsh-workspace-context-'))
|
||||
}
|
||||
@@ -797,6 +799,7 @@ describe('workspace context request injection', () => {
|
||||
await ctx.plugin(workspaceContext, { maxBytes: 65536 })
|
||||
|
||||
const decision = await ctx.waterfall('tools/post-execute', stubToolExecution({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('no-fs-post-execute'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/file.txt' },
|
||||
@@ -832,6 +835,7 @@ describe('workspace context request injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const exec = stubToolExecution({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-blocked-post-execute'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/file.txt' },
|
||||
@@ -977,6 +981,7 @@ describe('workspace context request injection', () => {
|
||||
await composeBaselinePrefix(ctx, agent)
|
||||
await write(join(root, 'AGENTS.md'), 'new root rule with more detail')
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-baseline-change'), name: 'read', arguments: { file_path: 'file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -1005,6 +1010,7 @@ describe('workspace context request injection', () => {
|
||||
await composeBaselinePrefix(ctx, agent)
|
||||
await rm(join(root, 'AGENTS.md'))
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-baseline-remove'), name: 'read', arguments: { file_path: 'file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -1030,6 +1036,7 @@ describe('workspace context request injection', () => {
|
||||
|
||||
await composeBaselinePrefix(ctx, agent)
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-with-shared-global-root'), name: 'read', arguments: { file_path: 'file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -1108,6 +1115,25 @@ describe('workspace context request injection', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('keeps the direct provider API usable without an operation signal', async () => {
|
||||
const root = '/virtual/no-signal-repo'
|
||||
const home = '/virtual/no-signal-home'
|
||||
const ctx = new Context()
|
||||
try {
|
||||
await ctx.plugin(RecordingFileSystem)
|
||||
const fs = ctx.fs as RecordingFileSystem
|
||||
fs.entries.set(join(root, '.git'), { type: 'directory' })
|
||||
fs.entries.set(join(root, 'AGENTS.md'), { type: 'file', content: 'optional capability signal' })
|
||||
|
||||
const rendered = await loadBaselineInstructions({ cwd: root, dshHome: home, maxBytes: 65536 }, fs)
|
||||
|
||||
expect(rendered?.text).toContain('optional capability signal')
|
||||
expect(fs.signals).toEqual([])
|
||||
} finally {
|
||||
await ctx.fiber.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
it('rejects a provider-sized instruction file before reading content', async () => {
|
||||
const root = join(await tempRepo(), 'virtual-repo')
|
||||
const home = join(await tempRepo(), 'virtual-home')
|
||||
@@ -1687,6 +1713,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-nested'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -1747,6 +1774,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
})
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-configured-nested-candidate'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -1775,12 +1803,14 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-nested-1'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
agent,
|
||||
})
|
||||
const second = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-nested-2'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -1813,10 +1843,12 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-version-fast-path'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
appendAdditionalContexts(agent, first)
|
||||
const second = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-with-version-fast-path'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -1848,14 +1880,17 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-same-digest-version-change'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
appendAdditionalContexts(agent, first)
|
||||
fs.entries.set(instructionPath, { type: 'file', content: 'same package rule', version: FsVersion('revision-2') })
|
||||
const afterVersionChange = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-same-digest-version-change'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
const afterRefresh = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-version-cache-refresh'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -1886,9 +1921,11 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await ctx.plugin(workspaceContext, { dshHome: home, maxBytes: 65536 })
|
||||
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-from-first-session'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent: stubAgent(root),
|
||||
})
|
||||
const second = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-from-second-session'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent: stubAgent(root),
|
||||
})
|
||||
|
||||
@@ -1914,11 +1951,13 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-change'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
appendAdditionalContexts(agent, first)
|
||||
await write(join(root, 'pkg/AGENTS.md'), 'new package rule with more detail')
|
||||
const changed = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-change'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -1954,15 +1993,18 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-fallback'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
appendAdditionalContexts(agent, first)
|
||||
await rm(join(root, 'pkg/AGENTS.md'))
|
||||
const changed = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-fallback'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
appendAdditionalContexts(agent, changed)
|
||||
const unchanged = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-logged-fallback'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -1993,11 +2035,13 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-remove'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
appendAdditionalContexts(agent, first)
|
||||
await rm(join(root, 'pkg/AGENTS.md'))
|
||||
const removed = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-remove'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -2031,17 +2075,20 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-tombstone'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
appendAdditionalContexts(agent, first)
|
||||
await rm(join(root, 'pkg/AGENTS.md'))
|
||||
const removed = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-to-create-tombstone'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
appendAdditionalContexts(agent, removed)
|
||||
await write(join(root, 'pkg/AGENTS.md'), 'restored package rule')
|
||||
|
||||
const restored = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-tombstone'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -2073,11 +2120,13 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-provider-failure'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
appendAdditionalContexts(agent, first)
|
||||
fs.throwOnStat.add(join(root, 'pkg/AGENTS.md'))
|
||||
const duringFailure = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-during-provider-failure'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
})
|
||||
|
||||
@@ -2101,6 +2150,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await mountFileToolsAndWorkspaceContext(ctx, { dshHome: home, maxBytes: 65536 })
|
||||
const agent = stubAgent(root)
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-resume'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2113,6 +2163,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
}
|
||||
|
||||
const afterResume = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-resume'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2138,6 +2189,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await mountFileToolsAndWorkspaceContext(ctx, { dshHome: home, maxBytes: 65536 })
|
||||
const original = stubAgent(root)
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-offline-change'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent: original,
|
||||
})
|
||||
appendAdditionalContexts(original, first)
|
||||
@@ -2168,6 +2220,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await mountFileToolsAndWorkspaceContext(ctx, { dshHome: home, maxBytes: 65536 })
|
||||
const agent = stubAgent(root)
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-before-compact'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2175,6 +2228,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
})
|
||||
const contextSeq = appendAdditionalContexts(agent, first)!
|
||||
const visibleBeforeCompact = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-while-visible'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2190,6 +2244,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
})
|
||||
|
||||
const afterCompact = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-compact'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2219,6 +2274,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await mountFileToolsAndWorkspaceContext(ctx, { dshHome: home, maxBytes: 65536 })
|
||||
const agent = stubAgent(root)
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-package'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/file.txt' },
|
||||
@@ -2227,6 +2283,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
appendAdditionalContexts(agent, first)
|
||||
|
||||
const second = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-subtree'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/sub/file.txt' },
|
||||
@@ -2254,6 +2311,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await mountFileToolsAndWorkspaceContext(ctx, { dshHome: home, maxBytes: 700 })
|
||||
const agent = stubAgent(root)
|
||||
const first = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-subtree-omitting-parent'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/sub/file.txt' },
|
||||
@@ -2262,6 +2320,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
appendAdditionalContexts(agent, first)
|
||||
|
||||
const second = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-parent-after-omit'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/other.txt' },
|
||||
@@ -2323,6 +2382,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
}, { surfaceOp: 'append' })
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-spoofed-state'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2349,12 +2409,14 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const rootResult = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-root-file'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'root.txt' },
|
||||
agent,
|
||||
})
|
||||
const absoluteResult = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-absolute-nested-file'),
|
||||
name: 'read',
|
||||
arguments: { file_path: join(root, 'pkg/deep/file.txt') },
|
||||
@@ -2388,11 +2450,13 @@ describe('dynamic nested workspace context injection', () => {
|
||||
}
|
||||
|
||||
const failedStat = await ctx.waterfall('tools/post-execute', stubToolExecution({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('provider-stat-failure'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
}), result, async () => ({ kind: 'accept' as const }))
|
||||
fs.throwOnStat.clear()
|
||||
fs.entries.set(join(root, 'pkg/AGENTS.md'), { type: 'directory' })
|
||||
const mismatchedStat = await ctx.waterfall('tools/post-execute', stubToolExecution({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('provider-stat-mismatch'), name: 'read', arguments: { file_path: 'pkg/file.txt' }, agent,
|
||||
}), result, async () => ({ kind: 'accept' as const }))
|
||||
|
||||
@@ -2418,6 +2482,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await mountFileToolsAndWorkspaceContext(ctx, { dshHome: home, maxBytes: 65536 })
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-with-unreadable-nested-instruction'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2452,6 +2517,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
}))
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-with-downstream'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2496,6 +2562,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
}))
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-blocked-downstream'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2536,6 +2603,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const blocked = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('outer-block-first'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2543,6 +2611,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
})
|
||||
shouldBlock = false
|
||||
const accepted = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('outer-block-retry'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2583,7 +2652,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
...exec.agent === undefined ? {} : { agent: exec.agent },
|
||||
parent: exec.token,
|
||||
...exec.signal === undefined ? {} : { signal: exec.signal },
|
||||
signal: exec.signal,
|
||||
})
|
||||
for (const context of nested.additionalContexts ?? []) exec.deferContext(context)
|
||||
return nested.content
|
||||
@@ -2600,10 +2669,12 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const agent = stubAgent(root)
|
||||
|
||||
const blocked = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('composite-first'), name: 'composite-read', arguments: {}, agent,
|
||||
})
|
||||
shouldBlock = false
|
||||
const accepted = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('composite-retry'), name: 'composite-read', arguments: {}, agent,
|
||||
})
|
||||
|
||||
@@ -2627,19 +2698,23 @@ describe('dynamic nested workspace context injection', () => {
|
||||
const plainResult = { callId: CallId('plain'), content: [], isError: false }
|
||||
|
||||
ctx.emit('tools/result', stubToolExecution({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('agentless-child'), name: 'read', arguments: {}, parent,
|
||||
}), plainResult)
|
||||
ctx.emit('tools/result', stubToolExecution({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('contextless-child'), name: 'read', arguments: {}, agent, parent,
|
||||
}), { ...plainResult, additionalContexts: [{ content: [], source: { kind: 'plugin', plugin: 'workspace-context' } }] })
|
||||
ctx.emit('tools/result', stubToolExecution({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('first-child'), name: 'read', arguments: {}, agent, parent,
|
||||
}), { ...plainResult, additionalContexts: [workspaceChangeContext('first', 'one')] })
|
||||
ctx.emit('tools/result', stubToolExecution({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('second-child'), name: 'read', arguments: {}, agent, parent,
|
||||
}), { ...plainResult, additionalContexts: [workspaceChangeContext('second', 'two')] })
|
||||
ctx.emit('tools/result', {
|
||||
...stubToolExecution({ callId: CallId('agentless-parent'), name: 'composite', arguments: {} }),
|
||||
...stubToolExecution({ signal: testToolSignal, callId: CallId('agentless-parent'), name: 'composite', arguments: {} }),
|
||||
token: parent,
|
||||
}, plainResult)
|
||||
|
||||
@@ -2675,6 +2750,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
|
||||
for (const item of cases) {
|
||||
const decision = await ctx.waterfall('tools/post-execute', stubToolExecution({
|
||||
signal: testToolSignal,
|
||||
callId: CallId(`manual-${item.name}-${cases.indexOf(item)}`),
|
||||
name: item.name,
|
||||
arguments: item.arguments,
|
||||
@@ -2699,6 +2775,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await mountFileToolsAndWorkspaceContext(ctx, { dshHome: home, maxBytes: 0 })
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-with-disabled-budget'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
@@ -2723,6 +2800,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await mountFileToolsAndWorkspaceContext(ctx, { dshHome: home, maxBytes: 65536 })
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-missing'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/missing.txt' },
|
||||
@@ -2749,6 +2827,7 @@ describe('dynamic nested workspace context injection', () => {
|
||||
await fiber.dispose()
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('read-after-dispose'),
|
||||
name: 'read',
|
||||
arguments: { file_path: 'pkg/deep/file.txt' },
|
||||
|
||||
Reference in New Issue
Block a user