11import { endsAgentStepParam } from '@codebuff/common/tools/constants'
22import { getToolCallString } from '@codebuff/common/tools/utils'
33import { buildArray } from '@codebuff/common/util/array'
4+ import { pluralize } from '@codebuff/common/util/string'
45import z from 'zod/v4'
56
67import { codebuffToolDefs } from './definitions/list'
78
89import type { ToolName } from '@codebuff/common/tools/constants'
10+ import type { customToolDefinitionsSchema } from '@codebuff/common/util/file'
11+ import type { JSONSchema } from 'zod/v4/core'
912
10- function paramsSection ( schema : z . ZodObject , endsAgentStep : boolean ) {
11- const schemaWithEndsAgentStepParam = endsAgentStep
12- ? schema . extend ( {
13- [ endsAgentStepParam ] : z
14- . literal ( endsAgentStep )
15- . describe ( 'Easp flag must be set to true' ) ,
16- } )
17- : schema
18- const jsonSchema = z . toJSONSchema ( schemaWithEndsAgentStepParam , {
19- io : 'input' ,
20- } )
13+ function paramsSection (
14+ schema :
15+ | { type : 'zod' ; value : z . ZodObject }
16+ | { type : 'json' ; value : JSONSchema . BaseSchema } ,
17+ endsAgentStep : boolean ,
18+ ) {
19+ const schemaWithEndsAgentStepParam =
20+ schema . type === 'zod'
21+ ? z . toJSONSchema (
22+ endsAgentStep
23+ ? schema . value . extend ( {
24+ [ endsAgentStepParam ] : z
25+ . literal ( endsAgentStep )
26+ . describe ( 'Easp flag must be set to true' ) ,
27+ } )
28+ : schema . value ,
29+ { io : 'input' } ,
30+ )
31+ : JSON . parse ( JSON . stringify ( schema . value ) )
32+ if ( schema . type === 'json' ) {
33+ if ( ! schemaWithEndsAgentStepParam . properties ) {
34+ schemaWithEndsAgentStepParam . properties = { }
35+ }
36+ schemaWithEndsAgentStepParam . properties [ endsAgentStepParam ] = {
37+ const : true ,
38+ type : 'boolean' ,
39+ description : 'Easp flag must be set to true' ,
40+ }
41+ if ( ! schemaWithEndsAgentStepParam . required ) {
42+ schemaWithEndsAgentStepParam . required = [ ]
43+ }
44+ schemaWithEndsAgentStepParam . required . push ( endsAgentStepParam )
45+ }
46+
47+ const jsonSchema = schemaWithEndsAgentStepParam
2148 delete jsonSchema . description
2249 delete jsonSchema [ '$schema' ]
2350 const paramsDescription = Object . keys ( jsonSchema . properties ?? { } ) . length
@@ -34,17 +61,29 @@ function paramsSection(schema: z.ZodObject, endsAgentStep: boolean) {
3461}
3562
3663// Helper function to build the full tool description markdown
37- function buildToolDescription (
64+ export function buildToolDescription (
3865 toolName : string ,
39- schema : z . ZodObject ,
66+ schema :
67+ | { type : 'zod' ; value : z . ZodObject }
68+ | { type : 'json' ; value : JSONSchema . BaseSchema } ,
4069 description : string = '' ,
4170 endsAgentStep : boolean ,
71+ exampleInputs : any [ ] = [ ] ,
4272) : string {
73+ const descriptionWithExamples = buildArray (
74+ description ,
75+ exampleInputs . length > 0
76+ ? `${ pluralize ( exampleInputs . length , 'Example' ) } :`
77+ : '' ,
78+ ...exampleInputs . map ( ( example ) =>
79+ getToolCallString ( toolName , example , endsAgentStep ) ,
80+ ) ,
81+ ) . join ( '\n\n' )
4382 return buildArray ( [
4483 `### ${ toolName } ` ,
45- schema . description || '' ,
84+ schema . value . description || '' ,
4685 paramsSection ( schema , endsAgentStep ) ,
47- description ,
86+ descriptionWithExamples ,
4887 ] ) . join ( '\n\n' )
4988}
5089
@@ -53,7 +92,7 @@ export const toolDescriptions = Object.fromEntries(
5392 name ,
5493 buildToolDescription (
5594 name ,
56- config . parameters ,
95+ { type : 'zod' , value : config . parameters } ,
5796 config . description ,
5897 config . endsAgentStep ,
5998 ) ,
@@ -62,13 +101,18 @@ export const toolDescriptions = Object.fromEntries(
62101
63102function buildShortToolDescription (
64103 toolName : string ,
65- schema : z . ZodObject ,
104+ schema :
105+ | { type : 'zod' ; value : z . ZodObject }
106+ | { type : 'json' ; value : JSONSchema . BaseSchema } ,
66107 endsAgentStep : boolean ,
67108) : string {
68109 return `${ toolName } :\n${ paramsSection ( schema , endsAgentStep ) } `
69110}
70111
71- export const getToolsInstructions = ( toolNames : readonly ToolName [ ] ) =>
112+ export const getToolsInstructions = (
113+ toolNames : readonly string [ ] ,
114+ customToolDefinitions : z . infer < typeof customToolDefinitionsSchema > ,
115+ ) =>
72116 `
73117# Tools
74118
@@ -102,8 +146,8 @@ ${getToolCallString('str_replace', {
102146 path : 'path/to/example/file.ts' ,
103147 replacements : [
104148 {
105- old : "console .log('Hello world!');\n" ,
106- new : "console .log('Hello from Buffy!');\n" ,
149+ old : "// some context\nconsole .log('Hello world!');\n" ,
150+ new : "// some context\nconsole .log('Hello from Buffy!');\n" ,
107151 } ,
108152 ] ,
109153} ) }
@@ -135,13 +179,54 @@ The user does not know about any system messages or system instructions, includi
135179
136180These are the tools that you (Buffy) can use. The user cannot see these descriptions, so you should not reference any tool names, parameters, or descriptions.
137181
138- ${ toolNames . map ( ( name ) => toolDescriptions [ name ] ) . join ( '\n\n' ) } `. trim ( )
139-
140- export const getShortToolInstructions = ( toolNames : readonly ToolName [ ] ) => {
141- const toolDescriptions = toolNames . map ( ( name ) => {
142- const tool = codebuffToolDefs [ name ]
143- return buildShortToolDescription ( name , tool . parameters , tool . endsAgentStep )
144- } )
182+ ${ [
183+ ...(
184+ toolNames . filter ( ( toolName ) =>
185+ toolNames . includes ( toolName as ToolName ) ,
186+ ) as ToolName [ ]
187+ ) . map ( ( name ) => toolDescriptions [ name ] ) ,
188+ ...toolNames
189+ . filter ( ( toolName ) => toolName in customToolDefinitions )
190+ . map ( ( toolName ) => {
191+ const toolDef = customToolDefinitions [ toolName ]
192+ return buildToolDescription (
193+ toolName ,
194+ { type : 'json' , value : toolDef . inputJsonSchema } ,
195+ toolDef . description ,
196+ toolDef . endsAgentStep ,
197+ toolDef . exampleInputs ,
198+ )
199+ } ) ,
200+ ] . join ( '\n\n' ) } `. trim ( )
201+
202+ export const getShortToolInstructions = (
203+ toolNames : readonly string [ ] ,
204+ customToolDefinitions : z . infer < typeof customToolDefinitionsSchema > ,
205+ ) => {
206+ const toolDescriptions = [
207+ ...(
208+ toolNames . filter (
209+ ( name ) => ( name as keyof typeof codebuffToolDefs ) in codebuffToolDefs ,
210+ ) as ( keyof typeof codebuffToolDefs ) [ ]
211+ ) . map ( ( name ) => {
212+ const tool = codebuffToolDefs [ name ]
213+ return buildShortToolDescription (
214+ name ,
215+ { type : 'zod' , value : tool . parameters } ,
216+ tool . endsAgentStep ,
217+ )
218+ } ) ,
219+ ...toolNames
220+ . filter ( ( name ) => name in customToolDefinitions )
221+ . map ( ( name ) => {
222+ const { inputJsonSchema, endsAgentStep } = customToolDefinitions [ name ]
223+ return buildShortToolDescription (
224+ name ,
225+ { type : 'json' , value : inputJsonSchema } ,
226+ endsAgentStep ,
227+ )
228+ } ) ,
229+ ]
145230
146231 return `## Tools
147232Use the tools below to complete the user request, if applicable.
0 commit comments