{"version":3,"file":"McpLlm.mjs","sources":["../src/McpLlm.ts"],"sourcesContent":["import { OpenApi } from \"./OpenApi\";\nimport { LlmSchemaComposer } from \"./composers/LlmSchemaComposer\";\nimport { OpenApiV3_1Emender } from \"./converters/OpenApiV3_1Emender\";\nimport { ILlmSchema } from \"./structures/ILlmSchema\";\nimport { IMcpLlmApplication } from \"./structures/IMcpLlmApplication\";\nimport { IMcpLlmFunction } from \"./structures/IMcpLlmFunction\";\nimport { IMcpTool } from \"./structures/IMcpTool\";\nimport { IOpenApiSchemaError } from \"./structures/IOpenApiSchemaError\";\nimport { IResult } from \"./structures/IResult\";\nimport { OpenApiTypeChecker } from \"./utils/OpenApiTypeChecker\";\nimport { OpenApiValidator } from \"./utils/OpenApiValidator\";\n\n/**\n * Application of LLM function calling from MCP document.\n *\n * `McpLlm` is a module for composing LLM (Large Language Model) function\n * calling application from MCP (Model Context Protocol) document.\n *\n * The reasons why `@samchon/openapi` recommends to use the function calling\n * feature instead of directly using the\n * [`mcp_servers`](https://openai.github.io/openai-agents-python/mcp/#using-mcp-servers)\n * property of LLM API are:\n *\n * - Model Specification: {@link ILlmSchema}\n * - Validation Feedback: {@link IMcpLlmFunction.validate}\n * - Selector agent for reducing context: [Agentica > Orchestration Strategy](https://wrtnlabs.io/agentica/docs/concepts/function-calling/#orchestration-strategy)\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport namespace McpLlm {\n  /**\n   * Properties for the LLM function calling application composer.\n   *\n   * @template Model Target LLM model\n   */\n  export interface IApplicationProps<Model extends ILlmSchema.Model> {\n    /**\n     * Target LLM model.\n     */\n    model: Model;\n\n    /**\n     * List of tools.\n     *\n     * A list of tools defined in the MCP (Model Context Protocol) document.\n     *\n     * It would better to validate the tools by\n     * [`typia.assert<T>()`](https://typia.io/docs/validate/assert) function\n     * for the type safety.\n     */\n    tools: Array<IMcpTool>;\n\n    /**\n     * Options for the LLM function calling schema conversion.\n     */\n    options?: Partial<IMcpLlmApplication.IOptions<Model>>;\n  }\n\n  /**\n   * Convert MCP document to LLM function calling application.\n   *\n   * Converts MCP (Model Context Protocol) to LLM (Large Language Model)\n   * function calling application.\n   *\n   * The reasons why `@samchon/openapi` recommends to use the function calling\n   * feature instead of directly using the\n   * [`mcp_servers`](https://openai.github.io/openai-agents-python/mcp/#using-mcp-servers)\n   * property of LLM API are:\n   *\n   * - Model Specification: {@link ILlmSchema}\n   * - Validation Feedback: {@link IMcpLlmFunction.validate}\n   * - Selector agent for reducing context: [Agentica > Orchestration Strategy](https://wrtnlabs.io/agentica/docs/concepts/function-calling/#orchestration-strategy)\n   *\n   * @param props Properties for composition\n   * @returns LLM function calling application\n   */\n  export const application = <Model extends ILlmSchema.Model>(\n    props: IApplicationProps<Model>,\n  ): IMcpLlmApplication<Model> => {\n    const options: IMcpLlmApplication.IOptions<Model> = {\n      ...Object.fromEntries(\n        Object.entries(LlmSchemaComposer.defaultConfig(props.model)).map(\n          ([key, value]) =>\n            [key, (props.options as any)?.[key] ?? value] as const,\n        ),\n      ),\n      maxLength: props.options?.maxLength ?? 64,\n    } as IMcpLlmApplication.IOptions<Model>;\n    const functions: IMcpLlmFunction<Model>[] = [];\n    const errors: IMcpLlmApplication.IError[] = [];\n\n    props.tools.forEach((tool, i) => {\n      // CONVERT TO EMENDED OPENAPI V3.1 SPECIFICATION\n      const components: OpenApi.IComponents =\n        OpenApiV3_1Emender.convertComponents({\n          schemas: tool.inputSchema.$defs,\n        });\n      const schema: OpenApi.IJsonSchema = OpenApiV3_1Emender.convertSchema({\n        schemas: tool.inputSchema.$defs,\n      })(tool.inputSchema);\n      if (components.schemas) {\n        const visited: Set<string> = new Set<string>();\n        OpenApiTypeChecker.visit({\n          closure: (schema: any) => {\n            if (typeof schema.$ref === \"string\")\n              visited.add(schema.$ref.split(\"/\").pop()!);\n          },\n          components,\n          schema,\n        });\n        components.schemas = Object.fromEntries(\n          Object.entries(components.schemas).filter(([key]) =>\n            visited.has(key),\n          ),\n        );\n      }\n\n      // CONVERT TO LLM PARAMETERS\n      const parameters: IResult<\n        ILlmSchema.IParameters<Model>,\n        IOpenApiSchemaError\n      > = LlmSchemaComposer.parameters(props.model)({\n        config: options as any,\n        components,\n        schema: schema as\n          | OpenApi.IJsonSchema.IObject\n          | OpenApi.IJsonSchema.IReference,\n        accessor: `$input.tools[${i}].inputSchema`,\n      }) as IResult<ILlmSchema.IParameters<Model>, IOpenApiSchemaError>;\n      if (parameters.success)\n        functions.push({\n          name: tool.name,\n          parameters: parameters.value,\n          description: tool.description,\n          validate: OpenApiValidator.create({\n            components,\n            schema,\n            required: true,\n          }),\n        });\n      else\n        errors.push({\n          name: tool.name,\n          parameters: tool.inputSchema,\n          description: tool.description,\n          messages: parameters.error.reasons.map((r) => {\n            const accessor: string = `$input.tools[${i}].inputSchema`;\n            return `${accessor}: ${r.message}`;\n          }),\n        });\n    });\n    return {\n      model: props.model,\n      functions,\n      options,\n      errors,\n    };\n  };\n}\n"],"names":["McpLlm","application","props","options","Object","fromEntries","entries","LlmSchemaComposer","defaultConfig","model","map","key","value","maxLength","functions","errors","tools","forEach","tool","i","components","OpenApiV3_1Emender","convertComponents","schemas","inputSchema","$defs","schema","convertSchema","visited","Set","OpenApiTypeChecker","visit","closure","$ref","add","split","pop","filter","has","parameters","config","accessor","success","push","name","description","validate","OpenApiValidator","create","required","messages","error","reasons","r","message"],"mappings":";;;;;;;;AA6BM,IAAWA;;CAAjB,SAAiBA;IA+CFA,OAAAC,cACXC;QAEA,MAAMC,UAA8C;eAC/CC,OAAOC,YACRD,OAAOE,QAAQC,kBAAkBC,cAAcN,MAAMO,QAAQC,KAC3D,EAAEC,KAAKC,WACL,EAACD,KAAMT,MAAMC,UAAkBQ,QAAQC;YAG7CC,WAAWX,MAAMC,SAASU,aAAa;;QAEzC,MAAMC,YAAsC;QAC5C,MAAMC,SAAsC;QAE5Cb,MAAMc,MAAMC,SAAQ,CAACC,MAAMC;YAEzB,MAAMC,aACJC,mBAAmBC,kBAAkB;gBACnCC,SAASL,KAAKM,YAAYC;;YAE9B,MAAMC,SAA8BL,mBAAmBM,cAAc;gBACnEJ,SAASL,KAAKM,YAAYC;cADQJ,CAEjCH,KAAKM;YACR,IAAIJ,WAAWG,SAAS;gBACtB,MAAMK,UAAuB,IAAIC;gBACjCC,mBAAmBC,MAAM;oBACvBC,SAAUN;wBACR,WAAWA,OAAOO,SAAS,UACzBL,QAAQM,IAAIR,OAAOO,KAAKE,MAAM,KAAKC;AAAO;oBAE9ChB;oBACAM;;gBAEFN,WAAWG,UAAUnB,OAAOC,YAC1BD,OAAOE,QAAQc,WAAWG,SAASc,QAAO,EAAE1B,SAC1CiB,QAAQU,IAAI3B;;YAMlB,MAAM4B,aAGFhC,kBAAkBgC,WAAWrC,MAAMO,MAAnCF,CAA0C;gBAC5CiC,QAAQrC;gBACRiB;gBACAM;gBAGAe,UAAU,gBAAgBtB;;YAE5B,IAAIoB,WAAWG,SACb5B,UAAU6B,KAAK;gBACbC,MAAM1B,KAAK0B;gBACXL,YAAYA,WAAW3B;gBACvBiC,aAAa3B,KAAK2B;gBAClBC,UAAUC,iBAAiBC,OAAO;oBAChC5B;oBACAM;oBACAuB,UAAU;;qBAIdlC,OAAO4B,KAAK;gBACVC,MAAM1B,KAAK0B;gBACXL,YAAYrB,KAAKM;gBACjBqB,aAAa3B,KAAK2B;gBAClBK,UAAUX,WAAWY,MAAMC,QAAQ1C,KAAK2C;oBACtC,MAAMZ,WAAmB,gBAAgBtB;oBACzC,OAAO,GAAGsB,aAAaY,EAAEC;AAAS;;AAEpC;QAEN,OAAO;YACL7C,OAAOP,MAAMO;YACbK;YACAX;YACAY;;AACD;AAEJ,EAjID,CAAiBf,WAAAA,SAiIhB,CAAA;;"}