@reititin/client 0.0.10 → 0.0.12
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 +7 -0
- package/index.js +154 -154
- package/package.json +29 -27
package/index.d.ts
ADDED
package/index.js
CHANGED
|
@@ -1,154 +1,154 @@
|
|
|
1
|
-
import http2 from 'http2';
|
|
2
|
-
|
|
3
|
-
export const ReititinClient = ({ host, token, onMessage }) => {
|
|
4
|
-
const MESSAGE_ENDPOINT = `/api/agents/messages`;
|
|
5
|
-
|
|
6
|
-
let client;
|
|
7
|
-
let req;
|
|
8
|
-
let reconnectTimer;
|
|
9
|
-
const RECONNECT_DELAY = 1000;
|
|
10
|
-
|
|
11
|
-
const connectSSE = () => {
|
|
12
|
-
console.log(`Connecting to SSE at ${host}...`);
|
|
13
|
-
|
|
14
|
-
client = http2.connect(`
|
|
15
|
-
|
|
16
|
-
client.on('error', (err) => {
|
|
17
|
-
console.error('Client error:', err);
|
|
18
|
-
cleanup();
|
|
19
|
-
scheduleReconnect();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
req = client.request({
|
|
23
|
-
':method': 'GET',
|
|
24
|
-
':path': MESSAGE_ENDPOINT,
|
|
25
|
-
'accept': 'text/event-stream',
|
|
26
|
-
'authorization': `Bearer ${token}`
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
req.setEncoding('utf8');
|
|
30
|
-
|
|
31
|
-
let buffer = '';
|
|
32
|
-
|
|
33
|
-
req.on('data', async (chunk) => {
|
|
34
|
-
// console.log("Received chunk:", chunk);
|
|
35
|
-
// Uncomment for debugging
|
|
36
|
-
|
|
37
|
-
buffer += chunk;
|
|
38
|
-
|
|
39
|
-
// SSE events are separated by double newline
|
|
40
|
-
const parts = buffer.split('\n\n');
|
|
41
|
-
buffer = parts.pop(); // Keep the incomplete part in the buffer
|
|
42
|
-
|
|
43
|
-
for (const part of parts) {
|
|
44
|
-
if (!part.trim()) continue;
|
|
45
|
-
|
|
46
|
-
// Skip comments like ": connected"
|
|
47
|
-
if (part.startsWith(':')) continue;
|
|
48
|
-
|
|
49
|
-
const lines = part.split('\n');
|
|
50
|
-
|
|
51
|
-
const dataLine = lines.find(line => line.startsWith('data: '));
|
|
52
|
-
if (dataLine) {
|
|
53
|
-
const rawData = dataLine.substring(6); // remove "data: "
|
|
54
|
-
try {
|
|
55
|
-
const payload = JSON.parse(rawData);
|
|
56
|
-
|
|
57
|
-
const { agent_id, chat_id, content } = payload;
|
|
58
|
-
|
|
59
|
-
if (onMessage && agent_id && chat_id && content) {
|
|
60
|
-
console.log("Message received. Processing payload:", payload);
|
|
61
|
-
|
|
62
|
-
// The content from backend is a stringified JSON array of messages
|
|
63
|
-
let messages = [];
|
|
64
|
-
try {
|
|
65
|
-
messages = JSON.parse(content);
|
|
66
|
-
} catch (err) {
|
|
67
|
-
console.error("Failed to parse message content:", err);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const processedMessage = await onMessage(messages);
|
|
71
|
-
|
|
72
|
-
// Send response via HTTP/2 stream
|
|
73
|
-
try {
|
|
74
|
-
const responseBody = JSON.stringify({
|
|
75
|
-
chat_id,
|
|
76
|
-
agent_id,
|
|
77
|
-
message: processedMessage
|
|
78
|
-
});
|
|
79
|
-
const responseBuffer = Buffer.from(responseBody);
|
|
80
|
-
|
|
81
|
-
const postReq = client.request({
|
|
82
|
-
':method': 'POST',
|
|
83
|
-
':path': '/api/inference/finalize',
|
|
84
|
-
'authorization': `Bearer ${token}`,
|
|
85
|
-
'content-type': 'application/json',
|
|
86
|
-
'content-length': responseBuffer.length
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
postReq.setEncoding('utf8');
|
|
90
|
-
postReq.on('response', (headers) => {
|
|
91
|
-
// console.log("Finalize response headers:", headers);
|
|
92
|
-
const status = headers[':status'];
|
|
93
|
-
if (status && status !== 200) {
|
|
94
|
-
console.error(`Error sending response: Status ${status}`);
|
|
95
|
-
// We can read body to see error message
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
postReq.on('data', (d) => {
|
|
99
|
-
// console.log("Finalize response data:", d);
|
|
100
|
-
});
|
|
101
|
-
postReq.on('end', () => {
|
|
102
|
-
console.log("Response sent successfully.");
|
|
103
|
-
});
|
|
104
|
-
postReq.on('error', (e) => {
|
|
105
|
-
console.error("Error sending response:", e);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
postReq.write(responseBuffer);
|
|
109
|
-
postReq.end();
|
|
110
|
-
|
|
111
|
-
} catch (e) {
|
|
112
|
-
console.error("Error creating response request:", e);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
} catch (e) {
|
|
116
|
-
console.error("Error processing message:", e);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
req.on('end', () => {
|
|
123
|
-
console.log('Stream ended.');
|
|
124
|
-
cleanup();
|
|
125
|
-
scheduleReconnect();
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
req.on('error', (err) => {
|
|
129
|
-
console.error('Stream error:', err);
|
|
130
|
-
cleanup();
|
|
131
|
-
scheduleReconnect();
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
req.end();
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
const cleanup = () => {
|
|
138
|
-
if (req) {
|
|
139
|
-
try { req.close(); } catch (e) { }
|
|
140
|
-
req = null;
|
|
141
|
-
}
|
|
142
|
-
if (client) {
|
|
143
|
-
try { client.close(); } catch (e) { }
|
|
144
|
-
client = null;
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const scheduleReconnect = () => {
|
|
149
|
-
if (reconnectTimer) clearTimeout(reconnectTimer);
|
|
150
|
-
reconnectTimer = setTimeout(connectSSE, RECONNECT_DELAY);
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
connectSSE();
|
|
154
|
-
};
|
|
1
|
+
import http2 from 'http2';
|
|
2
|
+
|
|
3
|
+
export const ReititinClient = ({ host, token, onMessage }) => {
|
|
4
|
+
const MESSAGE_ENDPOINT = `/api/agents/messages`;
|
|
5
|
+
|
|
6
|
+
let client;
|
|
7
|
+
let req;
|
|
8
|
+
let reconnectTimer;
|
|
9
|
+
const RECONNECT_DELAY = 1000;
|
|
10
|
+
|
|
11
|
+
const connectSSE = () => {
|
|
12
|
+
console.log(`Connecting to SSE at ${host}...`);
|
|
13
|
+
|
|
14
|
+
client = http2.connect(`https://${host}`);
|
|
15
|
+
|
|
16
|
+
client.on('error', (err) => {
|
|
17
|
+
console.error('Client error:', err);
|
|
18
|
+
cleanup();
|
|
19
|
+
scheduleReconnect();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
req = client.request({
|
|
23
|
+
':method': 'GET',
|
|
24
|
+
':path': MESSAGE_ENDPOINT,
|
|
25
|
+
'accept': 'text/event-stream',
|
|
26
|
+
'authorization': `Bearer ${token}`
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
req.setEncoding('utf8');
|
|
30
|
+
|
|
31
|
+
let buffer = '';
|
|
32
|
+
|
|
33
|
+
req.on('data', async (chunk) => {
|
|
34
|
+
// console.log("Received chunk:", chunk);
|
|
35
|
+
// Uncomment for debugging
|
|
36
|
+
|
|
37
|
+
buffer += chunk;
|
|
38
|
+
|
|
39
|
+
// SSE events are separated by double newline
|
|
40
|
+
const parts = buffer.split('\n\n');
|
|
41
|
+
buffer = parts.pop(); // Keep the incomplete part in the buffer
|
|
42
|
+
|
|
43
|
+
for (const part of parts) {
|
|
44
|
+
if (!part.trim()) continue;
|
|
45
|
+
|
|
46
|
+
// Skip comments like ": connected"
|
|
47
|
+
if (part.startsWith(':')) continue;
|
|
48
|
+
|
|
49
|
+
const lines = part.split('\n');
|
|
50
|
+
|
|
51
|
+
const dataLine = lines.find(line => line.startsWith('data: '));
|
|
52
|
+
if (dataLine) {
|
|
53
|
+
const rawData = dataLine.substring(6); // remove "data: "
|
|
54
|
+
try {
|
|
55
|
+
const payload = JSON.parse(rawData);
|
|
56
|
+
|
|
57
|
+
const { agent_id, chat_id, content } = payload;
|
|
58
|
+
|
|
59
|
+
if (onMessage && agent_id && chat_id && content) {
|
|
60
|
+
console.log("Message received. Processing payload:", payload);
|
|
61
|
+
|
|
62
|
+
// The content from backend is a stringified JSON array of messages
|
|
63
|
+
let messages = [];
|
|
64
|
+
try {
|
|
65
|
+
messages = JSON.parse(content);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error("Failed to parse message content:", err);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const processedMessage = await onMessage(messages);
|
|
71
|
+
|
|
72
|
+
// Send response via HTTP/2 stream
|
|
73
|
+
try {
|
|
74
|
+
const responseBody = JSON.stringify({
|
|
75
|
+
chat_id,
|
|
76
|
+
agent_id,
|
|
77
|
+
message: processedMessage
|
|
78
|
+
});
|
|
79
|
+
const responseBuffer = Buffer.from(responseBody);
|
|
80
|
+
|
|
81
|
+
const postReq = client.request({
|
|
82
|
+
':method': 'POST',
|
|
83
|
+
':path': '/api/inference/finalize',
|
|
84
|
+
'authorization': `Bearer ${token}`,
|
|
85
|
+
'content-type': 'application/json',
|
|
86
|
+
'content-length': responseBuffer.length
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
postReq.setEncoding('utf8');
|
|
90
|
+
postReq.on('response', (headers) => {
|
|
91
|
+
// console.log("Finalize response headers:", headers);
|
|
92
|
+
const status = headers[':status'];
|
|
93
|
+
if (status && status !== 200) {
|
|
94
|
+
console.error(`Error sending response: Status ${status}`);
|
|
95
|
+
// We can read body to see error message
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
postReq.on('data', (d) => {
|
|
99
|
+
// console.log("Finalize response data:", d);
|
|
100
|
+
});
|
|
101
|
+
postReq.on('end', () => {
|
|
102
|
+
console.log("Response sent successfully.");
|
|
103
|
+
});
|
|
104
|
+
postReq.on('error', (e) => {
|
|
105
|
+
console.error("Error sending response:", e);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
postReq.write(responseBuffer);
|
|
109
|
+
postReq.end();
|
|
110
|
+
|
|
111
|
+
} catch (e) {
|
|
112
|
+
console.error("Error creating response request:", e);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch (e) {
|
|
116
|
+
console.error("Error processing message:", e);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
req.on('end', () => {
|
|
123
|
+
console.log('Stream ended.');
|
|
124
|
+
cleanup();
|
|
125
|
+
scheduleReconnect();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
req.on('error', (err) => {
|
|
129
|
+
console.error('Stream error:', err);
|
|
130
|
+
cleanup();
|
|
131
|
+
scheduleReconnect();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
req.end();
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const cleanup = () => {
|
|
138
|
+
if (req) {
|
|
139
|
+
try { req.close(); } catch (e) { }
|
|
140
|
+
req = null;
|
|
141
|
+
}
|
|
142
|
+
if (client) {
|
|
143
|
+
try { client.close(); } catch (e) { }
|
|
144
|
+
client = null;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const scheduleReconnect = () => {
|
|
149
|
+
if (reconnectTimer) clearTimeout(reconnectTimer);
|
|
150
|
+
reconnectTimer = setTimeout(connectSSE, RECONNECT_DELAY);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
connectSSE();
|
|
154
|
+
};
|
package/package.json
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@reititin/client",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Reititin client allows you to connect your LLM system to Reititin platform.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"AI",
|
|
7
|
-
"LLM",
|
|
8
|
-
"message",
|
|
9
|
-
"broker"
|
|
10
|
-
],
|
|
11
|
-
"license": "ISC",
|
|
12
|
-
"author": "Reititin",
|
|
13
|
-
"type": "module",
|
|
14
|
-
"main": "index.js",
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@reititin/client",
|
|
3
|
+
"version": "0.0.12",
|
|
4
|
+
"description": "Reititin client allows you to connect your LLM system to Reititin platform.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"AI",
|
|
7
|
+
"LLM",
|
|
8
|
+
"message",
|
|
9
|
+
"broker"
|
|
10
|
+
],
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"author": "Reititin",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "index.js",
|
|
15
|
+
"types": "index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"index.js",
|
|
18
|
+
"index.d.ts"
|
|
19
|
+
],
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/reititin/reititin-client.git"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"axios": "1.8.2"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
}
|
|
28
30
|
}
|