@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,217 @@
1
+ /**
2
+ * Unit tests for llm-provider.ts
3
+ *
4
+ * Tests LLM provider tool generation and vendor extraction utilities.
5
+ */
6
+ import { describe, it, expect } from "vitest";
7
+ import { extractVendorFromModel, extractModelName, llmProvider, isLlmProviderTool, getLlmProviderMeta, } from "../llm-provider.js";
8
+ describe("extractVendorFromModel", () => {
9
+ it("should extract vendor from vendor/model format", () => {
10
+ expect(extractVendorFromModel("anthropic/claude-sonnet-4-5")).toBe("anthropic");
11
+ expect(extractVendorFromModel("openai/gpt-4o")).toBe("openai");
12
+ expect(extractVendorFromModel("google/gemini-2.0-flash")).toBe("google");
13
+ });
14
+ it("should return null for model without vendor prefix", () => {
15
+ expect(extractVendorFromModel("gpt-4")).toBeNull();
16
+ expect(extractVendorFromModel("claude-sonnet-4-5")).toBeNull();
17
+ });
18
+ it("should return null for empty string", () => {
19
+ expect(extractVendorFromModel("")).toBeNull();
20
+ });
21
+ it("should normalize vendor to lowercase", () => {
22
+ expect(extractVendorFromModel("ANTHROPIC/claude-sonnet-4-5")).toBe("anthropic");
23
+ expect(extractVendorFromModel("OpenAI/gpt-4o")).toBe("openai");
24
+ });
25
+ it("should trim whitespace from vendor", () => {
26
+ expect(extractVendorFromModel(" anthropic /claude-sonnet-4-5")).toBe("anthropic");
27
+ });
28
+ it("should handle multi-segment model names", () => {
29
+ expect(extractVendorFromModel("anthropic/claude-3-5-sonnet-20241022")).toBe("anthropic");
30
+ });
31
+ it("should return null for slash without vendor", () => {
32
+ expect(extractVendorFromModel("/gpt-4")).toBeNull();
33
+ });
34
+ });
35
+ describe("extractModelName", () => {
36
+ it("should extract model name without vendor prefix", () => {
37
+ expect(extractModelName("anthropic/claude-sonnet-4-5")).toBe("claude-sonnet-4-5");
38
+ expect(extractModelName("openai/gpt-4o")).toBe("gpt-4o");
39
+ });
40
+ it("should return model as-is if no vendor prefix", () => {
41
+ expect(extractModelName("gpt-4")).toBe("gpt-4");
42
+ expect(extractModelName("claude-sonnet-4-5")).toBe("claude-sonnet-4-5");
43
+ });
44
+ it("should handle multi-segment paths after vendor", () => {
45
+ expect(extractModelName("vendor/model/variant")).toBe("model/variant");
46
+ });
47
+ it("should handle empty input", () => {
48
+ expect(extractModelName("")).toBe("");
49
+ });
50
+ });
51
+ describe("llmProvider", () => {
52
+ describe("tool definition generation", () => {
53
+ it("should generate tool with correct structure", () => {
54
+ const tool = llmProvider({
55
+ model: "anthropic/claude-sonnet-4-5",
56
+ capability: "llm",
57
+ tags: ["llm", "claude"],
58
+ });
59
+ expect(tool.name).toBe("process_chat");
60
+ expect(typeof tool.description).toBe("string");
61
+ expect(tool.parameters).toBeDefined();
62
+ expect(typeof tool.execute).toBe("function");
63
+ });
64
+ it("should use custom tool name", () => {
65
+ const tool = llmProvider({
66
+ model: "openai/gpt-4o",
67
+ name: "custom_chat",
68
+ });
69
+ expect(tool.name).toBe("custom_chat");
70
+ });
71
+ it("should use custom description", () => {
72
+ const tool = llmProvider({
73
+ model: "openai/gpt-4o",
74
+ description: "Custom LLM endpoint",
75
+ });
76
+ expect(tool.description).toBe("Custom LLM endpoint");
77
+ });
78
+ it("should include model in default description", () => {
79
+ const tool = llmProvider({
80
+ model: "anthropic/claude-sonnet-4-5",
81
+ });
82
+ expect(tool.description).toContain("claude-sonnet-4-5");
83
+ });
84
+ it("should attach mesh metadata", () => {
85
+ const tool = llmProvider({
86
+ model: "anthropic/claude-sonnet-4-5",
87
+ capability: "llm",
88
+ tags: ["llm", "claude", "anthropic"],
89
+ version: "2.0.0",
90
+ });
91
+ expect(tool._meshMeta).toBeDefined();
92
+ expect(tool._meshMeta?.capability).toBe("llm");
93
+ expect(tool._meshMeta?.tags).toEqual(["llm", "claude", "anthropic"]);
94
+ expect(tool._meshMeta?.version).toBe("2.0.0");
95
+ expect(tool._meshMeta?.vendor).toBe("anthropic");
96
+ });
97
+ it("should use default values when not provided", () => {
98
+ const tool = llmProvider({
99
+ model: "openai/gpt-4o",
100
+ });
101
+ expect(tool._meshMeta?.capability).toBe("llm");
102
+ expect(tool._meshMeta?.tags).toEqual([]);
103
+ expect(tool._meshMeta?.version).toBe("1.0.0");
104
+ });
105
+ it("should extract vendor from model string", () => {
106
+ const anthropicTool = llmProvider({ model: "anthropic/claude-sonnet-4-5" });
107
+ const openaiTool = llmProvider({ model: "openai/gpt-4o" });
108
+ const googleTool = llmProvider({ model: "google/gemini-2.0-flash" });
109
+ expect(anthropicTool._meshMeta?.vendor).toBe("anthropic");
110
+ expect(openaiTool._meshMeta?.vendor).toBe("openai");
111
+ expect(googleTool._meshMeta?.vendor).toBe("google");
112
+ });
113
+ it("should use 'unknown' vendor for models without prefix", () => {
114
+ const tool = llmProvider({ model: "gpt-4" });
115
+ expect(tool._meshMeta?.vendor).toBe("unknown");
116
+ });
117
+ });
118
+ describe("parameter schema", () => {
119
+ it("should have request parameter with messages", () => {
120
+ const tool = llmProvider({ model: "anthropic/claude-sonnet-4-5" });
121
+ // The schema should be defined
122
+ expect(tool.parameters).toBeDefined();
123
+ expect(tool.parameters.shape.request).toBeDefined();
124
+ });
125
+ });
126
+ });
127
+ describe("isLlmProviderTool", () => {
128
+ it("should return true for LLM provider tools", () => {
129
+ const tool = llmProvider({ model: "anthropic/claude-sonnet-4-5" });
130
+ expect(isLlmProviderTool(tool)).toBe(true);
131
+ });
132
+ it("should return false for non-objects", () => {
133
+ expect(isLlmProviderTool(null)).toBe(false);
134
+ expect(isLlmProviderTool(undefined)).toBe(false);
135
+ expect(isLlmProviderTool("string")).toBe(false);
136
+ expect(isLlmProviderTool(123)).toBe(false);
137
+ });
138
+ it("should return false for objects without _meshMeta", () => {
139
+ expect(isLlmProviderTool({})).toBe(false);
140
+ expect(isLlmProviderTool({ name: "test" })).toBe(false);
141
+ });
142
+ it("should return false for objects with non-object _meshMeta", () => {
143
+ expect(isLlmProviderTool({ _meshMeta: "not an object" })).toBe(false);
144
+ expect(isLlmProviderTool({ _meshMeta: 123 })).toBe(false);
145
+ // Note: null returns true because typeof null === "object" in JavaScript
146
+ // This is a known quirk; getLlmProviderMeta handles null gracefully
147
+ });
148
+ });
149
+ describe("getLlmProviderMeta", () => {
150
+ it("should return metadata from LLM provider tool", () => {
151
+ const tool = llmProvider({
152
+ model: "openai/gpt-4o",
153
+ capability: "llm",
154
+ tags: ["gpt", "openai"],
155
+ version: "1.5.0",
156
+ });
157
+ const meta = getLlmProviderMeta(tool);
158
+ expect(meta).not.toBeNull();
159
+ expect(meta?.capability).toBe("llm");
160
+ expect(meta?.tags).toEqual(["gpt", "openai"]);
161
+ expect(meta?.version).toBe("1.5.0");
162
+ expect(meta?.vendor).toBe("openai");
163
+ });
164
+ it("should return null for tool without metadata", () => {
165
+ const fakeTool = {
166
+ name: "test",
167
+ execute: () => Promise.resolve(""),
168
+ inputSchema: {},
169
+ };
170
+ const meta = getLlmProviderMeta(fakeTool);
171
+ expect(meta).toBeNull();
172
+ });
173
+ });
174
+ describe("LLM provider configurations", () => {
175
+ it("should accept maxOutputTokens configuration", () => {
176
+ const tool = llmProvider({
177
+ model: "anthropic/claude-sonnet-4-5",
178
+ maxOutputTokens: 4096,
179
+ });
180
+ expect(tool).toBeDefined();
181
+ // maxOutputTokens is used internally in execute, verified via integration tests
182
+ });
183
+ it("should accept temperature configuration", () => {
184
+ const tool = llmProvider({
185
+ model: "openai/gpt-4o",
186
+ temperature: 0.7,
187
+ });
188
+ expect(tool).toBeDefined();
189
+ });
190
+ it("should accept topP configuration", () => {
191
+ const tool = llmProvider({
192
+ model: "google/gemini-2.0-flash",
193
+ topP: 0.9,
194
+ });
195
+ expect(tool).toBeDefined();
196
+ });
197
+ it("should accept all parameters together", () => {
198
+ const tool = llmProvider({
199
+ model: "anthropic/claude-sonnet-4-5",
200
+ capability: "custom-llm",
201
+ tags: ["production", "fast"],
202
+ version: "3.0.0",
203
+ name: "production_chat",
204
+ description: "Production LLM endpoint with Claude",
205
+ maxOutputTokens: 8192,
206
+ temperature: 0.5,
207
+ topP: 0.95,
208
+ });
209
+ expect(tool.name).toBe("production_chat");
210
+ expect(tool.description).toBe("Production LLM endpoint with Claude");
211
+ expect(tool._meshMeta?.capability).toBe("custom-llm");
212
+ expect(tool._meshMeta?.tags).toEqual(["production", "fast"]);
213
+ expect(tool._meshMeta?.version).toBe("3.0.0");
214
+ expect(tool._meshMeta?.vendor).toBe("anthropic");
215
+ });
216
+ });
217
+ //# sourceMappingURL=llm-provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-provider.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-provider.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Unit tests for openai-handler.ts
3
+ *
4
+ * Tests the OpenAIHandler provider for OpenAI models (GPT-4, etc.).
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=openai-handler.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-handler.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/openai-handler.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,359 @@
1
+ /**
2
+ * Unit tests for openai-handler.ts
3
+ *
4
+ * Tests the OpenAIHandler provider for OpenAI models (GPT-4, etc.).
5
+ */
6
+ import { describe, it, expect, beforeEach } from "vitest";
7
+ import { OpenAIHandler } from "../provider-handlers/openai-handler.js";
8
+ describe("OpenAIHandler", () => {
9
+ let handler;
10
+ beforeEach(() => {
11
+ handler = new OpenAIHandler();
12
+ });
13
+ describe("vendor", () => {
14
+ it("should have vendor set to 'openai'", () => {
15
+ expect(handler.vendor).toBe("openai");
16
+ });
17
+ });
18
+ describe("getCapabilities", () => {
19
+ it("should return OpenAI capabilities", () => {
20
+ const capabilities = handler.getCapabilities();
21
+ expect(capabilities.nativeToolCalling).toBe(true);
22
+ expect(capabilities.structuredOutput).toBe(true);
23
+ expect(capabilities.streaming).toBe(true);
24
+ expect(capabilities.vision).toBe(true);
25
+ expect(capabilities.jsonMode).toBe(true);
26
+ // OpenAI doesn't have promptCaching
27
+ expect(capabilities.promptCaching).toBeUndefined();
28
+ });
29
+ });
30
+ describe("determineOutputMode", () => {
31
+ it("should return 'text' when no schema provided", () => {
32
+ const mode = handler.determineOutputMode(null);
33
+ expect(mode).toBe("text");
34
+ });
35
+ it("should return override mode when specified", () => {
36
+ const schema = {
37
+ name: "TestSchema",
38
+ schema: { type: "object", properties: { a: { type: "string" } } },
39
+ };
40
+ expect(handler.determineOutputMode(schema, "hint")).toBe("hint");
41
+ expect(handler.determineOutputMode(schema, "strict")).toBe("strict");
42
+ expect(handler.determineOutputMode(schema, "text")).toBe("text");
43
+ });
44
+ it("should always return 'strict' for schemas (unlike Claude)", () => {
45
+ // OpenAI has excellent structured output, so always use strict
46
+ const simpleSchema = {
47
+ name: "Simple",
48
+ schema: { type: "object", properties: { name: { type: "string" } } },
49
+ };
50
+ const mode = handler.determineOutputMode(simpleSchema);
51
+ expect(mode).toBe("strict");
52
+ });
53
+ });
54
+ describe("prepareRequest", () => {
55
+ it("should convert messages to Vercel format", () => {
56
+ const messages = [
57
+ { role: "system", content: "You are helpful." },
58
+ { role: "user", content: "Hello" },
59
+ { role: "assistant", content: "Hi there!" },
60
+ ];
61
+ const request = handler.prepareRequest(messages, null, null);
62
+ expect(request.messages).toHaveLength(3);
63
+ expect(request.messages[0].role).toBe("system");
64
+ expect(request.messages[0].content).toBe("You are helpful.");
65
+ });
66
+ it("should NOT apply prompt caching (unlike Claude)", () => {
67
+ const messages = [
68
+ { role: "system", content: "You are a helpful assistant." },
69
+ ];
70
+ const request = handler.prepareRequest(messages, null, null);
71
+ // System message should remain as plain string (no cache_control)
72
+ expect(request.messages[0].content).toBe("You are a helpful assistant.");
73
+ });
74
+ it("should include tools when provided", () => {
75
+ const messages = [{ role: "user", content: "Hello" }];
76
+ const tools = [
77
+ {
78
+ type: "function",
79
+ function: { name: "get_weather", description: "Get weather info" },
80
+ },
81
+ ];
82
+ const request = handler.prepareRequest(messages, tools, null);
83
+ expect(request.tools).toEqual(tools);
84
+ });
85
+ it("should include response_format for any schema (always strict)", () => {
86
+ const messages = [{ role: "user", content: "Hello" }];
87
+ const simpleSchema = {
88
+ name: "Simple",
89
+ schema: { type: "object", properties: { name: { type: "string" } } },
90
+ };
91
+ const request = handler.prepareRequest(messages, null, simpleSchema);
92
+ // OpenAI always uses response_format for schemas
93
+ expect(request.responseFormat).toBeDefined();
94
+ expect(request.responseFormat?.type).toBe("json_schema");
95
+ expect(request.responseFormat?.jsonSchema.name).toBe("Simple");
96
+ expect(request.responseFormat?.jsonSchema.strict).toBe(true);
97
+ });
98
+ it("should NOT include response_format in text mode", () => {
99
+ const messages = [{ role: "user", content: "Hello" }];
100
+ const request = handler.prepareRequest(messages, null, null, { outputMode: "text" });
101
+ expect(request.responseFormat).toBeUndefined();
102
+ });
103
+ it("should NOT include response_format when no schema", () => {
104
+ const messages = [{ role: "user", content: "Hello" }];
105
+ const request = handler.prepareRequest(messages, null, null);
106
+ expect(request.responseFormat).toBeUndefined();
107
+ });
108
+ it("should pass through temperature, maxOutputTokens, and topP", () => {
109
+ const messages = [{ role: "user", content: "Hello" }];
110
+ const request = handler.prepareRequest(messages, null, null, {
111
+ temperature: 0.5,
112
+ maxOutputTokens: 2000,
113
+ topP: 0.95,
114
+ });
115
+ expect(request.temperature).toBe(0.5);
116
+ expect(request.maxOutputTokens).toBe(2000);
117
+ expect(request.topP).toBe(0.95);
118
+ });
119
+ it("should convert assistant tool_calls to Vercel format", () => {
120
+ const messages = [
121
+ {
122
+ role: "assistant",
123
+ content: "Let me check the weather.",
124
+ tool_calls: [
125
+ {
126
+ id: "call_abc",
127
+ type: "function",
128
+ function: { name: "get_weather", arguments: '{"location":"London"}' },
129
+ },
130
+ ],
131
+ },
132
+ ];
133
+ const request = handler.prepareRequest(messages, null, null);
134
+ const assistantMsg = request.messages[0];
135
+ expect(Array.isArray(assistantMsg.content)).toBe(true);
136
+ const content = assistantMsg.content;
137
+ // Should have text part and tool-call part
138
+ expect(content[0].type).toBe("text");
139
+ expect(content[0].text).toBe("Let me check the weather.");
140
+ expect(content[1].type).toBe("tool-call");
141
+ expect(content[1].toolCallId).toBe("call_abc");
142
+ });
143
+ });
144
+ describe("formatSystemPrompt", () => {
145
+ it("should return base prompt as-is when no tools or schema", () => {
146
+ const basePrompt = "You are a helpful assistant.";
147
+ const result = handler.formatSystemPrompt(basePrompt, null, null);
148
+ expect(result).toBe(basePrompt);
149
+ });
150
+ it("should add tool calling rules when tools provided", () => {
151
+ const basePrompt = "You are a helpful assistant.";
152
+ const tools = [
153
+ { type: "function", function: { name: "test" } },
154
+ ];
155
+ const result = handler.formatSystemPrompt(basePrompt, tools, null);
156
+ expect(result).toContain("IMPORTANT TOOL CALLING RULES:");
157
+ expect(result).toContain("Make ONE tool call at a time");
158
+ // OpenAI doesn't need anti-XML instructions
159
+ expect(result).not.toContain("XML");
160
+ });
161
+ it("should add brief JSON note when schema provided", () => {
162
+ const basePrompt = "You are a helpful assistant.";
163
+ const schema = {
164
+ name: "TestOutput",
165
+ schema: { type: "object", properties: { value: { type: "string" } } },
166
+ };
167
+ const result = handler.formatSystemPrompt(basePrompt, null, schema);
168
+ expect(result).toContain("TestOutput format");
169
+ });
170
+ it("should NOT add detailed JSON schema (response_format handles this)", () => {
171
+ const basePrompt = "You are a helpful assistant.";
172
+ const schema = {
173
+ name: "Response",
174
+ schema: {
175
+ type: "object",
176
+ properties: { data: { type: "string" } },
177
+ },
178
+ };
179
+ const result = handler.formatSystemPrompt(basePrompt, null, schema);
180
+ // OpenAI relies on response_format, not prompt-based JSON instructions
181
+ expect(result).not.toContain("RESPONSE FORMAT:");
182
+ expect(result).not.toContain('"type": "object"');
183
+ });
184
+ it("should not add JSON note in text mode", () => {
185
+ const basePrompt = "You are a helpful assistant.";
186
+ const result = handler.formatSystemPrompt(basePrompt, null, null, "text");
187
+ expect(result).toBe(basePrompt);
188
+ });
189
+ });
190
+ describe("schema strictness (addAdditionalPropertiesFalse)", () => {
191
+ it("should add additionalProperties:false to root object", () => {
192
+ const messages = [{ role: "user", content: "Hello" }];
193
+ const schema = {
194
+ name: "Test",
195
+ schema: {
196
+ type: "object",
197
+ properties: { name: { type: "string" } },
198
+ },
199
+ };
200
+ const request = handler.prepareRequest(messages, null, schema);
201
+ const resultSchema = request.responseFormat?.jsonSchema.schema;
202
+ expect(resultSchema.additionalProperties).toBe(false);
203
+ });
204
+ it("should make all properties required for OpenAI strict mode", () => {
205
+ const messages = [{ role: "user", content: "Hello" }];
206
+ const schema = {
207
+ name: "Test",
208
+ schema: {
209
+ type: "object",
210
+ properties: {
211
+ name: { type: "string" },
212
+ age: { type: "number" },
213
+ active: { type: "boolean" },
214
+ },
215
+ },
216
+ };
217
+ const request = handler.prepareRequest(messages, null, schema);
218
+ const resultSchema = request.responseFormat?.jsonSchema.schema;
219
+ expect(resultSchema.required).toEqual(["name", "age", "active"]);
220
+ });
221
+ it("should add additionalProperties:false to nested objects", () => {
222
+ const messages = [{ role: "user", content: "Hello" }];
223
+ const nestedSchema = {
224
+ name: "Nested",
225
+ schema: {
226
+ type: "object",
227
+ properties: {
228
+ user: {
229
+ type: "object",
230
+ properties: { name: { type: "string" } },
231
+ },
232
+ },
233
+ },
234
+ };
235
+ const request = handler.prepareRequest(messages, null, nestedSchema);
236
+ const schema = request.responseFormat?.jsonSchema.schema;
237
+ const properties = schema.properties;
238
+ expect(properties.user.additionalProperties).toBe(false);
239
+ expect(properties.user.required).toEqual(["name"]);
240
+ });
241
+ it("should process $defs for nested models", () => {
242
+ const messages = [{ role: "user", content: "Hello" }];
243
+ const schemaWithDefs = {
244
+ name: "WithDefs",
245
+ schema: {
246
+ type: "object",
247
+ properties: {
248
+ data: { $ref: "#/$defs/Data" },
249
+ },
250
+ $defs: {
251
+ Data: {
252
+ type: "object",
253
+ properties: { value: { type: "string" } },
254
+ },
255
+ },
256
+ },
257
+ };
258
+ const request = handler.prepareRequest(messages, null, schemaWithDefs);
259
+ const schema = request.responseFormat?.jsonSchema.schema;
260
+ const defs = schema.$defs;
261
+ expect(defs.Data.additionalProperties).toBe(false);
262
+ expect(defs.Data.required).toEqual(["value"]);
263
+ });
264
+ it("should process array items", () => {
265
+ const messages = [{ role: "user", content: "Hello" }];
266
+ const arraySchema = {
267
+ name: "ArraySchema",
268
+ schema: {
269
+ type: "object",
270
+ properties: {
271
+ items: {
272
+ type: "array",
273
+ items: {
274
+ type: "object",
275
+ properties: { id: { type: "number" } },
276
+ },
277
+ },
278
+ },
279
+ },
280
+ };
281
+ const request = handler.prepareRequest(messages, null, arraySchema);
282
+ const schema = request.responseFormat?.jsonSchema.schema;
283
+ const properties = schema.properties;
284
+ const items = properties.items.items;
285
+ expect(items.additionalProperties).toBe(false);
286
+ expect(items.required).toEqual(["id"]);
287
+ });
288
+ it("should process anyOf schemas", () => {
289
+ const messages = [{ role: "user", content: "Hello" }];
290
+ const anyOfSchema = {
291
+ name: "AnyOfUnion",
292
+ schema: {
293
+ type: "object",
294
+ properties: {
295
+ value: {
296
+ anyOf: [
297
+ { type: "object", properties: { str: { type: "string" } } },
298
+ { type: "object", properties: { num: { type: "number" } } },
299
+ ],
300
+ },
301
+ },
302
+ },
303
+ };
304
+ const request = handler.prepareRequest(messages, null, anyOfSchema);
305
+ const schema = request.responseFormat?.jsonSchema.schema;
306
+ const properties = schema.properties;
307
+ const anyOf = properties.value.anyOf;
308
+ expect(anyOf[0].additionalProperties).toBe(false);
309
+ expect(anyOf[1].additionalProperties).toBe(false);
310
+ });
311
+ it("should process oneOf schemas", () => {
312
+ const messages = [{ role: "user", content: "Hello" }];
313
+ const oneOfSchema = {
314
+ name: "OneOfUnion",
315
+ schema: {
316
+ type: "object",
317
+ properties: {
318
+ result: {
319
+ oneOf: [
320
+ { type: "object", properties: { success: { type: "boolean" } } },
321
+ { type: "object", properties: { error: { type: "string" } } },
322
+ ],
323
+ },
324
+ },
325
+ },
326
+ };
327
+ const request = handler.prepareRequest(messages, null, oneOfSchema);
328
+ const schema = request.responseFormat?.jsonSchema.schema;
329
+ const properties = schema.properties;
330
+ const oneOf = properties.result.oneOf;
331
+ expect(oneOf[0].additionalProperties).toBe(false);
332
+ expect(oneOf[1].additionalProperties).toBe(false);
333
+ });
334
+ it("should process allOf schemas", () => {
335
+ const messages = [{ role: "user", content: "Hello" }];
336
+ const allOfSchema = {
337
+ name: "AllOfComposite",
338
+ schema: {
339
+ type: "object",
340
+ properties: {
341
+ combined: {
342
+ allOf: [
343
+ { type: "object", properties: { id: { type: "number" } } },
344
+ { type: "object", properties: { name: { type: "string" } } },
345
+ ],
346
+ },
347
+ },
348
+ },
349
+ };
350
+ const request = handler.prepareRequest(messages, null, allOfSchema);
351
+ const schema = request.responseFormat?.jsonSchema.schema;
352
+ const properties = schema.properties;
353
+ const allOf = properties.combined.allOf;
354
+ expect(allOf[0].additionalProperties).toBe(false);
355
+ expect(allOf[1].additionalProperties).toBe(false);
356
+ });
357
+ });
358
+ });
359
+ //# sourceMappingURL=openai-handler.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-handler.test.js","sourceRoot":"","sources":["../../src/__tests__/openai-handler.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAIvE,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAI,OAAsB,CAAC;IAE3B,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAI,aAAa,EAAE,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;YAE/C,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClD,MAAM,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjD,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1C,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,oCAAoC;YACpC,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,aAAa,EAAE,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,MAAM,GAAiB;gBAC3B,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;aAClE,CAAC;YAEF,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjE,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrE,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,+DAA+D;YAC/D,MAAM,YAAY,GAAiB;gBACjC,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;aACrE,CAAC;YAEF,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;YACvD,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,QAAQ,GAAiB;gBAC7B,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,kBAAkB,EAAE;gBAC/C,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;gBAClC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE;aAC5C,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAE7D,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,QAAQ,GAAiB;gBAC7B,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,8BAA8B,EAAE;aAC5D,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAE7D,kEAAkE;YAClE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,KAAK,GAAiB;gBAC1B;oBACE,IAAI,EAAE,UAAU;oBAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,kBAAkB,EAAE;iBACnE;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAE9D,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACvE,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,YAAY,GAAiB;gBACjC,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;aACrE,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YAErE,iDAAiD;YACjD,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7C,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACzD,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/D,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YAEpE,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;YAErF,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,aAAa,EAAE,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YAEpE,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAE7D,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,aAAa,EAAE,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YAEpE,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE;gBAC3D,WAAW,EAAE,GAAG;gBAChB,eAAe,EAAE,IAAI;gBACrB,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,MAAM,QAAQ,GAAiB;gBAC7B;oBACE,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,2BAA2B;oBACpC,UAAU,EAAE;wBACV;4BACE,EAAE,EAAE,UAAU;4BACd,IAAI,EAAE,UAAU;4BAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,uBAAuB,EAAE;yBACtE;qBACF;iBACF;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAE7D,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvD,MAAM,OAAO,GAAG,YAAY,CAAC,OAAiF,CAAC;YAE/G,2CAA2C;YAC3C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YAC1D,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;YACjE,MAAM,UAAU,GAAG,8BAA8B,CAAC;YAClD,MAAM,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAElE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,UAAU,GAAG,8BAA8B,CAAC;YAClD,MAAM,KAAK,GAAiB;gBAC1B,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;aACjD,CAAC;YAEF,MAAM,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAEnE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;YACzD,4CAA4C;YAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,UAAU,GAAG,8BAA8B,CAAC;YAClD,MAAM,MAAM,GAAiB;gBAC3B,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;aACtE,CAAC;YAEF,MAAM,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;YAC5E,MAAM,UAAU,GAAG,8BAA8B,CAAC;YAClD,MAAM,MAAM,GAAiB;gBAC3B,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;iBACzC;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAEpE,uEAAuE;YACvE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,UAAU,GAAG,8BAA8B,CAAC;YAElD,MAAM,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAE1E,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAChE,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,MAAM,GAAiB;gBAC3B,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;iBACzC;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAE/D,MAAM,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAiC,CAAC;YAC1F,MAAM,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,MAAM,GAAiB;gBAC3B,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACxB,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACvB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;qBAC5B;iBACF;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAE/D,MAAM,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAiC,CAAC;YAC1F,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;YACjE,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,YAAY,GAAiB;gBACjC,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;yBACzC;qBACF;iBACF;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YAErE,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAiC,CAAC;YACpF,MAAM,UAAU,GAAG,MAAM,CAAC,UAAqD,CAAC;YAChF,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzD,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,cAAc,GAAiB;gBACnC,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,IAAI,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;qBAC/B;oBACD,KAAK,EAAE;wBACL,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;yBAC1C;qBACF;iBACF;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;YAEvE,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAiC,CAAC;YACpF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAgD,CAAC;YACrE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,WAAW,GAAiB;gBAChC,IAAI,EAAE,aAAa;gBACnB,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,KAAK,EAAE;4BACL,IAAI,EAAE,OAAO;4BACb,KAAK,EAAE;gCACL,IAAI,EAAE,QAAQ;gCACd,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;6BACvC;yBACF;qBACF;iBACF;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YAEpE,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAiC,CAAC;YACpF,MAAM,UAAU,GAAG,MAAM,CAAC,UAAqD,CAAC;YAChF,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAgC,CAAC;YAChE,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,WAAW,GAAiB;gBAChC,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,KAAK,EAAE;4BACL,KAAK,EAAE;gCACL,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;gCAC3D,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;6BAC5D;yBACF;qBACF;iBACF;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YAEpE,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAiC,CAAC;YACpF,MAAM,UAAU,GAAG,MAAM,CAAC,UAAqD,CAAC;YAChF,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAuC,CAAC;YAEvE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,WAAW,GAAiB;gBAChC,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,MAAM,EAAE;4BACN,KAAK,EAAE;gCACL,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;gCAChE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;6BAC9D;yBACF;qBACF;iBACF;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YAEpE,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAiC,CAAC;YACpF,MAAM,UAAU,GAAG,MAAM,CAAC,UAAqD,CAAC;YAChF,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,KAAuC,CAAC;YAExE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,QAAQ,GAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,MAAM,WAAW,GAAiB;gBAChC,IAAI,EAAE,gBAAgB;gBACtB,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,QAAQ,EAAE;4BACR,KAAK,EAAE;gCACL,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;gCAC1D,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;6BAC7D;yBACF;qBACF;iBACF;aACF,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YAEpE,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAiC,CAAC;YACpF,MAAM,UAAU,GAAG,MAAM,CAAC,UAAqD,CAAC;YAChF,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAuC,CAAC;YAE1E,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Unit tests for provider-handler-registry.ts
3
+ *
4
+ * Tests the ProviderHandlerRegistry singleton that manages vendor-specific handlers.
5
+ */
6
+ import "../provider-handlers/openai-handler.js";
7
+ import "../provider-handlers/gemini-handler.js";
8
+ import "../provider-handlers/generic-handler.js";
9
+ //# sourceMappingURL=provider-handler-registry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-handler-registry.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/provider-handler-registry.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,wCAAwC,CAAC;AAChD,OAAO,wCAAwC,CAAC;AAChD,OAAO,yCAAyC,CAAC"}