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 +48 -0
- package/package.json +1 -1
- package/src/chat/index.js +242 -9
- package/src/client.js +10 -3
- package/src/credits/index.js +181 -0
- package/src/chat/sessionQuota.js +0 -99
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
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 {
|
|
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 {
|
|
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:
|
|
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
|
-
*
|
|
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
|
|
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
|
}
|
package/src/credits/index.js
CHANGED
|
@@ -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
|
// =============================================================================
|
package/src/chat/sessionQuota.js
DELETED
|
@@ -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
|
-
|