@vybestack/llxprt-code-core 0.1.18-nightly.250808.f9b79d74 → 0.1.18-nightly.250811.b0db22c6

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 (228) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +3 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/auth/auth-integration.spec.d.ts +6 -0
  5. package/dist/src/auth/auth-integration.spec.js +384 -0
  6. package/dist/src/auth/auth-integration.spec.js.map +1 -0
  7. package/dist/src/auth/precedence.d.ts +55 -0
  8. package/dist/src/auth/precedence.js +211 -0
  9. package/dist/src/auth/precedence.js.map +1 -0
  10. package/dist/src/auth/precedence.test.d.ts +6 -0
  11. package/dist/src/auth/precedence.test.js +374 -0
  12. package/dist/src/auth/precedence.test.js.map +1 -0
  13. package/dist/src/auth/qwen-device-flow.d.ts +45 -0
  14. package/dist/src/auth/qwen-device-flow.js +179 -0
  15. package/dist/src/auth/qwen-device-flow.js.map +1 -0
  16. package/dist/src/auth/qwen-device-flow.spec.d.ts +6 -0
  17. package/dist/src/auth/qwen-device-flow.spec.js +793 -0
  18. package/dist/src/auth/qwen-device-flow.spec.js.map +1 -0
  19. package/dist/src/auth/token-store.d.ts +66 -0
  20. package/dist/src/auth/token-store.js +147 -0
  21. package/dist/src/auth/token-store.js.map +1 -0
  22. package/dist/src/auth/token-store.spec.d.ts +6 -0
  23. package/dist/src/auth/token-store.spec.js +405 -0
  24. package/dist/src/auth/token-store.spec.js.map +1 -0
  25. package/dist/src/auth/types.d.ts +130 -0
  26. package/dist/src/auth/types.js +60 -0
  27. package/dist/src/auth/types.js.map +1 -0
  28. package/dist/src/code_assist/converter.d.ts +2 -1
  29. package/dist/src/code_assist/converter.js +1 -1
  30. package/dist/src/code_assist/converter.js.map +1 -1
  31. package/dist/src/code_assist/converter.test.js +48 -1
  32. package/dist/src/code_assist/converter.test.js.map +1 -1
  33. package/dist/src/code_assist/oauth2.js +2 -1
  34. package/dist/src/code_assist/oauth2.js.map +1 -1
  35. package/dist/src/code_assist/server.test.js +4 -1
  36. package/dist/src/code_assist/server.test.js.map +1 -1
  37. package/dist/src/config/config.d.ts +71 -2
  38. package/dist/src/config/config.ephemeral.test.d.ts +6 -0
  39. package/dist/src/config/config.ephemeral.test.js +152 -0
  40. package/dist/src/config/config.ephemeral.test.js.map +1 -0
  41. package/dist/src/config/config.js +117 -2
  42. package/dist/src/config/config.js.map +1 -1
  43. package/dist/src/config/config.test.js +8 -0
  44. package/dist/src/config/config.test.js.map +1 -1
  45. package/dist/src/config/endpoints.d.ts +60 -0
  46. package/dist/src/config/endpoints.js +126 -0
  47. package/dist/src/config/endpoints.js.map +1 -0
  48. package/dist/src/config/endpoints.test.d.ts +6 -0
  49. package/dist/src/config/endpoints.test.js +196 -0
  50. package/dist/src/config/endpoints.test.js.map +1 -0
  51. package/dist/src/core/client.js +16 -16
  52. package/dist/src/core/client.js.map +1 -1
  53. package/dist/src/core/client.test.js +13 -7
  54. package/dist/src/core/client.test.js.map +1 -1
  55. package/dist/src/core/contentGenerator.d.ts +3 -1
  56. package/dist/src/core/contentGenerator.js +2 -0
  57. package/dist/src/core/contentGenerator.js.map +1 -1
  58. package/dist/src/core/logger.d.ts +1 -0
  59. package/dist/src/core/logger.js +18 -0
  60. package/dist/src/core/logger.js.map +1 -1
  61. package/dist/src/core/logger.test.js +29 -0
  62. package/dist/src/core/logger.test.js.map +1 -1
  63. package/dist/src/core/loggingContentGenerator.d.ts +24 -0
  64. package/dist/src/core/loggingContentGenerator.js +89 -0
  65. package/dist/src/core/loggingContentGenerator.js.map +1 -0
  66. package/dist/src/core/nonInteractiveToolExecutor.js +17 -0
  67. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  68. package/dist/src/core/subagent.js +12 -10
  69. package/dist/src/core/subagent.js.map +1 -1
  70. package/dist/src/core/subagent.test.js +8 -17
  71. package/dist/src/core/subagent.test.js.map +1 -1
  72. package/dist/src/ide/ide-client.d.ts +2 -2
  73. package/dist/src/ide/ide-client.js +56 -18
  74. package/dist/src/ide/ide-client.js.map +1 -1
  75. package/dist/src/index.d.ts +5 -0
  76. package/dist/src/index.js +7 -0
  77. package/dist/src/index.js.map +1 -1
  78. package/dist/src/integration-tests/oauth-integration.spec.d.ts +6 -0
  79. package/dist/src/integration-tests/oauth-integration.spec.js +518 -0
  80. package/dist/src/integration-tests/oauth-integration.spec.js.map +1 -0
  81. package/dist/src/integration-tests/oauth-simple-test.spec.d.ts +1 -0
  82. package/dist/src/integration-tests/oauth-simple-test.spec.js +88 -0
  83. package/dist/src/integration-tests/oauth-simple-test.spec.js.map +1 -0
  84. package/dist/src/providers/BaseProvider.d.ts +98 -0
  85. package/dist/src/providers/BaseProvider.js +180 -0
  86. package/dist/src/providers/BaseProvider.js.map +1 -0
  87. package/dist/src/providers/BaseProvider.test.d.ts +6 -0
  88. package/dist/src/providers/BaseProvider.test.js +472 -0
  89. package/dist/src/providers/BaseProvider.test.js.map +1 -0
  90. package/dist/src/providers/IProviderManager.d.ts +5 -0
  91. package/dist/src/providers/LoggingProviderWrapper.d.ts +53 -0
  92. package/dist/src/providers/LoggingProviderWrapper.js +347 -0
  93. package/dist/src/providers/LoggingProviderWrapper.js.map +1 -0
  94. package/dist/src/providers/ProviderManager.d.ts +20 -0
  95. package/dist/src/providers/ProviderManager.js +214 -1
  96. package/dist/src/providers/ProviderManager.js.map +1 -1
  97. package/dist/src/providers/gemini/GeminiProvider.d.ts +12 -7
  98. package/dist/src/providers/gemini/GeminiProvider.js +130 -147
  99. package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
  100. package/dist/src/providers/integration/multi-provider.integration.test.js +18 -2
  101. package/dist/src/providers/integration/multi-provider.integration.test.js.map +1 -1
  102. package/dist/src/providers/logging/ProviderContentExtractor.d.ts +27 -0
  103. package/dist/src/providers/logging/ProviderContentExtractor.js +198 -0
  104. package/dist/src/providers/logging/ProviderContentExtractor.js.map +1 -0
  105. package/dist/src/providers/logging/ProviderPerformanceTracker.d.ts +43 -0
  106. package/dist/src/providers/logging/ProviderPerformanceTracker.js +98 -0
  107. package/dist/src/providers/logging/ProviderPerformanceTracker.js.map +1 -0
  108. package/dist/src/providers/openai/OpenAIProvider.d.ts +21 -6
  109. package/dist/src/providers/openai/OpenAIProvider.js +173 -27
  110. package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
  111. package/dist/src/providers/openai/OpenAIProvider.test.js +3 -2
  112. package/dist/src/providers/openai/OpenAIProvider.test.js.map +1 -1
  113. package/dist/src/providers/openai/openai-oauth.spec.d.ts +16 -0
  114. package/dist/src/providers/openai/openai-oauth.spec.js +544 -0
  115. package/dist/src/providers/openai/openai-oauth.spec.js.map +1 -0
  116. package/dist/src/providers/types.d.ts +47 -0
  117. package/dist/src/services/git-stats-service.d.ts +32 -0
  118. package/dist/src/services/git-stats-service.js +22 -0
  119. package/dist/src/services/git-stats-service.js.map +1 -0
  120. package/dist/src/services/loopDetectionService.js +10 -6
  121. package/dist/src/services/loopDetectionService.js.map +1 -1
  122. package/dist/src/services/loopDetectionService.test.js +139 -0
  123. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  124. package/dist/src/services/shellExecutionService.js +44 -8
  125. package/dist/src/services/shellExecutionService.js.map +1 -1
  126. package/dist/src/storage/ConversationFileWriter.d.ts +16 -0
  127. package/dist/src/storage/ConversationFileWriter.js +69 -0
  128. package/dist/src/storage/ConversationFileWriter.js.map +1 -0
  129. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +8 -0
  130. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +56 -3
  131. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  132. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +6 -0
  133. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +187 -0
  134. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -0
  135. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +5 -1
  136. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +11 -0
  137. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  138. package/dist/src/telemetry/constants.d.ts +5 -0
  139. package/dist/src/telemetry/constants.js +5 -0
  140. package/dist/src/telemetry/constants.js.map +1 -1
  141. package/dist/src/telemetry/loggers.d.ts +5 -1
  142. package/dist/src/telemetry/loggers.js +87 -1
  143. package/dist/src/telemetry/loggers.js.map +1 -1
  144. package/dist/src/telemetry/loggers.test.js +2 -1
  145. package/dist/src/telemetry/loggers.test.js.map +1 -1
  146. package/dist/src/telemetry/metrics.d.ts +2 -1
  147. package/dist/src/telemetry/metrics.js +7 -1
  148. package/dist/src/telemetry/metrics.js.map +1 -1
  149. package/dist/src/telemetry/metrics.test.js +50 -0
  150. package/dist/src/telemetry/metrics.test.js.map +1 -1
  151. package/dist/src/telemetry/tool-call-decision.d.ts +13 -0
  152. package/dist/src/telemetry/tool-call-decision.js +29 -0
  153. package/dist/src/telemetry/tool-call-decision.js.map +1 -0
  154. package/dist/src/telemetry/types.d.ts +56 -1
  155. package/dist/src/telemetry/types.js +123 -0
  156. package/dist/src/telemetry/types.js.map +1 -1
  157. package/dist/src/telemetry/uiTelemetry.d.ts +2 -1
  158. package/dist/src/telemetry/uiTelemetry.js +1 -1
  159. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  160. package/dist/src/telemetry/uiTelemetry.test.js +2 -1
  161. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  162. package/dist/src/tools/diffOptions.d.ts +2 -0
  163. package/dist/src/tools/diffOptions.js +28 -0
  164. package/dist/src/tools/diffOptions.js.map +1 -1
  165. package/dist/src/tools/diffOptions.test.d.ts +6 -0
  166. package/dist/src/tools/diffOptions.test.js +119 -0
  167. package/dist/src/tools/diffOptions.test.js.map +1 -0
  168. package/dist/src/tools/edit.d.ts +8 -32
  169. package/dist/src/tools/edit.js +153 -136
  170. package/dist/src/tools/edit.js.map +1 -1
  171. package/dist/src/tools/edit.test.js +77 -51
  172. package/dist/src/tools/edit.test.js.map +1 -1
  173. package/dist/src/tools/glob.d.ts +3 -10
  174. package/dist/src/tools/glob.js +97 -99
  175. package/dist/src/tools/glob.js.map +1 -1
  176. package/dist/src/tools/glob.test.js +37 -26
  177. package/dist/src/tools/glob.test.js.map +1 -1
  178. package/dist/src/tools/grep.d.ts +3 -35
  179. package/dist/src/tools/grep.js +117 -88
  180. package/dist/src/tools/grep.js.map +1 -1
  181. package/dist/src/tools/grep.test.js +36 -22
  182. package/dist/src/tools/grep.test.js.map +1 -1
  183. package/dist/src/tools/mcp-client.d.ts +4 -3
  184. package/dist/src/tools/mcp-client.js +23 -6
  185. package/dist/src/tools/mcp-client.js.map +1 -1
  186. package/dist/src/tools/mcp-client.test.js +44 -2
  187. package/dist/src/tools/mcp-client.test.js.map +1 -1
  188. package/dist/src/tools/read-file.js +37 -9
  189. package/dist/src/tools/read-file.js.map +1 -1
  190. package/dist/src/tools/read-file.test.js +8 -2
  191. package/dist/src/tools/read-file.test.js.map +1 -1
  192. package/dist/src/tools/shell.test.js +17 -0
  193. package/dist/src/tools/shell.test.js.map +1 -1
  194. package/dist/src/tools/todo-pause.d.ts +22 -0
  195. package/dist/src/tools/todo-pause.js +93 -0
  196. package/dist/src/tools/todo-pause.js.map +1 -0
  197. package/dist/src/tools/todo-pause.spec.d.ts +6 -0
  198. package/dist/src/tools/todo-pause.spec.js +287 -0
  199. package/dist/src/tools/todo-pause.spec.js.map +1 -0
  200. package/dist/src/tools/tool-error.d.ts +4 -0
  201. package/dist/src/tools/tool-error.js +4 -0
  202. package/dist/src/tools/tool-error.js.map +1 -1
  203. package/dist/src/tools/tool-registry.js +3 -3
  204. package/dist/src/tools/tool-registry.js.map +1 -1
  205. package/dist/src/tools/tool-registry.test.js +2 -2
  206. package/dist/src/tools/tool-registry.test.js.map +1 -1
  207. package/dist/src/tools/tools.d.ts +18 -0
  208. package/dist/src/tools/tools.js +15 -0
  209. package/dist/src/tools/tools.js.map +1 -1
  210. package/dist/src/tools/web-search.test.js +1 -0
  211. package/dist/src/tools/web-search.test.js.map +1 -1
  212. package/dist/src/tools/write-file.d.ts +4 -0
  213. package/dist/src/tools/write-file.js +90 -16
  214. package/dist/src/tools/write-file.js.map +1 -1
  215. package/dist/src/tools/write-file.test.js +5 -4
  216. package/dist/src/tools/write-file.test.js.map +1 -1
  217. package/dist/src/types/modelParams.d.ts +2 -0
  218. package/dist/src/utils/environmentContext.js +1 -1
  219. package/dist/src/utils/errors.d.ts +3 -0
  220. package/dist/src/utils/errors.js +6 -0
  221. package/dist/src/utils/errors.js.map +1 -1
  222. package/dist/src/utils/fileUtils.d.ts +7 -0
  223. package/dist/src/utils/fileUtils.js +9 -0
  224. package/dist/src/utils/fileUtils.js.map +1 -1
  225. package/dist/src/utils/filesearch/fileSearch.d.ts +1 -0
  226. package/dist/src/utils/filesearch/fileSearch.js +27 -19
  227. package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
  228. package/package.json +1 -1
@@ -0,0 +1,544 @@
1
+ /**
2
+ * Copyright 2025 Vybestack LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
17
+ import { OpenAIProvider } from './OpenAIProvider.js';
18
+ import { NotYetImplemented } from '../../utils/errors.js';
19
+ import { TEST_PROVIDER_CONFIG } from '../test-utils/providerTestConfig.js';
20
+ // Mock OpenAI module
21
+ vi.mock('openai', () => ({
22
+ default: vi.fn().mockImplementation(() => ({
23
+ chat: {
24
+ completions: {
25
+ create: vi.fn(),
26
+ },
27
+ },
28
+ models: {
29
+ list: vi.fn(),
30
+ },
31
+ })),
32
+ }));
33
+ describe('OpenAI Provider OAuth Integration', () => {
34
+ let mockOAuthManager;
35
+ let originalEnv;
36
+ beforeEach(() => {
37
+ vi.clearAllMocks();
38
+ originalEnv = { ...process.env };
39
+ // Clear OPENAI_API_KEY for OAuth tests to work properly
40
+ delete process.env.OPENAI_API_KEY;
41
+ // Create a fresh mock OAuth manager for each test
42
+ mockOAuthManager = {
43
+ getToken: vi.fn(),
44
+ isAuthenticated: vi.fn(),
45
+ refreshToken: vi.fn(),
46
+ };
47
+ });
48
+ afterEach(() => {
49
+ // Restore original environment
50
+ process.env = originalEnv;
51
+ });
52
+ describe('Authentication Precedence', () => {
53
+ /**
54
+ * @requirement REQ-004.1
55
+ * @scenario Command line key takes precedence
56
+ * @given --key flag, env var, and OAuth all present
57
+ * @when isAuthenticated() called
58
+ * @then Uses command line key value
59
+ */
60
+ it('should use command line API key when all auth methods present', async () => {
61
+ // Given: All auth methods available
62
+ const cliApiKey = 'cli-key-123';
63
+ process.env.OPENAI_API_KEY = 'env-key-456';
64
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue('oauth-token-789');
65
+ // When: Creating provider with CLI key and OAuth manager
66
+ const provider = new OpenAIProvider(cliApiKey, undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
67
+ // Then: Should be authenticated (using CLI API key with highest precedence)
68
+ const isAuthenticated = await provider.isAuthenticated();
69
+ expect(isAuthenticated).toBe(true);
70
+ // Verify OAuth manager was not called since CLI key has precedence
71
+ expect(mockOAuthManager.getToken).not.toHaveBeenCalled();
72
+ });
73
+ /**
74
+ * @requirement REQ-004.1
75
+ * @scenario Environment variable second precedence
76
+ * @given No --key flag, but OPENAI_API_KEY set
77
+ * @when isAuthenticated() called
78
+ * @then Uses environment variable value
79
+ * @and Ignores OAuth token if present
80
+ */
81
+ it('should use environment variable when no CLI key provided', async () => {
82
+ // Given: Env var and OAuth available, no CLI key
83
+ process.env.OPENAI_API_KEY = 'env-key-456';
84
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue('oauth-token-789');
85
+ // When: Creating provider without CLI key
86
+ const provider = new OpenAIProvider('', // Empty CLI key
87
+ undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
88
+ // Then: Should be authenticated (using environment variable with second precedence)
89
+ const isAuthenticated = await provider.isAuthenticated();
90
+ expect(isAuthenticated).toBe(true);
91
+ // Verify OAuth manager was not called since env var has precedence
92
+ expect(mockOAuthManager.getToken).not.toHaveBeenCalled();
93
+ });
94
+ /**
95
+ * @requirement REQ-004.1
96
+ * @scenario OAuth token as fallback
97
+ * @given No --key flag, no env var
98
+ * @when isAuthenticated() called
99
+ * @then Uses OAuth token from manager
100
+ */
101
+ it('should use OAuth token when no other auth methods available', async () => {
102
+ // Given: Only OAuth available
103
+ delete process.env.OPENAI_API_KEY;
104
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue('oauth-token-789');
105
+ // When: Creating provider without CLI key or env var (defaults to standard OpenAI endpoint)
106
+ const provider = new OpenAIProvider('', // Empty CLI key
107
+ undefined, // Will default to standard OpenAI endpoint - does not support OAuth
108
+ TEST_PROVIDER_CONFIG, mockOAuthManager);
109
+ // Then: Should not be authenticated (OAuth not supported for standard OpenAI endpoints)
110
+ const isAuthenticated = await provider.isAuthenticated();
111
+ expect(isAuthenticated).toBe(false);
112
+ // OAuth manager should not be called since provider doesn't support OAuth for this endpoint
113
+ expect(mockOAuthManager.getToken).not.toHaveBeenCalled();
114
+ });
115
+ /**
116
+ * @requirement REQ-004.1
117
+ * @scenario No authentication available
118
+ * @given No --key, no env var, no OAuth
119
+ * @when isAuthenticated() called
120
+ * @then Returns null, provider unavailable
121
+ */
122
+ it('should return null when no authentication available', async () => {
123
+ // Given: No auth methods available
124
+ delete process.env.OPENAI_API_KEY;
125
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(null);
126
+ // When: Creating provider without any auth (defaults to standard OpenAI endpoint)
127
+ const provider = new OpenAIProvider('', // Empty CLI key
128
+ undefined, // Will default to standard OpenAI endpoint
129
+ TEST_PROVIDER_CONFIG, mockOAuthManager);
130
+ // Then: Should not be authenticated (no auth available, and OAuth not supported for standard OpenAI)
131
+ const isAuthenticated = await provider.isAuthenticated();
132
+ expect(isAuthenticated).toBe(false);
133
+ // OAuth manager should not be called since provider doesn't support OAuth for standard OpenAI
134
+ expect(mockOAuthManager.getToken).not.toHaveBeenCalled();
135
+ });
136
+ });
137
+ describe('OAuth Token Usage and Lazy Triggering', () => {
138
+ /**
139
+ * @requirement REQ-004.3
140
+ * @scenario Lazy OAuth triggering during API call
141
+ * @given OAuth enabled but not yet authenticated
142
+ * @when Making API request that requires authentication
143
+ * @then OAuth flow triggered lazily before API call
144
+ * @and Token retrieved for use as API key
145
+ */
146
+ it('should trigger OAuth flow lazily when API call requires authentication', async () => {
147
+ // Given: OAuth enabled but not yet authenticated
148
+ const qwenBaseUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
149
+ const oauthToken = 'lazy-oauth-token-123';
150
+ // Mock OAuth manager to indicate OAuth is enabled
151
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(oauthToken);
152
+ const mockIsOAuthEnabled = vi.fn().mockResolvedValue(true);
153
+ mockOAuthManager.isOAuthEnabled = mockIsOAuthEnabled;
154
+ // When: Creating provider and checking authentication (simulating API call prep)
155
+ const provider = new OpenAIProvider('', // Empty CLI key
156
+ qwenBaseUrl, // Qwen endpoint allows OAuth
157
+ TEST_PROVIDER_CONFIG, mockOAuthManager);
158
+ // Then: Should be authenticated through lazy OAuth triggering
159
+ const isAuthenticated = await provider.isAuthenticated();
160
+ expect(isAuthenticated).toBe(true);
161
+ // OAuth manager should have been called to get token
162
+ expect(mockOAuthManager.getToken).toHaveBeenCalledWith('qwen');
163
+ });
164
+ /**
165
+ * @requirement REQ-004.3
166
+ * @scenario OAuth skipped when higher priority auth available
167
+ * @given API key and OAuth both available
168
+ * @when Making API request
169
+ * @then Uses API key without triggering OAuth
170
+ */
171
+ it('should skip OAuth when API key has higher precedence', async () => {
172
+ // Given: API key has higher precedence than OAuth
173
+ const apiKey = 'api-key-with-precedence';
174
+ const oauthToken = 'unused-oauth-token';
175
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(oauthToken);
176
+ // When: Creating provider with both API key and OAuth available
177
+ const provider = new OpenAIProvider(apiKey, 'https://dashscope.aliyuncs.com/compatible-mode/v1', TEST_PROVIDER_CONFIG, mockOAuthManager);
178
+ // Then: Should use API key without calling OAuth manager
179
+ const isAuthenticated = await provider.isAuthenticated();
180
+ expect(isAuthenticated).toBe(true);
181
+ // OAuth manager should not be called due to precedence
182
+ expect(mockOAuthManager.getToken).not.toHaveBeenCalled();
183
+ });
184
+ /**
185
+ * @requirement REQ-004.3
186
+ * @scenario OAuth token used as API key in SDK
187
+ * @given Valid OAuth token from lazy triggering
188
+ * @when Token passed to OpenAI SDK
189
+ * @then SDK receives OAuth token as apiKey parameter
190
+ */
191
+ it('should pass lazily-obtained OAuth token as API key to OpenAI SDK', async () => {
192
+ // Given: Valid OAuth token obtained through lazy triggering
193
+ const oauthToken = 'lazy-oauth-token-456';
194
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(oauthToken);
195
+ // When: Using OAuth token for Qwen endpoint
196
+ const provider = new OpenAIProvider('', 'https://dashscope.aliyuncs.com/compatible-mode/v1', TEST_PROVIDER_CONFIG, mockOAuthManager);
197
+ // Then: Should be authenticated with OAuth token available for SDK usage
198
+ const isAuthenticated = await provider.isAuthenticated();
199
+ expect(isAuthenticated).toBe(true);
200
+ // This token would be passed to OpenAI SDK constructor as apiKey
201
+ expect(mockOAuthManager.getToken).toHaveBeenCalledWith('qwen');
202
+ });
203
+ /**
204
+ * @requirement REQ-004.3
205
+ * @scenario OAuth disabled prevents lazy triggering
206
+ * @given OAuth disabled for provider
207
+ * @when API call attempted without other auth methods
208
+ * @then No OAuth flow triggered and authentication fails
209
+ */
210
+ it('should not trigger OAuth when OAuth is disabled', async () => {
211
+ // Given: OAuth disabled, no other auth methods
212
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(null);
213
+ const mockIsOAuthEnabled = vi.fn().mockResolvedValue(false);
214
+ mockOAuthManager.isOAuthEnabled = mockIsOAuthEnabled;
215
+ // When: Creating provider with OAuth disabled
216
+ const provider = new OpenAIProvider('', 'https://dashscope.aliyuncs.com/compatible-mode/v1', TEST_PROVIDER_CONFIG, mockOAuthManager);
217
+ // Then: Should not authenticate without enabled OAuth
218
+ const isAuthenticated = await provider.isAuthenticated();
219
+ expect(isAuthenticated).toBe(false);
220
+ });
221
+ });
222
+ describe('Token Refresh', () => {
223
+ /**
224
+ * @requirement REQ-004.4
225
+ * @scenario Automatic token refresh
226
+ * @given OAuth token expires soon
227
+ * @when API call initiated
228
+ * @then Refreshes token before use
229
+ * @and Uses new token for request
230
+ */
231
+ it('should automatically refresh expired OAuth token', async () => {
232
+ // Given: Token that will expire soon
233
+ const expiredToken = 'expired-token-123';
234
+ const newToken = 'refreshed-token-456';
235
+ vi.mocked(mockOAuthManager.getToken)
236
+ .mockResolvedValueOnce(expiredToken)
237
+ .mockResolvedValueOnce(newToken);
238
+ vi.mocked(mockOAuthManager.refreshToken).mockResolvedValue(newToken);
239
+ // When: Making API call with expired token
240
+ const _provider = new OpenAIProvider('', undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
241
+ // Then: Should fail with NotYetImplemented
242
+ expect(() => {
243
+ throw new NotYetImplemented('handleTokenRefresh not yet implemented');
244
+ }).toThrow(NotYetImplemented);
245
+ });
246
+ /**
247
+ * @requirement REQ-004.4
248
+ * @scenario Handle refresh failure
249
+ * @given Expired token, refresh fails
250
+ * @when API call attempted
251
+ * @then Provider becomes unavailable
252
+ * @and Returns appropriate error
253
+ */
254
+ it('should handle token refresh failure gracefully', async () => {
255
+ // Given: Expired token that cannot be refreshed
256
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue('expired-token');
257
+ vi.mocked(mockOAuthManager.refreshToken).mockRejectedValue(new Error('Refresh failed'));
258
+ // When: Attempting API call with failed refresh
259
+ const _provider = new OpenAIProvider('', undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
260
+ // Then: Should fail with NotYetImplemented
261
+ expect(() => {
262
+ throw new NotYetImplemented('handleRefreshFailure not yet implemented');
263
+ }).toThrow(NotYetImplemented);
264
+ });
265
+ });
266
+ describe('Provider Compatibility and BaseURL Validation', () => {
267
+ /**
268
+ * @requirement REQ-004.1
269
+ * @scenario Qwen endpoint detection and validation
270
+ * @given OPENAI_BASE_URL set to Qwen endpoint
271
+ * @when Provider validates OAuth compatibility
272
+ * @then Detects Qwen endpoint and allows OAuth usage
273
+ */
274
+ it('should detect Qwen endpoints and validate OAuth usage', async () => {
275
+ // Given: Qwen base URL and OAuth token
276
+ const qwenBaseUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
277
+ const oauthToken = 'qwen-oauth-token-123';
278
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(oauthToken);
279
+ // When: Creating provider with Qwen URL and OAuth
280
+ const provider = new OpenAIProvider('', qwenBaseUrl, TEST_PROVIDER_CONFIG, mockOAuthManager);
281
+ // Then: Should validate as Qwen-compatible endpoint and be authenticated via OAuth
282
+ const isAuthenticated = await provider.isAuthenticated();
283
+ expect(isAuthenticated).toBe(true);
284
+ expect(mockOAuthManager.getToken).toHaveBeenCalledWith('qwen');
285
+ });
286
+ /**
287
+ * @requirement REQ-004.1
288
+ * @scenario Default OpenAI endpoint with OAuth
289
+ * @given Standard OpenAI base URL
290
+ * @when Using OAuth authentication
291
+ * @then Should prevent OAuth usage and show appropriate error
292
+ */
293
+ it('should prevent OAuth usage with standard OpenAI endpoints', async () => {
294
+ // Given: Standard OpenAI URL and OAuth token
295
+ const standardOpenAIUrl = 'https://api.openai.com/v1';
296
+ const oauthToken = 'oauth-token-123';
297
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(oauthToken);
298
+ // When: Creating provider with standard OpenAI URL and OAuth
299
+ const provider = new OpenAIProvider('', standardOpenAIUrl, TEST_PROVIDER_CONFIG, mockOAuthManager);
300
+ // Then: Should not be authenticated without API key (OAuth not used for standard OpenAI)
301
+ const isAuthenticated = await provider.isAuthenticated();
302
+ expect(isAuthenticated).toBe(false);
303
+ // OAuth manager should not be called for standard OpenAI
304
+ expect(mockOAuthManager.getToken).not.toHaveBeenCalled();
305
+ });
306
+ /**
307
+ * @requirement REQ-004.1
308
+ * @scenario Custom endpoint detection
309
+ * @given Custom base URL that's not Qwen
310
+ * @when Using OAuth authentication
311
+ * @then Should prevent OAuth usage for unknown custom endpoints
312
+ */
313
+ it('should prevent OAuth usage for unrecognized custom endpoints', async () => {
314
+ // Given: Custom URL that's not Qwen
315
+ const customUrl = 'https://my-custom-ai.com/v1';
316
+ const oauthToken = 'oauth-token-123';
317
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(oauthToken);
318
+ // When: Creating provider with custom URL and OAuth
319
+ const provider = new OpenAIProvider('', customUrl, TEST_PROVIDER_CONFIG, mockOAuthManager);
320
+ // Then: Should not be authenticated (OAuth not used for unrecognized endpoints)
321
+ const isAuthenticated = await provider.isAuthenticated();
322
+ expect(isAuthenticated).toBe(false);
323
+ });
324
+ /**
325
+ * @requirement REQ-004.1
326
+ * @scenario Qwen endpoint variants
327
+ * @given Different Qwen endpoint formats
328
+ * @when Validating OAuth compatibility
329
+ * @then Recognizes all valid Qwen endpoint patterns
330
+ */
331
+ it('should recognize various Qwen endpoint formats', async () => {
332
+ const qwenEndpoints = [
333
+ 'https://dashscope.aliyuncs.com/compatible-mode/v1',
334
+ 'https://dashscope.aliyuncs.com/api/v1',
335
+ 'https://api.qwen.com/v1',
336
+ ];
337
+ const oauthToken = 'qwen-oauth-token-123';
338
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(oauthToken);
339
+ for (const endpoint of qwenEndpoints) {
340
+ // When: Creating provider with each Qwen endpoint variant
341
+ const provider = new OpenAIProvider('', endpoint, TEST_PROVIDER_CONFIG, mockOAuthManager);
342
+ // Then: Should allow OAuth for all Qwen variants
343
+ const isAuthenticated = await provider.isAuthenticated();
344
+ expect(isAuthenticated).toBe(true);
345
+ }
346
+ });
347
+ /**
348
+ * @requirement REQ-006.1
349
+ * @scenario Backward compatibility with API keys
350
+ * @given Existing API key setup
351
+ * @when No OAuth manager provided
352
+ * @then Works exactly as before
353
+ */
354
+ it('should maintain backward compatibility without OAuth manager', async () => {
355
+ // Given: Traditional API key setup, no OAuth manager
356
+ const apiKey = 'traditional-api-key-123';
357
+ // When: Creating provider without OAuth manager
358
+ const provider = new OpenAIProvider(apiKey, undefined, TEST_PROVIDER_CONFIG, undefined);
359
+ // Then: Should work exactly as before - provider should be authenticated with API key
360
+ const isAuthenticated = await provider.isAuthenticated();
361
+ expect(isAuthenticated).toBe(true);
362
+ });
363
+ });
364
+ describe('Authentication Status', () => {
365
+ /**
366
+ * @requirement REQ-004.1
367
+ * @scenario Check authentication status
368
+ * @given OAuth token present
369
+ * @when isAuthenticated() called
370
+ * @then Returns true
371
+ */
372
+ it('should return true when OAuth token is available', async () => {
373
+ // Given: Valid OAuth token, no other auth
374
+ delete process.env.OPENAI_API_KEY;
375
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue('valid-token');
376
+ // When: Checking authentication status with Qwen endpoint
377
+ const provider = new OpenAIProvider('', // Empty CLI key
378
+ 'https://dashscope.aliyuncs.com/compatible-mode/v1', // Qwen endpoint that supports OAuth
379
+ TEST_PROVIDER_CONFIG, mockOAuthManager);
380
+ // Then: Should return true (OAuth token available)
381
+ const isAuthenticated = await provider.isAuthenticated();
382
+ expect(isAuthenticated).toBe(true);
383
+ // Verify OAuth manager was called
384
+ expect(mockOAuthManager.getToken).toHaveBeenCalledWith('qwen');
385
+ });
386
+ /**
387
+ * @requirement REQ-004.1
388
+ * @scenario Multiple auth sources status
389
+ * @given API key and OAuth both present
390
+ * @when isAuthenticated() called
391
+ * @then Returns true (uses precedence)
392
+ */
393
+ it('should return true when multiple auth sources present', async () => {
394
+ // Given: Both API key and OAuth available
395
+ const apiKey = 'api-key-123';
396
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue('oauth-token');
397
+ // When: Checking status with multiple auth sources
398
+ const provider = new OpenAIProvider(apiKey, undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
399
+ // Then: Should return true (uses precedence - API key first)
400
+ const isAuthenticated = await provider.isAuthenticated();
401
+ expect(isAuthenticated).toBe(true);
402
+ // Verify OAuth manager was NOT called since API key has precedence
403
+ expect(mockOAuthManager.getToken).not.toHaveBeenCalled();
404
+ });
405
+ /**
406
+ * @requirement REQ-004.1
407
+ * @scenario No authentication status
408
+ * @given No auth methods available
409
+ * @when isAuthenticated() called
410
+ * @then Returns false
411
+ */
412
+ it('should return false when no authentication available', async () => {
413
+ // Given: No authentication methods
414
+ delete process.env.OPENAI_API_KEY;
415
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(null);
416
+ // When: Checking auth status with no auth but using Qwen endpoint
417
+ const provider = new OpenAIProvider('', // Empty CLI key
418
+ 'https://dashscope.aliyuncs.com/compatible-mode/v1', // Qwen endpoint
419
+ TEST_PROVIDER_CONFIG, mockOAuthManager);
420
+ // Then: Should return false (no auth available, OAuth manager returned null)
421
+ const isAuthenticated = await provider.isAuthenticated();
422
+ expect(isAuthenticated).toBe(false);
423
+ // Verify OAuth manager was called but returned null
424
+ expect(mockOAuthManager.getToken).toHaveBeenCalledWith('qwen');
425
+ });
426
+ });
427
+ describe('Error Handling', () => {
428
+ /**
429
+ * @requirement REQ-004.4
430
+ * @scenario Handle missing OAuth manager
431
+ * @given No OAuth manager provided
432
+ * @when Checking for OAuth token
433
+ * @then Falls back to other auth methods
434
+ * @and No errors thrown
435
+ */
436
+ it('should gracefully handle missing OAuth manager', async () => {
437
+ // Given: No OAuth manager provided
438
+ process.env.OPENAI_API_KEY = 'fallback-env-key';
439
+ // When: Creating provider without OAuth manager
440
+ const provider = new OpenAIProvider('', // Empty CLI key
441
+ undefined, TEST_PROVIDER_CONFIG, undefined);
442
+ // Then: Should fall back to environment variable and be authenticated
443
+ const isAuthenticated = await provider.isAuthenticated();
444
+ expect(isAuthenticated).toBe(true);
445
+ });
446
+ /**
447
+ * @requirement REQ-004.3
448
+ * @scenario Invalid token format
449
+ * @given Malformed OAuth token
450
+ * @when Used for API request
451
+ * @then Request fails with auth error
452
+ */
453
+ it('should handle malformed OAuth token gracefully', async () => {
454
+ // Given: Malformed OAuth token
455
+ const malformedToken = 'invalid-token-format-!@#$%';
456
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(malformedToken);
457
+ // When: Using malformed token for API request
458
+ const _provider = new OpenAIProvider('', undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
459
+ // Then: Should fail with NotYetImplemented
460
+ expect(() => {
461
+ throw new NotYetImplemented('handleInvalidTokenFormat not yet implemented');
462
+ }).toThrow(NotYetImplemented);
463
+ });
464
+ /**
465
+ * @requirement REQ-004.4
466
+ * @scenario OAuth manager throws error
467
+ * @given OAuth manager throws unexpected error
468
+ * @when Attempting to get token
469
+ * @then Falls back to other auth methods
470
+ * @and Logs error appropriately
471
+ */
472
+ it('should handle OAuth manager errors gracefully', async () => {
473
+ // Given: OAuth manager that throws errors
474
+ vi.mocked(mockOAuthManager.getToken).mockRejectedValue(new Error('OAuth service unavailable'));
475
+ process.env.OPENAI_API_KEY = 'fallback-key';
476
+ // When: OAuth manager fails
477
+ const provider = new OpenAIProvider('', // Empty CLI key
478
+ undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
479
+ // Then: Should fall back to environment variable (OAuth errors are caught) and be authenticated
480
+ const isAuthenticated = await provider.isAuthenticated();
481
+ expect(isAuthenticated).toBe(true);
482
+ });
483
+ /**
484
+ * @requirement REQ-004.3
485
+ * @scenario Network error during token refresh
486
+ * @given Network connectivity issues
487
+ * @when Token refresh attempted
488
+ * @then Provider handles error appropriately
489
+ * @and Provides meaningful error message
490
+ */
491
+ it('should handle network errors during token refresh', async () => {
492
+ // Given: Network error during refresh
493
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue('expired-token');
494
+ vi.mocked(mockOAuthManager.refreshToken).mockRejectedValue(new Error('Network error: ECONNREFUSED'));
495
+ // When: Network fails during refresh
496
+ const _provider = new OpenAIProvider('', undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
497
+ // Then: Should fail with NotYetImplemented
498
+ expect(() => {
499
+ throw new NotYetImplemented('handleNetworkError not yet implemented');
500
+ }).toThrow(NotYetImplemented);
501
+ });
502
+ });
503
+ describe('Integration Scenarios', () => {
504
+ /**
505
+ * @requirement REQ-004.1
506
+ * @scenario Complete OAuth flow integration
507
+ * @given OAuth manager with full capabilities
508
+ * @when Provider is used for API calls
509
+ * @then All OAuth functionality works seamlessly
510
+ */
511
+ it('should integrate OAuth functionality end-to-end', async () => {
512
+ // Given: Full OAuth setup
513
+ const validToken = 'valid-oauth-token-123';
514
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(validToken);
515
+ vi.mocked(mockOAuthManager.isAuthenticated).mockResolvedValue(true);
516
+ // When: Using provider with complete OAuth integration
517
+ const _provider = new OpenAIProvider('', undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
518
+ // Then: Should fail with NotYetImplemented
519
+ expect(() => {
520
+ throw new NotYetImplemented('performEndToEndOAuthTest not yet implemented');
521
+ }).toThrow(NotYetImplemented);
522
+ });
523
+ /**
524
+ * @requirement REQ-006.1
525
+ * @scenario Migration from API key to OAuth
526
+ * @given Provider initially using API key
527
+ * @when OAuth manager is added later
528
+ * @then Seamlessly switches to OAuth precedence
529
+ */
530
+ it('should handle migration from API key to OAuth', async () => {
531
+ // Given: Initial API key setup
532
+ const apiKey = 'existing-api-key';
533
+ // When: OAuth manager is added
534
+ const oauthToken = 'new-oauth-token';
535
+ vi.mocked(mockOAuthManager.getToken).mockResolvedValue(oauthToken);
536
+ const _provider = new OpenAIProvider(apiKey, undefined, TEST_PROVIDER_CONFIG, mockOAuthManager);
537
+ // Then: Should fail with NotYetImplemented
538
+ expect(() => {
539
+ throw new NotYetImplemented('testMigrationScenario not yet implemented');
540
+ }).toThrow(NotYetImplemented);
541
+ });
542
+ });
543
+ });
544
+ //# sourceMappingURL=openai-oauth.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-oauth.spec.js","sourceRoot":"","sources":["../../../../src/providers/openai/openai-oauth.spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAW3E,qBAAqB;AACrB,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IACvB,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC;QACzC,IAAI,EAAE;YACJ,WAAW,EAAE;gBACX,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE;aAChB;SACF;QACD,MAAM,EAAE;YACN,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;SACd;KACF,CAAC,CAAC;CACJ,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,IAAI,gBAAkC,CAAC;IACvC,IAAI,WAA8B,CAAC;IAEnC,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,WAAW,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAEjC,wDAAwD;QACxD,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAElC,kDAAkD;QAClD,gBAAgB,GAAG;YACjB,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;YACjB,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE;YACxB,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;SACtB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,+BAA+B;QAC/B,OAAO,CAAC,GAAG,GAAG,WAAW,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC;;;;;;WAMG;QACH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;YAC7E,oCAAoC;YACpC,MAAM,SAAS,GAAG,aAAa,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,aAAa,CAAC;YAC3C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;YAE1E,yDAAyD;YACzD,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,SAAS,EACT,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,4EAA4E;YAC5E,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEnC,mEAAmE;YACnE,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH;;;;;;;WAOG;QACH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,iDAAiD;YACjD,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,aAAa,CAAC;YAC3C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;YAE1E,0CAA0C;YAC1C,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EAAE,gBAAgB;YACpB,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,oFAAoF;YACpF,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEnC,mEAAmE;YACnE,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;YAC3E,8BAA8B;YAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YAClC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;YAE1E,4FAA4F;YAC5F,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EAAE,gBAAgB;YACpB,SAAS,EAAE,oEAAoE;YAC/E,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,wFAAwF;YACxF,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEpC,4FAA4F;YAC5F,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACnE,mCAAmC;YACnC,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YAClC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAE7D,kFAAkF;YAClF,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EAAE,gBAAgB;YACpB,SAAS,EAAE,2CAA2C;YACtD,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,qGAAqG;YACrG,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEpC,8FAA8F;YAC9F,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;QACrD;;;;;;;WAOG;QACH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;YACtF,iDAAiD;YACjD,MAAM,WAAW,GAAG,mDAAmD,CAAC;YACxE,MAAM,UAAU,GAAG,sBAAsB,CAAC;YAE1C,kDAAkD;YAClD,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YACnE,MAAM,kBAAkB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEzD,gBAGD,CAAC,cAAc,GAAG,kBAAkB,CAAC;YAEtC,iFAAiF;YACjF,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EAAE,gBAAgB;YACpB,WAAW,EAAE,6BAA6B;YAC1C,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,8DAA8D;YAC9D,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEnC,qDAAqD;YACrD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,kDAAkD;YAClD,MAAM,MAAM,GAAG,yBAAyB,CAAC;YACzC,MAAM,UAAU,GAAG,oBAAoB,CAAC;YACxC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEnE,gEAAgE;YAChE,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,MAAM,EACN,mDAAmD,EACnD,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,yDAAyD;YACzD,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEnC,uDAAuD;YACvD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YAChF,4DAA4D;YAC5D,MAAM,UAAU,GAAG,sBAAsB,CAAC;YAC1C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEnE,4CAA4C;YAC5C,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EACF,mDAAmD,EACnD,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,yEAAyE;YACzE,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEnC,iEAAiE;YACjE,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,+CAA+C;YAC/C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,kBAAkB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAE1D,gBAGD,CAAC,cAAc,GAAG,kBAAkB,CAAC;YAEtC,8CAA8C;YAC9C,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EACF,mDAAmD,EACnD,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,sDAAsD;YACtD,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B;;;;;;;WAOG;QACH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,qCAAqC;YACrC,MAAM,YAAY,GAAG,mBAAmB,CAAC;YACzC,MAAM,QAAQ,GAAG,qBAAqB,CAAC;YACvC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC;iBACjC,qBAAqB,CAAC,YAAY,CAAC;iBACnC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;YACnC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAa,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAEtE,2CAA2C;YAC3C,MAAM,SAAS,GAAG,IAAI,cAAc,CAClC,EAAE,EACF,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,2CAA2C;YAC3C,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,IAAI,iBAAiB,CAAC,wCAAwC,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH;;;;;;;WAOG;QACH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,gDAAgD;YAChD,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;YACxE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAa,CAAC,CAAC,iBAAiB,CACzD,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAC5B,CAAC;YAEF,gDAAgD;YAChD,MAAM,SAAS,GAAG,IAAI,cAAc,CAClC,EAAE,EACF,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,2CAA2C;YAC3C,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,IAAI,iBAAiB,CAAC,0CAA0C,CAAC,CAAC;YAC1E,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;QAC7D;;;;;;WAMG;QACH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACrE,uCAAuC;YACvC,MAAM,WAAW,GAAG,mDAAmD,CAAC;YACxE,MAAM,UAAU,GAAG,sBAAsB,CAAC;YAC1C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEnE,kDAAkD;YAClD,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EACF,WAAW,EACX,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,mFAAmF;YACnF,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YACzE,6CAA6C;YAC7C,MAAM,iBAAiB,GAAG,2BAA2B,CAAC;YACtD,MAAM,UAAU,GAAG,iBAAiB,CAAC;YACrC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEnE,6DAA6D;YAC7D,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EACF,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,yFAAyF;YACzF,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEpC,yDAAyD;YACzD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,oCAAoC;YACpC,MAAM,SAAS,GAAG,6BAA6B,CAAC;YAChD,MAAM,UAAU,GAAG,iBAAiB,CAAC;YACrC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEnE,oDAAoD;YACpD,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EACF,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,gFAAgF;YAChF,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,aAAa,GAAG;gBACpB,mDAAmD;gBACnD,uCAAuC;gBACvC,yBAAyB;aAC1B,CAAC;YAEF,MAAM,UAAU,GAAG,sBAAsB,CAAC;YAC1C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEnE,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;gBACrC,0DAA0D;gBAC1D,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EACF,QAAQ,EACR,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;gBAEF,iDAAiD;gBACjD,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;gBACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,qDAAqD;YACrD,MAAM,MAAM,GAAG,yBAAyB,CAAC;YAEzC,gDAAgD;YAChD,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,MAAM,EACN,SAAS,EACT,oBAAoB,EACpB,SAAS,CACV,CAAC;YAEF,sFAAsF;YACtF,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC;;;;;;WAMG;QACH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,0CAA0C;YAC1C,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YAClC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;YAEtE,0DAA0D;YAC1D,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EAAE,gBAAgB;YACpB,mDAAmD,EAAE,oCAAoC;YACzF,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,mDAAmD;YACnD,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEnC,kCAAkC;YAClC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACrE,0CAA0C;YAC1C,MAAM,MAAM,GAAG,aAAa,CAAC;YAC7B,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;YAEtE,mDAAmD;YACnD,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,MAAM,EACN,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,6DAA6D;YAC7D,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEnC,mEAAmE;YACnE,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,mCAAmC;YACnC,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YAClC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAE7D,kEAAkE;YAClE,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EAAE,gBAAgB;YACpB,mDAAmD,EAAE,gBAAgB;YACrE,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,6EAA6E;YAC7E,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEpC,oDAAoD;YACpD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B;;;;;;;WAOG;QACH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,mCAAmC;YACnC,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,kBAAkB,CAAC;YAEhD,gDAAgD;YAChD,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EAAE,gBAAgB;YACpB,SAAS,EACT,oBAAoB,EACpB,SAAS,CACV,CAAC;YAEF,sEAAsE;YACtE,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,+BAA+B;YAC/B,MAAM,cAAc,GAAG,4BAA4B,CAAC;YACpD,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;YAEvE,8CAA8C;YAC9C,MAAM,SAAS,GAAG,IAAI,cAAc,CAClC,EAAE,EACF,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,2CAA2C;YAC3C,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,IAAI,iBAAiB,CACzB,8CAA8C,CAC/C,CAAC;YACJ,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH;;;;;;;WAOG;QACH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC7D,0CAA0C;YAC1C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CACpD,IAAI,KAAK,CAAC,2BAA2B,CAAC,CACvC,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,cAAc,CAAC;YAE5C,4BAA4B;YAC5B,MAAM,QAAQ,GAAG,IAAI,cAAc,CACjC,EAAE,EAAE,gBAAgB;YACpB,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,gGAAgG;YAChG,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;YACzD,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH;;;;;;;WAOG;QACH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,sCAAsC;YACtC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;YACxE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAa,CAAC,CAAC,iBAAiB,CACzD,IAAI,KAAK,CAAC,6BAA6B,CAAC,CACzC,CAAC;YAEF,qCAAqC;YACrC,MAAM,SAAS,GAAG,IAAI,cAAc,CAClC,EAAE,EACF,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,2CAA2C;YAC3C,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,IAAI,iBAAiB,CAAC,wCAAwC,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC;;;;;;WAMG;QACH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,0BAA0B;YAC1B,MAAM,UAAU,GAAG,uBAAuB,CAAC;YAC3C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YACnE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpE,uDAAuD;YACvD,MAAM,SAAS,GAAG,IAAI,cAAc,CAClC,EAAE,EACF,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,2CAA2C;YAC3C,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,IAAI,iBAAiB,CACzB,8CAA8C,CAC/C,CAAC;YACJ,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC7D,+BAA+B;YAC/B,MAAM,MAAM,GAAG,kBAAkB,CAAC;YAElC,+BAA+B;YAC/B,MAAM,UAAU,GAAG,iBAAiB,CAAC;YACrC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEnE,MAAM,SAAS,GAAG,IAAI,cAAc,CAClC,MAAM,EACN,SAAS,EACT,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;YAEF,2CAA2C;YAC3C,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,IAAI,iBAAiB,CACzB,2CAA2C,CAC5C,CAAC;YACJ,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -15,3 +15,50 @@ export interface ProviderToolCall {
15
15
  arguments: string;
16
16
  };
17
17
  }
18
+ export interface ProviderCapabilities {
19
+ supportsStreaming: boolean;
20
+ supportsTools: boolean;
21
+ supportsVision: boolean;
22
+ maxTokens: number;
23
+ supportedFormats: string[];
24
+ hasModelSelection?: boolean;
25
+ hasApiKeyConfig?: boolean;
26
+ hasBaseUrlConfig?: boolean;
27
+ supportsPaidMode?: boolean;
28
+ }
29
+ export interface ProviderContext {
30
+ providerName: string;
31
+ currentModel: string;
32
+ toolFormat: string;
33
+ isPaidMode: boolean;
34
+ capabilities: ProviderCapabilities;
35
+ sessionStartTime: number;
36
+ }
37
+ export interface ToolCall {
38
+ provider: string;
39
+ name: string;
40
+ arguments: unknown;
41
+ id: string;
42
+ }
43
+ export interface ProviderPerformanceMetrics {
44
+ providerName: string;
45
+ totalRequests: number;
46
+ totalTokens: number;
47
+ averageLatency: number;
48
+ timeToFirstToken: number | null;
49
+ tokensPerSecond: number;
50
+ chunksReceived: number;
51
+ errorRate: number;
52
+ errors: Array<{
53
+ timestamp: number;
54
+ duration: number;
55
+ error: string;
56
+ }>;
57
+ }
58
+ export interface ProviderComparison {
59
+ provider1: string;
60
+ provider2: string;
61
+ capabilities: Record<string, ProviderCapabilities>;
62
+ compatibility: number;
63
+ recommendation: string;
64
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export interface GitStats {
7
+ linesAdded: number;
8
+ linesRemoved: number;
9
+ filesChanged: number;
10
+ }
11
+ /**
12
+ * Service for tracking git statistics during file operations.
13
+ * This service is optional and can be set by the CLI package when logging is enabled.
14
+ */
15
+ export interface IGitStatsService {
16
+ /**
17
+ * Track file edit statistics
18
+ * @param filePath Path to the file being edited
19
+ * @param oldContent Original file content
20
+ * @param newContent New file content after edit
21
+ * @returns Git statistics or null if tracking is disabled
22
+ */
23
+ trackFileEdit(filePath: string, oldContent: string, newContent: string): Promise<GitStats | null>;
24
+ }
25
+ /**
26
+ * Set the git stats service implementation
27
+ */
28
+ export declare function setGitStatsService(service: IGitStatsService | null): void;
29
+ /**
30
+ * Get the current git stats service
31
+ */
32
+ export declare function getGitStatsService(): IGitStatsService | null;