@@ -14,6 +14,7 @@ import { ToolResponse } from '../types/common.ts';
1414import type { CommandExecutor } from './execution/index.ts' ;
1515import { createErrorResponse } from './responses/index.ts' ;
1616import { sessionStore , type SessionDefaults } from './session-store.ts' ;
17+ import { isSessionDefaultsSchemaOptOutEnabled } from './environment.ts' ;
1718
1819/**
1920 * Creates a type-safe tool handler that validates parameters at runtime
@@ -71,6 +72,27 @@ function missingFromMerged(
7172 return keys . filter ( ( k ) => merged [ k ] == null ) ;
7273}
7374
75+ function formatRequirementError ( opts : {
76+ message : string ;
77+ setHint ?: string ;
78+ optOutEnabled : boolean ;
79+ } ) {
80+ const title = opts . optOutEnabled
81+ ? 'Missing required parameters'
82+ : 'Missing required session defaults' ;
83+ const body = opts . optOutEnabled
84+ ? opts . message
85+ : [ opts . message , opts . setHint ] . filter ( Boolean ) . join ( '\n' ) ;
86+ return { title, body } ;
87+ }
88+
89+ export function getSessionAwareToolSchemaShape <
90+ TSession extends z . ZodRawShape ,
91+ TLegacy extends z . ZodRawShape ,
92+ > ( opts : { sessionAware : z . ZodObject < TSession > ; legacy : z . ZodObject < TLegacy > } ) : z . ZodRawShape {
93+ return isSessionDefaultsSchemaOptOutEnabled ( ) ? opts . legacy . shape : opts . sessionAware . shape ;
94+ }
95+
7496export function createSessionAwareTool < TParams > ( opts : {
7597 internalSchema : z . ZodType < TParams > ;
7698 logicFunction : ( params : TParams , executor : CommandExecutor ) => Promise < ToolResponse > ;
@@ -132,13 +154,15 @@ export function createSessionAwareTool<TParams>(opts: {
132154 if ( 'allOf' in req ) {
133155 const missing = missingFromMerged ( req . allOf , merged ) ;
134156 if ( missing . length > 0 ) {
135- return createErrorResponse (
136- 'Missing required session defaults' ,
137- `${ req . message ?? `Required: ${ req . allOf . join ( ', ' ) } ` } \n` +
138- `Set with: session-set-defaults { ${ missing
139- . map ( ( k ) => `"${ k } ": "..."` )
140- . join ( ', ' ) } }`,
141- ) ;
157+ const setHint = `Set with: session-set-defaults { ${ missing
158+ . map ( ( k ) => `"${ k } ": "..."` )
159+ . join ( ', ' ) } }`;
160+ const { title, body } = formatRequirementError ( {
161+ message : req . message ?? `Required: ${ req . allOf . join ( ', ' ) } ` ,
162+ setHint,
163+ optOutEnabled : isSessionDefaultsSchemaOptOutEnabled ( ) ,
164+ } ) ;
165+ return createErrorResponse ( title , body ) ;
142166 }
143167 } else if ( 'oneOf' in req ) {
144168 const satisfied = req . oneOf . some ( ( k ) => merged [ k ] != null ) ;
@@ -147,10 +171,12 @@ export function createSessionAwareTool<TParams>(opts: {
147171 const setHints = req . oneOf
148172 . map ( ( k ) => `session-set-defaults { "${ k } ": "..." }` )
149173 . join ( ' OR ' ) ;
150- return createErrorResponse (
151- 'Missing required session defaults' ,
152- `${ req . message ?? `Provide one of: ${ options } ` } \nSet with: ${ setHints } ` ,
153- ) ;
174+ const { title, body } = formatRequirementError ( {
175+ message : req . message ?? `Provide one of: ${ options } ` ,
176+ setHint : `Set with: ${ setHints } ` ,
177+ optOutEnabled : isSessionDefaultsSchemaOptOutEnabled ( ) ,
178+ } ) ;
179+ return createErrorResponse ( title , body ) ;
154180 }
155181 }
156182 }
@@ -164,10 +190,12 @@ export function createSessionAwareTool<TParams>(opts: {
164190 return `${ path } : ${ e . message } ` ;
165191 } ) ;
166192
167- return createErrorResponse (
168- 'Parameter validation failed' ,
169- `Invalid parameters:\n${ errorMessages . join ( '\n' ) } \nTip: set session defaults via session-set-defaults` ,
170- ) ;
193+ const tip = isSessionDefaultsSchemaOptOutEnabled ( )
194+ ? ''
195+ : '\nTip: set session defaults via session-set-defaults' ;
196+ const details = `Invalid parameters:\n${ errorMessages . join ( '\n' ) } ${ tip } ` ;
197+
198+ return createErrorResponse ( 'Parameter validation failed' , details ) ;
171199 }
172200 throw error ;
173201 }
0 commit comments