@affectively/aeon-pages 1.3.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.
- package/CHANGELOG.md +112 -0
- package/README.md +625 -0
- package/examples/basic/aeon.config.ts +39 -0
- package/examples/basic/components/Cursor.tsx +86 -0
- package/examples/basic/components/OfflineIndicator.tsx +103 -0
- package/examples/basic/components/PresenceBar.tsx +77 -0
- package/examples/basic/package.json +20 -0
- package/examples/basic/pages/index.tsx +80 -0
- package/package.json +101 -0
- package/packages/analytics/README.md +309 -0
- package/packages/analytics/build.ts +35 -0
- package/packages/analytics/package.json +50 -0
- package/packages/analytics/src/click-tracker.ts +368 -0
- package/packages/analytics/src/context-bridge.ts +319 -0
- package/packages/analytics/src/data-layer.ts +302 -0
- package/packages/analytics/src/gtm-loader.ts +239 -0
- package/packages/analytics/src/index.ts +230 -0
- package/packages/analytics/src/merkle-tree.ts +489 -0
- package/packages/analytics/src/provider.tsx +300 -0
- package/packages/analytics/src/types.ts +320 -0
- package/packages/analytics/src/use-analytics.ts +296 -0
- package/packages/analytics/tsconfig.json +19 -0
- package/packages/benchmarks/src/benchmark.test.ts +691 -0
- package/packages/cli/dist/index.js +61899 -0
- package/packages/cli/package.json +43 -0
- package/packages/cli/src/commands/build.test.ts +682 -0
- package/packages/cli/src/commands/build.ts +890 -0
- package/packages/cli/src/commands/dev.ts +473 -0
- package/packages/cli/src/commands/init.ts +409 -0
- package/packages/cli/src/commands/start.ts +297 -0
- package/packages/cli/src/index.ts +105 -0
- package/packages/directives/src/use-aeon.ts +272 -0
- package/packages/mcp-server/package.json +51 -0
- package/packages/mcp-server/src/index.ts +178 -0
- package/packages/mcp-server/src/resources.ts +346 -0
- package/packages/mcp-server/src/tools/index.ts +36 -0
- package/packages/mcp-server/src/tools/navigation.ts +545 -0
- package/packages/mcp-server/tsconfig.json +21 -0
- package/packages/react/package.json +40 -0
- package/packages/react/src/Link.tsx +388 -0
- package/packages/react/src/components/InstallPrompt.tsx +286 -0
- package/packages/react/src/components/OfflineDiagnostics.tsx +677 -0
- package/packages/react/src/components/PushNotifications.tsx +453 -0
- package/packages/react/src/hooks/useAeonNavigation.ts +219 -0
- package/packages/react/src/hooks/useConflicts.ts +277 -0
- package/packages/react/src/hooks/useNetworkState.ts +209 -0
- package/packages/react/src/hooks/usePilotNavigation.ts +254 -0
- package/packages/react/src/hooks/useServiceWorker.ts +278 -0
- package/packages/react/src/hooks.ts +195 -0
- package/packages/react/src/index.ts +151 -0
- package/packages/react/src/provider.tsx +467 -0
- package/packages/react/tsconfig.json +19 -0
- package/packages/runtime/README.md +399 -0
- package/packages/runtime/build.ts +48 -0
- package/packages/runtime/package.json +71 -0
- package/packages/runtime/schema.sql +40 -0
- package/packages/runtime/src/api-routes.ts +465 -0
- package/packages/runtime/src/benchmark.ts +171 -0
- package/packages/runtime/src/cache.ts +479 -0
- package/packages/runtime/src/durable-object.ts +1341 -0
- package/packages/runtime/src/index.ts +360 -0
- package/packages/runtime/src/navigation.test.ts +421 -0
- package/packages/runtime/src/navigation.ts +422 -0
- package/packages/runtime/src/nextjs-adapter.ts +272 -0
- package/packages/runtime/src/offline/encrypted-queue.test.ts +607 -0
- package/packages/runtime/src/offline/encrypted-queue.ts +478 -0
- package/packages/runtime/src/offline/encryption.test.ts +412 -0
- package/packages/runtime/src/offline/encryption.ts +397 -0
- package/packages/runtime/src/offline/types.ts +465 -0
- package/packages/runtime/src/predictor.ts +371 -0
- package/packages/runtime/src/registry.ts +351 -0
- package/packages/runtime/src/router/context-extractor.ts +661 -0
- package/packages/runtime/src/router/esi-control-react.tsx +2053 -0
- package/packages/runtime/src/router/esi-control.ts +541 -0
- package/packages/runtime/src/router/esi-cyrano.ts +779 -0
- package/packages/runtime/src/router/esi-format-react.tsx +1744 -0
- package/packages/runtime/src/router/esi-react.tsx +1065 -0
- package/packages/runtime/src/router/esi-translate-observer.ts +476 -0
- package/packages/runtime/src/router/esi-translate-react.tsx +556 -0
- package/packages/runtime/src/router/esi-translate.ts +503 -0
- package/packages/runtime/src/router/esi.ts +666 -0
- package/packages/runtime/src/router/heuristic-adapter.test.ts +295 -0
- package/packages/runtime/src/router/heuristic-adapter.ts +557 -0
- package/packages/runtime/src/router/index.ts +298 -0
- package/packages/runtime/src/router/merkle-capability.ts +473 -0
- package/packages/runtime/src/router/speculation.ts +451 -0
- package/packages/runtime/src/router/types.ts +630 -0
- package/packages/runtime/src/router.test.ts +470 -0
- package/packages/runtime/src/router.ts +302 -0
- package/packages/runtime/src/server.ts +481 -0
- package/packages/runtime/src/service-worker-push.ts +319 -0
- package/packages/runtime/src/service-worker.ts +553 -0
- package/packages/runtime/src/skeleton-hydrate.ts +237 -0
- package/packages/runtime/src/speculation.test.ts +389 -0
- package/packages/runtime/src/speculation.ts +486 -0
- package/packages/runtime/src/storage.test.ts +1297 -0
- package/packages/runtime/src/storage.ts +1048 -0
- package/packages/runtime/src/sync/conflict-resolver.test.ts +528 -0
- package/packages/runtime/src/sync/conflict-resolver.ts +565 -0
- package/packages/runtime/src/sync/coordinator.test.ts +608 -0
- package/packages/runtime/src/sync/coordinator.ts +596 -0
- package/packages/runtime/src/tree-compiler.ts +295 -0
- package/packages/runtime/src/types.ts +728 -0
- package/packages/runtime/src/worker.ts +327 -0
- package/packages/runtime/tsconfig.json +20 -0
- package/packages/runtime/wasm/aeon_pages_runtime.d.ts +504 -0
- package/packages/runtime/wasm/aeon_pages_runtime.js +1657 -0
- package/packages/runtime/wasm/aeon_pages_runtime_bg.wasm +0 -0
- package/packages/runtime/wasm/aeon_pages_runtime_bg.wasm.d.ts +196 -0
- package/packages/runtime/wasm/package.json +21 -0
- package/packages/runtime/wrangler.toml +41 -0
- package/packages/runtime-wasm/Cargo.lock +436 -0
- package/packages/runtime-wasm/Cargo.toml +29 -0
- package/packages/runtime-wasm/pkg/aeon_pages_runtime.d.ts +480 -0
- package/packages/runtime-wasm/pkg/aeon_pages_runtime.js +1568 -0
- package/packages/runtime-wasm/pkg/aeon_pages_runtime_bg.wasm +0 -0
- package/packages/runtime-wasm/pkg/aeon_pages_runtime_bg.wasm.d.ts +192 -0
- package/packages/runtime-wasm/pkg/package.json +21 -0
- package/packages/runtime-wasm/src/hydrate.rs +352 -0
- package/packages/runtime-wasm/src/lib.rs +191 -0
- package/packages/runtime-wasm/src/render.rs +629 -0
- package/packages/runtime-wasm/src/router.rs +298 -0
- package/packages/runtime-wasm/src/skeleton.rs +430 -0
- package/rfcs/RFC-001-ZERO-DEPENDENCY-RENDERING.md +1446 -0
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Router Types for Aeon Flux
|
|
3
|
+
*
|
|
4
|
+
* Defines the core types for the personalized routing system.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// User Context
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
export interface EmotionState {
|
|
12
|
+
/** Primary detected emotion */
|
|
13
|
+
primary: string;
|
|
14
|
+
/** Valence: negative (-1) to positive (1) */
|
|
15
|
+
valence: number;
|
|
16
|
+
/** Arousal: calm (0) to excited (1) */
|
|
17
|
+
arousal: number;
|
|
18
|
+
/** Confidence in detection (0-1) */
|
|
19
|
+
confidence: number;
|
|
20
|
+
/** Related emotions with intensity */
|
|
21
|
+
related?: Array<{ emotion: string; intensity: number }>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface Viewport {
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
devicePixelRatio?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type ConnectionType = 'slow-2g' | '2g' | '3g' | '4g' | 'fast';
|
|
31
|
+
export type UserTier = 'free' | 'starter' | 'pro' | 'enterprise' | 'admin';
|
|
32
|
+
|
|
33
|
+
export interface UserContext {
|
|
34
|
+
// Identity
|
|
35
|
+
userId?: string;
|
|
36
|
+
tier: UserTier;
|
|
37
|
+
/** Admin flag - bypasses ALL tier restrictions */
|
|
38
|
+
isAdmin?: boolean;
|
|
39
|
+
|
|
40
|
+
// Behavioral signals
|
|
41
|
+
recentPages: string[];
|
|
42
|
+
dwellTimes: Map<string, number>;
|
|
43
|
+
clickPatterns: string[];
|
|
44
|
+
|
|
45
|
+
// Emotional/cognitive state (from edge-workers)
|
|
46
|
+
emotionState?: EmotionState;
|
|
47
|
+
|
|
48
|
+
// Explicit preferences
|
|
49
|
+
preferences: Record<string, unknown>;
|
|
50
|
+
|
|
51
|
+
// Device context
|
|
52
|
+
viewport: Viewport;
|
|
53
|
+
connection: ConnectionType;
|
|
54
|
+
reducedMotion: boolean;
|
|
55
|
+
|
|
56
|
+
// Time context
|
|
57
|
+
localHour: number;
|
|
58
|
+
timezone: string;
|
|
59
|
+
|
|
60
|
+
// Session info
|
|
61
|
+
sessionId?: string;
|
|
62
|
+
isNewSession: boolean;
|
|
63
|
+
sessionStartedAt?: Date;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// Route Decision
|
|
68
|
+
// ============================================================================
|
|
69
|
+
|
|
70
|
+
export type ThemeMode = 'light' | 'dark' | 'auto';
|
|
71
|
+
export type LayoutDensity = 'compact' | 'normal' | 'comfortable';
|
|
72
|
+
export type LayoutType =
|
|
73
|
+
| 'dashboard'
|
|
74
|
+
| 'chat'
|
|
75
|
+
| 'settings'
|
|
76
|
+
| 'tools'
|
|
77
|
+
| 'marketing'
|
|
78
|
+
| 'custom';
|
|
79
|
+
|
|
80
|
+
export interface SkeletonHints {
|
|
81
|
+
layout: LayoutType;
|
|
82
|
+
estimatedHeight: number;
|
|
83
|
+
sections?: Array<{
|
|
84
|
+
id: string;
|
|
85
|
+
height: number;
|
|
86
|
+
priority: number;
|
|
87
|
+
}>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface RouteDecision {
|
|
91
|
+
// Primary route
|
|
92
|
+
route: string;
|
|
93
|
+
sessionId: string;
|
|
94
|
+
|
|
95
|
+
// Personalization
|
|
96
|
+
componentOrder?: string[];
|
|
97
|
+
hiddenComponents?: string[];
|
|
98
|
+
featureFlags?: Record<string, boolean>;
|
|
99
|
+
|
|
100
|
+
// Theming
|
|
101
|
+
theme?: ThemeMode;
|
|
102
|
+
accent?: string;
|
|
103
|
+
density?: LayoutDensity;
|
|
104
|
+
|
|
105
|
+
// Speculation hints
|
|
106
|
+
prefetch?: string[];
|
|
107
|
+
prerender?: string[];
|
|
108
|
+
|
|
109
|
+
// Skeleton hints
|
|
110
|
+
skeleton?: SkeletonHints;
|
|
111
|
+
|
|
112
|
+
// Metadata
|
|
113
|
+
routedAt: number;
|
|
114
|
+
routerName: string;
|
|
115
|
+
confidence: number;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ============================================================================
|
|
119
|
+
// Component Tree (simplified for routing)
|
|
120
|
+
// ============================================================================
|
|
121
|
+
|
|
122
|
+
export interface ComponentNode {
|
|
123
|
+
id: string;
|
|
124
|
+
type: string;
|
|
125
|
+
props?: Record<string, unknown>;
|
|
126
|
+
children?: string[];
|
|
127
|
+
// Personalization metadata
|
|
128
|
+
requiredTier?: UserTier;
|
|
129
|
+
relevanceSignals?: string[];
|
|
130
|
+
defaultHidden?: boolean;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface ComponentTree {
|
|
134
|
+
rootId: string;
|
|
135
|
+
nodes: Map<string, ComponentNode>;
|
|
136
|
+
|
|
137
|
+
// Methods
|
|
138
|
+
getNode(id: string): ComponentNode | undefined;
|
|
139
|
+
getChildren(id: string): ComponentNode[];
|
|
140
|
+
getSchema(): ComponentTreeSchema;
|
|
141
|
+
clone(): ComponentTree;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface ComponentTreeSchema {
|
|
145
|
+
rootId: string;
|
|
146
|
+
nodeCount: number;
|
|
147
|
+
nodeTypes: string[];
|
|
148
|
+
depth: number;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// Router Adapter Interface
|
|
153
|
+
// ============================================================================
|
|
154
|
+
|
|
155
|
+
export interface RouterAdapter {
|
|
156
|
+
/** Adapter name for logging/debugging */
|
|
157
|
+
name: string;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Route a request with user context
|
|
161
|
+
* Returns personalized routing decision
|
|
162
|
+
*/
|
|
163
|
+
route(
|
|
164
|
+
path: string,
|
|
165
|
+
context: UserContext,
|
|
166
|
+
tree: ComponentTree,
|
|
167
|
+
): Promise<RouteDecision>;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Speculate likely next paths for prefetching
|
|
171
|
+
* Returns ordered list of probable next routes
|
|
172
|
+
*/
|
|
173
|
+
speculate(currentPath: string, context: UserContext): Promise<string[]>;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Apply personalization to component tree
|
|
177
|
+
* Returns modified tree based on route decision
|
|
178
|
+
*/
|
|
179
|
+
personalizeTree(tree: ComponentTree, decision: RouteDecision): ComponentTree;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Compute accent color from emotion state
|
|
183
|
+
*/
|
|
184
|
+
emotionToAccent?(emotionState: EmotionState): string;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ============================================================================
|
|
188
|
+
// Router Configuration
|
|
189
|
+
// ============================================================================
|
|
190
|
+
|
|
191
|
+
export interface AIRouterConfig {
|
|
192
|
+
endpoint: string;
|
|
193
|
+
timeout: number;
|
|
194
|
+
fallbackToHeuristic: boolean;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export interface SpeculationConfig {
|
|
198
|
+
enabled: boolean;
|
|
199
|
+
depth: number;
|
|
200
|
+
prerenderTop: number;
|
|
201
|
+
maxPrefetch: number;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export interface PersonalizationConfig {
|
|
205
|
+
featureGating: boolean;
|
|
206
|
+
emotionTheming: boolean;
|
|
207
|
+
componentOrdering: boolean;
|
|
208
|
+
densityAdaptation: boolean;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface RouterConfig {
|
|
212
|
+
adapter: 'heuristic' | 'ai' | 'hybrid' | RouterAdapter;
|
|
213
|
+
ai?: AIRouterConfig;
|
|
214
|
+
speculation?: SpeculationConfig;
|
|
215
|
+
personalization?: PersonalizationConfig;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export const DEFAULT_ROUTER_CONFIG: RouterConfig = {
|
|
219
|
+
adapter: 'heuristic',
|
|
220
|
+
speculation: {
|
|
221
|
+
enabled: true,
|
|
222
|
+
depth: 2,
|
|
223
|
+
prerenderTop: 1,
|
|
224
|
+
maxPrefetch: 5,
|
|
225
|
+
},
|
|
226
|
+
personalization: {
|
|
227
|
+
featureGating: true,
|
|
228
|
+
emotionTheming: true,
|
|
229
|
+
componentOrdering: true,
|
|
230
|
+
densityAdaptation: true,
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
// ============================================================================
|
|
235
|
+
// Edge Side Inference (ESI)
|
|
236
|
+
// ============================================================================
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* ESI - Edge Side Inference
|
|
240
|
+
*
|
|
241
|
+
* Like Varnish's ESI (Edge Side Includes) but for AI inference.
|
|
242
|
+
* Components can invoke edge inference at render time, embedding AI
|
|
243
|
+
* directly in templates.
|
|
244
|
+
*
|
|
245
|
+
* Example usage in templates:
|
|
246
|
+
* ```tsx
|
|
247
|
+
* <ESI.Infer model="llm" prompt="Greet the user warmly" />
|
|
248
|
+
* <ESI.Infer model="llm">Summarize: {content}</ESI.Infer>
|
|
249
|
+
* <ESI.Embed>Some text to embed</ESI.Embed>
|
|
250
|
+
* <ESI.Emotion>How is the user feeling?</ESI.Emotion>
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
|
|
254
|
+
export type ESIModel =
|
|
255
|
+
| 'llm' // Text generation
|
|
256
|
+
| 'embed' // Embeddings
|
|
257
|
+
| 'vision' // Image analysis
|
|
258
|
+
| 'tts' // Text-to-speech
|
|
259
|
+
| 'stt' // Speech-to-text
|
|
260
|
+
| 'emotion' // Emotion detection
|
|
261
|
+
| 'classify' // Classification
|
|
262
|
+
| 'translate' // Translation
|
|
263
|
+
| 'custom'; // Custom model
|
|
264
|
+
|
|
265
|
+
export type ESIContentType =
|
|
266
|
+
| 'text' // Plain text prompt
|
|
267
|
+
| 'base64' // Base64 encoded (images, audio)
|
|
268
|
+
| 'json' // Structured data
|
|
269
|
+
| 'template'; // Template with interpolation
|
|
270
|
+
|
|
271
|
+
export interface ESIParams {
|
|
272
|
+
/** Model to use for inference */
|
|
273
|
+
model: ESIModel;
|
|
274
|
+
|
|
275
|
+
/** Specific model variant (e.g., 'gpt-4', 'mistral-7b') */
|
|
276
|
+
variant?: string;
|
|
277
|
+
|
|
278
|
+
/** Temperature for generation (0-2) */
|
|
279
|
+
temperature?: number;
|
|
280
|
+
|
|
281
|
+
/** Maximum tokens to generate */
|
|
282
|
+
maxTokens?: number;
|
|
283
|
+
|
|
284
|
+
/** Stop sequences */
|
|
285
|
+
stop?: string[];
|
|
286
|
+
|
|
287
|
+
/** Top-p sampling */
|
|
288
|
+
topP?: number;
|
|
289
|
+
|
|
290
|
+
/** Frequency penalty */
|
|
291
|
+
frequencyPenalty?: number;
|
|
292
|
+
|
|
293
|
+
/** Presence penalty */
|
|
294
|
+
presencePenalty?: number;
|
|
295
|
+
|
|
296
|
+
/** System prompt for context */
|
|
297
|
+
system?: string;
|
|
298
|
+
|
|
299
|
+
/** Enable streaming response */
|
|
300
|
+
stream?: boolean;
|
|
301
|
+
|
|
302
|
+
/** Cache duration in seconds (0 = no cache) */
|
|
303
|
+
cacheTtl?: number;
|
|
304
|
+
|
|
305
|
+
/** Cache key (auto-generated if not provided) */
|
|
306
|
+
cacheKey?: string;
|
|
307
|
+
|
|
308
|
+
/** Timeout in milliseconds */
|
|
309
|
+
timeout?: number;
|
|
310
|
+
|
|
311
|
+
/** Fallback content if inference fails */
|
|
312
|
+
fallback?: string;
|
|
313
|
+
|
|
314
|
+
/** Custom parameters for the model */
|
|
315
|
+
custom?: Record<string, unknown>;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export interface ESIContent {
|
|
319
|
+
/** Content type */
|
|
320
|
+
type: ESIContentType;
|
|
321
|
+
|
|
322
|
+
/** The actual content (prompt, base64 data, etc.) */
|
|
323
|
+
value: string;
|
|
324
|
+
|
|
325
|
+
/** Template variables for interpolation */
|
|
326
|
+
variables?: Record<string, unknown>;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export interface ESIDirective {
|
|
330
|
+
/** Unique ID for this ESI directive */
|
|
331
|
+
id: string;
|
|
332
|
+
|
|
333
|
+
/** Inference parameters */
|
|
334
|
+
params: ESIParams;
|
|
335
|
+
|
|
336
|
+
/** Content to process */
|
|
337
|
+
content: ESIContent;
|
|
338
|
+
|
|
339
|
+
/** Required user tier (for feature gating) */
|
|
340
|
+
requiredTier?: UserTier;
|
|
341
|
+
|
|
342
|
+
/** Context-aware: inject UserContext into prompt */
|
|
343
|
+
contextAware?: boolean;
|
|
344
|
+
|
|
345
|
+
/** Personalization signals to include */
|
|
346
|
+
signals?: Array<'emotion' | 'preferences' | 'history' | 'time' | 'device'>;
|
|
347
|
+
|
|
348
|
+
/** Cache key for this directive (auto-generated if not provided) */
|
|
349
|
+
cacheKey?: string;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export interface ESIResult {
|
|
353
|
+
/** Directive ID */
|
|
354
|
+
id: string;
|
|
355
|
+
|
|
356
|
+
/** Success status */
|
|
357
|
+
success: boolean;
|
|
358
|
+
|
|
359
|
+
/** Generated output */
|
|
360
|
+
output?: string;
|
|
361
|
+
|
|
362
|
+
/** For embeddings */
|
|
363
|
+
embedding?: number[];
|
|
364
|
+
|
|
365
|
+
/** For audio (TTS) */
|
|
366
|
+
audio?: ArrayBuffer;
|
|
367
|
+
|
|
368
|
+
/** Error message if failed */
|
|
369
|
+
error?: string;
|
|
370
|
+
|
|
371
|
+
/** Inference latency in ms */
|
|
372
|
+
latencyMs: number;
|
|
373
|
+
|
|
374
|
+
/** Was result from cache */
|
|
375
|
+
cached: boolean;
|
|
376
|
+
|
|
377
|
+
/** Model used */
|
|
378
|
+
model: string;
|
|
379
|
+
|
|
380
|
+
/** Tokens used (if applicable) */
|
|
381
|
+
tokens?: {
|
|
382
|
+
prompt: number;
|
|
383
|
+
completion: number;
|
|
384
|
+
total: number;
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export interface ESIProcessor {
|
|
389
|
+
/** Processor name */
|
|
390
|
+
name: string;
|
|
391
|
+
|
|
392
|
+
/** Process a single ESI directive */
|
|
393
|
+
process(directive: ESIDirective, context: UserContext): Promise<ESIResult>;
|
|
394
|
+
|
|
395
|
+
/** Process multiple directives (batch optimization) */
|
|
396
|
+
processBatch(
|
|
397
|
+
directives: ESIDirective[],
|
|
398
|
+
context: UserContext,
|
|
399
|
+
): Promise<ESIResult[]>;
|
|
400
|
+
|
|
401
|
+
/** Stream inference result */
|
|
402
|
+
stream?(
|
|
403
|
+
directive: ESIDirective,
|
|
404
|
+
context: UserContext,
|
|
405
|
+
onChunk: (chunk: string) => void,
|
|
406
|
+
): Promise<ESIResult>;
|
|
407
|
+
|
|
408
|
+
/** Warm up the processor (pre-load models, etc.) */
|
|
409
|
+
warmup?(): Promise<void>;
|
|
410
|
+
|
|
411
|
+
/** Check if a model is available */
|
|
412
|
+
isModelAvailable(model: ESIModel): boolean;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export interface ESIConfig {
|
|
416
|
+
/** Enable ESI processing */
|
|
417
|
+
enabled: boolean;
|
|
418
|
+
|
|
419
|
+
/** Edge inference endpoint */
|
|
420
|
+
endpoint: string;
|
|
421
|
+
|
|
422
|
+
/** Default timeout for inference */
|
|
423
|
+
timeout: number;
|
|
424
|
+
|
|
425
|
+
/** Default cache TTL */
|
|
426
|
+
defaultCacheTtl: number;
|
|
427
|
+
|
|
428
|
+
/** Maximum concurrent inferences */
|
|
429
|
+
maxConcurrent: number;
|
|
430
|
+
|
|
431
|
+
/** Models to pre-warm */
|
|
432
|
+
warmupModels?: ESIModel[];
|
|
433
|
+
|
|
434
|
+
/** Custom processor (plugin architecture) */
|
|
435
|
+
processor?: ESIProcessor;
|
|
436
|
+
|
|
437
|
+
/** Feature gating by tier */
|
|
438
|
+
tierLimits?: Record<
|
|
439
|
+
UserTier,
|
|
440
|
+
{
|
|
441
|
+
maxInferencesPerRequest: number;
|
|
442
|
+
allowedModels: ESIModel[];
|
|
443
|
+
maxTokens: number;
|
|
444
|
+
}
|
|
445
|
+
>;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
export const DEFAULT_ESI_CONFIG: ESIConfig = {
|
|
449
|
+
enabled: false, // Optional plugin - disabled by default
|
|
450
|
+
endpoint: process.env.ESI_ENDPOINT || '', // Must be configured by app
|
|
451
|
+
timeout: 5000,
|
|
452
|
+
defaultCacheTtl: 300, // 5 minutes
|
|
453
|
+
maxConcurrent: 5,
|
|
454
|
+
warmupModels: ['llm'],
|
|
455
|
+
// Default tier limits - override in your app config
|
|
456
|
+
tierLimits: {
|
|
457
|
+
free: {
|
|
458
|
+
maxInferencesPerRequest: 2,
|
|
459
|
+
allowedModels: ['llm', 'embed'],
|
|
460
|
+
maxTokens: 500,
|
|
461
|
+
},
|
|
462
|
+
starter: {
|
|
463
|
+
maxInferencesPerRequest: 5,
|
|
464
|
+
allowedModels: ['llm', 'embed', 'classify'],
|
|
465
|
+
maxTokens: 1000,
|
|
466
|
+
},
|
|
467
|
+
pro: {
|
|
468
|
+
maxInferencesPerRequest: 20,
|
|
469
|
+
allowedModels: ['llm', 'embed', 'classify', 'vision', 'tts'],
|
|
470
|
+
maxTokens: 4000,
|
|
471
|
+
},
|
|
472
|
+
enterprise: {
|
|
473
|
+
maxInferencesPerRequest: 100,
|
|
474
|
+
allowedModels: [
|
|
475
|
+
'llm',
|
|
476
|
+
'embed',
|
|
477
|
+
'classify',
|
|
478
|
+
'vision',
|
|
479
|
+
'tts',
|
|
480
|
+
'stt',
|
|
481
|
+
'custom',
|
|
482
|
+
],
|
|
483
|
+
maxTokens: 32000,
|
|
484
|
+
},
|
|
485
|
+
admin: {
|
|
486
|
+
maxInferencesPerRequest: 999999,
|
|
487
|
+
allowedModels: [
|
|
488
|
+
'llm',
|
|
489
|
+
'embed',
|
|
490
|
+
'classify',
|
|
491
|
+
'vision',
|
|
492
|
+
'tts',
|
|
493
|
+
'stt',
|
|
494
|
+
'emotion',
|
|
495
|
+
'custom',
|
|
496
|
+
],
|
|
497
|
+
maxTokens: 999999,
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
// Extended router config with ESI
|
|
503
|
+
export interface RouterConfigWithESI extends RouterConfig {
|
|
504
|
+
esi?: ESIConfig;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// ============================================================================
|
|
508
|
+
// Presence Types (for ESI Collaborative)
|
|
509
|
+
// ============================================================================
|
|
510
|
+
|
|
511
|
+
/** Presence info for a user/agent */
|
|
512
|
+
export interface PresenceUser {
|
|
513
|
+
/** User or agent ID */
|
|
514
|
+
userId: string;
|
|
515
|
+
|
|
516
|
+
/** User or agent role */
|
|
517
|
+
role: 'user' | 'assistant' | 'monitor' | 'admin';
|
|
518
|
+
|
|
519
|
+
/** Cursor position */
|
|
520
|
+
cursor?: { x: number; y: number };
|
|
521
|
+
|
|
522
|
+
/** Currently editing element path */
|
|
523
|
+
editingPath?: string;
|
|
524
|
+
|
|
525
|
+
/** User display name */
|
|
526
|
+
name?: string;
|
|
527
|
+
|
|
528
|
+
/** Avatar URL or initials */
|
|
529
|
+
avatar?: string;
|
|
530
|
+
|
|
531
|
+
/** Last active timestamp */
|
|
532
|
+
lastActive?: Date;
|
|
533
|
+
|
|
534
|
+
/** Is this a real-time presence (vs cached) */
|
|
535
|
+
isLive?: boolean;
|
|
536
|
+
|
|
537
|
+
/** User status (online, idle, etc.) */
|
|
538
|
+
status?: 'online' | 'idle' | 'away' | 'busy' | 'offline';
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// ============================================================================
|
|
542
|
+
// Translation Types
|
|
543
|
+
// ============================================================================
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Result of a translation operation
|
|
547
|
+
*/
|
|
548
|
+
export interface TranslationResult {
|
|
549
|
+
/** Original text that was translated */
|
|
550
|
+
original: string;
|
|
551
|
+
|
|
552
|
+
/** Translated text */
|
|
553
|
+
translated: string;
|
|
554
|
+
|
|
555
|
+
/** Source language (detected or specified) */
|
|
556
|
+
sourceLanguage: string;
|
|
557
|
+
|
|
558
|
+
/** Target language */
|
|
559
|
+
targetLanguage: string;
|
|
560
|
+
|
|
561
|
+
/** Translation confidence (0-1) */
|
|
562
|
+
confidence: number;
|
|
563
|
+
|
|
564
|
+
/** Was result from cache */
|
|
565
|
+
cached: boolean;
|
|
566
|
+
|
|
567
|
+
/** Latency in milliseconds */
|
|
568
|
+
latencyMs: number;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Configuration for the TranslationProvider
|
|
573
|
+
*/
|
|
574
|
+
export interface TranslationProviderConfig {
|
|
575
|
+
/** Default target language (ISO 639-1 code) */
|
|
576
|
+
defaultLanguage: string;
|
|
577
|
+
|
|
578
|
+
/** Fallback language if translation fails */
|
|
579
|
+
fallbackLanguage?: string;
|
|
580
|
+
|
|
581
|
+
/** Auto-detect source language */
|
|
582
|
+
autoDetectSource?: boolean;
|
|
583
|
+
|
|
584
|
+
/** AI Gateway endpoint for translation */
|
|
585
|
+
endpoint?: string;
|
|
586
|
+
|
|
587
|
+
/** Cache TTL in seconds (default: 86400 = 24 hours) */
|
|
588
|
+
cacheTtl?: number;
|
|
589
|
+
|
|
590
|
+
/** Maximum text length to translate (default: 5000 chars) */
|
|
591
|
+
maxTextLength?: number;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Supported language codes for translation
|
|
596
|
+
*/
|
|
597
|
+
export type SupportedLanguageCode =
|
|
598
|
+
| 'en'
|
|
599
|
+
| 'es'
|
|
600
|
+
| 'fr'
|
|
601
|
+
| 'de'
|
|
602
|
+
| 'it'
|
|
603
|
+
| 'pt'
|
|
604
|
+
| 'nl'
|
|
605
|
+
| 'pl'
|
|
606
|
+
| 'ru'
|
|
607
|
+
| 'zh'
|
|
608
|
+
| 'ja'
|
|
609
|
+
| 'ko'
|
|
610
|
+
| 'ar'
|
|
611
|
+
| 'hi'
|
|
612
|
+
| 'bn'
|
|
613
|
+
| 'vi'
|
|
614
|
+
| 'th'
|
|
615
|
+
| 'tr'
|
|
616
|
+
| 'id'
|
|
617
|
+
| 'ms'
|
|
618
|
+
| 'tl'
|
|
619
|
+
| 'sv'
|
|
620
|
+
| 'da'
|
|
621
|
+
| 'no'
|
|
622
|
+
| 'fi'
|
|
623
|
+
| 'cs'
|
|
624
|
+
| 'el'
|
|
625
|
+
| 'he'
|
|
626
|
+
| 'uk'
|
|
627
|
+
| 'ro'
|
|
628
|
+
| 'hu'
|
|
629
|
+
| 'ca'
|
|
630
|
+
| 'hy';
|