@toolplex/ai-engine 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/LICENSE +98 -0
  2. package/README.md +292 -0
  3. package/dist/adapters/index.d.ts +9 -0
  4. package/dist/adapters/index.d.ts.map +1 -0
  5. package/dist/adapters/index.js +9 -0
  6. package/dist/adapters/index.js.map +1 -0
  7. package/dist/adapters/types.d.ts +137 -0
  8. package/dist/adapters/types.d.ts.map +1 -0
  9. package/dist/adapters/types.js +14 -0
  10. package/dist/adapters/types.js.map +1 -0
  11. package/dist/core/ChatEngine.d.ts +47 -0
  12. package/dist/core/ChatEngine.d.ts.map +1 -0
  13. package/dist/core/ChatEngine.js +355 -0
  14. package/dist/core/ChatEngine.js.map +1 -0
  15. package/dist/core/ToolBuilder.d.ts +25 -0
  16. package/dist/core/ToolBuilder.d.ts.map +1 -0
  17. package/dist/core/ToolBuilder.js +215 -0
  18. package/dist/core/ToolBuilder.js.map +1 -0
  19. package/dist/core/index.d.ts +6 -0
  20. package/dist/core/index.d.ts.map +1 -0
  21. package/dist/core/index.js +6 -0
  22. package/dist/core/index.js.map +1 -0
  23. package/dist/index.d.ts +41 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +49 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/mcp/DefaultStdioTransportFactory.d.ts +27 -0
  28. package/dist/mcp/DefaultStdioTransportFactory.d.ts.map +1 -0
  29. package/dist/mcp/DefaultStdioTransportFactory.js +60 -0
  30. package/dist/mcp/DefaultStdioTransportFactory.js.map +1 -0
  31. package/dist/mcp/MCPClient.d.ts +60 -0
  32. package/dist/mcp/MCPClient.d.ts.map +1 -0
  33. package/dist/mcp/MCPClient.js +164 -0
  34. package/dist/mcp/MCPClient.js.map +1 -0
  35. package/dist/mcp/index.d.ts +10 -0
  36. package/dist/mcp/index.d.ts.map +1 -0
  37. package/dist/mcp/index.js +11 -0
  38. package/dist/mcp/index.js.map +1 -0
  39. package/dist/mcp/paths.d.ts +16 -0
  40. package/dist/mcp/paths.d.ts.map +1 -0
  41. package/dist/mcp/paths.js +58 -0
  42. package/dist/mcp/paths.js.map +1 -0
  43. package/dist/mcp/types.d.ts +85 -0
  44. package/dist/mcp/types.d.ts.map +1 -0
  45. package/dist/mcp/types.js +7 -0
  46. package/dist/mcp/types.js.map +1 -0
  47. package/dist/providers/index.d.ts +40 -0
  48. package/dist/providers/index.d.ts.map +1 -0
  49. package/dist/providers/index.js +148 -0
  50. package/dist/providers/index.js.map +1 -0
  51. package/dist/providers/toolplex.d.ts +43 -0
  52. package/dist/providers/toolplex.d.ts.map +1 -0
  53. package/dist/providers/toolplex.js +168 -0
  54. package/dist/providers/toolplex.js.map +1 -0
  55. package/dist/types/index.d.ts +218 -0
  56. package/dist/types/index.d.ts.map +1 -0
  57. package/dist/types/index.js +8 -0
  58. package/dist/types/index.js.map +1 -0
  59. package/dist/utils/index.d.ts +8 -0
  60. package/dist/utils/index.d.ts.map +1 -0
  61. package/dist/utils/index.js +8 -0
  62. package/dist/utils/index.js.map +1 -0
  63. package/dist/utils/models.d.ts +30 -0
  64. package/dist/utils/models.d.ts.map +1 -0
  65. package/dist/utils/models.js +52 -0
  66. package/dist/utils/models.js.map +1 -0
  67. package/dist/utils/schema.d.ts +74 -0
  68. package/dist/utils/schema.d.ts.map +1 -0
  69. package/dist/utils/schema.js +253 -0
  70. package/dist/utils/schema.js.map +1 -0
  71. package/package.json +70 -0
  72. package/src/adapters/index.ts +9 -0
  73. package/src/adapters/types.ts +241 -0
  74. package/src/core/ChatEngine.ts +464 -0
  75. package/src/core/ToolBuilder.ts +323 -0
  76. package/src/core/index.ts +6 -0
  77. package/src/index.ts +86 -0
  78. package/src/mcp/DefaultStdioTransportFactory.ts +71 -0
  79. package/src/mcp/MCPClient.ts +209 -0
  80. package/src/mcp/index.ts +24 -0
  81. package/src/mcp/paths.ts +91 -0
  82. package/src/mcp/types.ts +93 -0
  83. package/src/providers/index.ts +177 -0
  84. package/src/providers/toolplex.ts +217 -0
  85. package/src/types/index.ts +290 -0
  86. package/src/utils/index.ts +8 -0
  87. package/src/utils/models.ts +59 -0
  88. package/src/utils/schema.ts +307 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @toolplex/ai-engine - Utilities
3
+ *
4
+ * Export all utility functions.
5
+ */
6
+ export * from "./schema.js";
7
+ export * from "./models.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @toolplex/ai-engine - Model Utilities
3
+ *
4
+ * Utility functions for model detection and handling.
5
+ */
6
+ /**
7
+ * Check if a model is a ChatGPT/OpenAI model
8
+ * Includes both direct OpenAI models (gpt-*) and OpenRouter proxied models (openai/*)
9
+ */
10
+ export declare function isChatGPTModel(modelId: string): boolean;
11
+ /**
12
+ * Check if the model is a Google Gemini model
13
+ */
14
+ export declare function isGoogleGeminiModel(modelId: string): boolean;
15
+ /**
16
+ * Check if the model is an Anthropic Claude model
17
+ */
18
+ export declare function isAnthropicModel(modelId: string): boolean;
19
+ /**
20
+ * Extract provider and model ID from a combined model string
21
+ * Format: "provider/model-id" or just "model-id"
22
+ *
23
+ * @param modelId - Combined model ID string
24
+ * @returns Object with providerId and actualModelId
25
+ */
26
+ export declare function parseModelId(modelId: string): {
27
+ providerId: string;
28
+ actualModelId: string;
29
+ };
30
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/utils/models.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,CAoBA"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @toolplex/ai-engine - Model Utilities
3
+ *
4
+ * Utility functions for model detection and handling.
5
+ */
6
+ /**
7
+ * Check if a model is a ChatGPT/OpenAI model
8
+ * Includes both direct OpenAI models (gpt-*) and OpenRouter proxied models (openai/*)
9
+ */
10
+ export function isChatGPTModel(modelId) {
11
+ return modelId.startsWith("gpt-") || modelId.startsWith("openai/gpt-");
12
+ }
13
+ /**
14
+ * Check if the model is a Google Gemini model
15
+ */
16
+ export function isGoogleGeminiModel(modelId) {
17
+ return modelId.startsWith("google/") || modelId.startsWith("gemini");
18
+ }
19
+ /**
20
+ * Check if the model is an Anthropic Claude model
21
+ */
22
+ export function isAnthropicModel(modelId) {
23
+ return modelId.startsWith("anthropic/") || modelId.startsWith("claude");
24
+ }
25
+ /**
26
+ * Extract provider and model ID from a combined model string
27
+ * Format: "provider/model-id" or just "model-id"
28
+ *
29
+ * @param modelId - Combined model ID string
30
+ * @returns Object with providerId and actualModelId
31
+ */
32
+ export function parseModelId(modelId) {
33
+ const parts = modelId.split("/");
34
+ if (parts.length === 1) {
35
+ // No provider prefix, try to detect from model name
36
+ if (modelId.startsWith("gpt-") || modelId.startsWith("o1")) {
37
+ return { providerId: "openai", actualModelId: modelId };
38
+ }
39
+ if (modelId.startsWith("claude")) {
40
+ return { providerId: "anthropic", actualModelId: modelId };
41
+ }
42
+ if (modelId.startsWith("gemini")) {
43
+ return { providerId: "google", actualModelId: modelId };
44
+ }
45
+ // Default to toolplex
46
+ return { providerId: "toolplex", actualModelId: modelId };
47
+ }
48
+ const providerId = parts[0];
49
+ const actualModelId = parts.slice(1).join("/");
50
+ return { providerId, actualModelId };
51
+ }
52
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/utils/models.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AACzE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,OAAO,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAI1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,oDAAoD;QACpD,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;QAC1D,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;QAC7D,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;QAC1D,CAAC;QACD,sBAAsB;QACtB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @toolplex/ai-engine - Schema Utilities
3
+ *
4
+ * Pure utility functions for JSON Schema manipulation.
5
+ * Used for tool schema processing before passing to AI SDK.
6
+ */
7
+ import type { LoggerAdapter } from "../adapters/types.js";
8
+ /**
9
+ * Deep sanitize tool parameters by recursively parsing stringified JSON values
10
+ *
11
+ * Some LLMs incorrectly stringify nested objects in tool parameters.
12
+ * This function recursively detects and parses such stringified values while
13
+ * respecting the tool's input schema to avoid corrupting legitimate string parameters.
14
+ *
15
+ * CRITICAL FIX: This function is now schema-aware. It will NOT parse strings that
16
+ * the schema explicitly declares as type "string". This prevents catastrophic bugs
17
+ * where tools expecting JSON content as a string (e.g., write_file) would receive
18
+ * a parsed object instead.
19
+ *
20
+ * FIELD-AWARE FIX: Special handling for the 'arguments' field in call_tool.
21
+ * ChatGPT and other models sometimes stringify this field even though it should
22
+ * always be an object. This is a documented OpenAI issue (July 2024).
23
+ *
24
+ * @param params - The parameters to sanitize
25
+ * @param schema - The JSON Schema for these parameters (optional but recommended)
26
+ * @param fieldName - The name of the field being processed (for field-aware logic)
27
+ * @param logger - Optional logger for debug output
28
+ * @returns Sanitized parameters
29
+ */
30
+ export declare function deepSanitizeParams(params: any, schema?: any, fieldName?: string, logger?: LoggerAdapter): any;
31
+ /**
32
+ * Resolve $ref references in JSON Schema by inlining from $defs
33
+ *
34
+ * Some MCP servers (like ElevenLabs) return tool schemas with $ref references
35
+ * that point to $defs entries. The AI SDK's jsonSchema() validator (via AJV)
36
+ * fails to resolve these references if they're not properly structured.
37
+ *
38
+ * This function:
39
+ * 1. Extracts $defs from the root schema (if present)
40
+ * 2. Recursively replaces $ref references with their actual definitions
41
+ * 3. Falls back to permissive schema ({}) for unresolved references
42
+ *
43
+ * @param schema - The JSON Schema to process
44
+ * @param defs - The $defs object from the root schema (optional, extracted from schema if not provided)
45
+ * @param logger - Optional logger for warnings
46
+ * @returns Schema with $ref references resolved
47
+ */
48
+ export declare function resolveSchemaRefs(schema: any, defs?: Record<string, any>, logger?: LoggerAdapter): any;
49
+ /**
50
+ * Sanitize JSON Schema for Google Gemini compatibility
51
+ *
52
+ * Gemini has strict schema requirements for function calling:
53
+ * - No oneOf, anyOf, allOf constructs
54
+ * - No const values
55
+ * - enum only allowed for string types
56
+ * - Object types must have properties defined (even if empty)
57
+ * - required arrays cause issues with AI SDK transformation
58
+ */
59
+ export declare function sanitizeSchemaForGemini(schema: any): any;
60
+ /**
61
+ * Clean a tool schema for AI SDK consumption
62
+ *
63
+ * Combines all schema processing steps:
64
+ * 1. Remove $schema reference
65
+ * 2. Resolve $ref references
66
+ * 3. Apply Gemini sanitization if needed
67
+ *
68
+ * @param schema - Raw tool input schema from MCP
69
+ * @param isGemini - Whether the target model is Google Gemini
70
+ * @param logger - Optional logger
71
+ * @returns Cleaned schema ready for AI SDK
72
+ */
73
+ export declare function cleanToolSchema(schema: any, isGemini?: boolean, logger?: LoggerAdapter): any;
74
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/utils/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,GAAG,EACX,MAAM,CAAC,EAAE,GAAG,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,aAAa,GACrB,GAAG,CAqFL;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,GAAG,EACX,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,MAAM,CAAC,EAAE,aAAa,GACrB,GAAG,CAoDL;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CA6DxD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,GAAG,EACX,QAAQ,GAAE,OAAe,EACzB,MAAM,CAAC,EAAE,aAAa,GACrB,GAAG,CAkBL"}
@@ -0,0 +1,253 @@
1
+ /**
2
+ * @toolplex/ai-engine - Schema Utilities
3
+ *
4
+ * Pure utility functions for JSON Schema manipulation.
5
+ * Used for tool schema processing before passing to AI SDK.
6
+ */
7
+ /**
8
+ * Deep sanitize tool parameters by recursively parsing stringified JSON values
9
+ *
10
+ * Some LLMs incorrectly stringify nested objects in tool parameters.
11
+ * This function recursively detects and parses such stringified values while
12
+ * respecting the tool's input schema to avoid corrupting legitimate string parameters.
13
+ *
14
+ * CRITICAL FIX: This function is now schema-aware. It will NOT parse strings that
15
+ * the schema explicitly declares as type "string". This prevents catastrophic bugs
16
+ * where tools expecting JSON content as a string (e.g., write_file) would receive
17
+ * a parsed object instead.
18
+ *
19
+ * FIELD-AWARE FIX: Special handling for the 'arguments' field in call_tool.
20
+ * ChatGPT and other models sometimes stringify this field even though it should
21
+ * always be an object. This is a documented OpenAI issue (July 2024).
22
+ *
23
+ * @param params - The parameters to sanitize
24
+ * @param schema - The JSON Schema for these parameters (optional but recommended)
25
+ * @param fieldName - The name of the field being processed (for field-aware logic)
26
+ * @param logger - Optional logger for debug output
27
+ * @returns Sanitized parameters
28
+ */
29
+ export function deepSanitizeParams(params, schema, fieldName, logger) {
30
+ if (params === null || params === undefined) {
31
+ return params;
32
+ }
33
+ // If it's a string, check schema before attempting to parse
34
+ if (typeof params === "string") {
35
+ const trimmed = params.trim();
36
+ // Only consider parsing if it looks like JSON (starts with { or [)
37
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
38
+ // CRITICAL: If schema explicitly says this should be a string, NEVER parse
39
+ // This prevents corrupting legitimate JSON content that tools expect as strings
40
+ if (schema?.type === "string") {
41
+ return params;
42
+ }
43
+ // If schema says this should be an object or array, parse it
44
+ // This fixes LLMs that accidentally stringify nested objects
45
+ if (schema?.type === "object" || schema?.type === "array") {
46
+ try {
47
+ const parsed = JSON.parse(params);
48
+ return deepSanitizeParams(parsed, schema, fieldName, logger);
49
+ }
50
+ catch {
51
+ // Invalid JSON, return as-is
52
+ return params;
53
+ }
54
+ }
55
+ // FIELD-AWARE FIX: Special handling for 'arguments' field
56
+ // Known issue: ChatGPT sometimes stringifies the arguments field in call_tool
57
+ // even though it should always be an object (OpenAI bug documented July 2024)
58
+ if (fieldName === "arguments") {
59
+ try {
60
+ const parsed = JSON.parse(params);
61
+ logger?.info('Parsed stringified "arguments" field (ChatGPT workaround)', {
62
+ fieldName,
63
+ originalType: typeof params,
64
+ parsedType: typeof parsed,
65
+ hadSchema: !!schema,
66
+ });
67
+ return deepSanitizeParams(parsed, schema, fieldName, logger);
68
+ }
69
+ catch {
70
+ // Invalid JSON, let validation fail naturally
71
+ logger?.warn('Failed to parse stringified "arguments" field', {
72
+ fieldName,
73
+ });
74
+ return params;
75
+ }
76
+ }
77
+ // No schema or ambiguous schema - be conservative and don't parse
78
+ return params;
79
+ }
80
+ // Regular string (doesn't look like JSON), return as-is
81
+ return params;
82
+ }
83
+ // If it's an array, recursively sanitize each element
84
+ if (Array.isArray(params)) {
85
+ const itemSchema = schema?.items;
86
+ return params.map((item) => deepSanitizeParams(item, itemSchema, fieldName, logger));
87
+ }
88
+ // If it's an object, recursively sanitize each property with its schema
89
+ if (typeof params === "object") {
90
+ const sanitized = {};
91
+ const properties = schema?.properties || {};
92
+ for (const [key, value] of Object.entries(params)) {
93
+ const propertySchema = properties[key];
94
+ // Pass the key as fieldName for field-aware logic
95
+ sanitized[key] = deepSanitizeParams(value, propertySchema, key, logger);
96
+ }
97
+ return sanitized;
98
+ }
99
+ // Primitive value, return as-is
100
+ return params;
101
+ }
102
+ /**
103
+ * Resolve $ref references in JSON Schema by inlining from $defs
104
+ *
105
+ * Some MCP servers (like ElevenLabs) return tool schemas with $ref references
106
+ * that point to $defs entries. The AI SDK's jsonSchema() validator (via AJV)
107
+ * fails to resolve these references if they're not properly structured.
108
+ *
109
+ * This function:
110
+ * 1. Extracts $defs from the root schema (if present)
111
+ * 2. Recursively replaces $ref references with their actual definitions
112
+ * 3. Falls back to permissive schema ({}) for unresolved references
113
+ *
114
+ * @param schema - The JSON Schema to process
115
+ * @param defs - The $defs object from the root schema (optional, extracted from schema if not provided)
116
+ * @param logger - Optional logger for warnings
117
+ * @returns Schema with $ref references resolved
118
+ */
119
+ export function resolveSchemaRefs(schema, defs, logger) {
120
+ if (!schema || typeof schema !== "object")
121
+ return schema;
122
+ // Extract $defs from root schema if not provided
123
+ if (!defs && schema.$defs) {
124
+ defs = schema.$defs;
125
+ }
126
+ // Handle arrays
127
+ if (Array.isArray(schema)) {
128
+ return schema.map((item) => resolveSchemaRefs(item, defs, logger));
129
+ }
130
+ // Check if this is a $ref
131
+ if (schema.$ref && typeof schema.$ref === "string") {
132
+ // Parse the $ref to extract the definition name
133
+ // Format: "#/$defs/DefinitionName" or "#/definitions/DefinitionName"
134
+ const refMatch = schema.$ref.match(/^#\/(\$defs|definitions)\/(.+)$/);
135
+ if (refMatch && defs) {
136
+ const defName = refMatch[2];
137
+ const resolvedDef = defs[defName];
138
+ if (resolvedDef) {
139
+ // Recursively resolve any nested $refs in the definition
140
+ // Merge any other properties from the $ref schema (like description)
141
+ const { $ref: _ref, ...otherProps } = schema;
142
+ const resolved = resolveSchemaRefs(resolvedDef, defs, logger);
143
+ return { ...resolved, ...otherProps };
144
+ }
145
+ }
146
+ // Unresolved $ref - replace with permissive schema
147
+ logger?.warn("Unresolved $ref in tool schema, using permissive schema", {
148
+ ref: schema.$ref,
149
+ availableDefs: defs ? Object.keys(defs) : [],
150
+ });
151
+ return {}; // Permissive schema - accepts anything
152
+ }
153
+ // Recursively process object properties
154
+ const result = {};
155
+ for (const [key, value] of Object.entries(schema)) {
156
+ if (key === "$defs" || key === "definitions") {
157
+ // Keep $defs in result for nested resolution
158
+ result[key] = value;
159
+ }
160
+ else {
161
+ result[key] = resolveSchemaRefs(value, defs, logger);
162
+ }
163
+ }
164
+ return result;
165
+ }
166
+ /**
167
+ * Sanitize JSON Schema for Google Gemini compatibility
168
+ *
169
+ * Gemini has strict schema requirements for function calling:
170
+ * - No oneOf, anyOf, allOf constructs
171
+ * - No const values
172
+ * - enum only allowed for string types
173
+ * - Object types must have properties defined (even if empty)
174
+ * - required arrays cause issues with AI SDK transformation
175
+ */
176
+ export function sanitizeSchemaForGemini(schema) {
177
+ if (!schema || typeof schema !== "object")
178
+ return schema;
179
+ if (Array.isArray(schema)) {
180
+ return schema.map((item) => sanitizeSchemaForGemini(item));
181
+ }
182
+ const result = {};
183
+ for (const [key, value] of Object.entries(schema)) {
184
+ // Skip unsupported constructs
185
+ if (key === "oneOf" ||
186
+ key === "anyOf" ||
187
+ key === "allOf" ||
188
+ key === "const") {
189
+ continue;
190
+ }
191
+ // Skip enum on non-string types
192
+ if (key === "enum" && schema.type !== "string") {
193
+ continue;
194
+ }
195
+ // Skip required arrays entirely - Gemini has issues with AI SDK's transformation
196
+ if (key === "required") {
197
+ continue;
198
+ }
199
+ // Recursively sanitize nested structures
200
+ if (key === "properties" && typeof value === "object") {
201
+ result[key] = {};
202
+ for (const [propName, propValue] of Object.entries(value)) {
203
+ result[key][propName] = sanitizeSchemaForGemini(propValue);
204
+ }
205
+ continue;
206
+ }
207
+ if ((key === "items" || key === "additionalProperties") &&
208
+ typeof value === "object") {
209
+ result[key] = sanitizeSchemaForGemini(value);
210
+ continue;
211
+ }
212
+ if (typeof value === "object" && value !== null) {
213
+ result[key] = sanitizeSchemaForGemini(value);
214
+ }
215
+ else {
216
+ result[key] = value;
217
+ }
218
+ }
219
+ // Ensure object types have properties defined
220
+ if (result.type === "object" && !result.properties) {
221
+ result.properties = {};
222
+ }
223
+ return result;
224
+ }
225
+ /**
226
+ * Clean a tool schema for AI SDK consumption
227
+ *
228
+ * Combines all schema processing steps:
229
+ * 1. Remove $schema reference
230
+ * 2. Resolve $ref references
231
+ * 3. Apply Gemini sanitization if needed
232
+ *
233
+ * @param schema - Raw tool input schema from MCP
234
+ * @param isGemini - Whether the target model is Google Gemini
235
+ * @param logger - Optional logger
236
+ * @returns Cleaned schema ready for AI SDK
237
+ */
238
+ export function cleanToolSchema(schema, isGemini = false, logger) {
239
+ if (!schema) {
240
+ return { type: "object", properties: {} };
241
+ }
242
+ // Deep clone to avoid mutating original
243
+ const cleanedSchema = JSON.parse(JSON.stringify(schema));
244
+ delete cleanedSchema.$schema;
245
+ // Resolve $ref references
246
+ const resolvedSchema = resolveSchemaRefs(cleanedSchema, undefined, logger);
247
+ // Remove $defs after resolution
248
+ delete resolvedSchema.$defs;
249
+ delete resolvedSchema.definitions;
250
+ // Apply Gemini-specific sanitization if needed
251
+ return isGemini ? sanitizeSchemaForGemini(resolvedSchema) : resolvedSchema;
252
+ }
253
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/utils/schema.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@toolplex/ai-engine",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Core AI chat engine for ToolPlex - powers desktop, cloud, and CLI",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./adapters": {
15
+ "types": "./dist/adapters/index.d.ts",
16
+ "import": "./dist/adapters/index.js",
17
+ "require": "./dist/adapters/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "src"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "build:watch": "tsc --watch",
27
+ "clean": "rm -rf dist",
28
+ "typecheck": "tsc --noEmit",
29
+ "lint": "eslint 'src/**/*.ts'",
30
+ "lint:fix": "eslint 'src/**/*.ts' --fix",
31
+ "format": "prettier --write 'src/**/*.ts'"
32
+ },
33
+ "keywords": [
34
+ "ai",
35
+ "chat",
36
+ "mcp",
37
+ "toolplex"
38
+ ],
39
+ "license": "BSL-1.1",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/toolplex/ai-engine"
43
+ },
44
+ "homepage": "https://toolplex.ai",
45
+ "bugs": {
46
+ "url": "https://github.com/toolplex/ai-engine/issues"
47
+ },
48
+ "dependencies": {
49
+ "@ai-sdk/anthropic": "^2.0.23",
50
+ "@ai-sdk/google": "^2.0.17",
51
+ "@ai-sdk/openai": "^2.0.42",
52
+ "@ai-sdk/openai-compatible": "^1.0.19",
53
+ "@modelcontextprotocol/sdk": "^1.16.0",
54
+ "@openrouter/ai-sdk-provider": "^1.2.0",
55
+ "@toolplex/client": "^0.1.39",
56
+ "ai": "^5.0.60"
57
+ },
58
+ "devDependencies": {
59
+ "@eslint/js": "^9.24.0",
60
+ "@types/node": "^20.5.0",
61
+ "@typescript-eslint/eslint-plugin": "^8.29.0",
62
+ "@typescript-eslint/parser": "^8.29.0",
63
+ "eslint": "^9.24.0",
64
+ "eslint-config-prettier": "^10.1.1",
65
+ "eslint-plugin-prettier": "^5.2.6",
66
+ "prettier": "^3.5.3",
67
+ "typescript": "^5.0.0",
68
+ "typescript-eslint": "^8.29.0"
69
+ }
70
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @toolplex/ai-engine - Adapters
3
+ *
4
+ * Export adapter types and any shared adapter utilities.
5
+ * Platform-specific adapters (Electron, HTTP, CLI) are provided
6
+ * separately to avoid bundling unnecessary dependencies.
7
+ */
8
+
9
+ export * from "./types.js";