@@ -2,6 +2,12 @@ import { afterEach, describe, expect, mock, test } from 'bun:test';
22import { CACHE } from './cache' ;
33import { createWebfetchTool } from './tool' ;
44
5+ let mockV2Client : Record < string , unknown > ;
6+
7+ mock . module ( '../../utils/opencode-client' , ( ) => ( {
8+ getClient : ( ) => mockV2Client ,
9+ } ) ) ;
10+
511function createExecutionContext ( ) {
612 return {
713 ask : mock ( async ( ) => undefined ) ,
@@ -120,4 +126,55 @@ describe('smartfetch/tool', () => {
120126 'requested_url: "https://example.com/docs#sec2"' ,
121127 ) ;
122128 } ) ;
129+
130+ test ( 'passes ctx.sessionID as parentID to the secondary-model session' , async ( ) => {
131+ const fetchMock = mock ( async ( ) => {
132+ return new Response (
133+ 'Article about smartfetch: it fetches pages, extracts the main ' +
134+ 'content, caches results, and summarizes them with a secondary ' +
135+ 'model whenever a prompt is provided by the tool caller.' ,
136+ { status : 200 , headers : { 'content-type' : 'text/plain' } } ,
137+ ) ;
138+ } ) ;
139+ globalThis . fetch = fetchMock as unknown as typeof fetch ;
140+
141+ const session = {
142+ create : mock ( async ( ) => ( { data : { id : 'secondary-session' } } ) ) ,
143+ prompt : mock ( async ( ) => ( {
144+ data : { parts : [ { type : 'text' , text : 'Extracted answer' } ] } ,
145+ } ) ) ,
146+ delete : mock ( async ( ) => ( { data : true } ) ) ,
147+ abort : mock ( async ( ) => ( { data : true } ) ) ,
148+ } ;
149+ const toolIds = { ids : mock ( async ( ) => ( { data : [ 'read' ] } ) ) } ;
150+ mockV2Client = { session, tool : toolIds } ;
151+
152+ const webfetch = createWebfetchTool ( { client : mockV2Client } as any , {
153+ webfetchModels : [ { id : 'provider/small-model' } ] ,
154+ } ) ;
155+ const ctx = createExecutionContext ( ) ;
156+ ctx . sessionID = 'main-session-id' ;
157+ const result = await webfetch . execute (
158+ {
159+ url : 'https://example.com/article' ,
160+ format : 'markdown' ,
161+ extract_main : true ,
162+ prefer_llms_txt : 'auto' ,
163+ include_metadata : false ,
164+ save_binary : false ,
165+ prompt : 'Extract the answer' ,
166+ } ,
167+ ctx ,
168+ ) ;
169+
170+ expect ( session . create ) . toHaveBeenCalledWith (
171+ expect . objectContaining ( {
172+ body : expect . objectContaining ( {
173+ title : 'smartfetch-secondary' ,
174+ parentID : 'main-session-id' ,
175+ } ) ,
176+ } ) ,
177+ ) ;
178+ expect ( result ) . toContain ( 'Extracted answer' ) ;
179+ } ) ;
123180} ) ;
0 commit comments