1- import { test , expect } from "bun:test" ;
1+ import { test , expect , describe } from "bun:test" ;
22import { z } from "zod" ;
33import {
44 streamText ,
@@ -66,9 +66,9 @@ test("when properties is missing, remaining keys go into properties", () => {
6666 expect ( parsed . properties ) . toEqual ( { foo : "z" , bar : 2 } ) ;
6767} ) ;
6868
69- const colorTools : ToolSet = {
70- get_favorite_color : tool ( {
71- description : "Get your favorite colors " ,
69+ const colorTools = {
70+ async_generator : tool ( {
71+ description : "Get your favorite color " ,
7272 inputSchema : z . object ( { } ) ,
7373 async * execute ( ) {
7474 yield "blue" ;
@@ -78,16 +78,27 @@ const colorTools: ToolSet = {
7878 yield "green" ;
7979 } ,
8080 } ) ,
81- } ;
81+ async : tool ( {
82+ description : "Get your favorite color" ,
83+ inputSchema : z . object ( { } ) ,
84+ execute : async ( ) => "green" ,
85+ } ) ,
86+ sync : tool ( {
87+ description : "Get your favorite color" ,
88+ inputSchema : z . object ( { } ) ,
89+ execute : ( ) => "green" ,
90+ } ) ,
91+ } as const ;
8292
8393const baseMessages : ModelMessage [ ] = [
84- { role : "user" , content : "List your favorite colors ." } ,
94+ { role : "user" , content : "List your favorite color ." } ,
8595] ;
8696
8797const usageStub = { inputTokens : 0 , outputTokens : 0 , totalTokens : 0 } ;
8898
89- const runFavoriteColorTool = async (
99+ const runColorTool = async (
90100 tools : ToolSet ,
101+ toolName : keyof typeof colorTools ,
91102 rawToolInput : Record < string , unknown >
92103) => {
93104 const mockModel = new MockLanguageModelV2 ( {
@@ -99,7 +110,7 @@ const runFavoriteColorTool = async (
99110 {
100111 type : "tool-call" ,
101112 toolCallId : "call-1" ,
102- toolName : "get_favorite_color" ,
113+ toolName,
103114 input : JSON . stringify ( rawToolInput ) ,
104115 } ,
105116 {
@@ -117,24 +128,34 @@ const runFavoriteColorTool = async (
117128 model : mockModel ,
118129 messages : baseMessages ,
119130 tools,
120- toolChoice : { type : "tool" , toolName : "get_favorite_color" } ,
131+ toolChoice : { type : "tool" , toolName } ,
121132 } ) ;
122133
123134 return result . toolResults ;
124135} ;
125136
126- test ( "async generator tools stream their final output without model intent" , async ( ) => {
127- const toolResults = await runFavoriteColorTool ( colorTools , { } ) ;
128- expect ( toolResults ) . toHaveLength ( 1 ) ;
129- expect ( toolResults [ 0 ] ?. output ) . toBe ( "green" ) ;
130- } ) ;
131-
132- test ( "withModelIntent with async generator tool" , async ( ) => {
133- const wrappedTools = withModelIntent ( colorTools ) ;
134- const toolResults = await runFavoriteColorTool ( wrappedTools , {
135- model_intent : "listing colors" ,
136- properties : { } ,
137- } ) ;
138- expect ( toolResults ) . toHaveLength ( 1 ) ;
139- expect ( toolResults [ 0 ] ?. output ) . toBe ( "green" ) ;
137+ describe ( "withModelIntent" , ( ) => {
138+ for ( const toolName of Object . keys ( colorTools ) ) {
139+ test ( `should handle ${ toolName } tool` , async ( ) => {
140+ // sanity check
141+ const toolResults = await runColorTool (
142+ colorTools ,
143+ toolName as keyof typeof colorTools ,
144+ { }
145+ ) ;
146+ expect ( toolResults ) . toHaveLength ( 1 ) ;
147+ expect ( toolResults [ 0 ] ?. output ) . toBe ( "green" ) ;
148+
149+ const toolResultsWithModelIntent = await runColorTool (
150+ withModelIntent ( colorTools ) ,
151+ toolName as keyof typeof colorTools ,
152+ {
153+ model_intent : "listing colors" ,
154+ properties : { } ,
155+ }
156+ ) ;
157+ expect ( toolResultsWithModelIntent ) . toHaveLength ( 1 ) ;
158+ expect ( toolResultsWithModelIntent [ 0 ] ?. output ) . toBe ( "green" ) ;
159+ } ) ;
160+ }
140161} ) ;
0 commit comments