test(ptc): give nested tool fixtures an owned lifecycle context

This commit is contained in:
creatixchu committed 2026-09-25 15:38:45 +08:00
1 parent 10d4193663
commit ca3a438a4e
4 files changed
+7 -6

No files matched your search

@@ -70,8 +70,8 @@ async function executeShell(text: string, nested: boolean, name = 'bash', maxInl
async execute() { return [{ type: 'text', text }] },
})))
const session = Session.create(SessionId('spill-terminal'))
// The tool pipeline reads only the owner session; no agent loop runs here.
const agent = { session } as Agent
// Nested PTC registers retained-environment cleanup on the owning context.
const agent = { ctx, session } as Agent
const callId = ToolCallId('shell-call')
const result = await ctx.tools.execute({
callId,
+3 -2
View File
@@ -6,7 +6,7 @@
* regression that `read` keeps its text-only contract.
*/
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import { afterEach, beforeEach, describe, expect, it, onTestFinished } from 'vitest'
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
@@ -105,6 +105,7 @@ interface SetupOptions {
async function setup(options: SetupOptions = {}) {
const ctx = new Context()
onTestFinished(async () => { await ctx.fiber.dispose() })
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime, { mode: options.toolMode ?? 'native' })
if (options.toolMode === 'ptc' || options.toolMode === 'both') {
@@ -299,7 +300,7 @@ describe('read_image happy path', () => {
const result = await call(ctx, RUN_CODE_NAME, {
code: 'return await tools.read_image({ file_path: "red.png" })',
description: 'Read the image through PTC mode',
}, agentOn('vision-model'))
}, { ...agentOn('vision-model'), ctx })
expect(result.isError).toBe(false)
expect(result.content.every(block => block.type === 'text')).toBe(true)
@@ -80,7 +80,7 @@ async function setup(content: JsonValue[], maxInlineTokens: number) {
inputSchema: { type: 'object' }, call: async () => ({ content }),
}))
const session = Session.create(SessionId('mixed-spill'))
const agent = { session, options: { provider: 'vision', model: 'vision' } } as Agent
const agent = { ctx, session, options: { provider: 'vision', model: 'vision' } } as Agent
const execute = (name = 'inspect') => ctx.tools.execute({
signal: new AbortController().signal, callId: ToolCallId('mixed-call'), name,
arguments: name === 'run_code' ? { code: 'return await tools.inspect({})', description: 'Inspect a window' } : {}, agent,
@@ -50,7 +50,7 @@ async function mountRuntime(ctx: Context, config: NodeRuntimeConfig = {}): Promi
function observedAgent(ctx: Context, id: string, observe: (type: string, data: unknown) => void) {
const session = ctx.sessions.create(SessionId(id), { meta: { cwd: process.cwd() } })
ctx.on('session/event', (owner, event) => { if (owner === session) observe(event.type, event.data) })
return { session }
return { ctx, session }
}
const testToolSignal = new AbortController().signal