primeorbit-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/LICENSE +21 -0
- package/README.md +201 -0
- package/build/index.cjs +320 -0
- package/build/index.d.cts +76 -0
- package/build/index.d.ts +76 -0
- package/build/index.js +278 -0
- package/package.json +89 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [year] [fullname]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# π PrimeOrbit JavaScript Client β Complete Getting Started Guide
|
|
2
|
+
|
|
3
|
+
# π Overview
|
|
4
|
+
|
|
5
|
+
We can track conversations, model responses, user feedback, and custom analytics
|
|
6
|
+
through a simple event-based API.
|
|
7
|
+
|
|
8
|
+
# π¦ Installation
|
|
9
|
+
|
|
10
|
+
Install the SDK using:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install primeorbit-sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
π§ Import & Initialize
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
import { PrimeOrbitClient } from 'primeorbit-sdk';
|
|
20
|
+
|
|
21
|
+
const po = new PrimeOrbitClient(
|
|
22
|
+
'np_live_abc123', // Your API Key
|
|
23
|
+
'http://localhost:8000', // Endpoint
|
|
24
|
+
);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Note: You will receive your API key and the endpoint when you onboard with
|
|
28
|
+
PrimeOrbit. Each API key is unique to your organization and should be kept
|
|
29
|
+
confidential. Use this key to authenticate requests to the PrimeOrbit backend.
|
|
30
|
+
|
|
31
|
+
You can either pass the api_key and endpoint parameter directly when creating
|
|
32
|
+
the client, or set PRIMEORBIT_API_KEY and PRIMEORBIT_ENDPOINT in a .env file β
|
|
33
|
+
the client will automatically use it if the parameter is not provided.
|
|
34
|
+
|
|
35
|
+
π§© Set Base Properties (Required Once)
|
|
36
|
+
|
|
37
|
+
Call this once when your app loads or when the user session starts:
|
|
38
|
+
|
|
39
|
+
```javacript
|
|
40
|
+
po.add_properties({
|
|
41
|
+
agentId: "agent_456",
|
|
42
|
+
conversationId: "conv_789",
|
|
43
|
+
userId: "user_123",
|
|
44
|
+
sessionId: "sess_001",
|
|
45
|
+
platform: "web"
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
These will be automatically included in every event.
|
|
50
|
+
|
|
51
|
+
## π Supported Event Types
|
|
52
|
+
|
|
53
|
+
**Message Events:**
|
|
54
|
+
|
|
55
|
+
- `user_message`
|
|
56
|
+
- `agent_response`
|
|
57
|
+
|
|
58
|
+
**Feedback Events:**
|
|
59
|
+
|
|
60
|
+
- `user_feedback`
|
|
61
|
+
- `star_rating`
|
|
62
|
+
- `thumbs_feedback`
|
|
63
|
+
|
|
64
|
+
## π§± Required Fields for Every Event
|
|
65
|
+
|
|
66
|
+
Regardless of event type, the following fields must always be present:
|
|
67
|
+
|
|
68
|
+
| Field | Type | Description |
|
|
69
|
+
| ---------------- | ------ | --------------------------------------- |
|
|
70
|
+
| `conversationId` | string | Unique ID representing the conversation |
|
|
71
|
+
| `userId` | string | ID of the end user |
|
|
72
|
+
| `content` | string | Message text or feedback content |
|
|
73
|
+
|
|
74
|
+
These four fields are mandatory for all events.
|
|
75
|
+
|
|
76
|
+
Tip: To avoid repeating conversationId, agentId, and userId in every event, itβs
|
|
77
|
+
better to configure them once using po.add_properties(). You can then pass only
|
|
78
|
+
content and any event-specific fields in each record_raw_event() call. This
|
|
79
|
+
keeps your code clean and consistent.
|
|
80
|
+
|
|
81
|
+
## π§© Optional Supported Fields
|
|
82
|
+
|
|
83
|
+
In addition to the required fields, you may send any of the following optional
|
|
84
|
+
attributes:
|
|
85
|
+
|
|
86
|
+
| Field | Type | Description |
|
|
87
|
+
| ---------------------- | ------------ | ------------------------------------------------ |
|
|
88
|
+
| `eventId` | string | Optional unique event identifier |
|
|
89
|
+
| `agentId` | string | ID of the agent/app/model that handled the event |
|
|
90
|
+
| `sessionId` | string | Session identifier |
|
|
91
|
+
| `inputMode` | string | e.g., `"text"`, `"voice"`, `"button"` |
|
|
92
|
+
| `experimentId` | string | A/B test or experiment tracking |
|
|
93
|
+
| `productId` | string | Product or feature identifier |
|
|
94
|
+
| `errorMessage` | string | Error info for debugging |
|
|
95
|
+
| `country` | string | Userβs country |
|
|
96
|
+
| `device` | string | Device type (`mobile`, `desktop`) |
|
|
97
|
+
| `platform` | string | Platform (`web`, `ios`, `android`) |
|
|
98
|
+
| `timestamp` | datetime ISO | Auto-generated if omitted |
|
|
99
|
+
| `model` | string | Model name for `agent_response` events |
|
|
100
|
+
| `additionalProperties` | dict | Automatically populated metadata bucket |
|
|
101
|
+
|
|
102
|
+
> Any unsupported fields you send will automatically be placed inside
|
|
103
|
+
> `additionalProperties`.
|
|
104
|
+
|
|
105
|
+
additionalProperties: { ... } No data is lost β PrimeOrbit captures everything.
|
|
106
|
+
|
|
107
|
+
## π€ Recording Events
|
|
108
|
+
|
|
109
|
+
The primary method for sending events:
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
po.record_raw_event(event_type, propertiesObject);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
π Event Examples
|
|
116
|
+
|
|
117
|
+
1οΈβ£ User Message Event
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
po.record_raw_event('user_message', {
|
|
121
|
+
content: 'Hello, I need help!',
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
2οΈβ£ Agent Response Event
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
po.record_raw_event('agent_response', {
|
|
129
|
+
content: 'Sure! What can I help you with?',
|
|
130
|
+
model: 'gpt-5.1',
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
3οΈβ£ User Feedback (Free Text)
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
po.record_raw_event('user_feedback', {
|
|
138
|
+
content: "The answer wasn't very helpful.",
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
4οΈβ£ Star Rating Event
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
po.record_raw_event('star_rating', {
|
|
146
|
+
content: '4',
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
5οΈβ£ Thumbs Feedback Event
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
po.record_raw_event('thumbs_feedback', {
|
|
154
|
+
content: 'thumbs_down',
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
6οΈβ£ Full example:
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
import { PrimeOrbitClient } from 'primeorbit-sdk';
|
|
162
|
+
|
|
163
|
+
// Initialize the client (endpoint from parameter or .env)
|
|
164
|
+
const po = new PrimeOrbitClient('YOUR_API_KEY');
|
|
165
|
+
|
|
166
|
+
// Add conversation metadata including agent_id
|
|
167
|
+
po.add_properties({
|
|
168
|
+
userId: 'user_123',
|
|
169
|
+
agentId: 'agent_001',
|
|
170
|
+
conversationId: 'conv_456',
|
|
171
|
+
sessionId: 'session_789',
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Dummy function simulating sending a message to your bot/system
|
|
175
|
+
async function sendMessageToBot(message) {
|
|
176
|
+
// Simulate processing delay
|
|
177
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
178
|
+
return { message: `Bot reply to: "${message}"` };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async function runConversation() {
|
|
182
|
+
const userMessage = 'Hello, I need help!';
|
|
183
|
+
|
|
184
|
+
// Record user message *before* sending to bot
|
|
185
|
+
po.record_raw_event('user_message', {
|
|
186
|
+
content: userMessage,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Send the message to the bot
|
|
190
|
+
const botResponse = await sendMessageToBot(userMessage);
|
|
191
|
+
|
|
192
|
+
// Record bot response as agent_response
|
|
193
|
+
po.record_raw_event('agent_response', {
|
|
194
|
+
content: botResponse.message,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
console.log('Bot response recorded:', botResponse.message);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
runConversation();
|
|
201
|
+
```
|
package/build/index.cjs
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
PrimeOrbitClient: () => PrimeOrbitClient,
|
|
34
|
+
getNovaPhaseApiUrl: () => getNovaPhaseApiUrl,
|
|
35
|
+
record_star_rating: () => record_star_rating,
|
|
36
|
+
record_thumbs_feedback: () => record_thumbs_feedback,
|
|
37
|
+
setNovaPhaseApiUrl: () => setNovaPhaseApiUrl,
|
|
38
|
+
wrapToRecordLatency: () => wrapToRecordLatency
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(index_exports);
|
|
41
|
+
|
|
42
|
+
// src/api_utils.ts
|
|
43
|
+
async function recordData(endpoint, payload, headers = { "Content-Type": "application/json" }) {
|
|
44
|
+
const res = await fetch(endpoint, {
|
|
45
|
+
method: "POST",
|
|
46
|
+
headers,
|
|
47
|
+
body: JSON.stringify(payload)
|
|
48
|
+
});
|
|
49
|
+
const text = await res.text();
|
|
50
|
+
let responseBody;
|
|
51
|
+
try {
|
|
52
|
+
responseBody = text ? JSON.parse(text) : null;
|
|
53
|
+
} catch {
|
|
54
|
+
responseBody = text;
|
|
55
|
+
}
|
|
56
|
+
if (!res.ok) {
|
|
57
|
+
throw new Error(`HTTP ${res.status} ${res.statusText}: ${text}`);
|
|
58
|
+
}
|
|
59
|
+
return responseBody;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// src/routes.ts
|
|
63
|
+
var routes = {
|
|
64
|
+
latencies: "/system-metrics/latencies",
|
|
65
|
+
"star-ratings": "/user-metrics/star-ratings",
|
|
66
|
+
"thumbs-feedbacks": "/user-metrics/thumbs-feedbacks",
|
|
67
|
+
"raw-events": "/user-metrics/raw-events"
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// src/system_metrics/measure_latency.ts
|
|
71
|
+
function recordLatency(startTime, agentId, actionId, actionFailed) {
|
|
72
|
+
const endTime = performance.now();
|
|
73
|
+
const latency = Math.floor(endTime - startTime);
|
|
74
|
+
recordData(routes["latencies"], {
|
|
75
|
+
agent_id: agentId,
|
|
76
|
+
latency,
|
|
77
|
+
action_id: actionId,
|
|
78
|
+
action_failed: actionFailed
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function wrapToRecordLatency(fn, agentId, actionId = "") {
|
|
82
|
+
return function(...args) {
|
|
83
|
+
const start = performance.now();
|
|
84
|
+
let failed = true;
|
|
85
|
+
const agentActionId = actionId || fn.name;
|
|
86
|
+
try {
|
|
87
|
+
const result = fn.apply(this, args);
|
|
88
|
+
if (result instanceof Promise) {
|
|
89
|
+
return result.then((res) => {
|
|
90
|
+
failed = false;
|
|
91
|
+
recordLatency(start, agentId, agentActionId, failed);
|
|
92
|
+
return res;
|
|
93
|
+
}).catch((err) => {
|
|
94
|
+
recordLatency(start, agentId, agentActionId, failed);
|
|
95
|
+
throw err;
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
failed = false;
|
|
99
|
+
recordLatency(start, agentId, agentActionId, failed);
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
} catch (err) {
|
|
103
|
+
recordLatency(start, agentId, agentActionId, failed);
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/config.ts
|
|
110
|
+
var baseApiUrl;
|
|
111
|
+
function setNovaPhaseApiUrl(url) {
|
|
112
|
+
baseApiUrl = url;
|
|
113
|
+
}
|
|
114
|
+
function getNovaPhaseApiUrl() {
|
|
115
|
+
if (!baseApiUrl) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`NovaPhase API URL is not set. Please call 'setNovaPhaseApiUrl(<url>)' before using the SDK.`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
return baseApiUrl;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/user_metrics/record_star_rating.ts
|
|
124
|
+
async function record_star_rating(agentId, rating, taskName, userId = "") {
|
|
125
|
+
try {
|
|
126
|
+
const payload = {
|
|
127
|
+
agent_id: agentId,
|
|
128
|
+
rating,
|
|
129
|
+
task_name: taskName
|
|
130
|
+
};
|
|
131
|
+
if (userId) {
|
|
132
|
+
payload.user_id = userId;
|
|
133
|
+
}
|
|
134
|
+
await recordData(routes["star-ratings"], payload);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
console.error(
|
|
137
|
+
`[NovaPhase SDK] recordData failed: ${err.message}`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/user_metrics/record_thumbs_feedback.ts
|
|
143
|
+
async function record_thumbs_feedback(agentId, isThumbsUp, taskName, userId = "") {
|
|
144
|
+
try {
|
|
145
|
+
const payload = {
|
|
146
|
+
agent_id: agentId,
|
|
147
|
+
is_thumbs_up: isThumbsUp,
|
|
148
|
+
task_name: taskName
|
|
149
|
+
};
|
|
150
|
+
if (userId) {
|
|
151
|
+
payload.user_id = userId;
|
|
152
|
+
}
|
|
153
|
+
await recordData(routes["thumbs-feedbacks"], payload);
|
|
154
|
+
} catch (err) {
|
|
155
|
+
console.error(
|
|
156
|
+
`[NovaPhase SDK] Failed to record thumbs feedback: ${err.message}`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/user_metrics/record_user_event.ts
|
|
162
|
+
var dotenv = __toESM(require("dotenv"), 1);
|
|
163
|
+
dotenv.config();
|
|
164
|
+
var PrimeOrbitClient = class {
|
|
165
|
+
apiKey;
|
|
166
|
+
baseUrl;
|
|
167
|
+
baseProperties = {};
|
|
168
|
+
verbose = false;
|
|
169
|
+
/**
|
|
170
|
+
* @param {string} apiKey - Your PrimeOrbit API key
|
|
171
|
+
* @param {string} [endpoint] - endpoint URL
|
|
172
|
+
*/
|
|
173
|
+
constructor(apiKey, endpoint) {
|
|
174
|
+
if (apiKey) {
|
|
175
|
+
this.apiKey = apiKey;
|
|
176
|
+
} else if (process.env.PRIMEORBIT_API_KEY) {
|
|
177
|
+
this.apiKey = process.env.PRIMEORBIT_API_KEY;
|
|
178
|
+
} else {
|
|
179
|
+
throw new Error(
|
|
180
|
+
"API key not provided. Set the 'apiKey' parameter or the 'PRIMEORBIT_API_KEY' environment variable."
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
if (endpoint) {
|
|
184
|
+
this.baseUrl = endpoint;
|
|
185
|
+
} else if (process.env.PRIMEORBIT_ENDPOINT) {
|
|
186
|
+
this.baseUrl = process.env.PRIMEORBIT_ENDPOINT;
|
|
187
|
+
} else {
|
|
188
|
+
this.baseUrl = "https://sdk-dev.primeorbit.ai";
|
|
189
|
+
}
|
|
190
|
+
this.baseProperties = {};
|
|
191
|
+
}
|
|
192
|
+
add_properties(props) {
|
|
193
|
+
this.baseProperties = {
|
|
194
|
+
...this.baseProperties,
|
|
195
|
+
...props
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
_headers() {
|
|
199
|
+
return {
|
|
200
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
201
|
+
"Content-Type": "application/json"
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Records any agent interaction event such as user_question, agent_response, or user_feedback.
|
|
206
|
+
*
|
|
207
|
+
* @param eventType - Type of event. Can be:
|
|
208
|
+
* - 'user_question' β when the user asks a question
|
|
209
|
+
* - 'agent_response' β when the agent replies
|
|
210
|
+
* - 'user_feedback' β when the user gives feedback
|
|
211
|
+
*
|
|
212
|
+
* @param params - Object containing event details:
|
|
213
|
+
* - conversationId: string β Unique conversation identifier
|
|
214
|
+
* - agentId: string β Agent ID
|
|
215
|
+
* - userId: string β User ID
|
|
216
|
+
* - productId?: string β Optional product ID
|
|
217
|
+
* - content: string β Text content of the event (user question, agent reply, or feedback)
|
|
218
|
+
* - sessionId?: string β Optional session ID
|
|
219
|
+
* - messageId?: string β Optional message ID (for tracking within conversation)
|
|
220
|
+
* - inputMode?: string β Optional input mode (e.g., 'text', 'voice')
|
|
221
|
+
* - device?: string β Optional device name or model (e.g., 'iPhone 13')
|
|
222
|
+
* - country?: string β Optional country of the user (ISO country code, e.g., 'US')
|
|
223
|
+
* - platform?: string β Optional platform or OS (e.g., 'iOS', 'Android', 'Web')
|
|
224
|
+
* - language?: string β Optional language of the user (e.g., 'en-US')
|
|
225
|
+
* - Any additional properties will be captured in additional_properties
|
|
226
|
+
*/
|
|
227
|
+
async record_raw_event(eventType, params) {
|
|
228
|
+
const finalParams = {
|
|
229
|
+
...this.baseProperties,
|
|
230
|
+
...params
|
|
231
|
+
};
|
|
232
|
+
try {
|
|
233
|
+
const {
|
|
234
|
+
conversationId,
|
|
235
|
+
messageId,
|
|
236
|
+
agentId,
|
|
237
|
+
userId,
|
|
238
|
+
appId,
|
|
239
|
+
content,
|
|
240
|
+
sessionId,
|
|
241
|
+
eventId,
|
|
242
|
+
inputMode,
|
|
243
|
+
device,
|
|
244
|
+
country,
|
|
245
|
+
platform,
|
|
246
|
+
experimentId,
|
|
247
|
+
...extraProps
|
|
248
|
+
} = finalParams;
|
|
249
|
+
const requiredFields = ["conversationId", "userId", "content"];
|
|
250
|
+
const missingRequired = requiredFields.filter(
|
|
251
|
+
(field) => !(field in finalParams) || finalParams[field] === void 0
|
|
252
|
+
);
|
|
253
|
+
if (missingRequired.length > 0) {
|
|
254
|
+
throw new Error(
|
|
255
|
+
`Missing required fields: ${missingRequired.join(", ")}`
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
const optionalFields = [
|
|
259
|
+
"agentId",
|
|
260
|
+
"sessionId",
|
|
261
|
+
"eventId",
|
|
262
|
+
"messageId",
|
|
263
|
+
"experimentId",
|
|
264
|
+
"inputMode",
|
|
265
|
+
"device",
|
|
266
|
+
"country",
|
|
267
|
+
"platform",
|
|
268
|
+
"appId",
|
|
269
|
+
"model"
|
|
270
|
+
];
|
|
271
|
+
const missingOptionals = optionalFields.filter(
|
|
272
|
+
(field) => !(field in finalParams) || finalParams[field] === void 0
|
|
273
|
+
);
|
|
274
|
+
if (missingOptionals.length > 0) {
|
|
275
|
+
if (this.verbose) {
|
|
276
|
+
console.warn(
|
|
277
|
+
`[PrimeOrbit Analytics Warning] Missing optional fields: ${missingOptionals.join(", ")}. Analytics may be less accurate or incomplete.`
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const payload = {
|
|
282
|
+
event_type: eventType,
|
|
283
|
+
conversation_id: conversationId,
|
|
284
|
+
session_id: sessionId,
|
|
285
|
+
user_id: userId,
|
|
286
|
+
agent_id: agentId,
|
|
287
|
+
message_id: messageId,
|
|
288
|
+
event_id: eventId,
|
|
289
|
+
app_id: appId,
|
|
290
|
+
content,
|
|
291
|
+
input_mode: inputMode,
|
|
292
|
+
device,
|
|
293
|
+
country,
|
|
294
|
+
platform,
|
|
295
|
+
experiment_id: experimentId,
|
|
296
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
297
|
+
additional_properties: Object.keys(extraProps).length > 0 ? extraProps : void 0
|
|
298
|
+
};
|
|
299
|
+
console.log("[PrimeOrbit] Recording event:", payload);
|
|
300
|
+
await recordData(
|
|
301
|
+
`${this.baseUrl}${routes["raw-events"]}`,
|
|
302
|
+
payload,
|
|
303
|
+
this._headers()
|
|
304
|
+
);
|
|
305
|
+
} catch (err) {
|
|
306
|
+
console.error(
|
|
307
|
+
`[PrimeOrbit Error] recording_event failed}: ${err}`
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
313
|
+
0 && (module.exports = {
|
|
314
|
+
PrimeOrbitClient,
|
|
315
|
+
getNovaPhaseApiUrl,
|
|
316
|
+
record_star_rating,
|
|
317
|
+
record_thumbs_feedback,
|
|
318
|
+
setNovaPhaseApiUrl,
|
|
319
|
+
wrapToRecordLatency
|
|
320
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps a synchronous or asynchronous function and logs its execution latency.
|
|
3
|
+
*
|
|
4
|
+
* @template T - A function type with any parameters and return type.
|
|
5
|
+
* @param {T} fn - The function to be wrapped.
|
|
6
|
+
* @param {string} agentId - Identifier for the agent.
|
|
7
|
+
* @param {string} actionId - Identifier for the action id. If not provided, defaults to the name of the function `fn`.
|
|
8
|
+
* @returns {(...args: Parameters<T>) => ReturnType<T>} A wrapped function that logs latency and returns the same result as `fn`.
|
|
9
|
+
*/
|
|
10
|
+
declare function wrapToRecordLatency<T extends (...args: unknown[]) => unknown>(fn: T, agentId: string, actionId?: string): (...args: Parameters<T>) => ReturnType<T>;
|
|
11
|
+
|
|
12
|
+
declare function setNovaPhaseApiUrl(url: string): void;
|
|
13
|
+
declare function getNovaPhaseApiUrl(): string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Records a star rating for an agent after task completion.
|
|
17
|
+
*
|
|
18
|
+
* @param agentId - Unique identifier for the agent
|
|
19
|
+
* @param rating - Star rating given (e.g. 1β5)
|
|
20
|
+
* @param taskName - Name of completed task
|
|
21
|
+
* @param userId - Optional ID of the user giving the rating
|
|
22
|
+
*/
|
|
23
|
+
declare function record_star_rating(agentId: string, rating: number, taskName: string, userId?: string): Promise<void>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sends thumbs-up/down feedback to the backend.
|
|
27
|
+
*
|
|
28
|
+
* @param agentId - ID of the agent being rated
|
|
29
|
+
* @param isThumbsUp - true if thumbs up, false if thumbs down
|
|
30
|
+
* @param taskName - summary of the task
|
|
31
|
+
* @param userId - ID of the user who provided the feedback; defaults to ''.
|
|
32
|
+
*/
|
|
33
|
+
declare function record_thumbs_feedback(agentId: string, isThumbsUp: boolean, taskName: string, userId?: string): Promise<void>;
|
|
34
|
+
|
|
35
|
+
declare class PrimeOrbitClient {
|
|
36
|
+
private apiKey;
|
|
37
|
+
private baseUrl;
|
|
38
|
+
private baseProperties;
|
|
39
|
+
private verbose;
|
|
40
|
+
/**
|
|
41
|
+
* @param {string} apiKey - Your PrimeOrbit API key
|
|
42
|
+
* @param {string} [endpoint] - endpoint URL
|
|
43
|
+
*/
|
|
44
|
+
constructor(apiKey?: string, endpoint?: string);
|
|
45
|
+
add_properties(props: Record<string, unknown>): void;
|
|
46
|
+
_headers(): {
|
|
47
|
+
Authorization: string;
|
|
48
|
+
'Content-Type': string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Records any agent interaction event such as user_question, agent_response, or user_feedback.
|
|
52
|
+
*
|
|
53
|
+
* @param eventType - Type of event. Can be:
|
|
54
|
+
* - 'user_question' β when the user asks a question
|
|
55
|
+
* - 'agent_response' β when the agent replies
|
|
56
|
+
* - 'user_feedback' β when the user gives feedback
|
|
57
|
+
*
|
|
58
|
+
* @param params - Object containing event details:
|
|
59
|
+
* - conversationId: string β Unique conversation identifier
|
|
60
|
+
* - agentId: string β Agent ID
|
|
61
|
+
* - userId: string β User ID
|
|
62
|
+
* - productId?: string β Optional product ID
|
|
63
|
+
* - content: string β Text content of the event (user question, agent reply, or feedback)
|
|
64
|
+
* - sessionId?: string β Optional session ID
|
|
65
|
+
* - messageId?: string β Optional message ID (for tracking within conversation)
|
|
66
|
+
* - inputMode?: string β Optional input mode (e.g., 'text', 'voice')
|
|
67
|
+
* - device?: string β Optional device name or model (e.g., 'iPhone 13')
|
|
68
|
+
* - country?: string β Optional country of the user (ISO country code, e.g., 'US')
|
|
69
|
+
* - platform?: string β Optional platform or OS (e.g., 'iOS', 'Android', 'Web')
|
|
70
|
+
* - language?: string β Optional language of the user (e.g., 'en-US')
|
|
71
|
+
* - Any additional properties will be captured in additional_properties
|
|
72
|
+
*/
|
|
73
|
+
record_raw_event(eventType: 'user_question' | 'agent_response' | 'user_feedback', params: Record<string, unknown>): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { PrimeOrbitClient, getNovaPhaseApiUrl, record_star_rating, record_thumbs_feedback, setNovaPhaseApiUrl, wrapToRecordLatency };
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps a synchronous or asynchronous function and logs its execution latency.
|
|
3
|
+
*
|
|
4
|
+
* @template T - A function type with any parameters and return type.
|
|
5
|
+
* @param {T} fn - The function to be wrapped.
|
|
6
|
+
* @param {string} agentId - Identifier for the agent.
|
|
7
|
+
* @param {string} actionId - Identifier for the action id. If not provided, defaults to the name of the function `fn`.
|
|
8
|
+
* @returns {(...args: Parameters<T>) => ReturnType<T>} A wrapped function that logs latency and returns the same result as `fn`.
|
|
9
|
+
*/
|
|
10
|
+
declare function wrapToRecordLatency<T extends (...args: unknown[]) => unknown>(fn: T, agentId: string, actionId?: string): (...args: Parameters<T>) => ReturnType<T>;
|
|
11
|
+
|
|
12
|
+
declare function setNovaPhaseApiUrl(url: string): void;
|
|
13
|
+
declare function getNovaPhaseApiUrl(): string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Records a star rating for an agent after task completion.
|
|
17
|
+
*
|
|
18
|
+
* @param agentId - Unique identifier for the agent
|
|
19
|
+
* @param rating - Star rating given (e.g. 1β5)
|
|
20
|
+
* @param taskName - Name of completed task
|
|
21
|
+
* @param userId - Optional ID of the user giving the rating
|
|
22
|
+
*/
|
|
23
|
+
declare function record_star_rating(agentId: string, rating: number, taskName: string, userId?: string): Promise<void>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sends thumbs-up/down feedback to the backend.
|
|
27
|
+
*
|
|
28
|
+
* @param agentId - ID of the agent being rated
|
|
29
|
+
* @param isThumbsUp - true if thumbs up, false if thumbs down
|
|
30
|
+
* @param taskName - summary of the task
|
|
31
|
+
* @param userId - ID of the user who provided the feedback; defaults to ''.
|
|
32
|
+
*/
|
|
33
|
+
declare function record_thumbs_feedback(agentId: string, isThumbsUp: boolean, taskName: string, userId?: string): Promise<void>;
|
|
34
|
+
|
|
35
|
+
declare class PrimeOrbitClient {
|
|
36
|
+
private apiKey;
|
|
37
|
+
private baseUrl;
|
|
38
|
+
private baseProperties;
|
|
39
|
+
private verbose;
|
|
40
|
+
/**
|
|
41
|
+
* @param {string} apiKey - Your PrimeOrbit API key
|
|
42
|
+
* @param {string} [endpoint] - endpoint URL
|
|
43
|
+
*/
|
|
44
|
+
constructor(apiKey?: string, endpoint?: string);
|
|
45
|
+
add_properties(props: Record<string, unknown>): void;
|
|
46
|
+
_headers(): {
|
|
47
|
+
Authorization: string;
|
|
48
|
+
'Content-Type': string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Records any agent interaction event such as user_question, agent_response, or user_feedback.
|
|
52
|
+
*
|
|
53
|
+
* @param eventType - Type of event. Can be:
|
|
54
|
+
* - 'user_question' β when the user asks a question
|
|
55
|
+
* - 'agent_response' β when the agent replies
|
|
56
|
+
* - 'user_feedback' β when the user gives feedback
|
|
57
|
+
*
|
|
58
|
+
* @param params - Object containing event details:
|
|
59
|
+
* - conversationId: string β Unique conversation identifier
|
|
60
|
+
* - agentId: string β Agent ID
|
|
61
|
+
* - userId: string β User ID
|
|
62
|
+
* - productId?: string β Optional product ID
|
|
63
|
+
* - content: string β Text content of the event (user question, agent reply, or feedback)
|
|
64
|
+
* - sessionId?: string β Optional session ID
|
|
65
|
+
* - messageId?: string β Optional message ID (for tracking within conversation)
|
|
66
|
+
* - inputMode?: string β Optional input mode (e.g., 'text', 'voice')
|
|
67
|
+
* - device?: string β Optional device name or model (e.g., 'iPhone 13')
|
|
68
|
+
* - country?: string β Optional country of the user (ISO country code, e.g., 'US')
|
|
69
|
+
* - platform?: string β Optional platform or OS (e.g., 'iOS', 'Android', 'Web')
|
|
70
|
+
* - language?: string β Optional language of the user (e.g., 'en-US')
|
|
71
|
+
* - Any additional properties will be captured in additional_properties
|
|
72
|
+
*/
|
|
73
|
+
record_raw_event(eventType: 'user_question' | 'agent_response' | 'user_feedback', params: Record<string, unknown>): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { PrimeOrbitClient, getNovaPhaseApiUrl, record_star_rating, record_thumbs_feedback, setNovaPhaseApiUrl, wrapToRecordLatency };
|
package/build/index.js
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
// src/api_utils.ts
|
|
2
|
+
async function recordData(endpoint, payload, headers = { "Content-Type": "application/json" }) {
|
|
3
|
+
const res = await fetch(endpoint, {
|
|
4
|
+
method: "POST",
|
|
5
|
+
headers,
|
|
6
|
+
body: JSON.stringify(payload)
|
|
7
|
+
});
|
|
8
|
+
const text = await res.text();
|
|
9
|
+
let responseBody;
|
|
10
|
+
try {
|
|
11
|
+
responseBody = text ? JSON.parse(text) : null;
|
|
12
|
+
} catch {
|
|
13
|
+
responseBody = text;
|
|
14
|
+
}
|
|
15
|
+
if (!res.ok) {
|
|
16
|
+
throw new Error(`HTTP ${res.status} ${res.statusText}: ${text}`);
|
|
17
|
+
}
|
|
18
|
+
return responseBody;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/routes.ts
|
|
22
|
+
var routes = {
|
|
23
|
+
latencies: "/system-metrics/latencies",
|
|
24
|
+
"star-ratings": "/user-metrics/star-ratings",
|
|
25
|
+
"thumbs-feedbacks": "/user-metrics/thumbs-feedbacks",
|
|
26
|
+
"raw-events": "/user-metrics/raw-events"
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/system_metrics/measure_latency.ts
|
|
30
|
+
function recordLatency(startTime, agentId, actionId, actionFailed) {
|
|
31
|
+
const endTime = performance.now();
|
|
32
|
+
const latency = Math.floor(endTime - startTime);
|
|
33
|
+
recordData(routes["latencies"], {
|
|
34
|
+
agent_id: agentId,
|
|
35
|
+
latency,
|
|
36
|
+
action_id: actionId,
|
|
37
|
+
action_failed: actionFailed
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function wrapToRecordLatency(fn, agentId, actionId = "") {
|
|
41
|
+
return function(...args) {
|
|
42
|
+
const start = performance.now();
|
|
43
|
+
let failed = true;
|
|
44
|
+
const agentActionId = actionId || fn.name;
|
|
45
|
+
try {
|
|
46
|
+
const result = fn.apply(this, args);
|
|
47
|
+
if (result instanceof Promise) {
|
|
48
|
+
return result.then((res) => {
|
|
49
|
+
failed = false;
|
|
50
|
+
recordLatency(start, agentId, agentActionId, failed);
|
|
51
|
+
return res;
|
|
52
|
+
}).catch((err) => {
|
|
53
|
+
recordLatency(start, agentId, agentActionId, failed);
|
|
54
|
+
throw err;
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
failed = false;
|
|
58
|
+
recordLatency(start, agentId, agentActionId, failed);
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
} catch (err) {
|
|
62
|
+
recordLatency(start, agentId, agentActionId, failed);
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/config.ts
|
|
69
|
+
var baseApiUrl;
|
|
70
|
+
function setNovaPhaseApiUrl(url) {
|
|
71
|
+
baseApiUrl = url;
|
|
72
|
+
}
|
|
73
|
+
function getNovaPhaseApiUrl() {
|
|
74
|
+
if (!baseApiUrl) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`NovaPhase API URL is not set. Please call 'setNovaPhaseApiUrl(<url>)' before using the SDK.`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
return baseApiUrl;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/user_metrics/record_star_rating.ts
|
|
83
|
+
async function record_star_rating(agentId, rating, taskName, userId = "") {
|
|
84
|
+
try {
|
|
85
|
+
const payload = {
|
|
86
|
+
agent_id: agentId,
|
|
87
|
+
rating,
|
|
88
|
+
task_name: taskName
|
|
89
|
+
};
|
|
90
|
+
if (userId) {
|
|
91
|
+
payload.user_id = userId;
|
|
92
|
+
}
|
|
93
|
+
await recordData(routes["star-ratings"], payload);
|
|
94
|
+
} catch (err) {
|
|
95
|
+
console.error(
|
|
96
|
+
`[NovaPhase SDK] recordData failed: ${err.message}`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/user_metrics/record_thumbs_feedback.ts
|
|
102
|
+
async function record_thumbs_feedback(agentId, isThumbsUp, taskName, userId = "") {
|
|
103
|
+
try {
|
|
104
|
+
const payload = {
|
|
105
|
+
agent_id: agentId,
|
|
106
|
+
is_thumbs_up: isThumbsUp,
|
|
107
|
+
task_name: taskName
|
|
108
|
+
};
|
|
109
|
+
if (userId) {
|
|
110
|
+
payload.user_id = userId;
|
|
111
|
+
}
|
|
112
|
+
await recordData(routes["thumbs-feedbacks"], payload);
|
|
113
|
+
} catch (err) {
|
|
114
|
+
console.error(
|
|
115
|
+
`[NovaPhase SDK] Failed to record thumbs feedback: ${err.message}`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/user_metrics/record_user_event.ts
|
|
121
|
+
import * as dotenv from "dotenv";
|
|
122
|
+
dotenv.config();
|
|
123
|
+
var PrimeOrbitClient = class {
|
|
124
|
+
apiKey;
|
|
125
|
+
baseUrl;
|
|
126
|
+
baseProperties = {};
|
|
127
|
+
verbose = false;
|
|
128
|
+
/**
|
|
129
|
+
* @param {string} apiKey - Your PrimeOrbit API key
|
|
130
|
+
* @param {string} [endpoint] - endpoint URL
|
|
131
|
+
*/
|
|
132
|
+
constructor(apiKey, endpoint) {
|
|
133
|
+
if (apiKey) {
|
|
134
|
+
this.apiKey = apiKey;
|
|
135
|
+
} else if (process.env.PRIMEORBIT_API_KEY) {
|
|
136
|
+
this.apiKey = process.env.PRIMEORBIT_API_KEY;
|
|
137
|
+
} else {
|
|
138
|
+
throw new Error(
|
|
139
|
+
"API key not provided. Set the 'apiKey' parameter or the 'PRIMEORBIT_API_KEY' environment variable."
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
if (endpoint) {
|
|
143
|
+
this.baseUrl = endpoint;
|
|
144
|
+
} else if (process.env.PRIMEORBIT_ENDPOINT) {
|
|
145
|
+
this.baseUrl = process.env.PRIMEORBIT_ENDPOINT;
|
|
146
|
+
} else {
|
|
147
|
+
this.baseUrl = "https://sdk-dev.primeorbit.ai";
|
|
148
|
+
}
|
|
149
|
+
this.baseProperties = {};
|
|
150
|
+
}
|
|
151
|
+
add_properties(props) {
|
|
152
|
+
this.baseProperties = {
|
|
153
|
+
...this.baseProperties,
|
|
154
|
+
...props
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
_headers() {
|
|
158
|
+
return {
|
|
159
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
160
|
+
"Content-Type": "application/json"
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Records any agent interaction event such as user_question, agent_response, or user_feedback.
|
|
165
|
+
*
|
|
166
|
+
* @param eventType - Type of event. Can be:
|
|
167
|
+
* - 'user_question' β when the user asks a question
|
|
168
|
+
* - 'agent_response' β when the agent replies
|
|
169
|
+
* - 'user_feedback' β when the user gives feedback
|
|
170
|
+
*
|
|
171
|
+
* @param params - Object containing event details:
|
|
172
|
+
* - conversationId: string β Unique conversation identifier
|
|
173
|
+
* - agentId: string β Agent ID
|
|
174
|
+
* - userId: string β User ID
|
|
175
|
+
* - productId?: string β Optional product ID
|
|
176
|
+
* - content: string β Text content of the event (user question, agent reply, or feedback)
|
|
177
|
+
* - sessionId?: string β Optional session ID
|
|
178
|
+
* - messageId?: string β Optional message ID (for tracking within conversation)
|
|
179
|
+
* - inputMode?: string β Optional input mode (e.g., 'text', 'voice')
|
|
180
|
+
* - device?: string β Optional device name or model (e.g., 'iPhone 13')
|
|
181
|
+
* - country?: string β Optional country of the user (ISO country code, e.g., 'US')
|
|
182
|
+
* - platform?: string β Optional platform or OS (e.g., 'iOS', 'Android', 'Web')
|
|
183
|
+
* - language?: string β Optional language of the user (e.g., 'en-US')
|
|
184
|
+
* - Any additional properties will be captured in additional_properties
|
|
185
|
+
*/
|
|
186
|
+
async record_raw_event(eventType, params) {
|
|
187
|
+
const finalParams = {
|
|
188
|
+
...this.baseProperties,
|
|
189
|
+
...params
|
|
190
|
+
};
|
|
191
|
+
try {
|
|
192
|
+
const {
|
|
193
|
+
conversationId,
|
|
194
|
+
messageId,
|
|
195
|
+
agentId,
|
|
196
|
+
userId,
|
|
197
|
+
appId,
|
|
198
|
+
content,
|
|
199
|
+
sessionId,
|
|
200
|
+
eventId,
|
|
201
|
+
inputMode,
|
|
202
|
+
device,
|
|
203
|
+
country,
|
|
204
|
+
platform,
|
|
205
|
+
experimentId,
|
|
206
|
+
...extraProps
|
|
207
|
+
} = finalParams;
|
|
208
|
+
const requiredFields = ["conversationId", "userId", "content"];
|
|
209
|
+
const missingRequired = requiredFields.filter(
|
|
210
|
+
(field) => !(field in finalParams) || finalParams[field] === void 0
|
|
211
|
+
);
|
|
212
|
+
if (missingRequired.length > 0) {
|
|
213
|
+
throw new Error(
|
|
214
|
+
`Missing required fields: ${missingRequired.join(", ")}`
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
const optionalFields = [
|
|
218
|
+
"agentId",
|
|
219
|
+
"sessionId",
|
|
220
|
+
"eventId",
|
|
221
|
+
"messageId",
|
|
222
|
+
"experimentId",
|
|
223
|
+
"inputMode",
|
|
224
|
+
"device",
|
|
225
|
+
"country",
|
|
226
|
+
"platform",
|
|
227
|
+
"appId",
|
|
228
|
+
"model"
|
|
229
|
+
];
|
|
230
|
+
const missingOptionals = optionalFields.filter(
|
|
231
|
+
(field) => !(field in finalParams) || finalParams[field] === void 0
|
|
232
|
+
);
|
|
233
|
+
if (missingOptionals.length > 0) {
|
|
234
|
+
if (this.verbose) {
|
|
235
|
+
console.warn(
|
|
236
|
+
`[PrimeOrbit Analytics Warning] Missing optional fields: ${missingOptionals.join(", ")}. Analytics may be less accurate or incomplete.`
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const payload = {
|
|
241
|
+
event_type: eventType,
|
|
242
|
+
conversation_id: conversationId,
|
|
243
|
+
session_id: sessionId,
|
|
244
|
+
user_id: userId,
|
|
245
|
+
agent_id: agentId,
|
|
246
|
+
message_id: messageId,
|
|
247
|
+
event_id: eventId,
|
|
248
|
+
app_id: appId,
|
|
249
|
+
content,
|
|
250
|
+
input_mode: inputMode,
|
|
251
|
+
device,
|
|
252
|
+
country,
|
|
253
|
+
platform,
|
|
254
|
+
experiment_id: experimentId,
|
|
255
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
256
|
+
additional_properties: Object.keys(extraProps).length > 0 ? extraProps : void 0
|
|
257
|
+
};
|
|
258
|
+
console.log("[PrimeOrbit] Recording event:", payload);
|
|
259
|
+
await recordData(
|
|
260
|
+
`${this.baseUrl}${routes["raw-events"]}`,
|
|
261
|
+
payload,
|
|
262
|
+
this._headers()
|
|
263
|
+
);
|
|
264
|
+
} catch (err) {
|
|
265
|
+
console.error(
|
|
266
|
+
`[PrimeOrbit Error] recording_event failed}: ${err}`
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
export {
|
|
272
|
+
PrimeOrbitClient,
|
|
273
|
+
getNovaPhaseApiUrl,
|
|
274
|
+
record_star_rating,
|
|
275
|
+
record_thumbs_feedback,
|
|
276
|
+
setNovaPhaseApiUrl,
|
|
277
|
+
wrapToRecordLatency
|
|
278
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "primeorbit-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"files": [
|
|
7
|
+
"build"
|
|
8
|
+
],
|
|
9
|
+
"main": "build/index.js",
|
|
10
|
+
"module": "build/index.js",
|
|
11
|
+
"exports": {
|
|
12
|
+
"import": "./build/index.js",
|
|
13
|
+
"require": "./build/index.js"
|
|
14
|
+
},
|
|
15
|
+
"directories": {
|
|
16
|
+
"src": "src",
|
|
17
|
+
"tests": "tests"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --out-dir build",
|
|
21
|
+
"prepare": "husky",
|
|
22
|
+
"test": "jest",
|
|
23
|
+
"bundle": "npm run build && npm pack",
|
|
24
|
+
"prepublishOnly": "npm run test && npm run build",
|
|
25
|
+
"version:patch": "npm version patch --no-git-tag-version",
|
|
26
|
+
"version:minor": "npm version minor --no-git-tag-version",
|
|
27
|
+
"version:major": "npm version major --no-git-tag-version",
|
|
28
|
+
"publish:latest": "npm run build && npm publish --tag latest",
|
|
29
|
+
"publish:patch": "npm run version:patch && npm run build && npm publish --tag latest",
|
|
30
|
+
"publish:minor": "npm run version:minor && npm run build && npm publish --tag latest",
|
|
31
|
+
"publish:major": "npm run version:major && npm run build && npm publish --tag latest",
|
|
32
|
+
"publish:beta": "npm run build && npm publish --tag beta",
|
|
33
|
+
"publish:beta:patch": "npm run version:patch && npm run build && npm publish --tag beta",
|
|
34
|
+
"publish:alpha": "npm run build && npm publish --tag alpha",
|
|
35
|
+
"publish:alpha:patch": "npm run version:patch && npm run build && npm publish --tag alpha",
|
|
36
|
+
"publish:next": "npm run build && npm publish --tag next",
|
|
37
|
+
"publish:next:patch": "npm run version:patch && npm run build && npm publish --tag next"
|
|
38
|
+
},
|
|
39
|
+
"husky": {
|
|
40
|
+
"hooks": {
|
|
41
|
+
"pre-commit": "lint-staged"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"lint-staged": {
|
|
45
|
+
"{src,tests}/**/*.{js,jsx,ts,tsx}": [
|
|
46
|
+
"npx eslint --fix",
|
|
47
|
+
"npx prettier --write --ignore-unknown",
|
|
48
|
+
"npx jest --findRelatedTests"
|
|
49
|
+
],
|
|
50
|
+
"docs/**/*.md": "mdformat --wrap 80 --number",
|
|
51
|
+
"scripts/**/*.sh": "shellcheck -x"
|
|
52
|
+
},
|
|
53
|
+
"prettier": {
|
|
54
|
+
"proseWrap": "always",
|
|
55
|
+
"singleQuote": true
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@eslint/js": "^9.34.0",
|
|
59
|
+
"@jest/globals": "^30.1.1",
|
|
60
|
+
"@types/jest": "^30.0.0",
|
|
61
|
+
"@types/node": "^24.3.0",
|
|
62
|
+
"@types/supertest": "^6.0.3",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^8.41.0",
|
|
64
|
+
"@typescript-eslint/parser": "^8.41.0",
|
|
65
|
+
"eslint": "^9.34.0",
|
|
66
|
+
"eslint-config-love": "^122.0.0",
|
|
67
|
+
"eslint-config-prettier": "^10.1.8",
|
|
68
|
+
"eslint-plugin-import": "^2.32.0",
|
|
69
|
+
"eslint-plugin-n": "^17.21.3",
|
|
70
|
+
"eslint-plugin-promise": "^7.2.1",
|
|
71
|
+
"husky": "^9.1.7",
|
|
72
|
+
"jest": "^30.1.1",
|
|
73
|
+
"jest-fetch-mock": "^3.0.3",
|
|
74
|
+
"lint-staged": "^16.1.5",
|
|
75
|
+
"npm-check-updates": "^18.0.3",
|
|
76
|
+
"prettier": "^3.6.2",
|
|
77
|
+
"supertest": "^7.1.4",
|
|
78
|
+
"ts-jest": "^29.4.1",
|
|
79
|
+
"ts-node": "^10.9.2",
|
|
80
|
+
"tsup": "^8.5.1",
|
|
81
|
+
"tsx": "^4.20.5",
|
|
82
|
+
"typescript": "^5.9.3",
|
|
83
|
+
"vite": "^7.1.7",
|
|
84
|
+
"vite-tsconfig-paths": "^5.1.4"
|
|
85
|
+
},
|
|
86
|
+
"dependencies": {
|
|
87
|
+
"dotenv": "^17.2.3"
|
|
88
|
+
}
|
|
89
|
+
}
|