raindrop-ai 0.3.0 → 0.3.1
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/{chunk-5Y3LWBKV.mjs → chunk-4TM4IWHB.mjs} +192 -77
- package/dist/{index-DBdUrUXc.d.mts → index-DuXeVnSq.d.mts} +32 -1
- package/dist/{index-DBdUrUXc.d.ts → index-DuXeVnSq.d.ts} +32 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +224 -74
- package/dist/index.mjs +36 -1
- package/dist/tracing/index.d.mts +6 -16
- package/dist/tracing/index.d.ts +6 -16
- package/dist/tracing/index.js +208 -91
- package/dist/tracing/index.mjs +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -5778,7 +5778,7 @@ if (!globalThis.RAINDROP_ASYNC_LOCAL_STORAGE) {
|
|
|
5778
5778
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = import_node_async_hooks.AsyncLocalStorage;
|
|
5779
5779
|
}
|
|
5780
5780
|
|
|
5781
|
-
// ../core/dist/chunk-
|
|
5781
|
+
// ../core/dist/chunk-3V4MIA75.js
|
|
5782
5782
|
function normalizeFeatureFlags(input) {
|
|
5783
5783
|
if (Array.isArray(input)) {
|
|
5784
5784
|
return Object.fromEntries(input.map((name) => [name, "true"]));
|
|
@@ -6326,6 +6326,20 @@ function stringifyBounded(value, limit) {
|
|
|
6326
6326
|
}
|
|
6327
6327
|
return json.length <= max ? json : truncateToLimit(json, max);
|
|
6328
6328
|
}
|
|
6329
|
+
function attrString(key, value) {
|
|
6330
|
+
if (value === void 0) return void 0;
|
|
6331
|
+
return { key, value: { stringValue: value } };
|
|
6332
|
+
}
|
|
6333
|
+
function attrInt(key, value) {
|
|
6334
|
+
if (value === void 0) return void 0;
|
|
6335
|
+
if (!Number.isFinite(value)) return void 0;
|
|
6336
|
+
return { key, value: { intValue: String(Math.trunc(value)) } };
|
|
6337
|
+
}
|
|
6338
|
+
function attrDouble(key, value) {
|
|
6339
|
+
if (value === void 0) return void 0;
|
|
6340
|
+
if (!Number.isFinite(value)) return void 0;
|
|
6341
|
+
return { key, value: { doubleValue: value } };
|
|
6342
|
+
}
|
|
6329
6343
|
var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
|
|
6330
6344
|
var WORKSHOP_ENV_VAR = "RAINDROP_WORKSHOP";
|
|
6331
6345
|
var DEFAULT_LOCAL_WORKSHOP_URL = "http://localhost:5899/v1/";
|
|
@@ -6456,6 +6470,7 @@ function projectIdHeaders(projectId) {
|
|
|
6456
6470
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
6457
6471
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
6458
6472
|
var MODEL_USAGE_ATTRIBUTES = {
|
|
6473
|
+
usageSource: "raindrop.usage.source",
|
|
6459
6474
|
providerName: "gen_ai.provider.name",
|
|
6460
6475
|
requestModel: "gen_ai.request.model",
|
|
6461
6476
|
responseModel: "gen_ai.response.model",
|
|
@@ -6464,6 +6479,7 @@ var MODEL_USAGE_ATTRIBUTES = {
|
|
|
6464
6479
|
reasoningTokens: "gen_ai.usage.reasoning_tokens",
|
|
6465
6480
|
cacheReadInputTokens: "gen_ai.usage.cache_read_input_tokens",
|
|
6466
6481
|
cacheWriteInputTokens: "gen_ai.usage.cache_write_input_tokens",
|
|
6482
|
+
providerReportedCost: "gen_ai.usage.provider_reported_cost",
|
|
6467
6483
|
nonCachedInputTokens: "raindrop.usage.input_tokens.non_cached",
|
|
6468
6484
|
nonReasoningOutputTokens: "raindrop.usage.output_tokens.non_reasoning",
|
|
6469
6485
|
totalOutputTokens: "raindrop.usage.output_tokens.total",
|
|
@@ -6471,6 +6487,47 @@ var MODEL_USAGE_ATTRIBUTES = {
|
|
|
6471
6487
|
cacheReadTokens: "raindrop.usage.input_tokens.cache_read",
|
|
6472
6488
|
cacheWriteTokens: "raindrop.usage.input_tokens.cache_write"
|
|
6473
6489
|
};
|
|
6490
|
+
var MODEL_PROVIDER_NAMES = [
|
|
6491
|
+
["google.vertex.anthropic", "google-vertex"],
|
|
6492
|
+
["google.vertex_ai", "google-vertex"],
|
|
6493
|
+
["google.vertex", "google-vertex"],
|
|
6494
|
+
["gcp.vertex_ai", "google-vertex"],
|
|
6495
|
+
["gcp.gemini", "google"],
|
|
6496
|
+
["google_vertexai", "google-vertex"],
|
|
6497
|
+
["vertex.anthropic", "google-vertex"],
|
|
6498
|
+
["amazon-bedrock", "amazon-bedrock"],
|
|
6499
|
+
["aws.bedrock", "amazon-bedrock"],
|
|
6500
|
+
["bedrock", "amazon-bedrock"],
|
|
6501
|
+
["anthropic", "anthropic"],
|
|
6502
|
+
["openai", "openai"],
|
|
6503
|
+
["google", "google"],
|
|
6504
|
+
["az.ai.openai", "azure"],
|
|
6505
|
+
["azure", "azure"],
|
|
6506
|
+
["openrouter", "openrouter"]
|
|
6507
|
+
];
|
|
6508
|
+
function canonicalModelProvider(provider) {
|
|
6509
|
+
var _a;
|
|
6510
|
+
const normalizedProvider = provider.trim().toLowerCase();
|
|
6511
|
+
if (normalizedProvider === "gateway") return "vercel";
|
|
6512
|
+
const match = MODEL_PROVIDER_NAMES.find(
|
|
6513
|
+
([family]) => normalizedProvider === family || normalizedProvider.startsWith(`${family}.`)
|
|
6514
|
+
);
|
|
6515
|
+
return (_a = match == null ? void 0 : match[1]) != null ? _a : normalizedProvider;
|
|
6516
|
+
}
|
|
6517
|
+
function tokenCount(value) {
|
|
6518
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
6519
|
+
}
|
|
6520
|
+
function buildRawModelUsageAttributes(usage) {
|
|
6521
|
+
const providerReportedCost = typeof usage.providerReportedCost === "number" && Number.isFinite(usage.providerReportedCost) && usage.providerReportedCost >= 0 ? usage.providerReportedCost : void 0;
|
|
6522
|
+
return [
|
|
6523
|
+
attrInt(MODEL_USAGE_ATTRIBUTES.inputTokens, tokenCount(usage.inputTokens)),
|
|
6524
|
+
attrInt(MODEL_USAGE_ATTRIBUTES.outputTokens, tokenCount(usage.outputTokens)),
|
|
6525
|
+
attrInt(MODEL_USAGE_ATTRIBUTES.reasoningTokens, tokenCount(usage.reasoningTokens)),
|
|
6526
|
+
attrInt(MODEL_USAGE_ATTRIBUTES.cacheReadInputTokens, tokenCount(usage.cacheReadInputTokens)),
|
|
6527
|
+
attrInt(MODEL_USAGE_ATTRIBUTES.cacheWriteInputTokens, tokenCount(usage.cacheWriteInputTokens)),
|
|
6528
|
+
attrDouble(MODEL_USAGE_ATTRIBUTES.providerReportedCost, providerReportedCost)
|
|
6529
|
+
].filter((attribute) => attribute !== void 0);
|
|
6530
|
+
}
|
|
6474
6531
|
var STRING_ALIASES = {
|
|
6475
6532
|
[MODEL_USAGE_ATTRIBUTES.requestModel]: ["ai.model.id", "ai.model"]
|
|
6476
6533
|
};
|
|
@@ -10920,7 +10977,7 @@ var SignalEventSchema = external_exports.object({
|
|
|
10920
10977
|
// package.json
|
|
10921
10978
|
var package_default = {
|
|
10922
10979
|
name: "raindrop-ai",
|
|
10923
|
-
version: "0.3.
|
|
10980
|
+
version: "0.3.1",
|
|
10924
10981
|
main: "dist/index.js",
|
|
10925
10982
|
module: "dist/index.mjs",
|
|
10926
10983
|
types: "dist/index.d.ts",
|
|
@@ -11602,7 +11659,7 @@ var DirectTraceShipper = class {
|
|
|
11602
11659
|
* so spans still appear as children in the trace tree.
|
|
11603
11660
|
*/
|
|
11604
11661
|
sendSpan(params) {
|
|
11605
|
-
var _a, _b;
|
|
11662
|
+
var _a, _b, _c;
|
|
11606
11663
|
if (!this.enabled) return;
|
|
11607
11664
|
let traceIdB64 = params.traceId;
|
|
11608
11665
|
let parentSpanIdB64 = params.parentSpanId;
|
|
@@ -11646,6 +11703,7 @@ var DirectTraceShipper = class {
|
|
|
11646
11703
|
})) {
|
|
11647
11704
|
attributes.push(attrString2(key, value));
|
|
11648
11705
|
}
|
|
11706
|
+
attributes.push(...(_c = params.otlpAttributes) != null ? _c : []);
|
|
11649
11707
|
let status;
|
|
11650
11708
|
if (params.error) {
|
|
11651
11709
|
status = { code: 2, message: params.error };
|
|
@@ -11797,9 +11855,62 @@ var DirectTraceShipper = class {
|
|
|
11797
11855
|
}
|
|
11798
11856
|
};
|
|
11799
11857
|
|
|
11858
|
+
// src/tracing/exit-flush.ts
|
|
11859
|
+
var traceloop = __toESM(require("@traceloop/node-server-sdk"));
|
|
11860
|
+
var STATE_KEY2 = /* @__PURE__ */ Symbol.for("raindrop.tracing.exitFlushState");
|
|
11861
|
+
function getState2() {
|
|
11862
|
+
const holder = globalThis;
|
|
11863
|
+
let state = holder[STATE_KEY2];
|
|
11864
|
+
if (!state) {
|
|
11865
|
+
state = {
|
|
11866
|
+
clientFlushers: /* @__PURE__ */ new Set(),
|
|
11867
|
+
pipelineFlushNeeded: false,
|
|
11868
|
+
handlerRegistered: false
|
|
11869
|
+
};
|
|
11870
|
+
holder[STATE_KEY2] = state;
|
|
11871
|
+
}
|
|
11872
|
+
return state;
|
|
11873
|
+
}
|
|
11874
|
+
function ensureExitHandler(state) {
|
|
11875
|
+
if (state.handlerRegistered) return;
|
|
11876
|
+
if (typeof process === "undefined" || typeof process.once !== "function") return;
|
|
11877
|
+
state.handlerRegistered = true;
|
|
11878
|
+
process.once("beforeExit", () => {
|
|
11879
|
+
void flushAll();
|
|
11880
|
+
});
|
|
11881
|
+
}
|
|
11882
|
+
function registerClientFlusher(flush) {
|
|
11883
|
+
const state = getState2();
|
|
11884
|
+
state.clientFlushers.add(flush);
|
|
11885
|
+
ensureExitHandler(state);
|
|
11886
|
+
return () => {
|
|
11887
|
+
state.clientFlushers.delete(flush);
|
|
11888
|
+
};
|
|
11889
|
+
}
|
|
11890
|
+
function markPipelineForExitFlush() {
|
|
11891
|
+
const state = getState2();
|
|
11892
|
+
state.pipelineFlushNeeded = true;
|
|
11893
|
+
ensureExitHandler(state);
|
|
11894
|
+
}
|
|
11895
|
+
async function flushAll() {
|
|
11896
|
+
const state = getState2();
|
|
11897
|
+
const tasks = [];
|
|
11898
|
+
for (const flush of state.clientFlushers) {
|
|
11899
|
+
tasks.push(Promise.resolve().then(flush).catch(() => {
|
|
11900
|
+
}));
|
|
11901
|
+
}
|
|
11902
|
+
if (state.pipelineFlushNeeded) {
|
|
11903
|
+
tasks.push(
|
|
11904
|
+
Promise.resolve().then(() => traceloop.forceFlush()).catch(() => {
|
|
11905
|
+
})
|
|
11906
|
+
);
|
|
11907
|
+
}
|
|
11908
|
+
await Promise.all(tasks);
|
|
11909
|
+
}
|
|
11910
|
+
|
|
11800
11911
|
// src/tracing/liveInteraction.ts
|
|
11801
11912
|
var import_api3 = require("@opentelemetry/api");
|
|
11802
|
-
var
|
|
11913
|
+
var traceloop2 = __toESM(require("@traceloop/node-server-sdk"));
|
|
11803
11914
|
|
|
11804
11915
|
// src/tracing/subagents.ts
|
|
11805
11916
|
var import_api2 = require("@opentelemetry/api");
|
|
@@ -12223,6 +12334,7 @@ var DirectToolSpan = class {
|
|
|
12223
12334
|
};
|
|
12224
12335
|
var LiveInteraction = class {
|
|
12225
12336
|
constructor(context6, traceId, analytics, directShipper, routing) {
|
|
12337
|
+
this.usageEmitted = false;
|
|
12226
12338
|
this.context = context6;
|
|
12227
12339
|
this.analytics = analytics;
|
|
12228
12340
|
this.tracer = import_api3.trace.getTracer("traceloop.tracer");
|
|
@@ -12307,10 +12419,7 @@ var LiveInteraction = class {
|
|
|
12307
12419
|
spanId: base64ToHex2(spanIdB64),
|
|
12308
12420
|
traceFlags: import_api3.TraceFlags.SAMPLED
|
|
12309
12421
|
};
|
|
12310
|
-
const wrappedContext = import_api3.trace.setSpan(
|
|
12311
|
-
import_api3.context.active(),
|
|
12312
|
-
import_api3.trace.wrapSpanContext(spanContext)
|
|
12313
|
-
);
|
|
12422
|
+
const wrappedContext = import_api3.trace.setSpan(import_api3.context.active(), import_api3.trace.wrapSpanContext(spanContext));
|
|
12314
12423
|
const invoke = () => this.routing ? withRoutingContext(this.routing, () => fn.apply(thisArg, args)) : fn.apply(thisArg, args);
|
|
12315
12424
|
try {
|
|
12316
12425
|
const result = await import_api3.context.with(wrappedContext, invoke);
|
|
@@ -12361,7 +12470,7 @@ var LiveInteraction = class {
|
|
|
12361
12470
|
}
|
|
12362
12471
|
return fn.apply(thisArg, fnArgs);
|
|
12363
12472
|
};
|
|
12364
|
-
return
|
|
12473
|
+
return traceloop2.withTask(
|
|
12365
12474
|
{
|
|
12366
12475
|
name: taskName,
|
|
12367
12476
|
associationProperties: serializeAssociationProperties(properties),
|
|
@@ -12402,10 +12511,7 @@ var LiveInteraction = class {
|
|
|
12402
12511
|
spanId: base64ToHex2(spanIdB64),
|
|
12403
12512
|
traceFlags: import_api3.TraceFlags.SAMPLED
|
|
12404
12513
|
};
|
|
12405
|
-
const wrappedContext = import_api3.trace.setSpan(
|
|
12406
|
-
import_api3.context.active(),
|
|
12407
|
-
import_api3.trace.wrapSpanContext(spanContext)
|
|
12408
|
-
);
|
|
12514
|
+
const wrappedContext = import_api3.trace.setSpan(import_api3.context.active(), import_api3.trace.wrapSpanContext(spanContext));
|
|
12409
12515
|
const invoke = () => this.routing ? withRoutingContext(this.routing, () => fn.apply(thisArg, args)) : fn.apply(thisArg, args);
|
|
12410
12516
|
let result;
|
|
12411
12517
|
let error;
|
|
@@ -12515,7 +12621,7 @@ var LiveInteraction = class {
|
|
|
12515
12621
|
throw error;
|
|
12516
12622
|
}
|
|
12517
12623
|
};
|
|
12518
|
-
return
|
|
12624
|
+
return traceloop2.withTool(
|
|
12519
12625
|
{
|
|
12520
12626
|
name: toolName,
|
|
12521
12627
|
associationProperties: serializeAssociationProperties(properties),
|
|
@@ -12818,7 +12924,7 @@ var LiveInteraction = class {
|
|
|
12818
12924
|
span.end();
|
|
12819
12925
|
}
|
|
12820
12926
|
async finish(resultEvent) {
|
|
12821
|
-
var _a, _b, _c, _d;
|
|
12927
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
12822
12928
|
unbindRoutingContext(this.boundContext);
|
|
12823
12929
|
this.boundContext = void 0;
|
|
12824
12930
|
unbindSpanAttributes(this.toolEventsFrame);
|
|
@@ -12826,6 +12932,15 @@ var LiveInteraction = class {
|
|
|
12826
12932
|
if (!this.traceId) {
|
|
12827
12933
|
this.resolveLiveTraceId();
|
|
12828
12934
|
}
|
|
12935
|
+
const eventId = resultEvent.eventId || this.context.eventId;
|
|
12936
|
+
if (!this.usageEmitted) {
|
|
12937
|
+
(_c = this.analytics) == null ? void 0 : _c._recordModelUsage(
|
|
12938
|
+
eventId,
|
|
12939
|
+
(_a = resultEvent.model) != null ? _a : this.context.model,
|
|
12940
|
+
(_b = resultEvent.usage) != null ? _b : this.context.usage
|
|
12941
|
+
);
|
|
12942
|
+
this.usageEmitted = true;
|
|
12943
|
+
}
|
|
12829
12944
|
const spanFlush = (async () => {
|
|
12830
12945
|
var _a2;
|
|
12831
12946
|
try {
|
|
@@ -12833,21 +12948,20 @@ var LiveInteraction = class {
|
|
|
12833
12948
|
} catch (e) {
|
|
12834
12949
|
}
|
|
12835
12950
|
})();
|
|
12836
|
-
if ((
|
|
12951
|
+
if ((_e = (_d = this.analytics) == null ? void 0 : _d._shouldBlockFinishFlush()) != null ? _e : true) {
|
|
12837
12952
|
await spanFlush;
|
|
12838
12953
|
} else {
|
|
12839
12954
|
void spanFlush.catch(() => {
|
|
12840
12955
|
});
|
|
12841
12956
|
}
|
|
12842
|
-
const eventId = resultEvent.eventId || this.context.eventId;
|
|
12843
12957
|
try {
|
|
12844
|
-
await ((
|
|
12958
|
+
await ((_f = this.analytics) == null ? void 0 : _f._drainInFlightPartials(eventId));
|
|
12845
12959
|
} catch (e) {
|
|
12846
12960
|
}
|
|
12847
12961
|
if (this.traceId) {
|
|
12848
12962
|
this.setProperty("trace_id", this.traceId);
|
|
12849
12963
|
}
|
|
12850
|
-
await ((
|
|
12964
|
+
await ((_g = this.analytics) == null ? void 0 : _g._trackAiPartial({
|
|
12851
12965
|
...resultEvent,
|
|
12852
12966
|
eventId,
|
|
12853
12967
|
isPending: false
|
|
@@ -12964,7 +13078,7 @@ var LiveInteraction = class {
|
|
|
12964
13078
|
|
|
12965
13079
|
// src/tracing/liveTracer.ts
|
|
12966
13080
|
var import_api4 = require("@opentelemetry/api");
|
|
12967
|
-
var
|
|
13081
|
+
var traceloop3 = __toESM(require("@traceloop/node-server-sdk"));
|
|
12968
13082
|
var LiveTracer = class {
|
|
12969
13083
|
constructor(globalProperties, directShipper, routing) {
|
|
12970
13084
|
this.tracer = import_api4.trace.getTracer("traceloop.tracer");
|
|
@@ -13008,7 +13122,7 @@ var LiveTracer = class {
|
|
|
13008
13122
|
}
|
|
13009
13123
|
return fn.apply(thisArg, fnArgs);
|
|
13010
13124
|
};
|
|
13011
|
-
return
|
|
13125
|
+
return traceloop3.withTask(
|
|
13012
13126
|
{
|
|
13013
13127
|
name: taskName,
|
|
13014
13128
|
associationProperties: properties,
|
|
@@ -13120,59 +13234,6 @@ var LiveTracer = class {
|
|
|
13120
13234
|
}
|
|
13121
13235
|
};
|
|
13122
13236
|
|
|
13123
|
-
// src/tracing/exit-flush.ts
|
|
13124
|
-
var traceloop3 = __toESM(require("@traceloop/node-server-sdk"));
|
|
13125
|
-
var STATE_KEY2 = /* @__PURE__ */ Symbol.for("raindrop.tracing.exitFlushState");
|
|
13126
|
-
function getState2() {
|
|
13127
|
-
const holder = globalThis;
|
|
13128
|
-
let state = holder[STATE_KEY2];
|
|
13129
|
-
if (!state) {
|
|
13130
|
-
state = {
|
|
13131
|
-
clientFlushers: /* @__PURE__ */ new Set(),
|
|
13132
|
-
pipelineFlushNeeded: false,
|
|
13133
|
-
handlerRegistered: false
|
|
13134
|
-
};
|
|
13135
|
-
holder[STATE_KEY2] = state;
|
|
13136
|
-
}
|
|
13137
|
-
return state;
|
|
13138
|
-
}
|
|
13139
|
-
function ensureExitHandler(state) {
|
|
13140
|
-
if (state.handlerRegistered) return;
|
|
13141
|
-
if (typeof process === "undefined" || typeof process.once !== "function") return;
|
|
13142
|
-
state.handlerRegistered = true;
|
|
13143
|
-
process.once("beforeExit", () => {
|
|
13144
|
-
void flushAll();
|
|
13145
|
-
});
|
|
13146
|
-
}
|
|
13147
|
-
function registerClientFlusher(flush) {
|
|
13148
|
-
const state = getState2();
|
|
13149
|
-
state.clientFlushers.add(flush);
|
|
13150
|
-
ensureExitHandler(state);
|
|
13151
|
-
return () => {
|
|
13152
|
-
state.clientFlushers.delete(flush);
|
|
13153
|
-
};
|
|
13154
|
-
}
|
|
13155
|
-
function markPipelineForExitFlush() {
|
|
13156
|
-
const state = getState2();
|
|
13157
|
-
state.pipelineFlushNeeded = true;
|
|
13158
|
-
ensureExitHandler(state);
|
|
13159
|
-
}
|
|
13160
|
-
async function flushAll() {
|
|
13161
|
-
const state = getState2();
|
|
13162
|
-
const tasks = [];
|
|
13163
|
-
for (const flush of state.clientFlushers) {
|
|
13164
|
-
tasks.push(Promise.resolve().then(flush).catch(() => {
|
|
13165
|
-
}));
|
|
13166
|
-
}
|
|
13167
|
-
if (state.pipelineFlushNeeded) {
|
|
13168
|
-
tasks.push(
|
|
13169
|
-
Promise.resolve().then(() => traceloop3.forceFlush()).catch(() => {
|
|
13170
|
-
})
|
|
13171
|
-
);
|
|
13172
|
-
}
|
|
13173
|
-
await Promise.all(tasks);
|
|
13174
|
-
}
|
|
13175
|
-
|
|
13176
13237
|
// src/tracing/tracer-core.ts
|
|
13177
13238
|
if (localDebuggerEnabled()) {
|
|
13178
13239
|
if (!process.env.OTEL_EXPORTER_OTLP_PROTOCOL) {
|
|
@@ -13890,6 +13951,59 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
13890
13951
|
...frame ? { frame, frameOwner } : {}
|
|
13891
13952
|
});
|
|
13892
13953
|
};
|
|
13954
|
+
const recordModelUsage = (params) => {
|
|
13955
|
+
try {
|
|
13956
|
+
const attributes = [
|
|
13957
|
+
attrString(MODEL_USAGE_ATTRIBUTES.usageSource, "manual"),
|
|
13958
|
+
attrString(
|
|
13959
|
+
MODEL_USAGE_ATTRIBUTES.providerName,
|
|
13960
|
+
canonicalModelProvider(params.usage.provider)
|
|
13961
|
+
),
|
|
13962
|
+
attrString(MODEL_USAGE_ATTRIBUTES.requestModel, params.model),
|
|
13963
|
+
attrString(MODEL_USAGE_ATTRIBUTES.responseModel, params.model),
|
|
13964
|
+
...buildRawModelUsageAttributes({
|
|
13965
|
+
inputTokens: params.usage.inputTokens,
|
|
13966
|
+
outputTokens: params.usage.outputTokens,
|
|
13967
|
+
cacheReadInputTokens: params.usage.cacheReadTokens,
|
|
13968
|
+
cacheWriteInputTokens: params.usage.cacheWriteTokens,
|
|
13969
|
+
reasoningTokens: params.usage.reasoningTokens,
|
|
13970
|
+
providerReportedCost: params.usage.providerReportedCost
|
|
13971
|
+
})
|
|
13972
|
+
].filter((attribute) => attribute !== void 0);
|
|
13973
|
+
if (directShipper) {
|
|
13974
|
+
const timeMs = Date.now();
|
|
13975
|
+
directShipper.sendSpan({
|
|
13976
|
+
name: "ai.model.usage",
|
|
13977
|
+
spanKind: "llm",
|
|
13978
|
+
properties: { event_id: params.eventId },
|
|
13979
|
+
startTimeMs: timeMs,
|
|
13980
|
+
endTimeMs: timeMs,
|
|
13981
|
+
durationMs: 0,
|
|
13982
|
+
otlpAttributes: attributes
|
|
13983
|
+
});
|
|
13984
|
+
return;
|
|
13985
|
+
}
|
|
13986
|
+
const span = import_api5.trace.getTracer("traceloop.tracer").startSpan("ai.model.usage");
|
|
13987
|
+
span.setAttribute("traceloop.span.kind", "llm");
|
|
13988
|
+
span.setAttribute("traceloop.association.properties.event_id", params.eventId);
|
|
13989
|
+
stampSpan(span, projectId, authHint);
|
|
13990
|
+
for (const attribute of attributes) {
|
|
13991
|
+
const value = attribute.value;
|
|
13992
|
+
if (value.stringValue !== void 0) {
|
|
13993
|
+
span.setAttribute(attribute.key, value.stringValue);
|
|
13994
|
+
} else if (value.intValue !== void 0) {
|
|
13995
|
+
const parsed = Number(value.intValue);
|
|
13996
|
+
if (Number.isSafeInteger(parsed)) span.setAttribute(attribute.key, parsed);
|
|
13997
|
+
} else if (value.doubleValue !== void 0) {
|
|
13998
|
+
span.setAttribute(attribute.key, value.doubleValue);
|
|
13999
|
+
} else if (value.boolValue !== void 0) {
|
|
14000
|
+
span.setAttribute(attribute.key, value.boolValue);
|
|
14001
|
+
}
|
|
14002
|
+
}
|
|
14003
|
+
span.end();
|
|
14004
|
+
} catch (e) {
|
|
14005
|
+
}
|
|
14006
|
+
};
|
|
13893
14007
|
return {
|
|
13894
14008
|
/**
|
|
13895
14009
|
* Returns instrumentation instances for your NodeSDK.
|
|
@@ -14001,6 +14115,7 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
14001
14115
|
begin(traceContext) {
|
|
14002
14116
|
return beginInteraction(traceContext);
|
|
14003
14117
|
},
|
|
14118
|
+
recordModelUsage,
|
|
14004
14119
|
resumeSubagent(carrierOrHeaders, options2 = {}) {
|
|
14005
14120
|
return openSubagentRun(carrierOrHeaders, options2);
|
|
14006
14121
|
},
|
|
@@ -14081,6 +14196,15 @@ var PartialClientAiTrack = ClientAiTrack.extend({
|
|
|
14081
14196
|
convo_id: import_zod.z.string().optional().nullable()
|
|
14082
14197
|
}).optional()
|
|
14083
14198
|
});
|
|
14199
|
+
var AiTrackUsageSchema = import_zod.z.object({
|
|
14200
|
+
provider: import_zod.z.string().trim().min(1),
|
|
14201
|
+
inputTokens: import_zod.z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
14202
|
+
outputTokens: import_zod.z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
14203
|
+
cacheReadTokens: import_zod.z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
14204
|
+
cacheWriteTokens: import_zod.z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
14205
|
+
reasoningTokens: import_zod.z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
14206
|
+
providerReportedCost: import_zod.z.number().finite().nonnegative().optional()
|
|
14207
|
+
});
|
|
14084
14208
|
var AttachmentTypeSchema = import_zod.z.enum(["code", "text", "image", "iframe"]);
|
|
14085
14209
|
|
|
14086
14210
|
// src/index.ts
|
|
@@ -14588,6 +14712,7 @@ var Raindrop = class {
|
|
|
14588
14712
|
attachments,
|
|
14589
14713
|
properties,
|
|
14590
14714
|
featureFlags,
|
|
14715
|
+
usage,
|
|
14591
14716
|
timestamp,
|
|
14592
14717
|
...rest
|
|
14593
14718
|
} = e;
|
|
@@ -14637,6 +14762,7 @@ var Raindrop = class {
|
|
|
14637
14762
|
type: "ai",
|
|
14638
14763
|
...toSave
|
|
14639
14764
|
});
|
|
14765
|
+
this._recordModelUsage(customEventId, model, usage);
|
|
14640
14766
|
return customEventId;
|
|
14641
14767
|
};
|
|
14642
14768
|
if (Array.isArray(event)) {
|
|
@@ -15062,6 +15188,7 @@ var Raindrop = class {
|
|
|
15062
15188
|
attachments,
|
|
15063
15189
|
properties,
|
|
15064
15190
|
featureFlags,
|
|
15191
|
+
usage: _usage,
|
|
15065
15192
|
...rest
|
|
15066
15193
|
} = accumulatedEvent;
|
|
15067
15194
|
const normalizedFlags = featureFlags ? normalizeFeatureFlags(featureFlags) : void 0;
|
|
@@ -15205,6 +15332,29 @@ var Raindrop = class {
|
|
|
15205
15332
|
} catch (e) {
|
|
15206
15333
|
}
|
|
15207
15334
|
}
|
|
15335
|
+
/**
|
|
15336
|
+
* Emit one model span carrying raw provider usage facts.
|
|
15337
|
+
* @internal
|
|
15338
|
+
*/
|
|
15339
|
+
_recordModelUsage(eventId, model, usage) {
|
|
15340
|
+
if (usage === void 0) return;
|
|
15341
|
+
const parsed = AiTrackUsageSchema.safeParse(usage);
|
|
15342
|
+
if (!parsed.success) {
|
|
15343
|
+
console.warn(
|
|
15344
|
+
`[raindrop] Invalid usage provided to .track_ai(): ${this.formatZodError(parsed.error)}`
|
|
15345
|
+
);
|
|
15346
|
+
return;
|
|
15347
|
+
}
|
|
15348
|
+
if (typeof model !== "string" || model.trim() === "") {
|
|
15349
|
+
console.warn("[raindrop] .track_ai() usage requires a non-empty model.");
|
|
15350
|
+
return;
|
|
15351
|
+
}
|
|
15352
|
+
this._tracing.recordModelUsage({
|
|
15353
|
+
eventId,
|
|
15354
|
+
model,
|
|
15355
|
+
usage: parsed.data
|
|
15356
|
+
});
|
|
15357
|
+
}
|
|
15208
15358
|
/**
|
|
15209
15359
|
* Wait for already-issued partial-event POSTs to settle. Used to order the
|
|
15210
15360
|
* terminal partial-event POST after any earlier in-flight POST for the same
|
package/dist/index.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
stringifyBounded,
|
|
22
22
|
tracing,
|
|
23
23
|
withRoutingContext
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-4TM4IWHB.mjs";
|
|
25
25
|
import {
|
|
26
26
|
__commonJS,
|
|
27
27
|
__toESM
|
|
@@ -9973,6 +9973,15 @@ var PartialClientAiTrack = ClientAiTrack.extend({
|
|
|
9973
9973
|
convo_id: z.string().optional().nullable()
|
|
9974
9974
|
}).optional()
|
|
9975
9975
|
});
|
|
9976
|
+
var AiTrackUsageSchema = z.object({
|
|
9977
|
+
provider: z.string().trim().min(1),
|
|
9978
|
+
inputTokens: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
9979
|
+
outputTokens: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
9980
|
+
cacheReadTokens: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
9981
|
+
cacheWriteTokens: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
9982
|
+
reasoningTokens: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
9983
|
+
providerReportedCost: z.number().finite().nonnegative().optional()
|
|
9984
|
+
});
|
|
9976
9985
|
var AttachmentTypeSchema = z.enum(["code", "text", "image", "iframe"]);
|
|
9977
9986
|
|
|
9978
9987
|
// src/index.ts
|
|
@@ -10480,6 +10489,7 @@ var Raindrop = class {
|
|
|
10480
10489
|
attachments,
|
|
10481
10490
|
properties,
|
|
10482
10491
|
featureFlags,
|
|
10492
|
+
usage,
|
|
10483
10493
|
timestamp,
|
|
10484
10494
|
...rest
|
|
10485
10495
|
} = e;
|
|
@@ -10529,6 +10539,7 @@ var Raindrop = class {
|
|
|
10529
10539
|
type: "ai",
|
|
10530
10540
|
...toSave
|
|
10531
10541
|
});
|
|
10542
|
+
this._recordModelUsage(customEventId, model, usage);
|
|
10532
10543
|
return customEventId;
|
|
10533
10544
|
};
|
|
10534
10545
|
if (Array.isArray(event)) {
|
|
@@ -10954,6 +10965,7 @@ var Raindrop = class {
|
|
|
10954
10965
|
attachments,
|
|
10955
10966
|
properties,
|
|
10956
10967
|
featureFlags,
|
|
10968
|
+
usage: _usage,
|
|
10957
10969
|
...rest
|
|
10958
10970
|
} = accumulatedEvent;
|
|
10959
10971
|
const normalizedFlags = featureFlags ? normalizeFeatureFlags(featureFlags) : void 0;
|
|
@@ -11097,6 +11109,29 @@ var Raindrop = class {
|
|
|
11097
11109
|
} catch (e) {
|
|
11098
11110
|
}
|
|
11099
11111
|
}
|
|
11112
|
+
/**
|
|
11113
|
+
* Emit one model span carrying raw provider usage facts.
|
|
11114
|
+
* @internal
|
|
11115
|
+
*/
|
|
11116
|
+
_recordModelUsage(eventId, model, usage) {
|
|
11117
|
+
if (usage === void 0) return;
|
|
11118
|
+
const parsed = AiTrackUsageSchema.safeParse(usage);
|
|
11119
|
+
if (!parsed.success) {
|
|
11120
|
+
console.warn(
|
|
11121
|
+
`[raindrop] Invalid usage provided to .track_ai(): ${this.formatZodError(parsed.error)}`
|
|
11122
|
+
);
|
|
11123
|
+
return;
|
|
11124
|
+
}
|
|
11125
|
+
if (typeof model !== "string" || model.trim() === "") {
|
|
11126
|
+
console.warn("[raindrop] .track_ai() usage requires a non-empty model.");
|
|
11127
|
+
return;
|
|
11128
|
+
}
|
|
11129
|
+
this._tracing.recordModelUsage({
|
|
11130
|
+
eventId,
|
|
11131
|
+
model,
|
|
11132
|
+
usage: parsed.data
|
|
11133
|
+
});
|
|
11134
|
+
}
|
|
11100
11135
|
/**
|
|
11101
11136
|
* Wait for already-issued partial-event POSTs to settle. Used to order the
|
|
11102
11137
|
* terminal partial-event POST after any earlier in-flight POST for the same
|
package/dist/tracing/index.d.mts
CHANGED
|
@@ -1,24 +1,9 @@
|
|
|
1
|
-
import { R as Raindrop, a as RaindropSpanProcessor, P as PartialAiTrackEvent, I as Interaction, C as CarrierHeaders, T as TraceCarrier, S as SubagentResumeOptions, b as SubagentRun, c as Tracer } from '../index-DBdUrUXc.mjs';
|
|
2
1
|
import { Instrumentation } from '@opentelemetry/instrumentation';
|
|
2
|
+
import { R as Raindrop, a as RaindropSpanProcessor, P as PartialAiTrackEvent, I as Interaction, A as AiTrackUsage, C as CarrierHeaders, T as TraceCarrier, S as SubagentResumeOptions, b as SubagentRun, c as Tracer } from '../index-DuXeVnSq.mjs';
|
|
3
3
|
import * as traceloop from '@traceloop/node-server-sdk';
|
|
4
4
|
import '@opentelemetry/api';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Tracing core - the real tracing implementation.
|
|
9
|
-
*
|
|
10
|
-
* Two modes:
|
|
11
|
-
*
|
|
12
|
-
* 1. DEFAULT: Raindrop manages everything
|
|
13
|
-
* - Creates NodeSDK, registers instrumentations, exports traces
|
|
14
|
-
* - Customer just uses raindrop.begin(), withSpan(), etc.
|
|
15
|
-
*
|
|
16
|
-
* 2. EXTERNAL OTEL (useExternalOtel: true): Customer has their own NodeSDK
|
|
17
|
-
* - Raindrop does NOT create a NodeSDK (would conflict!)
|
|
18
|
-
* - Customer adds raindrop.createSpanProcessor() to their NodeSDK
|
|
19
|
-
* - Customer calls raindrop.getInstrumentations() to get configured instrumentations
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
7
|
interface TracingOptions extends traceloop.InitializeOptions {
|
|
23
8
|
/**
|
|
24
9
|
* Set to true when you have your own OpenTelemetry NodeSDK.
|
|
@@ -103,6 +88,11 @@ declare const tracing: (analytics: Raindrop, apiUrl: string, writeKey: string, o
|
|
|
103
88
|
*/
|
|
104
89
|
createSpanProcessor(processorOptions?: traceloop.SpanProcessorOptions): RaindropSpanProcessor;
|
|
105
90
|
begin(traceContext: PartialAiTrackEvent): Interaction;
|
|
91
|
+
recordModelUsage: (params: {
|
|
92
|
+
eventId: string;
|
|
93
|
+
model: string;
|
|
94
|
+
usage: AiTrackUsage;
|
|
95
|
+
}) => void;
|
|
106
96
|
resumeSubagent(carrierOrHeaders: CarrierHeaders | TraceCarrier | null | undefined, options?: SubagentResumeOptions): SubagentRun;
|
|
107
97
|
withSubagentRun<T>(carrierOrHeaders: CarrierHeaders | TraceCarrier | null | undefined, fn: (run: SubagentRun) => Promise<T> | T, options?: SubagentResumeOptions): Promise<T>;
|
|
108
98
|
getActiveInteraction(eventId: string): Interaction;
|
package/dist/tracing/index.d.ts
CHANGED
|
@@ -1,24 +1,9 @@
|
|
|
1
|
-
import { R as Raindrop, a as RaindropSpanProcessor, P as PartialAiTrackEvent, I as Interaction, C as CarrierHeaders, T as TraceCarrier, S as SubagentResumeOptions, b as SubagentRun, c as Tracer } from '../index-DBdUrUXc.js';
|
|
2
1
|
import { Instrumentation } from '@opentelemetry/instrumentation';
|
|
2
|
+
import { R as Raindrop, a as RaindropSpanProcessor, P as PartialAiTrackEvent, I as Interaction, A as AiTrackUsage, C as CarrierHeaders, T as TraceCarrier, S as SubagentResumeOptions, b as SubagentRun, c as Tracer } from '../index-DuXeVnSq.js';
|
|
3
3
|
import * as traceloop from '@traceloop/node-server-sdk';
|
|
4
4
|
import '@opentelemetry/api';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Tracing core - the real tracing implementation.
|
|
9
|
-
*
|
|
10
|
-
* Two modes:
|
|
11
|
-
*
|
|
12
|
-
* 1. DEFAULT: Raindrop manages everything
|
|
13
|
-
* - Creates NodeSDK, registers instrumentations, exports traces
|
|
14
|
-
* - Customer just uses raindrop.begin(), withSpan(), etc.
|
|
15
|
-
*
|
|
16
|
-
* 2. EXTERNAL OTEL (useExternalOtel: true): Customer has their own NodeSDK
|
|
17
|
-
* - Raindrop does NOT create a NodeSDK (would conflict!)
|
|
18
|
-
* - Customer adds raindrop.createSpanProcessor() to their NodeSDK
|
|
19
|
-
* - Customer calls raindrop.getInstrumentations() to get configured instrumentations
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
7
|
interface TracingOptions extends traceloop.InitializeOptions {
|
|
23
8
|
/**
|
|
24
9
|
* Set to true when you have your own OpenTelemetry NodeSDK.
|
|
@@ -103,6 +88,11 @@ declare const tracing: (analytics: Raindrop, apiUrl: string, writeKey: string, o
|
|
|
103
88
|
*/
|
|
104
89
|
createSpanProcessor(processorOptions?: traceloop.SpanProcessorOptions): RaindropSpanProcessor;
|
|
105
90
|
begin(traceContext: PartialAiTrackEvent): Interaction;
|
|
91
|
+
recordModelUsage: (params: {
|
|
92
|
+
eventId: string;
|
|
93
|
+
model: string;
|
|
94
|
+
usage: AiTrackUsage;
|
|
95
|
+
}) => void;
|
|
106
96
|
resumeSubagent(carrierOrHeaders: CarrierHeaders | TraceCarrier | null | undefined, options?: SubagentResumeOptions): SubagentRun;
|
|
107
97
|
withSubagentRun<T>(carrierOrHeaders: CarrierHeaders | TraceCarrier | null | undefined, fn: (run: SubagentRun) => Promise<T> | T, options?: SubagentResumeOptions): Promise<T>;
|
|
108
98
|
getActiveInteraction(eventId: string): Interaction;
|