66 readLiveDocumentMcpSchema ,
77} from '@/lib/api/contracts/knowledge/mcp'
88import { mcpToolCallParamsSchema } from '@/lib/api/contracts/mcp'
9+ import { liveSearchProviderSchema } from '@/lib/api/contracts/mothership-assistant-tools'
910
1011/** Search filters a client sometimes writes on each native query instead of on the search. */
1112const SEARCH_FILTERS_ON_NATIVE_QUERIES = [
@@ -17,11 +18,12 @@ const SEARCH_FILTERS_ON_NATIVE_QUERIES = [
1718 'topK' ,
1819] as const
1920
20- const TOOL_INPUT_SCHEMAS : Record < string , z . ZodType > = {
21- search : liveSearchMcpSchema ,
22- read_document : readLiveDocumentMcpSchema ,
23- chat : chatSearchMcpSchema ,
24- }
21+ /** Keyed by client-supplied tool names, so a name such as `constructor` finds nothing. */
22+ const TOOL_INPUT_SCHEMAS = new Map < string , z . ZodType > ( [
23+ [ 'search' , liveSearchMcpSchema ] ,
24+ [ 'read_document' , readLiveDocumentMcpSchema ] ,
25+ [ 'chat' , chatSearchMcpSchema ] ,
26+ ] )
2527
2628function readToolCall ( message : Record < string , unknown > ) {
2729 if ( message . method !== 'tools/call' ) return undefined
@@ -31,16 +33,17 @@ function readToolCall(message: Record<string, unknown>) {
3133
3234/**
3335 * Search arguments rewritten where the schema rejects them but they have exactly one reading: an
34- * empty `nativeQueries` list, a null optional native query field, a top-level `provider` (the
35- * `source` filter), and a search filter every native query carries with the same value. Native
36+ * empty `nativeQueries` list, a null optional native query field, a top-level `provider` naming a
37+ * provider (the `source` filter), and a search filter every native query carries with the same value. Native
3638 * queries that disagree on a filter are left for the schema to reject.
3739 */
3840function repairSearchArguments ( args : Record < string , unknown > ) {
3941 const { nativeQueries : queries , provider, ...rest } = args
4042 const repaired : Record < string , unknown > = rest
4143 const repairs = new Set < string > ( )
42- if ( typeof provider === 'string' && ( rest . source === undefined || rest . source === provider ) ) {
43- repaired . source = provider
44+ const providerId = liveSearchProviderSchema . safeParse ( provider )
45+ if ( providerId . success && ( rest . source === undefined || rest . source === providerId . data ) ) {
46+ repaired . source = providerId . data
4447 repairs . add ( 'providerAsSource' )
4548 } else if ( provider !== undefined ) repaired . provider = provider
4649 if ( Array . isArray ( queries ) && queries . length === 0 ) repairs . add ( 'emptyNativeQueries' )
@@ -90,7 +93,7 @@ export function repairToolCallMessage(message: Record<string, unknown>) {
9093 */
9194export function toolCallInputIssues ( message : Record < string , unknown > ) {
9295 const call = readToolCall ( message )
93- const schema = call ? TOOL_INPUT_SCHEMAS [ call . name ] : undefined
96+ const schema = call ? TOOL_INPUT_SCHEMAS . get ( call . name ) : undefined
9497 if ( ! call || ! schema ) return undefined
9598 const parsed = schema . safeParse ( call . arguments ?? { } )
9699 if ( parsed . success ) return undefined
0 commit comments