oblien 1.1.4 → 1.1.5

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/index.d.ts CHANGED
@@ -396,6 +396,42 @@ export interface SetQuotaOptions {
396
396
  period?: 'daily' | 'monthly' | 'unlimited';
397
397
  }
398
398
 
399
+ export interface SetEndUserQuotaOptions {
400
+ namespace: string;
401
+ endUserId: string;
402
+ service: string;
403
+ quotaLimit: number;
404
+ period?: 'daily' | 'monthly' | 'unlimited';
405
+ }
406
+
407
+ export interface EndUserQuota {
408
+ limit: number;
409
+ used: number;
410
+ remaining: number;
411
+ period: string;
412
+ enabled: boolean;
413
+ }
414
+
415
+ export interface SetDefaultQuotaOptions {
416
+ level: 'namespace' | 'end_user';
417
+ service: string;
418
+ quotaLimit: number | null;
419
+ period?: 'daily' | 'monthly' | 'unlimited';
420
+ autoApply?: boolean;
421
+ }
422
+
423
+ export interface DefaultQuotaConfig {
424
+ id: number;
425
+ level: 'namespace' | 'end_user';
426
+ service: string;
427
+ quotaLimit: number | null;
428
+ period: string;
429
+ autoApply: boolean;
430
+ enabled: boolean;
431
+ createdAt: string;
432
+ updatedAt: string;
433
+ }
434
+
399
435
  export interface HistoryOptions {
400
436
  namespace?: string;
401
437
  endUserId?: string;
@@ -457,6 +493,18 @@ export class OblienCredits {
457
493
  setQuota(options: SetQuotaOptions): Promise<QuotaData>;
458
494
  resetQuota(namespace: string, service: string): Promise<any>;
459
495
 
496
+ // End User Quota Management (Optional Third Level)
497
+ setEndUserQuota(options: SetEndUserQuotaOptions): Promise<any>;
498
+ getEndUserQuota(namespace: string, endUserId: string, service: string): Promise<{ success: boolean; quota: EndUserQuota | null }>;
499
+ resetEndUserQuota(namespace: string, endUserId: string, service: string): Promise<any>;
500
+
501
+ // Default Quota Configuration (Dynamic, per client)
502
+ setDefaultQuota(options: SetDefaultQuotaOptions): Promise<any>;
503
+ getDefaultQuota(level: 'namespace' | 'end_user', service: string): Promise<{ success: boolean; config: DefaultQuotaConfig | null }>;
504
+ getAllDefaultQuotas(level?: 'namespace' | 'end_user'): Promise<{ success: boolean; configs: DefaultQuotaConfig[] }>;
505
+ deleteDefaultQuota(level: 'namespace' | 'end_user', service: string): Promise<any>;
506
+ toggleDefaultQuotaAutoApply(level: 'namespace' | 'end_user', service: string, autoApply: boolean): Promise<any>;
507
+
460
508
  // Usage History & Transactions
461
509
  getHistory(options?: HistoryOptions): Promise<{ success: boolean; data: CreditTransaction[]; pagination: any }>;
462
510
  getHistoryFilters(): Promise<{ namespaces: string[]; services: string[] }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oblien",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "Server-side SDK for Oblien AI Platform - Build AI-powered applications with chat, agents, and workflows",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/src/chat/index.js CHANGED
@@ -52,23 +52,60 @@ export class OblienChat {
52
52
 
53
53
  /**
54
54
  * Create a guest session based on IP and fingerprint (dual-layer identification)
55
+ *
56
+ * Namespace handling:
57
+ * - If `namespace` is provided: Uses it as the session namespace
58
+ * - If `namespace` is NOT provided: Uses guest's auto-generated namespace (based on IP)
59
+ * - `endUserId`: Optional identifier for your end user (tracked separately)
60
+ *
55
61
  * @param {Object} options - Guest session options
56
- * @param {string} options.ip - Client IP address
62
+ * @param {string} options.ip - Client IP address (required)
57
63
  * @param {string} [options.fingerprint] - Client fingerprint for identification
58
64
  * @param {string} options.agentId - Agent ID to chat with
59
65
  * @param {string} [options.workflowId] - Workflow ID
60
- * @param {Object} [options.metadata] - Additional guest metadata
66
+ * @param {string} [options.namespace] - Custom namespace (e.g., 'my-app-guests'). If not provided, uses auto-generated guest namespace
67
+ * @param {string} [options.endUserId] - Your end user's ID (e.g., from your database)
68
+ * @param {Object} [options.metadata] - Additional guest metadata (userAgent, etc.)
61
69
  * @param {Object} [options.workspace] - Workspace configuration
62
- * @param {string} [options.endUserId] - End user ID (for client's end users)
63
70
  * @returns {Promise<Object>} Session data with token and guest info
71
+ *
72
+ * @example
73
+ * // Simple guest session (auto namespace)
74
+ * await chat.createGuestSession({
75
+ * ip: '1.2.3.4',
76
+ * agentId: 'my-agent-id'
77
+ * });
78
+ *
79
+ * @example
80
+ * // With custom namespace and end user ID
81
+ * await chat.createGuestSession({
82
+ * ip: '1.2.3.4',
83
+ * fingerprint: 'abc123',
84
+ * agentId: 'my-agent-id',
85
+ * namespace: 'my-app-guests',
86
+ * endUserId: 'user_12345'
87
+ * });
64
88
  */
65
89
  async createGuestSession(options) {
66
- const { ip, fingerprint, agentId, workflowId, metadata = {}, workspace, endUserId } = options;
90
+ const {
91
+ ip,
92
+ fingerprint,
93
+ agentId,
94
+ workflowId,
95
+ namespace,
96
+ endUserId,
97
+ metadata = {},
98
+ workspace
99
+ } = options;
67
100
 
68
101
  if (!ip) {
69
102
  throw new Error('IP address is required for guest sessions');
70
103
  }
71
104
 
105
+ if (!agentId) {
106
+ throw new Error('Agent ID is required for guest sessions');
107
+ }
108
+
72
109
  // Get or create guest user (handles fingerprint and IP mapping internally)
73
110
  const guest = await this.guestManager.getOrCreateGuest(ip, fingerprint, {
74
111
  ...metadata,
@@ -81,16 +118,20 @@ export class OblienChat {
81
118
  client: this.client,
82
119
  });
83
120
 
121
+ // Use custom namespace if provided, otherwise use guest's default namespace
122
+ const sessionNamespace = namespace || guest.namespace;
123
+
84
124
  const sessionData = await session.create({
85
125
  agentId,
86
126
  workflowId,
87
127
  workspace,
88
128
  isGuest: true,
89
- namespace: guest.namespace,
129
+ namespace: sessionNamespace,
90
130
  ipAddress: ip,
91
131
  userAgent: metadata.userAgent,
132
+ guestNamespace: guest.namespace,
92
133
  fingerprint: fingerprint,
93
- endUserId: endUserId,
134
+ endUserId: endUserId, // Optional: Your end user identifier
94
135
  });
95
136
 
96
137
  // Link session to guest
@@ -338,16 +379,104 @@ export class OblienChat {
338
379
  }
339
380
 
340
381
  /**
341
- * Get session info
382
+ * Get session info (server-side)
342
383
  * @param {string} sessionId - Session ID
343
384
  * @returns {Promise<Object>} Session details
344
385
  */
345
386
  async getSession(sessionId) {
387
+ if (!sessionId) {
388
+ throw new Error('Session ID is required');
389
+ }
346
390
  return await this.client.get(`ai/session/${sessionId}`);
347
391
  }
348
392
 
349
393
  /**
350
- * List sessions
394
+ * Create a session token for client-side access (server-side)
395
+ * @param {string} sessionId - Session ID
396
+ * @returns {Promise<Object>} Token data (accessToken, refreshToken)
397
+ */
398
+ async createSessionToken(sessionId) {
399
+ if (!sessionId) {
400
+ throw new Error('Session ID is required');
401
+ }
402
+ return await this.client.post(`ai/session/${sessionId}/token/create`);
403
+ }
404
+
405
+ /**
406
+ * Revoke a session token (server-side)
407
+ * @param {string} sessionId - Session ID
408
+ * @returns {Promise<Object>} Revocation result
409
+ */
410
+ async revokeSessionToken(sessionId) {
411
+ if (!sessionId) {
412
+ throw new Error('Session ID is required');
413
+ }
414
+ return await this.client.post(`ai/session/${sessionId}/token/revoke`);
415
+ }
416
+
417
+ /**
418
+ * Get session history by session ID (server-side)
419
+ * @param {string} sessionId - Session ID
420
+ * @param {Object} [options] - Query options
421
+ * @param {number} [options.limit] - Number of messages (max 100)
422
+ * @param {number} [options.offset] - Offset for pagination
423
+ * @returns {Promise<Object>} Session history with messages
424
+ */
425
+ async getSessionHistory(sessionId, options = {}) {
426
+ if (!sessionId) {
427
+ throw new Error('Session ID is required');
428
+ }
429
+
430
+ const params = new URLSearchParams();
431
+ if (options.limit) params.append('limit', Math.min(options.limit, 100).toString());
432
+ if (options.offset) params.append('offset', Math.max(options.offset, 0).toString());
433
+
434
+ const url = `ai/session/${sessionId}/history${params.toString() ? `?${params.toString()}` : ''}`;
435
+ return await this.client.get(url);
436
+ }
437
+
438
+ /**
439
+ * Ban a user from a session (server-side)
440
+ * @param {string} sessionId - Session ID
441
+ * @param {Object} [options] - Ban options
442
+ * @param {string} [options.reason] - Reason for ban
443
+ * @returns {Promise<Object>} Ban result
444
+ */
445
+ async banUser(sessionId, options = {}) {
446
+ if (!sessionId) {
447
+ throw new Error('Session ID is required');
448
+ }
449
+ return await this.client.post(`ai/session/${sessionId}/ban`, options);
450
+ }
451
+
452
+ /**
453
+ * Unban a user from a session (server-side)
454
+ * @param {string} sessionId - Session ID
455
+ * @returns {Promise<Object>} Unban result
456
+ */
457
+ async unbanUser(sessionId) {
458
+ if (!sessionId) {
459
+ throw new Error('Session ID is required');
460
+ }
461
+ return await this.client.post(`ai/session/${sessionId}/unban`);
462
+ }
463
+
464
+ /**
465
+ * Lock or unlock a session (server-side)
466
+ * @param {string} sessionId - Session ID
467
+ * @param {Object} [options] - Lock options
468
+ * @param {boolean} [options.locked] - Lock state (true to lock, false to unlock)
469
+ * @returns {Promise<Object>} Lock result
470
+ */
471
+ async lockSession(sessionId, options = {}) {
472
+ if (!sessionId) {
473
+ throw new Error('Session ID is required');
474
+ }
475
+ return await this.client.post(`ai/session/${sessionId}/lock`, options);
476
+ }
477
+
478
+ /**
479
+ * List sessions (server-side)
351
480
  * @param {Object} [options] - Query options
352
481
  * @param {string} [options.namespace] - Filter by namespace
353
482
  * @param {string} [options.agentId] - Filter by agent ID
@@ -369,11 +498,14 @@ export class OblienChat {
369
498
  }
370
499
 
371
500
  /**
372
- * Delete a session
501
+ * Delete a session (server-side)
373
502
  * @param {string} sessionId - Session ID to delete
374
503
  * @returns {Promise<Object>} Deletion result
375
504
  */
376
505
  async deleteSession(sessionId) {
506
+ if (!sessionId) {
507
+ throw new Error('Session ID is required');
508
+ }
377
509
  return await this.client.delete(`ai/session/${sessionId}`);
378
510
  }
379
511
 
@@ -429,6 +561,107 @@ export class OblienChat {
429
561
  const data = await this.client.get('ai/guest/cache-stats');
430
562
  return data;
431
563
  }
564
+
565
+ /**
566
+ * Refresh session token (client-side)
567
+ * Uses refresh token to get new access token
568
+ *
569
+ * @param {string} refreshToken - Refresh token from session
570
+ * @returns {Promise<Object>} New tokens
571
+ */
572
+ async refreshToken(refreshToken) {
573
+ if (!refreshToken) {
574
+ throw new Error('Refresh token is required');
575
+ }
576
+
577
+ const url = this.client._buildURL('ai/session/token/refresh');
578
+ const response = await fetch(url, {
579
+ method: 'POST',
580
+ headers: {
581
+ 'Authorization': `Bearer ${refreshToken}`,
582
+ 'Content-Type': 'application/json',
583
+ },
584
+ });
585
+
586
+ if (!response.ok) {
587
+ const error = await response.json().catch(() => ({ message: response.statusText }));
588
+ throw new Error(error.message || error.error || `API error: ${response.status}`);
589
+ }
590
+
591
+ return await response.json();
592
+ }
593
+
594
+ /**
595
+ * Get chat history (client-side)
596
+ * Uses session token to get chat history
597
+ *
598
+ * @param {Object} options - History options
599
+ * @param {string} options.token - Session token (required for client-side)
600
+ * @param {string} [options.namespace] - Namespace filter
601
+ * @param {number} [options.limit] - Number of messages (max 50)
602
+ * @param {number} [options.offset] - Offset for pagination
603
+ * @returns {Promise<Object>} Chat history with messages
604
+ */
605
+ async getHistory(options = {}) {
606
+ const { token, namespace, limit = 50, offset = 0 } = options;
607
+
608
+ if (!token) {
609
+ throw new Error('Session token is required for client-side history');
610
+ }
611
+
612
+ const params = new URLSearchParams();
613
+ if (namespace) params.append('namespace', namespace);
614
+ params.append('limit', Math.min(limit, 50).toString());
615
+ params.append('offset', Math.max(offset, 0).toString());
616
+
617
+ const url = `${this.client._buildURL('ai/session/history')}?${params.toString()}`;
618
+ const response = await fetch(url, {
619
+ method: 'GET',
620
+ headers: {
621
+ 'Authorization': `Bearer ${token}`,
622
+ 'Content-Type': 'application/json',
623
+ },
624
+ });
625
+
626
+ if (!response.ok) {
627
+ const error = await response.json().catch(() => ({ message: response.statusText }));
628
+ throw new Error(error.message || error.error || `API error: ${response.status}`);
629
+ }
630
+
631
+ return await response.json();
632
+ }
633
+
634
+ /**
635
+ * Prepare session (client-side)
636
+ * Prepares session for app/container usage
637
+ *
638
+ * @param {Object} options - Prepare options
639
+ * @param {string} options.token - Session token (required for client-side)
640
+ * @returns {Promise<Object>} Preparation result
641
+ */
642
+ async prepareSession(options = {}) {
643
+ const { token } = options;
644
+
645
+ if (!token) {
646
+ throw new Error('Session token is required for client-side prepare');
647
+ }
648
+
649
+ const url = this.client._buildURL('ai/session/prepare');
650
+ const response = await fetch(url, {
651
+ method: 'POST',
652
+ headers: {
653
+ 'Authorization': `Bearer ${token}`,
654
+ 'Content-Type': 'application/json',
655
+ },
656
+ });
657
+
658
+ if (!response.ok) {
659
+ const error = await response.json().catch(() => ({ message: response.statusText }));
660
+ throw new Error(error.message || error.error || `API error: ${response.status}`);
661
+ }
662
+
663
+ return await response.json();
664
+ }
432
665
  }
433
666
 
434
667
  export { ChatSession } from './session.js';
package/src/client.js CHANGED
@@ -126,15 +126,22 @@ export class OblienClient {
126
126
  /**
127
127
  * Make DELETE request
128
128
  * @param {string} path - API path
129
+ * @param {Object} [body] - Request body
129
130
  * @returns {Promise<any>} Response data
130
131
  */
131
- async delete(path) {
132
+ async delete(path, body = null) {
132
133
  const headers = this.getAuthHeaders();
133
134
 
134
- const response = await fetch(this._buildURL(path), {
135
+ const options = {
135
136
  method: 'DELETE',
136
137
  headers,
137
- });
138
+ };
139
+
140
+ if (body) {
141
+ options.body = JSON.stringify(body);
142
+ }
143
+
144
+ const response = await fetch(this._buildURL(path), options);
138
145
 
139
146
  return this._handleResponse(response);
140
147
  }
@@ -122,6 +122,187 @@ export class OblienCredits {
122
122
  return response;
123
123
  }
124
124
 
125
+ // =============================================================================
126
+ // End User Quota Management (Optional Third Level)
127
+ // =============================================================================
128
+
129
+ /**
130
+ * Set quota for an end user within a namespace
131
+ * @param {Object} options - Quota options
132
+ * @param {string} options.namespace - Namespace slug
133
+ * @param {string} options.endUserId - End user ID
134
+ * @param {string} options.service - Service name (e.g., 'ai_chat', 'deployment', 'sandbox')
135
+ * @param {number} options.quotaLimit - Quota limit (null or 0 for unlimited)
136
+ * @param {string} [options.period] - Quota period: 'daily', 'monthly', 'unlimited'
137
+ * @returns {Promise<Object>} Created/updated end user quota
138
+ */
139
+ async setEndUserQuota(options) {
140
+ if (!options.namespace || !options.endUserId || !options.service) {
141
+ throw new Error('namespace, endUserId, and service are required');
142
+ }
143
+
144
+ if (options.quotaLimit === undefined) {
145
+ throw new Error('quotaLimit is required');
146
+ }
147
+
148
+ const response = await this.client.post('credits/end-users/quota', {
149
+ namespace: options.namespace,
150
+ endUserId: options.endUserId,
151
+ service: options.service,
152
+ quotaLimit: options.quotaLimit,
153
+ period: options.period || 'unlimited'
154
+ });
155
+
156
+ return response;
157
+ }
158
+
159
+ /**
160
+ * Get end user quota
161
+ * @param {string} namespace - Namespace slug
162
+ * @param {string} endUserId - End user ID
163
+ * @param {string} service - Service name
164
+ * @returns {Promise<Object>} End user quota details
165
+ */
166
+ async getEndUserQuota(namespace, endUserId, service) {
167
+ if (!namespace || !endUserId || !service) {
168
+ throw new Error('namespace, endUserId, and service are required');
169
+ }
170
+
171
+ const response = await this.client.get('credits/end-users/quota', {
172
+ namespace,
173
+ endUserId,
174
+ service
175
+ });
176
+
177
+ return response;
178
+ }
179
+
180
+ /**
181
+ * Reset end user quota usage
182
+ * @param {string} namespace - Namespace slug
183
+ * @param {string} endUserId - End user ID
184
+ * @param {string} service - Service name
185
+ * @returns {Promise<Object>} Reset result
186
+ */
187
+ async resetEndUserQuota(namespace, endUserId, service) {
188
+ if (!namespace || !endUserId || !service) {
189
+ throw new Error('namespace, endUserId, and service are required');
190
+ }
191
+
192
+ const response = await this.client.post('credits/end-users/reset', {
193
+ namespace,
194
+ endUserId,
195
+ service
196
+ });
197
+
198
+ return response;
199
+ }
200
+
201
+ // =============================================================================
202
+ // Default Quota Configuration (Dynamic, per client)
203
+ // =============================================================================
204
+
205
+ /**
206
+ * Set default quota configuration
207
+ * @param {Object} options - Configuration options
208
+ * @param {string} options.level - 'namespace' or 'end_user'
209
+ * @param {string} options.service - Service name (e.g., 'ai_chat', 'deployment')
210
+ * @param {number} options.quotaLimit - Default quota limit (null for unlimited)
211
+ * @param {string} [options.period] - 'daily', 'monthly', or 'unlimited'
212
+ * @param {boolean} [options.autoApply] - Auto-apply to new namespaces/users
213
+ * @returns {Promise<Object>} Configuration result
214
+ */
215
+ async setDefaultQuota(options) {
216
+ if (!options.level || !options.service || options.quotaLimit === undefined) {
217
+ throw new Error('level, service, and quotaLimit are required');
218
+ }
219
+
220
+ if (!['namespace', 'end_user'].includes(options.level)) {
221
+ throw new Error('level must be "namespace" or "end_user"');
222
+ }
223
+
224
+ const response = await this.client.post('credits/defaults', {
225
+ level: options.level,
226
+ service: options.service,
227
+ quotaLimit: options.quotaLimit,
228
+ period: options.period || 'unlimited',
229
+ autoApply: options.autoApply !== undefined ? options.autoApply : true,
230
+ });
231
+
232
+ return response;
233
+ }
234
+
235
+ /**
236
+ * Get default quota configuration
237
+ * @param {string} level - 'namespace' or 'end_user'
238
+ * @param {string} service - Service name
239
+ * @returns {Promise<Object>} Configuration details
240
+ */
241
+ async getDefaultQuota(level, service) {
242
+ if (!level || !service) {
243
+ throw new Error('level and service are required');
244
+ }
245
+
246
+ const response = await this.client.get('credits/defaults', {
247
+ level,
248
+ service,
249
+ });
250
+
251
+ return response;
252
+ }
253
+
254
+ /**
255
+ * Get all default quota configurations
256
+ * @param {string} [level] - Optional: filter by 'namespace' or 'end_user'
257
+ * @returns {Promise<Object>} All configurations
258
+ */
259
+ async getAllDefaultQuotas(level = null) {
260
+ const params = level ? { level } : {};
261
+ const response = await this.client.get('credits/defaults/all', params);
262
+ return response;
263
+ }
264
+
265
+ /**
266
+ * Delete default quota configuration
267
+ * @param {string} level - 'namespace' or 'end_user'
268
+ * @param {string} service - Service name
269
+ * @returns {Promise<Object>} Deletion result
270
+ */
271
+ async deleteDefaultQuota(level, service) {
272
+ if (!level || !service) {
273
+ throw new Error('level and service are required');
274
+ }
275
+
276
+ // DELETE with body
277
+ const response = await this.client.delete('credits/defaults', {
278
+ level,
279
+ service,
280
+ });
281
+
282
+ return response;
283
+ }
284
+
285
+ /**
286
+ * Toggle auto-apply for default quota
287
+ * @param {string} level - 'namespace' or 'end_user'
288
+ * @param {string} service - Service name
289
+ * @param {boolean} autoApply - Enable/disable auto-apply
290
+ * @returns {Promise<Object>} Toggle result
291
+ */
292
+ async toggleDefaultQuotaAutoApply(level, service, autoApply) {
293
+ if (!level || !service || autoApply === undefined) {
294
+ throw new Error('level, service, and autoApply are required');
295
+ }
296
+
297
+ const response = await this.client.post('credits/defaults/toggle-auto-apply', {
298
+ level,
299
+ service,
300
+ autoApply,
301
+ });
302
+
303
+ return response;
304
+ }
305
+
125
306
  // =============================================================================
126
307
  // Usage History & Transactions
127
308
  // =============================================================================
@@ -1,99 +0,0 @@
1
- /**
2
- * Session Quota Manager
3
- * Manages per-session quota limits and tracking
4
- */
5
-
6
- export class SessionQuota {
7
- /**
8
- * @param {Object} options
9
- * @param {import('../client.js').OblienClient} options.client - Oblien client instance
10
- * @param {string} options.sessionId - Session ID
11
- */
12
- constructor({ client, sessionId }) {
13
- if (!client) {
14
- throw new Error('Oblien client is required');
15
- }
16
- if (!sessionId) {
17
- throw new Error('Session ID is required');
18
- }
19
-
20
- this.client = client;
21
- this.sessionId = sessionId;
22
- }
23
-
24
- /**
25
- * Get session quota status
26
- * @returns {Promise<Object>} Quota status
27
- */
28
- async get() {
29
- const data = await this.client.get(`ai/session/${this.sessionId}/quota`);
30
- return data.quota || data;
31
- }
32
-
33
- /**
34
- * Set session quota limit (manual override)
35
- * @param {number} limit - Quota limit (null for unlimited)
36
- * @param {string} [period] - Quota period: 'daily', 'monthly', 'unlimited'
37
- * @returns {Promise<Object>} Updated quota status
38
- */
39
- async set(limit, period = 'unlimited') {
40
- const data = await this.client.post(`ai/session/${this.sessionId}/quota`, {
41
- limit,
42
- period
43
- });
44
- return data.quota || data;
45
- }
46
-
47
- /**
48
- * Reset session quota usage
49
- * @returns {Promise<Object>} Reset result
50
- */
51
- async reset() {
52
- return await this.client.post(`ai/session/${this.sessionId}/quota/reset`, {});
53
- }
54
-
55
- /**
56
- * Check if session can use credits (validation before action)
57
- * @param {number} amount - Amount of credits to check
58
- * @returns {Promise<Object>} { canUse, quota, reason }
59
- */
60
- async canUse(amount) {
61
- const data = await this.client.post(`ai/session/${this.sessionId}/quota/can-use`, {
62
- amount
63
- });
64
- return {
65
- canUse: data.canUse,
66
- quota: data.quota,
67
- reason: data.reason
68
- };
69
- }
70
-
71
- /**
72
- * Get quota transaction history
73
- * @param {Object} [options] - Query options
74
- * @param {number} [options.limit] - Number of results (max 100)
75
- * @param {number} [options.offset] - Offset for pagination
76
- * @returns {Promise<Array>} Array of transactions
77
- */
78
- async getTransactions(options = {}) {
79
- const data = await this.client.get(`ai/session/${this.sessionId}/quota/transactions`, options);
80
- return data.transactions || data;
81
- }
82
-
83
- /**
84
- * Get current usage
85
- * @returns {Promise<Object>} { used, limit, available }
86
- */
87
- async getUsage() {
88
- const quota = await this.get();
89
- return {
90
- used: quota.used || 0,
91
- limit: quota.limit,
92
- available: quota.available,
93
- enabled: quota.enabled
94
- };
95
- }
96
- }
97
-
98
- export default SessionQuota;
99
-