@revealui/ai 0.8.0 → 0.9.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 (79) hide show
  1. package/README.md +25 -12
  2. package/dist/client/hooks/useAgentStream.d.ts.map +1 -1
  3. package/dist/client/hooks/useAgentStream.js +1 -29
  4. package/dist/index.d.ts +11 -2
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +11 -2
  7. package/dist/inference/context-assembly.d.ts.map +1 -1
  8. package/dist/inference/context-assembly.js +1 -3
  9. package/dist/inference/overflow-compressor.d.ts.map +1 -1
  10. package/dist/inference/overflow-compressor.js +1 -3
  11. package/dist/ingestion/pipeline.d.ts.map +1 -1
  12. package/dist/ingestion/pipeline.js +1 -3
  13. package/dist/ingestion/text-splitter.d.ts.map +1 -1
  14. package/dist/ingestion/text-splitter.js +1 -3
  15. package/dist/internal/token-estimate.d.ts +6 -0
  16. package/dist/internal/token-estimate.d.ts.map +1 -0
  17. package/dist/internal/token-estimate.js +7 -0
  18. package/dist/llm/client.d.ts +4 -3
  19. package/dist/llm/client.d.ts.map +1 -1
  20. package/dist/llm/client.js +11 -4
  21. package/dist/llm/key-validator.d.ts.map +1 -1
  22. package/dist/llm/key-validator.js +42 -3
  23. package/dist/llm/local-ai-profile.d.ts +39 -0
  24. package/dist/llm/local-ai-profile.d.ts.map +1 -0
  25. package/dist/llm/local-ai-profile.js +165 -0
  26. package/dist/llm/providers/inference-snaps.d.ts +24 -13
  27. package/dist/llm/providers/inference-snaps.d.ts.map +1 -1
  28. package/dist/llm/providers/inference-snaps.js +21 -17
  29. package/dist/llm/providers/us-origin-snaps.d.ts +79 -0
  30. package/dist/llm/providers/us-origin-snaps.d.ts.map +1 -0
  31. package/dist/llm/providers/us-origin-snaps.js +108 -0
  32. package/dist/observability/export.d.ts +78 -0
  33. package/dist/observability/export.d.ts.map +1 -0
  34. package/dist/observability/export.js +229 -0
  35. package/dist/observability/index.d.ts +19 -0
  36. package/dist/observability/index.d.ts.map +1 -0
  37. package/dist/observability/index.js +16 -0
  38. package/dist/observability/instrumentation.d.ts +68 -0
  39. package/dist/observability/instrumentation.d.ts.map +1 -0
  40. package/dist/observability/instrumentation.js +219 -0
  41. package/dist/observability/storage.d.ts +39 -0
  42. package/dist/observability/storage.d.ts.map +1 -0
  43. package/dist/observability/storage.js +184 -0
  44. package/dist/orchestration/runtime.d.ts +7 -0
  45. package/dist/orchestration/runtime.d.ts.map +1 -1
  46. package/dist/orchestration/runtime.js +9 -2
  47. package/dist/orchestration/ticket-agent.d.ts +10 -0
  48. package/dist/orchestration/ticket-agent.d.ts.map +1 -1
  49. package/dist/orchestration/ticket-agent.js +7 -1
  50. package/dist/skills/index.d.ts +4 -0
  51. package/dist/skills/index.d.ts.map +1 -1
  52. package/dist/skills/index.js +4 -0
  53. package/dist/skills/integration/agent-skill-provider.d.ts +0 -5
  54. package/dist/skills/integration/agent-skill-provider.d.ts.map +1 -1
  55. package/dist/skills/integration/agent-skill-provider.js +3 -9
  56. package/dist/tools/admin/factory.d.ts +6 -0
  57. package/dist/tools/admin/factory.d.ts.map +1 -1
  58. package/dist/tools/admin/factory.js +3 -2
  59. package/dist/tools/coding/index.d.ts +6 -0
  60. package/dist/tools/coding/index.d.ts.map +1 -1
  61. package/dist/tools/coding/index.js +7 -2
  62. package/dist/tools/governance.d.ts +37 -0
  63. package/dist/tools/governance.d.ts.map +1 -0
  64. package/dist/tools/governance.js +42 -0
  65. package/dist/tools/integrity-audit.d.ts +27 -0
  66. package/dist/tools/integrity-audit.d.ts.map +1 -0
  67. package/dist/tools/integrity-audit.js +64 -0
  68. package/dist/tools/mcp-adapter.d.ts +23 -3
  69. package/dist/tools/mcp-adapter.d.ts.map +1 -1
  70. package/dist/tools/mcp-adapter.js +189 -132
  71. package/dist/tools/mcp-sampling.d.ts +3 -3
  72. package/dist/tools/mcp-sampling.js +3 -3
  73. package/dist/tools/web/duck-duck-go.d.ts.map +1 -1
  74. package/dist/tools/web/duck-duck-go.js +1 -4
  75. package/dist/tools/web/exa.d.ts.map +1 -1
  76. package/dist/tools/web/exa.js +1 -4
  77. package/dist/tools/web/tavily.d.ts.map +1 -1
  78. package/dist/tools/web/tavily.js +1 -4
  79. package/package.json +69 -34
package/README.md CHANGED
@@ -39,29 +39,41 @@ The recommended on-prem / on-device stack pairs `@revealui/ai` with a
39
39
 
40
40
 
41
41
  Canonical Inference Snap
42
- (DeepSeek R1, Qwen 2.5 VL,
43
- Gemma 3, Nemotron Nano
42
+ (US-origin allowlist only:
43
+ Nemotron 3 Nano / Omni, Gemma 3/4
44
44
  silicon-optimized on Intel/
45
45
  Ampere/NVIDIA/NPU)
46
46
  ```
47
47
 
48
+ **US-origin hardline:** product Inference Snaps usage allows only
49
+ `nemotron-3-nano`, `nemotron-3-nano-omni`, `gemma3`, and `gemma4`.
50
+ Non-US snaps in Canonical's catalog (`deepseek-r1`, `qwen-*`, `glm-*`) are
51
+ rejected at provider construction. Operator escape (never seed):
52
+ `REVEALUI_ALLOW_NON_US_MODELS=1`.
53
+
48
54
  Quick setup:
49
55
 
50
56
  ```bash
51
- sudo snap install gemma3 # or deepseek-r1, qwen-vl, etc.
52
- gemma3 set http.port=9090
53
- gemma3 status # confirms base URL
57
+ sudo snap install nemotron-3-nano # default; or gemma4 / nemotron-3-nano-omni
58
+ nemotron-3-nano set http.port=9090
59
+ nemotron-3-nano status # confirms base URL
54
60
  ```
55
61
 
56
62
  ```typescript
57
63
  import { InferenceSnapsProvider, LLMClient } from '@revealui/ai'
58
64
 
59
- const provider = new InferenceSnapsProvider({
65
+ const client = new LLMClient({
66
+ provider: 'inference-snaps',
67
+ apiKey: 'inference-snaps',
60
68
  baseURL: 'http://localhost:9090/v1',
61
- model: 'gemma3',
69
+ model: 'nemotron-3-nano', // default when omitted
62
70
  })
63
71
 
64
- const client = new LLMClient({ provider })
72
+ // Or the provider alone:
73
+ const provider = new InferenceSnapsProvider({
74
+ baseURL: 'http://localhost:9090/v1',
75
+ model: 'gemma4',
76
+ })
65
77
  ```
66
78
 
67
79
  Groq, Anthropic, OpenAI, and HuggingFace remain supported as pluggable,
@@ -189,7 +201,7 @@ import { InferenceSnapsProvider, createSamplingHandler } from '@revealui/ai'
189
201
 
190
202
  const llm = new InferenceSnapsProvider({
191
203
  baseURL: 'http://localhost:9090/v1',
192
- model: 'gemma3',
204
+ model: 'nemotron-3-nano',
193
205
  })
194
206
 
195
207
  const client = new McpClient({
@@ -197,8 +209,9 @@ const client = new McpClient({
197
209
  transport: { kind: 'streamable-http', url: 'https://example.com/mcp' },
198
210
  samplingHandler: createSamplingHandler({
199
211
  llm,
200
- defaultModel: 'gemma3',
201
- allowedModels: ['gemma3', 'deepseek-r1'], // strongly recommended
212
+ defaultModel: 'nemotron-3-nano',
213
+ // Keep sampling hints on the US-origin allowlist (provider also enforces).
214
+ allowedModels: ['nemotron-3-nano', 'gemma4', 'gemma3'],
202
215
  onSamplingRequest: (info) => {
203
216
  // metering / audit trail
204
217
  metrics.incr('mcp.sampling', { model: info.model })
@@ -255,7 +268,7 @@ pnpm --filter @revealui/ai test
255
268
  POSTGRES_URL="postgresql://..." pnpm --filter @revealui/ai test __tests__/integration
256
269
 
257
270
  # Production validation
258
- POSTGRES_URL="postgresql://..." ./scripts/validate-production.sh
271
+ pnpm --filter @revealui/ai test # production validation script retired; use package tests / gate
259
272
  ```
260
273
 
261
274
  ### Testing Limitations
@@ -1 +1 @@
1
- {"version":3,"file":"useAgentStream.d.ts","sourceRoot":"","sources":["../../../src/client/hooks/useAgentStream.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useAgentStream.d.ts","sourceRoot":"","sources":["../../../src/client/hooks/useAgentStream.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@
20
20
  * the check, so omitting the header when the cookie is absent is correct.
21
21
  */
22
22
  'use client';
23
+ import { readCsrfToken } from '@revealui/core/admin/utils/csrf';
23
24
  import { useCallback, useRef, useState } from 'react';
24
25
  const INITIAL_STATE = {
25
26
  text: '',
@@ -29,35 +30,6 @@ const INITIAL_STATE = {
29
30
  sessionId: null,
30
31
  pendingElicitations: [],
31
32
  };
32
- /**
33
- * Read the JS-readable `revealui-csrf` cookie. The api's csrfMiddleware
34
- * (`apps/server/src/middleware/csrf.ts`) requires it as an `X-CSRF-Token`
35
- * header on any session-cookie-bearing unsafe request; the admin proxy
36
- * issues it on page load. Returns undefined outside the browser or when
37
- * the cookie is absent/empty. Mirrors the cookie-read in `@revealui/core`'s
38
- * admin APIClient (`request()`).
39
- */
40
- function readCsrfToken() {
41
- if (typeof document === 'undefined')
42
- return undefined;
43
- for (const part of document.cookie.split(';')) {
44
- const eqIdx = part.indexOf('=');
45
- if (eqIdx === -1)
46
- continue;
47
- if (part.slice(0, eqIdx).trim() === 'revealui-csrf') {
48
- const raw = part.slice(eqIdx + 1).trim();
49
- if (!raw)
50
- return undefined;
51
- try {
52
- return decodeURIComponent(raw);
53
- }
54
- catch {
55
- return raw;
56
- }
57
- }
58
- }
59
- return undefined;
60
- }
61
33
  export function useAgentStream() {
62
34
  const [state, setState] = useState(INITIAL_STATE);
63
35
  const controllerRef = useRef(null);
package/dist/index.d.ts CHANGED
@@ -14,14 +14,19 @@
14
14
  * ```typescript
15
15
  * import { EpisodicMemory } from '@revealui/ai/memory/stores'
16
16
  * import { NodeIdService } from '@revealui/ai/memory/services'
17
+ * import { AgentOrchestrator, LLMClient, ToolRegistry } from '@revealui/ai'
17
18
  *
18
19
  * // Memory operations
19
20
  * const memory = new EpisodicMemory(userId, nodeId, db)
20
21
  * await memory.add(agentMemory)
21
- *
22
- * // LLM, orchestration, and tools coming soon
23
22
  * ```
24
23
  *
24
+ * LLM, orchestration, and tools all ship from this root entry today:
25
+ * `LLMClient` and `createLLMClientFromEnv` come from `./llm/client.js`,
26
+ * `AgentOrchestrator` from `./orchestration/orchestrator.js`, and
27
+ * `ToolRegistry` plus `globalToolRegistry` from `./tools/registry.js`.
28
+ * See the re-export block below for the full surface.
29
+ *
25
30
  * ## Architecture
26
31
  *
27
32
  * ```
@@ -50,10 +55,12 @@ export * from './audit/index.js';
50
55
  export * from './embeddings/index.js';
51
56
  export * from './ingestion/index.js';
52
57
  export * from './llm/client.js';
58
+ export * from './llm/local-ai-profile.js';
53
59
  export * from './llm/provider-health.js';
54
60
  export * from './llm/providers/base.js';
55
61
  export * from './llm/providers/inference-snaps.js';
56
62
  export * from './llm/providers/openai-compat.js';
63
+ export * from './llm/providers/us-origin-snaps.js';
57
64
  export * from './llm/resolve.js';
58
65
  export * from './llm/token-counter.js';
59
66
  export * from './llm/workspace-provider-config.js';
@@ -70,6 +77,8 @@ export * from './templates/index.js';
70
77
  export * from './tools/base.js';
71
78
  export * from './tools/deduplicator.js';
72
79
  export * from './tools/document-summarizer.js';
80
+ export * from './tools/governance.js';
81
+ export * from './tools/integrity-audit.js';
73
82
  export * from './tools/mcp-adapter.js';
74
83
  export * from './tools/mcp-elicitation.js';
75
84
  export * from './tools/mcp-events.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAIjC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,sBAAsB,CAAC;AAErC,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oCAAoC,CAAC;AAEnD,cAAc,mBAAmB,CAAC;AAElC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAChD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC;AAEhD,cAAc,mBAAmB,CAAC;AAElC,cAAc,sBAAsB,CAAC;AAErC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAGH,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAIjC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,sBAAsB,CAAC;AAErC,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,oCAAoC,CAAC;AACnD,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oCAAoC,CAAC;AAEnD,cAAc,mBAAmB,CAAC;AAElC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAChD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC;AAEhD,cAAc,mBAAmB,CAAC;AAElC,cAAc,sBAAsB,CAAC;AAErC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -14,14 +14,19 @@
14
14
  * ```typescript
15
15
  * import { EpisodicMemory } from '@revealui/ai/memory/stores'
16
16
  * import { NodeIdService } from '@revealui/ai/memory/services'
17
+ * import { AgentOrchestrator, LLMClient, ToolRegistry } from '@revealui/ai'
17
18
  *
18
19
  * // Memory operations
19
20
  * const memory = new EpisodicMemory(userId, nodeId, db)
20
21
  * await memory.add(agentMemory)
21
- *
22
- * // LLM, orchestration, and tools coming soon
23
22
  * ```
24
23
  *
24
+ * LLM, orchestration, and tools all ship from this root entry today:
25
+ * `LLMClient` and `createLLMClientFromEnv` come from `./llm/client.js`,
26
+ * `AgentOrchestrator` from `./orchestration/orchestrator.js`, and
27
+ * `ToolRegistry` plus `globalToolRegistry` from `./tools/registry.js`.
28
+ * See the re-export block below for the full surface.
29
+ *
25
30
  * ## Architecture
26
31
  *
27
32
  * ```
@@ -57,10 +62,12 @@ export * from './embeddings/index.js';
57
62
  export * from './ingestion/index.js';
58
63
  // Re-export LLM providers and client
59
64
  export * from './llm/client.js';
65
+ export * from './llm/local-ai-profile.js';
60
66
  export * from './llm/provider-health.js';
61
67
  export * from './llm/providers/base.js';
62
68
  export * from './llm/providers/inference-snaps.js';
63
69
  export * from './llm/providers/openai-compat.js';
70
+ export * from './llm/providers/us-origin-snaps.js';
64
71
  export * from './llm/resolve.js';
65
72
  export * from './llm/token-counter.js';
66
73
  export * from './llm/workspace-provider-config.js';
@@ -82,6 +89,8 @@ export * from './templates/index.js';
82
89
  export * from './tools/base.js';
83
90
  export * from './tools/deduplicator.js';
84
91
  export * from './tools/document-summarizer.js';
92
+ export * from './tools/governance.js';
93
+ export * from './tools/integrity-audit.js';
85
94
  export * from './tools/mcp-adapter.js';
86
95
  export * from './tools/mcp-elicitation.js';
87
96
  export * from './tools/mcp-events.js';
@@ -1 +1 @@
1
- {"version":3,"file":"context-assembly.d.ts","sourceRoot":"","sources":["../../src/inference/context-assembly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E,MAAM,WAAW,sBAAsB;IACrC,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA+BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EAAE,EAC1B,OAAO,EAAE,sBAAsB,GAC9B,MAAM,CAiDR"}
1
+ {"version":3,"file":"context-assembly.d.ts","sourceRoot":"","sources":["../../src/inference/context-assembly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAG1E,MAAM,WAAW,sBAAsB;IACrC,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA2BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EAAE,EAC1B,OAAO,EAAE,sBAAsB,GAC9B,MAAM,CAiDR"}
@@ -8,9 +8,7 @@
8
8
  * AnythingLLM lesson: plain cosine-only retrieval without recency weighting
9
9
  * produces stale, misleading context in long-running knowledge bases.
10
10
  */
11
- function estimateTokens(text) {
12
- return Math.ceil(text.length / 4);
13
- }
11
+ import { estimateTokens } from '../internal/token-estimate.js';
14
12
  /**
15
13
  * Compute a 0–1 recency score: newest chunk = 1.0, oldest = 0.1.
16
14
  * Decays linearly based on position in time-sorted array.
@@ -1 +1 @@
1
- {"version":3,"file":"overflow-compressor.d.ts","sourceRoot":"","sources":["../../src/inference/overflow-compressor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAMlD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,GACnD,OAAO,CAAC,MAAM,CAAC,CA4BjB"}
1
+ {"version":3,"file":"overflow-compressor.d.ts","sourceRoot":"","sources":["../../src/inference/overflow-compressor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,GACnD,OAAO,CAAC,MAAM,CAAC,CA4BjB"}
@@ -4,9 +4,7 @@
4
4
  * Called when assembled context exceeds the token budget.
5
5
  * Uses the LLM to summarize, preserving key facts.
6
6
  */
7
- function estimateTokens(text) {
8
- return Math.ceil(text.length / 4);
9
- }
7
+ import { estimateTokens } from '../internal/token-estimate.js';
10
8
  /**
11
9
  * Compress context string if it exceeds maxTokens.
12
10
  * Returns the original context if it fits within budget.
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/ingestion/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAOpD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAcD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,QAAQ,CAA6B;gBAEjC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;IAOtF,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA6EjD,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAa3D,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;CAiBjB"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/ingestion/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAQpD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAUD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,QAAQ,CAA6B;gBAEjC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;IAOtF,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA6EjD,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAa3D,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;CAiBjB"}
@@ -7,6 +7,7 @@
7
7
  import { ragChunks, ragDocuments } from '@revealui/db/schema/rag';
8
8
  import { safeVectorInsert } from '@revealui/db/validation';
9
9
  import { and, eq } from 'drizzle-orm';
10
+ import { estimateTokens } from '../internal/token-estimate.js';
10
11
  import { createParser } from './file-parsers.js';
11
12
  import { RecursiveCharacterSplitter } from './text-splitter.js';
12
13
  function generateId(prefix) {
@@ -15,9 +16,6 @@ function generateId(prefix) {
15
16
  function estimateWordCount(text) {
16
17
  return text.split(/\s+/).filter((w) => w.length > 0).length;
17
18
  }
18
- function estimateTokens(text) {
19
- return Math.ceil(text.length / 4);
20
- }
21
19
  export class IngestionPipeline {
22
20
  db;
23
21
  restDb;
@@ -1 +1 @@
1
- {"version":3,"file":"text-splitter.d.ts","sourceRoot":"","sources":["../../src/ingestion/text-splitter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AA4ED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,YAAiB;IAKtC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,EAAE;CAoCzD"}
1
+ {"version":3,"file":"text-splitter.d.ts","sourceRoot":"","sources":["../../src/ingestion/text-splitter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAwED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,YAAiB;IAKtC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,EAAE;CAoCzD"}
@@ -5,10 +5,8 @@
5
5
  * double-newline → single-newline → period+space → space
6
6
  * Token count is estimated as Math.ceil(length / 4) - sufficient for chunking.
7
7
  */
8
+ import { estimateTokens } from '../internal/token-estimate.js';
8
9
  const SEPARATORS = ['\n\n', '\n', '. ', ' '];
9
- function estimateTokens(text) {
10
- return Math.ceil(text.length / 4);
11
- }
12
10
  function splitOnSeparator(text, separator) {
13
11
  if (!text.includes(separator))
14
12
  return [text];
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Heuristic token estimate used across AI package internals.
3
+ * ~4 characters per token (English-ish average). Not a model tokenizer.
4
+ */
5
+ export declare function estimateTokens(text: string): number;
6
+ //# sourceMappingURL=token-estimate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-estimate.d.ts","sourceRoot":"","sources":["../../src/internal/token-estimate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Heuristic token estimate used across AI package internals.
3
+ * ~4 characters per token (English-ish average). Not a model tokenizer.
4
+ */
5
+ export function estimateTokens(text) {
6
+ return Math.ceil(text.length / 4);
7
+ }
@@ -146,11 +146,12 @@ export declare class LLMClient {
146
146
  * (Anthropic + OpenAI ride their OpenAI-compatible endpoints).
147
147
  *
148
148
  * Canonical Inference Snaps is the reference local provider on Ubuntu — offline,
149
- * silicon-optimized, no API key required. See `providers/inference-snaps.ts` for
150
- * install docs (`sudo snap install gemma3`, etc.).
149
+ * silicon-optimized, no API key required. Product usage is **US-origin snaps
150
+ * only** (nemotron-3-nano default; gemma3/4 also allowlisted). See
151
+ * `providers/us-origin-snaps.ts` and `providers/inference-snaps.ts`.
151
152
  *
152
153
  * Provider defaults:
153
- * inference-snaps → gemma3 (base URL defaults to http://localhost:9090/v1)
154
+ * inference-snaps → nemotron-3-nano (base URL defaults to http://localhost:9090/v1)
154
155
  * groq → qwen/qwen3-32b
155
156
  * ollama → gemma4:e2b (base URL defaults to http://localhost:11434)
156
157
  * anthropic → claude-sonnet-4-6 (base URL defaults to https://api.anthropic.com/v1)
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/llm/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/llm/client.ts"],"names":[],"mappings":"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"}
@@ -10,12 +10,14 @@ import { decryptApiKey } from '@revealui/db/crypto';
10
10
  import { tenantProviderConfigs, userApiKeys } from '@revealui/db/schema';
11
11
  import { CircuitBreaker, CircuitBreakerOpenError, } from '@revealui/resilience';
12
12
  import { and, eq } from 'drizzle-orm';
13
+ import { applyLocalAiProfileToEnv } from './local-ai-profile.js';
13
14
  import { AnthropicProvider } from './providers/anthropic.js';
14
15
  import { GroqProvider } from './providers/groq.js';
15
16
  import { InferenceSnapsProvider, } from './providers/inference-snaps.js';
16
17
  import { OllamaProvider } from './providers/ollama.js';
17
18
  import { OpenAIProvider } from './providers/openai.js';
18
19
  import { OpenAICompatProvider } from './providers/openai-compat.js';
20
+ import { DEFAULT_US_ORIGIN_INFERENCE_SNAP } from './providers/us-origin-snaps.js';
19
21
  import { XaiProvider } from './providers/xai.js';
20
22
  import { ResponseCache } from './response-cache.js';
21
23
  import { SemanticCache, } from './semantic-cache.js';
@@ -461,11 +463,12 @@ export class LLMClient {
461
463
  * (Anthropic + OpenAI ride their OpenAI-compatible endpoints).
462
464
  *
463
465
  * Canonical Inference Snaps is the reference local provider on Ubuntu — offline,
464
- * silicon-optimized, no API key required. See `providers/inference-snaps.ts` for
465
- * install docs (`sudo snap install gemma3`, etc.).
466
+ * silicon-optimized, no API key required. Product usage is **US-origin snaps
467
+ * only** (nemotron-3-nano default; gemma3/4 also allowlisted). See
468
+ * `providers/us-origin-snaps.ts` and `providers/inference-snaps.ts`.
466
469
  *
467
470
  * Provider defaults:
468
- * inference-snaps → gemma3 (base URL defaults to http://localhost:9090/v1)
471
+ * inference-snaps → nemotron-3-nano (base URL defaults to http://localhost:9090/v1)
469
472
  * groq → qwen/qwen3-32b
470
473
  * ollama → gemma4:e2b (base URL defaults to http://localhost:11434)
471
474
  * anthropic → claude-sonnet-4-6 (base URL defaults to https://api.anthropic.com/v1)
@@ -473,6 +476,9 @@ export class LLMClient {
473
476
  * xai → grok-4.5 (base URL defaults to https://api.x.ai/v1)
474
477
  */
475
478
  export function createLLMClientFromEnv() {
479
+ // Self-host profile (idle/daily/snaps) fills missing LLM_* only; explicit env wins.
480
+ // Hosted (VERCEL / REVEALUI_HOSTED) never loads the profile.
481
+ applyLocalAiProfileToEnv();
476
482
  // Auto-detect provider when LLM_PROVIDER is not explicitly set. The existing
477
483
  // priority order (INFERENCE_SNAPS → GROQ → OLLAMA) is preserved so existing
478
484
  // deployments resolve identically; the frontier providers are appended after.
@@ -548,8 +554,9 @@ export function createLLMClientFromEnv() {
548
554
  apiKey = 'inference-snaps'; // inference-snaps ignores the API key
549
555
  // Defaults to Canonical's Inference Snap local service on port 9090; override
550
556
  // via INFERENCE_SNAPS_BASE_URL when the snap listens on a non-default port.
557
+ // Model defaults to the US-origin allowlist default (asserted in provider ctor).
551
558
  baseURL = process.env.INFERENCE_SNAPS_BASE_URL ?? 'http://localhost:9090/v1';
552
- defaultModel = 'gemma3';
559
+ defaultModel = DEFAULT_US_ORIGIN_INFERENCE_SNAP;
553
560
  }
554
561
  if (!apiKey) {
555
562
  throw new Error(`API key not found for provider "${provider}". Set the corresponding env var ` +
@@ -1 +1 @@
1
- {"version":3,"file":"key-validator.d.ts","sourceRoot":"","sources":["../../src/llm/key-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,wBAAwB,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAezF;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,wBAAwB,CAAC,CA2CnC"}
1
+ {"version":3,"file":"key-validator.d.ts","sourceRoot":"","sources":["../../src/llm/key-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,wBAAwB,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAezF;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,wBAAwB,CAAC,CAkFnC"}
@@ -30,6 +30,44 @@ async function probeFetch(url, init) {
30
30
  export async function validateProviderKey(provider, apiKey) {
31
31
  try {
32
32
  switch (provider) {
33
+ case 'anthropic': {
34
+ // Cheapest read-only probe: the models list. Honors the same base-URL
35
+ // override as the env factory (client.ts) so self-hosted proxies work.
36
+ const base = process.env.ANTHROPIC_BASE_URL ?? 'https://api.anthropic.com/v1';
37
+ const res = await probeFetch(`${base}/models`, {
38
+ headers: { 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' },
39
+ });
40
+ if (res.ok)
41
+ return { valid: true };
42
+ if (res.status === 401 || res.status === 403) {
43
+ return { valid: false, error: 'Invalid Anthropic API key' };
44
+ }
45
+ return { valid: false, error: `Anthropic validation failed: HTTP ${res.status}` };
46
+ }
47
+ case 'openai': {
48
+ const base = process.env.OPENAI_BASE_URL ?? 'https://api.openai.com/v1';
49
+ const res = await probeFetch(`${base}/models`, {
50
+ headers: { Authorization: `Bearer ${apiKey}` },
51
+ });
52
+ if (res.ok)
53
+ return { valid: true };
54
+ if (res.status === 401 || res.status === 403) {
55
+ return { valid: false, error: 'Invalid OpenAI API key' };
56
+ }
57
+ return { valid: false, error: `OpenAI validation failed: HTTP ${res.status}` };
58
+ }
59
+ case 'xai': {
60
+ const base = process.env.XAI_BASE_URL ?? 'https://api.x.ai/v1';
61
+ const res = await probeFetch(`${base}/models`, {
62
+ headers: { Authorization: `Bearer ${apiKey}` },
63
+ });
64
+ if (res.ok)
65
+ return { valid: true };
66
+ if (res.status === 401 || res.status === 403) {
67
+ return { valid: false, error: 'Invalid xAI API key' };
68
+ }
69
+ return { valid: false, error: `xAI validation failed: HTTP ${res.status}` };
70
+ }
33
71
  case 'groq': {
34
72
  const res = await probeFetch('https://api.groq.com/openai/v1/models', {
35
73
  headers: { Authorization: `Bearer ${apiKey}` },
@@ -52,9 +90,10 @@ export async function validateProviderKey(provider, apiKey) {
52
90
  }
53
91
  return { valid: false, error: `HuggingFace validation failed: HTTP ${res.status}` };
54
92
  }
55
- case 'ollama': {
56
- // Ollama is local - we cannot reliably probe it from the server.
57
- // Accept the key as-is (Ollama doesn't use API keys anyway).
93
+ case 'ollama':
94
+ case 'inference-snaps': {
95
+ // Local providers - we cannot reliably probe them from the server,
96
+ // and neither uses a real API key. Accept the key as-is.
58
97
  return { valid: true };
59
98
  }
60
99
  default:
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Self-host local AI profile (host resource tiers).
3
+ *
4
+ * Written by harnesses `InferenceService.profileApply` (control plane).
5
+ * Read by `createLLMClientFromEnv` to fill missing LLM_* env (self-host only).
6
+ *
7
+ * Tiers: idle | daily | snaps | heavy — see ADR US-origin + operator LOCAL-AI.md.
8
+ * Hosted deployments must never load this file into a serverless process path.
9
+ */
10
+ export type LocalAiTier = 'idle' | 'daily' | 'snaps' | 'heavy';
11
+ export type LocalAiProvider = 'ollama' | 'inference-snaps' | null;
12
+ export interface LocalAiProfile {
13
+ tier: LocalAiTier;
14
+ provider: LocalAiProvider;
15
+ model: string | null;
16
+ baseURL: string | null;
17
+ /** Ollama models directory (hot store) */
18
+ ollamaModelsDir: string | null;
19
+ /** Ollama keep_alive (e.g. "0" unloads after each request) */
20
+ keepAlive: string | null;
21
+ updatedAt: string;
22
+ /** Optional free-text note (e.g. RAM warning) */
23
+ note?: string;
24
+ }
25
+ export declare function getLocalAiProfilePath(): string;
26
+ /** Shell-compat env file written alongside the JSON profile. */
27
+ export declare function getLocalAiActiveEnvPath(): string;
28
+ /** Idle profile with best-effort hot model dir detection. */
29
+ export declare function emptyIdleProfile(): LocalAiProfile;
30
+ export declare function loadLocalAiProfile(path?: string): LocalAiProfile | null;
31
+ export declare function saveLocalAiProfile(profile: LocalAiProfile, path?: string): void;
32
+ /**
33
+ * Fill missing process.env LLM_* keys from the self-host profile.
34
+ * Never overrides explicit env. No-op when REVEALUI_SKIP_INFERENCE_PROFILE=1
35
+ * or when REVEALUI_HOSTED=1 / VERCEL (hosted fail-closed).
36
+ */
37
+ export declare function applyLocalAiProfileToEnv(env?: NodeJS.ProcessEnv, profile?: LocalAiProfile | null): void;
38
+ export declare function profileDefaultsForTier(tier: LocalAiTier): Pick<LocalAiProfile, 'provider' | 'model' | 'baseURL' | 'keepAlive' | 'note'>;
39
+ //# sourceMappingURL=local-ai-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-ai-profile.d.ts","sourceRoot":"","sources":["../../src/llm/local-ai-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAE/D,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,iBAAiB,GAAG,IAAI,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,0CAA0C;IAC1C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,8DAA8D;IAC9D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAK9C;AAED,gEAAgE;AAChE,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,IAAI,cAAc,CAiBjD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,MAAgC,GAAG,cAAc,GAAG,IAAI,CAShG;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,cAAc,EACvB,IAAI,GAAE,MAAgC,GACrC,IAAI,CAqCN;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,cAAc,GAAG,IAA2B,GACpD,IAAI,CAyBN;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,GAChB,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC,CAuC/E"}