oblien 1.0.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/LICENSE +21 -0
- package/README.md +455 -0
- package/chat.js +21 -0
- package/index.d.ts +180 -0
- package/index.js +23 -0
- package/package.json +67 -0
- package/src/chat/index.js +149 -0
- package/src/chat/session.js +99 -0
- package/src/client.js +189 -0
- package/src/utils/guest-manager.js +349 -0
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "oblien",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Server-side SDK for Oblien AI Platform - Build AI-powered applications with chat, agents, and workflows",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./index.js",
|
|
10
|
+
"./chat": "./chat.js",
|
|
11
|
+
"./agents": "./agents.js",
|
|
12
|
+
"./workflows": "./workflows.js",
|
|
13
|
+
"./guest": "./src/utils/guest-manager.js"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "node --test tests/**/*.test.js"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"oblien",
|
|
20
|
+
"ai",
|
|
21
|
+
"chat",
|
|
22
|
+
"agents",
|
|
23
|
+
"workflows",
|
|
24
|
+
"sdk",
|
|
25
|
+
"api",
|
|
26
|
+
"server-side",
|
|
27
|
+
"llm",
|
|
28
|
+
"assistant"
|
|
29
|
+
],
|
|
30
|
+
"author": "Oblien",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git@github.com:oblien/oblien-core.git"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://oblien.com/docs/core-sdk",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/oblien/oblien-core/issues"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"node-cache": "^5.1.2"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"redis": "^4.0.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependenciesMeta": {
|
|
47
|
+
"redis": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^20.0.0"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=18.0.0"
|
|
56
|
+
},
|
|
57
|
+
"files": [
|
|
58
|
+
"src/",
|
|
59
|
+
"index.js",
|
|
60
|
+
"index.d.ts",
|
|
61
|
+
"chat.js",
|
|
62
|
+
"agents.js",
|
|
63
|
+
"workflows.js",
|
|
64
|
+
"README.md",
|
|
65
|
+
"LICENSE"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Module (Server-Side Session Management)
|
|
3
|
+
* Creates sessions and returns tokens for client-side chat
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ChatSession } from './session.js';
|
|
7
|
+
import { GuestManager } from '../utils/guest-manager.js';
|
|
8
|
+
|
|
9
|
+
export class OblienChat {
|
|
10
|
+
/**
|
|
11
|
+
* @param {import('../client.js').OblienClient} client - Oblien client instance
|
|
12
|
+
* @param {Object} [options] - Configuration options
|
|
13
|
+
* @param {Object} [options.guestManager] - Custom guest manager instance
|
|
14
|
+
* @param {Object} [options.guestStorage] - Storage adapter for guest manager
|
|
15
|
+
* @param {number} [options.guestTTL] - Guest session TTL in seconds
|
|
16
|
+
*/
|
|
17
|
+
constructor(client, options = {}) {
|
|
18
|
+
if (!client) {
|
|
19
|
+
throw new Error('Oblien client is required');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
this.client = client;
|
|
23
|
+
|
|
24
|
+
// Initialize guest manager if not provided
|
|
25
|
+
this.guestManager = options.guestManager || new GuestManager({
|
|
26
|
+
storage: options.guestStorage,
|
|
27
|
+
ttl: options.guestTTL,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Create a new session and return token for client
|
|
33
|
+
* @param {Object} options - Session options
|
|
34
|
+
* @param {string} options.agentId - Agent ID to chat with
|
|
35
|
+
* @param {string} [options.workflowId] - Workflow ID (if using workflow)
|
|
36
|
+
* @param {Object} [options.workspace] - Workspace configuration
|
|
37
|
+
* @returns {Promise<Object>} Session data with token
|
|
38
|
+
*/
|
|
39
|
+
async createSession(options) {
|
|
40
|
+
const session = new ChatSession({
|
|
41
|
+
client: this.client,
|
|
42
|
+
...options,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return await session.create();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Create a guest session based on IP
|
|
50
|
+
* @param {Object} options - Guest session options
|
|
51
|
+
* @param {string} options.ip - Client IP address
|
|
52
|
+
* @param {string} options.agentId - Agent ID to chat with
|
|
53
|
+
* @param {string} [options.workflowId] - Workflow ID
|
|
54
|
+
* @param {Object} [options.metadata] - Additional guest metadata
|
|
55
|
+
* @param {Object} [options.workspace] - Workspace configuration
|
|
56
|
+
* @returns {Promise<Object>} Session data with token and guest info
|
|
57
|
+
*/
|
|
58
|
+
async createGuestSession(options) {
|
|
59
|
+
const { ip, agentId, workflowId, metadata, workspace } = options;
|
|
60
|
+
|
|
61
|
+
if (!ip) {
|
|
62
|
+
throw new Error('IP address is required for guest sessions');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Get or create guest user
|
|
66
|
+
const guest = await this.guestManager.getOrCreateGuest(ip, metadata);
|
|
67
|
+
|
|
68
|
+
// Create session
|
|
69
|
+
const session = new ChatSession({
|
|
70
|
+
client: this.client,
|
|
71
|
+
agentId,
|
|
72
|
+
workflowId,
|
|
73
|
+
workspace,
|
|
74
|
+
isGuest: true,
|
|
75
|
+
namespace: guest.namespace,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const sessionData = await session.create();
|
|
79
|
+
|
|
80
|
+
// Link session to guest
|
|
81
|
+
await this.guestManager.addSession(guest.id, sessionData.sessionId);
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
...sessionData,
|
|
85
|
+
guest: {
|
|
86
|
+
id: guest.id,
|
|
87
|
+
namespace: guest.namespace,
|
|
88
|
+
createdAt: guest.createdAt,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get guest by IP
|
|
95
|
+
* @param {string} ip - IP address
|
|
96
|
+
* @returns {Promise<Object|null>} Guest object or null
|
|
97
|
+
*/
|
|
98
|
+
async getGuestByIP(ip) {
|
|
99
|
+
const guestId = this.guestManager.generateGuestId(ip);
|
|
100
|
+
return await this.guestManager.getGuest(guestId);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Get session info
|
|
105
|
+
* @param {string} sessionId - Session ID
|
|
106
|
+
* @returns {Promise<Object>} Session details
|
|
107
|
+
*/
|
|
108
|
+
async getSession(sessionId) {
|
|
109
|
+
return await this.client.get(`ai/session/${sessionId}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* List sessions
|
|
114
|
+
* @param {Object} [options] - Query options
|
|
115
|
+
* @returns {Promise<Array>} Array of sessions
|
|
116
|
+
*/
|
|
117
|
+
async listSessions(options = {}) {
|
|
118
|
+
const data = await this.client.get('ai/session', options);
|
|
119
|
+
return data.sessions || data;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Delete a session
|
|
124
|
+
* @param {string} sessionId - Session ID to delete
|
|
125
|
+
* @returns {Promise<Object>} Deletion result
|
|
126
|
+
*/
|
|
127
|
+
async deleteSession(sessionId) {
|
|
128
|
+
return await this.client.delete(`ai/session/${sessionId}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Get all active guests (admin/monitoring)
|
|
133
|
+
* @returns {Promise<Array>} Array of guest objects
|
|
134
|
+
*/
|
|
135
|
+
async getAllGuests() {
|
|
136
|
+
return await this.guestManager.getAllGuests();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Clean up expired guests
|
|
141
|
+
* @returns {Promise<number>} Number of cleaned guests
|
|
142
|
+
*/
|
|
143
|
+
async cleanupGuests() {
|
|
144
|
+
return await this.guestManager.cleanup();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export { ChatSession } from './session.js';
|
|
149
|
+
export default OblienChat;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Session Manager (Server-Side Only)
|
|
3
|
+
* Creates and manages chat sessions - returns tokens for client-side chat
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class ChatSession {
|
|
7
|
+
/**
|
|
8
|
+
* @param {Object} options - Session options
|
|
9
|
+
* @param {import('../client.js').OblienClient} options.client - Oblien client instance
|
|
10
|
+
* @param {string} [options.sessionId] - Existing session ID
|
|
11
|
+
* @param {string} options.agentId - Agent ID to chat with
|
|
12
|
+
* @param {string} [options.workflowId] - Workflow ID (if using workflow)
|
|
13
|
+
* @param {boolean} [options.isGuest] - Is this a guest session
|
|
14
|
+
* @param {string} [options.namespace] - Guest namespace for rate limiting
|
|
15
|
+
* @param {Object} [options.workspace] - Workspace configuration
|
|
16
|
+
*/
|
|
17
|
+
constructor(options) {
|
|
18
|
+
if (!options.client) {
|
|
19
|
+
throw new Error('Oblien client is required');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!options.agentId && !options.workflowId) {
|
|
23
|
+
throw new Error('Either agentId or workflowId is required');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.client = options.client;
|
|
27
|
+
this.sessionId = options.sessionId || null;
|
|
28
|
+
this.agentId = options.agentId;
|
|
29
|
+
this.workflowId = options.workflowId;
|
|
30
|
+
this.isGuest = options.isGuest || false;
|
|
31
|
+
this.namespace = options.namespace;
|
|
32
|
+
this.workspace = options.workspace;
|
|
33
|
+
this.token = null;
|
|
34
|
+
this.data = null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Create session and get token for client
|
|
39
|
+
* @returns {Promise<Object>} Session data with token for browser
|
|
40
|
+
*/
|
|
41
|
+
async create() {
|
|
42
|
+
const payload = {
|
|
43
|
+
agent_id: this.agentId,
|
|
44
|
+
workflow_id: this.workflowId,
|
|
45
|
+
is_guest: this.isGuest,
|
|
46
|
+
namespace: this.namespace,
|
|
47
|
+
workspace: this.workspace,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
this.data = await this.client.post('ai/session', payload);
|
|
51
|
+
this.sessionId = this.data.sessionId || this.data.session_id;
|
|
52
|
+
this.token = this.data.token || this.data.tokens?.token;
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
sessionId: this.sessionId,
|
|
56
|
+
token: this.token,
|
|
57
|
+
agentId: this.data.agentId || this.agentId,
|
|
58
|
+
workflowId: this.data.workflowId || this.workflowId,
|
|
59
|
+
namespace: this.namespace,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get existing session info
|
|
65
|
+
* @param {string} sessionId - Session ID
|
|
66
|
+
* @returns {Promise<Object>} Session details
|
|
67
|
+
*/
|
|
68
|
+
async get(sessionId) {
|
|
69
|
+
this.data = await this.client.get(`ai/session/${sessionId || this.sessionId}`);
|
|
70
|
+
return this.data;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Delete session
|
|
76
|
+
* @param {string} [sessionId] - Session ID (uses instance sessionId if not provided)
|
|
77
|
+
* @returns {Promise<Object>} Deletion result
|
|
78
|
+
*/
|
|
79
|
+
async delete(sessionId) {
|
|
80
|
+
const id = sessionId || this.sessionId;
|
|
81
|
+
if (!id) {
|
|
82
|
+
throw new Error('Session ID required');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return await this.client.delete(`ai/session/${id}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* List all sessions
|
|
90
|
+
* @param {Object} [options] - Query options
|
|
91
|
+
* @returns {Promise<Array>} Array of sessions
|
|
92
|
+
*/
|
|
93
|
+
async list(options = {}) {
|
|
94
|
+
const data = await this.client.get('ai/session', options);
|
|
95
|
+
return data.sessions || data;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default ChatSession;
|
package/src/client.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Oblien Core Client
|
|
3
|
+
* Main client for authenticating and accessing Oblien API
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class OblienClient {
|
|
7
|
+
/**
|
|
8
|
+
* @param {Object} config - Configuration options
|
|
9
|
+
* @param {string} config.apiKey - Your Oblien API key
|
|
10
|
+
* @param {string} [config.apiSecret] - Your Oblien API secret (for server-side)
|
|
11
|
+
* @param {string} [config.baseURL] - Base URL for API (default: https://api.oblien.com)
|
|
12
|
+
* @param {string} [config.version] - API version (default: v1)
|
|
13
|
+
*/
|
|
14
|
+
constructor(config) {
|
|
15
|
+
if (!config || !config.apiKey) {
|
|
16
|
+
throw new Error('Oblien API key is required');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
this.apiKey = config.apiKey;
|
|
20
|
+
this.apiSecret = config.apiSecret;
|
|
21
|
+
this.baseURL = config.baseURL || 'https://api.oblien.com';
|
|
22
|
+
this.version = config.version || 'v1';
|
|
23
|
+
this.token = null;
|
|
24
|
+
this.tokenExpiry = null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Build full API URL
|
|
29
|
+
* @private
|
|
30
|
+
*/
|
|
31
|
+
_buildURL(path) {
|
|
32
|
+
const cleanPath = path.startsWith('/') ? path.slice(1) : path;
|
|
33
|
+
return `${this.baseURL}/${this.version}/${cleanPath}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Authenticate and get access token
|
|
38
|
+
* @returns {Promise<string>} Access token
|
|
39
|
+
*/
|
|
40
|
+
async authenticate() {
|
|
41
|
+
// Check if we have a valid token
|
|
42
|
+
if (this.token && this.tokenExpiry && Date.now() < this.tokenExpiry) {
|
|
43
|
+
return this.token;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const response = await fetch(this._buildURL('auth/authenticate'), {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
headers: {
|
|
50
|
+
'Content-Type': 'application/json',
|
|
51
|
+
},
|
|
52
|
+
body: JSON.stringify({
|
|
53
|
+
apiKey: this.apiKey,
|
|
54
|
+
apiSecret: this.apiSecret,
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
const error = await response.json();
|
|
60
|
+
throw new Error(error.message || 'Authentication failed');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const data = await response.json();
|
|
64
|
+
this.token = data.token;
|
|
65
|
+
// Token expires in 1 hour, refresh 5 min before
|
|
66
|
+
this.tokenExpiry = Date.now() + (55 * 60 * 1000);
|
|
67
|
+
|
|
68
|
+
return this.token;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
throw new Error(`Authentication error: ${error.message}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get authentication headers
|
|
76
|
+
* @returns {Promise<Object>} Headers object
|
|
77
|
+
*/
|
|
78
|
+
async getAuthHeaders() {
|
|
79
|
+
const token = await this.authenticate();
|
|
80
|
+
return {
|
|
81
|
+
'Authorization': `Bearer ${token}`,
|
|
82
|
+
'Content-Type': 'application/json',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Make GET request
|
|
88
|
+
* @param {string} path - API path
|
|
89
|
+
* @param {Object} [params] - Query parameters
|
|
90
|
+
* @returns {Promise<any>} Response data
|
|
91
|
+
*/
|
|
92
|
+
async get(path, params = {}) {
|
|
93
|
+
const headers = await this.getAuthHeaders();
|
|
94
|
+
const url = new URL(this._buildURL(path));
|
|
95
|
+
|
|
96
|
+
// Add query parameters
|
|
97
|
+
Object.keys(params).forEach(key => {
|
|
98
|
+
if (params[key] !== undefined && params[key] !== null) {
|
|
99
|
+
url.searchParams.append(key, params[key]);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const response = await fetch(url.toString(), {
|
|
104
|
+
method: 'GET',
|
|
105
|
+
headers,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return this._handleResponse(response);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Make POST request
|
|
113
|
+
* @param {string} path - API path
|
|
114
|
+
* @param {Object} [body] - Request body
|
|
115
|
+
* @returns {Promise<any>} Response data
|
|
116
|
+
*/
|
|
117
|
+
async post(path, body = {}) {
|
|
118
|
+
const headers = await this.getAuthHeaders();
|
|
119
|
+
|
|
120
|
+
const response = await fetch(this._buildURL(path), {
|
|
121
|
+
method: 'POST',
|
|
122
|
+
headers,
|
|
123
|
+
body: JSON.stringify(body),
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
return this._handleResponse(response);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Make PUT request
|
|
131
|
+
* @param {string} path - API path
|
|
132
|
+
* @param {Object} [body] - Request body
|
|
133
|
+
* @returns {Promise<any>} Response data
|
|
134
|
+
*/
|
|
135
|
+
async put(path, body = {}) {
|
|
136
|
+
const headers = await this.getAuthHeaders();
|
|
137
|
+
|
|
138
|
+
const response = await fetch(this._buildURL(path), {
|
|
139
|
+
method: 'PUT',
|
|
140
|
+
headers,
|
|
141
|
+
body: JSON.stringify(body),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return this._handleResponse(response);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Make DELETE request
|
|
149
|
+
* @param {string} path - API path
|
|
150
|
+
* @returns {Promise<any>} Response data
|
|
151
|
+
*/
|
|
152
|
+
async delete(path) {
|
|
153
|
+
const headers = await this.getAuthHeaders();
|
|
154
|
+
|
|
155
|
+
const response = await fetch(this._buildURL(path), {
|
|
156
|
+
method: 'DELETE',
|
|
157
|
+
headers,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
return this._handleResponse(response);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Handle API response
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
async _handleResponse(response) {
|
|
168
|
+
const contentType = response.headers.get('content-type');
|
|
169
|
+
|
|
170
|
+
// Handle non-JSON responses
|
|
171
|
+
if (!contentType || !contentType.includes('application/json')) {
|
|
172
|
+
if (!response.ok) {
|
|
173
|
+
throw new Error(`API error: ${response.status} ${response.statusText}`);
|
|
174
|
+
}
|
|
175
|
+
return response.text();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const data = await response.json();
|
|
179
|
+
|
|
180
|
+
if (!response.ok) {
|
|
181
|
+
throw new Error(data.message || data.error || `API error: ${response.status}`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return data;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export default OblienClient;
|