fix: preserve failed PTC image result forwarding semantics
This commit is contained in:
1 parent
14c1fec958
commit
b0be6e79c2
2 files changed
+19
-4
No files matched your search
@@ -140,7 +140,7 @@ export function apply(ctx: Context, config: Config): void {
|
||||
const retained = await bound(exec, content, exec.name, exec.callId, exec.parent === undefined ? 'result' : 'dispatch')
|
||||
if (retained === undefined) return decision
|
||||
const additionalContexts = [...decision.additionalContexts ?? []]
|
||||
if (exec.parent !== undefined && hasImages && !retained.some(block => block.type === 'image')) {
|
||||
if (exec.parent !== undefined && !result.isError && hasImages && !retained.some(block => block.type === 'image')) {
|
||||
additionalContexts.push(createUserMessage({ content: retained, source: { kind: 'ptc-mode' } }))
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -176,9 +176,20 @@ describe('multimodal spill', () => {
|
||||
expect(warning).toHaveBeenCalledWith(expect.stringContaining('inconsistent occurrence count'))
|
||||
})
|
||||
|
||||
it('preserves the complete PTC value and forwards recovery text when every image is omitted', async () => {
|
||||
it.each([false, true])('forwards omitted-image recovery only for successful PTC results (failure: %s)', async (failure) => {
|
||||
const original = [text('A'.repeat(4000)), image(), text('C'.repeat(4000))]
|
||||
const { ctx, execute, session } = await setup(original, 200)
|
||||
if (failure) {
|
||||
const attachment = await ctx.attachments.saveImage({ data: PNG, mediaType: 'image/png' })
|
||||
ctx.on('tools/execute', async (exec, next) => {
|
||||
if (exec.name !== 'inspect') return next()
|
||||
await next()
|
||||
return { isError: true, error: { message: 'capture failed' }, content: [
|
||||
{ type: 'text', text: 'A'.repeat(4000) }, { type: 'image', attachment },
|
||||
{ type: 'text', text: 'C'.repeat(4000) },
|
||||
] }
|
||||
})
|
||||
}
|
||||
class BindingRuntime extends PtcRuntime {
|
||||
readonly language = 'typescript'
|
||||
readonly isolation = 'fixture'
|
||||
@@ -186,14 +197,18 @@ describe('multimodal spill', () => {
|
||||
async run(spec: PtcRunSpec): Promise<PtcRunResult> {
|
||||
const binding = spec.bindings.find(item => item.global === 'tools')?.functions.inspect
|
||||
if (binding === undefined) throw new Error('missing inspect binding')
|
||||
const value = await binding({})
|
||||
expect(value).toEqual({ content: original })
|
||||
if (failure) await expect(binding({})).rejects.toThrow('capture failed')
|
||||
else expect(await binding({})).toEqual({ content: original })
|
||||
return { logs: [], value: 'complete' }
|
||||
}
|
||||
}
|
||||
await ctx.plugin(BindingRuntime)
|
||||
const result = await execute('run_code')
|
||||
expect(result.isError).toBe(false)
|
||||
if (failure) {
|
||||
expect(result.additionalContexts).toBeUndefined()
|
||||
return
|
||||
}
|
||||
expect(result.additionalContexts).toHaveLength(1)
|
||||
const context = result.additionalContexts?.[0]
|
||||
expect(context?.content.every(block => block.type === 'text')).toBe(true)
|
||||
|
||||
Reference in new issue
Block a user