@rheonic/sdk 0.1.0-beta.10 → 0.1.0-beta.11
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/CHANGELOG.md +4 -0
- package/README.md +20 -7
- package/dist/eventBuilder.d.ts +1 -0
- package/dist/providers/googleAdapter.js +64 -17
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,9 +4,13 @@ All notable changes to `@rheonic/sdk` will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
### Changed
|
|
8
|
+
- Google provider instrumentation and examples now align with the current official Google Gen AI JavaScript SDK shape: `@google/genai` with `ai.models.generateContent({...})`.
|
|
9
|
+
|
|
7
10
|
### Fixed
|
|
8
11
|
- SDK debug logs now always emit non-empty `trace_id` and `span_id`, including warmup, token-estimation, and protect preflight paths.
|
|
9
12
|
- Provider instrumentation now keeps the full protected call lifecycle under one trace so SDK debug logs correlate cleanly with backend requests.
|
|
13
|
+
- Quickstart and README examples now use the published `@rheonic/sdk` package name consistently and show the current Anthropic and Google instrumentation patterns.
|
|
10
14
|
|
|
11
15
|
## 0.1.0-beta.7
|
|
12
16
|
|
package/README.md
CHANGED
|
@@ -69,14 +69,18 @@ Anthropic:
|
|
|
69
69
|
|
|
70
70
|
```ts
|
|
71
71
|
import Anthropic from "@anthropic-ai/sdk";
|
|
72
|
-
import { createClient, RHEONICBlockedError } from "@rheonic/sdk";
|
|
72
|
+
import { createClient, instrumentAnthropic, RHEONICBlockedError } from "@rheonic/sdk";
|
|
73
73
|
|
|
74
74
|
const rheonic = createClient({
|
|
75
75
|
baseUrl: process.env.RHEONIC_BASE_URL!,
|
|
76
76
|
ingestKey: process.env.RHEONIC_INGEST_KEY!,
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
const anthropic =
|
|
79
|
+
const anthropic = instrumentAnthropic(new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY! }), {
|
|
80
|
+
client: rheonic,
|
|
81
|
+
endpoint: "/v1/messages",
|
|
82
|
+
feature: "assistant",
|
|
83
|
+
});
|
|
80
84
|
|
|
81
85
|
try {
|
|
82
86
|
await anthropic.messages.create({
|
|
@@ -100,19 +104,28 @@ try {
|
|
|
100
104
|
Google:
|
|
101
105
|
|
|
102
106
|
```ts
|
|
103
|
-
import {
|
|
104
|
-
import { createClient, RHEONICBlockedError } from "@rheonic/sdk";
|
|
107
|
+
import { GoogleGenAI } from "@google/genai";
|
|
108
|
+
import { createClient, instrumentGoogle, RHEONICBlockedError } from "@rheonic/sdk";
|
|
105
109
|
|
|
106
110
|
const rheonic = createClient({
|
|
107
111
|
baseUrl: process.env.RHEONIC_BASE_URL!,
|
|
108
112
|
ingestKey: process.env.RHEONIC_INGEST_KEY!,
|
|
109
113
|
});
|
|
110
114
|
|
|
111
|
-
const
|
|
112
|
-
|
|
115
|
+
const ai = instrumentGoogle(new GoogleGenAI({ apiKey: process.env.GOOGLE_API_KEY! }), {
|
|
116
|
+
client: rheonic,
|
|
117
|
+
endpoint: "/v1beta/models/generateContent",
|
|
118
|
+
feature: "assistant",
|
|
119
|
+
});
|
|
113
120
|
|
|
114
121
|
try {
|
|
115
|
-
await
|
|
122
|
+
await ai.models.generateContent({
|
|
123
|
+
model: "gemini-1.5-pro",
|
|
124
|
+
contents: "hello",
|
|
125
|
+
config: {
|
|
126
|
+
maxOutputTokens: 256,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
116
129
|
} catch (error) {
|
|
117
130
|
if (error instanceof RHEONICBlockedError) {
|
|
118
131
|
console.log(JSON.stringify({
|
package/dist/eventBuilder.d.ts
CHANGED
|
@@ -8,17 +8,17 @@ export function __setInputTokenEstimatorForTests(estimator) {
|
|
|
8
8
|
estimatorOverrideForTests = estimator;
|
|
9
9
|
}
|
|
10
10
|
export function instrumentGoogle(googleModel, options) {
|
|
11
|
-
const targetGenerate = googleModel
|
|
12
|
-
if (
|
|
11
|
+
const targetGenerate = resolveGenerateTarget(googleModel);
|
|
12
|
+
if (!targetGenerate) {
|
|
13
13
|
return googleModel;
|
|
14
14
|
}
|
|
15
|
-
const originalGenerate = targetGenerate.bind(
|
|
16
|
-
|
|
15
|
+
const originalGenerate = targetGenerate.fn.bind(targetGenerate.owner);
|
|
16
|
+
targetGenerate.owner[targetGenerate.key] = async (...args) => {
|
|
17
17
|
const traceId = generateTraceId();
|
|
18
18
|
const spanId = generateSpanId();
|
|
19
19
|
return bindTraceContext(traceId, spanId, async () => {
|
|
20
20
|
const startedAt = Date.now();
|
|
21
|
-
const requestedModel = extractRequestedModel(googleModel);
|
|
21
|
+
const requestedModel = extractRequestedModel(googleModel, args);
|
|
22
22
|
validateProviderModel("google", requestedModel);
|
|
23
23
|
const requestPayload = extractRequestPayload(args, requestedModel);
|
|
24
24
|
let estimatedInputTokens = null;
|
|
@@ -99,6 +99,26 @@ export function instrumentGoogle(googleModel, options) {
|
|
|
99
99
|
};
|
|
100
100
|
return googleModel;
|
|
101
101
|
}
|
|
102
|
+
function resolveGenerateTarget(googleModel) {
|
|
103
|
+
const directGenerate = googleModel?.generateContent;
|
|
104
|
+
if (typeof directGenerate === "function") {
|
|
105
|
+
return {
|
|
106
|
+
owner: googleModel,
|
|
107
|
+
fn: directGenerate,
|
|
108
|
+
key: "generateContent",
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const models = googleModel?.models;
|
|
112
|
+
const nestedGenerate = models?.generateContent;
|
|
113
|
+
if (models && typeof nestedGenerate === "function") {
|
|
114
|
+
return {
|
|
115
|
+
owner: models,
|
|
116
|
+
fn: nestedGenerate,
|
|
117
|
+
key: "generateContent",
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
102
122
|
function extractRequestPayload(args, model) {
|
|
103
123
|
const firstArg = args[0];
|
|
104
124
|
if (typeof firstArg === "string") {
|
|
@@ -109,8 +129,13 @@ function extractRequestPayload(args, model) {
|
|
|
109
129
|
}
|
|
110
130
|
return null;
|
|
111
131
|
}
|
|
112
|
-
function extractRequestedModel(googleModel) {
|
|
132
|
+
function extractRequestedModel(googleModel, args) {
|
|
113
133
|
if (!googleModel || typeof googleModel !== "object") {
|
|
134
|
+
const firstArg = args[0];
|
|
135
|
+
if (firstArg && typeof firstArg === "object" && "model" in firstArg) {
|
|
136
|
+
const payloadModel = firstArg.model;
|
|
137
|
+
return typeof payloadModel === "string" ? payloadModel : null;
|
|
138
|
+
}
|
|
114
139
|
return null;
|
|
115
140
|
}
|
|
116
141
|
const withModel = googleModel;
|
|
@@ -120,16 +145,35 @@ function extractRequestedModel(googleModel) {
|
|
|
120
145
|
if (typeof withModel.modelName === "string") {
|
|
121
146
|
return withModel.modelName;
|
|
122
147
|
}
|
|
148
|
+
const firstArg = args[0];
|
|
149
|
+
if (firstArg && typeof firstArg === "object" && "model" in firstArg) {
|
|
150
|
+
const payloadModel = firstArg.model;
|
|
151
|
+
return typeof payloadModel === "string" ? payloadModel : null;
|
|
152
|
+
}
|
|
123
153
|
return null;
|
|
124
154
|
}
|
|
125
155
|
function extractMaxOutputTokens(args) {
|
|
126
156
|
const firstArg = args[0];
|
|
127
157
|
if (!firstArg || typeof firstArg !== "object") {
|
|
128
|
-
|
|
158
|
+
const secondArg = args[1];
|
|
159
|
+
if (!secondArg || typeof secondArg !== "object") {
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
const options = secondArg;
|
|
163
|
+
const optionsGenerationMax = options.generationConfig?.maxOutputTokens;
|
|
164
|
+
if (typeof optionsGenerationMax === "number") {
|
|
165
|
+
return optionsGenerationMax;
|
|
166
|
+
}
|
|
167
|
+
const optionsConfigMax = options.config?.maxOutputTokens;
|
|
168
|
+
return typeof optionsConfigMax === "number" ? optionsConfigMax : undefined;
|
|
129
169
|
}
|
|
130
170
|
const payload = firstArg;
|
|
131
|
-
const
|
|
132
|
-
|
|
171
|
+
const generationMax = payload.generationConfig?.maxOutputTokens;
|
|
172
|
+
if (typeof generationMax === "number") {
|
|
173
|
+
return generationMax;
|
|
174
|
+
}
|
|
175
|
+
const configMax = payload.config?.maxOutputTokens;
|
|
176
|
+
return typeof configMax === "number" ? configMax : undefined;
|
|
133
177
|
}
|
|
134
178
|
function extractTotalTokens(response) {
|
|
135
179
|
if (!response || typeof response !== "object") {
|
|
@@ -189,11 +233,13 @@ function maybeApplyGoogleClamp(args, decision) {
|
|
|
189
233
|
const firstArg = nextArgs[0];
|
|
190
234
|
if (firstArg && typeof firstArg === "object") {
|
|
191
235
|
const payload = { ...firstArg };
|
|
192
|
-
const
|
|
193
|
-
|
|
236
|
+
const useModernConfig = "config" in payload || "contents" in payload || "model" in payload;
|
|
237
|
+
const configKey = useModernConfig ? "config" : "generationConfig";
|
|
238
|
+
const existingConfig = payload[configKey] && typeof payload[configKey] === "object"
|
|
239
|
+
? payload[configKey]
|
|
194
240
|
: {};
|
|
195
241
|
const existingMax = existingConfig.maxOutputTokens;
|
|
196
|
-
payload
|
|
242
|
+
payload[configKey] = {
|
|
197
243
|
...existingConfig,
|
|
198
244
|
maxOutputTokens: typeof existingMax === "number" ? Math.min(existingMax, recommended) : recommended,
|
|
199
245
|
};
|
|
@@ -201,14 +247,15 @@ function maybeApplyGoogleClamp(args, decision) {
|
|
|
201
247
|
return nextArgs;
|
|
202
248
|
}
|
|
203
249
|
const secondArg = nextArgs[1];
|
|
204
|
-
const
|
|
205
|
-
const
|
|
206
|
-
|
|
250
|
+
const existingOptions = secondArg && typeof secondArg === "object" ? { ...secondArg } : {};
|
|
251
|
+
const configKey = existingOptions.config && typeof existingOptions.config === "object" ? "config" : "generationConfig";
|
|
252
|
+
const generationConfig = existingOptions[configKey] && typeof existingOptions[configKey] === "object"
|
|
253
|
+
? { ...existingOptions[configKey] }
|
|
207
254
|
: {};
|
|
208
255
|
const existingMax = generationConfig.maxOutputTokens;
|
|
209
256
|
generationConfig.maxOutputTokens = typeof existingMax === "number" ? Math.min(existingMax, recommended) : recommended;
|
|
210
|
-
|
|
211
|
-
nextArgs[1] =
|
|
257
|
+
existingOptions[configKey] = generationConfig;
|
|
258
|
+
nextArgs[1] = existingOptions;
|
|
212
259
|
return nextArgs;
|
|
213
260
|
}
|
|
214
261
|
function markClampAppliedIfChanged(decision, originalMaxTokens, appliedMaxTokens) {
|
package/package.json
CHANGED