@raindrop-ai/ai-sdk 0.0.20 → 0.0.22
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/README.md +43 -9
- package/dist/{chunk-FD5GVIE2.mjs → chunk-7NLWLLB4.mjs} +318 -22
- package/dist/{index-DGziajf_.d.mts → index-sxjvhkYW.d.mts} +91 -1
- package/dist/{index-DGziajf_.d.ts → index-sxjvhkYW.d.ts} +91 -1
- package/dist/index.browser.d.mts +91 -1
- package/dist/index.browser.d.ts +91 -1
- package/dist/index.browser.js +318 -22
- package/dist/index.browser.mjs +318 -22
- package/dist/index.node.d.mts +1 -1
- package/dist/index.node.d.ts +1 -1
- package/dist/index.node.js +318 -22
- package/dist/index.node.mjs +1 -1
- package/dist/index.workers.d.mts +1 -1
- package/dist/index.workers.d.ts +1 -1
- package/dist/index.workers.js +318 -22
- package/dist/index.workers.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@ Standalone Vercel AI SDK integration for Raindrop:
|
|
|
5
5
|
- **Events**: sends a `track_partial` payload to `POST /v1/events/track_partial` when the model finishes
|
|
6
6
|
- **Standalone traces**: ships spans directly to `POST /v1/traces` as **OTLP/HTTP JSON**
|
|
7
7
|
- **No OpenTelemetry SDK init**: avoids global OTEL registration conflicts
|
|
8
|
+
- **Native v7 telemetry**: opt-in callback-based integration via AI SDK v7's `TelemetryIntegration` interface (no Proxy wrapping)
|
|
8
9
|
|
|
9
10
|
## Install
|
|
10
11
|
|
|
@@ -54,6 +55,27 @@ await raindrop.users.identify({
|
|
|
54
55
|
await raindrop.flush();
|
|
55
56
|
```
|
|
56
57
|
|
|
58
|
+
### AI SDK v7+ native telemetry (opt-in)
|
|
59
|
+
|
|
60
|
+
On AI SDK v7+, you can use the native `TelemetryIntegration` callback interface instead of Proxy wrapping. This avoids Proxy overhead and works with all AI SDK entry points (including `ToolLoopAgent`).
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// Option A: wrap() with nativeTelemetry flag
|
|
64
|
+
const { generateText } = raindrop.wrap(ai, {
|
|
65
|
+
context: { userId: "user_123" },
|
|
66
|
+
nativeTelemetry: true,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Option B: direct registration (no wrap needed)
|
|
70
|
+
import { registerTelemetryIntegration } from "ai";
|
|
71
|
+
|
|
72
|
+
registerTelemetryIntegration(
|
|
73
|
+
raindrop.createTelemetryIntegration({ userId: "user_123" })
|
|
74
|
+
);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Setting `nativeTelemetry: true` on pre-v7 throws a clear error. The Proxy path remains the default and supports features not yet available on the native path (`buildEvent`, output attachment extraction).
|
|
78
|
+
|
|
57
79
|
If `userId` is missing from both `wrap()` context and `eventMetadata()`, the SDK logs a warning (once) and skips sending events.
|
|
58
80
|
|
|
59
81
|
## Runtime support
|
|
@@ -101,11 +123,12 @@ but it uses the same synchronous fallback described above rather than real
|
|
|
101
123
|
|
|
102
124
|
This package is tested against multiple Vercel AI SDK versions:
|
|
103
125
|
|
|
104
|
-
| Version | Status |
|
|
105
|
-
|
|
106
|
-
| v4.x | ✅ Supported |
|
|
107
|
-
| v5.x | ✅ Supported |
|
|
108
|
-
| v6.x | ✅ Supported |
|
|
126
|
+
| Version | Status | Integration |
|
|
127
|
+
|---------|--------|-------------|
|
|
128
|
+
| v4.x | ✅ Supported | Proxy |
|
|
129
|
+
| v5.x | ✅ Supported | Proxy |
|
|
130
|
+
| v6.x | ✅ Supported | Proxy |
|
|
131
|
+
| v7.x (beta) | ✅ Supported | Proxy (default) or native `TelemetryIntegration` (opt-in) |
|
|
109
132
|
|
|
110
133
|
### Version Differences Handled
|
|
111
134
|
|
|
@@ -130,10 +153,15 @@ packages/ai-sdk/
|
|
|
130
153
|
│ │ ├── ai-sdk.v5.test.ts
|
|
131
154
|
│ │ ├── wrapper.test.ts
|
|
132
155
|
│ │ └── http-payloads.test.ts
|
|
133
|
-
│
|
|
134
|
-
│
|
|
135
|
-
│
|
|
136
|
-
│
|
|
156
|
+
│ ├── v6/ # AI SDK v6 (pins ai@^6.0.0)
|
|
157
|
+
│ │ ├── ai-sdk.v6.test.ts
|
|
158
|
+
│ │ ├── wrapper.test.ts
|
|
159
|
+
│ │ └── http-payloads.test.ts
|
|
160
|
+
│ └── v7/ # AI SDK v7 beta (native telemetry + proxy)
|
|
161
|
+
│ ├── telemetry-integration.test.ts # Unit tests for all callbacks
|
|
162
|
+
│ ├── e2e-native-telemetry.test.ts # E2E with real AI SDK + MSW
|
|
163
|
+
│ ├── e2e-subagent-nesting.test.ts # Subagent span hierarchy
|
|
164
|
+
│ └── wrapper.test.ts
|
|
137
165
|
```
|
|
138
166
|
|
|
139
167
|
### Running Tests
|
|
@@ -146,6 +174,7 @@ pnpm test
|
|
|
146
174
|
pnpm test:v4
|
|
147
175
|
pnpm test:v5
|
|
148
176
|
pnpm test:v6
|
|
177
|
+
pnpm test:v7
|
|
149
178
|
|
|
150
179
|
# Quick smoke test (real LLM calls, single version)
|
|
151
180
|
pnpm smoke:min
|
|
@@ -158,6 +187,11 @@ Each version runs:
|
|
|
158
187
|
- **HTTP payload tests** - MSW-based payload validation for each spec version
|
|
159
188
|
- **Version-specific tests** - API differences (finishReason format, usage naming)
|
|
160
189
|
|
|
190
|
+
v7 additionally runs:
|
|
191
|
+
- **Telemetry integration tests** - All callback lifecycles with mock shippers
|
|
192
|
+
- **E2E native telemetry** - Real AI SDK v7 with MSW-intercepted payloads
|
|
193
|
+
- **Subagent nesting** - Span hierarchy for nested generateText inside tool execution
|
|
194
|
+
|
|
161
195
|
## Notes
|
|
162
196
|
|
|
163
197
|
- Spans include `ai.telemetry.metadata.raindrop.eventId` for correlation, and **omit** `ai.telemetry.metadata.raindrop.userId` to prevent duplicate span→event creation server-side.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
2
2
|
|
|
3
|
-
// ../core/dist/chunk-
|
|
3
|
+
// ../core/dist/chunk-4UCYIEH4.js
|
|
4
4
|
function getCrypto() {
|
|
5
5
|
const c = globalThis.crypto;
|
|
6
6
|
return c;
|
|
@@ -145,6 +145,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
147
|
var SpanStatusCode = {
|
|
148
|
+
UNSET: 0,
|
|
148
149
|
ERROR: 2
|
|
149
150
|
};
|
|
150
151
|
function createSpanIds(parent) {
|
|
@@ -159,6 +160,9 @@ function createSpanIds(parent) {
|
|
|
159
160
|
function nowUnixNanoString() {
|
|
160
161
|
return Date.now().toString() + "000000";
|
|
161
162
|
}
|
|
163
|
+
function unixMsToNanoString(ms) {
|
|
164
|
+
return String(Math.floor(ms)) + "000000";
|
|
165
|
+
}
|
|
162
166
|
function attrString(key, value) {
|
|
163
167
|
if (value === void 0) return void 0;
|
|
164
168
|
return { key, value: { stringValue: value } };
|
|
@@ -465,11 +469,66 @@ var EventShipper = class {
|
|
|
465
469
|
}
|
|
466
470
|
}
|
|
467
471
|
};
|
|
472
|
+
var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
|
|
473
|
+
function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
474
|
+
var _a, _b, _c;
|
|
475
|
+
const resolved = (_b = baseUrl != null ? baseUrl : typeof process !== "undefined" ? (_a = process.env) == null ? void 0 : _a[LOCAL_DEBUGGER_ENV_VAR] : void 0) != null ? _b : null;
|
|
476
|
+
return resolved ? (_c = formatEndpoint(resolved)) != null ? _c : null : null;
|
|
477
|
+
}
|
|
478
|
+
function localDebuggerEnabled(baseUrl) {
|
|
479
|
+
return resolveLocalDebuggerBaseUrl(baseUrl) !== null;
|
|
480
|
+
}
|
|
481
|
+
function normalizeLocalDebuggerLiveEventType(type) {
|
|
482
|
+
switch (type) {
|
|
483
|
+
case "text-delta":
|
|
484
|
+
return "text_delta";
|
|
485
|
+
case "reasoning":
|
|
486
|
+
case "reasoning-delta":
|
|
487
|
+
return "reasoning_delta";
|
|
488
|
+
case "tool-call":
|
|
489
|
+
return "tool_start";
|
|
490
|
+
case "tool-result":
|
|
491
|
+
return "tool_result";
|
|
492
|
+
default:
|
|
493
|
+
return type;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
497
|
+
var _a;
|
|
498
|
+
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
499
|
+
if (!baseUrl) return;
|
|
500
|
+
void postJson(`${baseUrl}traces`, body, {}, {
|
|
501
|
+
maxAttempts: 1,
|
|
502
|
+
debug: (_a = options.debug) != null ? _a : false,
|
|
503
|
+
sdkName: options.sdkName
|
|
504
|
+
}).catch(() => {
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
function sendLocalDebuggerLiveEvent(event, options = {}) {
|
|
508
|
+
var _a, _b;
|
|
509
|
+
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
510
|
+
if (!baseUrl) return;
|
|
511
|
+
void postJson(
|
|
512
|
+
`${baseUrl}live`,
|
|
513
|
+
{
|
|
514
|
+
...event,
|
|
515
|
+
type: normalizeLocalDebuggerLiveEventType(event.type),
|
|
516
|
+
timestamp: (_a = event.timestamp) != null ? _a : Date.now()
|
|
517
|
+
},
|
|
518
|
+
{},
|
|
519
|
+
{
|
|
520
|
+
maxAttempts: 1,
|
|
521
|
+
debug: (_b = options.debug) != null ? _b : false,
|
|
522
|
+
sdkName: options.sdkName
|
|
523
|
+
}
|
|
524
|
+
).catch(() => {
|
|
525
|
+
});
|
|
526
|
+
}
|
|
468
527
|
var TraceShipper = class {
|
|
469
528
|
constructor(opts) {
|
|
470
529
|
this.queue = [];
|
|
471
530
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
472
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
531
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
473
532
|
this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
|
|
474
533
|
this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
|
|
475
534
|
this.enabled = opts.enabled !== false;
|
|
@@ -482,6 +541,13 @@ var TraceShipper = class {
|
|
|
482
541
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
483
542
|
this.serviceName = (_g = opts.serviceName) != null ? _g : "raindrop.core";
|
|
484
543
|
this.serviceVersion = (_h = opts.serviceVersion) != null ? _h : "0.0.0";
|
|
544
|
+
const localDebugger = typeof process !== "undefined" ? (_i = process.env) == null ? void 0 : _i.RAINDROP_LOCAL_DEBUGGER : void 0;
|
|
545
|
+
if (localDebugger) {
|
|
546
|
+
this.localDebuggerUrl = (_j = resolveLocalDebuggerBaseUrl(localDebugger)) != null ? _j : void 0;
|
|
547
|
+
if (this.debug) {
|
|
548
|
+
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
485
551
|
}
|
|
486
552
|
isDebugEnabled() {
|
|
487
553
|
return this.debug;
|
|
@@ -498,7 +564,25 @@ var TraceShipper = class {
|
|
|
498
564
|
attrString("ai.operationId", args.operationId)
|
|
499
565
|
];
|
|
500
566
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
501
|
-
|
|
567
|
+
const span = { ids, name: args.name, startTimeUnixNano: started, attributes: attrs };
|
|
568
|
+
if (this.localDebuggerUrl) {
|
|
569
|
+
const openSpan = buildOtlpSpan({
|
|
570
|
+
ids: span.ids,
|
|
571
|
+
name: span.name,
|
|
572
|
+
startTimeUnixNano: span.startTimeUnixNano,
|
|
573
|
+
endTimeUnixNano: span.startTimeUnixNano,
|
|
574
|
+
// placeholder — will be updated on endSpan
|
|
575
|
+
attributes: span.attributes,
|
|
576
|
+
status: { code: SpanStatusCode.UNSET }
|
|
577
|
+
});
|
|
578
|
+
const body = buildExportTraceServiceRequest([openSpan], this.serviceName, this.serviceVersion);
|
|
579
|
+
mirrorTraceExportToLocalDebugger(body, {
|
|
580
|
+
baseUrl: this.localDebuggerUrl,
|
|
581
|
+
debug: false,
|
|
582
|
+
sdkName: this.sdkName
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
return span;
|
|
502
586
|
}
|
|
503
587
|
endSpan(span, extra) {
|
|
504
588
|
var _a, _b;
|
|
@@ -521,6 +605,14 @@ var TraceShipper = class {
|
|
|
521
605
|
status
|
|
522
606
|
});
|
|
523
607
|
this.enqueue(otlp);
|
|
608
|
+
if (this.localDebuggerUrl) {
|
|
609
|
+
const body = buildExportTraceServiceRequest([otlp], this.serviceName, this.serviceVersion);
|
|
610
|
+
mirrorTraceExportToLocalDebugger(body, {
|
|
611
|
+
baseUrl: this.localDebuggerUrl,
|
|
612
|
+
debug: false,
|
|
613
|
+
sdkName: this.sdkName
|
|
614
|
+
});
|
|
615
|
+
}
|
|
524
616
|
}
|
|
525
617
|
createSpan(args) {
|
|
526
618
|
var _a;
|
|
@@ -538,6 +630,14 @@ var TraceShipper = class {
|
|
|
538
630
|
status: args.status
|
|
539
631
|
});
|
|
540
632
|
this.enqueue(otlp);
|
|
633
|
+
if (this.localDebuggerUrl) {
|
|
634
|
+
const body = buildExportTraceServiceRequest([otlp], this.serviceName, this.serviceVersion);
|
|
635
|
+
mirrorTraceExportToLocalDebugger(body, {
|
|
636
|
+
baseUrl: this.localDebuggerUrl,
|
|
637
|
+
debug: false,
|
|
638
|
+
sdkName: this.sdkName
|
|
639
|
+
});
|
|
640
|
+
}
|
|
541
641
|
}
|
|
542
642
|
enqueue(span) {
|
|
543
643
|
if (!this.enabled) return;
|
|
@@ -1517,6 +1617,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
1517
1617
|
]
|
|
1518
1618
|
});
|
|
1519
1619
|
state.toolSpans.set(toolCall.toolCallId, toolSpan);
|
|
1620
|
+
this.emitLive(state, "tool_start", toolCall.toolName, { args: toolCall.input });
|
|
1520
1621
|
};
|
|
1521
1622
|
// ── onToolCallFinish ────────────────────────────────────────────────────
|
|
1522
1623
|
this.onToolCallFinish = (event) => {
|
|
@@ -1531,11 +1632,12 @@ var RaindropTelemetryIntegration = class {
|
|
|
1531
1632
|
} else {
|
|
1532
1633
|
this.traceShipper.endSpan(toolSpan, { error: event.error });
|
|
1533
1634
|
}
|
|
1635
|
+
this.emitLive(state, "tool_result", event.toolCall.toolName);
|
|
1534
1636
|
state.toolSpans.delete(event.toolCall.toolCallId);
|
|
1535
1637
|
};
|
|
1536
1638
|
// ── onChunk (streaming) ─────────────────────────────────────────────────
|
|
1537
1639
|
this.onChunk = (event) => {
|
|
1538
|
-
var _a, _b, _c;
|
|
1640
|
+
var _a, _b, _c, _d, _e;
|
|
1539
1641
|
const callId = (_b = event.callId) != null ? _b : (_a = event.chunk) == null ? void 0 : _a.callId;
|
|
1540
1642
|
if (!callId) return;
|
|
1541
1643
|
const state = this.getState(callId);
|
|
@@ -1546,6 +1648,12 @@ var RaindropTelemetryIntegration = class {
|
|
|
1546
1648
|
const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
|
|
1547
1649
|
if (typeof delta === "string") {
|
|
1548
1650
|
state.accumulatedText += delta;
|
|
1651
|
+
this.emitLive(state, "text_delta", delta);
|
|
1652
|
+
}
|
|
1653
|
+
} else if (chunk.type === "reasoning" || chunk.type === "reasoning-delta") {
|
|
1654
|
+
const text = (_e = (_d = chunk.textDelta) != null ? _d : chunk.text) != null ? _e : chunk.delta;
|
|
1655
|
+
if (typeof text === "string") {
|
|
1656
|
+
this.emitLive(state, "reasoning_delta", text);
|
|
1549
1657
|
}
|
|
1550
1658
|
}
|
|
1551
1659
|
};
|
|
@@ -1733,6 +1841,23 @@ var RaindropTelemetryIntegration = class {
|
|
|
1733
1841
|
spanParentRef(span) {
|
|
1734
1842
|
return { traceIdB64: span.ids.traceIdB64, spanIdB64: span.ids.spanIdB64 };
|
|
1735
1843
|
}
|
|
1844
|
+
emitLive(state, type, content, extra) {
|
|
1845
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1846
|
+
if (!localDebuggerEnabled() || !state.rootSpan) return;
|
|
1847
|
+
const callMeta = this.extractRaindropMetadata(state.metadata);
|
|
1848
|
+
sendLocalDebuggerLiveEvent({
|
|
1849
|
+
traceId: state.rootSpan.ids.traceIdB64,
|
|
1850
|
+
type,
|
|
1851
|
+
content,
|
|
1852
|
+
metadata: {
|
|
1853
|
+
userId: (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId,
|
|
1854
|
+
convoId: (_d = callMeta.convoId) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.convoId,
|
|
1855
|
+
eventName: (_f = callMeta.eventName) != null ? _f : (_e = this.defaultContext) == null ? void 0 : _e.eventName,
|
|
1856
|
+
eventId: state.eventId,
|
|
1857
|
+
...extra
|
|
1858
|
+
}
|
|
1859
|
+
});
|
|
1860
|
+
}
|
|
1736
1861
|
extractRaindropMetadata(metadata) {
|
|
1737
1862
|
if (!metadata) return {};
|
|
1738
1863
|
const result = {};
|
|
@@ -2265,6 +2390,36 @@ function shouldKeepEventPending(params) {
|
|
|
2265
2390
|
if (params.error != null || !params.canKeepEventPending) return false;
|
|
2266
2391
|
return params.finishReason === "tool-calls" || params.finishReason === "tool_calls";
|
|
2267
2392
|
}
|
|
2393
|
+
function normalizePromptAttr(arg) {
|
|
2394
|
+
if (!isRecord(arg)) return arg;
|
|
2395
|
+
const system = arg["system"];
|
|
2396
|
+
const prompt = arg["prompt"];
|
|
2397
|
+
const messages = arg["messages"];
|
|
2398
|
+
if (Array.isArray(messages)) {
|
|
2399
|
+
if (system) {
|
|
2400
|
+
const sysContent = typeof system === "string" ? system : JSON.stringify(system);
|
|
2401
|
+
return [{ role: "system", content: sysContent }, ...messages];
|
|
2402
|
+
}
|
|
2403
|
+
return messages;
|
|
2404
|
+
}
|
|
2405
|
+
if (typeof prompt === "string") {
|
|
2406
|
+
const msgs = [];
|
|
2407
|
+
if (system) {
|
|
2408
|
+
msgs.push({ role: "system", content: typeof system === "string" ? system : JSON.stringify(system) });
|
|
2409
|
+
}
|
|
2410
|
+
msgs.push({ role: "user", content: prompt });
|
|
2411
|
+
return msgs;
|
|
2412
|
+
}
|
|
2413
|
+
return { system, prompt, messages };
|
|
2414
|
+
}
|
|
2415
|
+
function getLocalDebuggerMetadata(ctx) {
|
|
2416
|
+
return {
|
|
2417
|
+
eventId: ctx.eventId,
|
|
2418
|
+
...ctx.eventName ? { eventName: ctx.eventName } : {},
|
|
2419
|
+
...ctx.userId ? { userId: ctx.userId } : {},
|
|
2420
|
+
...ctx.convoId ? { convoId: ctx.convoId } : {}
|
|
2421
|
+
};
|
|
2422
|
+
}
|
|
2268
2423
|
async function safeFinalize(finalize, debug, result, error) {
|
|
2269
2424
|
try {
|
|
2270
2425
|
await finalize(result, error);
|
|
@@ -2337,17 +2492,17 @@ function setupOperation(params) {
|
|
|
2337
2492
|
attrString("ai.telemetry.functionId", telemetry == null ? void 0 : telemetry.functionId),
|
|
2338
2493
|
attrString("ai.model.provider", modelInfoFromArgs.provider),
|
|
2339
2494
|
attrString("ai.model.id", modelInfoFromArgs.modelId),
|
|
2495
|
+
attrString("ai.telemetry.metadata.raindrop.eventId", eventId),
|
|
2496
|
+
attrString("ai.telemetry.metadata.raindrop.eventName", mergedCtx.eventName),
|
|
2497
|
+
attrString("ai.telemetry.metadata.raindrop.userId", mergedCtx.userId),
|
|
2498
|
+
attrString("ai.telemetry.metadata.raindrop.convoId", mergedCtx.convoId),
|
|
2340
2499
|
...attrsFromTelemetryMetadata(telemetry == null ? void 0 : telemetry.metadata),
|
|
2341
2500
|
...attrsFromHeaders(isRecord(arg) ? arg["headers"] : void 0),
|
|
2342
2501
|
...attrsFromSettings(arg),
|
|
2343
2502
|
...(telemetry == null ? void 0 : telemetry.recordInputs) === false ? [] : [
|
|
2344
2503
|
attrString(
|
|
2345
2504
|
"ai.prompt",
|
|
2346
|
-
safeJsonWithUint8(
|
|
2347
|
-
system: isRecord(arg) ? arg["system"] : void 0,
|
|
2348
|
-
prompt: isRecord(arg) ? arg["prompt"] : void 0,
|
|
2349
|
-
messages: isRecord(arg) ? arg["messages"] : void 0
|
|
2350
|
-
})
|
|
2505
|
+
safeJsonWithUint8(normalizePromptAttr(arg))
|
|
2351
2506
|
)
|
|
2352
2507
|
]
|
|
2353
2508
|
]
|
|
@@ -2356,6 +2511,7 @@ function setupOperation(params) {
|
|
|
2356
2511
|
const operationSelfDiagnostics = isObjectOperation(operation) ? void 0 : selfDiagnostics;
|
|
2357
2512
|
const wrapCtx = {
|
|
2358
2513
|
eventId,
|
|
2514
|
+
context: mergedCtx,
|
|
2359
2515
|
telemetry,
|
|
2360
2516
|
sendTraces,
|
|
2361
2517
|
debug,
|
|
@@ -2730,6 +2886,7 @@ function wrapAISDK(aiSDK, deps) {
|
|
|
2730
2886
|
const perCallEventIdGenerated = !perCallEventIdExplicit;
|
|
2731
2887
|
const perCallCtx = {
|
|
2732
2888
|
eventId: perCallEventId,
|
|
2889
|
+
context: wrapTimeCtx,
|
|
2733
2890
|
telemetry,
|
|
2734
2891
|
sendTraces: false,
|
|
2735
2892
|
debug,
|
|
@@ -2884,7 +3041,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
2884
3041
|
if (!mergedCtx.userId) warnMissingUserIdOnce();
|
|
2885
3042
|
const inherited = await getCurrentParentSpanContext();
|
|
2886
3043
|
const eventId = (_c = (_b2 = (_a2 = callTimeCtx.eventId) != null ? _a2 : mergedCtx.eventId) != null ? _b2 : inherited == null ? void 0 : inherited.eventId) != null ? _c : randomUUID();
|
|
2887
|
-
const ctx = { ...mergedCtx};
|
|
3044
|
+
const ctx = { ...mergedCtx, eventId };
|
|
2888
3045
|
const inheritedParent = inherited && inherited.eventId === eventId ? { traceIdB64: inherited.traceIdB64, spanIdB64: inherited.spanIdB64 } : void 0;
|
|
2889
3046
|
const outerOperationId = `ai.${operation}`;
|
|
2890
3047
|
const { operationName, resourceName } = opName(outerOperationId, telemetry == null ? void 0 : telemetry.functionId);
|
|
@@ -2900,17 +3057,17 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
2900
3057
|
attrString("ai.telemetry.functionId", telemetry == null ? void 0 : telemetry.functionId),
|
|
2901
3058
|
attrString("ai.model.provider", modelInfoFromArgs.provider),
|
|
2902
3059
|
attrString("ai.model.id", modelInfoFromArgs.modelId),
|
|
3060
|
+
attrString("ai.telemetry.metadata.raindrop.eventId", eventId),
|
|
3061
|
+
attrString("ai.telemetry.metadata.raindrop.eventName", ctx.eventName),
|
|
3062
|
+
attrString("ai.telemetry.metadata.raindrop.userId", ctx.userId),
|
|
3063
|
+
attrString("ai.telemetry.metadata.raindrop.convoId", ctx.convoId),
|
|
2903
3064
|
...attrsFromTelemetryMetadata(telemetry == null ? void 0 : telemetry.metadata),
|
|
2904
3065
|
...attrsFromHeaders(mergedArgs["headers"]),
|
|
2905
3066
|
...attrsFromSettings(mergedArgs),
|
|
2906
3067
|
...(telemetry == null ? void 0 : telemetry.recordInputs) === false ? [] : [
|
|
2907
3068
|
attrString(
|
|
2908
3069
|
"ai.prompt",
|
|
2909
|
-
safeJsonWithUint8({
|
|
2910
|
-
system: (_d = mergedArgs["system"]) != null ? _d : mergedArgs["instructions"],
|
|
2911
|
-
prompt: mergedArgs["prompt"],
|
|
2912
|
-
messages: mergedArgs["messages"]
|
|
2913
|
-
})
|
|
3070
|
+
safeJsonWithUint8(normalizePromptAttr({ system: (_d = mergedArgs["system"]) != null ? _d : mergedArgs["instructions"], prompt: mergedArgs["prompt"], messages: mergedArgs["messages"] }))
|
|
2914
3071
|
)
|
|
2915
3072
|
]
|
|
2916
3073
|
]
|
|
@@ -2918,6 +3075,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
2918
3075
|
const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
|
|
2919
3076
|
const wrapCtx = {
|
|
2920
3077
|
eventId,
|
|
3078
|
+
context: ctx,
|
|
2921
3079
|
telemetry,
|
|
2922
3080
|
sendTraces,
|
|
2923
3081
|
debug,
|
|
@@ -3091,7 +3249,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
3091
3249
|
if (!mergedCtx.userId) warnMissingUserIdOnce();
|
|
3092
3250
|
const inherited = await getCurrentParentSpanContext();
|
|
3093
3251
|
const eventId = (_c = (_b2 = (_a2 = callTimeCtx.eventId) != null ? _a2 : mergedCtx.eventId) != null ? _b2 : inherited == null ? void 0 : inherited.eventId) != null ? _c : randomUUID();
|
|
3094
|
-
const ctx = { ...mergedCtx};
|
|
3252
|
+
const ctx = { ...mergedCtx, eventId };
|
|
3095
3253
|
const inheritedParent = inherited && inherited.eventId === eventId ? { traceIdB64: inherited.traceIdB64, spanIdB64: inherited.spanIdB64 } : void 0;
|
|
3096
3254
|
const outerOperationId = `ai.${operation}`;
|
|
3097
3255
|
const { operationName, resourceName } = opName(outerOperationId, telemetry == null ? void 0 : telemetry.functionId);
|
|
@@ -3107,17 +3265,17 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
3107
3265
|
attrString("ai.telemetry.functionId", telemetry == null ? void 0 : telemetry.functionId),
|
|
3108
3266
|
attrString("ai.model.provider", modelInfoFromArgs.provider),
|
|
3109
3267
|
attrString("ai.model.id", modelInfoFromArgs.modelId),
|
|
3268
|
+
attrString("ai.telemetry.metadata.raindrop.eventId", eventId),
|
|
3269
|
+
attrString("ai.telemetry.metadata.raindrop.eventName", ctx.eventName),
|
|
3270
|
+
attrString("ai.telemetry.metadata.raindrop.userId", ctx.userId),
|
|
3271
|
+
attrString("ai.telemetry.metadata.raindrop.convoId", ctx.convoId),
|
|
3110
3272
|
...attrsFromTelemetryMetadata(telemetry == null ? void 0 : telemetry.metadata),
|
|
3111
3273
|
...attrsFromHeaders(mergedArgs["headers"]),
|
|
3112
3274
|
...attrsFromSettings(mergedArgs),
|
|
3113
3275
|
...(telemetry == null ? void 0 : telemetry.recordInputs) === false ? [] : [
|
|
3114
3276
|
attrString(
|
|
3115
3277
|
"ai.prompt",
|
|
3116
|
-
safeJsonWithUint8({
|
|
3117
|
-
system: (_d = mergedArgs["system"]) != null ? _d : mergedArgs["instructions"],
|
|
3118
|
-
prompt: mergedArgs["prompt"],
|
|
3119
|
-
messages: mergedArgs["messages"]
|
|
3120
|
-
})
|
|
3278
|
+
safeJsonWithUint8(normalizePromptAttr({ system: (_d = mergedArgs["system"]) != null ? _d : mergedArgs["instructions"], prompt: mergedArgs["prompt"], messages: mergedArgs["messages"] }))
|
|
3121
3279
|
)
|
|
3122
3280
|
]
|
|
3123
3281
|
]
|
|
@@ -3125,6 +3283,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
3125
3283
|
const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
|
|
3126
3284
|
const wrapCtx = {
|
|
3127
3285
|
eventId,
|
|
3286
|
+
context: ctx,
|
|
3128
3287
|
telemetry,
|
|
3129
3288
|
sendTraces,
|
|
3130
3289
|
debug,
|
|
@@ -3348,6 +3507,21 @@ function wrapToolExecute(name, tool, ctx, toolCalls) {
|
|
|
3348
3507
|
});
|
|
3349
3508
|
}
|
|
3350
3509
|
};
|
|
3510
|
+
const sendToolLiveEvent = (parent, type, metadata) => {
|
|
3511
|
+
if (!localDebuggerEnabled() || !parent) return;
|
|
3512
|
+
sendLocalDebuggerLiveEvent({
|
|
3513
|
+
traceId: parent.traceIdB64,
|
|
3514
|
+
type,
|
|
3515
|
+
content: name,
|
|
3516
|
+
metadata: {
|
|
3517
|
+
...getLocalDebuggerMetadata({
|
|
3518
|
+
...ctx.context,
|
|
3519
|
+
eventId: ctx.eventId
|
|
3520
|
+
}),
|
|
3521
|
+
...metadata
|
|
3522
|
+
}
|
|
3523
|
+
});
|
|
3524
|
+
};
|
|
3351
3525
|
const createContextSpan = (span) => ({
|
|
3352
3526
|
traceIdB64: span.ids.traceIdB64,
|
|
3353
3527
|
spanIdB64: span.ids.spanIdB64,
|
|
@@ -3363,6 +3537,7 @@ function wrapToolExecute(name, tool, ctx, toolCalls) {
|
|
|
3363
3537
|
const parentCtx = await getCurrentParentSpanContext();
|
|
3364
3538
|
const parent = parentCtx && parentCtx.eventId === ctx.eventId ? { traceIdB64: parentCtx.traceIdB64, spanIdB64: parentCtx.spanIdB64 } : ctx.rootParentForChildren;
|
|
3365
3539
|
const toolSpan = createToolSpan(toolCallId, toolArgs, parent);
|
|
3540
|
+
sendToolLiveEvent(parent, "tool_start", { args: toolArgs });
|
|
3366
3541
|
try {
|
|
3367
3542
|
let lastValue;
|
|
3368
3543
|
const iterator = result[Symbol.asyncIterator]();
|
|
@@ -3378,9 +3553,13 @@ function wrapToolExecute(name, tool, ctx, toolCalls) {
|
|
|
3378
3553
|
}
|
|
3379
3554
|
toolCalls.push({ id: toolCallId, name, args: toolArgs, result: lastValue, status: "OK" });
|
|
3380
3555
|
endToolSpan(toolSpan, lastValue);
|
|
3556
|
+
sendToolLiveEvent(parent, "tool_result", { result: lastValue });
|
|
3381
3557
|
} catch (error) {
|
|
3382
3558
|
toolCalls.push({ id: toolCallId, name, args: toolArgs, status: "ERROR" });
|
|
3383
3559
|
endToolSpan(toolSpan, void 0, error);
|
|
3560
|
+
sendToolLiveEvent(parent, "tool_result", {
|
|
3561
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3562
|
+
});
|
|
3384
3563
|
throw error;
|
|
3385
3564
|
}
|
|
3386
3565
|
})();
|
|
@@ -3389,6 +3568,7 @@ function wrapToolExecute(name, tool, ctx, toolCalls) {
|
|
|
3389
3568
|
const parentCtx = await getCurrentParentSpanContext();
|
|
3390
3569
|
const parent = parentCtx && parentCtx.eventId === ctx.eventId ? { traceIdB64: parentCtx.traceIdB64, spanIdB64: parentCtx.spanIdB64 } : ctx.rootParentForChildren;
|
|
3391
3570
|
const toolSpan = createToolSpan(toolCallId, toolArgs, parent);
|
|
3571
|
+
sendToolLiveEvent(parent, "tool_start", { args: toolArgs });
|
|
3392
3572
|
const run = async () => {
|
|
3393
3573
|
try {
|
|
3394
3574
|
const awaitedResult = await result;
|
|
@@ -3400,10 +3580,14 @@ function wrapToolExecute(name, tool, ctx, toolCalls) {
|
|
|
3400
3580
|
status: "OK"
|
|
3401
3581
|
});
|
|
3402
3582
|
endToolSpan(toolSpan, awaitedResult);
|
|
3583
|
+
sendToolLiveEvent(parent, "tool_result", { result: awaitedResult });
|
|
3403
3584
|
return awaitedResult;
|
|
3404
3585
|
} catch (error) {
|
|
3405
3586
|
toolCalls.push({ id: toolCallId, name, args: toolArgs, status: "ERROR" });
|
|
3406
3587
|
endToolSpan(toolSpan, void 0, error);
|
|
3588
|
+
sendToolLiveEvent(parent, "tool_result", {
|
|
3589
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3590
|
+
});
|
|
3407
3591
|
throw error;
|
|
3408
3592
|
}
|
|
3409
3593
|
};
|
|
@@ -3443,6 +3627,7 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
3443
3627
|
const original = Reflect.get(target, prop, receiver);
|
|
3444
3628
|
if (prop === "doGenerate" && isFunction(original)) {
|
|
3445
3629
|
return async (...callArgs) => {
|
|
3630
|
+
var _a, _b;
|
|
3446
3631
|
const options = callArgs[0];
|
|
3447
3632
|
const parentCtx = await getCurrentParentSpanContext();
|
|
3448
3633
|
const parent = parentCtx && parentCtx.eventId === ctx.eventId ? { traceIdB64: parentCtx.traceIdB64, spanIdB64: parentCtx.spanIdB64 } : ctx.rootParentForChildren;
|
|
@@ -3450,6 +3635,22 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
3450
3635
|
try {
|
|
3451
3636
|
const result = await original.apply(target, callArgs);
|
|
3452
3637
|
if (span) endDoGenerateSpan(span, result, modelInfo, ctx);
|
|
3638
|
+
if (localDebuggerEnabled() && ctx.rootParentForChildren && isRecord(result)) {
|
|
3639
|
+
const traceId = ctx.rootParentForChildren.traceIdB64;
|
|
3640
|
+
const liveMeta = getLocalDebuggerMetadata({ ...ctx.context, eventId: ctx.eventId });
|
|
3641
|
+
const content = result["content"];
|
|
3642
|
+
if (Array.isArray(content)) {
|
|
3643
|
+
for (const part of content) {
|
|
3644
|
+
if (isRecord(part)) {
|
|
3645
|
+
if ((part["type"] === "reasoning" || part["type"] === "thinking") && typeof ((_a = part["text"]) != null ? _a : part["thinking"]) === "string") {
|
|
3646
|
+
sendLocalDebuggerLiveEvent({ traceId, type: "reasoning_delta", content: (_b = part["text"]) != null ? _b : part["thinking"], metadata: liveMeta });
|
|
3647
|
+
} else if (part["type"] === "text" && typeof part["text"] === "string") {
|
|
3648
|
+
sendLocalDebuggerLiveEvent({ traceId, type: "text_delta", content: part["text"], metadata: liveMeta });
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3453
3654
|
return result;
|
|
3454
3655
|
} catch (error) {
|
|
3455
3656
|
if (span)
|
|
@@ -3589,6 +3790,23 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
3589
3790
|
}
|
|
3590
3791
|
if ("usage" in value) usage = value["usage"];
|
|
3591
3792
|
if ("providerMetadata" in value) providerMetadata = value["providerMetadata"];
|
|
3793
|
+
if (localDebuggerEnabled() && ctx.rootParentForChildren) {
|
|
3794
|
+
const traceId = ctx.rootParentForChildren.traceIdB64;
|
|
3795
|
+
const liveMeta = getLocalDebuggerMetadata({ ...ctx.context, eventId: ctx.eventId });
|
|
3796
|
+
if (type === "text-delta") {
|
|
3797
|
+
const text = typeof value["delta"] === "string" ? value["delta"] : typeof value["textDelta"] === "string" ? value["textDelta"] : typeof value["text"] === "string" ? value["text"] : void 0;
|
|
3798
|
+
if (typeof text === "string" && text) sendLocalDebuggerLiveEvent({ traceId, type: "text_delta", content: text, metadata: liveMeta });
|
|
3799
|
+
} else if (type === "reasoning" || type === "reasoning-delta") {
|
|
3800
|
+
const text = typeof value["delta"] === "string" ? value["delta"] : typeof value["text"] === "string" ? value["text"] : typeof value["thinking"] === "string" ? value["thinking"] : void 0;
|
|
3801
|
+
if (typeof text === "string" && text) sendLocalDebuggerLiveEvent({ traceId, type: "reasoning_delta", content: text, metadata: liveMeta });
|
|
3802
|
+
} else if (type === "tool-call") {
|
|
3803
|
+
const toolName = typeof value["toolName"] === "string" ? value["toolName"] : "tool";
|
|
3804
|
+
sendLocalDebuggerLiveEvent({ traceId, type: "tool_start", content: toolName, metadata: { ...liveMeta, args: value["args"] } });
|
|
3805
|
+
} else if (type === "tool-result") {
|
|
3806
|
+
const toolName = typeof value["toolName"] === "string" ? value["toolName"] : "tool";
|
|
3807
|
+
sendLocalDebuggerLiveEvent({ traceId, type: "tool_result", content: toolName, metadata: { ...liveMeta, result: value["result"] } });
|
|
3808
|
+
}
|
|
3809
|
+
}
|
|
3592
3810
|
}
|
|
3593
3811
|
controller.enqueue(value);
|
|
3594
3812
|
} catch (error) {
|
|
@@ -3789,7 +4007,7 @@ function extractNestedTokens(usage, key) {
|
|
|
3789
4007
|
// package.json
|
|
3790
4008
|
var package_default = {
|
|
3791
4009
|
name: "@raindrop-ai/ai-sdk",
|
|
3792
|
-
version: "0.0.
|
|
4010
|
+
version: "0.0.22"};
|
|
3793
4011
|
|
|
3794
4012
|
// src/internal/version.ts
|
|
3795
4013
|
var libraryName = package_default.name;
|
|
@@ -3861,6 +4079,14 @@ function eventMetadataFromChatRequest(options) {
|
|
|
3861
4079
|
...eventId ? { eventId } : {}
|
|
3862
4080
|
});
|
|
3863
4081
|
}
|
|
4082
|
+
function stringify(v) {
|
|
4083
|
+
if (typeof v === "string") return v;
|
|
4084
|
+
return JSON.stringify(v);
|
|
4085
|
+
}
|
|
4086
|
+
function userAttrsToOtlp(attrs) {
|
|
4087
|
+
if (!attrs) return [];
|
|
4088
|
+
return Object.entries(attrs).map(([key, value]) => attrString(key, value));
|
|
4089
|
+
}
|
|
3864
4090
|
function envDebugEnabled() {
|
|
3865
4091
|
var _a;
|
|
3866
4092
|
if (typeof process === "undefined") return false;
|
|
@@ -3929,6 +4155,76 @@ function createRaindropAISDK(opts) {
|
|
|
3929
4155
|
await eventShipper.finish(eventId, patch);
|
|
3930
4156
|
}
|
|
3931
4157
|
},
|
|
4158
|
+
traces: /* @__PURE__ */ (() => {
|
|
4159
|
+
const openSpans = /* @__PURE__ */ new Map();
|
|
4160
|
+
function toTraceSpan(internal) {
|
|
4161
|
+
return { traceId: internal.ids.traceIdB64, spanId: internal.ids.spanIdB64 };
|
|
4162
|
+
}
|
|
4163
|
+
return {
|
|
4164
|
+
startSpan(args) {
|
|
4165
|
+
const parent = args.parent ? { traceIdB64: args.parent.traceId, spanIdB64: args.parent.spanId } : void 0;
|
|
4166
|
+
const attrs = userAttrsToOtlp(args.attributes);
|
|
4167
|
+
if (args.operationId === "ai.toolCall") {
|
|
4168
|
+
attrs.push(attrString("ai.toolCall.name", args.name));
|
|
4169
|
+
}
|
|
4170
|
+
const internal = traceShipper.startSpan({
|
|
4171
|
+
name: args.name,
|
|
4172
|
+
eventId: args.eventId,
|
|
4173
|
+
parent,
|
|
4174
|
+
operationId: args.operationId,
|
|
4175
|
+
attributes: attrs
|
|
4176
|
+
});
|
|
4177
|
+
const handle = toTraceSpan(internal);
|
|
4178
|
+
openSpans.set(handle.spanId, internal);
|
|
4179
|
+
return handle;
|
|
4180
|
+
},
|
|
4181
|
+
endSpan(span, extra) {
|
|
4182
|
+
const internal = openSpans.get(span.spanId);
|
|
4183
|
+
if (!internal) return;
|
|
4184
|
+
openSpans.delete(span.spanId);
|
|
4185
|
+
const errorValue = extra == null ? void 0 : extra.error;
|
|
4186
|
+
const error = errorValue instanceof Error ? errorValue : typeof errorValue === "string" ? new Error(errorValue) : void 0;
|
|
4187
|
+
traceShipper.endSpan(internal, {
|
|
4188
|
+
attributes: userAttrsToOtlp(extra == null ? void 0 : extra.attributes),
|
|
4189
|
+
error
|
|
4190
|
+
});
|
|
4191
|
+
},
|
|
4192
|
+
createSpan(args) {
|
|
4193
|
+
var _a2;
|
|
4194
|
+
const parent = args.parent ? { traceIdB64: args.parent.traceId, spanIdB64: args.parent.spanId } : void 0;
|
|
4195
|
+
const startMs = (_a2 = args.startTime) != null ? _a2 : Date.now() - args.durationMs;
|
|
4196
|
+
const startAttrs = [...userAttrsToOtlp(args.attributes)];
|
|
4197
|
+
if (args.operationId === "ai.toolCall") {
|
|
4198
|
+
startAttrs.push(attrString("ai.toolCall.name", args.name));
|
|
4199
|
+
}
|
|
4200
|
+
if (args.input !== void 0) startAttrs.push(attrString("traceloop.entity.input", stringify(args.input)));
|
|
4201
|
+
if (args.operationId === "ai.toolCall" && args.input !== void 0) {
|
|
4202
|
+
startAttrs.push(attrString("ai.toolCall.args", stringify(args.input)));
|
|
4203
|
+
}
|
|
4204
|
+
const internal = traceShipper.startSpan({
|
|
4205
|
+
name: args.name,
|
|
4206
|
+
eventId: args.eventId,
|
|
4207
|
+
parent,
|
|
4208
|
+
operationId: args.operationId,
|
|
4209
|
+
attributes: startAttrs,
|
|
4210
|
+
startTimeUnixNano: unixMsToNanoString(startMs)
|
|
4211
|
+
});
|
|
4212
|
+
const endAttrs = [];
|
|
4213
|
+
if (args.output !== void 0) endAttrs.push(attrString("traceloop.entity.output", stringify(args.output)));
|
|
4214
|
+
if (args.operationId === "ai.toolCall" && args.output !== void 0) {
|
|
4215
|
+
endAttrs.push(attrString("ai.toolCall.result", stringify(args.output)));
|
|
4216
|
+
}
|
|
4217
|
+
const errorValue = args.error;
|
|
4218
|
+
const error = errorValue instanceof Error ? errorValue : typeof errorValue === "string" ? new Error(errorValue) : void 0;
|
|
4219
|
+
traceShipper.endSpan(internal, {
|
|
4220
|
+
attributes: endAttrs,
|
|
4221
|
+
error,
|
|
4222
|
+
endTimeUnixNano: unixMsToNanoString(startMs + args.durationMs)
|
|
4223
|
+
});
|
|
4224
|
+
return toTraceSpan(internal);
|
|
4225
|
+
}
|
|
4226
|
+
};
|
|
4227
|
+
})(),
|
|
3932
4228
|
users: {
|
|
3933
4229
|
async identify(users) {
|
|
3934
4230
|
await eventShipper.identify(users);
|