@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.
Files changed (124) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +625 -0
  3. package/examples/basic/aeon.config.ts +39 -0
  4. package/examples/basic/components/Cursor.tsx +86 -0
  5. package/examples/basic/components/OfflineIndicator.tsx +103 -0
  6. package/examples/basic/components/PresenceBar.tsx +77 -0
  7. package/examples/basic/package.json +20 -0
  8. package/examples/basic/pages/index.tsx +80 -0
  9. package/package.json +101 -0
  10. package/packages/analytics/README.md +309 -0
  11. package/packages/analytics/build.ts +35 -0
  12. package/packages/analytics/package.json +50 -0
  13. package/packages/analytics/src/click-tracker.ts +368 -0
  14. package/packages/analytics/src/context-bridge.ts +319 -0
  15. package/packages/analytics/src/data-layer.ts +302 -0
  16. package/packages/analytics/src/gtm-loader.ts +239 -0
  17. package/packages/analytics/src/index.ts +230 -0
  18. package/packages/analytics/src/merkle-tree.ts +489 -0
  19. package/packages/analytics/src/provider.tsx +300 -0
  20. package/packages/analytics/src/types.ts +320 -0
  21. package/packages/analytics/src/use-analytics.ts +296 -0
  22. package/packages/analytics/tsconfig.json +19 -0
  23. package/packages/benchmarks/src/benchmark.test.ts +691 -0
  24. package/packages/cli/dist/index.js +61899 -0
  25. package/packages/cli/package.json +43 -0
  26. package/packages/cli/src/commands/build.test.ts +682 -0
  27. package/packages/cli/src/commands/build.ts +890 -0
  28. package/packages/cli/src/commands/dev.ts +473 -0
  29. package/packages/cli/src/commands/init.ts +409 -0
  30. package/packages/cli/src/commands/start.ts +297 -0
  31. package/packages/cli/src/index.ts +105 -0
  32. package/packages/directives/src/use-aeon.ts +272 -0
  33. package/packages/mcp-server/package.json +51 -0
  34. package/packages/mcp-server/src/index.ts +178 -0
  35. package/packages/mcp-server/src/resources.ts +346 -0
  36. package/packages/mcp-server/src/tools/index.ts +36 -0
  37. package/packages/mcp-server/src/tools/navigation.ts +545 -0
  38. package/packages/mcp-server/tsconfig.json +21 -0
  39. package/packages/react/package.json +40 -0
  40. package/packages/react/src/Link.tsx +388 -0
  41. package/packages/react/src/components/InstallPrompt.tsx +286 -0
  42. package/packages/react/src/components/OfflineDiagnostics.tsx +677 -0
  43. package/packages/react/src/components/PushNotifications.tsx +453 -0
  44. package/packages/react/src/hooks/useAeonNavigation.ts +219 -0
  45. package/packages/react/src/hooks/useConflicts.ts +277 -0
  46. package/packages/react/src/hooks/useNetworkState.ts +209 -0
  47. package/packages/react/src/hooks/usePilotNavigation.ts +254 -0
  48. package/packages/react/src/hooks/useServiceWorker.ts +278 -0
  49. package/packages/react/src/hooks.ts +195 -0
  50. package/packages/react/src/index.ts +151 -0
  51. package/packages/react/src/provider.tsx +467 -0
  52. package/packages/react/tsconfig.json +19 -0
  53. package/packages/runtime/README.md +399 -0
  54. package/packages/runtime/build.ts +48 -0
  55. package/packages/runtime/package.json +71 -0
  56. package/packages/runtime/schema.sql +40 -0
  57. package/packages/runtime/src/api-routes.ts +465 -0
  58. package/packages/runtime/src/benchmark.ts +171 -0
  59. package/packages/runtime/src/cache.ts +479 -0
  60. package/packages/runtime/src/durable-object.ts +1341 -0
  61. package/packages/runtime/src/index.ts +360 -0
  62. package/packages/runtime/src/navigation.test.ts +421 -0
  63. package/packages/runtime/src/navigation.ts +422 -0
  64. package/packages/runtime/src/nextjs-adapter.ts +272 -0
  65. package/packages/runtime/src/offline/encrypted-queue.test.ts +607 -0
  66. package/packages/runtime/src/offline/encrypted-queue.ts +478 -0
  67. package/packages/runtime/src/offline/encryption.test.ts +412 -0
  68. package/packages/runtime/src/offline/encryption.ts +397 -0
  69. package/packages/runtime/src/offline/types.ts +465 -0
  70. package/packages/runtime/src/predictor.ts +371 -0
  71. package/packages/runtime/src/registry.ts +351 -0
  72. package/packages/runtime/src/router/context-extractor.ts +661 -0
  73. package/packages/runtime/src/router/esi-control-react.tsx +2053 -0
  74. package/packages/runtime/src/router/esi-control.ts +541 -0
  75. package/packages/runtime/src/router/esi-cyrano.ts +779 -0
  76. package/packages/runtime/src/router/esi-format-react.tsx +1744 -0
  77. package/packages/runtime/src/router/esi-react.tsx +1065 -0
  78. package/packages/runtime/src/router/esi-translate-observer.ts +476 -0
  79. package/packages/runtime/src/router/esi-translate-react.tsx +556 -0
  80. package/packages/runtime/src/router/esi-translate.ts +503 -0
  81. package/packages/runtime/src/router/esi.ts +666 -0
  82. package/packages/runtime/src/router/heuristic-adapter.test.ts +295 -0
  83. package/packages/runtime/src/router/heuristic-adapter.ts +557 -0
  84. package/packages/runtime/src/router/index.ts +298 -0
  85. package/packages/runtime/src/router/merkle-capability.ts +473 -0
  86. package/packages/runtime/src/router/speculation.ts +451 -0
  87. package/packages/runtime/src/router/types.ts +630 -0
  88. package/packages/runtime/src/router.test.ts +470 -0
  89. package/packages/runtime/src/router.ts +302 -0
  90. package/packages/runtime/src/server.ts +481 -0
  91. package/packages/runtime/src/service-worker-push.ts +319 -0
  92. package/packages/runtime/src/service-worker.ts +553 -0
  93. package/packages/runtime/src/skeleton-hydrate.ts +237 -0
  94. package/packages/runtime/src/speculation.test.ts +389 -0
  95. package/packages/runtime/src/speculation.ts +486 -0
  96. package/packages/runtime/src/storage.test.ts +1297 -0
  97. package/packages/runtime/src/storage.ts +1048 -0
  98. package/packages/runtime/src/sync/conflict-resolver.test.ts +528 -0
  99. package/packages/runtime/src/sync/conflict-resolver.ts +565 -0
  100. package/packages/runtime/src/sync/coordinator.test.ts +608 -0
  101. package/packages/runtime/src/sync/coordinator.ts +596 -0
  102. package/packages/runtime/src/tree-compiler.ts +295 -0
  103. package/packages/runtime/src/types.ts +728 -0
  104. package/packages/runtime/src/worker.ts +327 -0
  105. package/packages/runtime/tsconfig.json +20 -0
  106. package/packages/runtime/wasm/aeon_pages_runtime.d.ts +504 -0
  107. package/packages/runtime/wasm/aeon_pages_runtime.js +1657 -0
  108. package/packages/runtime/wasm/aeon_pages_runtime_bg.wasm +0 -0
  109. package/packages/runtime/wasm/aeon_pages_runtime_bg.wasm.d.ts +196 -0
  110. package/packages/runtime/wasm/package.json +21 -0
  111. package/packages/runtime/wrangler.toml +41 -0
  112. package/packages/runtime-wasm/Cargo.lock +436 -0
  113. package/packages/runtime-wasm/Cargo.toml +29 -0
  114. package/packages/runtime-wasm/pkg/aeon_pages_runtime.d.ts +480 -0
  115. package/packages/runtime-wasm/pkg/aeon_pages_runtime.js +1568 -0
  116. package/packages/runtime-wasm/pkg/aeon_pages_runtime_bg.wasm +0 -0
  117. package/packages/runtime-wasm/pkg/aeon_pages_runtime_bg.wasm.d.ts +192 -0
  118. package/packages/runtime-wasm/pkg/package.json +21 -0
  119. package/packages/runtime-wasm/src/hydrate.rs +352 -0
  120. package/packages/runtime-wasm/src/lib.rs +191 -0
  121. package/packages/runtime-wasm/src/render.rs +629 -0
  122. package/packages/runtime-wasm/src/router.rs +298 -0
  123. package/packages/runtime-wasm/src/skeleton.rs +430 -0
  124. 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';