@rheonic/sdk 0.1.0-beta.11 → 0.1.0-beta.13
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/dist/eventBuilder.d.ts +5 -2
- package/dist/eventBuilder.js +2 -1
- package/dist/protectEngine.d.ts +1 -1
- package/dist/protectEngine.js +17 -7
- package/dist/providers/anthropicAdapter.js +15 -3
- package/dist/providers/googleAdapter.js +32 -3
- package/dist/providers/openaiAdapter.js +15 -3
- package/package.json +1 -1
package/dist/eventBuilder.d.ts
CHANGED
|
@@ -14,18 +14,21 @@ export interface EventResponse {
|
|
|
14
14
|
latency_ms?: number;
|
|
15
15
|
total_tokens?: number;
|
|
16
16
|
error_type?: string;
|
|
17
|
+
error_message?: string;
|
|
17
18
|
}
|
|
18
19
|
export interface EventPayload {
|
|
19
20
|
ts: string;
|
|
20
21
|
provider: string;
|
|
21
|
-
|
|
22
|
+
requested_model: string | null;
|
|
23
|
+
resolved_model: string | null;
|
|
22
24
|
environment: string;
|
|
23
25
|
request: EventRequest;
|
|
24
26
|
response: EventResponse;
|
|
25
27
|
}
|
|
26
28
|
export interface BuildEventInput {
|
|
27
29
|
provider: string;
|
|
28
|
-
|
|
30
|
+
requested_model?: string | null;
|
|
31
|
+
resolved_model?: string | null;
|
|
29
32
|
environment?: string;
|
|
30
33
|
ts?: string;
|
|
31
34
|
request?: EventRequest;
|
package/dist/eventBuilder.js
CHANGED
|
@@ -2,7 +2,8 @@ export function buildEvent(input) {
|
|
|
2
2
|
return {
|
|
3
3
|
ts: input.ts ?? new Date().toISOString(),
|
|
4
4
|
provider: input.provider,
|
|
5
|
-
|
|
5
|
+
requested_model: input.requested_model ?? null,
|
|
6
|
+
resolved_model: input.resolved_model ?? null,
|
|
6
7
|
environment: input.environment ?? "dev",
|
|
7
8
|
request: input.request ?? {},
|
|
8
9
|
response: input.response ?? {},
|
package/dist/protectEngine.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export type ProtectDecision = "allow" | "clamp" | "block";
|
|
|
2
2
|
export type ProtectFailMode = "open" | "closed";
|
|
3
3
|
export interface ProtectContext {
|
|
4
4
|
provider: string;
|
|
5
|
-
|
|
5
|
+
requested_model?: string | null;
|
|
6
6
|
feature?: string;
|
|
7
7
|
max_output_tokens?: number;
|
|
8
8
|
input_tokens_estimate?: number;
|
package/dist/protectEngine.js
CHANGED
|
@@ -90,7 +90,7 @@ export class ProtectEngine {
|
|
|
90
90
|
status_code: response.status,
|
|
91
91
|
latency_ms: Date.now() - startedAt,
|
|
92
92
|
});
|
|
93
|
-
void this.reportDecisionUnavailable(context.provider, typeof context.
|
|
93
|
+
void this.reportDecisionUnavailable(context.provider, typeof context.requested_model === "string" ? context.requested_model : undefined, requestId, traceId);
|
|
94
94
|
return this.fallbackEvaluation(traceId, requestId);
|
|
95
95
|
}
|
|
96
96
|
const parsed = (await response.json());
|
|
@@ -140,7 +140,7 @@ export class ProtectEngine {
|
|
|
140
140
|
latency_ms: Date.now() - startedAt,
|
|
141
141
|
timeout_ms: timeoutMs,
|
|
142
142
|
});
|
|
143
|
-
void this.reportDecisionTimeout(context.provider, typeof context.
|
|
143
|
+
void this.reportDecisionTimeout(context.provider, typeof context.requested_model === "string" ? context.requested_model : undefined, requestId, traceId);
|
|
144
144
|
}
|
|
145
145
|
else {
|
|
146
146
|
this.debugLog?.("Protect preflight failed", {
|
|
@@ -148,7 +148,7 @@ export class ProtectEngine {
|
|
|
148
148
|
latency_ms: Date.now() - startedAt,
|
|
149
149
|
error_type: extractErrorType(error),
|
|
150
150
|
});
|
|
151
|
-
void this.reportDecisionUnavailable(context.provider, typeof context.
|
|
151
|
+
void this.reportDecisionUnavailable(context.provider, typeof context.requested_model === "string" ? context.requested_model : undefined, requestId, traceId);
|
|
152
152
|
}
|
|
153
153
|
return this.fallbackEvaluation(traceId, requestId);
|
|
154
154
|
}
|
|
@@ -189,7 +189,7 @@ export class ProtectEngine {
|
|
|
189
189
|
// Best effort only; keep local defaults if bootstrap fails.
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
async reportDecisionTimeout(provider,
|
|
192
|
+
async reportDecisionTimeout(provider, requestedModel, requestId, traceId) {
|
|
193
193
|
try {
|
|
194
194
|
await requestJson(`${this.baseUrl}/api/v1/protect/decision-timeout`, {
|
|
195
195
|
method: "POST",
|
|
@@ -200,14 +200,19 @@ export class ProtectEngine {
|
|
|
200
200
|
"X-Span-ID": generateSpanId(),
|
|
201
201
|
"X-Rheonic-Protect-Request-Id": requestId,
|
|
202
202
|
},
|
|
203
|
-
body: JSON.stringify({
|
|
203
|
+
body: JSON.stringify({
|
|
204
|
+
environment: this.environment,
|
|
205
|
+
provider,
|
|
206
|
+
requested_model: requestedModel,
|
|
207
|
+
request_id: requestId,
|
|
208
|
+
}),
|
|
204
209
|
});
|
|
205
210
|
}
|
|
206
211
|
catch {
|
|
207
212
|
// Swallow timeout reporting errors; protect evaluation must never throw here.
|
|
208
213
|
}
|
|
209
214
|
}
|
|
210
|
-
async reportDecisionUnavailable(provider,
|
|
215
|
+
async reportDecisionUnavailable(provider, requestedModel, requestId, traceId) {
|
|
211
216
|
try {
|
|
212
217
|
await requestJson(`${this.baseUrl}/api/v1/protect/decision-unavailable`, {
|
|
213
218
|
method: "POST",
|
|
@@ -218,7 +223,12 @@ export class ProtectEngine {
|
|
|
218
223
|
"X-Span-ID": generateSpanId(),
|
|
219
224
|
"X-Rheonic-Protect-Request-Id": requestId,
|
|
220
225
|
},
|
|
221
|
-
body: JSON.stringify({
|
|
226
|
+
body: JSON.stringify({
|
|
227
|
+
environment: this.environment,
|
|
228
|
+
provider,
|
|
229
|
+
requested_model: requestedModel,
|
|
230
|
+
request_id: requestId,
|
|
231
|
+
}),
|
|
222
232
|
});
|
|
223
233
|
}
|
|
224
234
|
catch {
|
|
@@ -36,7 +36,7 @@ export function instrumentAnthropic(anthropicClient, options) {
|
|
|
36
36
|
});
|
|
37
37
|
const protectPayload = {
|
|
38
38
|
provider: "anthropic",
|
|
39
|
-
|
|
39
|
+
requested_model: requestedModel,
|
|
40
40
|
environment: options.environment ?? options.client.environment,
|
|
41
41
|
feature: options.feature,
|
|
42
42
|
max_output_tokens: extractMaxOutputTokens(args),
|
|
@@ -56,7 +56,8 @@ export function instrumentAnthropic(anthropicClient, options) {
|
|
|
56
56
|
const response = await originalCreate(...callArgs);
|
|
57
57
|
await options.client.captureEventAndFlush(buildEvent({
|
|
58
58
|
provider: "anthropic",
|
|
59
|
-
|
|
59
|
+
requested_model: requestedModel,
|
|
60
|
+
resolved_model: extractResponseModel(response),
|
|
60
61
|
environment: options.environment ?? options.client.environment,
|
|
61
62
|
request: {
|
|
62
63
|
endpoint: options.endpoint,
|
|
@@ -77,7 +78,8 @@ export function instrumentAnthropic(anthropicClient, options) {
|
|
|
77
78
|
catch (error) {
|
|
78
79
|
await options.client.captureEventAndFlush(buildEvent({
|
|
79
80
|
provider: "anthropic",
|
|
80
|
-
|
|
81
|
+
requested_model: requestedModel,
|
|
82
|
+
resolved_model: null,
|
|
81
83
|
environment: options.environment ?? options.client.environment,
|
|
82
84
|
request: {
|
|
83
85
|
endpoint: options.endpoint,
|
|
@@ -90,6 +92,7 @@ export function instrumentAnthropic(anthropicClient, options) {
|
|
|
90
92
|
response: {
|
|
91
93
|
latency_ms: Date.now() - startedAt,
|
|
92
94
|
error_type: extractErrorType(error),
|
|
95
|
+
error_message: extractErrorMessage(error),
|
|
93
96
|
http_status: extractHttpStatus(error),
|
|
94
97
|
},
|
|
95
98
|
}));
|
|
@@ -145,6 +148,15 @@ function extractErrorType(error) {
|
|
|
145
148
|
}
|
|
146
149
|
return "unknown";
|
|
147
150
|
}
|
|
151
|
+
function extractErrorMessage(error) {
|
|
152
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
153
|
+
const message = error.message;
|
|
154
|
+
if (typeof message === "string" && message.length > 0) {
|
|
155
|
+
return message;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
148
160
|
function extractHttpStatus(error) {
|
|
149
161
|
if (!error || typeof error !== "object") {
|
|
150
162
|
return undefined;
|
|
@@ -36,7 +36,7 @@ export function instrumentGoogle(googleModel, options) {
|
|
|
36
36
|
});
|
|
37
37
|
const protectPayload = {
|
|
38
38
|
provider: "google",
|
|
39
|
-
|
|
39
|
+
requested_model: requestedModel,
|
|
40
40
|
environment: options.environment ?? options.client.environment,
|
|
41
41
|
feature: options.feature,
|
|
42
42
|
max_output_tokens: extractMaxOutputTokens(args),
|
|
@@ -56,7 +56,8 @@ export function instrumentGoogle(googleModel, options) {
|
|
|
56
56
|
const response = await originalGenerate(...callArgs);
|
|
57
57
|
await options.client.captureEventAndFlush(buildEvent({
|
|
58
58
|
provider: "google",
|
|
59
|
-
|
|
59
|
+
requested_model: requestedModel,
|
|
60
|
+
resolved_model: extractResponseModel(response),
|
|
60
61
|
environment: options.environment ?? options.client.environment,
|
|
61
62
|
request: {
|
|
62
63
|
endpoint: options.endpoint,
|
|
@@ -77,7 +78,8 @@ export function instrumentGoogle(googleModel, options) {
|
|
|
77
78
|
catch (error) {
|
|
78
79
|
await options.client.captureEventAndFlush(buildEvent({
|
|
79
80
|
provider: "google",
|
|
80
|
-
|
|
81
|
+
requested_model: requestedModel,
|
|
82
|
+
resolved_model: null,
|
|
81
83
|
environment: options.environment ?? options.client.environment,
|
|
82
84
|
request: {
|
|
83
85
|
endpoint: options.endpoint,
|
|
@@ -90,6 +92,7 @@ export function instrumentGoogle(googleModel, options) {
|
|
|
90
92
|
response: {
|
|
91
93
|
latency_ms: Date.now() - startedAt,
|
|
92
94
|
error_type: extractErrorType(error),
|
|
95
|
+
error_message: extractErrorMessage(error),
|
|
93
96
|
http_status: extractHttpStatus(error),
|
|
94
97
|
},
|
|
95
98
|
}));
|
|
@@ -193,6 +196,23 @@ function extractTotalTokens(response) {
|
|
|
193
196
|
const total = prompt + candidates;
|
|
194
197
|
return total > 0 ? total : undefined;
|
|
195
198
|
}
|
|
199
|
+
function extractResponseModel(response) {
|
|
200
|
+
if (!response || typeof response !== "object") {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
const topLevelModel = response.model;
|
|
204
|
+
if (typeof topLevelModel === "string" && topLevelModel.trim()) {
|
|
205
|
+
return topLevelModel;
|
|
206
|
+
}
|
|
207
|
+
const nestedResponse = response.response;
|
|
208
|
+
if (typeof nestedResponse?.modelVersion === "string" && nestedResponse.modelVersion.trim()) {
|
|
209
|
+
return nestedResponse.modelVersion;
|
|
210
|
+
}
|
|
211
|
+
if (typeof nestedResponse?.model === "string" && nestedResponse.model.trim()) {
|
|
212
|
+
return nestedResponse.model;
|
|
213
|
+
}
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
196
216
|
function extractErrorType(error) {
|
|
197
217
|
if (error && typeof error === "object" && "name" in error) {
|
|
198
218
|
const name = error.name;
|
|
@@ -202,6 +222,15 @@ function extractErrorType(error) {
|
|
|
202
222
|
}
|
|
203
223
|
return "unknown";
|
|
204
224
|
}
|
|
225
|
+
function extractErrorMessage(error) {
|
|
226
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
227
|
+
const message = error.message;
|
|
228
|
+
if (typeof message === "string" && message.length > 0) {
|
|
229
|
+
return message;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
205
234
|
function extractHttpStatus(error) {
|
|
206
235
|
if (!error || typeof error !== "object") {
|
|
207
236
|
return undefined;
|
|
@@ -35,7 +35,7 @@ export function instrumentOpenAI(openaiClient, options) {
|
|
|
35
35
|
});
|
|
36
36
|
const protectPayload = {
|
|
37
37
|
provider: "openai",
|
|
38
|
-
model,
|
|
38
|
+
requested_model: model,
|
|
39
39
|
environment: options.environment ?? options.client.environment,
|
|
40
40
|
feature: options.feature,
|
|
41
41
|
max_output_tokens: extractMaxOutputTokens(args),
|
|
@@ -57,7 +57,8 @@ export function instrumentOpenAI(openaiClient, options) {
|
|
|
57
57
|
const response = await originalCreate(...callArgs);
|
|
58
58
|
await options.client.captureEventAndFlush(buildEvent({
|
|
59
59
|
provider: "openai",
|
|
60
|
-
|
|
60
|
+
requested_model: model,
|
|
61
|
+
resolved_model: extractResponseModel(response),
|
|
61
62
|
environment: options.environment ?? options.client.environment,
|
|
62
63
|
request: {
|
|
63
64
|
endpoint: options.endpoint,
|
|
@@ -77,7 +78,8 @@ export function instrumentOpenAI(openaiClient, options) {
|
|
|
77
78
|
catch (error) {
|
|
78
79
|
await options.client.captureEventAndFlush(buildEvent({
|
|
79
80
|
provider: "openai",
|
|
80
|
-
model,
|
|
81
|
+
requested_model: model,
|
|
82
|
+
resolved_model: null,
|
|
81
83
|
environment: options.environment ?? options.client.environment,
|
|
82
84
|
request: {
|
|
83
85
|
endpoint: options.endpoint,
|
|
@@ -89,6 +91,7 @@ export function instrumentOpenAI(openaiClient, options) {
|
|
|
89
91
|
response: {
|
|
90
92
|
latency_ms: Date.now() - startedAt,
|
|
91
93
|
error_type: extractErrorType(error),
|
|
94
|
+
error_message: extractErrorMessage(error),
|
|
92
95
|
http_status: extractHttpStatus(error),
|
|
93
96
|
},
|
|
94
97
|
}));
|
|
@@ -194,6 +197,15 @@ function extractErrorType(error) {
|
|
|
194
197
|
}
|
|
195
198
|
return "unknown";
|
|
196
199
|
}
|
|
200
|
+
function extractErrorMessage(error) {
|
|
201
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
202
|
+
const message = error.message;
|
|
203
|
+
if (typeof message === "string" && message.length > 0) {
|
|
204
|
+
return message;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
197
209
|
function extractHttpStatus(error) {
|
|
198
210
|
if (!error || typeof error !== "object") {
|
|
199
211
|
return undefined;
|
package/package.json
CHANGED