@@ -65,10 +65,11 @@ type ToolHttpResponse = IAdminForthHttpResponse & {
6565type ToolOverrideCallParams = Pick < ApiBasedToolCallParams , 'httpExtra' | 'inputs' | 'userTimeZone' > ;
6666
6767type ToolOverrideContext = {
68- output : unknown ;
68+ output ? : unknown ;
6969 adminUser ?: AdminUser ;
7070 httpExtra ?: Partial < HttpExtra > ;
7171 inputs ?: Record < string , unknown > ;
72+ resourceLabel ?: string ;
7273 userTimeZone ?: string ;
7374 invokeTool : ( toolName : string , params ?: ToolOverrideCallParams ) => Promise < unknown > ;
7475} ;
@@ -98,6 +99,42 @@ type DateTimeColumnType = AdminForthDataTypes.DATETIME | AdminForthDataTypes.TIM
9899
99100const DEFAULT_USER_TIME_ZONE = 'UTC' ;
100101
102+ function getInputString ( inputs : Record < string , unknown > | undefined , key : string ) {
103+ const value = inputs ?. [ key ] ;
104+
105+ return typeof value === 'string' && value ? value : undefined ;
106+ }
107+
108+ function getInputArrayLength ( inputs : Record < string , unknown > | undefined , key : string ) {
109+ const value = inputs ?. [ key ] ;
110+
111+ return Array . isArray ( value ) ? value . length : undefined ;
112+ }
113+
114+ function resourceLabel ( adminforth : IAdminForth , inputs : Record < string , unknown > | undefined ) {
115+ const resourceId = getInputString ( inputs , 'resourceId' ) ;
116+ const resource = adminforth . config . resources . find ( ( res ) => res . resourceId === resourceId ) ;
117+
118+ return resource ?. label ?? resourceId ?? 'resource' ;
119+ }
120+
121+ function getDataPrefix ( inputs : Record < string , unknown > | undefined ) {
122+ const offset = typeof inputs ?. offset === 'number' ? inputs . offset : undefined ;
123+ const limit = typeof inputs ?. limit === 'number' ? inputs . limit : undefined ;
124+
125+ if ( offset !== undefined && limit !== undefined ) {
126+ return `${ offset } -${ offset + limit } ` ;
127+ }
128+
129+ return limit === undefined ? '' : `${ limit } ` ;
130+ }
131+
132+ function actionText ( inputs : Record < string , unknown > | undefined ) {
133+ const actionId = getInputString ( inputs , 'actionId' ) ;
134+
135+ return actionId ? ` action ${ actionId } ` : ' action' ;
136+ }
137+
101138const TOOL_OVERRIDES : Record < string , ToolOverride > = {
102139 get_resource : {
103140 wipe_frontend_specific_data : [
@@ -106,11 +143,12 @@ const TOOL_OVERRIDES: Record<string, ToolOverride> = {
106143 'resource.options.actions[].customComponent' ,
107144 'resource.options.pageInjections' ,
108145 ] ,
109- format_tool : async ( { } ) => {
110- return "get resource Apartments"
111- }
146+ format_tool : ( { resourceLabel } ) => `Get ${ resourceLabel } resource` ,
112147 } ,
113148 get_resource_data : {
149+ format_tool : ( { inputs, resourceLabel } ) => (
150+ `Get ${ getDataPrefix ( inputs ) } ${ resourceLabel } `
151+ ) ,
114152 post_process_response : async ( { output, inputs, invokeTool, userTimeZone } ) => {
115153 if ( hasToolError ( output ) ) {
116154 return output ;
@@ -132,9 +170,37 @@ const TOOL_OVERRIDES: Record<string, ToolOverride> = {
132170
133171 return response ;
134172 } ,
135- format_tool : async ( { } ) => {
136- return "get 1-20 Apartment filtered listed=yes"
137- }
173+ } ,
174+ aggregate : {
175+ format_tool : ( { resourceLabel } ) => `Aggregate ${ resourceLabel } ` ,
176+ } ,
177+ start_custom_action : {
178+ format_tool : ( { inputs, resourceLabel } ) => `Run ${ resourceLabel } ${ actionText ( inputs ) } ` ,
179+ } ,
180+ start_custom_bulk_action : {
181+ format_tool : ( { inputs, resourceLabel } ) => {
182+ const recordCount = getInputArrayLength ( inputs , 'recordIds' ) ;
183+ const recordsText = recordCount === undefined ? '' : ` for ${ recordCount } records` ;
184+
185+ return `Run ${ resourceLabel } ${ actionText ( inputs ) } ${ recordsText } ` ;
186+ } ,
187+ } ,
188+ start_bulk_action : {
189+ format_tool : ( { inputs, resourceLabel } ) => {
190+ const recordCount = getInputArrayLength ( inputs , 'recordIds' ) ;
191+ const recordsText = recordCount === undefined ? '' : ` for ${ recordCount } records` ;
192+
193+ return `Run ${ resourceLabel } ${ actionText ( inputs ) } ${ recordsText } ` ;
194+ } ,
195+ } ,
196+ create_record : {
197+ format_tool : ( { resourceLabel } ) => `Create ${ resourceLabel } ` ,
198+ } ,
199+ update_record : {
200+ format_tool : ( { resourceLabel } ) => `Update ${ resourceLabel } ` ,
201+ } ,
202+ delete_record : {
203+ format_tool : ( { resourceLabel } ) => `Delete ${ resourceLabel } ` ,
138204 } ,
139205} ;
140206
@@ -401,6 +467,28 @@ function endpointPathToToolName(path: string) {
401467 . replace ( / ^ _ + | _ + $ / g, '' ) ;
402468}
403469
470+ export async function formatApiBasedToolCall ( params : {
471+ adminforth : IAdminForth ;
472+ adminUser ?: AdminUser ;
473+ httpExtra ?: Partial < HttpExtra > ;
474+ inputs ?: Record < string , unknown > ;
475+ toolName : string ;
476+ userTimeZone ?: string ;
477+ } ) {
478+ const formatTool = TOOL_OVERRIDES [ params . toolName ] ?. format_tool ;
479+
480+ return await formatTool ?.( {
481+ adminUser : params . adminUser ,
482+ httpExtra : params . httpExtra ,
483+ inputs : params . inputs ,
484+ resourceLabel : resourceLabel ( params . adminforth , params . inputs ) ,
485+ userTimeZone : params . userTimeZone ,
486+ invokeTool : async ( ) => {
487+ throw new Error ( 'Tool info formatting cannot invoke tools' ) ;
488+ } ,
489+ } ) ;
490+ }
491+
404492function normalizeCookies ( cookies ?: Partial < HttpExtra > [ 'cookies' ] ) : CookieItem [ ] {
405493 if ( ! cookies ) {
406494 return [ ] ;
0 commit comments