@raindrop-ai/ai-sdk 0.3.1 → 0.3.3

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.
@@ -1,6 +1,635 @@
1
1
  'use strict';
2
2
 
3
- // ../core/dist/chunk-3V4MIA75.js
3
+ // ../core/dist/chunk-BYBMRLZM.js
4
+ var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
5
+ var PROBE_SCOPE = { correlationId: "" };
6
+ var EvalScopeStorage = class {
7
+ constructor() {
8
+ this._als = null;
9
+ this._probed = false;
10
+ }
11
+ maybeAdoptAsyncLocalStorage() {
12
+ if (this._probed) return;
13
+ this._probed = true;
14
+ try {
15
+ const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
16
+ if (!Ctor) return;
17
+ const als = new Ctor();
18
+ als.run(PROBE_SCOPE, () => {
19
+ });
20
+ this._als = als;
21
+ } catch (e) {
22
+ this._als = null;
23
+ }
24
+ }
25
+ run(scope, callback) {
26
+ this.maybeAdoptAsyncLocalStorage();
27
+ if (this._als) return this._als.run(scope, callback);
28
+ const previous = this._syncScope;
29
+ this._syncScope = scope;
30
+ try {
31
+ return callback();
32
+ } finally {
33
+ this._syncScope = previous;
34
+ }
35
+ }
36
+ current() {
37
+ this.maybeAdoptAsyncLocalStorage();
38
+ if (this._als) return this._als.getStore();
39
+ return this._syncScope;
40
+ }
41
+ };
42
+ var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
43
+ function evalScopeStorage() {
44
+ const holder = globalThis;
45
+ let storage = holder[EVAL_SCOPE_STORAGE_KEY];
46
+ if (!storage) {
47
+ storage = new EvalScopeStorage();
48
+ holder[EVAL_SCOPE_STORAGE_KEY] = storage;
49
+ }
50
+ return storage;
51
+ }
52
+ function currentEvalScope() {
53
+ try {
54
+ return evalScopeStorage().current();
55
+ } catch (e) {
56
+ return void 0;
57
+ }
58
+ }
59
+ function evalScopeAttributes() {
60
+ const scope = currentEvalScope();
61
+ if (!scope) return {};
62
+ return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
63
+ }
64
+
65
+ // ../core/dist/chunk-WJOR6M7H.js
66
+ var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
67
+ function state() {
68
+ const holder = globalThis;
69
+ let current = holder[STATE_KEY];
70
+ if (!current) {
71
+ let storage = null;
72
+ try {
73
+ const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
74
+ if (Ctor) storage = new Ctor();
75
+ } catch (e) {
76
+ storage = null;
77
+ }
78
+ current = {
79
+ storage,
80
+ syncDestination: void 0,
81
+ spanDestinations: /* @__PURE__ */ new WeakMap()
82
+ };
83
+ holder[STATE_KEY] = current;
84
+ }
85
+ return current;
86
+ }
87
+ function currentReplayTraceDestination() {
88
+ var _a, _b;
89
+ const routing = state();
90
+ return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
91
+ }
92
+ function rememberReplayTraceDestination(span) {
93
+ const destination = currentReplayTraceDestination();
94
+ if (destination) state().spanDestinations.set(span, destination);
95
+ }
96
+ function copyReplayTraceDestination(source, target) {
97
+ const destination = state().spanDestinations.get(source);
98
+ if (destination) state().spanDestinations.set(target, destination);
99
+ }
100
+ function replayTraceDestinationFor(value) {
101
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
102
+ return void 0;
103
+ }
104
+ return state().spanDestinations.get(value);
105
+ }
106
+ function recordReplayExportedSpan(destination, spanId, traceId) {
107
+ var _a, _b;
108
+ if (!destination || !spanId || !traceId) return;
109
+ (_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
110
+ (_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
111
+ }
112
+ function replayTraceUrl(baseUrl) {
113
+ return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
114
+ }
115
+ var NOOP_SPAN = {
116
+ traceIdB64: "",
117
+ spanIdB64: "",
118
+ eventId: "",
119
+ log() {
120
+ }
121
+ };
122
+ function getAsyncLocalStorageCtor() {
123
+ return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
124
+ }
125
+ var SynchronousContextStorage = class {
126
+ constructor() {
127
+ this._stack = [];
128
+ }
129
+ isEmpty() {
130
+ return this._stack.length === 0;
131
+ }
132
+ getStore() {
133
+ return this._stack[this._stack.length - 1];
134
+ }
135
+ run(store, callback) {
136
+ this._stack.push(store);
137
+ try {
138
+ return callback();
139
+ } finally {
140
+ this._stack.pop();
141
+ }
142
+ }
143
+ };
144
+ var ContextManager = class {
145
+ };
146
+ var RaindropContextManager = class extends ContextManager {
147
+ constructor() {
148
+ super();
149
+ this._fallback = null;
150
+ const Ctor = getAsyncLocalStorageCtor();
151
+ if (Ctor) {
152
+ this._storage = new Ctor();
153
+ return;
154
+ }
155
+ this._fallback = new SynchronousContextStorage();
156
+ this._storage = this._fallback;
157
+ }
158
+ maybeAdoptAsyncLocalStorage() {
159
+ if (!this._fallback || !this._fallback.isEmpty()) return;
160
+ const Ctor = getAsyncLocalStorageCtor();
161
+ if (!Ctor) return;
162
+ this._storage = new Ctor();
163
+ this._fallback = null;
164
+ }
165
+ isReady() {
166
+ return true;
167
+ }
168
+ getParentSpanIds() {
169
+ this.maybeAdoptAsyncLocalStorage();
170
+ const span = this._storage.getStore();
171
+ if (!span || span === NOOP_SPAN) return void 0;
172
+ return {
173
+ traceIdB64: span.traceIdB64,
174
+ spanIdB64: span.spanIdB64,
175
+ eventId: span.eventId
176
+ };
177
+ }
178
+ runInContext(span, callback) {
179
+ this.maybeAdoptAsyncLocalStorage();
180
+ return this._storage.run(span, callback);
181
+ }
182
+ getCurrentSpan() {
183
+ this.maybeAdoptAsyncLocalStorage();
184
+ return this._storage.getStore();
185
+ }
186
+ };
187
+ var _contextManager = null;
188
+ function getContextManager() {
189
+ if (!_contextManager) {
190
+ _contextManager = globalThis.RAINDROP_CONTEXT_MANAGER ? new globalThis.RAINDROP_CONTEXT_MANAGER() : new RaindropContextManager();
191
+ }
192
+ return _contextManager;
193
+ }
194
+ function currentSpan() {
195
+ var _a;
196
+ return (_a = getContextManager().getCurrentSpan()) != null ? _a : NOOP_SPAN;
197
+ }
198
+ function withCurrent(span, callback) {
199
+ return getContextManager().runInContext(span, callback);
200
+ }
201
+ async function getCurrentParentSpanContext() {
202
+ var _a, _b;
203
+ return (_b = getContextManager().getParentSpanIds()) != null ? _b : (_a = currentReplayTraceDestination()) == null ? void 0 : _a.parentSpanContext;
204
+ }
205
+ async function runWithParentSpanContext(ctx, fn) {
206
+ const cm = getContextManager();
207
+ const span = {
208
+ traceIdB64: ctx.traceIdB64,
209
+ spanIdB64: ctx.spanIdB64,
210
+ eventId: ctx.eventId
211
+ };
212
+ return cm.runInContext(span, fn);
213
+ }
214
+ async function* asyncGeneratorWithCurrent(span, gen) {
215
+ let nextValue;
216
+ while (true) {
217
+ const result = await withCurrent(span, async () => {
218
+ try {
219
+ return await gen.next(nextValue);
220
+ } catch (e) {
221
+ return { value: void 0, done: true, error: e };
222
+ }
223
+ });
224
+ if ("error" in result && result.error !== void 0) {
225
+ throw result.error;
226
+ }
227
+ if (result.done) {
228
+ return result.value;
229
+ }
230
+ nextValue = yield result.value;
231
+ }
232
+ }
233
+ var MAX_BINDING_STACK = 128;
234
+ var EMPTY_STACK = [];
235
+ var ContextStackStorage = class {
236
+ /** Emitted once when this runtime cannot support an ambient push. */
237
+ constructor(noAmbientBindWarning) {
238
+ this.noAmbientBindWarning = noAmbientBindWarning;
239
+ this._als = null;
240
+ this._enterWithUsable = false;
241
+ this._syncStack = EMPTY_STACK;
242
+ this._adoptionChecked = false;
243
+ this._warnedNoAmbientBind = false;
244
+ }
245
+ maybeAdoptAsyncLocalStorage() {
246
+ if (this._adoptionChecked) return;
247
+ this._adoptionChecked = true;
248
+ const Ctor = getAsyncLocalStorageCtor();
249
+ if (!Ctor) return;
250
+ const als = new Ctor();
251
+ try {
252
+ als.run(EMPTY_STACK, () => {
253
+ });
254
+ } catch (e) {
255
+ return;
256
+ }
257
+ this._als = als;
258
+ if (typeof als.enterWith === "function") {
259
+ try {
260
+ als.enterWith(EMPTY_STACK);
261
+ this._enterWithUsable = true;
262
+ } catch (e) {
263
+ this._enterWithUsable = false;
264
+ }
265
+ }
266
+ }
267
+ getStack() {
268
+ var _a;
269
+ this.maybeAdoptAsyncLocalStorage();
270
+ if (this._als) return (_a = this._als.getStore()) != null ? _a : this._syncStack;
271
+ return this._syncStack;
272
+ }
273
+ /**
274
+ * Persist an ambient stack mutation. Returns false when an ALS is adopted but
275
+ * `enterWith` is unusable (workerd): callers must NOT fall back to the
276
+ * process-shared sync stack, since concurrent isolates would cross-stamp.
277
+ */
278
+ setAmbientStack(stack) {
279
+ if (this._als) {
280
+ if (!this._enterWithUsable) return false;
281
+ this._als.enterWith(stack);
282
+ return true;
283
+ }
284
+ this._syncStack = stack;
285
+ return true;
286
+ }
287
+ push(binding) {
288
+ this.maybeAdoptAsyncLocalStorage();
289
+ if (this._als && !this._enterWithUsable) {
290
+ this.warnNoAmbientBindOnce();
291
+ return;
292
+ }
293
+ let stack = this.getStack();
294
+ if (stack.length >= MAX_BINDING_STACK) {
295
+ stack = stack.filter((b) => b.isLive());
296
+ if (stack.length >= MAX_BINDING_STACK) {
297
+ stack = stack.slice(stack.length - (MAX_BINDING_STACK - 1));
298
+ }
299
+ }
300
+ this.setAmbientStack([...stack, binding]);
301
+ }
302
+ remove(binding) {
303
+ binding.markDead();
304
+ const stack = this.getStack();
305
+ const pruned = stack.filter((b) => b !== binding && b.isLive());
306
+ if (pruned.length !== stack.length) {
307
+ this.setAmbientStack(pruned);
308
+ }
309
+ }
310
+ runWith(binding, callback) {
311
+ this.maybeAdoptAsyncLocalStorage();
312
+ if (this._als) {
313
+ return this._als.run([...this.getStack(), binding], callback);
314
+ }
315
+ const previous = this._syncStack;
316
+ this._syncStack = [...previous, binding];
317
+ try {
318
+ return callback();
319
+ } finally {
320
+ this._syncStack = previous;
321
+ }
322
+ }
323
+ current() {
324
+ const stack = this.getStack();
325
+ if (stack.length === 0) return void 0;
326
+ const top = stack[stack.length - 1];
327
+ if (top.isLive()) return top;
328
+ const pruned = stack.filter((b) => b.isLive());
329
+ this.setAmbientStack(pruned);
330
+ return pruned.length > 0 ? pruned[pruned.length - 1] : void 0;
331
+ }
332
+ warnNoAmbientBindOnce() {
333
+ if (this._warnedNoAmbientBind) return;
334
+ this._warnedNoAmbientBind = true;
335
+ console.warn(this.noAmbientBindWarning);
336
+ }
337
+ };
338
+ var NO_AMBIENT_ROUTING_BIND_WARNING = "[raindrop] This runtime's AsyncLocalStorage does not implement enterWith (e.g. Cloudflare Workers), so begin()/finish() cannot scope auto-instrumented spans to a project without cross-contaminating concurrent requests. Manual events and explicit span routing are unaffected; use asCurrent()/withSpan (run-based) to route auto-instrumented spans on this runtime.";
339
+ var ROUTING_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.routingContextStorage");
340
+ function routingStorage() {
341
+ const holder = globalThis;
342
+ let storage = holder[ROUTING_STORAGE_KEY];
343
+ if (!storage) {
344
+ storage = new ContextStackStorage(NO_AMBIENT_ROUTING_BIND_WARNING);
345
+ holder[ROUTING_STORAGE_KEY] = storage;
346
+ }
347
+ return storage;
348
+ }
349
+ function currentRoutingBinding() {
350
+ const bound = routingStorage().current();
351
+ if (!bound) return void 0;
352
+ return {
353
+ projectId: bound.projectId,
354
+ authHint: bound.authHint,
355
+ ...bound.appGit ? { appGit: bound.appGit } : {},
356
+ ...bound.appGitSource ? { appGitSource: bound.appGitSource } : {}
357
+ };
358
+ }
359
+ var APP_COMMIT_SHA = "raindrop.app.commit_sha";
360
+ var APP_COMMIT_DIRTY = "raindrop.app.commit_dirty";
361
+ var APP_BRANCH = "raindrop.app.branch";
362
+ var APP_GIT_KEYS = [APP_COMMIT_SHA, APP_COMMIT_DIRTY, APP_BRANCH];
363
+ var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
364
+ function appGitExplicitKeys(properties) {
365
+ const keys = /* @__PURE__ */ new Set();
366
+ if (!properties) return keys;
367
+ for (const key of APP_GIT_KEYS) {
368
+ if (own(properties, key)) keys.add(key);
369
+ }
370
+ return keys;
371
+ }
372
+ function mergeAppGitSnapshot(base, properties, explicitKeys = /* @__PURE__ */ new Set()) {
373
+ try {
374
+ const result = { ...base };
375
+ if (properties && own(properties, APP_COMMIT_SHA) && properties[APP_COMMIT_SHA] !== result[APP_COMMIT_SHA]) {
376
+ if (!explicitKeys.has(APP_COMMIT_DIRTY) && !own(properties, APP_COMMIT_DIRTY)) {
377
+ delete result[APP_COMMIT_DIRTY];
378
+ }
379
+ if (!explicitKeys.has(APP_BRANCH) && !own(properties, APP_BRANCH)) {
380
+ delete result[APP_BRANCH];
381
+ }
382
+ }
383
+ for (const key of APP_GIT_KEYS) {
384
+ if (properties && own(properties, key)) result[key] = properties[key];
385
+ }
386
+ return Object.freeze(result);
387
+ } catch (e) {
388
+ return Object.freeze({});
389
+ }
390
+ }
391
+ function validAppCommitSha(value) {
392
+ if (typeof value !== "string" || value.length > 128) return void 0;
393
+ const cleaned = value.trim();
394
+ return /^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/.test(cleaned) ? cleaned.toLowerCase() : void 0;
395
+ }
396
+ function shortString(value) {
397
+ if (typeof value !== "string" || value.length > 1024) return void 0;
398
+ const cleaned = value.trim();
399
+ return cleaned.length > 0 ? cleaned : void 0;
400
+ }
401
+ function flag(value) {
402
+ if (value === true || value === "true" || value === "1") return true;
403
+ if (value === false || value === "false" || value === "0") return false;
404
+ return void 0;
405
+ }
406
+ function environment() {
407
+ try {
408
+ return typeof process === "undefined" ? {} : process.env;
409
+ } catch (e) {
410
+ return {};
411
+ }
412
+ }
413
+ var DEPLOYMENTS = [
414
+ ["VERCEL", "VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF"],
415
+ ["NETLIFY", "COMMIT_REF", "BRANCH"],
416
+ ["RAILWAY_ENVIRONMENT_NAME", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
417
+ ["RAILWAY_ENVIRONMENT", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
418
+ ["RENDER", "RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH"],
419
+ ["DYNO", "HEROKU_BUILD_COMMIT", ""],
420
+ ["DYNO", "HEROKU_SLUG_COMMIT", ""],
421
+ ["AWS_APP_ID", "AWS_COMMIT_ID", "AWS_BRANCH"],
422
+ ["WORKERS_CI", "WORKERS_CI_COMMIT_SHA", "WORKERS_CI_BRANCH"]
423
+ ];
424
+ var CI_SOURCES = [
425
+ ["GITHUB_ACTIONS", "GITHUB_SHA", "GITHUB_REF_NAME"],
426
+ ["GITLAB_CI", "CI_COMMIT_SHA", "CI_COMMIT_REF_NAME"],
427
+ ["CIRCLECI", "CIRCLE_SHA1", "CIRCLE_BRANCH"]
428
+ ];
429
+ function detectedSource(env, table, detectBranch) {
430
+ for (const row of table) {
431
+ const [marker, shaKey, branchKey] = row;
432
+ if (!marker || !shaKey || !shortString(env[marker]) || flag(env[marker]) === false) continue;
433
+ const commitSha = validAppCommitSha(env[shaKey]);
434
+ if (commitSha)
435
+ return {
436
+ commitSha,
437
+ ...detectBranch && branchKey ? { branch: shortString(env[branchKey]) } : {}
438
+ };
439
+ }
440
+ return {};
441
+ }
442
+ var AppGitContextImpl = class {
443
+ constructor(options, runtime = {}) {
444
+ this.defaults = {};
445
+ this.explicit = {};
446
+ this.explicitKeys = /* @__PURE__ */ new Set();
447
+ this.disposed = false;
448
+ this.operations = /* @__PURE__ */ new Map();
449
+ this.operationOverflow = false;
450
+ this.detectBranch = false;
451
+ this.disabled = false;
452
+ var _a, _b, _c, _d, _e, _f;
453
+ try {
454
+ if (options === false) {
455
+ this.disabled = true;
456
+ return;
457
+ }
458
+ const opts = options != null ? options : {};
459
+ const env = (_a = runtime.env) != null ? _a : environment();
460
+ const detectBranch = (_c = (_b = flag(opts.detectBranch)) != null ? _b : flag(env.RAINDROP_GIT_DETECT_BRANCH)) != null ? _c : false;
461
+ this.detectBranch = detectBranch;
462
+ const collectBranch = detectBranch || runtime.captureLegacyReplayBranch === true;
463
+ const autoDetect = runtime.allowDiscovery === false ? false : (_e = (_d = flag(opts.autoDetect)) != null ? _d : flag(env.RAINDROP_GIT_AUTO_DETECT)) != null ? _e : true;
464
+ const configuredSha = opts.commitSha;
465
+ const explicitSha = configuredSha === void 0 ? env.RAINDROP_COMMIT_SHA : configuredSha;
466
+ if (explicitSha === null) this.explicit[APP_COMMIT_SHA] = null;
467
+ else if (typeof explicitSha === "string" && validAppCommitSha(explicitSha))
468
+ this.explicit[APP_COMMIT_SHA] = explicitSha;
469
+ const configuredDirty = opts.commitDirty;
470
+ const explicitDirty = configuredDirty === void 0 ? flag(env.RAINDROP_COMMIT_DIRTY) : configuredDirty;
471
+ if (explicitDirty === null || typeof explicitDirty === "boolean")
472
+ this.explicit[APP_COMMIT_DIRTY] = explicitDirty;
473
+ const configuredBranch = opts.branch;
474
+ const explicitBranch = configuredBranch === void 0 ? env.RAINDROP_BRANCH : configuredBranch;
475
+ if (explicitBranch === null) this.explicit[APP_BRANCH] = null;
476
+ else if (typeof explicitBranch === "string" && explicitBranch.length <= 1024)
477
+ this.explicit[APP_BRANCH] = explicitBranch;
478
+ this.explicitKeys = appGitExplicitKeys(this.explicit);
479
+ this.defaults = { ...this.explicit };
480
+ if (!autoDetect || explicitSha !== void 0) return;
481
+ const sourceDirectory = (_f = shortString(opts.sourceDirectory)) != null ? _f : shortString(env.RAINDROP_GIT_SOURCE_DIRECTORY);
482
+ if (runtime.allowLocalGit === false && !sourceDirectory) return;
483
+ const deploy = sourceDirectory ? {} : detectedSource(env, DEPLOYMENTS, collectBranch);
484
+ if (deploy.commitSha) {
485
+ this.accept(deploy);
486
+ return;
487
+ }
488
+ const fallback = sourceDirectory ? {} : detectedSource(env, CI_SOURCES, collectBranch);
489
+ if (runtime.resolveLocal && (runtime.allowLocalGit !== false || sourceDirectory)) {
490
+ this.cancel = runtime.resolveLocal(sourceDirectory, collectBranch, (result) => {
491
+ try {
492
+ if (!this.disposed) this.accept(result.commitSha ? result : fallback);
493
+ } catch (e) {
494
+ }
495
+ });
496
+ } else this.accept(fallback);
497
+ } catch (e) {
498
+ }
499
+ }
500
+ accept(result) {
501
+ const sha = validAppCommitSha(result.commitSha);
502
+ if (!sha) return;
503
+ this.replayBranch = shortString(result.branch);
504
+ this.defaults = {
505
+ [APP_COMMIT_SHA]: sha,
506
+ ...typeof result.commitDirty === "boolean" ? { [APP_COMMIT_DIRTY]: result.commitDirty } : {},
507
+ ...this.detectBranch && this.replayBranch ? { [APP_BRANCH]: this.replayBranch } : {},
508
+ ...this.explicit
509
+ };
510
+ }
511
+ snapshot(properties) {
512
+ var _a;
513
+ try {
514
+ const binding = currentRoutingBinding();
515
+ const base = this.disabled && (binding == null ? void 0 : binding.appGitSource) !== "replay-override" ? {} : (_a = binding == null ? void 0 : binding.appGit) != null ? _a : this.defaults;
516
+ return this.mergeSnapshot(base, properties);
517
+ } catch (e) {
518
+ return Object.freeze({});
519
+ }
520
+ }
521
+ /** Safe defaults when no operation/span start was observed; never infer identity. */
522
+ snapshotExplicit(properties, eventId) {
523
+ try {
524
+ const base = { ...this.explicit };
525
+ const operation = eventId ? this.operations.get(eventId) : void 0;
526
+ if (operation) {
527
+ for (const key of operation.explicitKeys) base[key] = operation.snapshot[key];
528
+ }
529
+ return this.mergeSnapshot(base, properties, new Set(Object.keys(base)));
530
+ } catch (e) {
531
+ return mergeAppGitSnapshot({}, properties);
532
+ }
533
+ }
534
+ /** Existing replay branch reporting stays separate from opt-in event properties. */
535
+ snapshotForReplay() {
536
+ const snapshot = this.snapshot();
537
+ if (this.replayBranch && !own(snapshot, APP_BRANCH) && snapshot[APP_COMMIT_SHA] === this.defaults[APP_COMMIT_SHA]) {
538
+ return Object.freeze({ ...snapshot, [APP_BRANCH]: this.replayBranch });
539
+ }
540
+ return snapshot;
541
+ }
542
+ /** Merge a frozen span snapshot without losing client-authored provenance. */
543
+ mergeSnapshot(base, properties, explicitKeys = this.explicitKeys) {
544
+ return mergeAppGitSnapshot(base, properties, /* @__PURE__ */ new Set([...this.explicitKeys, ...explicitKeys]));
545
+ }
546
+ /** Shippers belonging to one client share this bounded operation registry. */
547
+ forOperation(eventId, properties, owner) {
548
+ if (!eventId) return this.snapshot(properties);
549
+ let operation = this.operations.get(eventId);
550
+ if (!operation) {
551
+ if (this.operations.size >= 1e4) this.operationOverflow = true;
552
+ if (this.operationOverflow) return this.mergeSnapshot({}, properties);
553
+ operation = {
554
+ snapshot: this.snapshot(properties),
555
+ owners: /* @__PURE__ */ new Set(),
556
+ unowned: owner === void 0,
557
+ explicitKeys: appGitExplicitKeys(properties)
558
+ };
559
+ this.operations.set(eventId, operation);
560
+ } else if (properties && APP_GIT_KEYS.some((key) => own(properties, key))) {
561
+ const explicitKeys = /* @__PURE__ */ new Set([...this.explicitKeys, ...operation.explicitKeys]);
562
+ operation.snapshot = this.mergeSnapshot(operation.snapshot, properties, explicitKeys);
563
+ for (const key of appGitExplicitKeys(properties)) operation.explicitKeys.add(key);
564
+ }
565
+ if (!owner) operation.unowned = true;
566
+ if (owner) operation.owners.add(owner);
567
+ return operation.snapshot;
568
+ }
569
+ releaseOperation(eventId, owner) {
570
+ const operation = this.operations.get(eventId);
571
+ if (!operation) return;
572
+ operation.owners.delete(owner);
573
+ if (operation.owners.size === 0 && !operation.unowned) this.operations.delete(eventId);
574
+ }
575
+ finishOperation(eventId) {
576
+ this.operations.delete(eventId);
577
+ }
578
+ dispose() {
579
+ var _a;
580
+ this.disposed = true;
581
+ try {
582
+ (_a = this.cancel) == null ? void 0 : _a.call(this);
583
+ } catch (e) {
584
+ }
585
+ }
586
+ };
587
+ var AppGitContext = AppGitContextImpl;
588
+ function createAppGitContext(options, runtime = {}) {
589
+ return new AppGitContext(options, runtime);
590
+ }
591
+ function withAppGitProperties(properties, snapshot) {
592
+ try {
593
+ const merged = { ...properties };
594
+ for (const key of APP_GIT_KEYS)
595
+ if (!own(merged, key) && own(snapshot, key)) merged[key] = snapshot[key];
596
+ return merged;
597
+ } catch (e) {
598
+ return properties != null ? properties : {};
599
+ }
600
+ }
601
+ function withAppGitAttributes(attributes, snapshot) {
602
+ try {
603
+ const present = new Set(attributes.flatMap((attr) => attr ? [attr.key] : []));
604
+ const added = [];
605
+ for (const key of APP_GIT_KEYS) {
606
+ if (present.has(key) || present.has(`ai.telemetry.metadata.${key}`) || present.has(`traceloop.association.properties.${key}`))
607
+ continue;
608
+ const value = snapshot[key];
609
+ if (typeof value === "string") added.push({ key, value: { stringValue: value } });
610
+ else if (typeof value === "boolean") added.push({ key, value: { boolValue: value } });
611
+ }
612
+ return added.length ? [...attributes, ...added] : attributes;
613
+ } catch (e) {
614
+ return attributes;
615
+ }
616
+ }
617
+ function appGitPropertiesFromAttributes(attributes) {
618
+ var _a, _b, _c;
619
+ const properties = {};
620
+ try {
621
+ for (const attr of attributes) {
622
+ if (!attr) continue;
623
+ for (const key of APP_GIT_KEYS) {
624
+ if (attr.key === key || attr.key === `ai.telemetry.metadata.${key}` || attr.key === `traceloop.association.properties.${key}`) {
625
+ properties[key] = (_c = (_b = (_a = attr.value.stringValue) != null ? _a : attr.value.boolValue) != null ? _b : attr.value.intValue) != null ? _c : null;
626
+ }
627
+ }
628
+ }
629
+ } catch (e) {
630
+ }
631
+ return properties;
632
+ }
4
633
  function normalizeFeatureFlags(input) {
5
634
  if (Array.isArray(input)) {
6
635
  return Object.fromEntries(input.map((name) => [name, "true"]));
@@ -495,6 +1124,7 @@ async function postJson(url, body, headers, opts) {
495
1124
  const resp = await runWithTracingSuppressed(
496
1125
  () => fetch(url, {
497
1126
  method: "POST",
1127
+ redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
498
1128
  headers: {
499
1129
  "Content-Type": "application/json",
500
1130
  ...headers
@@ -683,31 +1313,36 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
683
1313
  function localDebuggerEnabled(baseUrl) {
684
1314
  return resolveLocalDebuggerBaseUrl(baseUrl) !== null;
685
1315
  }
1316
+ var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
686
1317
  function mirrorTraceExportToLocalDebugger(body, options = {}) {
687
1318
  var _a;
688
1319
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
689
- if (!baseUrl) return;
690
- void postJson(`${baseUrl}traces`, body, {}, {
1320
+ if (!baseUrl) return Promise.resolve();
1321
+ return postJson(`${baseUrl}traces`, body, {}, {
691
1322
  maxAttempts: 1,
692
1323
  debug: (_a = options.debug) != null ? _a : false,
693
- sdkName: options.sdkName
1324
+ sdkName: options.sdkName,
1325
+ timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
694
1326
  }).catch(() => {
695
1327
  });
696
1328
  }
697
1329
  function mirrorPartialEventToLocalDebugger(event, options = {}) {
698
1330
  var _a;
699
1331
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
700
- if (!baseUrl) return;
1332
+ if (!baseUrl) return Promise.resolve();
701
1333
  const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
702
- void postJson(`${baseUrl}events/track_partial`, event, headers, {
1334
+ return postJson(`${baseUrl}events/track_partial`, event, headers, {
703
1335
  maxAttempts: 1,
704
1336
  debug: (_a = options.debug) != null ? _a : false,
705
- sdkName: options.sdkName
1337
+ sdkName: options.sdkName,
1338
+ timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
706
1339
  }).catch(() => {
707
1340
  });
708
1341
  }
709
1342
  function sendLocalDebuggerLiveEvent(event, options = {}) {
710
1343
  var _a, _b;
1344
+ const destination = currentReplayTraceDestination();
1345
+ if (destination && destination.kind !== "workshop") return;
711
1346
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
712
1347
  if (!baseUrl) return;
713
1348
  void postJson(
@@ -747,6 +1382,13 @@ function projectIdHeaders(projectId) {
747
1382
  }
748
1383
  var SHUTDOWN_DEADLINE_MS = 1e4;
749
1384
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
1385
+ function appGitOwnerId(prefix) {
1386
+ try {
1387
+ return `${prefix}:${randomUUID()}`;
1388
+ } catch (e) {
1389
+ return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
1390
+ }
1391
+ }
750
1392
  function mergePatches(target, source) {
751
1393
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
752
1394
  const out = { ...target, ...source };
@@ -796,22 +1438,25 @@ function eventTelemetryProperties(patch) {
796
1438
  }
797
1439
  var EventShipper = class {
798
1440
  constructor(opts) {
1441
+ this.appGitOwner = appGitOwnerId("event");
799
1442
  this.buffers = /* @__PURE__ */ new Map();
800
1443
  this.sticky = /* @__PURE__ */ new Map();
801
1444
  this.timers = /* @__PURE__ */ new Map();
802
1445
  this.inFlight = /* @__PURE__ */ new Set();
803
1446
  this.hasShutdown = false;
804
- var _a, _b, _c, _d, _e, _f, _g, _h;
805
- this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
806
- this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
1447
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1448
+ this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
1449
+ this.ownsAppGitContext = opts.appGitContext === void 0;
1450
+ this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
1451
+ this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
807
1452
  this.enabled = opts.enabled !== false;
808
1453
  this.debug = opts.debug;
809
- this.partialFlushMs = (_c = opts.partialFlushMs) != null ? _c : 1e3;
810
- this.sdkName = (_d = opts.sdkName) != null ? _d : "core";
1454
+ this.partialFlushMs = (_d = opts.partialFlushMs) != null ? _d : 1e3;
1455
+ this.sdkName = (_e = opts.sdkName) != null ? _e : "core";
811
1456
  this.prefix = `[raindrop-ai/${this.sdkName}]`;
812
- this.defaultEventName = (_e = opts.defaultEventName) != null ? _e : "ai_generation";
1457
+ this.defaultEventName = (_f = opts.defaultEventName) != null ? _f : "ai_generation";
813
1458
  this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
814
- this.localDebuggerUrl = (_f = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _f : void 0;
1459
+ this.localDebuggerUrl = (_g = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _g : void 0;
815
1460
  if (this.debug && this.localDebuggerUrl) {
816
1461
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
817
1462
  }
@@ -822,8 +1467,8 @@ var EventShipper = class {
822
1467
  const isNode = typeof process !== "undefined" && typeof process.version === "string";
823
1468
  this.context = {
824
1469
  library: {
825
- name: (_g = opts.libraryName) != null ? _g : "@raindrop-ai/core",
826
- version: (_h = opts.libraryVersion) != null ? _h : "0.0.0"
1470
+ name: (_h = opts.libraryName) != null ? _h : "@raindrop-ai/core",
1471
+ version: (_i = opts.libraryVersion) != null ? _i : "0.0.0"
827
1472
  },
828
1473
  metadata: {
829
1474
  jsRuntime: isNode ? "node" : "web",
@@ -831,6 +1476,9 @@ var EventShipper = class {
831
1476
  }
832
1477
  };
833
1478
  }
1479
+ ownAppGitContextForShutdown() {
1480
+ this.ownsAppGitContext = true;
1481
+ }
834
1482
  isDebugEnabled() {
835
1483
  return this.debug;
836
1484
  }
@@ -879,6 +1527,15 @@ var EventShipper = class {
879
1527
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
880
1528
  if (!this.enabled) return;
881
1529
  if (!eventId || !eventId.trim()) return;
1530
+ const capturedSticky = this.sticky.get(eventId);
1531
+ const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
1532
+ const destination = currentReplayTraceDestination();
1533
+ const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
1534
+ if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
1535
+ if (patch.isPending === false) this.sticky.delete(eventId);
1536
+ else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
1537
+ return;
1538
+ }
882
1539
  const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
883
1540
  if (typeof patch.input === "string" && patch.input.length > maxChars) {
884
1541
  patch = { ...patch, input: capText(patch.input, maxChars) };
@@ -900,6 +1557,13 @@ var EventShipper = class {
900
1557
  }
901
1558
  const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
902
1559
  const existing = (_d = this.buffers.get(eventId)) != null ? _d : {};
1560
+ patch = {
1561
+ ...patch,
1562
+ properties: withAppGitProperties(
1563
+ patch.properties,
1564
+ this.appGitContext.forOperation(eventId, patch.properties, this.appGitOwner)
1565
+ )
1566
+ };
903
1567
  const merged = mergePatches(existing, patch);
904
1568
  merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
905
1569
  this.buffers.set(eventId, merged);
@@ -913,6 +1577,8 @@ var EventShipper = class {
913
1577
  if (t) clearTimeout(t);
914
1578
  if (merged.isPending === false) {
915
1579
  await this.flushOne(eventId);
1580
+ if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
1581
+ else this.appGitContext.finishOperation(eventId);
916
1582
  return;
917
1583
  }
918
1584
  const timeout = setTimeout(() => {
@@ -937,15 +1603,21 @@ var EventShipper = class {
937
1603
  try {
938
1604
  for (const t of this.timers.values()) clearTimeout(t);
939
1605
  this.timers.clear();
1606
+ for (const [eventId, sticky] of this.sticky) {
1607
+ if (sticky.replayOnly) this.sticky.delete(eventId);
1608
+ }
940
1609
  const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
941
1610
  if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
942
1611
  } finally {
943
1612
  this.shutdownDeadlineAt = void 0;
1613
+ if (this.ownsAppGitContext) this.appGitContext.dispose();
944
1614
  }
945
1615
  }
946
1616
  async trackSignal(signal) {
947
1617
  var _a, _b;
948
1618
  if (!this.enabled) return;
1619
+ const destination = currentReplayTraceDestination();
1620
+ if (destination && destination.kind !== "workshop") return;
949
1621
  const body = [
950
1622
  {
951
1623
  event_id: signal.eventId,
@@ -980,6 +1652,8 @@ var EventShipper = class {
980
1652
  }
981
1653
  async identify(users) {
982
1654
  if (!this.enabled) return;
1655
+ const destination = currentReplayTraceDestination();
1656
+ if (destination && destination.kind !== "workshop") return;
983
1657
  const list = Array.isArray(users) ? users : [users];
984
1658
  const body = list.filter((user) => {
985
1659
  if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
@@ -1032,8 +1706,9 @@ var EventShipper = class {
1032
1706
  this.buffers.delete(eventId);
1033
1707
  if (!accumulated) return;
1034
1708
  const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
1035
- const eventName = (_c = (_b = accumulated.eventName) != null ? _b : sticky.eventName) != null ? _c : this.defaultEventName;
1036
- const userId = (_d = accumulated.userId) != null ? _d : sticky.userId;
1709
+ const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
1710
+ const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
1711
+ const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
1037
1712
  if (!userId) {
1038
1713
  if (this.debug) {
1039
1714
  console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
@@ -1041,14 +1716,13 @@ var EventShipper = class {
1041
1716
  this.sticky.delete(eventId);
1042
1717
  return;
1043
1718
  }
1044
- const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
1719
+ const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
1045
1720
  let telemetryProperties = {};
1046
1721
  try {
1047
1722
  telemetryProperties = eventTelemetryProperties(accumulated);
1048
1723
  } catch (e) {
1049
1724
  }
1050
- const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
1051
- const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
1725
+ const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
1052
1726
  const payload = {
1053
1727
  event_id: eventId,
1054
1728
  user_id: userId,
@@ -1090,29 +1764,30 @@ var EventShipper = class {
1090
1764
  endpoint: url
1091
1765
  });
1092
1766
  }
1093
- if (this.localDebuggerUrl) {
1094
- mirrorPartialEventToLocalDebugger(payload, {
1095
- baseUrl: this.localDebuggerUrl,
1096
- writeKey: this.writeKey,
1097
- debug: this.debug,
1098
- sdkName: this.sdkName
1099
- });
1100
- }
1767
+ const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
1768
+ baseUrl: this.localDebuggerUrl,
1769
+ writeKey: this.writeKey,
1770
+ debug: this.debug,
1771
+ sdkName: this.sdkName
1772
+ }) : void 0;
1101
1773
  if (!this.writeKey) {
1102
1774
  if (!isPending) this.sticky.delete(eventId);
1775
+ if (mirror) await mirror;
1103
1776
  return;
1104
1777
  }
1105
1778
  const opts = this.requestOpts();
1106
1779
  if (!opts) {
1107
1780
  this.warnShutdownDrop(`track_partial ${eventId}`);
1108
1781
  if (!isPending) this.sticky.delete(eventId);
1782
+ if (mirror) await mirror;
1109
1783
  return;
1110
1784
  }
1111
1785
  const p = postJson(url, payload, this.requestHeaders(), opts);
1112
- this.inFlight.add(p);
1786
+ const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
1787
+ this.inFlight.add(combined);
1113
1788
  try {
1114
1789
  try {
1115
- await p;
1790
+ await combined;
1116
1791
  if (this.debug) {
1117
1792
  console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
1118
1793
  }
@@ -1124,7 +1799,7 @@ var EventShipper = class {
1124
1799
  );
1125
1800
  }
1126
1801
  } finally {
1127
- this.inFlight.delete(p);
1802
+ this.inFlight.delete(combined);
1128
1803
  }
1129
1804
  if (!isPending) {
1130
1805
  this.sticky.delete(eventId);
@@ -1370,6 +2045,13 @@ function redactJsonAttributeValue(key, value) {
1370
2045
  if (scrubbedJson === json) return void 0;
1371
2046
  return { stringValue: scrubbedJson };
1372
2047
  }
2048
+ function appGitOwnerId2(prefix) {
2049
+ try {
2050
+ return `${prefix}:${randomUUID()}`;
2051
+ } catch (e) {
2052
+ return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
2053
+ }
2054
+ }
1373
2055
  function identityAttrs(args) {
1374
2056
  return [
1375
2057
  attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
@@ -1392,23 +2074,30 @@ function applyOtelSpanAttributeLimit(limit) {
1392
2074
  }
1393
2075
  var TraceShipper = class {
1394
2076
  constructor(opts) {
2077
+ this.appGitOwner = appGitOwnerId2("trace");
2078
+ this.appGitEventIds = /* @__PURE__ */ new WeakMap();
2079
+ this.appGitActiveSpans = /* @__PURE__ */ new Map();
2080
+ this.appGitCaptured = /* @__PURE__ */ new WeakSet();
2081
+ this.appGitAdded = /* @__PURE__ */ new WeakMap();
1395
2082
  this.queue = [];
1396
2083
  this.inFlight = /* @__PURE__ */ new Set();
1397
2084
  this.hasShutdown = false;
1398
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1399
- this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
1400
- this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
2085
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2086
+ this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
2087
+ this.ownsAppGitContext = opts.appGitContext === void 0;
2088
+ this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
2089
+ this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
1401
2090
  this.enabled = opts.enabled !== false;
1402
2091
  this.debug = opts.debug;
1403
2092
  this.debugSpans = opts.debugSpans === true;
1404
- this.flushIntervalMs = (_c = opts.flushIntervalMs) != null ? _c : 1e3;
1405
- this.maxBatchSize = (_d = opts.maxBatchSize) != null ? _d : 50;
1406
- this.maxQueueSize = (_e = opts.maxQueueSize) != null ? _e : 5e3;
1407
- this.sdkName = (_f = opts.sdkName) != null ? _f : "core";
2093
+ this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
2094
+ this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
2095
+ this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
2096
+ this.sdkName = (_g = opts.sdkName) != null ? _g : "core";
1408
2097
  this.prefix = `[raindrop-ai/${this.sdkName}]`;
1409
- this.serviceName = (_g = opts.serviceName) != null ? _g : "raindrop.core";
1410
- this.serviceVersion = (_h = opts.serviceVersion) != null ? _h : "0.0.0";
1411
- this.localDebuggerUrl = (_i = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _i : void 0;
2098
+ this.serviceName = (_h = opts.serviceName) != null ? _h : "raindrop.core";
2099
+ this.serviceVersion = (_i = opts.serviceVersion) != null ? _i : "0.0.0";
2100
+ this.localDebuggerUrl = (_j = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _j : void 0;
1412
2101
  if (this.debug && this.localDebuggerUrl) {
1413
2102
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
1414
2103
  }
@@ -1472,7 +2161,10 @@ var TraceShipper = class {
1472
2161
  try {
1473
2162
  const result = this.transformSpanHook(current);
1474
2163
  if (result === null) return null;
1475
- if (result !== void 0) current = result;
2164
+ if (result !== void 0) {
2165
+ copyReplayTraceDestination(current, result);
2166
+ current = result;
2167
+ }
1476
2168
  } catch (err) {
1477
2169
  if (this.debug) {
1478
2170
  const msg = err instanceof Error ? err.message : String(err);
@@ -1482,13 +2174,19 @@ var TraceShipper = class {
1482
2174
  }
1483
2175
  }
1484
2176
  try {
1485
- current = normalizeModelUsageSpan(current);
2177
+ const normalized = normalizeModelUsageSpan(current);
2178
+ copyReplayTraceDestination(current, normalized);
2179
+ current = normalized;
1486
2180
  } catch (e) {
1487
2181
  }
1488
2182
  if (!this.disableDefaultRedaction) {
1489
- current = defaultTransformSpan(current);
2183
+ const redacted = defaultTransformSpan(current);
2184
+ copyReplayTraceDestination(current, redacted);
2185
+ current = redacted;
1490
2186
  }
1491
- return this.capSpanAttributes(current);
2187
+ const capped = this.capSpanAttributes(current);
2188
+ copyReplayTraceDestination(current, capped);
2189
+ return capped;
1492
2190
  }
1493
2191
  isDebugEnabled() {
1494
2192
  return this.debug;
@@ -1500,46 +2198,84 @@ var TraceShipper = class {
1500
2198
  return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
1501
2199
  }
1502
2200
  startSpan(args) {
1503
- var _a, _b;
2201
+ var _a, _b, _c;
1504
2202
  const ids = createSpanIds(args.parent);
1505
2203
  const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
1506
2204
  const attrs = [
1507
2205
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1508
2206
  ...identityAttrs(args),
1509
- attrString("ai.operationId", args.operationId)
2207
+ attrString("ai.operationId", args.operationId),
2208
+ ...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
1510
2209
  ];
1511
2210
  if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
1512
- const span = { ids, name: args.name, startTimeUnixNano: started, attributes: attrs };
1513
- this.mirrorToLocalDebugger(
1514
- buildOtlpSpan({
1515
- ids: span.ids,
1516
- name: span.name,
1517
- startTimeUnixNano: span.startTimeUnixNano,
1518
- endTimeUnixNano: span.startTimeUnixNano,
1519
- // placeholder — will be updated on endSpan
1520
- attributes: span.attributes,
1521
- status: { code: SpanStatusCode.UNSET }
1522
- })
1523
- );
2211
+ const tracksAppGit = this.appGitActiveSpans.has(args.eventId) || this.appGitActiveSpans.size < 1e4;
2212
+ const appGitOverrides = appGitPropertiesFromAttributes(attrs);
2213
+ const span = {
2214
+ ids,
2215
+ name: args.name,
2216
+ startTimeUnixNano: started,
2217
+ attributes: withAppGitAttributes(
2218
+ attrs,
2219
+ this.appGitContext.forOperation(args.eventId, appGitOverrides, this.appGitOwner)
2220
+ )
2221
+ };
2222
+ rememberReplayTraceDestination(span);
2223
+ this.appGitCaptured.add(span);
2224
+ this.appGitEventIds.set(span, args.eventId);
2225
+ if (tracksAppGit) {
2226
+ this.appGitActiveSpans.set(args.eventId, ((_c = this.appGitActiveSpans.get(args.eventId)) != null ? _c : 0) + 1);
2227
+ }
2228
+ this.appGitAdded.set(span, new Set(span.attributes.filter((attr) => !attrs.includes(attr))));
2229
+ const openSpan = buildOtlpSpan({
2230
+ ids: span.ids,
2231
+ name: span.name,
2232
+ startTimeUnixNano: span.startTimeUnixNano,
2233
+ endTimeUnixNano: span.startTimeUnixNano,
2234
+ // placeholder — will be updated on endSpan
2235
+ attributes: span.attributes,
2236
+ status: { code: SpanStatusCode.UNSET }
2237
+ });
2238
+ copyReplayTraceDestination(span, openSpan);
2239
+ this.mirrorToLocalDebugger(openSpan);
1524
2240
  return span;
1525
2241
  }
1526
- mirrorToLocalDebugger(span) {
1527
- if (!this.localDebuggerUrl) return;
2242
+ mirrorToLocalDebugger(span, completed = false) {
2243
+ const destination = replayTraceDestinationFor(span);
2244
+ if (destination && destination.kind !== "workshop") return;
2245
+ const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
2246
+ if (!localDebuggerUrl) return;
1528
2247
  const redacted = this.redactSpan(span);
1529
2248
  if (redacted === null) return;
2249
+ if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
2250
+ recordReplayExportedSpan(
2251
+ destination,
2252
+ base64ToHex(redacted.spanId),
2253
+ base64ToHex(redacted.traceId)
2254
+ );
2255
+ }
1530
2256
  const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
1531
- mirrorTraceExportToLocalDebugger(body, {
1532
- baseUrl: this.localDebuggerUrl,
2257
+ const p = mirrorTraceExportToLocalDebugger(body, {
2258
+ baseUrl: localDebuggerUrl,
1533
2259
  debug: false,
1534
2260
  sdkName: this.sdkName
1535
2261
  });
2262
+ this.inFlight.add(p);
2263
+ void p.finally(() => {
2264
+ this.inFlight.delete(p);
2265
+ });
1536
2266
  }
1537
2267
  endSpan(span, extra) {
1538
- var _a, _b;
2268
+ var _a, _b, _c;
1539
2269
  if (span.endTimeUnixNano) return;
1540
2270
  span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
1541
2271
  if ((_b = extra == null ? void 0 : extra.attributes) == null ? void 0 : _b.length) {
2272
+ const overrides = appGitPropertiesFromAttributes(extra.attributes);
2273
+ const eventId2 = this.appGitEventIds.get(span);
2274
+ const snapshot = eventId2 ? this.appGitContext.forOperation(eventId2, overrides, this.appGitOwner) : overrides;
2275
+ const added = this.appGitAdded.get(span);
2276
+ span.attributes = span.attributes.filter((attr) => !(added == null ? void 0 : added.has(attr)) || !attr || !Object.prototype.hasOwnProperty.call(overrides, APP_COMMIT_SHA) && !Object.prototype.hasOwnProperty.call(overrides, attr.key));
1542
2277
  span.attributes.push(...extra.attributes);
2278
+ span.attributes = withAppGitAttributes(span.attributes, snapshot);
1543
2279
  }
1544
2280
  let status = extra == null ? void 0 : extra.status;
1545
2281
  if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
@@ -1554,30 +2290,65 @@ var TraceShipper = class {
1554
2290
  attributes: span.attributes,
1555
2291
  status
1556
2292
  });
2293
+ copyReplayTraceDestination(span, otlp);
2294
+ this.appGitCaptured.add(otlp);
1557
2295
  this.enqueue(otlp);
1558
- this.mirrorToLocalDebugger(otlp);
2296
+ this.mirrorToLocalDebugger(otlp, true);
2297
+ const eventId = this.appGitEventIds.get(span);
2298
+ if (eventId && this.appGitActiveSpans.has(eventId)) {
2299
+ const remaining = ((_c = this.appGitActiveSpans.get(eventId)) != null ? _c : 1) - 1;
2300
+ if (remaining > 0) this.appGitActiveSpans.set(eventId, remaining);
2301
+ else {
2302
+ this.appGitActiveSpans.delete(eventId);
2303
+ if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
2304
+ else if (this.ownsAppGitContext) this.appGitContext.finishOperation(eventId);
2305
+ }
2306
+ }
1559
2307
  }
1560
2308
  createSpan(args) {
1561
2309
  var _a;
1562
2310
  const ids = createSpanIds(args.parent);
1563
2311
  const attrs = [
1564
2312
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1565
- ...identityAttrs(args)
2313
+ ...identityAttrs(args),
2314
+ ...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
1566
2315
  ];
1567
2316
  if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
2317
+ const tracksAppGit = !this.appGitActiveSpans.has(args.eventId);
1568
2318
  const otlp = buildOtlpSpan({
1569
2319
  ids,
1570
2320
  name: args.name,
1571
2321
  startTimeUnixNano: args.startTimeUnixNano,
1572
2322
  endTimeUnixNano: args.endTimeUnixNano,
1573
- attributes: attrs,
2323
+ attributes: withAppGitAttributes(
2324
+ attrs,
2325
+ this.appGitContext.forOperation(
2326
+ args.eventId,
2327
+ appGitPropertiesFromAttributes(attrs),
2328
+ this.appGitOwner
2329
+ )
2330
+ ),
1574
2331
  status: args.status
1575
2332
  });
2333
+ rememberReplayTraceDestination(otlp);
2334
+ this.appGitCaptured.add(otlp);
2335
+ if (tracksAppGit) {
2336
+ if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(args.eventId, this.appGitOwner);
2337
+ else if (this.ownsAppGitContext) this.appGitContext.finishOperation(args.eventId);
2338
+ }
1576
2339
  this.enqueue(otlp);
1577
- this.mirrorToLocalDebugger(otlp);
2340
+ this.mirrorToLocalDebugger(otlp, true);
1578
2341
  }
1579
2342
  enqueue(span) {
2343
+ var _a;
1580
2344
  if (!this.enabled) return;
2345
+ const attributes = (_a = span.attributes) != null ? _a : [];
2346
+ const enriched = this.appGitCaptured.has(span) ? attributes : withAppGitAttributes(attributes, this.appGitContext.snapshot(appGitPropertiesFromAttributes(attributes)));
2347
+ if (enriched !== attributes) {
2348
+ const original = span;
2349
+ span = { ...span, attributes: enriched.filter((attr) => attr !== void 0) };
2350
+ copyReplayTraceDestination(original, span);
2351
+ }
1581
2352
  if (this.debugSpans) {
1582
2353
  const short = (s) => s ? s.slice(-8) : "none";
1583
2354
  console.log(
@@ -1588,6 +2359,13 @@ var TraceShipper = class {
1588
2359
  }
1589
2360
  const redacted = this.redactSpan(span);
1590
2361
  if (redacted === null) return;
2362
+ const destination = replayTraceDestinationFor(redacted);
2363
+ recordReplayExportedSpan(
2364
+ destination,
2365
+ base64ToHex(redacted.spanId),
2366
+ base64ToHex(redacted.traceId)
2367
+ );
2368
+ if ((destination == null ? void 0 : destination.kind) === "workshop") return;
1591
2369
  if (this.queue.length >= this.maxQueueSize) {
1592
2370
  this.queue.shift();
1593
2371
  }
@@ -1606,47 +2384,67 @@ var TraceShipper = class {
1606
2384
  }
1607
2385
  }
1608
2386
  async flush() {
1609
- if (!this.enabled) return;
2387
+ var _a;
2388
+ if (!this.enabled) {
2389
+ await Promise.all([...this.inFlight].map((p) => p.catch(() => {
2390
+ })));
2391
+ return;
2392
+ }
1610
2393
  if (this.timer) {
1611
2394
  clearTimeout(this.timer);
1612
2395
  this.timer = void 0;
1613
2396
  }
1614
2397
  while (this.queue.length > 0) {
1615
2398
  const batch = this.queue.splice(0, this.maxBatchSize);
1616
- if (!this.writeKey) continue;
1617
- const opts = this.requestOpts();
1618
- if (!opts) {
1619
- rateLimitedLog(
1620
- `${this.prefix}.shutdown_deadline`,
1621
- () => console.warn(
1622
- `${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
1623
- )
1624
- );
1625
- continue;
1626
- }
1627
- const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
1628
- const url = `${this.baseUrl}traces`;
1629
- if (this.debug) {
1630
- console.log(`${this.prefix} sending traces batch`, {
1631
- spans: batch.length,
1632
- endpoint: url
1633
- });
2399
+ const groups = /* @__PURE__ */ new Map();
2400
+ for (const span of batch) {
2401
+ const destination = replayTraceDestinationFor(span);
2402
+ const spans = groups.get(destination);
2403
+ if (spans) spans.push(span);
2404
+ else groups.set(destination, [span]);
1634
2405
  }
1635
- const p = postJson(url, body, this.requestHeaders(), opts);
1636
- this.inFlight.add(p);
1637
- try {
1638
- try {
1639
- await p;
1640
- if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
1641
- } catch (err) {
1642
- const msg = err instanceof Error ? err.message : String(err);
2406
+ for (const [destination, spans] of groups) {
2407
+ if (!destination && !this.writeKey) continue;
2408
+ if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
2409
+ const opts = this.requestOpts();
2410
+ if (!opts) {
1643
2411
  rateLimitedLog(
1644
- `${this.prefix}.send_spans_failed`,
1645
- () => console.warn(`${this.prefix} failed to send ${batch.length} spans: ${msg}`)
2412
+ `${this.prefix}.shutdown_deadline`,
2413
+ () => console.warn(
2414
+ `${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
2415
+ )
1646
2416
  );
2417
+ continue;
2418
+ }
2419
+ const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
2420
+ const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
2421
+ const headers = destination ? {
2422
+ Authorization: `Bearer ${destination.apiKey}`,
2423
+ "X-Raindrop-Replay-Id": destination.replayId,
2424
+ "X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
2425
+ } : this.requestHeaders();
2426
+ if (this.debug) {
2427
+ console.log(`${this.prefix} sending traces batch`, {
2428
+ spans: spans.length,
2429
+ endpoint: url
2430
+ });
2431
+ }
2432
+ const p = postJson(url, body, headers, opts);
2433
+ this.inFlight.add(p);
2434
+ try {
2435
+ try {
2436
+ await p;
2437
+ if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
2438
+ } catch (err) {
2439
+ const msg = err instanceof Error ? err.message : String(err);
2440
+ rateLimitedLog(
2441
+ `${this.prefix}.send_spans_failed`,
2442
+ () => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
2443
+ );
2444
+ }
2445
+ } finally {
2446
+ this.inFlight.delete(p);
1647
2447
  }
1648
- } finally {
1649
- this.inFlight.delete(p);
1650
2448
  }
1651
2449
  }
1652
2450
  }
@@ -1689,136 +2487,22 @@ var TraceShipper = class {
1689
2487
  if (!settled) {
1690
2488
  rateLimitedLog(
1691
2489
  `${this.prefix}.shutdown_deadline`,
1692
- () => console.warn(`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`)
2490
+ () => console.warn(
2491
+ `${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
2492
+ )
1693
2493
  );
1694
2494
  }
1695
2495
  } finally {
1696
2496
  this.shutdownDeadlineAt = void 0;
2497
+ if (this.ownsAppGitContext) this.appGitContext.dispose();
1697
2498
  }
1698
2499
  }
1699
2500
  };
1700
- var NOOP_SPAN = {
1701
- traceIdB64: "",
1702
- spanIdB64: "",
1703
- eventId: "",
1704
- log() {
1705
- }
1706
- };
1707
- function getAsyncLocalStorageCtor() {
1708
- return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
1709
- }
1710
- var SynchronousContextStorage = class {
1711
- constructor() {
1712
- this._stack = [];
1713
- }
1714
- isEmpty() {
1715
- return this._stack.length === 0;
1716
- }
1717
- getStore() {
1718
- return this._stack[this._stack.length - 1];
1719
- }
1720
- run(store, callback) {
1721
- this._stack.push(store);
1722
- try {
1723
- return callback();
1724
- } finally {
1725
- this._stack.pop();
1726
- }
1727
- }
1728
- };
1729
- var ContextManager = class {
1730
- };
1731
- var RaindropContextManager = class extends ContextManager {
1732
- constructor() {
1733
- super();
1734
- this._fallback = null;
1735
- const Ctor = getAsyncLocalStorageCtor();
1736
- if (Ctor) {
1737
- this._storage = new Ctor();
1738
- return;
1739
- }
1740
- this._fallback = new SynchronousContextStorage();
1741
- this._storage = this._fallback;
1742
- }
1743
- maybeAdoptAsyncLocalStorage() {
1744
- if (!this._fallback || !this._fallback.isEmpty()) return;
1745
- const Ctor = getAsyncLocalStorageCtor();
1746
- if (!Ctor) return;
1747
- this._storage = new Ctor();
1748
- this._fallback = null;
1749
- }
1750
- isReady() {
1751
- return true;
1752
- }
1753
- getParentSpanIds() {
1754
- this.maybeAdoptAsyncLocalStorage();
1755
- const span = this._storage.getStore();
1756
- if (!span || span === NOOP_SPAN) return void 0;
1757
- return {
1758
- traceIdB64: span.traceIdB64,
1759
- spanIdB64: span.spanIdB64,
1760
- eventId: span.eventId
1761
- };
1762
- }
1763
- runInContext(span, callback) {
1764
- this.maybeAdoptAsyncLocalStorage();
1765
- return this._storage.run(span, callback);
1766
- }
1767
- getCurrentSpan() {
1768
- this.maybeAdoptAsyncLocalStorage();
1769
- return this._storage.getStore();
1770
- }
1771
- };
1772
- var _contextManager = null;
1773
- function getContextManager() {
1774
- if (!_contextManager) {
1775
- _contextManager = globalThis.RAINDROP_CONTEXT_MANAGER ? new globalThis.RAINDROP_CONTEXT_MANAGER() : new RaindropContextManager();
1776
- }
1777
- return _contextManager;
1778
- }
1779
- function currentSpan() {
1780
- var _a;
1781
- return (_a = getContextManager().getCurrentSpan()) != null ? _a : NOOP_SPAN;
1782
- }
1783
- function withCurrent(span, callback) {
1784
- return getContextManager().runInContext(span, callback);
1785
- }
1786
- async function getCurrentParentSpanContext() {
1787
- return getContextManager().getParentSpanIds();
1788
- }
1789
- async function runWithParentSpanContext(ctx, fn) {
1790
- const cm = getContextManager();
1791
- const span = {
1792
- traceIdB64: ctx.traceIdB64,
1793
- spanIdB64: ctx.spanIdB64,
1794
- eventId: ctx.eventId
1795
- };
1796
- return cm.runInContext(span, fn);
1797
- }
1798
- async function* asyncGeneratorWithCurrent(span, gen) {
1799
- let nextValue;
1800
- while (true) {
1801
- const result = await withCurrent(span, async () => {
1802
- try {
1803
- return await gen.next(nextValue);
1804
- } catch (e) {
1805
- return { value: void 0, done: true, error: e };
1806
- }
1807
- });
1808
- if ("error" in result && result.error !== void 0) {
1809
- throw result.error;
1810
- }
1811
- if (result.done) {
1812
- return result.value;
1813
- }
1814
- nextValue = yield result.value;
1815
- }
1816
- }
1817
2501
 
1818
2502
  // package.json
1819
2503
  var package_default = {
1820
2504
  name: "@raindrop-ai/ai-sdk",
1821
- version: "0.3.1"};
2505
+ version: "0.3.3"};
1822
2506
 
1823
2507
  // src/internal/version.ts
1824
2508
  var libraryName = package_default.name;
@@ -3344,13 +4028,13 @@ var RaindropTelemetryIntegration = class {
3344
4028
  };
3345
4029
  // ── onStepStart ─────────────────────────────────────────────────────────
3346
4030
  this.onStepStart = (event) => {
3347
- const state = this.getState(event.callId);
3348
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
3349
- const isStream = state.operationId === "ai.streamText" || state.operationId === "ai.streamObject";
3350
- const stepOperationId = isStream ? `${state.operationId}.doStream` : `${state.operationId}.doGenerate`;
3351
- const { operationName, resourceName } = opName(stepOperationId, state.functionId);
4031
+ const state2 = this.getState(event.callId);
4032
+ if (!(state2 == null ? void 0 : state2.rootSpan) || !state2.rootParent) return;
4033
+ const isStream = state2.operationId === "ai.streamText" || state2.operationId === "ai.streamObject";
4034
+ const stepOperationId = isStream ? `${state2.operationId}.doStream` : `${state2.operationId}.doGenerate`;
4035
+ const { operationName, resourceName } = opName(stepOperationId, state2.functionId);
3352
4036
  const inputAttrs = [];
3353
- if (state.recordInputs) {
4037
+ if (state2.recordInputs) {
3354
4038
  if (event.promptMessages) {
3355
4039
  inputAttrs.push(attrString("ai.prompt.messages", safeJsonWithUint8(event.promptMessages)));
3356
4040
  }
@@ -3373,25 +4057,25 @@ var RaindropTelemetryIntegration = class {
3373
4057
  }
3374
4058
  const stepSpan = this.traceShipper.startSpan({
3375
4059
  name: stepOperationId,
3376
- parent: state.rootParent,
3377
- eventId: state.eventId,
3378
- ...state.identity,
4060
+ parent: state2.rootParent,
4061
+ eventId: state2.eventId,
4062
+ ...state2.identity,
3379
4063
  operationId: stepOperationId,
3380
4064
  attributes: [
3381
4065
  attrString("operation.name", operationName),
3382
4066
  attrString("resource.name", resourceName),
3383
- attrString("ai.telemetry.functionId", state.functionId),
4067
+ attrString("ai.telemetry.functionId", state2.functionId),
3384
4068
  ...attrsFromModelProvider(event.provider),
3385
4069
  attrString("ai.model.id", event.modelId),
3386
4070
  attrString(MODEL_USAGE_ATTRIBUTES.requestModel, event.modelId),
3387
4071
  ...inputAttrs,
3388
- ...handoffSpanAttrs(state.handoff)
4072
+ ...handoffSpanAttrs(state2.handoff)
3389
4073
  ]
3390
4074
  });
3391
- state.stepSpan = stepSpan;
3392
- state.stepParent = this.spanParentRef(stepSpan);
3393
- state.stepProvider = event.provider;
3394
- state.stepModelId = event.modelId;
4075
+ state2.stepSpan = stepSpan;
4076
+ state2.stepParent = this.spanParentRef(stepSpan);
4077
+ state2.stepProvider = event.provider;
4078
+ state2.stepModelId = event.modelId;
3395
4079
  };
3396
4080
  this.onToolExecutionStart = (event) => this.toolExecutionStart(event);
3397
4081
  this.onToolExecutionEnd = (event) => this.toolExecutionEnd(event);
@@ -3418,33 +4102,33 @@ var RaindropTelemetryIntegration = class {
3418
4102
  var _a, _b, _c, _d, _e;
3419
4103
  const callId = (_b = event.callId) != null ? _b : (_a = event.chunk) == null ? void 0 : _a.callId;
3420
4104
  if (!callId) return;
3421
- const state = this.getState(callId);
3422
- if (!state) return;
4105
+ const state2 = this.getState(callId);
4106
+ if (!state2) return;
3423
4107
  const chunk = event.chunk;
3424
4108
  if (!chunk || typeof chunk !== "object") return;
3425
4109
  if (chunk.type === "text-delta") {
3426
4110
  const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
3427
4111
  if (typeof delta === "string") {
3428
- if (state.accumulatedText.length <= effectiveMaxTextFieldChars()) {
3429
- state.accumulatedText += delta;
4112
+ if (state2.accumulatedText.length <= effectiveMaxTextFieldChars()) {
4113
+ state2.accumulatedText += delta;
3430
4114
  }
3431
- this.emitLive(state, "text_delta", delta);
4115
+ this.emitLive(state2, "text_delta", delta);
3432
4116
  }
3433
4117
  } else if (chunk.type === "reasoning" || chunk.type === "reasoning-delta") {
3434
4118
  const text = (_e = (_d = chunk.textDelta) != null ? _d : chunk.text) != null ? _e : chunk.delta;
3435
4119
  if (typeof text === "string") {
3436
- this.emitLive(state, "reasoning_delta", text);
4120
+ this.emitLive(state2, "reasoning_delta", text);
3437
4121
  }
3438
4122
  }
3439
4123
  };
3440
4124
  // ── onStepFinish ────────────────────────────────────────────────────────
3441
4125
  this.onStepFinish = (event) => {
3442
4126
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
3443
- const state = this.getState(event.callId);
3444
- if (!(state == null ? void 0 : state.stepSpan)) return;
3445
- const responseModelId = (_b = (_a = event.response) == null ? void 0 : _a.modelId) != null ? _b : state.stepModelId;
4127
+ const state2 = this.getState(event.callId);
4128
+ if (!(state2 == null ? void 0 : state2.stepSpan)) return;
4129
+ const responseModelId = (_b = (_a = event.response) == null ? void 0 : _a.modelId) != null ? _b : state2.stepModelId;
3446
4130
  const outputAttrs = [];
3447
- if (state.recordOutputs) {
4131
+ if (state2.recordOutputs) {
3448
4132
  outputAttrs.push(
3449
4133
  attrString("ai.response.finishReason", event.finishReason),
3450
4134
  attrString("ai.response.text", capText2((_c = event.text) != null ? _c : void 0)),
@@ -3489,7 +4173,7 @@ var RaindropTelemetryIntegration = class {
3489
4173
  if (usage) {
3490
4174
  const usageMetrics = extractUsageMetricsFromUsage(
3491
4175
  usage,
3492
- state.stepProvider,
4176
+ state2.stepProvider,
3493
4177
  event.providerMetadata
3494
4178
  );
3495
4179
  outputAttrs.push(
@@ -3502,51 +4186,51 @@ var RaindropTelemetryIntegration = class {
3502
4186
  ...buildRawModelUsageAttributes(usageMetrics)
3503
4187
  );
3504
4188
  }
3505
- this.emitProviderExecutedToolSpans(event, state);
3506
- this.traceShipper.endSpan(state.stepSpan, { attributes: outputAttrs });
3507
- state.stepSpan = void 0;
3508
- state.stepParent = void 0;
3509
- state.stepProvider = void 0;
3510
- state.stepModelId = void 0;
4189
+ this.emitProviderExecutedToolSpans(event, state2);
4190
+ this.traceShipper.endSpan(state2.stepSpan, { attributes: outputAttrs });
4191
+ state2.stepSpan = void 0;
4192
+ state2.stepParent = void 0;
4193
+ state2.stepProvider = void 0;
4194
+ state2.stepModelId = void 0;
3511
4195
  };
3512
4196
  // ── onEmbedStart ────────────────────────────────────────────────────────
3513
4197
  this.onEmbedStart = (event) => {
3514
- const state = this.getState(event.callId);
3515
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
3516
- const { operationName, resourceName } = opName(event.operationId, state.functionId);
3517
- const inputAttrs = state.recordInputs ? [attrString("ai.values", safeJsonWithUint8(event.values))] : [];
4198
+ const state2 = this.getState(event.callId);
4199
+ if (!(state2 == null ? void 0 : state2.rootSpan) || !state2.rootParent) return;
4200
+ const { operationName, resourceName } = opName(event.operationId, state2.functionId);
4201
+ const inputAttrs = state2.recordInputs ? [attrString("ai.values", safeJsonWithUint8(event.values))] : [];
3518
4202
  const embedSpan = this.traceShipper.startSpan({
3519
4203
  name: event.operationId,
3520
- parent: state.rootParent,
3521
- eventId: state.eventId,
3522
- ...state.identity,
4204
+ parent: state2.rootParent,
4205
+ eventId: state2.eventId,
4206
+ ...state2.identity,
3523
4207
  operationId: event.operationId,
3524
4208
  attributes: [
3525
4209
  attrString("operation.name", operationName),
3526
4210
  attrString("resource.name", resourceName),
3527
- attrString("ai.telemetry.functionId", state.functionId),
4211
+ attrString("ai.telemetry.functionId", state2.functionId),
3528
4212
  ...inputAttrs,
3529
- ...handoffSpanAttrs(state.handoff)
4213
+ ...handoffSpanAttrs(state2.handoff)
3530
4214
  ]
3531
4215
  });
3532
- state.embedSpans.set(event.embedCallId, embedSpan);
4216
+ state2.embedSpans.set(event.embedCallId, embedSpan);
3533
4217
  };
3534
4218
  // ── onEmbedFinish ───────────────────────────────────────────────────────
3535
4219
  this.onEmbedFinish = (event) => {
3536
4220
  var _a;
3537
- const state = this.getState(event.callId);
3538
- if (!state) return;
3539
- const embedSpan = state.embedSpans.get(event.embedCallId);
4221
+ const state2 = this.getState(event.callId);
4222
+ if (!state2) return;
4223
+ const embedSpan = state2.embedSpans.get(event.embedCallId);
3540
4224
  if (!embedSpan) return;
3541
4225
  const outputAttrs = [];
3542
- if (state.recordOutputs) {
4226
+ if (state2.recordOutputs) {
3543
4227
  outputAttrs.push(attrString("ai.embeddings", safeJsonWithUint8(event.embeddings)));
3544
4228
  }
3545
4229
  if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
3546
4230
  outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
3547
4231
  }
3548
4232
  this.traceShipper.endSpan(embedSpan, { attributes: outputAttrs });
3549
- state.embedSpans.delete(event.embedCallId);
4233
+ state2.embedSpans.delete(event.embedCallId);
3550
4234
  };
3551
4235
  // v7 canary.159 renamed `onEmbedFinish` -> `onEmbedEnd`. Both names forward
3552
4236
  // to the same implementation; the installed SDK only wires up whichever it
@@ -3554,16 +4238,16 @@ var RaindropTelemetryIntegration = class {
3554
4238
  this.onEmbedEnd = (event) => this.onEmbedFinish(event);
3555
4239
  // ── onFinish ────────────────────────────────────────────────────────────
3556
4240
  this.onFinish = (event) => {
3557
- const state = this.getState(event.callId);
3558
- if (!state) return;
3559
- const isEmbed = state.operationId === "ai.embed" || state.operationId === "ai.embedMany";
4241
+ const state2 = this.getState(event.callId);
4242
+ if (!state2) return;
4243
+ const isEmbed = state2.operationId === "ai.embed" || state2.operationId === "ai.embedMany";
3560
4244
  if (isEmbed) {
3561
- this.finishEmbed(event, state);
4245
+ this.finishEmbed(event, state2);
3562
4246
  } else {
3563
- this.finishGenerate(event, state);
4247
+ this.finishGenerate(event, state2);
3564
4248
  }
3565
- if (state.subagentToolCallSpan) {
3566
- this.traceShipper.endSpan(state.subagentToolCallSpan);
4249
+ if (state2.subagentToolCallSpan) {
4250
+ this.traceShipper.endSpan(state2.subagentToolCallSpan);
3567
4251
  }
3568
4252
  this.cleanup(event.callId);
3569
4253
  };
@@ -3578,42 +4262,42 @@ var RaindropTelemetryIntegration = class {
3578
4262
  var _a;
3579
4263
  const event = error;
3580
4264
  if (!(event == null ? void 0 : event.callId)) return;
3581
- const state = this.getState(event.callId);
3582
- if (!state) return;
4265
+ const state2 = this.getState(event.callId);
4266
+ if (!state2) return;
3583
4267
  const actualError = (_a = event.error) != null ? _a : error;
3584
- if (state.stepSpan) {
3585
- this.traceShipper.endSpan(state.stepSpan, { error: actualError });
3586
- state.stepProvider = void 0;
3587
- state.stepModelId = void 0;
4268
+ if (state2.stepSpan) {
4269
+ this.traceShipper.endSpan(state2.stepSpan, { error: actualError });
4270
+ state2.stepProvider = void 0;
4271
+ state2.stepModelId = void 0;
3588
4272
  }
3589
- for (const embedSpan of state.embedSpans.values()) {
4273
+ for (const embedSpan of state2.embedSpans.values()) {
3590
4274
  this.traceShipper.endSpan(embedSpan, { error: actualError });
3591
4275
  }
3592
- state.embedSpans.clear();
3593
- for (const toolCallId of state.parentContextToolCallIds) {
4276
+ state2.embedSpans.clear();
4277
+ for (const toolCallId of state2.parentContextToolCallIds) {
3594
4278
  this.priorParentContexts.delete(toolCallId);
3595
4279
  }
3596
- state.parentContextToolCallIds.clear();
3597
- for (const toolSpan of state.toolSpans.values()) {
4280
+ state2.parentContextToolCallIds.clear();
4281
+ for (const toolSpan of state2.toolSpans.values()) {
3598
4282
  this.traceShipper.endSpan(toolSpan, { error: actualError });
3599
4283
  }
3600
- state.toolSpans.clear();
4284
+ state2.toolSpans.clear();
3601
4285
  const abortReason = describeAbortReason(actualError);
3602
- if (state.rootSpan) {
3603
- this.traceShipper.endSpan(state.rootSpan, {
4286
+ if (state2.rootSpan) {
4287
+ this.traceShipper.endSpan(state2.rootSpan, {
3604
4288
  error: actualError,
3605
- attributes: this.abortOutcomeAttrs(state, abortReason, "error")
4289
+ attributes: this.abortOutcomeAttrs(state2, abortReason, "error")
3606
4290
  });
3607
4291
  }
3608
- if (state.subagentToolCallSpan) {
3609
- this.traceShipper.endSpan(state.subagentToolCallSpan, { error: actualError });
4292
+ if (state2.subagentToolCallSpan) {
4293
+ this.traceShipper.endSpan(state2.subagentToolCallSpan, { error: actualError });
3610
4294
  }
3611
- const isEmbed = state.operationId === "ai.embed" || state.operationId === "ai.embedMany";
4295
+ const isEmbed = state2.operationId === "ai.embed" || state2.operationId === "ai.embedMany";
3612
4296
  if (!isEmbed) {
3613
- const errorIsTheRunsOutcome = state.handoff !== void 0 && !state.nestedInEvent;
4297
+ const errorIsTheRunsOutcome = state2.handoff !== void 0 && !state2.nestedInEvent;
3614
4298
  this.finalizeGenerateEvent(
3615
- state,
3616
- state.accumulatedText || void 0,
4299
+ state2,
4300
+ state2.accumulatedText || void 0,
3617
4301
  void 0,
3618
4302
  false,
3619
4303
  errorIsTheRunsOutcome ? { fallbackOutput: abortReason } : void 0
@@ -3632,51 +4316,51 @@ var RaindropTelemetryIntegration = class {
3632
4316
  this.onAbort = (event) => {
3633
4317
  const callId = event == null ? void 0 : event.callId;
3634
4318
  if (!callId) return;
3635
- const state = this.getState(callId);
3636
- if (!state) return;
4319
+ const state2 = this.getState(callId);
4320
+ if (!state2) return;
3637
4321
  const abortedAttr = attrString("ai.response.aborted", "true");
3638
- if (state.stepSpan) {
3639
- this.traceShipper.endSpan(state.stepSpan, { attributes: [abortedAttr] });
3640
- state.stepSpan = void 0;
3641
- state.stepParent = void 0;
3642
- state.stepProvider = void 0;
3643
- state.stepModelId = void 0;
4322
+ if (state2.stepSpan) {
4323
+ this.traceShipper.endSpan(state2.stepSpan, { attributes: [abortedAttr] });
4324
+ state2.stepSpan = void 0;
4325
+ state2.stepParent = void 0;
4326
+ state2.stepProvider = void 0;
4327
+ state2.stepModelId = void 0;
3644
4328
  }
3645
- for (const embedSpan of state.embedSpans.values()) {
4329
+ for (const embedSpan of state2.embedSpans.values()) {
3646
4330
  this.traceShipper.endSpan(embedSpan, { attributes: [abortedAttr] });
3647
4331
  }
3648
- state.embedSpans.clear();
3649
- for (const toolCallId of state.parentContextToolCallIds) {
4332
+ state2.embedSpans.clear();
4333
+ for (const toolCallId of state2.parentContextToolCallIds) {
3650
4334
  this.priorParentContexts.delete(toolCallId);
3651
4335
  }
3652
- state.parentContextToolCallIds.clear();
3653
- for (const toolSpan of state.toolSpans.values()) {
4336
+ state2.parentContextToolCallIds.clear();
4337
+ for (const toolSpan of state2.toolSpans.values()) {
3654
4338
  this.traceShipper.endSpan(toolSpan, { attributes: [abortedAttr] });
3655
4339
  }
3656
- state.toolSpans.clear();
3657
- const abortIsTheRunsOutcome = state.handoff !== void 0 && !state.nestedInEvent;
3658
- if (state.rootSpan) {
3659
- this.traceShipper.endSpan(state.rootSpan, {
4340
+ state2.toolSpans.clear();
4341
+ const abortIsTheRunsOutcome = state2.handoff !== void 0 && !state2.nestedInEvent;
4342
+ if (state2.rootSpan) {
4343
+ this.traceShipper.endSpan(state2.rootSpan, {
3660
4344
  attributes: [
3661
4345
  abortedAttr,
3662
- attrInt("ai.toolCall.count", state.toolCallCount),
4346
+ attrInt("ai.toolCall.count", state2.toolCallCount),
3663
4347
  // An aborted detached child IS a cancelled sub-agent, and a cancelled
3664
4348
  // run is span-for-span identical to a finished one — spans close,
3665
4349
  // nothing errors, there is just no answer. So it is the one outcome
3666
4350
  // that has to be stated, and the child states it on itself.
3667
4351
  ...abortIsTheRunsOutcome ? cancelledSpanAttrs() : [],
3668
- ...abortIsTheRunsOutcome ? this.abortOutcomeAttrs(state, SUBAGENT_CANCELLED_OUTPUT, "stop") : []
4352
+ ...abortIsTheRunsOutcome ? this.abortOutcomeAttrs(state2, SUBAGENT_CANCELLED_OUTPUT, "stop") : []
3669
4353
  ]
3670
4354
  });
3671
4355
  }
3672
- if (state.subagentToolCallSpan) {
3673
- this.traceShipper.endSpan(state.subagentToolCallSpan, {
4356
+ if (state2.subagentToolCallSpan) {
4357
+ this.traceShipper.endSpan(state2.subagentToolCallSpan, {
3674
4358
  attributes: [abortedAttr]
3675
4359
  });
3676
4360
  }
3677
4361
  this.finalizeGenerateEvent(
3678
- state,
3679
- state.accumulatedText || void 0,
4362
+ state2,
4363
+ state2.accumulatedText || void 0,
3680
4364
  void 0,
3681
4365
  false,
3682
4366
  abortIsTheRunsOutcome ? {
@@ -3684,7 +4368,7 @@ var RaindropTelemetryIntegration = class {
3684
4368
  properties: { [HANDOFF_TERMINAL_PROPERTY_KEY]: HANDOFF_TERMINAL_CANCELLED }
3685
4369
  } : void 0
3686
4370
  );
3687
- if (abortIsTheRunsOutcome) this.subagents.noteSettled(state.eventId);
4371
+ if (abortIsTheRunsOutcome) this.subagents.noteSettled(state2.eventId);
3688
4372
  this.cleanup(callId);
3689
4373
  };
3690
4374
  // ── executeTool ─────────────────────────────────────────────────────────
@@ -3693,14 +4377,14 @@ var RaindropTelemetryIntegration = class {
3693
4377
  toolCallId,
3694
4378
  execute
3695
4379
  }) => {
3696
- const state = this.getState(callId);
3697
- const toolSpan = state == null ? void 0 : state.toolSpans.get(toolCallId);
4380
+ const state2 = this.getState(callId);
4381
+ const toolSpan = state2 == null ? void 0 : state2.toolSpans.get(toolCallId);
3698
4382
  if (!toolSpan) return execute();
3699
4383
  return runWithParentSpanContext(
3700
4384
  {
3701
4385
  traceIdB64: toolSpan.ids.traceIdB64,
3702
4386
  spanIdB64: toolSpan.ids.spanIdB64,
3703
- eventId: state.eventId
4387
+ eventId: state2.eventId
3704
4388
  },
3705
4389
  () => execute()
3706
4390
  );
@@ -3749,35 +4433,35 @@ var RaindropTelemetryIntegration = class {
3749
4433
  activeDispatch() {
3750
4434
  var _a;
3751
4435
  const parentTool = getCurrentParentToolContext();
3752
- let state = parentTool ? this.getState(parentTool.parentCallId) : void 0;
4436
+ let state2 = parentTool ? this.getState(parentTool.parentCallId) : void 0;
3753
4437
  const inheritedEventId = (_a = getContextManager().getParentSpanIds()) == null ? void 0 : _a.eventId;
3754
- if (!state && inheritedEventId) {
4438
+ if (!state2 && inheritedEventId) {
3755
4439
  for (const candidate of this.callStates.values()) {
3756
4440
  if (candidate.eventId === inheritedEventId) {
3757
- state = candidate;
4441
+ state2 = candidate;
3758
4442
  break;
3759
4443
  }
3760
4444
  }
3761
4445
  }
3762
- if (!state) return void 0;
4446
+ if (!state2) return void 0;
3763
4447
  return {
3764
- eventId: state.eventId,
3765
- userId: state.identity.userId,
3766
- convoId: state.identity.convoId,
3767
- dispatchSpan: parentTool ? state.toolSpans.get(parentTool.toolCallId) : void 0,
3768
- turnSpans: [state.rootSpan, state.stepSpan].filter(
4448
+ eventId: state2.eventId,
4449
+ userId: state2.identity.userId,
4450
+ convoId: state2.identity.convoId,
4451
+ dispatchSpan: parentTool ? state2.toolSpans.get(parentTool.toolCallId) : void 0,
4452
+ turnSpans: [state2.rootSpan, state2.stepSpan].filter(
3769
4453
  (span) => span !== void 0
3770
4454
  ),
3771
- recordInputs: state.recordInputs
4455
+ recordInputs: state2.recordInputs
3772
4456
  };
3773
4457
  }
3774
4458
  /** Spans still open for an event, so a late outcome can still be stated. */
3775
4459
  openSpansForEvent(eventId) {
3776
4460
  const spans = [];
3777
- for (const state of this.callStates.values()) {
3778
- if (state.eventId !== eventId) continue;
3779
- if (state.rootSpan) spans.push(state.rootSpan);
3780
- if (state.stepSpan) spans.push(state.stepSpan);
4461
+ for (const state2 of this.callStates.values()) {
4462
+ if (state2.eventId !== eventId) continue;
4463
+ if (state2.rootSpan) spans.push(state2.rootSpan);
4464
+ if (state2.stepSpan) spans.push(state2.stepSpan);
3781
4465
  }
3782
4466
  return spans;
3783
4467
  }
@@ -3797,10 +4481,10 @@ var RaindropTelemetryIntegration = class {
3797
4481
  * created from an LLM span with output, `ai.response.text` here would state
3798
4482
  * the run's outcome through the span while the turn is still working.
3799
4483
  */
3800
- abortOutcomeAttrs(state, reason, finishReason) {
3801
- if (!state.handoff || state.nestedInEvent) return [];
4484
+ abortOutcomeAttrs(state2, reason, finishReason) {
4485
+ if (!state2.handoff || state2.nestedInEvent) return [];
3802
4486
  return [
3803
- attrString("ai.response.text", capText2(state.accumulatedText || reason)),
4487
+ attrString("ai.response.text", capText2(state2.accumulatedText || reason)),
3804
4488
  attrString("ai.response.finishReason", finishReason)
3805
4489
  ];
3806
4490
  }
@@ -3814,19 +4498,19 @@ var RaindropTelemetryIntegration = class {
3814
4498
  spanParentRef(span) {
3815
4499
  return { traceIdB64: span.ids.traceIdB64, spanIdB64: span.ids.spanIdB64 };
3816
4500
  }
3817
- emitLive(state, type, content, extra) {
4501
+ emitLive(state2, type, content, extra) {
3818
4502
  var _a, _b, _c, _d, _e, _f;
3819
- if (!localDebuggerEnabled() || !state.rootSpan) return;
3820
- const callMeta = this.extractRaindropMetadata(state.metadata);
4503
+ if (!localDebuggerEnabled() || !state2.rootSpan) return;
4504
+ const callMeta = this.extractRaindropMetadata(state2.metadata);
3821
4505
  sendLocalDebuggerLiveEvent({
3822
- traceId: state.rootSpan.ids.traceIdB64,
4506
+ traceId: state2.rootSpan.ids.traceIdB64,
3823
4507
  type,
3824
4508
  content,
3825
4509
  metadata: {
3826
4510
  userId: (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId,
3827
4511
  convoId: (_d = callMeta.convoId) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.convoId,
3828
4512
  eventName: (_f = callMeta.eventName) != null ? _f : (_e = this.defaultContext) == null ? void 0 : _e.eventName,
3829
- eventId: state.eventId,
4513
+ eventId: state2.eventId,
3830
4514
  ...extra
3831
4515
  }
3832
4516
  });
@@ -3904,29 +4588,29 @@ var RaindropTelemetryIntegration = class {
3904
4588
  toolCallId: toolCall.toolCallId,
3905
4589
  toolName: toolCall.toolName
3906
4590
  });
3907
- const state = this.getState(event.callId);
3908
- state == null ? void 0 : state.parentContextToolCallIds.add(toolCall.toolCallId);
3909
- if (!(state == null ? void 0 : state.stepParent)) return;
3910
- const { operationName, resourceName } = opName("ai.toolCall", state.functionId);
3911
- const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
4591
+ const state2 = this.getState(event.callId);
4592
+ state2 == null ? void 0 : state2.parentContextToolCallIds.add(toolCall.toolCallId);
4593
+ if (!(state2 == null ? void 0 : state2.stepParent)) return;
4594
+ const { operationName, resourceName } = opName("ai.toolCall", state2.functionId);
4595
+ const inputAttrs = state2.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
3912
4596
  const toolSpan = this.traceShipper.startSpan({
3913
4597
  name: "ai.toolCall",
3914
- parent: state.stepParent,
3915
- eventId: state.eventId,
3916
- ...state.identity,
4598
+ parent: state2.stepParent,
4599
+ eventId: state2.eventId,
4600
+ ...state2.identity,
3917
4601
  operationId: "ai.toolCall",
3918
4602
  attributes: [
3919
4603
  attrString("operation.name", operationName),
3920
4604
  attrString("resource.name", resourceName),
3921
- attrString("ai.telemetry.functionId", state.functionId),
4605
+ attrString("ai.telemetry.functionId", state2.functionId),
3922
4606
  attrString("ai.toolCall.name", toolCall.toolName),
3923
4607
  attrString("ai.toolCall.id", toolCall.toolCallId),
3924
4608
  ...inputAttrs,
3925
- ...handoffSpanAttrs(state.handoff)
4609
+ ...handoffSpanAttrs(state2.handoff)
3926
4610
  ]
3927
4611
  });
3928
- state.toolSpans.set(toolCall.toolCallId, toolSpan);
3929
- this.emitLive(state, "tool_start", toolCall.toolName, { args: toolCall.input });
4612
+ state2.toolSpans.set(toolCall.toolCallId, toolSpan);
4613
+ this.emitLive(state2, "tool_start", toolCall.toolName, { args: toolCall.input });
3930
4614
  }
3931
4615
  toolExecutionEnd(event) {
3932
4616
  var _a;
@@ -3940,20 +4624,20 @@ var RaindropTelemetryIntegration = class {
3940
4624
  clearParentToolContext();
3941
4625
  }
3942
4626
  }
3943
- const state = this.getState(event.callId);
3944
- if (!state) return;
3945
- const toolSpan = state.toolSpans.get(event.toolCall.toolCallId);
4627
+ const state2 = this.getState(event.callId);
4628
+ if (!state2) return;
4629
+ const toolSpan = state2.toolSpans.get(event.toolCall.toolCallId);
3946
4630
  if (!toolSpan) return;
3947
- state.toolCallCount += 1;
4631
+ state2.toolCallCount += 1;
3948
4632
  const outcome = "toolOutput" in event ? event.toolOutput.type === "tool-result" ? { success: true, output: event.toolOutput.output } : { success: false, error: event.toolOutput.error } : event.success ? { success: true, output: event.output } : { success: false, error: event.error };
3949
4633
  if (outcome.success) {
3950
- const outputAttrs = state.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(outcome.output))] : [];
4634
+ const outputAttrs = state2.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(outcome.output))] : [];
3951
4635
  this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
3952
4636
  } else {
3953
4637
  this.traceShipper.endSpan(toolSpan, { error: outcome.error });
3954
4638
  }
3955
- this.emitLive(state, "tool_result", event.toolCall.toolName);
3956
- state.toolSpans.delete(event.toolCall.toolCallId);
4639
+ this.emitLive(state2, "tool_result", event.toolCall.toolName);
4640
+ state2.toolSpans.delete(event.toolCall.toolCallId);
3957
4641
  }
3958
4642
  // ── provider-executed tool calls ─────────────────────────────────────────
3959
4643
  //
@@ -3972,8 +4656,8 @@ var RaindropTelemetryIntegration = class {
3972
4656
  //
3973
4657
  // Client-executed tools are excluded (`providerExecuted` falsy) — they were
3974
4658
  // already spanned during execution, so this never double-emits.
3975
- emitProviderExecutedToolSpans(event, state) {
3976
- if (!state.stepParent) return;
4659
+ emitProviderExecutedToolSpans(event, state2) {
4660
+ if (!state2.stepParent) return;
3977
4661
  const content = Array.isArray(event.content) ? event.content : [];
3978
4662
  const providerToolCalls = content.filter(
3979
4663
  (part) => (part == null ? void 0 : part.type) === "tool-call" && part.providerExecuted === true
@@ -3986,42 +4670,42 @@ var RaindropTelemetryIntegration = class {
3986
4670
  }
3987
4671
  }
3988
4672
  for (const call of providerToolCalls) {
3989
- const { operationName, resourceName } = opName("ai.toolCall", state.functionId);
3990
- const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(call.input))] : [];
4673
+ const { operationName, resourceName } = opName("ai.toolCall", state2.functionId);
4674
+ const inputAttrs = state2.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(call.input))] : [];
3991
4675
  const toolSpan = this.traceShipper.startSpan({
3992
4676
  name: "ai.toolCall",
3993
- parent: state.stepParent,
3994
- eventId: state.eventId,
3995
- ...state.identity,
4677
+ parent: state2.stepParent,
4678
+ eventId: state2.eventId,
4679
+ ...state2.identity,
3996
4680
  operationId: "ai.toolCall",
3997
4681
  attributes: [
3998
4682
  attrString("operation.name", operationName),
3999
4683
  attrString("resource.name", resourceName),
4000
- attrString("ai.telemetry.functionId", state.functionId),
4684
+ attrString("ai.telemetry.functionId", state2.functionId),
4001
4685
  attrString("ai.toolCall.name", call.toolName),
4002
4686
  attrString("ai.toolCall.id", call.toolCallId),
4003
4687
  attrString("ai.toolCall.providerExecuted", "true"),
4004
4688
  ...inputAttrs,
4005
- ...handoffSpanAttrs(state.handoff)
4689
+ ...handoffSpanAttrs(state2.handoff)
4006
4690
  ]
4007
4691
  });
4008
- state.toolCallCount += 1;
4009
- this.emitLive(state, "tool_start", call.toolName, { args: call.input });
4692
+ state2.toolCallCount += 1;
4693
+ this.emitLive(state2, "tool_start", call.toolName, { args: call.input });
4010
4694
  const resultPart = resultsByCallId.get(call.toolCallId);
4011
4695
  if ((resultPart == null ? void 0 : resultPart.type) === "tool-error") {
4012
4696
  this.traceShipper.endSpan(toolSpan, { error: resultPart.error });
4013
4697
  } else {
4014
- const outputAttrs = state.recordOutputs && resultPart && "output" in resultPart ? [attrString("ai.toolCall.result", safeJsonWithUint8(resultPart.output))] : [];
4698
+ const outputAttrs = state2.recordOutputs && resultPart && "output" in resultPart ? [attrString("ai.toolCall.result", safeJsonWithUint8(resultPart.output))] : [];
4015
4699
  this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
4016
4700
  }
4017
- this.emitLive(state, "tool_result", call.toolName);
4701
+ this.emitLive(state2, "tool_result", call.toolName);
4018
4702
  }
4019
4703
  }
4020
- finishGenerate(event, state) {
4704
+ finishGenerate(event, state2) {
4021
4705
  var _a, _b, _c, _d, _e, _f;
4022
- if (state.rootSpan) {
4706
+ if (state2.rootSpan) {
4023
4707
  const outputAttrs = [];
4024
- if (state.recordOutputs) {
4708
+ if (state2.recordOutputs) {
4025
4709
  outputAttrs.push(
4026
4710
  attrString("ai.response.finishReason", event.finishReason),
4027
4711
  attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
@@ -4062,12 +4746,12 @@ var RaindropTelemetryIntegration = class {
4062
4746
  attrInt("ai.usage.cachedInputTokens", usageMetrics.cachedInputTokens)
4063
4747
  );
4064
4748
  }
4065
- outputAttrs.push(attrInt("ai.toolCall.count", state.toolCallCount));
4066
- this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
4749
+ outputAttrs.push(attrInt("ai.toolCall.count", state2.toolCallCount));
4750
+ this.traceShipper.endSpan(state2.rootSpan, { attributes: outputAttrs });
4067
4751
  }
4068
4752
  this.finalizeGenerateEvent(
4069
- state,
4070
- (_e = event.text) != null ? _e : state.accumulatedText || void 0,
4753
+ state2,
4754
+ (_e = event.text) != null ? _e : state2.accumulatedText || void 0,
4071
4755
  (_f = event.response) == null ? void 0 : _f.modelId,
4072
4756
  hasUnresolvedToolApproval(event)
4073
4757
  );
@@ -4083,29 +4767,29 @@ var RaindropTelemetryIntegration = class {
4083
4767
  * is finalized by that resume — otherwise each execution would finalize the
4084
4768
  * same event ID into a separate canonical row.
4085
4769
  */
4086
- finalizeGenerateEvent(state, output, model, keepPending = false, detachedOutcome) {
4770
+ finalizeGenerateEvent(state2, output, model, keepPending = false, detachedOutcome) {
4087
4771
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
4088
- const suppressSubagentEvent = state.subagentName !== void 0 && state.subagentToolCallSpan !== void 0;
4772
+ const suppressSubagentEvent = state2.subagentName !== void 0 && state2.subagentToolCallSpan !== void 0;
4089
4773
  if (!this.sendEvents || suppressSubagentEvent) return;
4090
- if (this.subagents.wasSettledExplicitly(state.eventId)) return;
4091
- const callMeta = this.extractRaindropMetadata(state.metadata);
4774
+ if (this.subagents.wasSettledExplicitly(state2.eventId)) return;
4775
+ const callMeta = this.extractRaindropMetadata(state2.metadata);
4092
4776
  const userId = (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId;
4093
4777
  if (!userId) return;
4094
- const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state.operationId;
4778
+ const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state2.operationId;
4095
4779
  const cappedOutput = capText2(output);
4096
- const reportedOutput = state.handoff && detachedOutcome && !(cappedOutput == null ? void 0 : cappedOutput.trim()) ? detachedOutcome.fallbackOutput : cappedOutput;
4097
- const input = capText2(state.inputText);
4780
+ const reportedOutput = state2.handoff && detachedOutcome && !(cappedOutput == null ? void 0 : cappedOutput.trim()) ? detachedOutcome.fallbackOutput : cappedOutput;
4781
+ const input = capText2(state2.inputText);
4098
4782
  const properties = {
4099
4783
  ...(_f = this.defaultContext) == null ? void 0 : _f.properties,
4100
4784
  ...callMeta.properties,
4101
- ...state.handoff ? detachedOutcome == null ? void 0 : detachedOutcome.properties : void 0
4785
+ ...state2.handoff ? detachedOutcome == null ? void 0 : detachedOutcome.properties : void 0
4102
4786
  };
4103
4787
  const featureFlags = {
4104
4788
  ...((_g = this.defaultContext) == null ? void 0 : _g.featureFlags) ? normalizeFeatureFlags(this.defaultContext.featureFlags) : {},
4105
4789
  ...callMeta.featureFlags
4106
4790
  };
4107
4791
  const convoId = (_i = callMeta.convoId) != null ? _i : (_h = this.defaultContext) == null ? void 0 : _h.convoId;
4108
- void this.eventShipper.patch(state.eventId, {
4792
+ void this.eventShipper.patch(state2.eventId, {
4109
4793
  eventName,
4110
4794
  userId,
4111
4795
  convoId,
@@ -4123,12 +4807,12 @@ var RaindropTelemetryIntegration = class {
4123
4807
  }
4124
4808
  });
4125
4809
  }
4126
- finishEmbed(event, state) {
4810
+ finishEmbed(event, state2) {
4127
4811
  var _a;
4128
- if (!state.rootSpan) return;
4812
+ if (!state2.rootSpan) return;
4129
4813
  const outputAttrs = [];
4130
- const isMany = state.operationId === "ai.embedMany";
4131
- if (state.recordOutputs) {
4814
+ const isMany = state2.operationId === "ai.embedMany";
4815
+ if (state2.recordOutputs) {
4132
4816
  if (isMany) {
4133
4817
  outputAttrs.push(attrString("ai.embeddings", safeJsonWithUint8(event.embedding)));
4134
4818
  } else {
@@ -4138,7 +4822,7 @@ var RaindropTelemetryIntegration = class {
4138
4822
  if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
4139
4823
  outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
4140
4824
  }
4141
- this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
4825
+ this.traceShipper.endSpan(state2.rootSpan, { attributes: outputAttrs });
4142
4826
  }
4143
4827
  };
4144
4828
 
@@ -6316,11 +7000,11 @@ function userAttrsToOtlp(attrs) {
6316
7000
  function envDebugEnabled() {
6317
7001
  var _a;
6318
7002
  if (typeof process === "undefined") return false;
6319
- const flag = (_a = process.env) == null ? void 0 : _a.RAINDROP_AI_DEBUG;
6320
- return flag === "1" || flag === "true";
7003
+ const flag2 = (_a = process.env) == null ? void 0 : _a.RAINDROP_AI_DEBUG;
7004
+ return flag2 === "1" || flag2 === "true";
6321
7005
  }
6322
7006
  function createRaindropAISDK(opts) {
6323
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
7007
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
6324
7008
  const writeKey = opts.writeKey;
6325
7009
  const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
6326
7010
  const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
@@ -6329,37 +7013,53 @@ function createRaindropAISDK(opts) {
6329
7013
  const localWorkshopInput = opts.localWorkshopUrl === false ? null : opts.localWorkshopUrl;
6330
7014
  const resolvedLocalDebuggerUrl = resolveLocalDebuggerBaseUrl(localWorkshopInput);
6331
7015
  const localDebuggerUrl = localWorkshopInput === null ? null : resolvedLocalDebuggerUrl != null ? resolvedLocalDebuggerUrl : void 0;
6332
- const hasDestination = !!writeKey || !!resolvedLocalDebuggerUrl;
7016
+ const hasDestination = Boolean(writeKey == null ? void 0 : writeKey.trim()) || Boolean(resolvedLocalDebuggerUrl);
6333
7017
  const eventsEnabled = eventsRequested && hasDestination;
6334
7018
  const tracesEnabled = tracesRequested && hasDestination;
7019
+ const appGitContext = (_c = opts.appGitContext) != null ? _c : createAppGitContext(
7020
+ eventsEnabled || tracesEnabled ? opts.appGit : false,
7021
+ { allowLocalGit: true }
7022
+ );
6335
7023
  if (!hasDestination && (eventsRequested || tracesRequested)) {
6336
7024
  console.warn(
6337
7025
  "[raindrop-ai/ai-sdk] writeKey not provided and no local Workshop reachable; telemetry shipping is disabled"
6338
7026
  );
6339
7027
  }
6340
- const eventShipper = new EventShipper2({
6341
- writeKey,
6342
- endpoint: opts.endpoint,
6343
- enabled: eventsEnabled,
6344
- debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
6345
- partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
6346
- projectId: opts.projectId,
6347
- localDebuggerUrl
6348
- });
6349
- const traceShipper = new TraceShipper2({
6350
- writeKey,
6351
- endpoint: opts.endpoint,
6352
- enabled: tracesEnabled,
6353
- debug: ((_e = opts.traces) == null ? void 0 : _e.debug) === true || envDebug,
6354
- debugSpans: ((_f = opts.traces) == null ? void 0 : _f.debugSpans) === true || envDebug,
6355
- flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
6356
- maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
6357
- maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
6358
- projectId: opts.projectId,
6359
- localDebuggerUrl,
6360
- transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
6361
- disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
6362
- });
7028
+ let eventShipper;
7029
+ let traceShipper;
7030
+ try {
7031
+ eventShipper = new EventShipper2({
7032
+ writeKey,
7033
+ endpoint: opts.endpoint,
7034
+ enabled: eventsEnabled,
7035
+ debug: ((_d = opts.events) == null ? void 0 : _d.debug) === true || envDebug,
7036
+ partialFlushMs: (_e = opts.events) == null ? void 0 : _e.partialFlushMs,
7037
+ projectId: opts.projectId,
7038
+ localDebuggerUrl,
7039
+ appGitContext
7040
+ });
7041
+ traceShipper = new TraceShipper2({
7042
+ writeKey,
7043
+ endpoint: opts.endpoint,
7044
+ enabled: tracesEnabled,
7045
+ debug: ((_f = opts.traces) == null ? void 0 : _f.debug) === true || envDebug,
7046
+ debugSpans: ((_g = opts.traces) == null ? void 0 : _g.debugSpans) === true || envDebug,
7047
+ flushIntervalMs: (_h = opts.traces) == null ? void 0 : _h.flushIntervalMs,
7048
+ maxBatchSize: (_i = opts.traces) == null ? void 0 : _i.maxBatchSize,
7049
+ maxQueueSize: (_j = opts.traces) == null ? void 0 : _j.maxQueueSize,
7050
+ projectId: opts.projectId,
7051
+ localDebuggerUrl,
7052
+ transformSpan: (_k = opts.traces) == null ? void 0 : _k.transformSpan,
7053
+ disableDefaultRedaction: (_l = opts.traces) == null ? void 0 : _l.disableDefaultRedaction,
7054
+ appGitContext
7055
+ });
7056
+ } catch (error) {
7057
+ try {
7058
+ appGitContext.dispose();
7059
+ } catch (e) {
7060
+ }
7061
+ throw error;
7062
+ }
6363
7063
  const settledEventIds = /* @__PURE__ */ new Set();
6364
7064
  const subagentApi = new SubagentApi({
6365
7065
  traceShipper,
@@ -6527,7 +7227,14 @@ function createRaindropAISDK(opts) {
6527
7227
  await Promise.all([eventShipper.flush(), traceShipper.flush()]);
6528
7228
  },
6529
7229
  async shutdown() {
6530
- await Promise.all([eventShipper.shutdown(), traceShipper.shutdown()]);
7230
+ try {
7231
+ await Promise.all([eventShipper.shutdown(), traceShipper.shutdown()]);
7232
+ } finally {
7233
+ try {
7234
+ appGitContext.dispose();
7235
+ } catch (e) {
7236
+ }
7237
+ }
6531
7238
  }
6532
7239
  };
6533
7240
  }