lettactl 0.2.1 → 0.3.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 (46) hide show
  1. package/README.md +57 -0
  2. package/dist/commands/apply.d.ts.map +1 -1
  3. package/dist/commands/apply.js +20 -4
  4. package/dist/commands/apply.js.map +1 -1
  5. package/dist/commands/validate.d.ts +4 -0
  6. package/dist/commands/validate.d.ts.map +1 -0
  7. package/dist/commands/validate.js +31 -0
  8. package/dist/commands/validate.js.map +1 -0
  9. package/dist/index.js +2 -4
  10. package/dist/index.js.map +1 -1
  11. package/dist/lib/agent-manager.d.ts.map +1 -1
  12. package/dist/lib/agent-manager.js +19 -6
  13. package/dist/lib/agent-manager.js.map +1 -1
  14. package/dist/lib/block-manager.d.ts +4 -0
  15. package/dist/lib/block-manager.d.ts.map +1 -1
  16. package/dist/lib/block-manager.js +8 -0
  17. package/dist/lib/block-manager.js.map +1 -1
  18. package/dist/lib/bucket-config-validator.d.ts +20 -0
  19. package/dist/lib/bucket-config-validator.d.ts.map +1 -0
  20. package/dist/lib/bucket-config-validator.js +95 -0
  21. package/dist/lib/bucket-config-validator.js.map +1 -0
  22. package/dist/lib/config-validators.d.ts +62 -0
  23. package/dist/lib/config-validators.d.ts.map +1 -0
  24. package/dist/lib/config-validators.js +380 -0
  25. package/dist/lib/config-validators.js.map +1 -0
  26. package/dist/lib/diff-engine.d.ts +5 -0
  27. package/dist/lib/diff-engine.d.ts.map +1 -1
  28. package/dist/lib/diff-engine.js +47 -14
  29. package/dist/lib/diff-engine.js.map +1 -1
  30. package/dist/lib/file-content-tracker.d.ts +5 -2
  31. package/dist/lib/file-content-tracker.d.ts.map +1 -1
  32. package/dist/lib/file-content-tracker.js +20 -2
  33. package/dist/lib/file-content-tracker.js.map +1 -1
  34. package/dist/lib/fleet-parser.d.ts +7 -1
  35. package/dist/lib/fleet-parser.d.ts.map +1 -1
  36. package/dist/lib/fleet-parser.js +24 -3
  37. package/dist/lib/fleet-parser.js.map +1 -1
  38. package/dist/lib/storage-backend.d.ts +47 -0
  39. package/dist/lib/storage-backend.d.ts.map +1 -0
  40. package/dist/lib/storage-backend.js +280 -0
  41. package/dist/lib/storage-backend.js.map +1 -0
  42. package/dist/lib/storage-error-handler.d.ts +44 -0
  43. package/dist/lib/storage-error-handler.d.ts.map +1 -0
  44. package/dist/lib/storage-error-handler.js +176 -0
  45. package/dist/lib/storage-error-handler.js.map +1 -0
  46. package/package.json +3 -1
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Comprehensive YAML configuration validation system
3
+ * Composition-based validators for different config sections
4
+ */
5
+ /**
6
+ * Main orchestrator for fleet configuration validation
7
+ */
8
+ export declare class FleetConfigValidator {
9
+ static validate(config: any): void;
10
+ private static validateStructure;
11
+ private static validateAgents;
12
+ }
13
+ /**
14
+ * Validator for individual agent configurations
15
+ */
16
+ export declare class AgentValidator {
17
+ static validate(agent: any): void;
18
+ private static validateStructure;
19
+ private static validateRequiredFields;
20
+ private static validateUnknownFields;
21
+ private static validateEmbedding;
22
+ private static validateSharedBlockReferences;
23
+ }
24
+ /**
25
+ * Validator for system prompt configurations
26
+ */
27
+ export declare class SystemPromptValidator {
28
+ static validate(prompt: any): void;
29
+ }
30
+ /**
31
+ * Validator for memory blocks
32
+ */
33
+ export declare class MemoryBlockValidator {
34
+ static validate(blocks: any): void;
35
+ private static validateBlock;
36
+ }
37
+ /**
38
+ * Validator for tools configuration
39
+ */
40
+ export declare class ToolsValidator {
41
+ static validate(tools: any): void;
42
+ }
43
+ /**
44
+ * Validator for folders configuration
45
+ */
46
+ export declare class FoldersValidator {
47
+ static validate(folders: any): void;
48
+ private static validateFolder;
49
+ }
50
+ /**
51
+ * Validator for shared blocks configuration
52
+ */
53
+ export declare class SharedBlockValidator {
54
+ static validate(blocks: any): void;
55
+ }
56
+ /**
57
+ * Validator for LLM configuration
58
+ */
59
+ export declare class LLMConfigValidator {
60
+ static validate(config: any): void;
61
+ }
62
+ //# sourceMappingURL=config-validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-validators.d.ts","sourceRoot":"","sources":["../../src/lib/config-validators.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;IAYlC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IA4BhC,OAAO,CAAC,MAAM,CAAC,cAAc;CAoB9B;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IAiCjC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAMhC,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAmCrC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAiBpC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAMhC,OAAO,CAAC,MAAM,CAAC,6BAA6B;CAW7C;AAED;;GAEG;AACH,qBAAa,qBAAqB;IAChC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;CAoDnC;AAED;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;IAyBlC,OAAO,CAAC,MAAM,CAAC,aAAa;CAuD7B;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;CAWlC;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAcnC,OAAO,CAAC,MAAM,CAAC,cAAc;CAmB9B;AAED;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;CAanC;AAED;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;CAsCnC"}
@@ -0,0 +1,380 @@
1
+ "use strict";
2
+ /**
3
+ * Comprehensive YAML configuration validation system
4
+ * Composition-based validators for different config sections
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.LLMConfigValidator = exports.SharedBlockValidator = exports.FoldersValidator = exports.ToolsValidator = exports.MemoryBlockValidator = exports.SystemPromptValidator = exports.AgentValidator = exports.FleetConfigValidator = void 0;
8
+ const bucket_config_validator_1 = require("./bucket-config-validator");
9
+ /**
10
+ * Main orchestrator for fleet configuration validation
11
+ */
12
+ class FleetConfigValidator {
13
+ static validate(config) {
14
+ this.validateStructure(config);
15
+ if (config.shared_blocks) {
16
+ SharedBlockValidator.validate(config.shared_blocks);
17
+ }
18
+ if (config.agents) {
19
+ this.validateAgents(config.agents);
20
+ }
21
+ }
22
+ static validateStructure(config) {
23
+ if (!config || typeof config !== 'object') {
24
+ throw new Error('Invalid fleet configuration. Expected YAML object with agents array.\n' +
25
+ 'Example:\n' +
26
+ 'agents:\n' +
27
+ ' - name: my-agent\n' +
28
+ ' system_prompt:\n' +
29
+ ' value: "You are helpful"');
30
+ }
31
+ if (!config.agents || !Array.isArray(config.agents)) {
32
+ throw new Error('Fleet configuration must have an "agents" array.\n' +
33
+ 'Example:\n' +
34
+ 'agents:\n' +
35
+ ' - name: my-agent\n' +
36
+ ' system_prompt:\n' +
37
+ ' value: "You are helpful"');
38
+ }
39
+ if (config.agents.length === 0) {
40
+ throw new Error('Fleet configuration must have at least one agent.');
41
+ }
42
+ }
43
+ static validateAgents(agents) {
44
+ // Check for duplicate agent names
45
+ const agentNames = new Set();
46
+ agents.forEach((agent, index) => {
47
+ try {
48
+ AgentValidator.validate(agent);
49
+ // Check name uniqueness
50
+ if (agent.name) {
51
+ if (agentNames.has(agent.name)) {
52
+ throw new Error(`Duplicate agent name "${agent.name}". Agent names must be unique.`);
53
+ }
54
+ agentNames.add(agent.name);
55
+ }
56
+ }
57
+ catch (error) {
58
+ throw new Error(`Agent ${index + 1}: ${error.message}`);
59
+ }
60
+ });
61
+ }
62
+ }
63
+ exports.FleetConfigValidator = FleetConfigValidator;
64
+ /**
65
+ * Validator for individual agent configurations
66
+ */
67
+ class AgentValidator {
68
+ static validate(agent) {
69
+ this.validateStructure(agent);
70
+ this.validateUnknownFields(agent);
71
+ this.validateRequiredFields(agent);
72
+ // Validate sub-components
73
+ SystemPromptValidator.validate(agent.system_prompt);
74
+ if (agent.memory_blocks) {
75
+ MemoryBlockValidator.validate(agent.memory_blocks);
76
+ }
77
+ if (agent.tools) {
78
+ ToolsValidator.validate(agent.tools);
79
+ }
80
+ if (agent.folders) {
81
+ FoldersValidator.validate(agent.folders);
82
+ }
83
+ if (agent.llm_config) {
84
+ LLMConfigValidator.validate(agent.llm_config);
85
+ }
86
+ if (agent.embedding) {
87
+ this.validateEmbedding(agent.embedding);
88
+ }
89
+ if (agent.shared_blocks) {
90
+ this.validateSharedBlockReferences(agent.shared_blocks);
91
+ }
92
+ }
93
+ static validateStructure(agent) {
94
+ if (!agent || typeof agent !== 'object') {
95
+ throw new Error('Agent configuration must be an object.');
96
+ }
97
+ }
98
+ static validateRequiredFields(agent) {
99
+ const requiredFields = ['name', 'description', 'system_prompt', 'llm_config'];
100
+ const missing = requiredFields.filter(field => !(field in agent));
101
+ if (missing.length > 0) {
102
+ throw new Error(`Missing required fields: ${missing.join(', ')}\n` +
103
+ 'Required fields: name, description, system_prompt, llm_config\n' +
104
+ 'Example:\n' +
105
+ '- name: my-agent\n' +
106
+ ' description: "What this agent does"\n' +
107
+ ' llm_config:\n' +
108
+ ' model: "google_ai/gemini-2.5-pro"\n' +
109
+ ' context_window: 32000\n' +
110
+ ' system_prompt:\n' +
111
+ ' value: "You are helpful"');
112
+ }
113
+ // Validate name is non-empty string
114
+ if (!agent.name || typeof agent.name !== 'string' || agent.name.trim() === '') {
115
+ throw new Error('Agent name must be a non-empty string.');
116
+ }
117
+ // Validate agent name format (no special characters that could break system)
118
+ if (!/^[a-zA-Z0-9_-]+$/.test(agent.name)) {
119
+ throw new Error('Agent name can only contain letters, numbers, hyphens, and underscores.');
120
+ }
121
+ // Validate description is non-empty string
122
+ if (!agent.description || typeof agent.description !== 'string' || agent.description.trim() === '') {
123
+ throw new Error('Agent description must be a non-empty string.');
124
+ }
125
+ }
126
+ static validateUnknownFields(agent) {
127
+ const allowedFields = [
128
+ 'name', 'description', 'system_prompt', 'llm_config',
129
+ 'tools', 'memory_blocks', 'folders', 'embedding', 'shared_blocks'
130
+ ];
131
+ const unknownFields = Object.keys(agent).filter(field => !allowedFields.includes(field));
132
+ if (unknownFields.length > 0) {
133
+ throw new Error(`Unknown fields: ${unknownFields.join(', ')}\n` +
134
+ `Allowed fields: ${allowedFields.join(', ')}\n` +
135
+ 'Check for typos in field names.');
136
+ }
137
+ }
138
+ static validateEmbedding(embedding) {
139
+ if (!embedding || typeof embedding !== 'string' || embedding.trim() === '') {
140
+ throw new Error('Embedding must be a non-empty string.');
141
+ }
142
+ }
143
+ static validateSharedBlockReferences(sharedBlocks) {
144
+ if (!Array.isArray(sharedBlocks)) {
145
+ throw new Error('Agent shared_blocks must be an array.');
146
+ }
147
+ sharedBlocks.forEach((blockName, index) => {
148
+ if (!blockName || typeof blockName !== 'string' || blockName.trim() === '') {
149
+ throw new Error(`Shared block reference ${index + 1} must be a non-empty string (block name).`);
150
+ }
151
+ });
152
+ }
153
+ }
154
+ exports.AgentValidator = AgentValidator;
155
+ /**
156
+ * Validator for system prompt configurations
157
+ */
158
+ class SystemPromptValidator {
159
+ static validate(prompt) {
160
+ if (!prompt || typeof prompt !== 'object') {
161
+ throw new Error('System prompt must be an object with value, from_file, or from_bucket.\n' +
162
+ 'Example:\n' +
163
+ 'system_prompt:\n' +
164
+ ' value: "You are helpful"');
165
+ }
166
+ const hasValue = 'value' in prompt;
167
+ const hasFile = 'from_file' in prompt;
168
+ const hasBucket = 'from_bucket' in prompt;
169
+ if (!hasValue && !hasFile && !hasBucket) {
170
+ throw new Error('System prompt must have one of: value, from_file, or from_bucket.\n' +
171
+ 'Examples:\n' +
172
+ 'system_prompt:\n' +
173
+ ' value: "You are helpful"\n' +
174
+ '# OR\n' +
175
+ 'system_prompt:\n' +
176
+ ' from_file: "prompts/my-prompt.md"\n' +
177
+ '# OR\n' +
178
+ 'system_prompt:\n' +
179
+ ' from_bucket:\n' +
180
+ ' provider: supabase\n' +
181
+ ' bucket: my-bucket\n' +
182
+ ' path: prompts/my-prompt.md');
183
+ }
184
+ // Only one source allowed
185
+ const sources = [hasValue, hasFile, hasBucket].filter(Boolean);
186
+ if (sources.length > 1) {
187
+ throw new Error('System prompt can only have one of: value, from_file, or from_bucket (not multiple).');
188
+ }
189
+ // Validate bucket config if present
190
+ if (hasBucket) {
191
+ bucket_config_validator_1.BucketConfigValidator.validate(prompt.from_bucket);
192
+ }
193
+ // Validate string values are non-empty
194
+ if (hasValue && (!prompt.value || typeof prompt.value !== 'string' || prompt.value.trim() === '')) {
195
+ throw new Error('System prompt value must be a non-empty string.');
196
+ }
197
+ if (hasFile && (!prompt.from_file || typeof prompt.from_file !== 'string' || prompt.from_file.trim() === '')) {
198
+ throw new Error('System prompt from_file must be a non-empty string.');
199
+ }
200
+ }
201
+ }
202
+ exports.SystemPromptValidator = SystemPromptValidator;
203
+ /**
204
+ * Validator for memory blocks
205
+ */
206
+ class MemoryBlockValidator {
207
+ static validate(blocks) {
208
+ if (!Array.isArray(blocks)) {
209
+ throw new Error('Memory blocks must be an array.');
210
+ }
211
+ // Check for duplicate block names
212
+ const blockNames = new Set();
213
+ blocks.forEach((block, index) => {
214
+ try {
215
+ this.validateBlock(block);
216
+ // Check name uniqueness
217
+ if (block.name) {
218
+ if (blockNames.has(block.name)) {
219
+ throw new Error(`Duplicate memory block name "${block.name}". Block names must be unique within an agent.`);
220
+ }
221
+ blockNames.add(block.name);
222
+ }
223
+ }
224
+ catch (error) {
225
+ throw new Error(`Memory block ${index + 1}: ${error.message}`);
226
+ }
227
+ });
228
+ }
229
+ static validateBlock(block) {
230
+ if (!block || typeof block !== 'object') {
231
+ throw new Error('Memory block must be an object.');
232
+ }
233
+ // Required fields
234
+ if (!block.name || typeof block.name !== 'string' || block.name.trim() === '') {
235
+ throw new Error('Memory block must have a non-empty name.');
236
+ }
237
+ // Description is required
238
+ if (!block.description || typeof block.description !== 'string' || block.description.trim() === '') {
239
+ throw new Error(`Memory block "${block.name}" must have a non-empty description.`);
240
+ }
241
+ // Limit is required
242
+ if (!block.limit) {
243
+ throw new Error(`Memory block "${block.name}" must have a limit field.`);
244
+ }
245
+ if (!Number.isInteger(block.limit) || block.limit <= 0) {
246
+ throw new Error(`Memory block "${block.name}" limit must be a positive integer.`);
247
+ }
248
+ // Must have content source
249
+ const hasValue = 'value' in block;
250
+ const hasFile = 'from_file' in block;
251
+ const hasBucket = 'from_bucket' in block;
252
+ if (!hasValue && !hasFile && !hasBucket) {
253
+ throw new Error(`Memory block "${block.name}" must have one of: value, from_file, or from_bucket.`);
254
+ }
255
+ // Only one content source allowed
256
+ const sources = [hasValue, hasFile, hasBucket].filter(Boolean);
257
+ if (sources.length > 1) {
258
+ throw new Error(`Memory block "${block.name}" can only have one of: value, from_file, or from_bucket (not multiple).`);
259
+ }
260
+ // Validate string values are non-empty
261
+ if (hasValue && (!block.value || typeof block.value !== 'string' || block.value.trim() === '')) {
262
+ throw new Error(`Memory block "${block.name}" value must be a non-empty string.`);
263
+ }
264
+ if (hasFile && (!block.from_file || typeof block.from_file !== 'string' || block.from_file.trim() === '')) {
265
+ throw new Error(`Memory block "${block.name}" from_file must be a non-empty string.`);
266
+ }
267
+ // Validate bucket config if present
268
+ if (hasBucket) {
269
+ bucket_config_validator_1.BucketConfigValidator.validate(block.from_bucket);
270
+ }
271
+ }
272
+ }
273
+ exports.MemoryBlockValidator = MemoryBlockValidator;
274
+ /**
275
+ * Validator for tools configuration
276
+ */
277
+ class ToolsValidator {
278
+ static validate(tools) {
279
+ if (!Array.isArray(tools)) {
280
+ throw new Error('Tools must be an array.');
281
+ }
282
+ tools.forEach((tool, index) => {
283
+ if (!tool || typeof tool !== 'string' || tool.trim() === '') {
284
+ throw new Error(`Tool ${index + 1} must be a non-empty string (tool name).`);
285
+ }
286
+ });
287
+ }
288
+ }
289
+ exports.ToolsValidator = ToolsValidator;
290
+ /**
291
+ * Validator for folders configuration
292
+ */
293
+ class FoldersValidator {
294
+ static validate(folders) {
295
+ if (!Array.isArray(folders)) {
296
+ throw new Error('Folders must be an array.');
297
+ }
298
+ folders.forEach((folder, index) => {
299
+ try {
300
+ this.validateFolder(folder);
301
+ }
302
+ catch (error) {
303
+ throw new Error(`Folder ${index + 1}: ${error.message}`);
304
+ }
305
+ });
306
+ }
307
+ static validateFolder(folder) {
308
+ if (!folder || typeof folder !== 'object') {
309
+ throw new Error('Folder must be an object.');
310
+ }
311
+ if (!folder.name || typeof folder.name !== 'string' || folder.name.trim() === '') {
312
+ throw new Error('Folder must have a non-empty name.');
313
+ }
314
+ if (!folder.files || !Array.isArray(folder.files)) {
315
+ throw new Error(`Folder "${folder.name}" must have a files array.`);
316
+ }
317
+ folder.files.forEach((file, index) => {
318
+ if (!file || typeof file !== 'string' || file.trim() === '') {
319
+ throw new Error(`Folder "${folder.name}" file ${index + 1} must be a non-empty string.`);
320
+ }
321
+ });
322
+ }
323
+ }
324
+ exports.FoldersValidator = FoldersValidator;
325
+ /**
326
+ * Validator for shared blocks configuration
327
+ */
328
+ class SharedBlockValidator {
329
+ static validate(blocks) {
330
+ if (!Array.isArray(blocks)) {
331
+ throw new Error('Shared blocks must be an array.');
332
+ }
333
+ blocks.forEach((block, index) => {
334
+ try {
335
+ MemoryBlockValidator['validateBlock'](block); // Reuse memory block validation
336
+ }
337
+ catch (error) {
338
+ throw new Error(`Shared block ${index + 1}: ${error.message}`);
339
+ }
340
+ });
341
+ }
342
+ }
343
+ exports.SharedBlockValidator = SharedBlockValidator;
344
+ /**
345
+ * Validator for LLM configuration
346
+ */
347
+ class LLMConfigValidator {
348
+ static validate(config) {
349
+ if (!config || typeof config !== 'object') {
350
+ throw new Error('LLM config is required and must be an object.\n' +
351
+ 'Example:\n' +
352
+ 'llm_config:\n' +
353
+ ' model: "google_ai/gemini-2.5-pro"\n' +
354
+ ' context_window: 32000');
355
+ }
356
+ // Model is required
357
+ if (!config.model) {
358
+ throw new Error('LLM config must include a model field.');
359
+ }
360
+ if (typeof config.model !== 'string' || config.model.trim() === '') {
361
+ throw new Error('LLM config model must be a non-empty string.');
362
+ }
363
+ // Context window is required
364
+ if (!config.context_window) {
365
+ throw new Error('LLM config must include context_window field.');
366
+ }
367
+ if (!Number.isInteger(config.context_window) || config.context_window <= 0) {
368
+ throw new Error('LLM config context_window must be a positive integer.');
369
+ }
370
+ // Validate reasonable context window bounds
371
+ if (config.context_window < 1000) {
372
+ throw new Error('LLM config context_window must be at least 1000.');
373
+ }
374
+ if (config.context_window > 200000) {
375
+ throw new Error('LLM config context_window cannot exceed 200000.');
376
+ }
377
+ }
378
+ }
379
+ exports.LLMConfigValidator = LLMConfigValidator;
380
+ //# sourceMappingURL=config-validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-validators.js","sourceRoot":"","sources":["../../src/lib/config-validators.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,uEAAkE;AAElE;;GAEG;AACH,MAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,MAAW;QACzB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAE/B,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,iBAAiB,CAAC,MAAW;QAC1C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,wEAAwE;gBACxE,YAAY;gBACZ,WAAW;gBACX,sBAAsB;gBACtB,sBAAsB;gBACtB,gCAAgC,CACjC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CACb,oDAAoD;gBACpD,YAAY;gBACZ,WAAW;gBACX,sBAAsB;gBACtB,sBAAsB;gBACtB,gCAAgC,CACjC,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,cAAc,CAAC,MAAa;QACzC,kCAAkC;QAClC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QAErC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC9B,IAAI,CAAC;gBACH,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAE/B,wBAAwB;gBACxB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBACf,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC/B,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,CAAC,IAAI,gCAAgC,CAAC,CAAC;oBACvF,CAAC;oBACD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA7DD,oDA6DC;AAED;;GAEG;AACH,MAAa,cAAc;IACzB,MAAM,CAAC,QAAQ,CAAC,KAAU;QACxB,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAEnC,0BAA0B;QAC1B,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAEpD,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;YACxB,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,6BAA6B,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,iBAAiB,CAAC,KAAU;QACzC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,sBAAsB,CAAC,KAAU;QAC9C,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;QAC9E,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC;QAElE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,4BAA4B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBAClD,iEAAiE;gBACjE,YAAY;gBACZ,oBAAoB;gBACpB,yCAAyC;gBACzC,iBAAiB;gBACjB,yCAAyC;gBACzC,6BAA6B;gBAC7B,oBAAoB;gBACpB,8BAA8B,CAC/B,CAAC;QACJ,CAAC;QAED,oCAAoC;QACpC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC9E,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QAED,6EAA6E;QAC7E,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;QAC7F,CAAC;QAED,2CAA2C;QAC3C,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACnG,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,KAAU;QAC7C,MAAM,aAAa,GAAG;YACpB,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY;YACpD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe;SAClE,CAAC;QAEF,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAEzF,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,mBAAmB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBAC/C,mBAAmB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBAC/C,iCAAiC,CAClC,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,iBAAiB,CAAC,SAAc;QAC7C,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,6BAA6B,CAAC,YAAiB;QAC5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,YAAY,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;YACxC,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC3E,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,GAAG,CAAC,2CAA2C,CAAC,CAAC;YAClG,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA7GD,wCA6GC;AAED;;GAEG;AACH,MAAa,qBAAqB;IAChC,MAAM,CAAC,QAAQ,CAAC,MAAW;QACzB,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,0EAA0E;gBAC1E,YAAY;gBACZ,kBAAkB;gBAClB,4BAA4B,CAC7B,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,IAAI,MAAM,CAAC;QACnC,MAAM,OAAO,GAAG,WAAW,IAAI,MAAM,CAAC;QACtC,MAAM,SAAS,GAAG,aAAa,IAAI,MAAM,CAAC;QAE1C,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CACb,qEAAqE;gBACrE,aAAa;gBACb,kBAAkB;gBAClB,8BAA8B;gBAC9B,QAAQ;gBACR,kBAAkB;gBAClB,uCAAuC;gBACvC,QAAQ;gBACR,kBAAkB;gBAClB,kBAAkB;gBAClB,0BAA0B;gBAC1B,yBAAyB;gBACzB,gCAAgC,CACjC,CAAC;QACJ,CAAC;QAED,0BAA0B;QAC1B,MAAM,OAAO,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,sFAAsF,CAAC,CAAC;QAC1G,CAAC;QAED,oCAAoC;QACpC,IAAI,SAAS,EAAE,CAAC;YACd,+CAAqB,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACrD,CAAC;QAED,uCAAuC;QACvC,IAAI,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAClG,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAC7G,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;CACF;AArDD,sDAqDC;AAED;;GAEG;AACH,MAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,MAAW;QACzB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,kCAAkC;QAClC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QAErC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC9B,IAAI,CAAC;gBACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAE1B,wBAAwB;gBACxB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBACf,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC/B,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,IAAI,gDAAgD,CAAC,CAAC;oBAC9G,CAAC;oBACD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,gBAAgB,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,aAAa,CAAC,KAAU;QACrC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,kBAAkB;QAClB,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC9E,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QAED,0BAA0B;QAC1B,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACnG,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,IAAI,sCAAsC,CAAC,CAAC;QACrF,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,IAAI,4BAA4B,CAAC,CAAC;QAC3E,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,IAAI,qCAAqC,CAAC,CAAC;QACpF,CAAC;QAED,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,CAAC;QAClC,MAAM,OAAO,GAAG,WAAW,IAAI,KAAK,CAAC;QACrC,MAAM,SAAS,GAAG,aAAa,IAAI,KAAK,CAAC;QAEzC,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CACb,iBAAiB,KAAK,CAAC,IAAI,uDAAuD,CACnF,CAAC;QACJ,CAAC;QAED,kCAAkC;QAClC,MAAM,OAAO,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,IAAI,0EAA0E,CAAC,CAAC;QACzH,CAAC;QAED,uCAAuC;QACvC,IAAI,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAC/F,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,IAAI,qCAAqC,CAAC,CAAC;QACpF,CAAC;QAED,IAAI,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAC1G,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,IAAI,yCAAyC,CAAC,CAAC;QACxF,CAAC;QAED,oCAAoC;QACpC,IAAI,SAAS,EAAE,CAAC;YACd,+CAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;CACF;AAjFD,oDAiFC;AAED;;GAEG;AACH,MAAa,cAAc;IACzB,MAAM,CAAC,QAAQ,CAAC,KAAU;QACxB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC5B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC5D,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,GAAG,CAAC,0CAA0C,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAZD,wCAYC;AAED;;GAEG;AACH,MAAa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,OAAY;QAC1B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YAChC,IAAI,CAAC;gBACH,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,cAAc,CAAC,MAAW;QACvC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACjF,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,IAAI,4BAA4B,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAS,EAAE,KAAa,EAAE,EAAE;YAChD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC5D,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,IAAI,UAAU,KAAK,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAC3F,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAlCD,4CAkCC;AAED;;GAEG;AACH,MAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,MAAW;QACzB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC9B,IAAI,CAAC;gBACH,oBAAoB,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gCAAgC;YAChF,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,gBAAgB,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAdD,oDAcC;AAED;;GAEG;AACH,MAAa,kBAAkB;IAC7B,MAAM,CAAC,QAAQ,CAAC,MAAW;QACzB,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,iDAAiD;gBACjD,YAAY;gBACZ,eAAe;gBACf,uCAAuC;gBACvC,yBAAyB,CAC1B,CAAC;QACJ,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,CAAC;QAED,6BAA6B;QAC7B,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,cAAc,IAAI,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QAED,4CAA4C;QAC5C,IAAI,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,MAAM,CAAC,cAAc,GAAG,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;CACF;AAvCD,gDAuCC"}
@@ -83,6 +83,10 @@ export declare class DiffEngine {
83
83
  private blockManager;
84
84
  private basePath;
85
85
  constructor(client: LettaClientWrapper, blockManager: BlockManager, basePath?: string);
86
+ /**
87
+ * Helper method to check if an item has file-based content that might have changed
88
+ */
89
+ private hasFileBasedContent;
86
90
  /**
87
91
  * Analyzes differences between existing and desired agent configuration
88
92
  * and generates specific update operations that preserve conversation history
@@ -100,6 +104,7 @@ export declare class DiffEngine {
100
104
  limit: number;
101
105
  value: string;
102
106
  }>;
107
+ memoryBlockFileHashes?: Record<string, string>;
103
108
  folders?: Array<{
104
109
  name: string;
105
110
  files: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"diff-engine.d.ts","sourceRoot":"","sources":["../../src/lib/diff-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diff-engine.d.ts","sourceRoot":"","sources":["../../src/lib/diff-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3C,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpF,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3C,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,aAAa,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC,CAAC;IACH,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,qBAAqB;IAEpC,YAAY,CAAC,EAAE;QACb,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IAGF,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,OAAO,CAAC,EAAE,UAAU,CAAC;IAGrB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,GAAE,MAAW;IAMzF;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;;OAGG;IACG,wBAAwB,CAC5B,aAAa,EAAE,YAAY,EAC3B,aAAa,EAAE;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,KAAK,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAC,CAAC,CAAC;QACxF,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,EAAE,KAAK,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,EAAE,CAAA;SAAC,CAAC,CAAC;QACjD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,EACD,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,OAAO,GAAE,OAAe,GACvB,OAAO,CAAC,qBAAqB,CAAC;YA0FnB,kBAAkB;YAmElB,mBAAmB;YA8DnB,oBAAoB;IAgGlC;;OAEG;IACG,qBAAqB,CACzB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,qBAAqB,EACjC,OAAO,GAAE,OAAe,GACvB,OAAO,CAAC,IAAI,CAAC;IAwGhB;;OAEG;YACW,eAAe;IAe7B;;OAEG;YACW,oBAAoB;IAYlC;;OAEG;YACW,kBAAkB;CAgBjC"}
@@ -12,6 +12,12 @@ class DiffEngine {
12
12
  this.blockManager = blockManager;
13
13
  this.basePath = basePath;
14
14
  }
15
+ /**
16
+ * Helper method to check if an item has file-based content that might have changed
17
+ */
18
+ hasFileBasedContent(itemName, fileHashes) {
19
+ return !!fileHashes[itemName];
20
+ }
15
21
  /**
16
22
  * Analyzes differences between existing and desired agent configuration
17
23
  * and generates specific update operations that preserve conversation history
@@ -71,7 +77,7 @@ class DiffEngine {
71
77
  operations.blocks = await this.analyzeBlockChanges(currentBlocks, [
72
78
  ...(desiredConfig.memoryBlocks || []),
73
79
  ...(desiredConfig.sharedBlocks || []).map(name => ({ name, isShared: true }))
74
- ]);
80
+ ], desiredConfig.memoryBlockFileHashes || {});
75
81
  operations.operationCount += operations.blocks.toAdd.length + operations.blocks.toRemove.length + operations.blocks.toUpdate.length;
76
82
  // Analyze folder changes
77
83
  operations.folders = await this.analyzeFolderChanges(currentFolders, desiredConfig.folders || [], folderRegistry);
@@ -100,11 +106,10 @@ class DiffEngine {
100
106
  if (desiredToolSet.has(tool.name)) {
101
107
  // Tool exists in both current and desired
102
108
  const toolName = tool.name;
103
- // Check if source code has changed for custom tools
104
- if (toolSourceHashes[toolName] && !['archival_memory_insert', 'archival_memory_search'].includes(toolName)) {
105
- // For tools with source code, we need to check if the source has changed
106
- // This would require getting the current tool's source hash and comparing
107
- // For now, we'll re-register tools when their source files exist and have hashes
109
+ // Check if source code has changed for custom tools using the same pattern
110
+ if (this.hasFileBasedContent(toolName, toolSourceHashes) && !['archival_memory_insert', 'archival_memory_search'].includes(toolName)) {
111
+ // This tool has file-based source code, assume it might have changed and mark for update
112
+ console.log(`Tool ${toolName} has file-based content, checking for updates...`);
108
113
  const currentToolId = tool.id;
109
114
  const newToolId = toolRegistry.get(toolName);
110
115
  if (newToolId && newToolId !== currentToolId) {
@@ -117,7 +122,13 @@ class DiffEngine {
117
122
  });
118
123
  }
119
124
  else {
120
- unchanged.push({ name: tool.name, id: tool.id });
125
+ // Tool ID is same but source might have changed, still mark as update needed
126
+ toUpdate.push({
127
+ name: toolName,
128
+ currentId: currentToolId,
129
+ newId: currentToolId,
130
+ reason: 'source_content_changed'
131
+ });
121
132
  }
122
133
  }
123
134
  else {
@@ -131,7 +142,10 @@ class DiffEngine {
131
142
  }
132
143
  return { toAdd, toRemove, toUpdate, unchanged };
133
144
  }
134
- async analyzeBlockChanges(currentBlocks, desiredBlocks) {
145
+ async analyzeBlockChanges(currentBlocks, desiredBlocks, memoryBlockFileHashes = {}) {
146
+ console.log(`DEBUG DIFF - memoryBlockFileHashes:`, memoryBlockFileHashes);
147
+ console.log(`DEBUG DIFF - currentBlocks:`, currentBlocks.map(b => ({ label: b.label, id: b.id })));
148
+ console.log(`DEBUG DIFF - desiredBlocks:`, desiredBlocks.map(b => ({ name: b.name, isShared: b.isShared })));
135
149
  const currentBlockNames = new Set(currentBlocks.map(b => b.label));
136
150
  const desiredBlockNames = new Set(desiredBlocks.map(b => b.name));
137
151
  const toAdd = [];
@@ -143,16 +157,35 @@ class DiffEngine {
143
157
  if (!currentBlockNames.has(blockConfig.name)) {
144
158
  const blockId = blockConfig.isShared
145
159
  ? this.blockManager.getSharedBlockId(blockConfig.name)
146
- : this.blockManager.getSharedBlockId(blockConfig.name); // TODO: Add agent block lookup
160
+ : this.blockManager.getAgentBlockId(blockConfig.name);
161
+ console.log(`DEBUG DIFF - Looking for block '${blockConfig.name}', isShared: ${blockConfig.isShared}, found ID: ${blockId}`);
147
162
  if (blockId) {
148
163
  toAdd.push({ name: blockConfig.name, id: blockId });
149
164
  }
150
165
  }
151
166
  }
152
- // Find blocks to remove and unchanged
167
+ // Find blocks to remove, update (content changed), or unchanged
153
168
  for (const block of currentBlocks) {
154
169
  if (desiredBlockNames.has(block.label)) {
155
- unchanged.push({ name: block.label, id: block.id });
170
+ // Block exists in both current and desired
171
+ const blockName = block.label;
172
+ // Check if content has changed by comparing with file hash
173
+ if (this.hasFileBasedContent(blockName, memoryBlockFileHashes)) {
174
+ // This block has file-based content, assume it might have changed and mark for update
175
+ console.log(`Block ${blockName} has file-based content, checking for updates...`);
176
+ // Create new block with updated content and mark for update
177
+ const newBlockId = this.blockManager.getSharedBlockId(blockName); // Get updated block ID
178
+ if (newBlockId && newBlockId !== block.id) {
179
+ toUpdate.push({ name: blockName, currentId: block.id, newId: newBlockId });
180
+ }
181
+ else {
182
+ // Content may have changed but block ID is same, still mark as update needed
183
+ toUpdate.push({ name: blockName, currentId: block.id, newId: block.id });
184
+ }
185
+ }
186
+ else {
187
+ unchanged.push({ name: block.label, id: block.id });
188
+ }
156
189
  }
157
190
  else {
158
191
  toRemove.push({ name: block.label, id: block.id });
@@ -198,9 +231,9 @@ class DiffEngine {
198
231
  filesToAdd.push(filePath);
199
232
  }
200
233
  else {
201
- // File exists, check if content changed
202
- // For now, assume content may have changed if folder hash changed
203
- if (desiredFolder.fileContentHashes && desiredFolder.fileContentHashes[filePath]) {
234
+ // File exists, check if content changed using the same pattern as memory blocks
235
+ if (this.hasFileBasedContent(filePath, desiredFolder.fileContentHashes || {})) {
236
+ console.log(`File ${filePath} has file-based content, checking for updates...`);
204
237
  filesToUpdate.push(filePath);
205
238
  }
206
239
  }