jiva-core 0.3.41 → 0.3.42-dev.b6b238d

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 (71) hide show
  1. package/README.md +28 -7
  2. package/dist/code/agent.d.ts +4 -0
  3. package/dist/code/agent.d.ts.map +1 -1
  4. package/dist/code/agent.js +70 -18
  5. package/dist/code/agent.js.map +1 -1
  6. package/dist/core/agent-interface.d.ts +8 -0
  7. package/dist/core/agent-interface.d.ts.map +1 -1
  8. package/dist/core/agent-spawner.d.ts.map +1 -1
  9. package/dist/core/agent-spawner.js +2 -1
  10. package/dist/core/agent-spawner.js.map +1 -1
  11. package/dist/core/config.d.ts +56 -0
  12. package/dist/core/config.d.ts.map +1 -1
  13. package/dist/core/config.js +4 -0
  14. package/dist/core/config.js.map +1 -1
  15. package/dist/core/conversation-manager.d.ts +4 -3
  16. package/dist/core/conversation-manager.d.ts.map +1 -1
  17. package/dist/core/conversation-manager.js +16 -8
  18. package/dist/core/conversation-manager.js.map +1 -1
  19. package/dist/core/dual-agent.d.ts +3 -0
  20. package/dist/core/dual-agent.d.ts.map +1 -1
  21. package/dist/core/dual-agent.js +15 -4
  22. package/dist/core/dual-agent.js.map +1 -1
  23. package/dist/core/worker-agent.d.ts.map +1 -1
  24. package/dist/core/worker-agent.js +32 -0
  25. package/dist/core/worker-agent.js.map +1 -1
  26. package/dist/core/workspace.d.ts +6 -0
  27. package/dist/core/workspace.d.ts.map +1 -1
  28. package/dist/core/workspace.js +18 -0
  29. package/dist/core/workspace.js.map +1 -1
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/interfaces/cli/index.js +7 -7
  35. package/dist/interfaces/cli/index.js.map +1 -1
  36. package/dist/interfaces/cli/repl.d.ts.map +1 -1
  37. package/dist/interfaces/cli/repl.js +21 -3
  38. package/dist/interfaces/cli/repl.js.map +1 -1
  39. package/dist/interfaces/cli/setup-wizard.d.ts +5 -3
  40. package/dist/interfaces/cli/setup-wizard.d.ts.map +1 -1
  41. package/dist/interfaces/cli/setup-wizard.js +265 -288
  42. package/dist/interfaces/cli/setup-wizard.js.map +1 -1
  43. package/dist/interfaces/http/middleware/auth.d.ts.map +1 -1
  44. package/dist/interfaces/http/middleware/auth.js +2 -1
  45. package/dist/interfaces/http/middleware/auth.js.map +1 -1
  46. package/dist/interfaces/http/routes/chat.d.ts.map +1 -1
  47. package/dist/interfaces/http/routes/chat.js +20 -0
  48. package/dist/interfaces/http/routes/chat.js.map +1 -1
  49. package/dist/interfaces/http/session-manager.d.ts +6 -0
  50. package/dist/interfaces/http/session-manager.d.ts.map +1 -1
  51. package/dist/interfaces/http/session-manager.js +14 -5
  52. package/dist/interfaces/http/session-manager.js.map +1 -1
  53. package/dist/interfaces/http/websocket-handler.d.ts.map +1 -1
  54. package/dist/interfaces/http/websocket-handler.js +12 -0
  55. package/dist/interfaces/http/websocket-handler.js.map +1 -1
  56. package/dist/models/krutrim.d.ts +8 -66
  57. package/dist/models/krutrim.d.ts.map +1 -1
  58. package/dist/models/krutrim.js +7 -307
  59. package/dist/models/krutrim.js.map +1 -1
  60. package/dist/models/model-client.d.ts +95 -0
  61. package/dist/models/model-client.d.ts.map +1 -0
  62. package/dist/models/model-client.js +317 -0
  63. package/dist/models/model-client.js.map +1 -0
  64. package/dist/models/orchestrator.d.ts +9 -8
  65. package/dist/models/orchestrator.d.ts.map +1 -1
  66. package/dist/models/orchestrator.js +2 -1
  67. package/dist/models/orchestrator.js.map +1 -1
  68. package/dist/storage/types.d.ts +1 -0
  69. package/dist/storage/types.d.ts.map +1 -1
  70. package/dist/storage/types.js.map +1 -1
  71. package/package.json +1 -1
@@ -1,311 +1,11 @@
1
1
  /**
2
- * Krutrim API Client
2
+ * @deprecated
3
+ * This file is kept for backward compatibility only.
4
+ * Import from './model-client.js' instead.
3
5
  *
4
- * Handles communication with Krutrim Cloud API for both gpt-oss-120b and Llama-4-Maverick-17B models.
5
- * Implements Harmony format for gpt-oss-120b and standard format for multimodal model.
6
+ * KrutrimModel → ModelClient
7
+ * KrutrimConfig ModelClientConfig
8
+ * createKrutrimModel → createModelClient
6
9
  */
7
- import { formatMessagesForHarmony, parseHarmonyResponse } from './harmony.js';
8
- import { ModelError } from '../utils/errors.js';
9
- import { logger } from '../utils/logger.js';
10
- export class KrutrimModel {
11
- config;
12
- constructor(config) {
13
- this.config = config;
14
- }
15
- supportsVision() {
16
- return this.config.type === 'multimodal';
17
- }
18
- supportsToolCalling() {
19
- // Both the reasoning model and dedicated tool-calling model support tool calling
20
- return this.config.type === 'reasoning' || this.config.type === 'tool-calling';
21
- }
22
- async chat(options) {
23
- // 'tool-calling' models are treated as reasoning models for tool-call formatting purposes
24
- const isReasoningModel = this.config.type === 'reasoning' || this.config.type === 'tool-calling';
25
- // Retry logic for transient errors (WAF/rate limiting/server errors)
26
- const maxRetries = 4;
27
- let lastError = null;
28
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
29
- if (attempt > 0) {
30
- await new Promise(resolve => setTimeout(resolve, this._lastRetryWait ?? 2000));
31
- }
32
- try {
33
- return await this.attemptChat(options, isReasoningModel);
34
- }
35
- catch (error) {
36
- lastError = error;
37
- // Retry on transient errors: 403 (WAF), 429 (rate limit), 500/502/503/504 (server errors)
38
- if (error instanceof ModelError) {
39
- const is429 = error.message.includes('(429)');
40
- const shouldRetry = error.message.includes('(403)') || // WAF blocking
41
- is429 || // Rate limiting
42
- error.message.includes('(500)') || // Internal server error
43
- error.message.includes('(502)') || // Bad gateway
44
- error.message.includes('(503)') || // Service unavailable
45
- error.message.includes('(504)'); // Gateway timeout
46
- if (!shouldRetry || attempt === maxRetries) {
47
- throw error;
48
- }
49
- // Log the error type for debugging
50
- let errorType = 'Unknown error';
51
- if (error.message.includes('(403)'))
52
- errorType = '403 Access Denied (WAF)';
53
- else if (is429)
54
- errorType = '429 Rate Limited';
55
- else if (error.message.includes('(500)'))
56
- errorType = '500 Internal Server Error';
57
- else if (error.message.includes('(502)'))
58
- errorType = '502 Bad Gateway';
59
- else if (error.message.includes('(503)'))
60
- errorType = '503 Service Unavailable';
61
- else if (error.message.includes('(504)'))
62
- errorType = '504 Gateway Timeout';
63
- // For 429s, parse the actual retry-after time from the error message.
64
- // Groq returns: "Please try again in 8.53s."
65
- if (is429) {
66
- const match = error.message.match(/try again in (\d+(?:\.\d+)?)\s*s/i);
67
- const retryAfterMs = match ? Math.ceil(parseFloat(match[1]) * 1000) + 500 : null;
68
- // Use parsed time, falling back to capped exponential backoff
69
- const exponential = Math.min(Math.pow(2, attempt) * 1000, 30_000);
70
- this._lastRetryWait = retryAfterMs ?? exponential;
71
- logger.warn(`Got ${errorType}, will retry in ${(this._lastRetryWait / 1000).toFixed(1)}s (attempt ${attempt + 1}/${maxRetries + 1})...`);
72
- }
73
- else {
74
- const waitTime = Math.min(Math.pow(2, attempt) * 1000, 30_000);
75
- this._lastRetryWait = waitTime;
76
- logger.warn(`Got ${errorType}, will retry in ${waitTime / 1000}s (attempt ${attempt + 1}/${maxRetries + 1})...`);
77
- }
78
- }
79
- else {
80
- throw error;
81
- }
82
- }
83
- }
84
- throw lastError;
85
- }
86
- /** Retry wait time in ms, set dynamically based on API hint or exponential backoff. */
87
- _lastRetryWait;
88
- async attemptChat(options, isReasoningModel) {
89
- try {
90
- let messages;
91
- let tools;
92
- const useHarmony = this.config.useHarmonyFormat ?? false;
93
- if (isReasoningModel && options.tools && options.tools.length > 0) {
94
- if (useHarmony) {
95
- // Convert to Harmony format (Krutrim-specific)
96
- // Tools are embedded in the developer message
97
- tools = options.tools.map(t => ({
98
- name: t.name,
99
- description: t.description,
100
- parameters: t.parameters,
101
- }));
102
- messages = formatMessagesForHarmony(options.messages, tools);
103
- }
104
- else {
105
- // Standard OpenAI format - tools sent separately
106
- messages = options.messages;
107
- }
108
- }
109
- else {
110
- messages = options.messages;
111
- }
112
- // All OpenAI-compatible APIs support standard roles: system, user, assistant, tool
113
- // Convert 'developer' role to 'system' for API compatibility
114
- const apiMessages = messages.map((msg) => {
115
- if (msg.role === 'developer') {
116
- return { ...msg, role: 'system' };
117
- }
118
- return msg;
119
- });
120
- // ── Reasoning effort ────────────────────────────────────────────────────
121
- // Per-call value takes precedence over model-level default.
122
- const effort = options.reasoningEffort ?? this.config.defaultReasoningEffort;
123
- const strategy = this.config.reasoningEffortStrategy ?? 'both';
124
- // System-prompt injection: prepend "Reasoning: <level>" as the very first
125
- // system message. gpt-oss-120b understands this on any provider — it's the
126
- // official fallback for Krutrim/self-hosted endpoints that strip unknown
127
- // request body params.
128
- if (effort && isReasoningModel && (strategy === 'system_prompt' || strategy === 'both')) {
129
- apiMessages.unshift({ role: 'system', content: `Reasoning: ${effort}` });
130
- }
131
- const requestBody = {
132
- model: options.model || this.config.model,
133
- messages: apiMessages,
134
- temperature: options.temperature ?? 0.2, // Lower default to reduce hallucination
135
- };
136
- if (options.maxTokens) {
137
- requestBody.max_tokens = options.maxTokens;
138
- }
139
- // API param: native Groq support; silently ignored by providers that don't implement it.
140
- if (effort && isReasoningModel && (strategy === 'api_param' || strategy === 'both')) {
141
- requestBody.reasoning_effort = effort;
142
- }
143
- // include_reasoning: request thinking tokens in the response (Groq-specific).
144
- // When present, tokens appear in choice.message.reasoning and are logged below.
145
- if (this.config.includeReasoning && isReasoningModel) {
146
- requestBody.include_reasoning = true;
147
- }
148
- // ────────────────────────────────────────────────────────────────────────
149
- // Send tools in standard OpenAI format if not using Harmony
150
- if (!useHarmony && isReasoningModel && options.tools && options.tools.length > 0) {
151
- requestBody.tools = options.tools.map(t => ({
152
- type: 'function',
153
- function: {
154
- name: t.name,
155
- description: t.description,
156
- parameters: t.parameters,
157
- },
158
- }));
159
- requestBody.tool_choice = 'auto';
160
- }
161
- // Log full request for debugging
162
- logger.debug('API Request:', JSON.stringify(requestBody, null, 2));
163
- logger.debug('Request size:', JSON.stringify(requestBody).length, 'bytes');
164
- logger.debug('Message count:', requestBody.messages.length);
165
- const response = await fetch(this.config.endpoint, {
166
- method: 'POST',
167
- headers: {
168
- 'Content-Type': 'application/json',
169
- 'Authorization': `Bearer ${this.config.apiKey}`,
170
- 'User-Agent': 'Jiva/0.1.0',
171
- 'Accept': 'application/json',
172
- },
173
- body: JSON.stringify(requestBody),
174
- });
175
- if (!response.ok) {
176
- const errorText = await response.text();
177
- logger.error(`API Error Response (${response.status}):`, errorText);
178
- logger.debug('Request that failed:', JSON.stringify(requestBody, null, 2));
179
- // Write failing request to file for debugging
180
- if (response.status === 403) {
181
- try {
182
- const fs = await import('fs');
183
- const debugPath = '/tmp/jiva_failed_request.json';
184
- await fs.promises.writeFile(debugPath, JSON.stringify(requestBody, null, 2));
185
- logger.warn(`Failing request saved to: ${debugPath}`);
186
- }
187
- catch (e) {
188
- // Ignore file write errors
189
- }
190
- }
191
- throw new ModelError(`API error (${response.status}): ${errorText}`, this.config.model);
192
- }
193
- const data = await response.json();
194
- logger.debug('API Response:', JSON.stringify(data, null, 2));
195
- if (!data.choices || data.choices.length === 0) {
196
- throw new ModelError('No choices in response', this.config.model);
197
- }
198
- const choice = data.choices[0];
199
- const messageContent = choice.message?.content || '';
200
- // Log reasoning tokens when include_reasoning=true (Groq returns them in
201
- // choice.message.reasoning). Useful for debugging model "thinking" quality.
202
- const reasoningTokens = choice.message?.reasoning;
203
- if (reasoningTokens) {
204
- logger.debug(`[Model reasoning] ${reasoningTokens.substring(0, 2000)}${reasoningTokens.length > 2000 ? '…' : ''}`);
205
- }
206
- // Parse response based on format used
207
- if (useHarmony && isReasoningModel && options.tools && options.tools.length > 0) {
208
- // Parse Harmony format response (Krutrim-specific)
209
- const parsed = parseHarmonyResponse(messageContent);
210
- return {
211
- content: parsed.final || parsed.commentary || messageContent,
212
- toolCalls: parsed.toolCalls.length > 0 ? parsed.toolCalls : undefined,
213
- usage: data.usage ? {
214
- promptTokens: data.usage.prompt_tokens || 0,
215
- completionTokens: data.usage.completion_tokens || 0,
216
- totalTokens: data.usage.total_tokens || 0,
217
- } : undefined,
218
- raw: {
219
- ...data,
220
- parsedHarmony: parsed,
221
- },
222
- };
223
- }
224
- else {
225
- // Standard OpenAI format response
226
- // Check for tool calls in standard format
227
- const toolCalls = choice.message?.tool_calls;
228
- return {
229
- content: messageContent,
230
- toolCalls: toolCalls && toolCalls.length > 0 ? toolCalls : undefined,
231
- usage: data.usage ? {
232
- promptTokens: data.usage.prompt_tokens || 0,
233
- completionTokens: data.usage.completion_tokens || 0,
234
- totalTokens: data.usage.total_tokens || 0,
235
- } : undefined,
236
- raw: data,
237
- };
238
- }
239
- }
240
- catch (error) {
241
- if (error instanceof ModelError) {
242
- throw error;
243
- }
244
- throw new ModelError(`Failed to communicate with API: ${error instanceof Error ? error.message : String(error)}`, this.config.model);
245
- }
246
- }
247
- /**
248
- * Helper method for vision tasks using multimodal model
249
- */
250
- async describeImage(imageUrl, prompt) {
251
- if (!this.supportsVision()) {
252
- throw new ModelError('This model does not support vision tasks', this.config.model);
253
- }
254
- const response = await this.chat({
255
- model: this.config.model,
256
- messages: [
257
- {
258
- role: 'user',
259
- content: [
260
- {
261
- type: 'text',
262
- text: prompt || 'Describe this image in detail.',
263
- },
264
- {
265
- type: 'image_url',
266
- image_url: {
267
- url: imageUrl,
268
- },
269
- },
270
- ],
271
- },
272
- ],
273
- });
274
- return response.content;
275
- }
276
- /**
277
- * Test connectivity to the API endpoint
278
- * Returns true if connection is successful, throws error otherwise
279
- */
280
- async testConnectivity() {
281
- const startTime = Date.now();
282
- try {
283
- logger.debug(`Testing connectivity to ${this.config.endpoint}...`);
284
- // Simple test request with minimal tokens and low reasoning effort (it's just a ping)
285
- const testResponse = await this.chat({
286
- messages: [{ role: 'user', content: 'test' }],
287
- temperature: 0,
288
- maxTokens: 5,
289
- reasoningEffort: 'low',
290
- });
291
- const latency = Date.now() - startTime;
292
- logger.debug(`Connectivity test passed in ${latency}ms`);
293
- return { success: true, latency };
294
- }
295
- catch (error) {
296
- const errorMessage = error instanceof Error ? error.message : String(error);
297
- logger.error(`Connectivity test failed: ${errorMessage}`);
298
- return {
299
- success: false,
300
- error: errorMessage,
301
- };
302
- }
303
- }
304
- }
305
- /**
306
- * Factory function to create Krutrim model instances
307
- */
308
- export function createKrutrimModel(config) {
309
- return new KrutrimModel(config);
310
- }
10
+ export { ModelClient as KrutrimModel, createModelClient as createKrutrimModel, } from './model-client.js';
311
11
  //# sourceMappingURL=krutrim.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"krutrim.js","sourceRoot":"","sources":["../../src/models/krutrim.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"krutrim.js","sourceRoot":"","sources":["../../src/models/krutrim.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,WAAW,IAAI,YAAY,EAC3B,iBAAiB,IAAI,kBAAkB,GACxC,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * OpenAI-Compatible Model Client
3
+ *
4
+ * Generic client for any OpenAI-compatible chat completion API.
5
+ * Supports: Krutrim, Groq, Sarvam, OpenAI, and any other provider
6
+ * that exposes a /v1/chat/completions endpoint.
7
+ *
8
+ * Provider-specific behaviour is controlled entirely through config flags:
9
+ * - useHarmonyFormat → Krutrim gpt-oss-120b (Harmony tool format)
10
+ * - reasoningEffortStrategy → how reasoning effort is communicated
11
+ * - defaultMaxTokens → required for reasoning models (e.g. Sarvam-105B)
12
+ */
13
+ import { IModel, ChatCompletionOptions, ModelResponse } from './base.js';
14
+ export interface ModelClientConfig {
15
+ endpoint: string;
16
+ apiKey: string;
17
+ model: string;
18
+ defaultModel?: string;
19
+ type: 'reasoning' | 'multimodal' | 'tool-calling';
20
+ /**
21
+ * Use Harmony format for tool calling.
22
+ * Only needed for Krutrim's gpt-oss-120b model.
23
+ * Default: false (standard OpenAI format)
24
+ */
25
+ useHarmonyFormat?: boolean;
26
+ /**
27
+ * Default reasoning effort for all calls made through this model instance.
28
+ * Can be overridden per-call via ChatCompletionOptions.reasoningEffort.
29
+ * Sensible defaults: 'high' for reasoning models, 'medium' for tool-calling models.
30
+ */
31
+ defaultReasoningEffort?: 'low' | 'medium' | 'high';
32
+ /**
33
+ * How to communicate reasoning effort to the model.
34
+ *
35
+ * 'api_param' — send only as the `reasoning_effort` request body field.
36
+ * Works natively on Groq and Sarvam.
37
+ * 'system_prompt' — inject only as a leading system message: "Reasoning: <level>".
38
+ * Required for gpt-oss-120b on Krutrim (strips unknown params).
39
+ * 'both' — do both (safe default for unknown providers).
40
+ *
41
+ * Provider recommendations:
42
+ * Krutrim → 'system_prompt'
43
+ * Groq → 'api_param'
44
+ * Sarvam → 'api_param'
45
+ * Other → 'both'
46
+ *
47
+ * Default: 'both'
48
+ */
49
+ reasoningEffortStrategy?: 'api_param' | 'system_prompt' | 'both';
50
+ /**
51
+ * Request reasoning tokens in the response body (Groq-specific: `include_reasoning`).
52
+ * When true, the model's thinking tokens are logged at debug level.
53
+ * Has no effect on providers that do not support the field.
54
+ * Note: Sarvam always returns reasoning_content regardless of this flag.
55
+ * Default: false
56
+ */
57
+ includeReasoning?: boolean;
58
+ /**
59
+ * Default max tokens for completion.
60
+ *
61
+ * REQUIRED for reasoning models like Sarvam-105B that spend completion tokens
62
+ * on their thinking chain before producing output. Without a sufficient budget
63
+ * the model exhausts the default limit (~2048) reasoning and returns empty content.
64
+ *
65
+ * Recommended: 8192 for Sarvam-105B, unset for Groq/Krutrim.
66
+ */
67
+ defaultMaxTokens?: number;
68
+ }
69
+ export declare class ModelClient implements IModel {
70
+ private config;
71
+ constructor(config: ModelClientConfig);
72
+ supportsVision(): boolean;
73
+ supportsToolCalling(): boolean;
74
+ chat(options: ChatCompletionOptions): Promise<ModelResponse>;
75
+ /** Retry wait time in ms, set dynamically based on API hint or exponential backoff. */
76
+ private _lastRetryWait?;
77
+ private attemptChat;
78
+ /**
79
+ * Helper method for vision tasks using multimodal model
80
+ */
81
+ describeImage(imageUrl: string, prompt?: string): Promise<string>;
82
+ /**
83
+ * Test connectivity to the API endpoint
84
+ */
85
+ testConnectivity(): Promise<{
86
+ success: boolean;
87
+ error?: string;
88
+ latency?: number;
89
+ }>;
90
+ }
91
+ /**
92
+ * Factory function to create a model client instance
93
+ */
94
+ export declare function createModelClient(config: ModelClientConfig): ModelClient;
95
+ //# sourceMappingURL=model-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-client.d.ts","sourceRoot":"","sources":["../../src/models/model-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAE,qBAAqB,EAAE,aAAa,EAAW,MAAM,WAAW,CAAC;AAUlF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,cAAc,CAAC;IAElD;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAEnD;;;;;;;;;;;;;;;;OAgBG;IACH,uBAAuB,CAAC,EAAE,WAAW,GAAG,eAAe,GAAG,MAAM,CAAC;IAEjE;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,WAAY,YAAW,MAAM;IACxC,OAAO,CAAC,MAAM,CAAoB;gBAEtB,MAAM,EAAE,iBAAiB;IAIrC,cAAc,IAAI,OAAO;IAIzB,mBAAmB,IAAI,OAAO;IAKxB,IAAI,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC;IAiElE,uFAAuF;IACvF,OAAO,CAAC,cAAc,CAAC,CAAS;YAElB,WAAW;IAiMzB;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCvE;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CA2B1F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAExE"}