@dreamingai/sdk 0.1.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/dist/index.js ADDED
@@ -0,0 +1,1396 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // Dreaming AI — TypeScript SDK
4
+ //
5
+ // The primary client SDK for Dreaming AI Platform.
6
+ // Used by: TekkoStudio Web, Tekko AI Mobile (Expo), Node.js apps
7
+ //
8
+ // Zero dependencies — uses native fetch API.
9
+ // ============================================================
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.DreamingClient = exports.DreamingError = void 0;
12
+ // ─── HTTP Client ─────────────────────────────────────────────
13
+ class HttpClient {
14
+ constructor(config) {
15
+ this.baseUrl = (config.baseUrl ?? 'https://api.dreaming.ai').replace(/\/$/, '');
16
+ this.headers = {
17
+ 'Authorization': `Bearer ${config.apiKey}`,
18
+ 'X-Dreaming-App-Id': config.appId,
19
+ 'Content-Type': 'application/json',
20
+ };
21
+ this.timeout = config.timeout ?? 30000;
22
+ }
23
+ async request(method, path, body) {
24
+ const controller = new AbortController();
25
+ const timer = setTimeout(() => controller.abort(), this.timeout);
26
+ try {
27
+ const res = await fetch(`${this.baseUrl}${path}`, {
28
+ method,
29
+ headers: this.headers,
30
+ body: body ? JSON.stringify(body) : undefined,
31
+ signal: controller.signal,
32
+ });
33
+ if (!res.ok) {
34
+ const error = await res.json().catch(() => ({ message: res.statusText }));
35
+ throw new DreamingError(error.code ?? 'API_ERROR', error.message ?? res.statusText, res.status);
36
+ }
37
+ return await res.json();
38
+ }
39
+ finally {
40
+ clearTimeout(timer);
41
+ }
42
+ }
43
+ get(path) { return this.request('GET', path); }
44
+ post(path, body) { return this.request('POST', path, body); }
45
+ patch(path, body) { return this.request('PATCH', path, body); }
46
+ delete(path) { return this.request('DELETE', path); }
47
+ }
48
+ // ─── Error Class ─────────────────────────────────────────────
49
+ class DreamingError extends Error {
50
+ constructor(code, message, status) {
51
+ super(message);
52
+ this.code = code;
53
+ this.status = status;
54
+ this.name = 'DreamingError';
55
+ }
56
+ }
57
+ exports.DreamingError = DreamingError;
58
+ // ─── Resource Clients ────────────────────────────────────────
59
+ class MemoriesClient {
60
+ constructor(http) {
61
+ this.http = http;
62
+ }
63
+ async create(input) {
64
+ return this.http.post('/v1/memories', input);
65
+ }
66
+ async list(userId, options) {
67
+ const params = new URLSearchParams({ userId });
68
+ if (options?.limit)
69
+ params.set('limit', String(options.limit));
70
+ if (options?.offset)
71
+ params.set('offset', String(options.offset));
72
+ if (options?.types)
73
+ params.set('types', options.types.join(','));
74
+ return this.http.get(`/v1/memories?${params}`);
75
+ }
76
+ async get(id) {
77
+ return this.http.get(`/v1/memories/${id}`);
78
+ }
79
+ async delete(id) {
80
+ return this.http.delete(`/v1/memories/${id}`);
81
+ }
82
+ async search(input) {
83
+ return this.http.post('/v1/memories/search', input);
84
+ }
85
+ async recall(input) {
86
+ return this.http.post('/v1/memories/recall', input);
87
+ }
88
+ }
89
+ class DreamingApiClient {
90
+ constructor(http) {
91
+ this.http = http;
92
+ }
93
+ async process(input) {
94
+ return this.http.post('/v1/dreaming/process', input);
95
+ }
96
+ async consolidate(userId) {
97
+ return this.http.post('/v1/dreaming/consolidate', { userId });
98
+ }
99
+ async getInsights(userId, limit) {
100
+ const params = new URLSearchParams({ userId });
101
+ if (limit)
102
+ params.set('limit', String(limit));
103
+ return this.http.get(`/v1/dreaming/insights?${params}`);
104
+ }
105
+ async getStatus() {
106
+ return this.http.get('/v1/dreaming/status');
107
+ }
108
+ }
109
+ class GraphClient {
110
+ constructor(http) {
111
+ this.http = http;
112
+ }
113
+ async addEntity(userId, name, entityType, properties) {
114
+ return this.http.post('/v1/graph/entities', { userId, name, entityType, properties });
115
+ }
116
+ async addTriple(userId, subject, predicate, object, options) {
117
+ return this.http.post('/v1/graph/triples', { userId, subject, predicate, object, ...options });
118
+ }
119
+ async query(userId, options) {
120
+ return this.http.post('/v1/graph/query', { userId, ...options });
121
+ }
122
+ async getEntityFacts(userId, entityName) {
123
+ return this.http.get(`/v1/graph/entities/${encodeURIComponent(entityName)}/facts?userId=${userId}`);
124
+ }
125
+ }
126
+ class PersonalityClient {
127
+ constructor(http) {
128
+ this.http = http;
129
+ }
130
+ async getOcean(userId) {
131
+ return this.http.get(`/v1/personality/ocean?userId=${userId}`);
132
+ }
133
+ async analyzeOcean(userId, text) {
134
+ return this.http.post('/v1/personality/analyze', { userId, text });
135
+ }
136
+ async getFingerprint(userId) {
137
+ return this.http.get(`/v1/personality/fingerprint?userId=${userId}`);
138
+ }
139
+ }
140
+ // ─── Status Client ───────────────────────────────────────────
141
+ class StatusClient {
142
+ constructor(http) {
143
+ this.http = http;
144
+ }
145
+ /** Get current AI cognitive state (for orb rendering) */
146
+ async getStatus(userId) {
147
+ const params = userId ? `?userId=${userId}` : '';
148
+ return this.http.get(`/v1/status${params}`);
149
+ }
150
+ /** Get detailed brain health metrics (for settings page) */
151
+ async getBrainHealth(userId) {
152
+ const params = userId ? `?userId=${userId}` : '';
153
+ return this.http.get(`/v1/status/brain${params}`);
154
+ }
155
+ /** Get quota usage and limits */
156
+ async getQuota(userId) {
157
+ const params = userId ? `?userId=${userId}` : '';
158
+ const res = await this.http.get(`/v1/admin/quota${params}`);
159
+ return res.data || res;
160
+ }
161
+ }
162
+ // ─── Sync Client ─────────────────────────────────────────────
163
+ class SyncClient {
164
+ constructor(http) {
165
+ this.http = http;
166
+ }
167
+ /** Get user's global sync settings */
168
+ async getSettings(userId) {
169
+ const params = userId ? `?userId=${userId}` : '';
170
+ const res = await this.http.get(`/v1/sync/settings${params}`);
171
+ return res.data || res;
172
+ }
173
+ /** Update sync settings (global toggle + category toggles) */
174
+ async updateSettings(input) {
175
+ const res = await this.http.post('/v1/sync/settings', input);
176
+ return res.data || res;
177
+ }
178
+ /** Get consent status for all partner workspaces */
179
+ async getConsents(userId, appId) {
180
+ const params = new URLSearchParams();
181
+ if (userId)
182
+ params.set('userId', userId);
183
+ if (appId)
184
+ params.set('appId', appId);
185
+ const res = await this.http.get(`/v1/sync/consent?${params}`);
186
+ return res.data?.workspaces || [];
187
+ }
188
+ /** Accept, pause, resume, or decline sync with a target workspace */
189
+ async updateConsent(input) {
190
+ const res = await this.http.post('/v1/sync/consent', {
191
+ target_workspace_id: input.targetWorkspaceId,
192
+ action: input.action,
193
+ userId: input.userId,
194
+ domain: input.domain,
195
+ name: input.name,
196
+ });
197
+ return res.data || res;
198
+ }
199
+ /** Get privacy exposure toggles */
200
+ async getExposure(userId, appId) {
201
+ const params = new URLSearchParams();
202
+ if (userId)
203
+ params.set('userId', userId);
204
+ if (appId)
205
+ params.set('appId', appId);
206
+ const res = await this.http.get(`/v1/privacy/exposure?${params}`);
207
+ return res.data || res;
208
+ }
209
+ /** Update privacy exposure toggles */
210
+ async updateExposure(toggles, userId) {
211
+ const res = await this.http.post('/v1/privacy/exposure', {
212
+ toggles, userId,
213
+ });
214
+ return res.data?.toggles || res.data || toggles;
215
+ }
216
+ }
217
+ // ─── Context Client ──────────────────────────────────────────
218
+ class ContextClient {
219
+ constructor(http) {
220
+ this.http = http;
221
+ }
222
+ /** Get pre-built context string for injection into LLM prompts */
223
+ async getContext(userId) {
224
+ return this.http.get(`/v1/memories/recall?userId=${userId}&limit=10`);
225
+ }
226
+ /** Before-chat hook: enrich messages with context (for non-middleware integrations) */
227
+ async beforeChat(input) {
228
+ const res = await this.http.post('/v1/dreaming/process', {
229
+ userId: input.userId,
230
+ conversation: input.messages,
231
+ });
232
+ return res.messages || input.messages;
233
+ }
234
+ /** After-chat hook: queue conversation for sleeptime processing */
235
+ async afterChat(input) {
236
+ return this.http.post('/v1/dreaming/process', {
237
+ userId: input.userId,
238
+ conversation: input.messages,
239
+ });
240
+ }
241
+ }
242
+ const TIER_COLORS = {
243
+ efficient: '#22c55e', // green-500
244
+ smart: '#3b82f6', // blue-500
245
+ genius: '#a855f7', // purple-500
246
+ };
247
+ const TIER_ORDER = ['efficient', 'smart', 'genius'];
248
+ class MeterClient {
249
+ constructor(http) {
250
+ this.http = http;
251
+ }
252
+ /** Get current model tier status for the authenticated user */
253
+ async getStatus(userId) {
254
+ const params = userId ? `?userId=${userId}` : '';
255
+ const res = await this.http.get(`/v1/meter/status${params}`);
256
+ return res.data || res;
257
+ }
258
+ /** Get detailed usage history */
259
+ async getUsage(userId, options) {
260
+ const params = new URLSearchParams({ userId });
261
+ if (options?.days)
262
+ params.set('days', String(options.days));
263
+ if (options?.limit)
264
+ params.set('limit', String(options.limit));
265
+ const res = await this.http.get(`/v1/meter/usage?${params}`);
266
+ return res.data || res;
267
+ }
268
+ /**
269
+ * Get a ready-to-use UI badge for displaying the AI tier.
270
+ * Partners can drop this directly into their app UI.
271
+ *
272
+ * @example
273
+ * ```tsx
274
+ * const badge = await dreaming.meter.getBadge('user-123');
275
+ * return (
276
+ * <div style={{ background: badge.color, borderRadius: 12, padding: '4px 12px' }}>
277
+ * {badge.icon} {badge.label}
278
+ * </div>
279
+ * );
280
+ * ```
281
+ */
282
+ async getBadge(userId) {
283
+ const status = await this.getStatus(userId);
284
+ const tier = status.modelTier;
285
+ const tierIndex = TIER_ORDER.indexOf(tier);
286
+ const canUpgrade = tierIndex < TIER_ORDER.length - 1;
287
+ const nextTier = canUpgrade ? TIER_ORDER[tierIndex + 1] : undefined;
288
+ const nextTierName = nextTier
289
+ ? status.availableTiers.find(t => t.key === nextTier)?.name
290
+ : undefined;
291
+ return {
292
+ tier,
293
+ icon: status.modelTierIcon,
294
+ label: `${status.modelTierName} AI`,
295
+ color: TIER_COLORS[tier] || '#6b7280',
296
+ description: status.modelTierDescription,
297
+ model: status.primaryModel,
298
+ canUpgrade,
299
+ nextTier: nextTierName,
300
+ upgradeMessage: canUpgrade
301
+ ? `Upgrade to ${nextTierName} AI for smarter, deeper insights powered by ${status.availableTiers.find(t => t.key === nextTier)?.primaryModel || 'a premium model'}.`
302
+ : undefined,
303
+ };
304
+ }
305
+ /** Quick check: is this user on the highest AI tier? */
306
+ async isGeniusTier(userId) {
307
+ const status = await this.getStatus(userId);
308
+ return status.modelTier === 'genius';
309
+ }
310
+ /** Quick check: can this user upgrade to a better AI tier? */
311
+ async canUpgrade(userId) {
312
+ const status = await this.getStatus(userId);
313
+ const tierIndex = TIER_ORDER.indexOf(status.modelTier);
314
+ return tierIndex < TIER_ORDER.length - 1;
315
+ }
316
+ /**
317
+ * Get a formatted usage summary string for dashboards.
318
+ *
319
+ * @example
320
+ * ```
321
+ * "🔵 Smart AI — 45 calls, 12.5k tokens this month (avg 230ms)"
322
+ * ```
323
+ */
324
+ async getUsageSummary(userId) {
325
+ const status = await this.getStatus(userId);
326
+ const u = status.usage;
327
+ const tokens = u.tokensThisMonth >= 1000
328
+ ? `${(u.tokensThisMonth / 1000).toFixed(1)}k`
329
+ : String(u.tokensThisMonth);
330
+ return `${status.modelTierIcon} ${status.modelTierName} AI — ${u.callsThisMonth} calls, ${tokens} tokens this month (avg ${u.avgLatencyMs}ms)`;
331
+ }
332
+ }
333
+ // ─── Main Client ─────────────────────────────────────────────
334
+ class DreamingClient {
335
+ constructor(config) {
336
+ const http = new HttpClient(config);
337
+ this.memories = new MemoriesClient(http);
338
+ this.dreaming = new DreamingApiClient(http);
339
+ this.graph = new GraphClient(http);
340
+ this.personality = new PersonalityClient(http);
341
+ this.status = new StatusClient(http);
342
+ this.sync = new SyncClient(http);
343
+ this.context = new ContextClient(http);
344
+ this.meter = new MeterClient(http);
345
+ this.activities = new ActivityClient(http, config);
346
+ this.constraints = new ConstraintClient(http);
347
+ this.chat = new ChatClient(http);
348
+ this.knowledge = new KnowledgeClient(http);
349
+ this.web = new WebClient(http);
350
+ this.identity = new IdentityClient(http);
351
+ this.friends = new FriendsClient(http);
352
+ this.proactive = new ProactiveClient(http);
353
+ this.notifications = new NotificationsClient(http);
354
+ this.evolution = new EvolutionClient(http);
355
+ this.dna = new DnaClient(http);
356
+ this.partnerTokens = new PartnerTokensClient(http);
357
+ }
358
+ /**
359
+ * Flush any buffered activity events before shutdown.
360
+ * Call this in your app's cleanup/beforeunload handler.
361
+ */
362
+ async flush() {
363
+ await this.activities.flush();
364
+ }
365
+ }
366
+ exports.DreamingClient = DreamingClient;
367
+ class KnowledgeClient {
368
+ constructor(http) {
369
+ this.http = http;
370
+ }
371
+ /**
372
+ * Upload a document to the knowledge base.
373
+ * Supports: text, markdown, CSV, JSON, HTML, URL, base64, PDF.
374
+ * Auto-detects format from filename/content if sourceType is 'auto' or omitted.
375
+ *
376
+ * @example
377
+ * ```typescript
378
+ * // Upload markdown
379
+ * await dreaming.knowledge.upload({
380
+ * appId: 'my-app',
381
+ * title: 'Training Guide',
382
+ * content: '# Running Tips\n\nStart slow...',
383
+ * });
384
+ *
385
+ * // Upload CSV data
386
+ * await dreaming.knowledge.upload({
387
+ * appId: 'my-app',
388
+ * title: 'Workout Log',
389
+ * content: 'date,distance,time\n2024-01-01,5km,28min',
390
+ * sourceType: 'csv',
391
+ * });
392
+ *
393
+ * // Upload with constraint auto-linking
394
+ * await dreaming.knowledge.upload({
395
+ * appId: 'my-app',
396
+ * userId: 'user-1',
397
+ * title: 'Fitness Plan',
398
+ * content: pdfBase64,
399
+ * sourceType: 'base64',
400
+ * feedConstraints: true, // Auto-creates tags from content
401
+ * });
402
+ * ```
403
+ */
404
+ async upload(options) {
405
+ const res = await this.http.post('/v1/knowledge/upload', options);
406
+ return res.data;
407
+ }
408
+ /**
409
+ * Upload content from a URL. Fetches and parses automatically.
410
+ *
411
+ * @example
412
+ * ```typescript
413
+ * await dreaming.knowledge.uploadUrl({
414
+ * appId: 'my-app',
415
+ * title: 'Running Tips Article',
416
+ * url: 'https://example.com/running-tips',
417
+ * });
418
+ * ```
419
+ */
420
+ async uploadUrl(options) {
421
+ return this.upload({
422
+ appId: options.appId,
423
+ title: options.title,
424
+ content: options.url,
425
+ sourceType: 'url',
426
+ sourceUrl: options.url,
427
+ moduleId: options.moduleId,
428
+ userId: options.userId,
429
+ });
430
+ }
431
+ /** List uploaded documents. */
432
+ async listDocs(options) {
433
+ const params = new URLSearchParams();
434
+ if (options?.appId)
435
+ params.set('appId', options.appId);
436
+ if (options?.moduleId)
437
+ params.set('moduleId', options.moduleId);
438
+ const res = await this.http.get(`/v1/knowledge/docs?${params}`);
439
+ return res.data;
440
+ }
441
+ /** Get document details. */
442
+ async getDoc(docId) {
443
+ const res = await this.http.get(`/v1/knowledge/docs/${docId}`);
444
+ return res.data;
445
+ }
446
+ /** View chunks of a document. */
447
+ async getChunks(docId) {
448
+ const res = await this.http.get(`/v1/knowledge/docs/${docId}/chunks`);
449
+ return res.data;
450
+ }
451
+ /**
452
+ * Search knowledge base with semantic + keyword fallback.
453
+ *
454
+ * @example
455
+ * ```typescript
456
+ * const results = await dreaming.knowledge.search('running tips', {
457
+ * appId: 'active365',
458
+ * limit: 5,
459
+ * domain: 'fitness',
460
+ * });
461
+ * ```
462
+ */
463
+ async search(query, options) {
464
+ const params = new URLSearchParams({ appId: options.appId, q: query });
465
+ if (options.domain)
466
+ params.set('domain', options.domain);
467
+ if (options.limit)
468
+ params.set('limit', String(options.limit));
469
+ const res = await this.http.get(`/v1/knowledge/search?${params}`);
470
+ return res.data;
471
+ }
472
+ /** Delete a document and all its chunks. */
473
+ async deleteDoc(docId) {
474
+ await this.http.delete(`/v1/knowledge/docs/${docId}`);
475
+ }
476
+ /**
477
+ * Enable or disable a document (soft toggle).
478
+ * Disabled docs are excluded from search and chat context.
479
+ */
480
+ async toggleDoc(docId, enabled) {
481
+ await this.http.patch(`/v1/knowledge/docs/${docId}/toggle`, { enabled });
482
+ }
483
+ /**
484
+ * List knowledge modules with doc/chunk counts.
485
+ *
486
+ * @example
487
+ * ```typescript
488
+ * const modules = await dreaming.knowledge.listModules('active365');
489
+ * // [{ module_id: 'fitness-guides', enabled: true, doc_count: 3, chunk_count: 45 }]
490
+ * ```
491
+ */
492
+ async listModules(appId) {
493
+ const res = await this.http.get(`/v1/knowledge/modules?appId=${appId}`);
494
+ return res.data;
495
+ }
496
+ /**
497
+ * Enable or disable an entire knowledge module.
498
+ * All docs in a disabled module are excluded from search.
499
+ */
500
+ async toggleModule(moduleId, options) {
501
+ await this.http.patch(`/v1/knowledge/modules/${moduleId}/toggle`, options);
502
+ }
503
+ /**
504
+ * Re-chunk a document with different settings.
505
+ */
506
+ async reprocess(docId, options) {
507
+ const res = await this.http.post(`/v1/knowledge/reprocess/${docId}`, options || {});
508
+ return res.data;
509
+ }
510
+ }
511
+ class ChatClient {
512
+ constructor(http) {
513
+ this.http = http;
514
+ }
515
+ // ─── Core: Enrich + Learn ─────────────────────────────────
516
+ /**
517
+ * BEFORE your LLM call: get memory/personality/goal context.
518
+ *
519
+ * Returns messages you inject into your conversation.
520
+ * Default format is OpenAI-compatible.
521
+ *
522
+ * @example
523
+ * ```typescript
524
+ * const ctx = await dreaming.chat.enrich('user-1', 'How should I train today?');
525
+ *
526
+ * // Inject into your OpenAI call:
527
+ * const response = await openai.chat.completions.create({
528
+ * model: 'gpt-4o',
529
+ * messages: [...ctx.messages, ...yourConversation],
530
+ * });
531
+ * ```
532
+ */
533
+ async enrich(userId, query, options) {
534
+ const res = await this.http.post('/v1/chat/context', {
535
+ userId,
536
+ query,
537
+ maxMemories: options?.maxMemories,
538
+ includePersonality: options?.includePersonality,
539
+ includeConstraints: options?.includeConstraints,
540
+ includeKnowledge: options?.includeKnowledge,
541
+ webGrounding: options?.webGrounding,
542
+ format: options?.format || 'openai',
543
+ });
544
+ return res.data;
545
+ }
546
+ /**
547
+ * AFTER your LLM responds: tell Dreaming to extract memories.
548
+ *
549
+ * This queues background tasks: memory extraction, entity detection,
550
+ * insight generation (goal-aware), and personality evolution.
551
+ *
552
+ * @example
553
+ * ```typescript
554
+ * await dreaming.chat.learn('user-1', userMessage, aiResponse);
555
+ * ```
556
+ */
557
+ async learn(userId, userMessage, aiResponse, options) {
558
+ const res = await this.http.post('/v1/chat/learn', {
559
+ userId,
560
+ userMessage,
561
+ aiResponse,
562
+ metadata: options?.metadata,
563
+ });
564
+ return res.data;
565
+ }
566
+ /**
567
+ * Full conversation version of learn.
568
+ */
569
+ async learnFromMessages(userId, messages, options) {
570
+ const res = await this.http.post('/v1/chat/learn', {
571
+ userId,
572
+ messages,
573
+ metadata: options?.metadata,
574
+ });
575
+ return res.data;
576
+ }
577
+ // ─── One-Line Wrappers ────────────────────────────────────
578
+ /**
579
+ * Wrap an OpenAI client call. Memory + personality + goals, one line.
580
+ *
581
+ * @example
582
+ * ```typescript
583
+ * import OpenAI from 'openai';
584
+ * const openai = new OpenAI();
585
+ * const dreaming = new DreamingClient({ ... });
586
+ *
587
+ * // This one line gives your GPT memory, personality, and goals:
588
+ * const reply = await dreaming.chat.wrapOpenAI(openai, 'user-1', [
589
+ * { role: 'user', content: 'How should I train today?' }
590
+ * ], { model: 'gpt-4o' });
591
+ *
592
+ * console.log(reply); // Goal-aware, memory-enriched response
593
+ * ```
594
+ */
595
+ async wrapOpenAI(openai, userId, messages, options) {
596
+ // 1. Enrich with context
597
+ const lastUser = [...messages].reverse().find(m => m.role === 'user')?.content || '';
598
+ const ctx = await this.enrich(userId, lastUser, { format: 'openai' });
599
+ // 2. Call OpenAI with enriched messages
600
+ const enrichedMessages = [...ctx.messages, ...messages];
601
+ const completion = await openai.chat.completions.create({
602
+ model: options?.model || 'gpt-4o-mini',
603
+ messages: enrichedMessages,
604
+ temperature: options?.temperature,
605
+ max_tokens: options?.maxTokens,
606
+ });
607
+ const aiResponse = completion.choices?.[0]?.message?.content || '';
608
+ // 3. Learn from the conversation (non-blocking)
609
+ this.learn(userId, lastUser, aiResponse).catch(() => { });
610
+ return aiResponse;
611
+ }
612
+ /**
613
+ * Wrap a Google Gemini call. Memory + personality + goals, one line.
614
+ *
615
+ * @example
616
+ * ```typescript
617
+ * import { GoogleGenerativeAI } from '@google/generative-ai';
618
+ * const genAI = new GoogleGenerativeAI('YOUR_API_KEY');
619
+ * const dreaming = new DreamingClient({ ... });
620
+ *
621
+ * const reply = await dreaming.chat.wrapGemini(genAI, 'user-1',
622
+ * 'How should I train today?',
623
+ * { model: 'gemini-2.0-flash' }
624
+ * );
625
+ * ```
626
+ */
627
+ async wrapGemini(genAI, userId, userMessage, options) {
628
+ // 1. Enrich
629
+ const ctx = await this.enrich(userId, userMessage, { format: 'raw' });
630
+ // 2. Call Gemini
631
+ const model = genAI.getGenerativeModel({ model: options?.model || 'gemini-2.0-flash' });
632
+ const chat = model.startChat({
633
+ history: options?.history || [],
634
+ systemInstruction: ctx.system || ctx.systemPrompt || '',
635
+ });
636
+ const result = await chat.sendMessage(userMessage);
637
+ const aiResponse = result.response.text();
638
+ // 3. Learn (non-blocking)
639
+ this.learn(userId, userMessage, aiResponse).catch(() => { });
640
+ return aiResponse;
641
+ }
642
+ /**
643
+ * Wrap an Anthropic Claude call. Memory + personality + goals, one line.
644
+ *
645
+ * @example
646
+ * ```typescript
647
+ * import Anthropic from '@anthropic-ai/sdk';
648
+ * const anthropic = new Anthropic();
649
+ * const dreaming = new DreamingClient({ ... });
650
+ *
651
+ * const reply = await dreaming.chat.wrapAnthropic(anthropic, 'user-1', [
652
+ * { role: 'user', content: 'How should I train today?' }
653
+ * ], { model: 'claude-sonnet-4-20250514' });
654
+ * ```
655
+ */
656
+ async wrapAnthropic(anthropic, userId, messages, options) {
657
+ // 1. Enrich (Anthropic format: system is separate)
658
+ const lastUser = [...messages].reverse().find(m => m.role === 'user')?.content || '';
659
+ const ctx = await this.enrich(userId, lastUser, { format: 'anthropic' });
660
+ // 2. Call Anthropic
661
+ const response = await anthropic.messages.create({
662
+ model: options?.model || 'claude-sonnet-4-20250514',
663
+ max_tokens: options?.maxTokens || 1024,
664
+ system: ctx.system || '',
665
+ messages,
666
+ });
667
+ const aiResponse = response.content?.[0]?.text || '';
668
+ // 3. Learn (non-blocking)
669
+ this.learn(userId, lastUser, aiResponse).catch(() => { });
670
+ return aiResponse;
671
+ }
672
+ /**
673
+ * Generic wrapper for any LLM. You provide the call function.
674
+ *
675
+ * @example
676
+ * ```typescript
677
+ * const reply = await dreaming.chat.wrap(
678
+ * 'user-1',
679
+ * 'How should I train today?',
680
+ * async (systemPrompt, userMsg) => {
681
+ * // Call your LLM however you want
682
+ * return await myCustomLLM.generate(systemPrompt + '\n' + userMsg);
683
+ * }
684
+ * );
685
+ * ```
686
+ */
687
+ async wrap(userId, userMessage, llmCall, options) {
688
+ // 1. Enrich
689
+ const ctx = await this.enrich(userId, userMessage, { ...options, format: 'raw' });
690
+ const systemPrompt = ctx.systemPrompt || ctx.system || '';
691
+ // 2. Call their LLM
692
+ const aiResponse = await llmCall(systemPrompt, userMessage);
693
+ // 3. Learn (non-blocking)
694
+ this.learn(userId, userMessage, aiResponse).catch(() => { });
695
+ return aiResponse;
696
+ }
697
+ }
698
+ class ConstraintClient {
699
+ constructor(http) {
700
+ this.http = http;
701
+ }
702
+ // ─── Goals & Constraints ──────────────────────────────────
703
+ /**
704
+ * Create a goal, sub-goal, task, checkpoint, or achievement.
705
+ *
706
+ * @example
707
+ * ```typescript
708
+ * await dreaming.constraints.setGoal('user-1', 'Run 5K under 25min', {
709
+ * category: 'fitness', weight: 90,
710
+ * targetValue: 25, unit: 'min',
711
+ * deadline: '2026-06-01',
712
+ * tags: ['running', 'cardio'],
713
+ * });
714
+ * ```
715
+ */
716
+ async setGoal(userId, title, options) {
717
+ const res = await this.http.post('/v1/constraints', {
718
+ userId,
719
+ title,
720
+ constraintType: options?.type || 'goal',
721
+ parentId: options?.parentId,
722
+ description: options?.description,
723
+ weight: options?.weight,
724
+ priority: options?.priority,
725
+ category: options?.category,
726
+ domain: options?.domain,
727
+ targetValue: options?.targetValue,
728
+ unit: options?.unit,
729
+ deadline: options?.deadline,
730
+ pinned: options?.pinned,
731
+ tags: options?.tags,
732
+ metadata: options?.metadata,
733
+ });
734
+ return res.data;
735
+ }
736
+ /** Create a sub-goal under a parent goal */
737
+ async addSubGoal(userId, parentId, title, options) {
738
+ return this.setGoal(userId, title, { ...options, type: 'sub_goal', parentId });
739
+ }
740
+ /** Create a task under a goal or sub-goal */
741
+ async addTask(userId, parentId, title, options) {
742
+ return this.setGoal(userId, title, { ...options, type: 'task', parentId });
743
+ }
744
+ /** Create a checkpoint (milestone) */
745
+ async addCheckpoint(userId, parentId, title, options) {
746
+ return this.setGoal(userId, title, { ...options, type: 'checkpoint', parentId });
747
+ }
748
+ /** Record an achievement */
749
+ async addAchievement(userId, title, options) {
750
+ return this.setGoal(userId, title, { ...options, type: 'achievement' });
751
+ }
752
+ /**
753
+ * List constraints with optional filters.
754
+ */
755
+ async list(userId, options) {
756
+ const params = new URLSearchParams({ userId });
757
+ if (options?.type)
758
+ params.set('type', options.type);
759
+ if (options?.status)
760
+ params.set('status', options.status);
761
+ if (options?.category)
762
+ params.set('category', options.category);
763
+ if (options?.parentId)
764
+ params.set('parentId', options.parentId);
765
+ if (options?.pinned)
766
+ params.set('pinned', 'true');
767
+ const res = await this.http.get(`/v1/constraints?${params}`);
768
+ return res.data;
769
+ }
770
+ /**
771
+ * Update a constraint's weight, status, progress, or other fields.
772
+ *
773
+ * @example
774
+ * ```typescript
775
+ * // Update progress
776
+ * await dreaming.constraints.update(goalId, { progress: 75 });
777
+ *
778
+ * // Change weight (influences how much AI focuses on this)
779
+ * await dreaming.constraints.update(goalId, { weight: 30 });
780
+ *
781
+ * // Complete a goal
782
+ * await dreaming.constraints.update(goalId, { status: 'completed' });
783
+ * ```
784
+ */
785
+ async update(constraintId, updates) {
786
+ const res = await this.http.patch(`/v1/constraints/${constraintId}`, updates);
787
+ return res.data;
788
+ }
789
+ /** Complete a constraint */
790
+ async complete(constraintId) {
791
+ return this.update(constraintId, { status: 'completed' });
792
+ }
793
+ /** Cancel a constraint */
794
+ async cancel(constraintId, reason) {
795
+ return this.update(constraintId, { status: 'cancelled', reason });
796
+ }
797
+ /** Pause a constraint (keeps weight but AI won't actively suggest) */
798
+ async pause(constraintId) {
799
+ return this.update(constraintId, { status: 'paused' });
800
+ }
801
+ /** Resume a paused constraint */
802
+ async resume(constraintId) {
803
+ return this.update(constraintId, { status: 'active' });
804
+ }
805
+ /** Pin a constraint (locks it from fading) */
806
+ async pin(constraintId) {
807
+ return this.update(constraintId, { pinned: true });
808
+ }
809
+ /** Unpin a constraint */
810
+ async unpin(constraintId) {
811
+ return this.update(constraintId, { pinned: false });
812
+ }
813
+ /** Set the weight (0-100) — how much the AI focuses on this */
814
+ async setWeight(constraintId, weight, reason) {
815
+ return this.update(constraintId, { weight: Math.min(Math.max(weight, 0), 100), reason });
816
+ }
817
+ /** Delete a constraint (soft delete) */
818
+ async delete(constraintId) {
819
+ await this.http.delete(`/v1/constraints/${constraintId}`);
820
+ }
821
+ /** Get change history for a constraint */
822
+ async getHistory(constraintId) {
823
+ const res = await this.http.get(`/v1/constraints/${constraintId}/history`);
824
+ return res.data;
825
+ }
826
+ // ─── Tags ─────────────────────────────────────────────────
827
+ /**
828
+ * Create or update a focus tag.
829
+ *
830
+ * @example
831
+ * ```typescript
832
+ * await dreaming.constraints.addTag('user-1', 'mindfulness', {
833
+ * category: 'wellness', weight: 70, pinned: true,
834
+ * });
835
+ * ```
836
+ */
837
+ async addTag(userId, tagKey, options) {
838
+ const res = await this.http.post('/v1/constraints/tags', {
839
+ userId,
840
+ tagKey,
841
+ label: options?.label || tagKey,
842
+ category: options?.category,
843
+ weight: options?.weight,
844
+ pinned: options?.pinned,
845
+ source: 'user',
846
+ birthReason: options?.birthReason,
847
+ });
848
+ return res.data;
849
+ }
850
+ /** List tags */
851
+ async listTags(userId, options) {
852
+ const params = new URLSearchParams({ userId });
853
+ if (options?.status)
854
+ params.set('status', options.status);
855
+ if (options?.category)
856
+ params.set('category', options.category);
857
+ if (options?.pinned)
858
+ params.set('pinned', 'true');
859
+ const res = await this.http.get(`/v1/constraints/tags?${params}`);
860
+ return res.data;
861
+ }
862
+ /** Update a tag (weight, pin, category) */
863
+ async updateTag(tagId, updates) {
864
+ const res = await this.http.patch(`/v1/constraints/tags/${tagId}`, updates);
865
+ return res.data;
866
+ }
867
+ /** Pin a tag */
868
+ async pinTag(tagId) {
869
+ return this.updateTag(tagId, { pinned: true });
870
+ }
871
+ /** Set tag weight */
872
+ async setTagWeight(tagId, weight) {
873
+ return this.updateTag(tagId, { weight: Math.min(Math.max(weight, 0), 100) });
874
+ }
875
+ // ─── Context ──────────────────────────────────────────────
876
+ /**
877
+ * Get the weighted constraint context that the AI uses.
878
+ * Shows exactly how constraints + tags influence dreaming.
879
+ */
880
+ async getContext(userId) {
881
+ const res = await this.http.get(`/v1/constraints/context?userId=${userId}`);
882
+ return res.data;
883
+ }
884
+ }
885
+ class ActivityClient {
886
+ constructor(http, config) {
887
+ this.http = http;
888
+ this.buffer = [];
889
+ this.flushTimer = null;
890
+ this.isFlushing = false;
891
+ const bufConfig = config.activityBuffer ?? {};
892
+ this.bufferSize = bufConfig.bufferSize ?? 20;
893
+ this.sessionId = `ses_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
894
+ if (!bufConfig.disableAutoFlush) {
895
+ const interval = bufConfig.flushIntervalMs ?? 5000;
896
+ this.flushTimer = setInterval(() => this.flush().catch(() => { }), interval);
897
+ }
898
+ }
899
+ /**
900
+ * Track a user activity event — SYNCHRONOUS, zero overhead.
901
+ * Events are queued locally and flushed as a batch automatically.
902
+ *
903
+ * @example
904
+ * ```typescript
905
+ * // Track a screen view
906
+ * dreaming.activities.track('user-123', 'screen_view', 'Dashboard');
907
+ *
908
+ * // Track a feature interaction with data
909
+ * dreaming.activities.track('user-123', 'feature_use', 'AIChat', {
910
+ * domain: 'productivity',
911
+ * data: { messageCount: 5, topic: 'project planning' },
912
+ * durationMs: 45000,
913
+ * });
914
+ *
915
+ * // Track a button click
916
+ * dreaming.activities.track('user-123', 'button_click', 'UpgradeToProBtn', {
917
+ * domain: 'billing',
918
+ * });
919
+ * ```
920
+ */
921
+ track(userId, activityType, activityName, options) {
922
+ this.buffer.push({
923
+ userId,
924
+ activityType,
925
+ activityName,
926
+ domain: options?.domain,
927
+ data: options?.data,
928
+ durationMs: options?.durationMs,
929
+ sessionId: options?.sessionId ?? this.sessionId,
930
+ });
931
+ // Auto-flush when buffer is full
932
+ if (this.buffer.length >= this.bufferSize) {
933
+ this.flush().catch(() => { });
934
+ }
935
+ }
936
+ /**
937
+ * Flush buffered events to the server.
938
+ * Called automatically by the timer/buffer-full, but you can call manually.
939
+ */
940
+ async flush() {
941
+ if (this.buffer.length === 0 || this.isFlushing)
942
+ return 0;
943
+ this.isFlushing = true;
944
+ // Take the current buffer and clear it
945
+ const events = [...this.buffer];
946
+ this.buffer = [];
947
+ try {
948
+ const res = await this.http.post('/v1/activities/batch', {
949
+ events,
950
+ });
951
+ return res.data?.inserted ?? events.length;
952
+ }
953
+ catch {
954
+ // Put events back on failure (will retry on next flush)
955
+ this.buffer.unshift(...events);
956
+ return 0;
957
+ }
958
+ finally {
959
+ this.isFlushing = false;
960
+ }
961
+ }
962
+ /**
963
+ * Query activity history for a user.
964
+ */
965
+ async getHistory(userId, options) {
966
+ const params = new URLSearchParams({ userId });
967
+ if (options?.type)
968
+ params.set('type', options.type);
969
+ if (options?.domain)
970
+ params.set('domain', options.domain);
971
+ if (options?.days)
972
+ params.set('days', String(options.days));
973
+ if (options?.limit)
974
+ params.set('limit', String(options.limit));
975
+ return this.http.get(`/v1/activities?${params}`);
976
+ }
977
+ /** Get the current auto-generated session ID */
978
+ getSessionId() {
979
+ return this.sessionId;
980
+ }
981
+ /** Start a new session (generates a new session ID) */
982
+ newSession() {
983
+ this.sessionId = `ses_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
984
+ return this.sessionId;
985
+ }
986
+ /** Get the number of buffered (unflushed) events */
987
+ get pendingCount() {
988
+ return this.buffer.length;
989
+ }
990
+ /** Stop the auto-flush timer (call before app shutdown after flush) */
991
+ destroy() {
992
+ if (this.flushTimer) {
993
+ clearInterval(this.flushTimer);
994
+ this.flushTimer = null;
995
+ }
996
+ }
997
+ }
998
+ class WebClient {
999
+ constructor(http) {
1000
+ this.http = http;
1001
+ }
1002
+ /**
1003
+ * Search the web. Respects DNA guardrails (must be enabled for the app).
1004
+ * Results are cached for 24h.
1005
+ *
1006
+ * @example
1007
+ * ```typescript
1008
+ * const results = await dreaming.web.search('5K running tips', {
1009
+ * appId: 'active365',
1010
+ * limit: 5,
1011
+ * });
1012
+ * ```
1013
+ */
1014
+ async search(query, options) {
1015
+ const res = await this.http.post('/v1/web/search', { query, ...options });
1016
+ return res.data.results;
1017
+ }
1018
+ /**
1019
+ * Search and return formatted system prompt (for direct LLM injection).
1020
+ */
1021
+ async searchForPrompt(query, appId) {
1022
+ const res = await this.http.post('/v1/web/search', { query, appId, format: 'prompt', limit: 3 });
1023
+ return res.data.contextPrompt || '';
1024
+ }
1025
+ /** Crawl a specific URL for content. */
1026
+ async crawl(url, appId) {
1027
+ try {
1028
+ const res = await this.http.post('/v1/web/crawl', { url, appId });
1029
+ return res.data;
1030
+ }
1031
+ catch {
1032
+ return null;
1033
+ }
1034
+ }
1035
+ /** Get the web access policy for an app. */
1036
+ async getPolicy(appId) {
1037
+ const res = await this.http.get(`/v1/web/policy?appId=${appId}`);
1038
+ return res.data;
1039
+ }
1040
+ /**
1041
+ * Update web access policy.
1042
+ *
1043
+ * @example
1044
+ * ```typescript
1045
+ * await dreaming.web.updatePolicy('active365', {
1046
+ * enabled: true,
1047
+ * maxDailySearches: 100,
1048
+ * blockedDomains: ['facebook.com'],
1049
+ * });
1050
+ * ```
1051
+ */
1052
+ async updatePolicy(appId, policy) {
1053
+ const res = await this.http.post('/v1/web/policy', { appId, ...policy });
1054
+ return res.data;
1055
+ }
1056
+ /** Get daily web usage stats for budget monitoring. */
1057
+ async getUsage(appId, date) {
1058
+ const params = date ? `appId=${appId}&date=${date}` : `appId=${appId}`;
1059
+ const res = await this.http.get(`/v1/web/usage?${params}`);
1060
+ return res.data;
1061
+ }
1062
+ /** Get user dreaming settings (all toggles). */
1063
+ async getSettings(userId, appId) {
1064
+ const params = appId ? `userId=${userId}&appId=${appId}` : `userId=${userId}`;
1065
+ const res = await this.http.get(`/v1/web/settings?${params}`);
1066
+ return res.data;
1067
+ }
1068
+ /** Update user dreaming settings (toggle features on/off). */
1069
+ async updateSettings(userId, settings, appId) {
1070
+ const res = await this.http.post('/v1/web/settings', {
1071
+ userId,
1072
+ appId: appId || 'default',
1073
+ ...settings,
1074
+ });
1075
+ return res.data;
1076
+ }
1077
+ }
1078
+ class IdentityClient {
1079
+ constructor(http) {
1080
+ this.http = http;
1081
+ }
1082
+ /** Get user identity (names, AI name, sync status). */
1083
+ async get(userId, appId) {
1084
+ const params = appId ? `userId=${userId}&appId=${appId}` : `userId=${userId}`;
1085
+ const res = await this.http.get(`/v1/identity?${params}`);
1086
+ return res.data;
1087
+ }
1088
+ /** Update user identity (display name, preferred name, etc). */
1089
+ async update(userId, appId, updates) {
1090
+ const res = await this.http.post('/v1/identity', { userId, appId, ...updates });
1091
+ return res.data;
1092
+ }
1093
+ /** Get the effective AI name for this user in this app. */
1094
+ async getAiName(userId, appId) {
1095
+ const params = appId ? `userId=${userId}&appId=${appId}` : `userId=${userId}`;
1096
+ const res = await this.http.get(`/v1/identity/ai-name?${params}`);
1097
+ return res.data.aiName;
1098
+ }
1099
+ /** Set a custom AI name (user-chosen or partner default). */
1100
+ async setAiName(userId, appId, aiName, isPartnerDefault = false) {
1101
+ const res = await this.http.post('/v1/identity/ai-name', {
1102
+ userId, appId, aiName, isPartnerDefault,
1103
+ });
1104
+ return res.data.aiName;
1105
+ }
1106
+ /** Get people the user knows (family, friends, colleagues). */
1107
+ async getSocialCircle(userId, appId, relationship) {
1108
+ let params = `userId=${userId}`;
1109
+ if (appId)
1110
+ params += `&appId=${appId}`;
1111
+ if (relationship)
1112
+ params += `&relationship=${relationship}`;
1113
+ const res = await this.http.get(`/v1/identity/social?${params}`);
1114
+ return res.data;
1115
+ }
1116
+ /** Add a person to the user's social circle. */
1117
+ async addPerson(userId, appId, person) {
1118
+ const res = await this.http.post('/v1/identity/social', {
1119
+ userId, appId, ...person,
1120
+ });
1121
+ return res.data;
1122
+ }
1123
+ /** Sync identity from HQ to a partner app. */
1124
+ async syncFromHq(userId, appId) {
1125
+ const res = await this.http.post('/v1/identity/sync', { userId, appId });
1126
+ return res.data;
1127
+ }
1128
+ }
1129
+ class FriendsClient {
1130
+ constructor(http) {
1131
+ this.http = http;
1132
+ }
1133
+ /** Send a friend request. */
1134
+ async request(userId, friendUserId, options) {
1135
+ const res = await this.http.post('/v1/friends/request', {
1136
+ userId, friendUserId, ...options,
1137
+ });
1138
+ return res.data;
1139
+ }
1140
+ /** Accept a friend connection. */
1141
+ async accept(connectionId, options) {
1142
+ const res = await this.http.post(`/v1/friends/accept/${connectionId}`, options || {});
1143
+ return res.data;
1144
+ }
1145
+ /** Reject or block a connection. */
1146
+ async reject(connectionId, block = false) {
1147
+ await this.http.post(`/v1/friends/reject/${connectionId}`, { block });
1148
+ }
1149
+ /** List all connections for a user. */
1150
+ async list(userId) {
1151
+ const res = await this.http.get(`/v1/friends?userId=${userId}`);
1152
+ return res.data;
1153
+ }
1154
+ /** Get connection details. */
1155
+ async get(connectionId) {
1156
+ const res = await this.http.get(`/v1/friends/${connectionId}`);
1157
+ return res.data;
1158
+ }
1159
+ /** Trigger an AI-to-AI exchange. */
1160
+ async exchange(connectionId, topic, maxRounds) {
1161
+ const res = await this.http.post(`/v1/friends/${connectionId}/exchange`, { topic, maxRounds });
1162
+ return res.data;
1163
+ }
1164
+ /** Get exchange conversation history. */
1165
+ async conversations(connectionId, limit) {
1166
+ const params = limit ? `?limit=${limit}` : '';
1167
+ const res = await this.http.get(`/v1/friends/${connectionId}/conversations${params}`);
1168
+ return res.data;
1169
+ }
1170
+ /** Get shared memories for a connection. */
1171
+ async sharedMemories(connectionId, limit) {
1172
+ const params = limit ? `?limit=${limit}` : '';
1173
+ const res = await this.http.get(`/v1/friends/${connectionId}/shared${params}`);
1174
+ return res.data;
1175
+ }
1176
+ /** Share a specific memory with a friend. */
1177
+ async shareMemory(connectionId, userId, content, domain, importance) {
1178
+ const res = await this.http.post(`/v1/friends/${connectionId}/share`, {
1179
+ userId, content, domain, importance,
1180
+ });
1181
+ return res.data;
1182
+ }
1183
+ /** Update connection settings. */
1184
+ async update(connectionId, settings) {
1185
+ await this.http.request('PATCH', `/v1/friends/${connectionId}`, settings);
1186
+ }
1187
+ }
1188
+ class ProactiveClient {
1189
+ constructor(http) {
1190
+ this.http = http;
1191
+ }
1192
+ /** Trigger proactive evaluation for a user. */
1193
+ async evaluate(userId, appId) {
1194
+ const res = await this.http.post('/v1/proactive/evaluate', { userId, appId });
1195
+ return res;
1196
+ }
1197
+ /** Get pending proactive suggestions. */
1198
+ async getSuggestions(userId, appId, limit) {
1199
+ let params = `userId=${userId}`;
1200
+ if (appId)
1201
+ params += `&appId=${appId}`;
1202
+ if (limit)
1203
+ params += `&limit=${limit}`;
1204
+ const res = await this.http.get(`/v1/proactive/suggestions?${params}`);
1205
+ return res.data;
1206
+ }
1207
+ /** Dismiss a proactive suggestion. */
1208
+ async dismiss(suggestionId) {
1209
+ await this.http.post('/v1/proactive/dismiss', { suggestionId });
1210
+ }
1211
+ }
1212
+ class NotificationsClient {
1213
+ constructor(http) {
1214
+ this.http = http;
1215
+ }
1216
+ /** Mark notifications as read. */
1217
+ async markRead(ids) {
1218
+ await this.http.post('/v1/proactive/read', { ids });
1219
+ }
1220
+ /** Act on a proactive suggestion. */
1221
+ async act(suggestionId, action) {
1222
+ const res = await this.http.post('/v1/proactive/act', { suggestionId, action });
1223
+ return res;
1224
+ }
1225
+ /** Get notification preferences. */
1226
+ async getPrefs(userId, appId) {
1227
+ let params = `userId=${userId}`;
1228
+ if (appId)
1229
+ params += `&appId=${appId}`;
1230
+ const res = await this.http.get(`/v1/notifications/prefs?${params}`);
1231
+ return res.data;
1232
+ }
1233
+ /** Update notification preferences. */
1234
+ async updatePrefs(userId, prefs, appId) {
1235
+ const res = await this.http.request('PUT', '/v1/notifications/prefs', { userId, appId, ...prefs });
1236
+ return res.data;
1237
+ }
1238
+ /** Register a push notification token. */
1239
+ async registerPushToken(userId, token, platform, appId) {
1240
+ await this.http.post('/v1/notifications/push-token', { userId, token, platform, appId });
1241
+ }
1242
+ /** Get behavior timeline (activity/mood history). */
1243
+ async getTimeline(userId, options) {
1244
+ let params = `userId=${userId}`;
1245
+ if (options?.days)
1246
+ params += `&days=${options.days}`;
1247
+ if (options?.limit)
1248
+ params += `&limit=${options.limit}`;
1249
+ const res = await this.http.get(`/v1/behavior/timeline?${params}`);
1250
+ return res.data;
1251
+ }
1252
+ /** Get behavior signals. */
1253
+ async getSignals(userId, type) {
1254
+ let params = `userId=${userId}`;
1255
+ if (type)
1256
+ params += `&type=${type}`;
1257
+ const res = await this.http.get(`/v1/behavior/signals?${params}`);
1258
+ return res.data;
1259
+ }
1260
+ /** Get behavior summary. */
1261
+ async getSummary(userId) {
1262
+ const res = await this.http.get(`/v1/behavior/summary?userId=${userId}`);
1263
+ return res.data;
1264
+ }
1265
+ }
1266
+ class EvolutionClient {
1267
+ constructor(http) {
1268
+ this.http = http;
1269
+ }
1270
+ /** Track a single activity event. */
1271
+ async trackActivity(activity) {
1272
+ const res = await this.http.post('/v1/activities', activity);
1273
+ return res.data;
1274
+ }
1275
+ /** Track a batch of activities. */
1276
+ async trackBatch(activities) {
1277
+ const res = await this.http.post('/v1/activities/batch', { activities });
1278
+ return res;
1279
+ }
1280
+ /** Get activity history. */
1281
+ async getActivities(userId, options) {
1282
+ let params = `userId=${userId}`;
1283
+ if (options?.category)
1284
+ params += `&category=${options.category}`;
1285
+ if (options?.limit)
1286
+ params += `&limit=${options.limit}`;
1287
+ if (options?.days)
1288
+ params += `&days=${options.days}`;
1289
+ const res = await this.http.get(`/v1/activities?${params}`);
1290
+ return res.data;
1291
+ }
1292
+ /** Get user's life domains. */
1293
+ async getDomains(userId) {
1294
+ const res = await this.http.get(`/v1/domains?userId=${userId}`);
1295
+ return res.data;
1296
+ }
1297
+ /** Create a life domain. */
1298
+ async createDomain(domain) {
1299
+ const res = await this.http.post('/v1/domains', domain);
1300
+ return res.data;
1301
+ }
1302
+ /** Update domain progress. */
1303
+ async updateProgress(domainId, progress, note) {
1304
+ const res = await this.http.post(`/v1/domains/${domainId}/progress`, { progress, note });
1305
+ return res.data;
1306
+ }
1307
+ /** Get domain progress history. */
1308
+ async getDomainHistory(domainId, limit) {
1309
+ const params = limit ? `?limit=${limit}` : '';
1310
+ const res = await this.http.get(`/v1/domains/${domainId}/history${params}`);
1311
+ return res.data;
1312
+ }
1313
+ /** Register an app feature. */
1314
+ async registerFeature(appId, feature) {
1315
+ const res = await this.http.post(`/v1/apps/${appId}/features`, feature);
1316
+ return res.data;
1317
+ }
1318
+ /** Emit an app event. */
1319
+ async emitEvent(appId, event) {
1320
+ const res = await this.http.post(`/v1/apps/${appId}/events`, event);
1321
+ return res.data;
1322
+ }
1323
+ /** Get app context (features, recent events). */
1324
+ async getAppContext(appId, userId) {
1325
+ const params = userId ? `?userId=${userId}` : '';
1326
+ const res = await this.http.get(`/v1/apps/${appId}/context${params}`);
1327
+ return res.data;
1328
+ }
1329
+ /** Get or set user state (mood, role, context). */
1330
+ async getUserState(userId) {
1331
+ const res = await this.http.get(`/v1/user-state?userId=${userId}`);
1332
+ return res.data;
1333
+ }
1334
+ /** Update user state. */
1335
+ async setUserState(userId, state) {
1336
+ const res = await this.http.post('/v1/user-state', { userId, ...state });
1337
+ return res.data;
1338
+ }
1339
+ }
1340
+ class DnaClient {
1341
+ constructor(http) {
1342
+ this.http = http;
1343
+ }
1344
+ /** Get app DNA configuration. */
1345
+ async get(appId) {
1346
+ const res = await this.http.get(`/v1/apps/${appId}/dna`);
1347
+ return res.data;
1348
+ }
1349
+ /** Register or update app DNA. */
1350
+ async update(appId, dna) {
1351
+ const res = await this.http.post(`/v1/apps/${appId}/dna`, dna);
1352
+ return res.data;
1353
+ }
1354
+ /** Seed a new user's brain with app defaults. */
1355
+ async seedUser(appId, userId) {
1356
+ const res = await this.http.post(`/v1/apps/${appId}/seed`, { userId });
1357
+ return res.data;
1358
+ }
1359
+ /** List all registered apps. */
1360
+ async listApps() {
1361
+ const res = await this.http.get('/v1/apps/directory');
1362
+ return res.data;
1363
+ }
1364
+ }
1365
+ class PartnerTokensClient {
1366
+ constructor(http) {
1367
+ this.http = http;
1368
+ }
1369
+ /** Create a child token. */
1370
+ async create(options) {
1371
+ const res = await this.http.post('/v1/partner/tokens', options);
1372
+ return res.data;
1373
+ }
1374
+ /** List partner's tokens. */
1375
+ async list() {
1376
+ const res = await this.http.get('/v1/partner/tokens');
1377
+ return res.data;
1378
+ }
1379
+ /** Revoke a token. */
1380
+ async revoke(tokenId) {
1381
+ await this.http.request('DELETE', `/v1/partner/tokens/${tokenId}`);
1382
+ }
1383
+ /** Update token settings. */
1384
+ async update(tokenId, updates) {
1385
+ const res = await this.http.request('PATCH', `/v1/partner/tokens/${tokenId}`, updates);
1386
+ return res.data;
1387
+ }
1388
+ /** Get token usage stats. */
1389
+ async getUsage(tokenId) {
1390
+ const res = await this.http.get(`/v1/partner/tokens/${tokenId}/usage`);
1391
+ return res.data;
1392
+ }
1393
+ }
1394
+ // ─── Default Export ──────────────────────────────────────────
1395
+ exports.default = DreamingClient;
1396
+ //# sourceMappingURL=index.js.map