@mcpmesh/sdk 0.8.0-beta.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 (145) hide show
  1. package/dist/__tests__/claude-handler.test.d.ts +7 -0
  2. package/dist/__tests__/claude-handler.test.d.ts.map +1 -0
  3. package/dist/__tests__/claude-handler.test.js +455 -0
  4. package/dist/__tests__/claude-handler.test.js.map +1 -0
  5. package/dist/__tests__/config.test.d.ts +7 -0
  6. package/dist/__tests__/config.test.d.ts.map +1 -0
  7. package/dist/__tests__/config.test.js +156 -0
  8. package/dist/__tests__/config.test.js.map +1 -0
  9. package/dist/__tests__/errors.test.d.ts +7 -0
  10. package/dist/__tests__/errors.test.d.ts.map +1 -0
  11. package/dist/__tests__/errors.test.js +170 -0
  12. package/dist/__tests__/errors.test.js.map +1 -0
  13. package/dist/__tests__/generic-handler.test.d.ts +7 -0
  14. package/dist/__tests__/generic-handler.test.d.ts.map +1 -0
  15. package/dist/__tests__/generic-handler.test.js +243 -0
  16. package/dist/__tests__/generic-handler.test.js.map +1 -0
  17. package/dist/__tests__/llm-provider.test.d.ts +7 -0
  18. package/dist/__tests__/llm-provider.test.d.ts.map +1 -0
  19. package/dist/__tests__/llm-provider.test.js +217 -0
  20. package/dist/__tests__/llm-provider.test.js.map +1 -0
  21. package/dist/__tests__/openai-handler.test.d.ts +7 -0
  22. package/dist/__tests__/openai-handler.test.d.ts.map +1 -0
  23. package/dist/__tests__/openai-handler.test.js +359 -0
  24. package/dist/__tests__/openai-handler.test.js.map +1 -0
  25. package/dist/__tests__/provider-handler-registry.test.d.ts +9 -0
  26. package/dist/__tests__/provider-handler-registry.test.d.ts.map +1 -0
  27. package/dist/__tests__/provider-handler-registry.test.js +187 -0
  28. package/dist/__tests__/provider-handler-registry.test.js.map +1 -0
  29. package/dist/__tests__/response-parser.test.d.ts +7 -0
  30. package/dist/__tests__/response-parser.test.d.ts.map +1 -0
  31. package/dist/__tests__/response-parser.test.js +360 -0
  32. package/dist/__tests__/response-parser.test.js.map +1 -0
  33. package/dist/__tests__/route.test.d.ts +7 -0
  34. package/dist/__tests__/route.test.d.ts.map +1 -0
  35. package/dist/__tests__/route.test.js +281 -0
  36. package/dist/__tests__/route.test.js.map +1 -0
  37. package/dist/__tests__/sse.test.d.ts +7 -0
  38. package/dist/__tests__/sse.test.d.ts.map +1 -0
  39. package/dist/__tests__/sse.test.js +172 -0
  40. package/dist/__tests__/sse.test.js.map +1 -0
  41. package/dist/__tests__/template.test.d.ts +7 -0
  42. package/dist/__tests__/template.test.d.ts.map +1 -0
  43. package/dist/__tests__/template.test.js +176 -0
  44. package/dist/__tests__/template.test.js.map +1 -0
  45. package/dist/__tests__/tracing.test.d.ts +7 -0
  46. package/dist/__tests__/tracing.test.d.ts.map +1 -0
  47. package/dist/__tests__/tracing.test.js +264 -0
  48. package/dist/__tests__/tracing.test.js.map +1 -0
  49. package/dist/agent.d.ts +165 -0
  50. package/dist/agent.d.ts.map +1 -0
  51. package/dist/agent.js +626 -0
  52. package/dist/agent.js.map +1 -0
  53. package/dist/api-runtime.d.ts +166 -0
  54. package/dist/api-runtime.d.ts.map +1 -0
  55. package/dist/api-runtime.js +459 -0
  56. package/dist/api-runtime.js.map +1 -0
  57. package/dist/config.d.ts +31 -0
  58. package/dist/config.d.ts.map +1 -0
  59. package/dist/config.js +60 -0
  60. package/dist/config.js.map +1 -0
  61. package/dist/debug.d.ts +47 -0
  62. package/dist/debug.d.ts.map +1 -0
  63. package/dist/debug.js +86 -0
  64. package/dist/debug.js.map +1 -0
  65. package/dist/errors.d.ts +99 -0
  66. package/dist/errors.d.ts.map +1 -0
  67. package/dist/errors.js +110 -0
  68. package/dist/errors.js.map +1 -0
  69. package/dist/express.d.ts +146 -0
  70. package/dist/express.d.ts.map +1 -0
  71. package/dist/express.js +371 -0
  72. package/dist/express.js.map +1 -0
  73. package/dist/index.d.ts +96 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +107 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/llm-agent.d.ts +193 -0
  78. package/dist/llm-agent.d.ts.map +1 -0
  79. package/dist/llm-agent.js +634 -0
  80. package/dist/llm-agent.js.map +1 -0
  81. package/dist/llm-provider.d.ts +323 -0
  82. package/dist/llm-provider.d.ts.map +1 -0
  83. package/dist/llm-provider.js +446 -0
  84. package/dist/llm-provider.js.map +1 -0
  85. package/dist/llm.d.ts +194 -0
  86. package/dist/llm.d.ts.map +1 -0
  87. package/dist/llm.js +304 -0
  88. package/dist/llm.js.map +1 -0
  89. package/dist/provider-handlers/claude-handler.d.ts +98 -0
  90. package/dist/provider-handlers/claude-handler.d.ts.map +1 -0
  91. package/dist/provider-handlers/claude-handler.js +268 -0
  92. package/dist/provider-handlers/claude-handler.js.map +1 -0
  93. package/dist/provider-handlers/gemini-handler.d.ts +82 -0
  94. package/dist/provider-handlers/gemini-handler.d.ts.map +1 -0
  95. package/dist/provider-handlers/gemini-handler.js +152 -0
  96. package/dist/provider-handlers/gemini-handler.js.map +1 -0
  97. package/dist/provider-handlers/generic-handler.d.ts +78 -0
  98. package/dist/provider-handlers/generic-handler.d.ts.map +1 -0
  99. package/dist/provider-handlers/generic-handler.js +152 -0
  100. package/dist/provider-handlers/generic-handler.js.map +1 -0
  101. package/dist/provider-handlers/index.d.ts +29 -0
  102. package/dist/provider-handlers/index.d.ts.map +1 -0
  103. package/dist/provider-handlers/index.js +32 -0
  104. package/dist/provider-handlers/index.js.map +1 -0
  105. package/dist/provider-handlers/openai-handler.d.ts +86 -0
  106. package/dist/provider-handlers/openai-handler.d.ts.map +1 -0
  107. package/dist/provider-handlers/openai-handler.js +160 -0
  108. package/dist/provider-handlers/openai-handler.js.map +1 -0
  109. package/dist/provider-handlers/provider-handler-registry.d.ts +124 -0
  110. package/dist/provider-handlers/provider-handler-registry.d.ts.map +1 -0
  111. package/dist/provider-handlers/provider-handler-registry.js +180 -0
  112. package/dist/provider-handlers/provider-handler-registry.js.map +1 -0
  113. package/dist/provider-handlers/provider-handler.d.ts +245 -0
  114. package/dist/provider-handlers/provider-handler.d.ts.map +1 -0
  115. package/dist/provider-handlers/provider-handler.js +238 -0
  116. package/dist/provider-handlers/provider-handler.js.map +1 -0
  117. package/dist/proxy.d.ts +44 -0
  118. package/dist/proxy.d.ts.map +1 -0
  119. package/dist/proxy.js +324 -0
  120. package/dist/proxy.js.map +1 -0
  121. package/dist/response-parser.d.ts +103 -0
  122. package/dist/response-parser.d.ts.map +1 -0
  123. package/dist/response-parser.js +232 -0
  124. package/dist/response-parser.js.map +1 -0
  125. package/dist/route.d.ts +185 -0
  126. package/dist/route.d.ts.map +1 -0
  127. package/dist/route.js +310 -0
  128. package/dist/route.js.map +1 -0
  129. package/dist/sse.d.ts +45 -0
  130. package/dist/sse.d.ts.map +1 -0
  131. package/dist/sse.js +77 -0
  132. package/dist/sse.js.map +1 -0
  133. package/dist/template.d.ts +86 -0
  134. package/dist/template.d.ts.map +1 -0
  135. package/dist/template.js +206 -0
  136. package/dist/template.js.map +1 -0
  137. package/dist/tracing.d.ts +88 -0
  138. package/dist/tracing.d.ts.map +1 -0
  139. package/dist/tracing.js +193 -0
  140. package/dist/tracing.js.map +1 -0
  141. package/dist/types.d.ts +618 -0
  142. package/dist/types.d.ts.map +1 -0
  143. package/dist/types.js +5 -0
  144. package/dist/types.js.map +1 -0
  145. package/package.json +68 -0
@@ -0,0 +1,160 @@
1
+ /**
2
+ * OpenAI provider handler.
3
+ *
4
+ * Optimized for OpenAI models (GPT-4, GPT-4 Turbo, GPT-3.5-turbo)
5
+ * using OpenAI's native structured output capabilities.
6
+ *
7
+ * Based on Python's OpenAIHandler:
8
+ * src/runtime/python/_mcp_mesh/engine/provider_handlers/openai_handler.py
9
+ */
10
+ import { createDebug } from "../debug.js";
11
+ import { convertMessagesToVercelFormat, makeSchemaStrict, defaultDetermineOutputMode, BASE_TOOL_INSTRUCTIONS, } from "./provider-handler.js";
12
+ import { ProviderHandlerRegistry } from "./provider-handler-registry.js";
13
+ const debug = createDebug("openai-handler");
14
+ /**
15
+ * Provider handler for OpenAI models.
16
+ *
17
+ * OpenAI Characteristics:
18
+ * - Native structured output via response_format parameter
19
+ * - Strict JSON schema enforcement
20
+ * - Built-in function calling
21
+ * - Works best with concise, focused prompts
22
+ * - response_format ensures valid JSON matching schema
23
+ *
24
+ * Key Difference from Claude:
25
+ * - Uses response_format instead of prompt-based JSON instructions
26
+ * - OpenAI API guarantees JSON schema compliance
27
+ * - More strict parsing, less tolerance for malformed JSON
28
+ * - Shorter system prompts work better
29
+ *
30
+ * Supported Models:
31
+ * - gpt-4-turbo-preview and later
32
+ * - gpt-4-0125-preview and later
33
+ * - gpt-3.5-turbo-0125 and later
34
+ * - All gpt-4o models
35
+ *
36
+ * Reference: https://platform.openai.com/docs/guides/structured-outputs
37
+ */
38
+ export class OpenAIHandler {
39
+ vendor = "openai";
40
+ /**
41
+ * Prepare request parameters for OpenAI API with structured output.
42
+ *
43
+ * OpenAI Strategy:
44
+ * - Use response_format parameter for guaranteed JSON schema compliance
45
+ * - This is the KEY difference from Claude handler
46
+ * - response_format.json_schema ensures the response matches output schema
47
+ * - Skip structured output for text mode (string return types)
48
+ *
49
+ * Message Format (OpenAI-specific):
50
+ * - Assistant messages with tool_calls → content blocks with type "tool-call"
51
+ * - Tool result messages → content blocks with type "tool-result"
52
+ * This is required for Vercel AI SDK to properly convert to OpenAI's native format.
53
+ */
54
+ prepareRequest(messages, tools, outputSchema, options) {
55
+ const { outputMode, temperature, maxOutputTokens: maxTokens, topP, ...rest } = options ?? {};
56
+ const determinedMode = this.determineOutputMode(outputSchema, outputMode);
57
+ // Convert messages to Vercel AI SDK format (shared utility)
58
+ const convertedMessages = convertMessagesToVercelFormat(messages);
59
+ const request = {
60
+ messages: convertedMessages,
61
+ ...rest,
62
+ };
63
+ // Add tools if provided
64
+ if (tools && tools.length > 0) {
65
+ request.tools = tools;
66
+ }
67
+ // Add standard parameters if provided
68
+ if (temperature !== undefined) {
69
+ request.temperature = temperature;
70
+ }
71
+ if (maxTokens !== undefined) {
72
+ request.maxOutputTokens = maxTokens;
73
+ }
74
+ if (topP !== undefined) {
75
+ request.topP = topP;
76
+ }
77
+ // Skip structured output for text mode or no schema
78
+ if (determinedMode === "text" || !outputSchema) {
79
+ return request;
80
+ }
81
+ // Only add response_format in "strict" mode
82
+ // Hint mode relies on prompt instructions instead
83
+ if (determinedMode === "strict") {
84
+ // Transform schema for OpenAI strict mode
85
+ // OpenAI requires additionalProperties: false and all properties in required
86
+ const strictSchema = makeSchemaStrict(outputSchema.schema, { addAllRequired: true });
87
+ // OpenAI structured output format
88
+ // See: https://platform.openai.com/docs/guides/structured-outputs
89
+ request.responseFormat = {
90
+ type: "json_schema",
91
+ jsonSchema: {
92
+ name: outputSchema.name,
93
+ schema: strictSchema,
94
+ strict: true, // Enforce schema compliance
95
+ },
96
+ };
97
+ debug(`Using response_format with strict schema: ${outputSchema.name}`);
98
+ }
99
+ return request;
100
+ }
101
+ /**
102
+ * Format system prompt for OpenAI (concise approach).
103
+ *
104
+ * OpenAI Strategy:
105
+ * 1. Use base prompt as-is
106
+ * 2. Add tool calling instructions if tools present
107
+ * 3. NO JSON schema instructions (response_format handles this)
108
+ * 4. Keep prompt concise - OpenAI works well with shorter prompts
109
+ * 5. Skip JSON note for text mode (string return type)
110
+ *
111
+ * Key Difference from Claude:
112
+ * - No JSON schema in prompt (response_format ensures compliance)
113
+ * - Shorter, more focused instructions
114
+ * - Let response_format handle output structure
115
+ */
116
+ formatSystemPrompt(basePrompt, toolSchemas, outputSchema, outputMode) {
117
+ let systemContent = basePrompt;
118
+ const determinedMode = this.determineOutputMode(outputSchema, outputMode);
119
+ // Add tool calling instructions if tools available
120
+ if (toolSchemas && toolSchemas.length > 0) {
121
+ systemContent += BASE_TOOL_INSTRUCTIONS;
122
+ }
123
+ // Skip JSON note for text mode
124
+ if (determinedMode === "text" || !outputSchema) {
125
+ return systemContent;
126
+ }
127
+ // NOTE: We do NOT add JSON schema instructions here!
128
+ // OpenAI's response_format parameter handles JSON structure automatically.
129
+ // Adding explicit JSON instructions can actually confuse the model.
130
+ // Optional: Add a brief note that response should be JSON
131
+ // (though response_format enforces this anyway)
132
+ systemContent += `
133
+
134
+ Your final response will be structured as JSON matching the ${outputSchema.name} format.`;
135
+ return systemContent;
136
+ }
137
+ /**
138
+ * Return OpenAI-specific capabilities.
139
+ */
140
+ getCapabilities() {
141
+ return {
142
+ nativeToolCalling: true, // OpenAI has native function calling
143
+ structuredOutput: true, // Native response_format support!
144
+ streaming: true, // Supports streaming
145
+ vision: true, // GPT-4V and later support vision
146
+ jsonMode: true, // Has dedicated JSON mode via response_format
147
+ };
148
+ }
149
+ /**
150
+ * Determine output mode - OpenAI always uses strict mode for schemas.
151
+ *
152
+ * Uses the default implementation since OpenAI has excellent structured output support.
153
+ */
154
+ determineOutputMode(outputSchema, overrideMode) {
155
+ return defaultDetermineOutputMode(outputSchema, overrideMode);
156
+ }
157
+ }
158
+ // Register with the registry
159
+ ProviderHandlerRegistry.register("openai", OpenAIHandler);
160
+ //# sourceMappingURL=openai-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-handler.js","sourceRoot":"","sources":["../../src/provider-handlers/openai-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Provider handler registry for vendor-specific LLM behavior.
3
+ *
4
+ * Manages selection and instantiation of provider handlers based on vendor name.
5
+ *
6
+ * Based on Python's ProviderHandlerRegistry:
7
+ * src/runtime/python/_mcp_mesh/engine/provider_handlers/provider_handler_registry.py
8
+ */
9
+ import type { ProviderHandler } from "./provider-handler.js";
10
+ /**
11
+ * Constructor type for provider handlers.
12
+ */
13
+ export type ProviderHandlerConstructor = new () => ProviderHandler;
14
+ /**
15
+ * Registry for provider-specific handlers.
16
+ *
17
+ * Manages mapping from vendor names to handler classes and provides
18
+ * handler selection logic. Handlers customize LLM API calls for
19
+ * optimal performance with each vendor.
20
+ *
21
+ * Vendor Mapping:
22
+ * - "anthropic" -> ClaudeHandler
23
+ * - "openai" -> OpenAIHandler
24
+ * - "unknown" or others -> GenericHandler
25
+ *
26
+ * Usage:
27
+ * ```typescript
28
+ * const handler = ProviderHandlerRegistry.getHandler("anthropic");
29
+ * const request = handler.prepareRequest(messages, tools, outputSchema);
30
+ * const systemPrompt = handler.formatSystemPrompt(base, tools, outputSchema);
31
+ * ```
32
+ *
33
+ * Extensibility:
34
+ * ```typescript
35
+ * ProviderHandlerRegistry.register("cohere", CohereHandler);
36
+ * ```
37
+ */
38
+ export declare class ProviderHandlerRegistry {
39
+ /** Built-in vendor mappings */
40
+ private static handlers;
41
+ /** Cache of instantiated handlers (singleton per vendor) */
42
+ private static instances;
43
+ /** Fallback handler class (set by generic-handler.ts) */
44
+ private static fallbackHandlerClass;
45
+ /**
46
+ * Register a custom provider handler.
47
+ *
48
+ * Allows runtime registration of new handlers without modifying registry code.
49
+ *
50
+ * @param vendor - Vendor name (e.g., "cohere", "gemini", "together")
51
+ * @param handlerClass - Handler class (must implement ProviderHandler)
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * class CohereHandler implements ProviderHandler {
56
+ * // ...
57
+ * }
58
+ *
59
+ * ProviderHandlerRegistry.register("cohere", CohereHandler);
60
+ * ```
61
+ */
62
+ static register(vendor: string, handlerClass: ProviderHandlerConstructor): void;
63
+ /**
64
+ * Set the fallback handler class.
65
+ *
66
+ * Called by generic-handler.ts during module initialization.
67
+ *
68
+ * @param handlerClass - Fallback handler class
69
+ */
70
+ static setFallbackHandler(handlerClass: ProviderHandlerConstructor): void;
71
+ /**
72
+ * Get provider handler for vendor.
73
+ *
74
+ * Selection Logic:
75
+ * 1. If vendor matches registered handler -> use that handler
76
+ * 2. If vendor is null or "unknown" -> use GenericHandler
77
+ * 3. If vendor unknown -> use GenericHandler with warning
78
+ *
79
+ * Handlers are cached (singleton per vendor) for performance.
80
+ *
81
+ * @param vendor - Vendor name from model string (e.g., "anthropic", "openai")
82
+ * @returns Provider handler instance for the vendor
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * // Get Claude handler
87
+ * const handler = ProviderHandlerRegistry.getHandler("anthropic");
88
+ *
89
+ * // Get OpenAI handler
90
+ * const handler = ProviderHandlerRegistry.getHandler("openai");
91
+ *
92
+ * // Get generic fallback
93
+ * const handler = ProviderHandlerRegistry.getHandler("unknown");
94
+ * ```
95
+ */
96
+ static getHandler(vendor: string | null): ProviderHandler;
97
+ /**
98
+ * List all registered vendors and their handlers.
99
+ *
100
+ * @returns Map of vendor name -> handler class name
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * const vendors = ProviderHandlerRegistry.listVendors();
105
+ * // Map { 'anthropic' => 'ClaudeHandler', 'openai' => 'OpenAIHandler' }
106
+ * ```
107
+ */
108
+ static listVendors(): Map<string, string>;
109
+ /**
110
+ * Clear cached handler instances.
111
+ *
112
+ * Useful for testing or when handler behavior needs to be reset.
113
+ * Next getHandler() call will create fresh instances.
114
+ */
115
+ static clearCache(): void;
116
+ /**
117
+ * Check if a handler is registered for a vendor.
118
+ *
119
+ * @param vendor - Vendor name
120
+ * @returns True if a specific handler is registered
121
+ */
122
+ static hasHandler(vendor: string): boolean;
123
+ }
124
+ //# sourceMappingURL=provider-handler-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-handler-registry.d.ts","sourceRoot":"","sources":["../../src/provider-handlers/provider-handler-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQ7D;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG,UAAU,eAAe,CAAC;AAMnE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,uBAAuB;IAClC,+BAA+B;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsD;IAE7E,4DAA4D;IAC5D,OAAO,CAAC,MAAM,CAAC,SAAS,CAA2C;IAEnE,yDAAyD;IACzD,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAA2C;IAE9E;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,0BAA0B,GAAG,IAAI;IAW/E;;;;;;OAMG;IACH,MAAM,CAAC,kBAAkB,CAAC,YAAY,EAAE,0BAA0B,GAAG,IAAI;IAKzE;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,eAAe;IA2CzD;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAQzC;;;;;OAKG;IACH,MAAM,CAAC,UAAU,IAAI,IAAI;IAKzB;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;CAG3C"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Provider handler registry for vendor-specific LLM behavior.
3
+ *
4
+ * Manages selection and instantiation of provider handlers based on vendor name.
5
+ *
6
+ * Based on Python's ProviderHandlerRegistry:
7
+ * src/runtime/python/_mcp_mesh/engine/provider_handlers/provider_handler_registry.py
8
+ */
9
+ import { createDebug } from "../debug.js";
10
+ const debug = createDebug("provider-handler-registry");
11
+ // ============================================================================
12
+ // Registry Singleton
13
+ // ============================================================================
14
+ /**
15
+ * Registry for provider-specific handlers.
16
+ *
17
+ * Manages mapping from vendor names to handler classes and provides
18
+ * handler selection logic. Handlers customize LLM API calls for
19
+ * optimal performance with each vendor.
20
+ *
21
+ * Vendor Mapping:
22
+ * - "anthropic" -> ClaudeHandler
23
+ * - "openai" -> OpenAIHandler
24
+ * - "unknown" or others -> GenericHandler
25
+ *
26
+ * Usage:
27
+ * ```typescript
28
+ * const handler = ProviderHandlerRegistry.getHandler("anthropic");
29
+ * const request = handler.prepareRequest(messages, tools, outputSchema);
30
+ * const systemPrompt = handler.formatSystemPrompt(base, tools, outputSchema);
31
+ * ```
32
+ *
33
+ * Extensibility:
34
+ * ```typescript
35
+ * ProviderHandlerRegistry.register("cohere", CohereHandler);
36
+ * ```
37
+ */
38
+ export class ProviderHandlerRegistry {
39
+ /** Built-in vendor mappings */
40
+ static handlers = new Map();
41
+ /** Cache of instantiated handlers (singleton per vendor) */
42
+ static instances = new Map();
43
+ /** Fallback handler class (set by generic-handler.ts) */
44
+ static fallbackHandlerClass = null;
45
+ /**
46
+ * Register a custom provider handler.
47
+ *
48
+ * Allows runtime registration of new handlers without modifying registry code.
49
+ *
50
+ * @param vendor - Vendor name (e.g., "cohere", "gemini", "together")
51
+ * @param handlerClass - Handler class (must implement ProviderHandler)
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * class CohereHandler implements ProviderHandler {
56
+ * // ...
57
+ * }
58
+ *
59
+ * ProviderHandlerRegistry.register("cohere", CohereHandler);
60
+ * ```
61
+ */
62
+ static register(vendor, handlerClass) {
63
+ const normalizedVendor = vendor.toLowerCase().trim();
64
+ this.handlers.set(normalizedVendor, handlerClass);
65
+ debug(`Registered provider handler: ${normalizedVendor} -> ${handlerClass.name}`);
66
+ // Clear cached instance if it exists (force re-instantiation)
67
+ if (this.instances.has(normalizedVendor)) {
68
+ this.instances.delete(normalizedVendor);
69
+ }
70
+ }
71
+ /**
72
+ * Set the fallback handler class.
73
+ *
74
+ * Called by generic-handler.ts during module initialization.
75
+ *
76
+ * @param handlerClass - Fallback handler class
77
+ */
78
+ static setFallbackHandler(handlerClass) {
79
+ this.fallbackHandlerClass = handlerClass;
80
+ debug(`Set fallback handler: ${handlerClass.name}`);
81
+ }
82
+ /**
83
+ * Get provider handler for vendor.
84
+ *
85
+ * Selection Logic:
86
+ * 1. If vendor matches registered handler -> use that handler
87
+ * 2. If vendor is null or "unknown" -> use GenericHandler
88
+ * 3. If vendor unknown -> use GenericHandler with warning
89
+ *
90
+ * Handlers are cached (singleton per vendor) for performance.
91
+ *
92
+ * @param vendor - Vendor name from model string (e.g., "anthropic", "openai")
93
+ * @returns Provider handler instance for the vendor
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // Get Claude handler
98
+ * const handler = ProviderHandlerRegistry.getHandler("anthropic");
99
+ *
100
+ * // Get OpenAI handler
101
+ * const handler = ProviderHandlerRegistry.getHandler("openai");
102
+ *
103
+ * // Get generic fallback
104
+ * const handler = ProviderHandlerRegistry.getHandler("unknown");
105
+ * ```
106
+ */
107
+ static getHandler(vendor) {
108
+ // Normalize vendor name (handle null, empty string)
109
+ const normalizedVendor = (vendor ?? "unknown").toLowerCase().trim();
110
+ // Check cache first
111
+ const cached = this.instances.get(normalizedVendor);
112
+ if (cached) {
113
+ debug(`Using cached handler for vendor: ${normalizedVendor}`);
114
+ return cached;
115
+ }
116
+ // Get handler class (or fallback to Generic)
117
+ let handlerClass = this.handlers.get(normalizedVendor);
118
+ let handler;
119
+ if (handlerClass) {
120
+ debug(`Selected ${handlerClass.name} for vendor: ${normalizedVendor}`);
121
+ handler = new handlerClass();
122
+ }
123
+ else {
124
+ // Use fallback handler
125
+ if (!this.fallbackHandlerClass) {
126
+ throw new Error(`No handler registered for vendor '${normalizedVendor}' and no fallback handler set. ` +
127
+ `Import provider-handlers/index.ts to initialize handlers.`);
128
+ }
129
+ if (normalizedVendor !== "unknown") {
130
+ debug(`No specific handler for vendor '${normalizedVendor}', using GenericHandler`);
131
+ }
132
+ else {
133
+ debug(`Using GenericHandler for unknown vendor`);
134
+ }
135
+ handler = new this.fallbackHandlerClass();
136
+ }
137
+ // Cache the instance
138
+ this.instances.set(normalizedVendor, handler);
139
+ debug(`Instantiated handler: ${handler.constructor.name} for vendor: ${normalizedVendor}`);
140
+ return handler;
141
+ }
142
+ /**
143
+ * List all registered vendors and their handlers.
144
+ *
145
+ * @returns Map of vendor name -> handler class name
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * const vendors = ProviderHandlerRegistry.listVendors();
150
+ * // Map { 'anthropic' => 'ClaudeHandler', 'openai' => 'OpenAIHandler' }
151
+ * ```
152
+ */
153
+ static listVendors() {
154
+ const result = new Map();
155
+ for (const [vendor, handlerClass] of this.handlers) {
156
+ result.set(vendor, handlerClass.name);
157
+ }
158
+ return result;
159
+ }
160
+ /**
161
+ * Clear cached handler instances.
162
+ *
163
+ * Useful for testing or when handler behavior needs to be reset.
164
+ * Next getHandler() call will create fresh instances.
165
+ */
166
+ static clearCache() {
167
+ this.instances.clear();
168
+ debug(`Cleared provider handler cache`);
169
+ }
170
+ /**
171
+ * Check if a handler is registered for a vendor.
172
+ *
173
+ * @param vendor - Vendor name
174
+ * @returns True if a specific handler is registered
175
+ */
176
+ static hasHandler(vendor) {
177
+ return this.handlers.has(vendor.toLowerCase().trim());
178
+ }
179
+ }
180
+ //# sourceMappingURL=provider-handler-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-handler-registry.js","sourceRoot":"","sources":["../../src/provider-handlers/provider-handler-registry.ts"],"names":[],"mappings":"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"}