@ddse/acm-examples 0.5.0

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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +113 -0
  3. package/bin/acm-demo.ts +495 -0
  4. package/data/coaching/agents.json +16 -0
  5. package/data/coaching/transcripts.json +37 -0
  6. package/data/documents.json +72 -0
  7. package/data/entitlement/customers.json +38 -0
  8. package/data/entitlement/policies.json +38 -0
  9. package/data/incidents/incidents.json +30 -0
  10. package/data/incidents/routing_rules.json +36 -0
  11. package/data/invoices/invoices.json +38 -0
  12. package/data/invoices/purchase-orders.json +38 -0
  13. package/data/issues.json +99 -0
  14. package/data/knowledge/docs/kb-001.md +7 -0
  15. package/data/knowledge/docs/kb-002.md +7 -0
  16. package/data/knowledge/docs/kb-003.md +9 -0
  17. package/data/knowledge/index.json +25 -0
  18. package/data/orders.json +106 -0
  19. package/dist/bin/acm-demo.d.ts +3 -0
  20. package/dist/bin/acm-demo.d.ts.map +1 -0
  21. package/dist/bin/acm-demo.js +392 -0
  22. package/dist/bin/acm-demo.js.map +1 -0
  23. package/dist/src/context/directives.d.ts +3 -0
  24. package/dist/src/context/directives.d.ts.map +1 -0
  25. package/dist/src/context/directives.js +325 -0
  26. package/dist/src/context/directives.js.map +1 -0
  27. package/dist/src/context/index.d.ts +2 -0
  28. package/dist/src/context/index.d.ts.map +1 -0
  29. package/dist/src/context/index.js +2 -0
  30. package/dist/src/context/index.js.map +1 -0
  31. package/dist/src/data/coaching.d.ts +19 -0
  32. package/dist/src/data/coaching.d.ts.map +1 -0
  33. package/dist/src/data/coaching.js +22 -0
  34. package/dist/src/data/coaching.js.map +1 -0
  35. package/dist/src/data/entitlement.d.ts +25 -0
  36. package/dist/src/data/entitlement.d.ts.map +1 -0
  37. package/dist/src/data/entitlement.js +26 -0
  38. package/dist/src/data/entitlement.js.map +1 -0
  39. package/dist/src/data/incidents.d.ts +23 -0
  40. package/dist/src/data/incidents.d.ts.map +1 -0
  41. package/dist/src/data/incidents.js +37 -0
  42. package/dist/src/data/incidents.js.map +1 -0
  43. package/dist/src/data/invoices.d.ts +34 -0
  44. package/dist/src/data/invoices.d.ts.map +1 -0
  45. package/dist/src/data/invoices.js +49 -0
  46. package/dist/src/data/invoices.js.map +1 -0
  47. package/dist/src/data/knowledge.d.ts +11 -0
  48. package/dist/src/data/knowledge.d.ts.map +1 -0
  49. package/dist/src/data/knowledge.js +57 -0
  50. package/dist/src/data/knowledge.js.map +1 -0
  51. package/dist/src/data/loader.d.ts +4 -0
  52. package/dist/src/data/loader.d.ts.map +1 -0
  53. package/dist/src/data/loader.js +69 -0
  54. package/dist/src/data/loader.js.map +1 -0
  55. package/dist/src/examples/scenarios.d.ts +23 -0
  56. package/dist/src/examples/scenarios.d.ts.map +1 -0
  57. package/dist/src/examples/scenarios.js +609 -0
  58. package/dist/src/examples/scenarios.js.map +1 -0
  59. package/dist/src/goals/index.d.ts +8 -0
  60. package/dist/src/goals/index.d.ts.map +1 -0
  61. package/dist/src/goals/index.js +12 -0
  62. package/dist/src/goals/index.js.map +1 -0
  63. package/dist/src/policy.d.ts +5 -0
  64. package/dist/src/policy.d.ts.map +1 -0
  65. package/dist/src/policy.js +24 -0
  66. package/dist/src/policy.js.map +1 -0
  67. package/dist/src/registries.d.ts +18 -0
  68. package/dist/src/registries.d.ts.map +1 -0
  69. package/dist/src/registries.js +38 -0
  70. package/dist/src/registries.js.map +1 -0
  71. package/dist/src/renderer.d.ts +9 -0
  72. package/dist/src/renderer.d.ts.map +1 -0
  73. package/dist/src/renderer.js +76 -0
  74. package/dist/src/renderer.js.map +1 -0
  75. package/dist/src/search/bm25.d.ts +68 -0
  76. package/dist/src/search/bm25.d.ts.map +1 -0
  77. package/dist/src/search/bm25.js +131 -0
  78. package/dist/src/search/bm25.js.map +1 -0
  79. package/dist/src/search/index.d.ts +2 -0
  80. package/dist/src/search/index.d.ts.map +1 -0
  81. package/dist/src/search/index.js +3 -0
  82. package/dist/src/search/index.js.map +1 -0
  83. package/dist/src/tasks/coaching.d.ts +30 -0
  84. package/dist/src/tasks/coaching.d.ts.map +1 -0
  85. package/dist/src/tasks/coaching.js +143 -0
  86. package/dist/src/tasks/coaching.js.map +1 -0
  87. package/dist/src/tasks/entitlement.d.ts +29 -0
  88. package/dist/src/tasks/entitlement.d.ts.map +1 -0
  89. package/dist/src/tasks/entitlement.js +135 -0
  90. package/dist/src/tasks/entitlement.js.map +1 -0
  91. package/dist/src/tasks/incidents.d.ts +42 -0
  92. package/dist/src/tasks/incidents.d.ts.map +1 -0
  93. package/dist/src/tasks/incidents.js +189 -0
  94. package/dist/src/tasks/incidents.js.map +1 -0
  95. package/dist/src/tasks/index.d.ts +7 -0
  96. package/dist/src/tasks/index.d.ts.map +1 -0
  97. package/dist/src/tasks/index.js +7 -0
  98. package/dist/src/tasks/index.js.map +1 -0
  99. package/dist/src/tasks/invoices.d.ts +40 -0
  100. package/dist/src/tasks/invoices.d.ts.map +1 -0
  101. package/dist/src/tasks/invoices.js +180 -0
  102. package/dist/src/tasks/invoices.js.map +1 -0
  103. package/dist/src/tasks/knowledge.d.ts +23 -0
  104. package/dist/src/tasks/knowledge.d.ts.map +1 -0
  105. package/dist/src/tasks/knowledge.js +115 -0
  106. package/dist/src/tasks/knowledge.js.map +1 -0
  107. package/dist/src/tasks/legacy.d.ts +50 -0
  108. package/dist/src/tasks/legacy.d.ts.map +1 -0
  109. package/dist/src/tasks/legacy.js +85 -0
  110. package/dist/src/tasks/legacy.js.map +1 -0
  111. package/dist/src/tools/coaching/index.d.ts +49 -0
  112. package/dist/src/tools/coaching/index.d.ts.map +1 -0
  113. package/dist/src/tools/coaching/index.js +119 -0
  114. package/dist/src/tools/coaching/index.js.map +1 -0
  115. package/dist/src/tools/entitlement/index.d.ts +52 -0
  116. package/dist/src/tools/entitlement/index.d.ts.map +1 -0
  117. package/dist/src/tools/entitlement/index.js +120 -0
  118. package/dist/src/tools/entitlement/index.js.map +1 -0
  119. package/dist/src/tools/incidents/index.d.ts +55 -0
  120. package/dist/src/tools/incidents/index.d.ts.map +1 -0
  121. package/dist/src/tools/incidents/index.js +109 -0
  122. package/dist/src/tools/incidents/index.js.map +1 -0
  123. package/dist/src/tools/index.d.ts +90 -0
  124. package/dist/src/tools/index.d.ts.map +1 -0
  125. package/dist/src/tools/index.js +109 -0
  126. package/dist/src/tools/index.js.map +1 -0
  127. package/dist/src/tools/invoices/index.d.ts +56 -0
  128. package/dist/src/tools/invoices/index.d.ts.map +1 -0
  129. package/dist/src/tools/invoices/index.js +85 -0
  130. package/dist/src/tools/invoices/index.js.map +1 -0
  131. package/dist/src/tools/knowledge/index.d.ts +52 -0
  132. package/dist/src/tools/knowledge/index.d.ts.map +1 -0
  133. package/dist/src/tools/knowledge/index.js +120 -0
  134. package/dist/src/tools/knowledge/index.js.map +1 -0
  135. package/dist/tests/bm25.test.d.ts +2 -0
  136. package/dist/tests/bm25.test.d.ts.map +1 -0
  137. package/dist/tests/bm25.test.js +98 -0
  138. package/dist/tests/bm25.test.js.map +1 -0
  139. package/dist/tests/integration.test.d.ts +2 -0
  140. package/dist/tests/integration.test.d.ts.map +1 -0
  141. package/dist/tests/integration.test.js +126 -0
  142. package/dist/tests/integration.test.js.map +1 -0
  143. package/dist/tests/plan-hydration.test.d.ts +2 -0
  144. package/dist/tests/plan-hydration.test.d.ts.map +1 -0
  145. package/dist/tests/plan-hydration.test.js +28 -0
  146. package/dist/tests/plan-hydration.test.js.map +1 -0
  147. package/dist/tsconfig.tsbuildinfo +1 -0
  148. package/docs/examples-architecture.md +144 -0
  149. package/docs/successrun.md +1022 -0
  150. package/package.json +33 -0
  151. package/src/context/directives.ts +366 -0
  152. package/src/context/index.ts +1 -0
  153. package/src/data/coaching.ts +50 -0
  154. package/src/data/entitlement.ts +60 -0
  155. package/src/data/incidents.ts +78 -0
  156. package/src/data/invoices.ts +103 -0
  157. package/src/data/knowledge.ts +77 -0
  158. package/src/data/loader.ts +80 -0
  159. package/src/examples/scenarios.ts +724 -0
  160. package/src/goals/index.ts +18 -0
  161. package/src/policy.ts +30 -0
  162. package/src/registries.ts +48 -0
  163. package/src/renderer.ts +82 -0
  164. package/src/search/bm25.ts +173 -0
  165. package/src/search/index.ts +2 -0
  166. package/src/tasks/coaching.ts +217 -0
  167. package/src/tasks/entitlement.ts +197 -0
  168. package/src/tasks/incidents.ts +277 -0
  169. package/src/tasks/index.ts +6 -0
  170. package/src/tasks/invoices.ts +269 -0
  171. package/src/tasks/knowledge.ts +169 -0
  172. package/src/tasks/legacy.ts +112 -0
  173. package/src/tools/coaching/index.ts +197 -0
  174. package/src/tools/entitlement/index.ts +199 -0
  175. package/src/tools/incidents/index.ts +185 -0
  176. package/src/tools/index.ts +192 -0
  177. package/src/tools/invoices/index.ts +165 -0
  178. package/src/tools/knowledge/index.ts +203 -0
  179. package/tests/bm25.test.ts +129 -0
  180. package/tests/integration.test.ts +163 -0
  181. package/tests/plan-hydration.test.ts +33 -0
  182. package/tsconfig.json +18 -0
@@ -0,0 +1,85 @@
1
+ import { Tool } from '@ddse/acm-sdk';
2
+ import { getInvoice, getPurchaseOrder, compareLineItems, } from '../../data/invoices.js';
3
+ export class FetchInvoiceTool extends Tool {
4
+ name() {
5
+ return 'fetch_invoice';
6
+ }
7
+ async call(input) {
8
+ if (!input?.invoiceId) {
9
+ throw new Error('invoiceId is required');
10
+ }
11
+ const invoice = await getInvoice(input.invoiceId);
12
+ if (!invoice) {
13
+ throw new Error(`Invoice ${input.invoiceId} not found`);
14
+ }
15
+ return { invoice };
16
+ }
17
+ }
18
+ export class FetchPurchaseOrderTool extends Tool {
19
+ name() {
20
+ return 'fetch_purchase_order';
21
+ }
22
+ async call(input) {
23
+ if (!input?.purchaseOrderId) {
24
+ throw new Error('purchaseOrderId is required');
25
+ }
26
+ const purchaseOrder = await getPurchaseOrder(input.purchaseOrderId);
27
+ if (!purchaseOrder) {
28
+ throw new Error(`Purchase order ${input.purchaseOrderId} not found`);
29
+ }
30
+ return { purchaseOrder };
31
+ }
32
+ }
33
+ export class CompareLineItemsTool extends Tool {
34
+ name() {
35
+ return 'compare_line_items';
36
+ }
37
+ async call(input) {
38
+ if (!input?.invoice || !input?.purchaseOrder) {
39
+ throw new Error('invoice and purchaseOrder are required');
40
+ }
41
+ const discrepancies = compareLineItems(input.invoice, input.purchaseOrder).map(item => ({
42
+ ...item,
43
+ varianceAmount: (item.actualQuantity - item.expectedQuantity) * item.expectedPrice ||
44
+ (item.actualPrice - item.expectedPrice) * item.actualQuantity,
45
+ }));
46
+ const matchedLines = input.invoice.lines.length - discrepancies.length;
47
+ const variance = discrepancies.reduce((sum, item) => sum + item.varianceAmount, 0);
48
+ return {
49
+ discrepancies,
50
+ variance,
51
+ matchedLines,
52
+ };
53
+ }
54
+ }
55
+ export class RecordFindingsTool extends Tool {
56
+ name() {
57
+ return 'record_findings';
58
+ }
59
+ async call(input) {
60
+ if (!input?.invoice || !input?.purchaseOrder) {
61
+ throw new Error('invoice and purchaseOrder are required');
62
+ }
63
+ const status = input.discrepancies.length === 0 && Math.abs(input.variance) < 1
64
+ ? 'clean'
65
+ : 'needs_remediation';
66
+ const summary = status === 'clean'
67
+ ? `Invoice ${input.invoice.id} matches purchase order ${input.purchaseOrder.id}`
68
+ : `Invoice ${input.invoice.id} has ${input.discrepancies.length} discrepancy(s)`;
69
+ const nextSteps = status === 'clean'
70
+ ? ['Archive reconciliation report in AP system']
71
+ : [
72
+ 'Open remediation ticket with procurement',
73
+ 'Notify accounts payable supervisor',
74
+ 'Schedule supplier follow-up call',
75
+ ];
76
+ return {
77
+ reportId: `recon-${Date.now()}`,
78
+ status,
79
+ summary,
80
+ nextSteps,
81
+ generatedAt: new Date().toISOString(),
82
+ };
83
+ }
84
+ }
85
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/tools/invoices/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { Tool } from '@ddse/acm-sdk';
2
+ import { type KnowledgeSnippetMeta } from '../../data/knowledge.js';
3
+ export type KnowledgeSearchInput = {
4
+ query: string;
5
+ limit?: number;
6
+ };
7
+ export type KnowledgeSearchHit = KnowledgeSnippetMeta & {
8
+ score: number;
9
+ };
10
+ export type KnowledgeSearchOutput = {
11
+ hits: KnowledgeSearchHit[];
12
+ };
13
+ export declare class SearchKnowledgeTool extends Tool<KnowledgeSearchInput, KnowledgeSearchOutput> {
14
+ name(): string;
15
+ call(input: KnowledgeSearchInput): Promise<KnowledgeSearchOutput>;
16
+ }
17
+ export type SummarizeSnippetInput = {
18
+ docId: string;
19
+ maxSentences?: number;
20
+ focus?: string;
21
+ };
22
+ export type SummarizeSnippetOutput = {
23
+ docId: string;
24
+ title: string;
25
+ summary: string;
26
+ highlights: string[];
27
+ followups: string[];
28
+ };
29
+ export declare class SummarizeSnippetTool extends Tool<SummarizeSnippetInput, SummarizeSnippetOutput> {
30
+ name(): string;
31
+ call(input: SummarizeSnippetInput): Promise<SummarizeSnippetOutput>;
32
+ }
33
+ export type SuggestFollowupsInput = {
34
+ docId: string;
35
+ context?: {
36
+ channel?: string;
37
+ urgency?: 'low' | 'normal' | 'high';
38
+ };
39
+ };
40
+ export type SuggestFollowupsOutput = {
41
+ docId: string;
42
+ suggestions: Array<{
43
+ action: string;
44
+ owner: string;
45
+ dueInHours: number;
46
+ }>;
47
+ };
48
+ export declare class SuggestFollowupsTool extends Tool<SuggestFollowupsInput, SuggestFollowupsOutput> {
49
+ name(): string;
50
+ call(input: SuggestFollowupsInput): Promise<SuggestFollowupsOutput>;
51
+ }
52
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tools/knowledge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,GAAG;IACtD,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,kBAAkB,EAAE,CAAC;CAC5B,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,IAAI,CAAC,oBAAoB,EAAE,qBAAqB,CAAC;IACxF,IAAI,IAAI,MAAM;IAIR,IAAI,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAgBxE;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AA4DF,qBAAa,oBAAqB,SAAQ,IAAI,CAC5C,qBAAqB,EACrB,sBAAsB,CACvB;IACC,IAAI,IAAI,MAAM;IAIR,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;CA2B1E;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;KACrC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,KAAK,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ,CAAC;AAEF,qBAAa,oBAAqB,SAAQ,IAAI,CAC5C,qBAAqB,EACrB,sBAAsB,CACvB;IACC,IAAI,IAAI,MAAM;IAIR,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;CAwB1E"}
@@ -0,0 +1,120 @@
1
+ import { Tool } from '@ddse/acm-sdk';
2
+ import { searchSnippets, loadSnippetContent, getSnippetMeta, } from '../../data/knowledge.js';
3
+ export class SearchKnowledgeTool extends Tool {
4
+ name() {
5
+ return 'search_knowledge';
6
+ }
7
+ async call(input) {
8
+ const query = input?.query?.trim();
9
+ if (!query) {
10
+ throw new Error('query is required');
11
+ }
12
+ const limit = Math.max(1, Math.min(input.limit ?? 5, 10));
13
+ const snippets = await searchSnippets(query);
14
+ const hits = snippets.slice(0, limit).map((snippet, index) => ({
15
+ ...snippet,
16
+ score: Math.max(1, snippets.length - index),
17
+ }));
18
+ return { hits };
19
+ }
20
+ }
21
+ function summarizeContent(content, maxSentences) {
22
+ const sentences = content
23
+ .replace(/\s+/g, ' ')
24
+ .split(/(?<=[.!?])\s+(?=[A-Z0-9])/)
25
+ .filter(Boolean);
26
+ if (sentences.length === 0) {
27
+ return content.trim();
28
+ }
29
+ return sentences.slice(0, maxSentences).join(' ');
30
+ }
31
+ function extractHighlights(content, maxHighlights = 3) {
32
+ const lines = content.split(/\r?\n/).map(line => line.trim()).filter(Boolean);
33
+ const bulletLines = lines.filter(line => /^[-*]/.test(line));
34
+ const highlights = [];
35
+ for (const line of bulletLines) {
36
+ highlights.push(line.replace(/^[-*]\s*/, ''));
37
+ if (highlights.length >= maxHighlights) {
38
+ break;
39
+ }
40
+ }
41
+ if (highlights.length === 0) {
42
+ highlights.push(...lines.slice(0, maxHighlights));
43
+ }
44
+ return highlights.slice(0, maxHighlights);
45
+ }
46
+ function deriveFollowups(meta, focus) {
47
+ const followups = new Set();
48
+ for (const tag of meta.tags) {
49
+ if (tag.toLowerCase().includes('escalation')) {
50
+ followups.add('Confirm escalation steps with runbook owner');
51
+ }
52
+ if (tag.toLowerCase().includes('training')) {
53
+ followups.add('Share summary with enablement channel for awareness');
54
+ }
55
+ if (tag.toLowerCase().includes('automation')) {
56
+ followups.add('Evaluate automation opportunity with platform team');
57
+ }
58
+ }
59
+ if (focus) {
60
+ followups.add(`Identify additional knowledge gaps related to "${focus}"`);
61
+ }
62
+ if (followups.size === 0) {
63
+ followups.add('Log follow-up tasks in support queue');
64
+ }
65
+ return Array.from(followups);
66
+ }
67
+ export class SummarizeSnippetTool extends Tool {
68
+ name() {
69
+ return 'summarize_snippet';
70
+ }
71
+ async call(input) {
72
+ if (!input?.docId) {
73
+ throw new Error('docId is required');
74
+ }
75
+ const [meta, content] = await Promise.all([
76
+ getSnippetMeta(input.docId),
77
+ loadSnippetContent(input.docId),
78
+ ]);
79
+ if (!meta || !content) {
80
+ throw new Error(`Snippet ${input.docId} not found`);
81
+ }
82
+ const maxSentences = Math.max(1, Math.min(input.maxSentences ?? 3, 6));
83
+ const summary = summarizeContent(content, maxSentences);
84
+ const highlights = extractHighlights(content);
85
+ const followups = deriveFollowups(meta, input.focus);
86
+ return {
87
+ docId: input.docId,
88
+ title: meta.title,
89
+ summary,
90
+ highlights,
91
+ followups,
92
+ };
93
+ }
94
+ }
95
+ export class SuggestFollowupsTool extends Tool {
96
+ name() {
97
+ return 'suggest_followups';
98
+ }
99
+ async call(input) {
100
+ if (!input?.docId) {
101
+ throw new Error('docId is required');
102
+ }
103
+ const meta = await getSnippetMeta(input.docId);
104
+ if (!meta) {
105
+ throw new Error(`Snippet ${input.docId} not found`);
106
+ }
107
+ const baseDue = input.context?.urgency === 'high' ? 4 : input.context?.urgency === 'low' ? 24 : 8;
108
+ const suggestions = deriveFollowups(meta)
109
+ .map((action, index) => ({
110
+ action,
111
+ owner: index === 0 ? 'support.enablement' : 'support.lead',
112
+ dueInHours: baseDue + index * 4,
113
+ }));
114
+ return {
115
+ docId: input.docId,
116
+ suggestions,
117
+ };
118
+ }
119
+ }
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/tools/knowledge/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bm25.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bm25.test.d.ts","sourceRoot":"","sources":["../../tests/bm25.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,98 @@
1
+ // Tests for BM25 search functionality
2
+ import { BM25Search } from '../src/search/bm25.js';
3
+ async function testIndexAndSearch() {
4
+ console.log('Testing index and search...');
5
+ const documents = [
6
+ { id: 'doc1', content: 'The quick brown fox jumps over the lazy dog' },
7
+ { id: 'doc2', content: 'A fast brown fox leaps over a sleepy dog' },
8
+ { id: 'doc3', content: 'The cat sits on the mat' },
9
+ ];
10
+ const search = new BM25Search();
11
+ search.index(documents);
12
+ const results = search.search('brown fox');
13
+ if (results.length === 0) {
14
+ throw new Error('Expected results, got none');
15
+ }
16
+ if (!['doc1', 'doc2'].includes(results[0].document.id)) {
17
+ throw new Error(`Expected doc1 or doc2, got ${results[0].document.id}`);
18
+ }
19
+ console.log('✅ Index and search test passed');
20
+ }
21
+ async function testEmptyQuery() {
22
+ console.log('Testing empty query...');
23
+ const documents = [{ id: 'doc1', content: 'Test document' }];
24
+ const search = new BM25Search();
25
+ search.index(documents);
26
+ const results = search.search('');
27
+ if (results.length !== 0) {
28
+ throw new Error('Expected empty results for empty query');
29
+ }
30
+ console.log('✅ Empty query test passed');
31
+ }
32
+ async function testRanking() {
33
+ console.log('Testing ranking...');
34
+ const documents = [
35
+ { id: 'doc1', content: 'machine learning algorithms' },
36
+ { id: 'doc2', content: 'learning machine code' },
37
+ { id: 'doc3', content: 'deep learning neural networks' },
38
+ ];
39
+ const search = new BM25Search();
40
+ search.index(documents);
41
+ const results = search.search('machine learning');
42
+ if (results.length < 2) {
43
+ throw new Error('Expected at least 2 results');
44
+ }
45
+ if (results[0].score < results[1].score) {
46
+ throw new Error('Results not properly ranked');
47
+ }
48
+ console.log('✅ Ranking test passed');
49
+ }
50
+ async function testLimitParameter() {
51
+ console.log('Testing limit parameter...');
52
+ const documents = Array.from({ length: 10 }, (_, i) => ({
53
+ id: `doc${i}`,
54
+ content: `Document ${i} with test content`,
55
+ }));
56
+ const search = new BM25Search();
57
+ search.index(documents);
58
+ const results = search.search('test', 3);
59
+ if (results.length > 3) {
60
+ throw new Error(`Expected max 3 results, got ${results.length}`);
61
+ }
62
+ console.log('✅ Limit parameter test passed');
63
+ }
64
+ async function runTests() {
65
+ console.log('Running BM25 Search Tests\n');
66
+ console.log('='.repeat(50));
67
+ const tests = [
68
+ testIndexAndSearch,
69
+ testEmptyQuery,
70
+ testRanking,
71
+ testLimitParameter,
72
+ ];
73
+ let passed = 0;
74
+ let failed = 0;
75
+ for (const test of tests) {
76
+ try {
77
+ await test();
78
+ passed++;
79
+ }
80
+ catch (error) {
81
+ console.error(`❌ Test failed: ${error}`);
82
+ failed++;
83
+ }
84
+ }
85
+ console.log('\n' + '='.repeat(50));
86
+ console.log(`Results: ${passed} passed, ${failed} failed\n`);
87
+ return failed === 0;
88
+ }
89
+ // Run if executed directly
90
+ if (import.meta.url === `file://${process.argv[1]}`) {
91
+ runTests().then(success => {
92
+ process.exit(success ? 0 : 1);
93
+ }).catch(error => {
94
+ console.error('Test runner error:', error);
95
+ process.exit(1);
96
+ });
97
+ }
98
+ //# sourceMappingURL=bm25.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bm25.test.js","sourceRoot":"","sources":["../../tests/bm25.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../tests/integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,126 @@
1
+ // Integration test for ACM framework
2
+ import { ExternalContextProviderAdapter, } from '@ddse/acm-sdk';
3
+ import { MemoryLedger } from '@ddse/acm-runtime';
4
+ import { ACMFramework } from '@ddse/acm-framework';
5
+ import { SimpleCapabilityRegistry, SimpleToolRegistry } from '../src/registries.js';
6
+ import { registerExampleContextProviders } from '../src/context/index.js';
7
+ import { listScenarioKeys, scenarios } from '../src/examples/scenarios.js';
8
+ const stubLLMCall = async () => ({
9
+ reasoning: '',
10
+ toolCalls: [],
11
+ raw: {},
12
+ });
13
+ function createVerifyFn() {
14
+ return async (taskId, output, expressions) => {
15
+ for (const expr of expressions) {
16
+ try {
17
+ const fn = new Function('output', `return ${expr};`);
18
+ const result = fn(output);
19
+ if (!result) {
20
+ console.error(`Verification failed for ${taskId}: ${expr}`);
21
+ return false;
22
+ }
23
+ }
24
+ catch (error) {
25
+ console.error(`Verification error for ${taskId}: ${expr}`, error);
26
+ return false;
27
+ }
28
+ }
29
+ return true;
30
+ };
31
+ }
32
+ async function runScenario(definition) {
33
+ console.log(`\n▶️ Scenario: ${definition.name} (${definition.key})`);
34
+ const toolRegistry = new SimpleToolRegistry();
35
+ const capabilityRegistry = new SimpleCapabilityRegistry();
36
+ definition.registerTools(toolRegistry);
37
+ definition.registerCapabilities(capabilityRegistry);
38
+ const adapter = new ExternalContextProviderAdapter();
39
+ registerExampleContextProviders(adapter);
40
+ const framework = ACMFramework.create({
41
+ capabilityRegistry,
42
+ toolRegistry,
43
+ nucleus: {
44
+ call: stubLLMCall,
45
+ llmConfig: {
46
+ provider: 'test',
47
+ model: 'stub',
48
+ temperature: 0,
49
+ maxTokens: 0,
50
+ },
51
+ hooks: {
52
+ preflight: false,
53
+ postcheck: false,
54
+ },
55
+ },
56
+ verify: createVerifyFn(),
57
+ contextProvider: adapter,
58
+ });
59
+ const reference = await definition.buildReferencePlan();
60
+ const plan = reference.plan;
61
+ const ledger = new MemoryLedger();
62
+ const executeResult = await framework.execute({
63
+ goal: definition.goal,
64
+ context: definition.context,
65
+ ledger,
66
+ existingPlan: {
67
+ plan,
68
+ plannerResult: {
69
+ plans: [plan],
70
+ contextRef: plan.contextRef,
71
+ rationale: `${definition.name} reference plan`,
72
+ },
73
+ },
74
+ });
75
+ definition.assertExecution(executeResult.execution);
76
+ console.log(' ✅ Execution succeeded');
77
+ for (const task of plan.tasks) {
78
+ const record = executeResult.execution.outputsByTask?.[task.id];
79
+ if (!record?.output) {
80
+ throw new Error(`Task ${task.id} did not produce an output`);
81
+ }
82
+ }
83
+ if (executeResult.execution.ledger.length === 0) {
84
+ throw new Error('Ledger is empty after execution');
85
+ }
86
+ }
87
+ async function runIntegrationSuite() {
88
+ console.log('Running ACM Scenario Integration Suite');
89
+ console.log('='.repeat(50));
90
+ const keys = listScenarioKeys();
91
+ const results = [];
92
+ for (const key of keys) {
93
+ const scenario = scenarios[key];
94
+ try {
95
+ await runScenario(scenario);
96
+ results.push({ scenario, success: true });
97
+ }
98
+ catch (error) {
99
+ console.error(` ❌ Scenario failed: ${scenario.name}`);
100
+ console.error(error);
101
+ results.push({ scenario, success: false, error });
102
+ }
103
+ }
104
+ const passed = results.filter(r => r.success).length;
105
+ const failed = results.length - passed;
106
+ console.log('\n' + '='.repeat(50));
107
+ console.log(`Summary: ${passed} passed, ${failed} failed`);
108
+ if (failed > 0) {
109
+ console.log('\nFailed scenarios:');
110
+ for (const result of results.filter(r => !r.success)) {
111
+ console.log(` - ${result.scenario.name} (${result.scenario.key})`);
112
+ }
113
+ }
114
+ return failed === 0;
115
+ }
116
+ if (import.meta.url === `file://${process.argv[1]}`) {
117
+ runIntegrationSuite()
118
+ .then(success => {
119
+ process.exit(success ? 0 : 1);
120
+ })
121
+ .catch(error => {
122
+ console.error('Test runner error:', error);
123
+ process.exit(1);
124
+ });
125
+ }
126
+ //# sourceMappingURL=integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../tests/integration.test.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,OAAO,EACL,8BAA8B,GAa/B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,+BAA+B,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAA2B,MAAM,8BAA8B,CAAC;AAQpG,MAAM,WAAW,GAAc,KAAK,IAAI,EAAE,CAAC,CAAC;IAC1C,SAAS,EAAE,EAAE;IACb,SAAS,EAAE,EAAE;IACb,GAAG,EAAE,EAAE;CACR,CAAC,CAAC;AAEH,SAAS,cAAc;IACrB,OAAO,KAAK,EAAE,MAAc,EAAE,MAAW,EAAE,WAAqB,EAAoB,EAAE;QACpF,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,QAAQ,EAAE,UAAU,IAAI,GAAG,CAAC,CAAC;gBACrD,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;gBAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO,CAAC,KAAK,CAAC,2BAA2B,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;oBAC5D,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,MAAM,KAAK,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;gBAClE,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,UAA8B;IACvD,OAAO,CAAC,GAAG,CAAC,mBAAmB,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;IAEtE,MAAM,YAAY,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAC9C,MAAM,kBAAkB,GAAG,IAAI,wBAAwB,EAAE,CAAC;IAC1D,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACvC,UAAU,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;IAEpD,MAAM,OAAO,GAAG,IAAI,8BAA8B,EAAE,CAAC;IACrD,+BAA+B,CAAC,OAAO,CAAC,CAAC;IAEzC,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC;QACpC,kBAAkB;QAClB,YAAY;QACZ,OAAO,EAAE;YACP,IAAI,EAAE,WAAW;YACjB,SAAS,EAAE;gBACT,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,MAAM;gBACb,WAAW,EAAE,CAAC;gBACd,SAAS,EAAE,CAAC;aACb;YACD,KAAK,EAAE;gBACL,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,KAAK;aACjB;SACF;QACD,MAAM,EAAE,cAAc,EAAE;QACxB,eAAe,EAAE,OAAO;KACzB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,kBAAkB,EAAE,CAAC;IACxD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAElC,MAAM,aAAa,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC;QAC5C,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,MAAM;QACN,YAAY,EAAE;YACZ,IAAI;YACJ,aAAa,EAAE;gBACb,KAAK,EAAE,CAAC,IAAI,CAAC;gBACb,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,SAAS,EAAE,GAAG,UAAU,CAAC,IAAI,iBAAiB;aAC/C;SACF;KACF,CAAC,CAAC;IAEH,UAAU,CAAC,eAAe,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAEpD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAExC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,EAAE,4BAA4B,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,IAAI,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB;IAChC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACrD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IAEvC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,YAAY,MAAM,SAAS,CAAC,CAAC;IAE3D,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,OAAO,MAAM,KAAK,CAAC,CAAC;AACtB,CAAC;AAED,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,mBAAmB,EAAE;SAClB,IAAI,CAAC,OAAO,CAAC,EAAE;QACd,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC;SACD,KAAK,CAAC,KAAK,CAAC,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plan-hydration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-hydration.test.d.ts","sourceRoot":"","sources":["../../tests/plan-hydration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import { listScenarioKeys, scenarios } from '../src/examples/scenarios.js';
4
+ describe('scenario reference plans', () => {
5
+ for (const key of listScenarioKeys()) {
6
+ const scenario = scenarios[key];
7
+ it(`produces deterministic reference plan for ${scenario.name}`, async () => {
8
+ const reference = await scenario.buildReferencePlan();
9
+ const plan = reference.plan;
10
+ assert.ok(plan, 'Expected a plan to be returned');
11
+ assert.ok(Array.isArray(plan.tasks) && plan.tasks.length > 0, 'Plan must include at least one task');
12
+ for (const task of plan.tasks ?? []) {
13
+ assert.ok(task.id, 'Task must include a stable id');
14
+ assert.ok(task.capability ?? task.capabilityRef, 'Task must include a capability reference');
15
+ assert.ok(task.input && Object.keys(task.input).length > 0, 'Task must include deterministic input');
16
+ }
17
+ if (Array.isArray(plan.edges)) {
18
+ for (const edge of plan.edges) {
19
+ const fromExists = plan.tasks?.some(task => task.id === edge.from);
20
+ const toExists = plan.tasks?.some(task => task.id === edge.to);
21
+ assert.ok(fromExists, `Edge from ${edge.from} must reference an existing task`);
22
+ assert.ok(toExists, `Edge to ${edge.to} must reference an existing task`);
23
+ }
24
+ }
25
+ });
26
+ }
27
+ });
28
+ //# sourceMappingURL=plan-hydration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-hydration.test.js","sourceRoot":"","sources":["../../tests/plan-hydration.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE3E,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAEhC,EAAE,CAAC,6CAA6C,QAAQ,CAAC,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE;YAC1E,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,kBAAkB,EAAE,CAAC;YACtD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;YAE5B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,gCAAgC,CAAC,CAAC;YAClD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,qCAAqC,CAAC,CAAC;YAErG,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;gBACpC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,+BAA+B,CAAC,CAAC;gBACpD,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,aAAa,EAAE,0CAA0C,CAAC,CAAC;gBAC7F,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,uCAAuC,CAAC,CAAC;YACvG,CAAC;YAED,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;oBACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;oBAC/D,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,IAAI,CAAC,IAAI,kCAAkC,CAAC,CAAC;oBAChF,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,IAAI,CAAC,EAAE,kCAAkC,CAAC,CAAC;gBAC5E,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC"}