universal-llm-client 4.5.0 → 4.5.1

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 (174) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +2 -0
  3. package/dist/ai-model.d.ts +0 -1
  4. package/dist/ai-model.js +0 -1
  5. package/dist/auditor.d.ts +0 -1
  6. package/dist/auditor.js +0 -1
  7. package/dist/client.d.ts +0 -1
  8. package/dist/client.js +0 -1
  9. package/dist/gemma-channel.d.ts +0 -1
  10. package/dist/gemma-channel.js +0 -1
  11. package/dist/gemma-diffusion.d.ts +0 -1
  12. package/dist/gemma-diffusion.js +0 -1
  13. package/dist/http.d.ts +0 -1
  14. package/dist/http.js +0 -1
  15. package/dist/index.d.ts +0 -1
  16. package/dist/index.js +0 -1
  17. package/dist/interfaces.d.ts +0 -1
  18. package/dist/interfaces.js +0 -1
  19. package/dist/mcp.d.ts +0 -1
  20. package/dist/mcp.js +0 -1
  21. package/dist/providers/anthropic.d.ts +0 -1
  22. package/dist/providers/anthropic.js +0 -1
  23. package/dist/providers/google.d.ts +0 -1
  24. package/dist/providers/google.js +0 -1
  25. package/dist/providers/index.d.ts +0 -1
  26. package/dist/providers/index.js +0 -1
  27. package/dist/providers/ollama.d.ts +0 -1
  28. package/dist/providers/ollama.js +0 -1
  29. package/dist/providers/openai.d.ts +2 -1
  30. package/dist/providers/openai.js +303 -74
  31. package/dist/router.d.ts +0 -1
  32. package/dist/router.js +0 -1
  33. package/dist/stream-decoder.d.ts +0 -1
  34. package/dist/stream-decoder.js +0 -1
  35. package/dist/structured-output.d.ts +0 -1
  36. package/dist/structured-output.js +0 -1
  37. package/dist/thinking.d.ts +0 -1
  38. package/dist/thinking.js +0 -1
  39. package/dist/tools.d.ts +0 -1
  40. package/dist/tools.js +0 -1
  41. package/dist/zod-adapter.d.ts +0 -1
  42. package/dist/zod-adapter.js +0 -1
  43. package/package.json +1 -2
  44. package/dist/ai-model.d.ts.map +0 -1
  45. package/dist/ai-model.js.map +0 -1
  46. package/dist/auditor.d.ts.map +0 -1
  47. package/dist/auditor.js.map +0 -1
  48. package/dist/client.d.ts.map +0 -1
  49. package/dist/client.js.map +0 -1
  50. package/dist/gemma-channel.d.ts.map +0 -1
  51. package/dist/gemma-channel.js.map +0 -1
  52. package/dist/gemma-diffusion.d.ts.map +0 -1
  53. package/dist/gemma-diffusion.js.map +0 -1
  54. package/dist/http.d.ts.map +0 -1
  55. package/dist/http.js.map +0 -1
  56. package/dist/index.d.ts.map +0 -1
  57. package/dist/index.js.map +0 -1
  58. package/dist/interfaces.d.ts.map +0 -1
  59. package/dist/interfaces.js.map +0 -1
  60. package/dist/mcp.d.ts.map +0 -1
  61. package/dist/mcp.js.map +0 -1
  62. package/dist/providers/anthropic.d.ts.map +0 -1
  63. package/dist/providers/anthropic.js.map +0 -1
  64. package/dist/providers/google.d.ts.map +0 -1
  65. package/dist/providers/google.js.map +0 -1
  66. package/dist/providers/index.d.ts.map +0 -1
  67. package/dist/providers/index.js.map +0 -1
  68. package/dist/providers/ollama.d.ts.map +0 -1
  69. package/dist/providers/ollama.js.map +0 -1
  70. package/dist/providers/openai.d.ts.map +0 -1
  71. package/dist/providers/openai.js.map +0 -1
  72. package/dist/router.d.ts.map +0 -1
  73. package/dist/router.js.map +0 -1
  74. package/dist/stream-decoder.d.ts.map +0 -1
  75. package/dist/stream-decoder.js.map +0 -1
  76. package/dist/structured-output.d.ts.map +0 -1
  77. package/dist/structured-output.js.map +0 -1
  78. package/dist/thinking.d.ts.map +0 -1
  79. package/dist/thinking.js.map +0 -1
  80. package/dist/tools.d.ts.map +0 -1
  81. package/dist/tools.js.map +0 -1
  82. package/dist/zod-adapter.d.ts.map +0 -1
  83. package/dist/zod-adapter.js.map +0 -1
  84. package/src/ai-model.ts +0 -400
  85. package/src/auditor.ts +0 -213
  86. package/src/client.ts +0 -402
  87. package/src/debug/debug-google-streaming.ts +0 -97
  88. package/src/debug/debug-tool-execution.ts +0 -86
  89. package/src/debug/test-lmstudio-tools.ts +0 -155
  90. package/src/demos/README.md +0 -47
  91. package/src/demos/basic/universal-llm-examples.ts +0 -161
  92. package/src/demos/diffusion-gemma/.env +0 -29
  93. package/src/demos/diffusion-gemma/.env.example +0 -27
  94. package/src/demos/diffusion-gemma/CLAUDE.md +0 -95
  95. package/src/demos/diffusion-gemma/README.md +0 -59
  96. package/src/demos/diffusion-gemma/canvas.ts +0 -1606
  97. package/src/demos/diffusion-gemma/docker-compose.yml +0 -29
  98. package/src/demos/diffusion-gemma/probe-stream.ts +0 -51
  99. package/src/demos/diffusion-gemma/probe-tools.ts +0 -55
  100. package/src/demos/diffusion-gemma/server.ts +0 -1205
  101. package/src/demos/diffusion-gemma/start-vllm.sh +0 -98
  102. package/src/demos/mcp/astrid-memory-demo.ts +0 -295
  103. package/src/demos/mcp/astrid-persona-memory.ts +0 -357
  104. package/src/demos/mcp/mcp-mongodb-demo.ts +0 -275
  105. package/src/demos/mcp/simple-astrid-memory.ts +0 -148
  106. package/src/demos/mcp/simple-mcp-demo.ts +0 -68
  107. package/src/demos/mcp/working-mcp-demo.ts +0 -62
  108. package/src/demos/model-alias-demo.ts +0 -0
  109. package/src/demos/tools/RAG_MEMORY_INTEGRATION.md +0 -267
  110. package/src/demos/tools/astrid-memory-demo.ts +0 -270
  111. package/src/demos/tools/astrid-production-memory-clean.ts +0 -785
  112. package/src/demos/tools/astrid-production-memory.ts +0 -558
  113. package/src/demos/tools/basic-translation-test.ts +0 -66
  114. package/src/demos/tools/chromadb-similarity-tuning.ts +0 -390
  115. package/src/demos/tools/clean-multilingual-conversation.ts +0 -209
  116. package/src/demos/tools/clean-translation-test.ts +0 -119
  117. package/src/demos/tools/clean-universal-multilingual-test.ts +0 -131
  118. package/src/demos/tools/complete-rag-demo.ts +0 -369
  119. package/src/demos/tools/complete-tool-demo.ts +0 -132
  120. package/src/demos/tools/demo-tool-calling.ts +0 -124
  121. package/src/demos/tools/dynamic-language-switching-test.ts +0 -251
  122. package/src/demos/tools/hybrid-thinking-test.ts +0 -154
  123. package/src/demos/tools/memory-integration-test.ts +0 -420
  124. package/src/demos/tools/multilingual-memory-system.ts +0 -802
  125. package/src/demos/tools/ondemand-translation-demo.ts +0 -655
  126. package/src/demos/tools/production-tool-demo.ts +0 -245
  127. package/src/demos/tools/revolutionary-multilingual-test.ts +0 -151
  128. package/src/demos/tools/rigorous-language-analysis.ts +0 -218
  129. package/src/demos/tools/test-universal-memory-system.ts +0 -126
  130. package/src/demos/tools/translation-integration-guide.ts +0 -346
  131. package/src/demos/tools/universal-memory-system.ts +0 -560
  132. package/src/gemma-channel.ts +0 -47
  133. package/src/gemma-diffusion.ts +0 -167
  134. package/src/http.ts +0 -261
  135. package/src/index.ts +0 -180
  136. package/src/interfaces.ts +0 -843
  137. package/src/mcp.ts +0 -345
  138. package/src/providers/anthropic.ts +0 -796
  139. package/src/providers/google.ts +0 -840
  140. package/src/providers/index.ts +0 -8
  141. package/src/providers/ollama.ts +0 -503
  142. package/src/providers/openai.ts +0 -587
  143. package/src/router.ts +0 -785
  144. package/src/stream-decoder.ts +0 -535
  145. package/src/structured-output.ts +0 -759
  146. package/src/test-scripts/test-advanced-tools.ts +0 -310
  147. package/src/test-scripts/test-google-deep-research.ts +0 -33
  148. package/src/test-scripts/test-google-streaming-enhanced.ts +0 -147
  149. package/src/test-scripts/test-google-streaming.ts +0 -63
  150. package/src/test-scripts/test-google-system-prompt-comprehensive.ts +0 -189
  151. package/src/test-scripts/test-google-thinking.ts +0 -46
  152. package/src/test-scripts/test-mcp-config.ts +0 -28
  153. package/src/test-scripts/test-mcp-connection.ts +0 -29
  154. package/src/test-scripts/test-system-message-positions.ts +0 -163
  155. package/src/test-scripts/test-system-prompt-improvement-demo.ts +0 -83
  156. package/src/test-scripts/test-tool-calling.ts +0 -231
  157. package/src/test-scripts/test-vllm-qwen36.ts +0 -256
  158. package/src/tests/ai-model.test.ts +0 -1614
  159. package/src/tests/auditor.test.ts +0 -224
  160. package/src/tests/gemma-diffusion.test.ts +0 -115
  161. package/src/tests/http.test.ts +0 -200
  162. package/src/tests/interfaces.test.ts +0 -117
  163. package/src/tests/providers/anthropic.test.ts +0 -118
  164. package/src/tests/providers/google.test.ts +0 -841
  165. package/src/tests/providers/ollama.test.ts +0 -1034
  166. package/src/tests/providers/openai.test.ts +0 -1511
  167. package/src/tests/router.test.ts +0 -254
  168. package/src/tests/stream-decoder.test.ts +0 -263
  169. package/src/tests/structured-output.test.ts +0 -1450
  170. package/src/tests/thinking.test.ts +0 -65
  171. package/src/tests/tools.test.ts +0 -175
  172. package/src/thinking.ts +0 -73
  173. package/src/tools.ts +0 -246
  174. package/src/zod-adapter.ts +0 -72
package/src/mcp.ts DELETED
@@ -1,345 +0,0 @@
1
- /**
2
- * Universal LLM Client v3 — MCP Integration
3
- *
4
- * Native MCP tool discovery and execution bridge.
5
- * Uses @modelcontextprotocol/sdk as a peer dependency.
6
- *
7
- * Supports:
8
- * - Stdio transport (Node/Bun/Deno — spawns server processes)
9
- * - Streamable HTTP transport (all runtimes including browsers)
10
- *
11
- * Usage:
12
- * const mcp = new MCPToolBridge({
13
- * servers: {
14
- * filesystem: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', './'] },
15
- * weather: { url: 'https://mcp.example.com/weather' },
16
- * }
17
- * });
18
- * await mcp.connect();
19
- * await mcp.registerTools(model); // or registerTools(model)
20
- * // ... use model.chatWithTools() — MCP tools are now callable
21
- * await mcp.disconnect();
22
- */
23
-
24
- import type { AIModel } from './ai-model.js';
25
- import type { LLMFunction, ToolHandler } from './interfaces.js';
26
- import type { Auditor } from './auditor.js';
27
- import { NoopAuditor } from './auditor.js';
28
-
29
- // ============================================================================
30
- // MCP Types
31
- // ============================================================================
32
-
33
- export interface MCPServerConfig {
34
- /** Stdio transport: command to spawn the MCP server */
35
- command?: string;
36
- /** Stdio transport: arguments for the command */
37
- args?: string[];
38
- /** Stdio transport: environment variables for the spawned process */
39
- env?: Record<string, string>;
40
- /** HTTP transport: URL of the remote MCP server */
41
- url?: string;
42
- /** HTTP transport: additional headers for requests */
43
- headers?: Record<string, string>;
44
- }
45
-
46
- export interface MCPBridgeConfig {
47
- /** Named MCP server configurations */
48
- servers: Record<string, MCPServerConfig>;
49
- /** Auditor for observability */
50
- auditor?: Auditor;
51
- }
52
-
53
- export interface MCPTool {
54
- /** Server this tool came from */
55
- serverName: string;
56
- /** Tool name (as reported by the server) */
57
- name: string;
58
- /** Full qualified name (serverName:toolName) */
59
- qualifiedName: string;
60
- /** Tool description */
61
- description: string;
62
- /** JSON Schema for tool input */
63
- inputSchema: Record<string, unknown>;
64
- }
65
-
66
- // ============================================================================
67
- // Internal: SDK types (to avoid hard dependency)
68
- // ============================================================================
69
-
70
- interface MCPClientLike {
71
- connect(transport: unknown): Promise<void>;
72
- close(): Promise<void>;
73
- listTools(): Promise<{ tools: Array<{ name: string; description?: string; inputSchema: Record<string, unknown> }> }>;
74
- callTool(params: { name: string; arguments?: Record<string, unknown> }): Promise<{ content: Array<{ type: string; text?: string }> }>;
75
- }
76
-
77
- // ============================================================================
78
- // MCPToolBridge
79
- // ============================================================================
80
-
81
- export class MCPToolBridge {
82
- private config: MCPBridgeConfig;
83
- private auditor: Auditor;
84
- private clients: Map<string, MCPClientLike> = new Map();
85
- private transports: Map<string, unknown> = new Map();
86
- private discoveredTools: MCPTool[] = [];
87
- private connected = false;
88
-
89
- constructor(config: MCPBridgeConfig) {
90
- this.config = config;
91
- this.auditor = config.auditor ?? new NoopAuditor();
92
- }
93
-
94
- // ========================================================================
95
- // Connection Lifecycle
96
- // ========================================================================
97
-
98
- /**
99
- * Connect to all configured MCP servers and discover their tools.
100
- * Requires @modelcontextprotocol/sdk to be installed.
101
- */
102
- async connect(): Promise<void> {
103
- if (this.connected) return;
104
-
105
- // Dynamic import of MCP SDK (peer dependency)
106
- let sdk: {
107
- Client: new (info: { name: string; version: string }, opts?: { capabilities?: Record<string, unknown> }) => MCPClientLike;
108
- StdioClientTransport?: new (opts: { command: string; args?: string[]; env?: Record<string, string> }) => unknown;
109
- StreamableHTTPClientTransport?: new (url: URL, opts?: { requestInit?: { headers: Record<string, string> } }) => unknown;
110
- };
111
-
112
- try {
113
- // @ts-ignore — peer dependency, may not be installed
114
- sdk = await import('@modelcontextprotocol/sdk/client/index.js');
115
- } catch {
116
- throw new Error(
117
- 'MCP integration requires @modelcontextprotocol/sdk.\n' +
118
- 'Install it: bun add @modelcontextprotocol/sdk'
119
- );
120
- }
121
-
122
- const entries = Object.entries(this.config.servers);
123
-
124
- for (const [serverName, serverConfig] of entries) {
125
- try {
126
- const client = new sdk.Client(
127
- { name: 'universal-llm-client', version: '3.0.0' },
128
- { capabilities: {} },
129
- );
130
-
131
- let transport: unknown;
132
-
133
- if (serverConfig.url) {
134
- // HTTP transport (all runtimes)
135
- if (!sdk.StreamableHTTPClientTransport) {
136
- // Try separate import path
137
- // @ts-ignore — peer dependency, may not be installed
138
- const httpModule = await import('@modelcontextprotocol/sdk/client/streamableHttp.js').catch(() => null);
139
- if (!httpModule?.StreamableHTTPClientTransport) {
140
- throw new Error('StreamableHTTPClientTransport not available in this SDK version');
141
- }
142
- transport = new httpModule.StreamableHTTPClientTransport(
143
- new URL(serverConfig.url),
144
- serverConfig.headers ? { requestInit: { headers: serverConfig.headers } } : undefined,
145
- );
146
- } else {
147
- transport = new sdk.StreamableHTTPClientTransport(
148
- new URL(serverConfig.url),
149
- serverConfig.headers ? { requestInit: { headers: serverConfig.headers } } : undefined,
150
- );
151
- }
152
- } else if (serverConfig.command) {
153
- // Stdio transport (Node/Bun/Deno only)
154
- if (!sdk.StdioClientTransport) {
155
- // @ts-ignore — peer dependency, may not be installed
156
- const stdioModule = await import('@modelcontextprotocol/sdk/client/stdio.js').catch(() => null);
157
- if (!stdioModule?.StdioClientTransport) {
158
- throw new Error(
159
- 'Stdio transport not available. This is expected in browser environments.\n' +
160
- 'Use HTTP transport (url) instead, or run in Node/Bun/Deno.'
161
- );
162
- }
163
- transport = new stdioModule.StdioClientTransport({
164
- command: serverConfig.command,
165
- args: serverConfig.args,
166
- env: serverConfig.env,
167
- });
168
- } else {
169
- transport = new sdk.StdioClientTransport({
170
- command: serverConfig.command,
171
- args: serverConfig.args,
172
- env: serverConfig.env,
173
- });
174
- }
175
- } else {
176
- throw new Error(`MCP server "${serverName}" must have either "url" or "command" configured`);
177
- }
178
-
179
- await client.connect(transport);
180
- this.clients.set(serverName, client);
181
- this.transports.set(serverName, transport);
182
-
183
- // Discover tools
184
- const toolList = await client.listTools();
185
- for (const tool of toolList.tools) {
186
- this.discoveredTools.push({
187
- serverName,
188
- name: tool.name,
189
- qualifiedName: `${serverName}:${tool.name}`,
190
- description: tool.description ?? '',
191
- inputSchema: tool.inputSchema,
192
- });
193
- }
194
-
195
- this.auditor.record({
196
- timestamp: Date.now(),
197
- type: 'response',
198
- metadata: {
199
- event: 'mcp_connected',
200
- server: serverName,
201
- toolCount: toolList.tools.length,
202
- },
203
- });
204
- } catch (error) {
205
- this.auditor.record({
206
- timestamp: Date.now(),
207
- type: 'error',
208
- error: error instanceof Error ? error.message : String(error),
209
- metadata: { event: 'mcp_connect_failed', server: serverName },
210
- });
211
- throw error;
212
- }
213
- }
214
-
215
- this.connected = true;
216
- }
217
-
218
- // ========================================================================
219
- // Tool Registration
220
- // ========================================================================
221
-
222
- /**
223
- * Register all discovered MCP tools with an AIModel instance.
224
- * Each MCP tool becomes a callable tool that forwards execution
225
- * to the appropriate MCP server.
226
- */
227
- async registerTools(model: AIModel): Promise<void> {
228
- if (!this.connected) {
229
- await this.connect();
230
- }
231
-
232
- const tools = this.discoveredTools.map(mcpTool => ({
233
- name: mcpTool.qualifiedName,
234
- description: mcpTool.description,
235
- parameters: this.convertInputSchema(mcpTool.inputSchema),
236
- handler: this.createToolHandler(mcpTool),
237
- }));
238
-
239
- model.registerTools(tools);
240
- }
241
-
242
- /**
243
- * Get all discovered MCP tools (for inspection).
244
- */
245
- getTools(): ReadonlyArray<MCPTool> {
246
- return this.discoveredTools;
247
- }
248
-
249
- // ========================================================================
250
- // Disconnect
251
- // ========================================================================
252
-
253
- /**
254
- * Disconnect from all MCP servers and clean up.
255
- */
256
- async disconnect(): Promise<void> {
257
- for (const [serverName, client] of this.clients) {
258
- try {
259
- await client.close();
260
- } catch (error) {
261
- this.auditor.record({
262
- timestamp: Date.now(),
263
- type: 'error',
264
- error: error instanceof Error ? error.message : String(error),
265
- metadata: { event: 'mcp_disconnect_failed', server: serverName },
266
- });
267
- }
268
- }
269
- this.clients.clear();
270
- this.transports.clear();
271
- this.discoveredTools = [];
272
- this.connected = false;
273
- }
274
-
275
- // ========================================================================
276
- // Internal
277
- // ========================================================================
278
-
279
- private createToolHandler(mcpTool: MCPTool): ToolHandler {
280
- return async (args: unknown) => {
281
- const client = this.clients.get(mcpTool.serverName);
282
- if (!client) {
283
- throw new Error(`MCP server "${mcpTool.serverName}" is not connected`);
284
- }
285
-
286
- const start = Date.now();
287
- this.auditor.record({
288
- timestamp: start,
289
- type: 'tool_call',
290
- metadata: {
291
- event: 'mcp_tool_call',
292
- server: mcpTool.serverName,
293
- tool: mcpTool.name,
294
- },
295
- });
296
-
297
- try {
298
- const result = await client.callTool({
299
- name: mcpTool.name,
300
- arguments: args as Record<string, unknown> | undefined,
301
- });
302
-
303
- // Extract text content from MCP response
304
- const textParts = result.content
305
- .filter(c => c.type === 'text' && c.text)
306
- .map(c => c.text);
307
-
308
- const output = textParts.length === 1 ? textParts[0] : textParts.join('\n');
309
-
310
- this.auditor.record({
311
- timestamp: Date.now(),
312
- type: 'tool_result',
313
- metadata: {
314
- event: 'mcp_tool_result',
315
- server: mcpTool.serverName,
316
- tool: mcpTool.name,
317
- duration: Date.now() - start,
318
- },
319
- });
320
-
321
- return output;
322
- } catch (error) {
323
- this.auditor.record({
324
- timestamp: Date.now(),
325
- type: 'error',
326
- error: error instanceof Error ? error.message : String(error),
327
- metadata: {
328
- event: 'mcp_tool_error',
329
- server: mcpTool.serverName,
330
- tool: mcpTool.name,
331
- },
332
- });
333
- throw error;
334
- }
335
- };
336
- }
337
-
338
- private convertInputSchema(schema: Record<string, unknown>): LLMFunction['parameters'] {
339
- return {
340
- type: 'object',
341
- properties: (schema['properties'] as Record<string, unknown>) ?? {},
342
- required: schema['required'] as string[] | undefined,
343
- };
344
- }
345
- }